Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/view/OutlinerIterator.cxx
Line
Count
Source
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 <OutlinerIterator.hxx>
21
#include <OutlinerIteratorImpl.hxx>
22
#include <svx/svditer.hxx>
23
#include <tools/debug.hxx>
24
#include <osl/diagnose.h>
25
#include <Outliner.hxx>
26
27
#include <drawdoc.hxx>
28
#include <DrawViewShell.hxx>
29
#include <sdpage.hxx>
30
#include <utility>
31
#include <ViewShellBase.hxx>
32
#include <ViewShellManager.hxx>
33
34
namespace sd::outliner {
35
36
//===== IteratorPosition ======================================================
37
38
IteratorPosition::IteratorPosition()
39
72.1k
: mnText(0)
40
72.1k
, mnPageIndex(-1)
41
72.1k
, mePageKind(PageKind::Standard)
42
72.1k
, meEditMode(EditMode::Page)
43
72.1k
{
44
72.1k
}
45
46
bool IteratorPosition::operator== (const IteratorPosition& aPosition) const
47
0
{
48
0
    return mxObject.get() == aPosition.mxObject.get()
49
0
        && mnText == aPosition.mnText
50
0
        && mnPageIndex == aPosition.mnPageIndex
51
0
        && mePageKind == aPosition.mePageKind
52
0
        && meEditMode == aPosition.meEditMode;
53
0
}
54
55
//===== Iterator ==============================================================
56
57
Iterator::Iterator()
58
72.1k
{
59
72.1k
}
60
61
Iterator::Iterator (const Iterator& rIterator)
62
0
    : mxIterator(rIterator.mxIterator ? rIterator.mxIterator->Clone() : nullptr)
63
0
{
64
0
}
65
66
Iterator::Iterator(Iterator&& rIterator) noexcept
67
0
    : mxIterator(std::move(rIterator.mxIterator))
68
0
{
69
0
}
70
71
Iterator::Iterator (std::unique_ptr<IteratorImplBase> pObject)
72
0
    : mxIterator(std::move(pObject))
73
0
{
74
0
}
75
76
Iterator::~Iterator()
77
72.1k
{
78
72.1k
}
79
80
Iterator& Iterator::operator= (const Iterator& rIterator)
81
0
{
82
0
    if (this != &rIterator)
83
0
    {
84
0
        if (rIterator.mxIterator)
85
0
            mxIterator.reset(rIterator.mxIterator->Clone());
86
0
        else
87
0
            mxIterator.reset();
88
0
    }
89
0
    return *this;
90
0
}
91
92
Iterator& Iterator::operator=(Iterator&& rIterator) noexcept
93
0
{
94
0
    mxIterator = std::move(rIterator.mxIterator);
95
0
    return *this;
96
0
}
97
98
const IteratorPosition& Iterator::operator* () const
99
0
{
100
0
    DBG_ASSERT (mxIterator, "::sd::outliner::Iterator::operator* : missing implementation object");
101
0
    return mxIterator->GetPosition();
102
0
}
103
104
Iterator& Iterator::operator++ ()
105
0
{
106
0
    if (mxIterator)
107
0
        mxIterator->GotoNextText();
108
0
    return *this;
109
0
}
110
111
bool Iterator::operator== (const Iterator& rIterator) const
112
0
{
113
0
    if (!mxIterator || !rIterator.mxIterator)
114
0
        return mxIterator.get() == rIterator.mxIterator.get();
115
0
    else
116
0
        return *mxIterator == *rIterator.mxIterator;
117
0
}
118
119
bool Iterator::operator!= (const Iterator& rIterator) const
120
0
{
121
0
    return ! operator==(rIterator);
122
0
}
123
124
void Iterator::Reverse()
125
0
{
126
0
    if (mxIterator)
127
0
        mxIterator->Reverse();
128
0
}
129
130
//===== IteratorFactory =======================================================
131
132
OutlinerContainer::OutlinerContainer (SdOutliner* pOutliner)
133
0
: mpOutliner(pOutliner)
134
0
{
135
0
}
136
137
Iterator OutlinerContainer::begin()
138
0
{
139
0
    return CreateIterator (BEGIN);
140
0
}
141
142
Iterator OutlinerContainer::end()
143
0
{
144
0
    return CreateIterator (END);
145
0
}
146
147
Iterator OutlinerContainer::current()
148
0
{
149
0
    return CreateIterator (CURRENT);
150
0
}
151
152
Iterator OutlinerContainer::CreateIterator (IteratorLocation aLocation)
153
0
{
154
0
    std::shared_ptr<sd::ViewShell> pOverridingShell{};
155
0
    if (auto pBase = dynamic_cast<sd::ViewShellBase*>(SfxViewShell::Current()))
156
0
        if (auto pViewShellManager = pBase->GetViewShellManager())
157
0
            pOverridingShell = pViewShellManager->GetOverridingMainShell();
158
159
    // Decide on certain features of the outliner which kind of iterator to
160
    // use.
161
0
    if (mpOutliner->mbRestrictSearchToSelection)
162
        // There is a selection.  Search only in this.
163
0
        return CreateSelectionIterator (
164
0
            mpOutliner->maMarkListCopy,
165
0
            &mpOutliner->mrDrawDocument,
166
0
            pOverridingShell ? std::move(pOverridingShell) :
167
0
            mpOutliner->mpWeakViewShell.lock(),
168
0
            mpOutliner->mbDirectionIsForward,
169
0
            aLocation);
170
0
    else
171
        // Search in the whole document.
172
0
        return CreateDocumentIterator (
173
0
            &mpOutliner->mrDrawDocument,
174
0
            pOverridingShell ? std::move(pOverridingShell) :
175
0
            mpOutliner->mpWeakViewShell.lock(),
176
0
            mpOutliner->mbDirectionIsForward,
177
0
            aLocation);
178
0
}
179
180
Iterator OutlinerContainer::CreateSelectionIterator (
181
    const ::std::vector<::unotools::WeakReference<SdrObject>>& rObjectList,
182
    SdDrawDocument* pDocument,
183
    const std::shared_ptr<ViewShell>& rpViewShell,
184
    bool bDirectionIsForward,
185
    IteratorLocation aLocation)
186
0
{
187
0
    OSL_ASSERT(rpViewShell);
188
189
0
    sal_Int32 nObjectIndex;
190
191
0
    if (bDirectionIsForward)
192
0
        switch (aLocation)
193
0
        {
194
0
            case CURRENT:
195
0
            case BEGIN:
196
0
            default:
197
0
                nObjectIndex = 0;
198
0
                break;
199
0
            case END:
200
0
                nObjectIndex = rObjectList.size();
201
0
                break;
202
0
        }
203
0
    else
204
0
        switch (aLocation)
205
0
        {
206
0
            case CURRENT:
207
0
            case BEGIN:
208
0
            default:
209
0
                nObjectIndex = rObjectList.size()-1;
210
0
                break;
211
0
            case END:
212
0
                nObjectIndex = -1;
213
0
                break;
214
0
        }
215
216
0
    return Iterator (std::make_unique<SelectionIteratorImpl> (
217
0
        rObjectList, nObjectIndex, pDocument, rpViewShell, bDirectionIsForward));
218
0
}
219
220
Iterator OutlinerContainer::CreateDocumentIterator (
221
    SdDrawDocument* pDocument,
222
    const std::shared_ptr<ViewShell>& rpViewShell,
223
    bool bDirectionIsForward,
224
    IteratorLocation aLocation)
225
0
{
226
0
    OSL_ASSERT(rpViewShell);
227
228
0
    PageKind ePageKind;
229
0
    EditMode eEditMode;
230
231
0
    switch (aLocation)
232
0
    {
233
0
        case BEGIN:
234
0
        default:
235
0
            if (bDirectionIsForward)
236
0
            {
237
0
                ePageKind = PageKind::Standard;
238
0
                eEditMode = EditMode::Page;
239
0
            }
240
0
            else
241
0
            {
242
0
                ePageKind = PageKind::Handout;
243
0
                eEditMode = EditMode::MasterPage;
244
0
            }
245
0
            break;
246
247
0
        case END:
248
0
            if (bDirectionIsForward)
249
0
            {
250
0
                ePageKind = PageKind::Handout;
251
0
                eEditMode = EditMode::MasterPage;
252
0
            }
253
0
            else
254
0
            {
255
0
                ePageKind = PageKind::Standard;
256
0
                eEditMode = EditMode::Page;
257
0
            }
258
0
            break;
259
260
0
        case CURRENT:
261
0
            const std::shared_ptr<DrawViewShell> pDrawViewShell(
262
0
                std::dynamic_pointer_cast<DrawViewShell>(rpViewShell));
263
0
            if (pDrawViewShell)
264
0
            {
265
0
                ePageKind = pDrawViewShell->GetPageKind();
266
0
                eEditMode = pDrawViewShell->GetEditMode();
267
0
            }
268
0
            else
269
0
            {
270
0
                auto pPage = rpViewShell->getCurrentPage();
271
0
                ePageKind =  pPage ? pPage->GetPageKind() : PageKind::Standard;
272
0
                eEditMode = EditMode::Page;
273
0
            }
274
0
            break;
275
0
    }
276
277
0
    sal_Int32 nPageIndex = GetPageIndex (pDocument, rpViewShell,
278
0
        ePageKind, eEditMode, bDirectionIsForward, aLocation);
279
280
0
    return Iterator (
281
0
        std::make_unique<DocumentIteratorImpl> (nPageIndex, ePageKind, eEditMode,
282
0
            pDocument, rpViewShell, bDirectionIsForward));
283
0
}
284
285
sal_Int32 OutlinerContainer::GetPageIndex (
286
    SdDrawDocument const * pDocument,
287
    const std::shared_ptr<ViewShell>& rpViewShell,
288
    PageKind ePageKind,
289
    EditMode eEditMode,
290
    bool bDirectionIsForward,
291
    IteratorLocation aLocation)
292
0
{
293
0
    OSL_ASSERT(rpViewShell);
294
295
0
    sal_Int32 nPageIndex;
296
0
    sal_Int32 nPageCount;
297
298
0
    const std::shared_ptr<DrawViewShell> pDrawViewShell(
299
0
        std::dynamic_pointer_cast<DrawViewShell>(rpViewShell));
300
301
0
    switch (eEditMode)
302
0
    {
303
0
        case EditMode::Page:
304
0
            nPageCount = pDocument->GetSdPageCount (ePageKind);
305
0
            break;
306
0
        case EditMode::MasterPage:
307
0
            nPageCount = pDocument->GetMasterSdPageCount(ePageKind);
308
0
            break;
309
0
        default:
310
0
            nPageCount = 0;
311
0
    }
312
313
0
    switch (aLocation)
314
0
    {
315
0
        case CURRENT:
316
0
            if (pDrawViewShell)
317
0
                nPageIndex = pDrawViewShell->GetCurPagePos();
318
0
            else
319
0
            {
320
0
                const SdPage* pPage = rpViewShell->GetActualPage();
321
0
                if (pPage != nullptr)
322
0
                    nPageIndex = (pPage->GetPageNum()-1)/2;
323
0
                else
324
0
                    nPageIndex = 0;
325
0
            }
326
0
            break;
327
328
0
        case BEGIN:
329
0
        default:
330
0
            if (bDirectionIsForward)
331
0
                nPageIndex = 0;
332
0
            else
333
0
                nPageIndex = nPageCount-1;
334
0
            break;
335
336
0
        case END:
337
0
            if (bDirectionIsForward)
338
0
                nPageIndex = nPageCount;
339
0
            else
340
0
                nPageIndex = -1;
341
0
            break;
342
0
    }
343
344
0
    return nPageIndex;
345
0
}
346
347
//===== IteratorImplBase ====================================================
348
349
IteratorImplBase::IteratorImplBase(SdDrawDocument* pDocument,
350
    const std::weak_ptr<ViewShell>& rpViewShellWeak,
351
    bool bDirectionIsForward)
352
0
:   mpDocument (pDocument)
353
0
,   mpViewShellWeak (rpViewShellWeak)
354
0
,   mbDirectionIsForward (bDirectionIsForward)
355
0
{
356
0
    std::shared_ptr<DrawViewShell> pDrawViewShell;
357
0
    if ( ! mpViewShellWeak.expired())
358
0
        pDrawViewShell = std::dynamic_pointer_cast<DrawViewShell>(rpViewShellWeak.lock());
359
360
0
    if (pDrawViewShell)
361
0
    {
362
0
        maPosition.mePageKind = pDrawViewShell->GetPageKind();
363
0
        maPosition.meEditMode = pDrawViewShell->GetEditMode();
364
0
    }
365
0
    else
366
0
    {
367
0
        maPosition.mePageKind = PageKind::Standard;
368
0
        maPosition.meEditMode = EditMode::Page;
369
0
    }
370
0
}
371
372
IteratorImplBase::IteratorImplBase( SdDrawDocument* pDocument,
373
    std::weak_ptr<ViewShell> pViewShellWeak,
374
    bool bDirectionIsForward, PageKind ePageKind, EditMode eEditMode)
375
0
: mpDocument (pDocument)
376
0
, mpViewShellWeak (std::move(pViewShellWeak))
377
0
, mbDirectionIsForward (bDirectionIsForward)
378
0
{
379
0
    maPosition.mePageKind = ePageKind;
380
0
    maPosition.meEditMode = eEditMode;
381
0
}
382
383
IteratorImplBase::~IteratorImplBase()
384
0
{}
385
386
bool IteratorImplBase::operator== (const IteratorImplBase& rIterator) const
387
0
{
388
0
    return maPosition == rIterator.maPosition;
389
0
}
390
391
bool IteratorImplBase::IsEqualSelection(const IteratorImplBase& rIterator) const
392
0
{
393
    // When this method is executed instead of the ones from derived classes
394
    // then the argument is of another type then the object itself.  In this
395
    // just compare the position objects.
396
0
    return maPosition == rIterator.maPosition;
397
0
}
398
399
const IteratorPosition& IteratorImplBase::GetPosition()
400
0
{
401
0
    return maPosition;
402
0
}
403
404
IteratorImplBase* IteratorImplBase::Clone (IteratorImplBase* pObject) const
405
0
{
406
0
    if (pObject != nullptr)
407
0
    {
408
0
        pObject->maPosition = maPosition;
409
0
        pObject->mpDocument = mpDocument;
410
0
        pObject->mpViewShellWeak = mpViewShellWeak;
411
0
        pObject->mbDirectionIsForward = mbDirectionIsForward;
412
0
    }
413
0
    return pObject;
414
0
}
415
416
void IteratorImplBase::Reverse()
417
0
{
418
0
    mbDirectionIsForward = ! mbDirectionIsForward;
419
0
}
420
421
//===== SelectionIteratorImpl ===========================================
422
423
SelectionIteratorImpl::SelectionIteratorImpl (
424
    const ::std::vector<::unotools::WeakReference<SdrObject>>& rObjectList,
425
    sal_Int32 nObjectIndex,
426
    SdDrawDocument* pDocument,
427
    const std::weak_ptr<ViewShell>& rpViewShellWeak,
428
    bool bDirectionIsForward)
429
0
    : IteratorImplBase (pDocument, rpViewShellWeak, bDirectionIsForward),
430
0
      mrObjectList(rObjectList),
431
0
      mnObjectIndex(nObjectIndex)
432
0
{
433
0
}
434
435
SelectionIteratorImpl::~SelectionIteratorImpl()
436
{}
437
438
IteratorImplBase* SelectionIteratorImpl::Clone (IteratorImplBase* pObject) const
439
0
{
440
0
    SelectionIteratorImpl* pIterator = static_cast<SelectionIteratorImpl*>(pObject);
441
0
    if (pIterator == nullptr)
442
0
        pIterator = new SelectionIteratorImpl (
443
0
            mrObjectList, mnObjectIndex, mpDocument, mpViewShellWeak, mbDirectionIsForward);
444
0
    return pIterator;
445
0
}
446
447
void SelectionIteratorImpl::GotoNextText()
448
0
{
449
0
    SdrTextObj* pTextObj = DynCastSdrTextObj( mrObjectList.at(mnObjectIndex).get().get() );
450
0
    if (mbDirectionIsForward)
451
0
    {
452
0
        if( pTextObj )
453
0
        {
454
0
            ++maPosition.mnText;
455
0
            if( maPosition.mnText >= pTextObj->getTextCount() )
456
0
            {
457
0
                maPosition.mnText = 0;
458
0
                ++mnObjectIndex;
459
0
            }
460
0
        }
461
0
        else
462
0
        {
463
0
            ++mnObjectIndex;
464
0
        }
465
0
    }
466
0
    else
467
0
    {
468
0
        if( pTextObj )
469
0
        {
470
0
            --maPosition.mnText;
471
0
            if( maPosition.mnText < 0 )
472
0
            {
473
0
                maPosition.mnText = -1;
474
0
                --mnObjectIndex;
475
0
            }
476
0
        }
477
0
        else
478
0
        {
479
0
            --mnObjectIndex;
480
0
            maPosition.mnText = -1;
481
0
        }
482
483
0
        if( (maPosition.mnText == -1) && (mnObjectIndex >= 0) )
484
0
        {
485
0
            pTextObj = DynCastSdrTextObj( mrObjectList.at(mnObjectIndex).get().get() );
486
0
            if( pTextObj )
487
0
                maPosition.mnText = pTextObj->getTextCount() - 1;
488
0
        }
489
490
0
        if( maPosition.mnText == -1 )
491
0
            maPosition.mnText = 0;
492
0
    }
493
0
}
494
495
const IteratorPosition& SelectionIteratorImpl::GetPosition()
496
0
{
497
0
    maPosition.mxObject = mrObjectList.at(mnObjectIndex);
498
499
0
    return maPosition;
500
0
}
501
502
bool SelectionIteratorImpl::operator== (const IteratorImplBase& rIterator) const
503
0
{
504
0
    return rIterator.IsEqualSelection(*this);
505
0
}
506
507
bool SelectionIteratorImpl::IsEqualSelection(const IteratorImplBase& rIterator) const
508
0
{
509
0
    const SelectionIteratorImpl* pSelectionIterator =
510
0
        static_cast<const SelectionIteratorImpl*>(&rIterator);
511
0
    return mpDocument == pSelectionIterator->mpDocument
512
0
        && mnObjectIndex == pSelectionIterator->mnObjectIndex;
513
0
}
514
515
void DocumentIteratorImpl::SetPage(sal_Int32 nPageIndex)
516
0
{
517
0
    maPosition.mnPageIndex = nPageIndex;
518
519
0
    sal_Int32 nPageCount;
520
0
    if (maPosition.meEditMode == EditMode::Page)
521
0
        nPageCount = mpDocument->GetSdPageCount(maPosition.mePageKind);
522
0
    else
523
0
        nPageCount = mpDocument->GetMasterSdPageCount(
524
0
            maPosition.mePageKind);
525
526
    // Get page pointer.  Here we have three cases: regular pages,
527
    // master pages and invalid page indices.  The later ones are not
528
    // errors but the effect of the iterator advancing to the next page
529
    // and going past the last one.  This dropping of the rim at the far
530
    // side is detected here and has to be reacted to by the caller.
531
0
    if (nPageIndex>=0 && nPageIndex < nPageCount)
532
0
    {
533
0
        if (maPosition.meEditMode == EditMode::Page)
534
0
            mpPage = mpDocument->GetSdPage (
535
0
                static_cast<sal_uInt16>(nPageIndex),
536
0
                maPosition.mePageKind);
537
0
        else
538
0
            mpPage = mpDocument->GetMasterSdPage (
539
0
                static_cast<sal_uInt16>(nPageIndex),
540
0
                maPosition.mePageKind);
541
0
    }
542
0
    else
543
0
        mpPage = nullptr;
544
545
    // Set up object list iterator.
546
0
    if (mpPage != nullptr)
547
0
        moObjectIterator.emplace(mpPage, SdrIterMode::DeepNoGroups, ! mbDirectionIsForward);
548
0
    else
549
0
        moObjectIterator.reset();
550
551
    // Get object pointer.
552
0
    if (moObjectIterator && moObjectIterator->IsMore())
553
0
        maPosition.mxObject = moObjectIterator->Next();
554
0
    else
555
0
        maPosition.mxObject = nullptr;
556
557
0
    maPosition.mnText = 0;
558
0
    if( !mbDirectionIsForward && maPosition.mxObject.get().is() )
559
0
    {
560
0
        SdrTextObj* pTextObj = DynCastSdrTextObj( maPosition.mxObject.get().get() );
561
0
        if( pTextObj )
562
0
            maPosition.mnText = pTextObj->getTextCount() - 1;
563
0
    }
564
565
0
}
566
567
void DocumentIteratorImpl::Reverse()
568
0
{
569
0
    IteratorImplBase::Reverse ();
570
571
    // Create reversed object list iterator.
572
0
    if (mpPage != nullptr)
573
0
        moObjectIterator.emplace(mpPage, SdrIterMode::DeepNoGroups, ! mbDirectionIsForward);
574
0
    else
575
0
        moObjectIterator.reset();
576
577
    // Move iterator to the current object.
578
0
    ::unotools::WeakReference<SdrObject> xObject = std::move(maPosition.mxObject);
579
0
    maPosition.mxObject = nullptr;
580
581
0
    if (!moObjectIterator)
582
0
        return;
583
584
0
    while (moObjectIterator->IsMore() && maPosition.mxObject.get() != xObject.get())
585
0
        maPosition.mxObject = moObjectIterator->Next();
586
0
}
587
588
//===== DocumentIteratorImpl ============================================
589
590
DocumentIteratorImpl::DocumentIteratorImpl (
591
    sal_Int32 nPageIndex,
592
    PageKind ePageKind, EditMode eEditMode,
593
    SdDrawDocument* pDocument,
594
    const std::weak_ptr<ViewShell>& rpViewShellWeak,
595
    bool bDirectionIsForward)
596
0
    : IteratorImplBase (pDocument, rpViewShellWeak, bDirectionIsForward, ePageKind, eEditMode)
597
0
    , mpPage(nullptr)
598
0
{
599
0
    if (eEditMode == EditMode::Page)
600
0
        mnPageCount = pDocument->GetSdPageCount (ePageKind);
601
0
    else
602
0
        mnPageCount = pDocument->GetMasterSdPageCount(ePageKind);
603
0
    SetPage(nPageIndex);
604
0
}
605
606
DocumentIteratorImpl::~DocumentIteratorImpl()
607
0
{}
608
609
IteratorImplBase* DocumentIteratorImpl::Clone (IteratorImplBase* pObject) const
610
0
{
611
0
    DocumentIteratorImpl* pIterator = static_cast<DocumentIteratorImpl*>(pObject);
612
0
    if (pIterator == nullptr)
613
0
        pIterator = new DocumentIteratorImpl (
614
0
            maPosition.mnPageIndex, maPosition.mePageKind, maPosition.meEditMode,
615
0
            mpDocument, mpViewShellWeak, mbDirectionIsForward);
616
    // Finish the cloning.
617
0
    IteratorImplBase::Clone (pObject);
618
619
0
    if (moObjectIterator)
620
0
    {
621
0
        pIterator->moObjectIterator.emplace(mpPage, SdrIterMode::DeepNoGroups, !mbDirectionIsForward);
622
623
        // No direct way to set the object iterator to the current object.
624
0
        pIterator->maPosition.mxObject = nullptr;
625
0
        while (pIterator->moObjectIterator->IsMore() && pIterator->maPosition.mxObject.get()!=maPosition.mxObject.get())
626
0
            pIterator->maPosition.mxObject = pIterator->moObjectIterator->Next();
627
0
    }
628
0
    else
629
0
        pIterator->moObjectIterator.reset();
630
631
0
    return pIterator;
632
0
}
633
634
void DocumentIteratorImpl::GotoNextText()
635
0
{
636
0
    bool bSetToOnePastLastPage = false;
637
0
    bool bViewChanged = false;
638
639
0
    SdrTextObj* pTextObj = DynCastSdrTextObj( maPosition.mxObject.get().get() );
640
0
    if( pTextObj )
641
0
    {
642
0
        if (mbDirectionIsForward)
643
0
        {
644
0
            ++maPosition.mnText;
645
0
            if( maPosition.mnText < pTextObj->getTextCount() )
646
0
                return;
647
0
        }
648
0
        else
649
0
        {
650
0
            --maPosition.mnText;
651
0
            if( maPosition.mnText >= 0 )
652
0
                return;
653
0
       }
654
0
    }
655
656
0
    if (moObjectIterator && moObjectIterator->IsMore())
657
0
        maPosition.mxObject = moObjectIterator->Next();
658
0
    else
659
0
        maPosition.mxObject = nullptr;
660
661
0
    if (!maPosition.mxObject.get().is() )
662
0
    {
663
0
        if (maPosition.meEditMode == EditMode::Page
664
0
            && maPosition.mePageKind == PageKind::Standard)
665
0
        {
666
0
            maPosition.mePageKind = PageKind::Notes;
667
0
            if (mbDirectionIsForward)
668
0
                SetPage(maPosition.mnPageIndex);
669
0
            else
670
0
                SetPage(maPosition.mnPageIndex - 1);
671
0
        }
672
0
        else if (maPosition.meEditMode == EditMode::Page
673
0
                 && maPosition.mePageKind == PageKind::Notes)
674
0
        {
675
0
            maPosition.mePageKind = PageKind::Standard;
676
0
            if (mbDirectionIsForward)
677
0
                SetPage(maPosition.mnPageIndex + 1);
678
0
            else
679
0
                SetPage(maPosition.mnPageIndex);
680
0
        }
681
0
        else
682
0
        {
683
0
            if (mbDirectionIsForward)
684
0
                SetPage(maPosition.mnPageIndex + 1);
685
0
            else
686
0
                SetPage(maPosition.mnPageIndex - 1);
687
0
        }
688
689
0
        if (mpPage != nullptr)
690
0
            moObjectIterator.emplace( mpPage, SdrIterMode::DeepNoGroups, !mbDirectionIsForward );
691
0
        if (moObjectIterator && moObjectIterator->IsMore())
692
0
            maPosition.mxObject = moObjectIterator->Next();
693
0
        else
694
0
            maPosition.mxObject = nullptr;
695
0
    }
696
697
0
    maPosition.mnText = 0;
698
0
    if( !mbDirectionIsForward && maPosition.mxObject.get().is() )
699
0
    {
700
0
        pTextObj = DynCastSdrTextObj( maPosition.mxObject.get().get() );
701
0
        if( pTextObj )
702
0
            maPosition.mnText = pTextObj->getTextCount() - 1;
703
0
    }
704
705
706
0
    if (mbDirectionIsForward)
707
0
    {
708
0
        if (maPosition.mnPageIndex >= mnPageCount)
709
0
        {
710
            // Switch to master page.
711
0
            if (maPosition.meEditMode == EditMode::Page)
712
0
            {
713
0
                maPosition.meEditMode = EditMode::MasterPage;
714
0
                SetPage (0);
715
0
            }
716
            // Switch to next view mode.
717
0
            else
718
0
            {
719
0
                if (maPosition.mePageKind == PageKind::Handout)
720
0
                {
721
                    // search wrapped
722
0
                    bSetToOnePastLastPage = true;
723
0
                }
724
0
                else if (maPosition.mePageKind == PageKind::Standard)
725
0
                {
726
                    // switch to master notes
727
0
                    maPosition.mePageKind = PageKind::Notes;
728
0
                    SetPage(0);
729
0
                }
730
0
                else if (maPosition.mePageKind == PageKind::Notes)
731
0
                {
732
                    // switch to master handout
733
0
                    maPosition.mePageKind = PageKind::Handout;
734
0
                    SetPage(0);
735
0
                }
736
0
            }
737
0
            bViewChanged = true;
738
0
        }
739
0
    }
740
0
    else
741
0
    {
742
0
        if (maPosition.mnPageIndex < 0)
743
0
        {
744
0
            if (maPosition.meEditMode == EditMode::MasterPage)
745
0
            {
746
0
                if (maPosition.mePageKind == PageKind::Standard)
747
0
                {
748
0
                    maPosition.meEditMode = EditMode::Page;
749
0
                    maPosition.mePageKind = PageKind::Notes;
750
0
                    bSetToOnePastLastPage = true;
751
0
                }
752
0
                else if (maPosition.mePageKind == PageKind::Handout)
753
0
                {
754
0
                    maPosition.mePageKind = PageKind::Notes;
755
0
                    bSetToOnePastLastPage = true;
756
0
                }
757
0
                else if (maPosition.mePageKind == PageKind::Notes)
758
0
                {
759
0
                    maPosition.mePageKind = PageKind::Standard;
760
0
                    bSetToOnePastLastPage = true;
761
0
                }
762
0
            }
763
0
            else
764
0
            {
765
                // search wrapped
766
0
                SetPage(-1);
767
0
            }
768
0
        }
769
0
        bViewChanged = true;
770
0
    }
771
772
0
    if (!bViewChanged)
773
0
        return;
774
775
    // Get new page count;
776
0
    if (maPosition.meEditMode == EditMode::Page)
777
0
        mnPageCount = mpDocument->GetSdPageCount (maPosition.mePageKind);
778
0
    else
779
0
        mnPageCount = mpDocument->GetMasterSdPageCount(maPosition.mePageKind);
780
781
    // Now that we know the number of pages we can set the current page index.
782
0
    if (bSetToOnePastLastPage)
783
0
        SetPage (mnPageCount);
784
0
}
785
786
} // end of namespace ::sd::outliner
787
788
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */