1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "OutlinerIterator.hxx"
22 #include "OutlinerIteratorImpl.hxx"
23 #include <svx/svditer.hxx>
24 #include <sfx2/dispatch.hxx>
25 #include <sfx2/viewfrm.hxx>
26 #include "Outliner.hxx"
28 #include "drawdoc.hxx"
29 #include "DrawViewShell.hxx"
30 #include "drawview.hxx"
33 #include "FrameView.hxx"
35 #include "DrawDocShell.hxx"
38 namespace sd
{ namespace outliner
{
41 //===== IteratorPosition ======================================================
43 IteratorPosition::IteratorPosition (void)
46 , mePageKind(PK_STANDARD
)
51 IteratorPosition::IteratorPosition (const IteratorPosition
& aPosition
)
52 : mxObject(aPosition
.mxObject
)
53 , mnText(aPosition
.mnText
)
54 , mnPageIndex(aPosition
.mnPageIndex
)
55 , mePageKind(aPosition
.mePageKind
)
56 , meEditMode(aPosition
.meEditMode
)
60 IteratorPosition::~IteratorPosition (void)
64 IteratorPosition
& IteratorPosition::operator= (const IteratorPosition
& aPosition
)
66 mxObject
= aPosition
.mxObject
;
67 mnText
= aPosition
.mnText
;
68 mnPageIndex
= aPosition
.mnPageIndex
;
69 mePageKind
= aPosition
.mePageKind
;
70 meEditMode
= aPosition
.meEditMode
;
74 bool IteratorPosition::operator== (const IteratorPosition
& aPosition
) const
76 return mxObject
.get() == aPosition
.mxObject
.get()
77 && mnText
== aPosition
.mnText
78 && mnPageIndex
== aPosition
.mnPageIndex
79 && mePageKind
== aPosition
.mePageKind
80 && meEditMode
== aPosition
.meEditMode
;
86 //===== Iterator ==============================================================
88 Iterator::Iterator (void)
93 Iterator::Iterator (const Iterator
& rIterator
)
95 mpIterator
= rIterator
.mpIterator
->Clone();
98 Iterator::Iterator (IteratorImplBase
* pObject
)
100 mpIterator
= pObject
;
103 Iterator::~Iterator (void)
108 Iterator
& Iterator::operator= (const Iterator
& rIterator
)
110 if (this != &rIterator
)
113 if (rIterator
.mpIterator
!= NULL
)
114 mpIterator
= rIterator
.mpIterator
->Clone();
121 const IteratorPosition
& Iterator::operator* () const
123 DBG_ASSERT (mpIterator
!=NULL
, "::sd::outliner::Iterator::operator* : missing implementation object");
124 return mpIterator
->GetPosition();
127 Iterator
& Iterator::operator++ ()
129 if (mpIterator
!=NULL
)
130 mpIterator
->GotoNextText();
134 Iterator
Iterator::operator++ (int)
136 Iterator
aTmp (*this);
137 if (mpIterator
!=NULL
)
138 mpIterator
->GotoNextText();
142 bool Iterator::operator== (const Iterator
& rIterator
)
144 if (mpIterator
== NULL
|| rIterator
.mpIterator
==NULL
)
145 return mpIterator
== rIterator
.mpIterator
;
147 return *mpIterator
== *rIterator
.mpIterator
;
150 bool Iterator::operator!= (const Iterator
& rIterator
)
152 return ! operator==(rIterator
);
155 void Iterator::Reverse (void)
157 if (mpIterator
!= NULL
)
158 mpIterator
->Reverse();
161 //===== IteratorFactory =======================================================
163 OutlinerContainer::OutlinerContainer (Outliner
* pOutliner
)
164 : mpOutliner(pOutliner
)
168 Iterator
OutlinerContainer::begin (void)
170 return CreateIterator (BEGIN
);
173 Iterator
OutlinerContainer::end (void)
175 return CreateIterator (END
);
178 Iterator
OutlinerContainer::current (void)
180 return CreateIterator (CURRENT
);
184 Iterator
OutlinerContainer::CreateIterator (IteratorLocation aLocation
)
186 // Decide on certain features of the outliner which kind of iterator to
188 if (mpOutliner
->mbRestrictSearchToSelection
)
189 // There is a selection. Search only in this.
190 return CreateSelectionIterator (
191 mpOutliner
->maMarkListCopy
,
192 mpOutliner
->mpDrawDocument
,
193 mpOutliner
->mpWeakViewShell
.lock(),
194 mpOutliner
->mbDirectionIsForward
,
197 // Search in the whole document.
198 return CreateDocumentIterator (
199 mpOutliner
->mpDrawDocument
,
200 mpOutliner
->mpWeakViewShell
.lock(),
201 mpOutliner
->mbDirectionIsForward
,
205 Iterator
OutlinerContainer::CreateSelectionIterator (
206 const ::std::vector
<SdrObjectWeakRef
>& rObjectList
,
207 SdDrawDocument
* pDocument
,
208 const ::boost::shared_ptr
<ViewShell
>& rpViewShell
,
209 bool bDirectionIsForward
,
210 IteratorLocation aLocation
)
212 OSL_ASSERT(rpViewShell
.get());
214 sal_Int32 nObjectIndex
;
216 if (bDirectionIsForward
)
225 nObjectIndex
= rObjectList
.size();
234 nObjectIndex
= rObjectList
.size()-1;
241 return Iterator (new SelectionIteratorImpl (
242 rObjectList
, nObjectIndex
, pDocument
, rpViewShell
, bDirectionIsForward
));
245 Iterator
OutlinerContainer::CreateDocumentIterator (
246 SdDrawDocument
* pDocument
,
247 const ::boost::shared_ptr
<ViewShell
>& rpViewShell
,
248 bool bDirectionIsForward
,
249 IteratorLocation aLocation
)
251 OSL_ASSERT(rpViewShell
.get());
260 if (bDirectionIsForward
)
262 ePageKind
= PK_STANDARD
;
267 ePageKind
= PK_HANDOUT
;
268 eEditMode
= EM_MASTERPAGE
;
273 if (bDirectionIsForward
)
275 ePageKind
= PK_HANDOUT
;
276 eEditMode
= EM_MASTERPAGE
;
280 ePageKind
= PK_STANDARD
;
286 const ::boost::shared_ptr
<DrawViewShell
> pDrawViewShell(
287 ::boost::dynamic_pointer_cast
<DrawViewShell
>(rpViewShell
));
288 if (pDrawViewShell
.get())
290 ePageKind
= pDrawViewShell
->GetPageKind();
291 eEditMode
= pDrawViewShell
->GetEditMode();
295 ePageKind
= PK_STANDARD
;
301 sal_Int32 nPageIndex
= GetPageIndex (pDocument
, rpViewShell
,
302 ePageKind
, eEditMode
, bDirectionIsForward
, aLocation
);
305 new DocumentIteratorImpl (nPageIndex
, ePageKind
, eEditMode
,
306 pDocument
, rpViewShell
, bDirectionIsForward
));
309 sal_Int32
OutlinerContainer::GetPageIndex (
310 SdDrawDocument
* pDocument
,
311 const ::boost::shared_ptr
<ViewShell
>& rpViewShell
,
314 bool bDirectionIsForward
,
315 IteratorLocation aLocation
)
317 OSL_ASSERT(rpViewShell
);
319 sal_Int32 nPageIndex
;
320 sal_Int32 nPageCount
;
322 const ::boost::shared_ptr
<DrawViewShell
> pDrawViewShell(
323 ::boost::dynamic_pointer_cast
<DrawViewShell
>(rpViewShell
));
328 nPageCount
= pDocument
->GetSdPageCount (ePageKind
);
331 nPageCount
= pDocument
->GetMasterSdPageCount(ePageKind
);
340 if (pDrawViewShell
.get())
341 nPageIndex
= pDrawViewShell
->GetCurPageId() - 1;
344 const SdPage
* pPage
= rpViewShell
->GetActualPage();
346 nPageIndex
= (pPage
->GetPageNum()-1)/2;
354 if (bDirectionIsForward
)
357 nPageIndex
= nPageCount
-1;
361 if (bDirectionIsForward
)
362 nPageIndex
= nPageCount
;
374 //===== IteratorImplBase ====================================================
376 IteratorImplBase::IteratorImplBase(SdDrawDocument
* pDocument
,
377 const ::boost::weak_ptr
<ViewShell
>& rpViewShellWeak
,
378 bool bDirectionIsForward
)
380 , mpDocument (pDocument
)
381 , mpViewShellWeak (rpViewShellWeak
)
382 , mbDirectionIsForward (bDirectionIsForward
)
384 ::boost::shared_ptr
<DrawViewShell
> pDrawViewShell
;
385 if ( ! mpViewShellWeak
.expired())
386 pDrawViewShell
= ::boost::dynamic_pointer_cast
<DrawViewShell
>(rpViewShellWeak
.lock());
388 if (pDrawViewShell
.get())
390 maPosition
.mePageKind
= pDrawViewShell
->GetPageKind();
391 maPosition
.meEditMode
= pDrawViewShell
->GetEditMode();
395 maPosition
.mePageKind
= PK_STANDARD
;
396 maPosition
.meEditMode
= EM_PAGE
;
400 IteratorImplBase::IteratorImplBase( SdDrawDocument
* pDocument
,
401 const ::boost::weak_ptr
<ViewShell
>& rpViewShellWeak
,
402 bool bDirectionIsForward
, PageKind ePageKind
, EditMode eEditMode
)
404 , mpDocument (pDocument
)
405 , mpViewShellWeak (rpViewShellWeak
)
406 , mbDirectionIsForward (bDirectionIsForward
)
408 maPosition
.mePageKind
= ePageKind
;
409 maPosition
.meEditMode
= eEditMode
;
412 IteratorImplBase::~IteratorImplBase (void)
415 bool IteratorImplBase::operator== (const IteratorImplBase
& rIterator
) const
417 return maPosition
== rIterator
.maPosition
;
420 bool IteratorImplBase::IsEqual (const IteratorImplBase
& rIterator
, IteratorType
) const
422 // When this method is executed instead of the ones from derived classes
423 // then the argument is of another type then the object itself. In this
424 // just compare the position objects.
425 return maPosition
== rIterator
.maPosition
;
428 const IteratorPosition
& IteratorImplBase::GetPosition (void)
436 IteratorImplBase
* IteratorImplBase::Clone (IteratorImplBase
* pObject
) const
440 pObject
->maPosition
= maPosition
;
441 pObject
->mpDocument
= mpDocument
;
442 pObject
->mpViewShellWeak
= mpViewShellWeak
;
443 pObject
->mbDirectionIsForward
= mbDirectionIsForward
;
450 void IteratorImplBase::Reverse (void)
452 mbDirectionIsForward
= ! mbDirectionIsForward
;
457 //===== SelectionIteratorImpl ===========================================
459 SelectionIteratorImpl::SelectionIteratorImpl (
460 const ::std::vector
<SdrObjectWeakRef
>& rObjectList
,
461 sal_Int32 nObjectIndex
,
462 SdDrawDocument
* pDocument
,
463 const ::boost::weak_ptr
<ViewShell
>& rpViewShellWeak
,
464 bool bDirectionIsForward
)
465 : IteratorImplBase (pDocument
, rpViewShellWeak
, bDirectionIsForward
),
466 mrObjectList(rObjectList
),
467 mnObjectIndex(nObjectIndex
)
471 SelectionIteratorImpl::~SelectionIteratorImpl (void)
474 IteratorImplBase
* SelectionIteratorImpl::Clone (IteratorImplBase
* pObject
) const
476 SelectionIteratorImpl
* pIterator
= static_cast<SelectionIteratorImpl
*>(pObject
);
477 if (pIterator
== NULL
)
478 pIterator
= new SelectionIteratorImpl (
479 mrObjectList
, mnObjectIndex
, mpDocument
, mpViewShellWeak
, mbDirectionIsForward
);
484 void SelectionIteratorImpl::GotoNextText (void)
486 SdrTextObj
* pTextObj
= dynamic_cast< SdrTextObj
* >( mrObjectList
.at(mnObjectIndex
).get() );
487 if (mbDirectionIsForward
)
492 if( maPosition
.mnText
>= pTextObj
->getTextCount() )
494 maPosition
.mnText
= 0;
508 if( maPosition
.mnText
< 0 )
510 maPosition
.mnText
= -1;
517 maPosition
.mnText
= -1;
520 if( (maPosition
.mnText
== -1) && (mnObjectIndex
>= 0) )
522 pTextObj
= dynamic_cast< SdrTextObj
* >( mrObjectList
.at(mnObjectIndex
).get() );
524 maPosition
.mnText
= pTextObj
->getTextCount() - 1;
527 if( maPosition
.mnText
== -1 )
528 maPosition
.mnText
= 0;
533 const IteratorPosition
& SelectionIteratorImpl::GetPosition (void)
535 maPosition
.mxObject
= mrObjectList
.at(mnObjectIndex
);
541 bool SelectionIteratorImpl::operator== (const IteratorImplBase
& rIterator
) const
543 return rIterator
.IsEqual (*this, SELECTION
);
547 bool SelectionIteratorImpl::IsEqual (
548 const IteratorImplBase
& rIterator
,
549 IteratorType aType
) const
551 if (aType
== SELECTION
)
553 const SelectionIteratorImpl
* pSelectionIterator
=
554 static_cast<const SelectionIteratorImpl
*>(&rIterator
);
555 return mpDocument
== pSelectionIterator
->mpDocument
556 && mnObjectIndex
== pSelectionIterator
->mnObjectIndex
;
565 //===== ViewIteratorImpl ================================================
567 ViewIteratorImpl::ViewIteratorImpl (
568 sal_Int32 nPageIndex
,
569 SdDrawDocument
* pDocument
,
570 const ::boost::weak_ptr
<ViewShell
>& rpViewShellWeak
,
571 bool bDirectionIsForward
)
572 : IteratorImplBase (pDocument
, rpViewShellWeak
, bDirectionIsForward
),
573 mbPageChangeOccurred(false),
575 mpObjectIterator(NULL
)
577 SetPage (nPageIndex
);
583 ViewIteratorImpl::ViewIteratorImpl (
584 sal_Int32 nPageIndex
,
585 SdDrawDocument
* pDocument
,
586 const ::boost::weak_ptr
<ViewShell
>& rpViewShellWeak
,
587 bool bDirectionIsForward
,
590 : IteratorImplBase (pDocument
, rpViewShellWeak
, bDirectionIsForward
, ePageKind
, eEditMode
),
591 mbPageChangeOccurred(false),
593 mpObjectIterator(NULL
)
595 SetPage (nPageIndex
);
601 ViewIteratorImpl::~ViewIteratorImpl (void)
608 IteratorImplBase
* ViewIteratorImpl::Clone (IteratorImplBase
* pObject
) const
611 ViewIteratorImpl
* pIterator
= static_cast<ViewIteratorImpl
*>(pObject
);
612 if (pIterator
== NULL
)
613 pIterator
= new ViewIteratorImpl (
614 maPosition
.mnPageIndex
, mpDocument
, mpViewShellWeak
, mbDirectionIsForward
);
616 IteratorImplBase::Clone (pObject
);
618 if (mpObjectIterator
!= NULL
)
620 pIterator
->mpObjectIterator
= new SdrObjListIter(*mpPage
, IM_DEEPNOGROUPS
, !mbDirectionIsForward
);
622 // No direct way to set the object iterator to the current object.
623 pIterator
->maPosition
.mxObject
.reset(NULL
);
624 while (pIterator
->mpObjectIterator
->IsMore() && pIterator
->maPosition
.mxObject
!=maPosition
.mxObject
)
625 pIterator
->maPosition
.mxObject
.reset(pIterator
->mpObjectIterator
->Next());
628 pIterator
->mpObjectIterator
= NULL
;
635 void ViewIteratorImpl::GotoNextText(void)
637 SdrTextObj
* pTextObj
= dynamic_cast< SdrTextObj
* >( maPosition
.mxObject
.get() );
640 if (mbDirectionIsForward
)
643 if( maPosition
.mnText
< pTextObj
->getTextCount() )
649 if( maPosition
.mnText
>= 0 )
654 if (mpObjectIterator
!= NULL
&& mpObjectIterator
->IsMore())
655 maPosition
.mxObject
.reset(mpObjectIterator
->Next());
657 maPosition
.mxObject
.reset(NULL
);
659 if (!maPosition
.mxObject
.is() )
661 if (mbDirectionIsForward
)
662 SetPage (maPosition
.mnPageIndex
+1);
664 SetPage (maPosition
.mnPageIndex
-1);
667 mpObjectIterator
= new SdrObjListIter(*mpPage
, IM_DEEPNOGROUPS
, !mbDirectionIsForward
);
668 if (mpObjectIterator
!=NULL
&& mpObjectIterator
->IsMore())
669 maPosition
.mxObject
.reset(mpObjectIterator
->Next());
671 maPosition
.mxObject
.reset(NULL
);
674 maPosition
.mnText
= 0;
675 if( !mbDirectionIsForward
&& maPosition
.mxObject
.is() )
677 pTextObj
= dynamic_cast< SdrTextObj
* >( maPosition
.mxObject
.get() );
679 maPosition
.mnText
= pTextObj
->getTextCount() - 1;
686 void ViewIteratorImpl::SetPage (sal_Int32 nPageIndex
)
688 mbPageChangeOccurred
= (maPosition
.mnPageIndex
!=nPageIndex
);
689 if (mbPageChangeOccurred
)
691 maPosition
.mnPageIndex
= nPageIndex
;
693 sal_Int32 nPageCount
;
694 if (maPosition
.meEditMode
== EM_PAGE
)
695 nPageCount
= mpDocument
->GetSdPageCount(maPosition
.mePageKind
);
697 nPageCount
= mpDocument
->GetMasterSdPageCount(
698 maPosition
.mePageKind
);
700 // Get page pointer. Here we have three cases: regular pages,
701 // master pages and invalid page indices. The later ones are not
702 // errors but the effect of the iterator advancing to the next page
703 // and going past the last one. This dropping of the rim at the far
704 // side is detected here and has to be reacted to by the caller.
705 if (nPageIndex
>=0 && nPageIndex
< nPageCount
)
707 if (maPosition
.meEditMode
== EM_PAGE
)
708 mpPage
= mpDocument
->GetSdPage (
709 (sal_uInt16
)nPageIndex
,
710 maPosition
.mePageKind
);
712 mpPage
= mpDocument
->GetMasterSdPage (
713 (sal_uInt16
)nPageIndex
,
714 maPosition
.mePageKind
);
720 // Set up object list iterator.
722 mpObjectIterator
= new SdrObjListIter(*mpPage
, IM_DEEPNOGROUPS
, ! mbDirectionIsForward
);
724 mpObjectIterator
= NULL
;
726 // Get object pointer.
727 if (mpObjectIterator
!=NULL
&& mpObjectIterator
->IsMore())
728 maPosition
.mxObject
.reset( mpObjectIterator
->Next() );
730 maPosition
.mxObject
.reset( NULL
);
732 maPosition
.mnText
= 0;
733 if( !mbDirectionIsForward
&& maPosition
.mxObject
.is() )
735 SdrTextObj
* pTextObj
= dynamic_cast< SdrTextObj
* >( maPosition
.mxObject
.get() );
737 maPosition
.mnText
= pTextObj
->getTextCount() - 1;
745 void ViewIteratorImpl::Reverse (void)
747 IteratorImplBase::Reverse ();
749 // Create reversed object list iterator.
750 if (mpObjectIterator
!= NULL
)
751 delete mpObjectIterator
;
753 mpObjectIterator
= new SdrObjListIter(*mpPage
, IM_DEEPNOGROUPS
, ! mbDirectionIsForward
);
755 mpObjectIterator
= NULL
;
757 // Move iterator to the current object.
758 SdrObjectWeakRef xObject
= maPosition
.mxObject
;
759 maPosition
.mxObject
.reset(NULL
);
761 if (!mpObjectIterator
)
764 while (mpObjectIterator
->IsMore() && maPosition
.mxObject
!= xObject
)
765 maPosition
.mxObject
.reset(mpObjectIterator
->Next());
771 //===== DocumentIteratorImpl ============================================
773 DocumentIteratorImpl::DocumentIteratorImpl (
774 sal_Int32 nPageIndex
,
775 PageKind ePageKind
, EditMode eEditMode
,
776 SdDrawDocument
* pDocument
,
777 const ::boost::weak_ptr
<ViewShell
>& rpViewShellWeak
,
778 bool bDirectionIsForward
)
779 : ViewIteratorImpl (nPageIndex
, pDocument
, rpViewShellWeak
, bDirectionIsForward
,
780 ePageKind
, eEditMode
)
782 if (eEditMode
== EM_PAGE
)
783 mnPageCount
= pDocument
->GetSdPageCount (ePageKind
);
785 mnPageCount
= pDocument
->GetMasterSdPageCount(ePageKind
);
791 DocumentIteratorImpl::~DocumentIteratorImpl (void)
797 IteratorImplBase
* DocumentIteratorImpl::Clone (IteratorImplBase
* pObject
) const
799 DocumentIteratorImpl
* pIterator
= static_cast<DocumentIteratorImpl
*>(pObject
);
800 if (pIterator
== NULL
)
801 pIterator
= new DocumentIteratorImpl (
802 maPosition
.mnPageIndex
, maPosition
.mePageKind
, maPosition
.meEditMode
,
803 mpDocument
, mpViewShellWeak
, mbDirectionIsForward
);
804 // Finish the cloning.
805 return ViewIteratorImpl::Clone (pIterator
);
811 void DocumentIteratorImpl::GotoNextText (void)
813 bool bSetToOnePastLastPage
= false;
814 bool bViewChanged
= false;
816 ViewIteratorImpl::GotoNextText();
818 if (mbDirectionIsForward
)
820 if (maPosition
.mnPageIndex
>= mnPageCount
)
822 // Switch to master page.
823 if (maPosition
.meEditMode
== EM_PAGE
)
825 maPosition
.meEditMode
= EM_MASTERPAGE
;
829 // Switch to next view mode.
832 if (maPosition
.mePageKind
== PK_HANDOUT
)
833 // Not really necessary but makes things more clear.
834 bSetToOnePastLastPage
= true;
837 maPosition
.meEditMode
= EM_PAGE
;
838 if (maPosition
.mePageKind
== PK_STANDARD
)
839 maPosition
.mePageKind
= PK_NOTES
;
840 else if (maPosition
.mePageKind
== PK_NOTES
)
841 maPosition
.mePageKind
= PK_HANDOUT
;
849 if (maPosition
.mnPageIndex
< 0)
851 // Switch from master pages to draw pages.
852 if (maPosition
.meEditMode
== EM_MASTERPAGE
)
854 maPosition
.meEditMode
= EM_PAGE
;
855 bSetToOnePastLastPage
= true;
858 // Switch to previous view mode.
861 if (maPosition
.mePageKind
== PK_STANDARD
)
865 maPosition
.meEditMode
= EM_MASTERPAGE
;
866 if (maPosition
.mePageKind
== PK_HANDOUT
)
867 maPosition
.mePageKind
= PK_NOTES
;
868 else if (maPosition
.mePageKind
== PK_NOTES
)
869 maPosition
.mePageKind
= PK_STANDARD
;
870 bSetToOnePastLastPage
= true;
878 // Get new page count;
879 sal_Int32 nPageCount
;
880 if (maPosition
.meEditMode
== EM_PAGE
)
881 nPageCount
= mpDocument
->GetSdPageCount (maPosition
.mePageKind
);
883 nPageCount
= mpDocument
->GetMasterSdPageCount(maPosition
.mePageKind
);
885 // Now that we know the number of pages we can set the current page index.
886 if (bSetToOnePastLastPage
)
887 SetPage (nPageCount
);
892 } } // end of namespace ::sd::outliner
894 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */