1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26 
27 #include "OutlinerIterator.hxx"
28 #include "OutlinerIteratorImpl.hxx"
29 #include <svx/svditer.hxx>
30 #include <sfx2/dispatch.hxx>
31 #include <sfx2/viewfrm.hxx>
32 #include "Outliner.hxx"
33 
34 #include "drawdoc.hxx"
35 #include "DrawViewShell.hxx"
36 #include "drawview.hxx"
37 #include "sdpage.hxx"
38 #ifndef SD_FRAME_VIEW
39 #include "FrameView.hxx"
40 #endif
41 #include "DrawDocShell.hxx"
42 #include "Window.hxx"
43 
44 namespace sd { namespace outliner {
45 
46 
47 //===== IteratorPosition ======================================================
48 
49 IteratorPosition::IteratorPosition (void)
50 : mnText(0)
51 , mnPageIndex(-1)
52 , mePageKind(PK_STANDARD)
53 , meEditMode(EM_PAGE)
54 {
55 }
56 
57 IteratorPosition::IteratorPosition (const IteratorPosition& aPosition)
58 : mxObject(aPosition.mxObject)
59 , mnText(aPosition.mnText)
60 , mnPageIndex(aPosition.mnPageIndex)
61 , mePageKind(aPosition.mePageKind)
62 , meEditMode(aPosition.meEditMode)
63 {
64 }
65 
66 IteratorPosition::~IteratorPosition (void)
67 {
68 }
69 
70 IteratorPosition& IteratorPosition::operator= (const IteratorPosition& aPosition)
71 {
72     mxObject = aPosition.mxObject;
73 	mnText = aPosition.mnText;
74     mnPageIndex = aPosition.mnPageIndex;
75     mePageKind = aPosition.mePageKind;
76     meEditMode = aPosition.meEditMode;
77     return *this;
78 }
79 
80 bool IteratorPosition::operator== (const IteratorPosition& aPosition) const
81 {
82     return mxObject.get() == aPosition.mxObject.get()
83 		&& mnText == aPosition.mnText
84         && mnPageIndex == aPosition.mnPageIndex
85         && mePageKind == aPosition.mePageKind
86         && meEditMode == aPosition.meEditMode;
87 }
88 
89 
90 
91 
92 //===== Iterator ==============================================================
93 
94 Iterator::Iterator (void)
95 {
96     mpIterator = NULL;
97 }
98 
99 Iterator::Iterator (const Iterator& rIterator)
100 {
101     mpIterator = rIterator.mpIterator->Clone();
102 }
103 
104 Iterator::Iterator (IteratorImplBase* pObject)
105 {
106     mpIterator = pObject;
107 }
108 
109 Iterator::~Iterator (void)
110 {
111     delete mpIterator;
112 }
113 
114 Iterator& Iterator::operator= (const Iterator& rIterator)
115 {
116     if (this != &rIterator)
117     {
118         delete mpIterator;
119         if (rIterator.mpIterator != NULL)
120             mpIterator = rIterator.mpIterator->Clone();
121         else
122             mpIterator = NULL;
123     }
124     return *this;
125 }
126 
127 const IteratorPosition& Iterator::operator* () const
128 {
129     DBG_ASSERT (mpIterator!=NULL, "::sd::outliner::Iterator::operator* : missing implementation object");
130     return mpIterator->GetPosition();
131 }
132 
133 Iterator& Iterator::operator++ ()
134 {
135     if (mpIterator!=NULL)
136         mpIterator->GotoNextText();
137     return *this;
138 }
139 
140 Iterator Iterator::operator++ (int)
141 {
142     Iterator aTmp (*this);
143     if (mpIterator!=NULL)
144         mpIterator->GotoNextText();
145     return aTmp;
146 }
147 
148 bool Iterator::operator== (const Iterator& rIterator)
149 {
150     if (mpIterator == NULL || rIterator.mpIterator==NULL)
151         return mpIterator == rIterator.mpIterator;
152     else
153         return *mpIterator == *rIterator.mpIterator;
154 }
155 
156 bool Iterator::operator!= (const Iterator& rIterator)
157 {
158     return ! operator==(rIterator);
159 }
160 
161 void Iterator::Reverse (void)
162 {
163     if (mpIterator != NULL)
164         mpIterator->Reverse();
165 }
166 
167 //===== IteratorFactory =======================================================
168 
169 OutlinerContainer::OutlinerContainer (Outliner* pOutliner)
170 : mpOutliner(pOutliner)
171 {
172 }
173 
174 Iterator OutlinerContainer::begin (void)
175 {
176     return CreateIterator (BEGIN);
177 }
178 
179 Iterator OutlinerContainer::end (void)
180 {
181     return CreateIterator (END);
182 }
183 
184 Iterator OutlinerContainer::current (void)
185 {
186     return CreateIterator (CURRENT);
187 }
188 
189 
190 Iterator OutlinerContainer::CreateIterator (IteratorLocation aLocation)
191 {
192     // Decide on certain features of the outliner which kind of iterator to
193     // use.
194     if (mpOutliner->mbRestrictSearchToSelection)
195         // There is a selection.  Search only in this.
196         return CreateSelectionIterator (
197             mpOutliner->maMarkListCopy,
198             mpOutliner->mpDrawDocument,
199             mpOutliner->mpWeakViewShell.lock(),
200             mpOutliner->mbDirectionIsForward,
201             aLocation);
202     else
203         // Search in the whole document.
204         return CreateDocumentIterator (
205             mpOutliner->mpDrawDocument,
206             mpOutliner->mpWeakViewShell.lock(),
207             mpOutliner->mbDirectionIsForward,
208             aLocation);
209 }
210 
211 Iterator OutlinerContainer::CreateSelectionIterator (
212     const ::std::vector<SdrObjectWeakRef>& rObjectList,
213     SdDrawDocument* pDocument,
214     const ::boost::shared_ptr<ViewShell>& rpViewShell,
215     bool bDirectionIsForward,
216     IteratorLocation aLocation)
217 {
218     OSL_ASSERT(rpViewShell.get());
219 
220     sal_Int32 nObjectIndex;
221 
222     if (bDirectionIsForward)
223         switch (aLocation)
224         {
225             case CURRENT:
226             case BEGIN:
227             default:
228                 nObjectIndex = 0;
229                 break;
230             case END:
231                 nObjectIndex = rObjectList.size();
232                 break;
233         }
234     else
235         switch (aLocation)
236         {
237             case CURRENT:
238             case BEGIN:
239             default:
240                 nObjectIndex = rObjectList.size()-1;
241                 break;
242             case END:
243                 nObjectIndex = -1;
244                 break;
245         }
246 
247     return Iterator (new SelectionIteratorImpl (
248         rObjectList, nObjectIndex, pDocument, rpViewShell, bDirectionIsForward));
249 }
250 
251 Iterator OutlinerContainer::CreateDocumentIterator (
252     SdDrawDocument* pDocument,
253     const ::boost::shared_ptr<ViewShell>& rpViewShell,
254     bool bDirectionIsForward,
255     IteratorLocation aLocation)
256 {
257     OSL_ASSERT(rpViewShell.get());
258 
259     PageKind ePageKind;
260     EditMode eEditMode;
261 
262     switch (aLocation)
263     {
264         case BEGIN:
265         default:
266             if (bDirectionIsForward)
267             {
268                 ePageKind = PK_STANDARD;
269                 eEditMode = EM_PAGE;
270             }
271             else
272             {
273                 ePageKind = PK_HANDOUT;
274                 eEditMode = EM_MASTERPAGE;
275             }
276             break;
277 
278         case END:
279             if (bDirectionIsForward)
280             {
281                 ePageKind = PK_HANDOUT;
282                 eEditMode = EM_MASTERPAGE;
283             }
284             else
285             {
286                 ePageKind = PK_STANDARD;
287                 eEditMode = EM_PAGE;
288             }
289             break;
290 
291         case CURRENT:
292             const ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
293                 ::boost::dynamic_pointer_cast<DrawViewShell>(rpViewShell));
294             if (pDrawViewShell.get())
295             {
296                 ePageKind = pDrawViewShell->GetPageKind();
297                 eEditMode = pDrawViewShell->GetEditMode();
298             }
299             else
300             {
301                 ePageKind = PK_STANDARD;
302                 eEditMode = EM_PAGE;
303             }
304             break;
305     }
306 
307     sal_Int32 nPageIndex = GetPageIndex (pDocument, rpViewShell,
308         ePageKind, eEditMode, bDirectionIsForward, aLocation);
309 
310     return Iterator (
311         new DocumentIteratorImpl (nPageIndex, ePageKind, eEditMode,
312             pDocument, rpViewShell, bDirectionIsForward));
313 }
314 
315 sal_Int32 OutlinerContainer::GetPageIndex (
316     SdDrawDocument* pDocument,
317     const ::boost::shared_ptr<ViewShell>& rpViewShell,
318     PageKind ePageKind,
319     EditMode eEditMode,
320     bool bDirectionIsForward,
321     IteratorLocation aLocation)
322 {
323     OSL_ASSERT(rpViewShell);
324 
325     sal_Int32 nPageIndex;
326     sal_Int32 nPageCount;
327 
328     const ::boost::shared_ptr<DrawViewShell> pDrawViewShell(
329         ::boost::dynamic_pointer_cast<DrawViewShell>(rpViewShell));
330 
331     switch (eEditMode)
332     {
333         case EM_PAGE:
334             nPageCount = pDocument->GetSdPageCount (ePageKind);
335             break;
336         case EM_MASTERPAGE:
337             nPageCount = pDocument->GetMasterSdPageCount(ePageKind);
338             break;
339         default:
340             nPageCount = 0;
341     }
342 
343     switch (aLocation)
344     {
345         case CURRENT:
346             if (pDrawViewShell.get())
347                 nPageIndex = pDrawViewShell->GetCurPageId() - 1;
348             else
349             {
350                 const SdPage* pPage = rpViewShell->GetActualPage();
351                 if (pPage != NULL)
352                     nPageIndex = (pPage->GetPageNum()-1)/2;
353                 else
354                     nPageIndex = 0;
355             }
356             break;
357 
358         case BEGIN:
359         default:
360             if (bDirectionIsForward)
361                 nPageIndex = 0;
362             else
363                 nPageIndex = nPageCount-1;
364             break;
365 
366         case END:
367             if (bDirectionIsForward)
368                 nPageIndex = nPageCount;
369             else
370                 nPageIndex = -1;
371             break;
372     }
373 
374     return nPageIndex;
375 }
376 
377 
378 
379 
380 //===== IteratorImplBase ====================================================
381 
382 IteratorImplBase::IteratorImplBase(SdDrawDocument* pDocument,
383     const ::boost::weak_ptr<ViewShell>& rpViewShellWeak,
384     bool bDirectionIsForward)
385 :	maPosition()
386 ,	mpDocument (pDocument)
387 ,	mpViewShellWeak (rpViewShellWeak)
388 ,	mbDirectionIsForward (bDirectionIsForward)
389 {
390     ::boost::shared_ptr<DrawViewShell> pDrawViewShell;
391     if ( ! mpViewShellWeak.expired())
392         pDrawViewShell = ::boost::dynamic_pointer_cast<DrawViewShell>(rpViewShellWeak.lock());
393 
394     if (pDrawViewShell.get())
395     {
396         maPosition.mePageKind = pDrawViewShell->GetPageKind();
397         maPosition.meEditMode = pDrawViewShell->GetEditMode();
398     }
399     else
400     {
401         maPosition.mePageKind = PK_STANDARD;
402         maPosition.meEditMode = EM_PAGE;
403     }
404 }
405 
406 IteratorImplBase::IteratorImplBase( SdDrawDocument* pDocument,
407     const ::boost::weak_ptr<ViewShell>& rpViewShellWeak,
408     bool bDirectionIsForward, PageKind ePageKind, EditMode eEditMode)
409 : maPosition()
410 , mpDocument (pDocument)
411 , mpViewShellWeak (rpViewShellWeak)
412 , mbDirectionIsForward (bDirectionIsForward)
413 {
414     maPosition.mePageKind = ePageKind;
415     maPosition.meEditMode = eEditMode;
416 }
417 
418 IteratorImplBase::~IteratorImplBase (void)
419 {}
420 
421 bool IteratorImplBase::operator== (const IteratorImplBase& rIterator) const
422 {
423     return maPosition == rIterator.maPosition;
424 }
425 
426 bool IteratorImplBase::IsEqual (const IteratorImplBase& rIterator, IteratorType ) const
427 {
428     // When this method is executed instead of the ones from derived classes
429     // then the argument is of another type then the object itself.  In this
430     // just compare the position objects.
431     return maPosition == rIterator.maPosition;
432 }
433 
434 const IteratorPosition& IteratorImplBase::GetPosition (void)
435 {
436     return maPosition;
437 }
438 
439 
440 
441 
442 IteratorImplBase* IteratorImplBase::Clone (IteratorImplBase* pObject) const
443 {
444     if (pObject != NULL)
445     {
446         pObject->maPosition = maPosition;
447         pObject->mpDocument = mpDocument;
448         pObject->mpViewShellWeak = mpViewShellWeak;
449         pObject->mbDirectionIsForward = mbDirectionIsForward;
450     }
451     return pObject;
452 }
453 
454 
455 
456 void IteratorImplBase::Reverse (void)
457 {
458     mbDirectionIsForward = ! mbDirectionIsForward;
459 }
460 
461 
462 
463 //===== SelectionIteratorImpl ===========================================
464 
465 SelectionIteratorImpl::SelectionIteratorImpl (
466     const ::std::vector<SdrObjectWeakRef>& rObjectList,
467     sal_Int32 nObjectIndex,
468     SdDrawDocument* pDocument,
469     const ::boost::weak_ptr<ViewShell>& rpViewShellWeak,
470     bool bDirectionIsForward)
471     : IteratorImplBase (pDocument, rpViewShellWeak, bDirectionIsForward),
472       mrObjectList(rObjectList),
473       mnObjectIndex(nObjectIndex)
474 {
475 }
476 
477 SelectionIteratorImpl::~SelectionIteratorImpl (void)
478 {}
479 
480 IteratorImplBase* SelectionIteratorImpl::Clone (IteratorImplBase* pObject) const
481 {
482     SelectionIteratorImpl* pIterator = static_cast<SelectionIteratorImpl*>(pObject);
483     if (pIterator == NULL)
484         pIterator = new SelectionIteratorImpl (
485             mrObjectList, mnObjectIndex, mpDocument, mpViewShellWeak, mbDirectionIsForward);
486     return pIterator;
487 }
488 
489 
490 void SelectionIteratorImpl::GotoNextText (void)
491 {
492 	SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( mrObjectList.at(mnObjectIndex).get() );
493     if (mbDirectionIsForward)
494 	{
495 		if( pTextObj )
496 		{
497 			++maPosition.mnText;
498 			if( maPosition.mnText >= pTextObj->getTextCount() )
499 			{
500 				maPosition.mnText = 0;
501 		        ++mnObjectIndex;
502 			}
503 		}
504 		else
505 		{
506 			++mnObjectIndex;
507 		}
508 	}
509     else
510 	{
511 		if( pTextObj )
512 		{
513 			--maPosition.mnText;
514 			if( maPosition.mnText < 0 )
515 			{
516 				maPosition.mnText = -1;
517 		        --mnObjectIndex;
518 			}
519 		}
520 		else
521 		{
522 			--mnObjectIndex;
523 			maPosition.mnText = -1;
524 		}
525 
526 		if( (maPosition.mnText == -1) && (mnObjectIndex >= 0) )
527 		{
528 			pTextObj = dynamic_cast< SdrTextObj* >( mrObjectList.at(mnObjectIndex).get() );
529 			if( pTextObj )
530 				maPosition.mnText = pTextObj->getTextCount() - 1;
531 		}
532 
533 		if( maPosition.mnText == -1 )
534 			maPosition.mnText = 0;
535 	}
536 }
537 
538 
539 const IteratorPosition& SelectionIteratorImpl::GetPosition (void)
540 {
541     maPosition.mxObject = mrObjectList.at(mnObjectIndex);
542 
543     return maPosition;
544 }
545 
546 
547 bool SelectionIteratorImpl::operator== (const IteratorImplBase& rIterator) const
548 {
549     return rIterator.IsEqual (*this, SELECTION);
550 }
551 
552 
553 bool SelectionIteratorImpl::IsEqual (
554     const IteratorImplBase& rIterator,
555     IteratorType aType) const
556 {
557     if (aType == SELECTION)
558     {
559         const SelectionIteratorImpl* pSelectionIterator =
560             static_cast<const SelectionIteratorImpl*>(&rIterator);
561         return mpDocument == pSelectionIterator->mpDocument
562             && mnObjectIndex == pSelectionIterator->mnObjectIndex;
563     }
564     else
565         return false;
566 }
567 
568 
569 
570 
571 //===== ViewIteratorImpl ================================================
572 
573 ViewIteratorImpl::ViewIteratorImpl (
574     sal_Int32 nPageIndex,
575     SdDrawDocument* pDocument,
576     const ::boost::weak_ptr<ViewShell>& rpViewShellWeak,
577     bool bDirectionIsForward)
578     : IteratorImplBase (pDocument, rpViewShellWeak, bDirectionIsForward),
579       mbPageChangeOccured(false),
580       mpPage(NULL),
581       mpObjectIterator(NULL)
582 {
583     SetPage (nPageIndex);
584 }
585 
586 
587 
588 
589 ViewIteratorImpl::ViewIteratorImpl (
590     sal_Int32 nPageIndex,
591     SdDrawDocument* pDocument,
592     const ::boost::weak_ptr<ViewShell>& rpViewShellWeak,
593     bool bDirectionIsForward,
594     PageKind ePageKind,
595     EditMode eEditMode)
596     : IteratorImplBase (pDocument, rpViewShellWeak, bDirectionIsForward, ePageKind, eEditMode),
597       mbPageChangeOccured(false),
598       mpPage(NULL),
599       mpObjectIterator(NULL)
600 {
601     SetPage (nPageIndex);
602 }
603 
604 
605 
606 
607 ViewIteratorImpl::~ViewIteratorImpl (void)
608 {
609 }
610 
611 
612 
613 
614 IteratorImplBase* ViewIteratorImpl::Clone (IteratorImplBase* pObject) const
615 {
616 
617     ViewIteratorImpl* pIterator = static_cast<ViewIteratorImpl*>(pObject);
618     if (pIterator == NULL)
619         pIterator = new ViewIteratorImpl (
620             maPosition.mnPageIndex, mpDocument, mpViewShellWeak, mbDirectionIsForward);
621 
622     IteratorImplBase::Clone (pObject);
623 
624     if (mpObjectIterator != NULL)
625     {
626         pIterator->mpObjectIterator = new SdrObjListIter(*mpPage, IM_DEEPNOGROUPS, !mbDirectionIsForward);
627 
628         // No direct way to set the object iterator to the current object.
629         pIterator->maPosition.mxObject.reset(NULL);
630         while (pIterator->mpObjectIterator->IsMore() && pIterator->maPosition.mxObject!=maPosition.mxObject)
631             pIterator->maPosition.mxObject.reset(pIterator->mpObjectIterator->Next());
632     }
633     else
634         pIterator->mpObjectIterator = NULL;
635 
636     return pIterator;
637 }
638 
639 
640 
641 void ViewIteratorImpl::GotoNextText(void)
642 {
643 	SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( maPosition.mxObject.get() );
644 	if( pTextObj )
645 	{
646 	    if (mbDirectionIsForward)
647 		{
648 			++maPosition.mnText;
649 			if( maPosition.mnText < pTextObj->getTextCount() )
650 				return;
651 		}
652 		else
653 		{
654 			--maPosition.mnText;
655 			if( maPosition.mnText >= 0 )
656 				return;
657 		}
658 	}
659 
660     if (mpObjectIterator != NULL && mpObjectIterator->IsMore())
661         maPosition.mxObject.reset(mpObjectIterator->Next());
662     else
663         maPosition.mxObject.reset(NULL);
664 
665     if (!maPosition.mxObject.is() )
666     {
667         if (mbDirectionIsForward)
668             SetPage (maPosition.mnPageIndex+1);
669         else
670             SetPage (maPosition.mnPageIndex-1);
671 
672         if (mpPage != NULL)
673             mpObjectIterator = new SdrObjListIter(*mpPage, IM_DEEPNOGROUPS, !mbDirectionIsForward);
674         if (mpObjectIterator!=NULL && mpObjectIterator->IsMore())
675             maPosition.mxObject.reset(mpObjectIterator->Next());
676         else
677             maPosition.mxObject.reset(NULL);
678     }
679 
680 	maPosition.mnText = 0;
681 	if( !mbDirectionIsForward && maPosition.mxObject.is() )
682 	{
683 		pTextObj = dynamic_cast< SdrTextObj* >( maPosition.mxObject.get() );
684 		if( pTextObj )
685 			maPosition.mnText = pTextObj->getTextCount() - 1;
686 	}
687 }
688 
689 
690 
691 
692 void ViewIteratorImpl::SetPage (sal_Int32 nPageIndex)
693 {
694     mbPageChangeOccured = (maPosition.mnPageIndex!=nPageIndex);
695     if (mbPageChangeOccured)
696     {
697         maPosition.mnPageIndex = nPageIndex;
698 
699         sal_Int32 nPageCount;
700         if (maPosition.meEditMode == EM_PAGE)
701             nPageCount = mpDocument->GetSdPageCount(maPosition.mePageKind);
702         else
703             nPageCount = mpDocument->GetMasterSdPageCount(
704                 maPosition.mePageKind);
705 
706         // Get page pointer.  Here we have three cases: regular pages,
707         // master pages and invalid page indices.  The later ones are not
708         // errors but the effect of the iterator advancing to the next page
709         // and going past the last one.  This dropping of the rim at the far
710         // side is detected here and has to be reacted to by the caller.
711         if (nPageIndex>=0 && nPageIndex < nPageCount)
712         {
713             if (maPosition.meEditMode == EM_PAGE)
714                 mpPage = mpDocument->GetSdPage (
715                     (sal_uInt16)nPageIndex,
716                     maPosition.mePageKind);
717             else
718                 mpPage = mpDocument->GetMasterSdPage (
719                     (sal_uInt16)nPageIndex,
720                     maPosition.mePageKind);
721         }
722         else
723             mpPage = NULL;
724     }
725 
726     // Set up object list iterator.
727     if (mpPage != NULL)
728         mpObjectIterator = new SdrObjListIter(*mpPage, IM_DEEPNOGROUPS, ! mbDirectionIsForward);
729     else
730         mpObjectIterator = NULL;
731 
732     // Get object pointer.
733     if (mpObjectIterator!=NULL && mpObjectIterator->IsMore())
734         maPosition.mxObject.reset( mpObjectIterator->Next() );
735     else
736         maPosition.mxObject.reset( NULL );
737 
738 	maPosition.mnText = 0;
739 	if( !mbDirectionIsForward && maPosition.mxObject.is() )
740 	{
741 		SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( maPosition.mxObject.get() );
742 		if( pTextObj )
743 			maPosition.mnText = pTextObj->getTextCount() - 1;
744 	}
745 
746 }
747 
748 
749 
750 
751 void ViewIteratorImpl::Reverse (void)
752 {
753     IteratorImplBase::Reverse ();
754 
755     // Create reversed object list iterator.
756     if (mpObjectIterator != NULL)
757         delete mpObjectIterator;
758     if (mpPage != NULL)
759         mpObjectIterator = new SdrObjListIter(*mpPage, IM_DEEPNOGROUPS, ! mbDirectionIsForward);
760     else
761         mpObjectIterator = NULL;
762 
763     // Move iterator to the current object.
764     SdrObjectWeakRef xObject = maPosition.mxObject;
765     maPosition.mxObject.reset(NULL);
766     while (mpObjectIterator->IsMore() && maPosition.mxObject != xObject)
767         maPosition.mxObject.reset(mpObjectIterator->Next());
768 }
769 
770 
771 
772 
773 //===== DocumentIteratorImpl ============================================
774 
775 DocumentIteratorImpl::DocumentIteratorImpl (
776     sal_Int32 nPageIndex,
777     PageKind ePageKind, EditMode eEditMode,
778     SdDrawDocument* pDocument,
779     const ::boost::weak_ptr<ViewShell>& rpViewShellWeak,
780     bool bDirectionIsForward)
781     : ViewIteratorImpl (nPageIndex, pDocument, rpViewShellWeak, bDirectionIsForward,
782         ePageKind, eEditMode)
783 {
784     if (eEditMode == EM_PAGE)
785         mnPageCount = pDocument->GetSdPageCount (ePageKind);
786     else
787         mnPageCount = pDocument->GetMasterSdPageCount(ePageKind);
788 }
789 
790 
791 
792 
793 DocumentIteratorImpl::~DocumentIteratorImpl (void)
794 {}
795 
796 
797 
798 
799 IteratorImplBase* DocumentIteratorImpl::Clone (IteratorImplBase* pObject) const
800 {
801     DocumentIteratorImpl* pIterator = static_cast<DocumentIteratorImpl*>(pObject);
802     if (pIterator == NULL)
803         pIterator = new DocumentIteratorImpl (
804             maPosition.mnPageIndex, maPosition.mePageKind, maPosition.meEditMode,
805             mpDocument, mpViewShellWeak, mbDirectionIsForward);
806     // Finish the cloning.
807     return ViewIteratorImpl::Clone (pIterator);
808 }
809 
810 
811 
812 
813 void DocumentIteratorImpl::GotoNextText (void)
814 {
815     bool bSetToOnePastLastPage = false;
816     bool bViewChanged = false;
817 
818     ViewIteratorImpl::GotoNextText();
819 
820     if (mbDirectionIsForward)
821     {
822         if (maPosition.mnPageIndex >= mnPageCount)
823         {
824             // Switch to master page.
825             if (maPosition.meEditMode == EM_PAGE)
826             {
827                 maPosition.meEditMode = EM_MASTERPAGE;
828                 SetPage (0);
829             }
830 
831             // Switch to next view mode.
832             else
833             {
834                 if (maPosition.mePageKind == PK_HANDOUT)
835                     // Not really necessary but makes things more clear.
836                     bSetToOnePastLastPage = true;
837                 else
838                 {
839                     maPosition.meEditMode = EM_PAGE;
840                     if (maPosition.mePageKind == PK_STANDARD)
841                         maPosition.mePageKind = PK_NOTES;
842                     else if (maPosition.mePageKind == PK_NOTES)
843                         maPosition.mePageKind = PK_HANDOUT;
844                     SetPage (0);
845                 }
846             }
847             bViewChanged = true;
848         }
849     }
850     else
851         if (maPosition.mnPageIndex < 0)
852         {
853             // Switch from master pages to draw pages.
854             if (maPosition.meEditMode == EM_MASTERPAGE)
855             {
856                 maPosition.meEditMode = EM_PAGE;
857                 bSetToOnePastLastPage = true;
858             }
859 
860             // Switch to previous view mode.
861             else
862             {
863                 if (maPosition.mePageKind == PK_STANDARD)
864                     SetPage (-1);
865                 else
866                 {
867                     maPosition.meEditMode = EM_MASTERPAGE;
868                     if (maPosition.mePageKind == PK_HANDOUT)
869                         maPosition.mePageKind = PK_NOTES;
870                     else if (maPosition.mePageKind == PK_NOTES)
871                         maPosition.mePageKind = PK_STANDARD;
872                     bSetToOnePastLastPage = true;
873                 }
874             }
875             bViewChanged = true;
876         }
877 
878     if (bViewChanged)
879     {
880         // Get new page count;
881         sal_Int32 nPageCount;
882         if (maPosition.meEditMode == EM_PAGE)
883             nPageCount = mpDocument->GetSdPageCount (maPosition.mePageKind);
884         else
885             nPageCount = mpDocument->GetMasterSdPageCount(maPosition.mePageKind);
886 
887         // Now that we know the number of pages we can set the current page index.
888         if (bSetToOnePastLastPage)
889             SetPage (nPageCount);
890     }
891 }
892 
893 
894 } } // end of namespace ::sd::outliner
895