Coverage Report

Created: 2026-05-16 09:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/view/prevloc.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 <prevloc.hxx>
21
#include <document.hxx>
22
23
#include <o3tl/unit_conversion.hxx>
24
#include <osl/diagnose.h>
25
#include <vcl/outdev.hxx>
26
27
namespace {
28
29
enum ScPreviewLocationType : sal_uInt8
30
{
31
    SC_PLOC_CELLRANGE,
32
    SC_PLOC_COLHEADER,
33
    SC_PLOC_ROWHEADER,
34
    SC_PLOC_LEFTHEADER,
35
    SC_PLOC_RIGHTHEADER,
36
    SC_PLOC_LEFTFOOTER,
37
    SC_PLOC_RIGHTFOOTER,
38
    SC_PLOC_NOTEMARK,
39
    SC_PLOC_NOTETEXT
40
};
41
42
}
43
44
struct ScPreviewLocationEntry
45
{
46
    tools::Rectangle         aPixelRect;
47
    ScRange                 aCellRange;
48
    ScPreviewLocationType   eType;
49
    bool                    bRepeatCol;
50
    bool                    bRepeatRow;
51
52
    ScPreviewLocationEntry( ScPreviewLocationType eNewType, const tools::Rectangle& rPixel, const ScRange& rRange,
53
                            bool bRepCol, bool bRepRow ) :
54
0
        aPixelRect( rPixel ),
55
0
        aCellRange( rRange ),
56
0
        eType( eNewType ),
57
0
        bRepeatCol( bRepCol ),
58
0
        bRepeatRow( bRepRow )
59
0
    {
60
0
    }
61
};
62
63
ScPreviewTableInfo::ScPreviewTableInfo() :
64
0
    nTab(0),
65
0
    nCols(0),
66
0
    nRows(0)
67
0
{
68
0
}
69
70
ScPreviewTableInfo::~ScPreviewTableInfo()
71
0
{
72
0
}
73
74
void ScPreviewTableInfo::SetTab( SCTAB nNewTab )
75
0
{
76
0
    nTab = nNewTab;
77
0
}
78
79
void ScPreviewTableInfo::SetColInfo( SCCOL nCount, ScPreviewColRowInfo* pNewInfo )
80
0
{
81
0
    pColInfo.reset(pNewInfo);
82
0
    nCols = nCount;
83
0
}
84
85
void ScPreviewTableInfo::SetRowInfo( SCROW nCount, ScPreviewColRowInfo* pNewInfo )
86
0
{
87
0
    pRowInfo.reset(pNewInfo);
88
0
    nRows = nCount;
89
0
}
90
91
void ScPreviewTableInfo::LimitToArea( const tools::Rectangle& rPixelArea )
92
0
{
93
0
    if ( pColInfo )
94
0
    {
95
        //  cells completely left of the visible area
96
0
        SCCOL nStart = 0;
97
0
        while ( nStart < nCols && pColInfo[nStart].nPixelEnd < rPixelArea.Left() )
98
0
            ++nStart;
99
100
        //  cells completely right of the visible area
101
0
        SCCOL nEnd = nCols;
102
0
        while ( nEnd > 0 && pColInfo[nEnd-1].nPixelStart > rPixelArea.Right() )
103
0
            --nEnd;
104
105
0
        if ( nStart > 0 || nEnd < nCols )
106
0
        {
107
0
            if ( nEnd > nStart )
108
0
            {
109
0
                SCCOL nNewCount = nEnd - nStart;
110
0
                ScPreviewColRowInfo* pNewInfo = new ScPreviewColRowInfo[nNewCount];
111
0
                for (SCCOL i=0; i<nNewCount; i++)
112
0
                    pNewInfo[i] = pColInfo[nStart + i];
113
0
                SetColInfo( nNewCount, pNewInfo );
114
0
            }
115
0
            else
116
0
                SetColInfo( 0, nullptr );      // all invisible
117
0
        }
118
0
    }
119
120
0
    if ( !pRowInfo )
121
0
        return;
122
123
    //  cells completely above the visible area
124
0
    SCROW nStart = 0;
125
0
    while ( nStart < nRows && pRowInfo[nStart].nPixelEnd < rPixelArea.Top() )
126
0
        ++nStart;
127
128
    //  cells completely below the visible area
129
0
    SCROW nEnd = nRows;
130
0
    while ( nEnd > 0 && pRowInfo[nEnd-1].nPixelStart > rPixelArea.Bottom() )
131
0
        --nEnd;
132
133
0
    if ( nStart <= 0 && nEnd >= nRows )
134
0
        return;
135
136
0
    if ( nEnd > nStart )
137
0
    {
138
0
        SCROW nNewCount = nEnd - nStart;
139
0
        ScPreviewColRowInfo* pNewInfo = new ScPreviewColRowInfo[nNewCount];
140
0
        for (SCROW i=0; i<nNewCount; i++)
141
0
            pNewInfo[i] = pRowInfo[nStart + i];
142
0
        SetRowInfo( nNewCount, pNewInfo );
143
0
    }
144
0
    else
145
0
        SetRowInfo( 0, nullptr );      // all invisible
146
0
}
147
148
ScPreviewLocationData::ScPreviewLocationData( ScDocument* pDocument, OutputDevice* pWin ) :
149
0
    pWindow( pWin ),
150
0
    pDoc( pDocument ),
151
0
    nDrawRanges( 0 ),
152
0
    nPrintTab( 0 )
153
0
{
154
0
}
155
156
ScPreviewLocationData::~ScPreviewLocationData()
157
0
{
158
0
    Clear();
159
0
}
160
161
void ScPreviewLocationData::SetCellMapMode( const MapMode& rMapMode )
162
0
{
163
0
    aCellMapMode = rMapMode;
164
0
}
165
166
void ScPreviewLocationData::SetPrintTab( SCTAB nNew )
167
0
{
168
0
    nPrintTab = nNew;
169
0
}
170
171
void ScPreviewLocationData::Clear()
172
0
{
173
0
    m_Entries.clear();
174
175
0
    nDrawRanges = 0;
176
0
}
177
178
void ScPreviewLocationData::AddCellRange( const tools::Rectangle& rRect, const ScRange& rRange, bool bRepCol, bool bRepRow,
179
                                            const MapMode& rDrawMap )
180
0
{
181
0
    tools::Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
182
0
    m_Entries.push_front( std::make_unique<ScPreviewLocationEntry>(SC_PLOC_CELLRANGE, aPixelRect, rRange, bRepCol, bRepRow) );
183
184
0
    OSL_ENSURE( nDrawRanges < SC_PREVIEW_MAXRANGES, "too many ranges" );
185
186
0
    if ( nDrawRanges >= SC_PREVIEW_MAXRANGES )
187
0
        return;
188
189
0
    aDrawRectangle[nDrawRanges] = aPixelRect;
190
0
    aDrawMapMode[nDrawRanges] = rDrawMap;
191
192
0
    if (bRepCol)
193
0
    {
194
0
        if (bRepRow)
195
0
            aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_EDGE;
196
0
        else
197
0
            aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_REPCOL;
198
0
    }
199
0
    else
200
0
    {
201
0
        if (bRepRow)
202
0
            aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_REPROW;
203
0
        else
204
0
            aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_TAB;
205
0
    }
206
207
0
    ++nDrawRanges;
208
0
}
209
210
void ScPreviewLocationData::AddColHeaders( const tools::Rectangle& rRect, SCCOL nStartCol, SCCOL nEndCol, bool bRepCol )
211
0
{
212
0
    SCTAB nTab = 0; //! ?
213
0
    ScRange aRange( nStartCol, 0, nTab, nEndCol, 0, nTab );
214
0
    tools::Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
215
216
0
    m_Entries.push_front( std::make_unique<ScPreviewLocationEntry>(SC_PLOC_COLHEADER, aPixelRect, aRange, bRepCol, false) );
217
0
}
218
219
void ScPreviewLocationData::AddRowHeaders( const tools::Rectangle& rRect, SCROW nStartRow, SCROW nEndRow, bool bRepRow )
220
0
{
221
0
    SCTAB nTab = 0; //! ?
222
0
    ScRange aRange( 0, nStartRow, nTab, 0, nEndRow, nTab );
223
0
    tools::Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
224
225
0
    m_Entries.push_front( std::make_unique<ScPreviewLocationEntry>(SC_PLOC_ROWHEADER, aPixelRect, aRange, false, bRepRow) );
226
0
}
227
228
void ScPreviewLocationData::AddHeaderFooter( const tools::Rectangle& rRect, bool bHeader, bool bLeft )
229
0
{
230
0
    ScRange aRange;     //! ?
231
0
    tools::Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
232
233
0
    ScPreviewLocationType eType = bHeader ?
234
0
                ( bLeft ? SC_PLOC_LEFTHEADER : SC_PLOC_RIGHTHEADER ) :
235
0
                ( bLeft ? SC_PLOC_LEFTFOOTER : SC_PLOC_RIGHTFOOTER );
236
237
0
    m_Entries.push_front( std::make_unique<ScPreviewLocationEntry>(eType, aPixelRect, aRange, false, false) );
238
0
}
239
240
void ScPreviewLocationData::AddNoteMark( const tools::Rectangle& rRect, const ScAddress& rPos )
241
0
{
242
0
    ScRange aRange( rPos );
243
0
    tools::Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
244
245
0
    m_Entries.push_front( std::make_unique<ScPreviewLocationEntry>(SC_PLOC_NOTEMARK, aPixelRect, aRange, false, false) );
246
0
}
247
248
void ScPreviewLocationData::AddNoteText( const tools::Rectangle& rRect, const ScAddress& rPos )
249
0
{
250
0
    ScRange aRange( rPos );
251
0
    tools::Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
252
253
0
    m_Entries.push_front( std::make_unique<ScPreviewLocationEntry>(SC_PLOC_NOTETEXT, aPixelRect, aRange, false, false) );
254
0
}
255
256
void ScPreviewLocationData::GetDrawRange( sal_uInt16 nPos, tools::Rectangle& rPixelRect, MapMode& rMapMode, sal_uInt8& rRangeId ) const
257
0
{
258
0
    OSL_ENSURE( nPos < nDrawRanges, "wrong position" );
259
0
    if ( nPos < nDrawRanges )
260
0
    {
261
0
        rPixelRect = aDrawRectangle[nPos];
262
0
        rMapMode = aDrawMapMode[nPos];
263
0
        rRangeId = aDrawRangeId[nPos];
264
0
    }
265
0
}
266
267
static ScPreviewLocationEntry* lcl_GetEntryByAddress(
268
        ScPreviewLocationData::Entries_t const& rEntries,
269
        const ScAddress& rPos, ScPreviewLocationType const eType)
270
0
{
271
0
    for (auto const& it : rEntries)
272
0
    {
273
0
        if ( it->eType == eType && it->aCellRange.Contains( rPos ) )
274
0
            return it.get();
275
0
    }
276
277
0
    return nullptr;
278
0
}
279
280
tools::Rectangle ScPreviewLocationData::GetOffsetPixel( const ScAddress& rCellPos, const ScRange& rRange ) const
281
0
{
282
0
    SCTAB nTab = rRange.aStart.Tab();
283
284
0
    tools::Long nPosX = 0;
285
0
    SCCOL nEndCol = rCellPos.Col();
286
0
    for (SCCOL nCol = rRange.aStart.Col(); nCol < nEndCol; nCol++)
287
0
    {
288
0
        sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab );
289
0
        if (nDocW)
290
0
            nPosX += o3tl::convert(nDocW, o3tl::Length::twip, o3tl::Length::mm100);
291
0
    }
292
0
    const tools::Long nSizeX
293
0
        = o3tl::convert(pDoc->GetColWidth(nEndCol, nTab), o3tl::Length::twip, o3tl::Length::mm100);
294
295
0
    SCROW nEndRow = rCellPos.Row();
296
0
    tools::Long nPosY = o3tl::convert(pDoc->GetRowHeight(rRange.aStart.Row(), nEndRow, nTab),
297
0
                                      o3tl::Length::twip, o3tl::Length::mm100);
298
0
    tools::Long nSizeY
299
0
        = o3tl::convert(pDoc->GetRowHeight(nEndRow, nTab), o3tl::Length::twip, o3tl::Length::mm100);
300
301
0
    Size aOffsetLogic( nPosX, nPosY );
302
0
    Size aSizeLogic( nSizeX, nSizeY );
303
0
    Size aOffsetPixel = pWindow->LogicToPixel( aOffsetLogic, aCellMapMode );
304
0
    Size aSizePixel = pWindow->LogicToPixel( aSizeLogic, aCellMapMode );
305
306
0
    return tools::Rectangle( Point( aOffsetPixel.Width(), aOffsetPixel.Height() ), aSizePixel );
307
0
}
308
309
tools::Rectangle ScPreviewLocationData::GetCellPosition(const ScAddress& rCellPos) const
310
0
{
311
0
    ScPreviewLocationEntry* pEntry = lcl_GetEntryByAddress( m_Entries, rCellPos, SC_PLOC_CELLRANGE );
312
0
    if (!pEntry)
313
0
        return tools::Rectangle();
314
315
0
    tools::Rectangle aOffsetRect = GetOffsetPixel(rCellPos, pEntry->aCellRange);
316
0
    return tools::Rectangle(aOffsetRect.Left() + pEntry->aPixelRect.Left(),
317
0
                            aOffsetRect.Top() + pEntry->aPixelRect.Top(),
318
0
                            aOffsetRect.Right() + pEntry->aPixelRect.Left(),
319
0
                            aOffsetRect.Bottom() + pEntry->aPixelRect.Top());
320
0
}
321
322
bool ScPreviewLocationData::HasCellsInRange( const tools::Rectangle& rVisiblePixel ) const
323
0
{
324
0
    for (auto const& it : m_Entries)
325
0
    {
326
0
        if ( it->eType == SC_PLOC_CELLRANGE || it->eType == SC_PLOC_COLHEADER || it->eType == SC_PLOC_ROWHEADER )
327
0
            if ( it->aPixelRect.Overlaps( rVisiblePixel ) )
328
0
                return true;
329
0
    }
330
331
0
    return false;
332
0
}
333
334
bool ScPreviewLocationData::GetHeaderPosition( tools::Rectangle& rRect ) const
335
0
{
336
0
    for (auto const& it : m_Entries)
337
0
    {
338
0
        if ( it->eType == SC_PLOC_LEFTHEADER || it->eType == SC_PLOC_RIGHTHEADER )
339
0
        {
340
0
            rRect = it->aPixelRect;
341
0
            return true;
342
0
        }
343
0
    }
344
345
0
    return false;
346
0
}
347
348
bool ScPreviewLocationData::GetFooterPosition( tools::Rectangle& rRect ) const
349
0
{
350
0
    for (auto const& it : m_Entries)
351
0
    {
352
0
        if ( it->eType == SC_PLOC_LEFTFOOTER || it->eType == SC_PLOC_RIGHTFOOTER )
353
0
        {
354
0
            rRect = it->aPixelRect;
355
0
            return true;
356
0
        }
357
0
    }
358
359
0
    return false;
360
0
}
361
362
bool ScPreviewLocationData::IsHeaderLeft() const
363
0
{
364
0
    for (auto const& it : m_Entries)
365
0
    {
366
0
        if ( it->eType == SC_PLOC_LEFTHEADER )
367
0
            return true;
368
369
0
        if ( it->eType == SC_PLOC_RIGHTHEADER )
370
0
            return false;
371
0
    }
372
373
0
    return false;
374
0
}
375
376
bool ScPreviewLocationData::IsFooterLeft() const
377
0
{
378
0
    for (auto const& it : m_Entries)
379
0
    {
380
0
        if ( it->eType == SC_PLOC_LEFTFOOTER )
381
0
            return true;
382
383
0
        if ( it->eType == SC_PLOC_RIGHTFOOTER )
384
0
            return false;
385
0
    }
386
387
0
    return false;
388
0
}
389
390
tools::Long ScPreviewLocationData::GetNoteCountInRange( const tools::Rectangle& rVisiblePixel, bool bNoteMarks ) const
391
0
{
392
0
    ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT;
393
394
0
    tools::Long nRet = 0;
395
0
    for (auto const& it : m_Entries)
396
0
    {
397
0
        if ( it->eType == eType && it->aPixelRect.Overlaps( rVisiblePixel ) )
398
0
            ++nRet;
399
0
    }
400
401
0
    return nRet;
402
0
}
403
404
bool ScPreviewLocationData::GetNoteInRange( const tools::Rectangle& rVisiblePixel, tools::Long nIndex, bool bNoteMarks,
405
                                            ScAddress& rCellPos, tools::Rectangle& rNoteRect ) const
406
0
{
407
0
    ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT;
408
409
0
    tools::Long nPos = 0;
410
0
    for (auto const& it : m_Entries)
411
0
    {
412
0
        if ( it->eType == eType && it->aPixelRect.Overlaps( rVisiblePixel ) )
413
0
        {
414
0
            if ( nPos == nIndex )
415
0
            {
416
0
                rCellPos = it->aCellRange.aStart;
417
0
                rNoteRect = it->aPixelRect;
418
0
                return true;
419
0
            }
420
0
            ++nPos;
421
0
        }
422
0
    }
423
424
0
    return false;
425
0
}
426
427
tools::Rectangle ScPreviewLocationData::GetNoteInRangeOutputRect(const tools::Rectangle& rVisiblePixel, bool bNoteMarks, const ScAddress& aCellPos) const
428
0
{
429
0
    ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT;
430
431
0
    for (auto const& it : m_Entries)
432
0
    {
433
0
        if ( it->eType == eType && it->aPixelRect.Overlaps( rVisiblePixel ) )
434
0
        {
435
0
            if ( aCellPos == it->aCellRange.aStart )
436
0
                return it->aPixelRect;
437
0
        }
438
0
    }
439
440
0
    return tools::Rectangle();
441
0
}
442
443
void ScPreviewLocationData::GetTableInfo( const tools::Rectangle& rVisiblePixel, ScPreviewTableInfo& rInfo ) const
444
0
{
445
    // from left to right:
446
0
    bool bHasHeaderCol = false;
447
0
    bool bHasRepCols   = false;
448
0
    bool bHasMainCols  = false;
449
0
    SCCOL nRepeatColStart = 0;
450
0
    SCCOL nRepeatColEnd   = 0;
451
0
    SCCOL nMainColStart   = 0;
452
0
    SCCOL nMainColEnd     = 0;
453
454
    // from top to bottom:
455
0
    bool bHasHeaderRow = false;
456
0
    bool bHasRepRows   = false;
457
0
    bool bHasMainRows  = false;
458
0
    SCROW nRepeatRowStart = 0;
459
0
    SCROW nRepeatRowEnd   = 0;
460
0
    SCROW nMainRowStart   = 0;
461
0
    SCROW nMainRowEnd     = 0;
462
463
0
    tools::Rectangle aHeaderRect, aRepeatRect, aMainRect;
464
0
    SCTAB nTab = 0;
465
466
0
    for (auto const& it : m_Entries)
467
0
    {
468
0
        if ( it->eType == SC_PLOC_CELLRANGE )
469
0
        {
470
0
            if ( it->bRepeatCol )
471
0
            {
472
0
                bHasRepCols = true;
473
0
                nRepeatColStart = it->aCellRange.aStart.Col();
474
0
                nRepeatColEnd = it->aCellRange.aEnd.Col();
475
0
                aRepeatRect.SetLeft( it->aPixelRect.Left() );
476
0
                aRepeatRect.SetRight( it->aPixelRect.Right() );
477
0
            }
478
0
            else
479
0
            {
480
0
                bHasMainCols = true;
481
0
                nMainColStart = it->aCellRange.aStart.Col();
482
0
                nMainColEnd = it->aCellRange.aEnd.Col();
483
0
                aMainRect.SetLeft( it->aPixelRect.Left() );
484
0
                aMainRect.SetRight( it->aPixelRect.Right() );
485
0
            }
486
0
            if ( it->bRepeatRow )
487
0
            {
488
0
                bHasRepRows = true;
489
0
                nRepeatRowStart = it->aCellRange.aStart.Row();
490
0
                nRepeatRowEnd = it->aCellRange.aEnd.Row();
491
0
                aRepeatRect.SetTop( it->aPixelRect.Top() );
492
0
                aRepeatRect.SetBottom( it->aPixelRect.Bottom() );
493
0
            }
494
0
            else
495
0
            {
496
0
                bHasMainRows = true;
497
0
                nMainRowStart = it->aCellRange.aStart.Row();
498
0
                nMainRowEnd = it->aCellRange.aEnd.Row();
499
0
                aMainRect.SetTop( it->aPixelRect.Top() );
500
0
                aMainRect.SetBottom( it->aPixelRect.Bottom() );
501
0
            }
502
0
            nTab = it->aCellRange.aStart.Tab();     //! store separately?
503
0
        }
504
0
        else if ( it->eType == SC_PLOC_ROWHEADER )
505
0
        {
506
            // row headers result in an additional column
507
0
            bHasHeaderCol = true;
508
0
            aHeaderRect.SetLeft( it->aPixelRect.Left() );
509
0
            aHeaderRect.SetRight( it->aPixelRect.Right() );
510
0
        }
511
0
        else if ( it->eType == SC_PLOC_COLHEADER )
512
0
        {
513
            // column headers result in an additional row
514
0
            bHasHeaderRow = true;
515
0
            aHeaderRect.SetTop( it->aPixelRect.Top() );
516
0
            aHeaderRect.SetBottom( it->aPixelRect.Bottom() );
517
0
        }
518
0
    }
519
520
    //  get column info
521
522
0
    SCCOL nColCount = 0;
523
0
    SCCOL nCol;
524
0
    if ( bHasHeaderCol )
525
0
        ++nColCount;
526
0
    if ( bHasRepCols )
527
0
        for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ )
528
0
            if (!pDoc->ColHidden(nCol, nTab))
529
0
                ++nColCount;
530
0
    if ( bHasMainCols )
531
0
        for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ )
532
0
            if (!pDoc->ColHidden(nCol, nTab))
533
0
                ++nColCount;
534
535
0
    if ( nColCount > 0 )
536
0
    {
537
0
        ScPreviewColRowInfo* pColInfo = new ScPreviewColRowInfo[ nColCount ];
538
0
        SCCOL nColPos = 0;
539
540
0
        if ( bHasHeaderCol )
541
0
        {
542
0
            pColInfo[nColPos].Set( true, 0, aHeaderRect.Left(), aHeaderRect.Right() );
543
0
            ++nColPos;
544
0
        }
545
0
        if ( bHasRepCols )
546
0
        {
547
0
            tools::Long nPosX = 0;
548
0
            for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ )
549
0
                if (!pDoc->ColHidden(nCol, nTab))
550
0
                {
551
0
                    sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab );
552
0
                    tools::Long nNextX
553
0
                        = nPosX + o3tl::convert(nDocW, o3tl::Length::twip, o3tl::Length::mm100);
554
555
0
                    tools::Long nPixelStart = pWindow->LogicToPixel( Size( nPosX, 0 ), aCellMapMode ).Width();
556
0
                    tools::Long nPixelEnd = pWindow->LogicToPixel( Size( nNextX, 0 ), aCellMapMode ).Width() - 1;
557
0
                    pColInfo[nColPos].Set( false, nCol,
558
0
                                                aRepeatRect.Left() + nPixelStart,
559
0
                                                aRepeatRect.Left() + nPixelEnd );
560
561
0
                    nPosX = nNextX;
562
0
                    ++nColPos;
563
0
                }
564
0
        }
565
0
        if ( bHasMainCols )
566
0
        {
567
0
            tools::Long nPosX = 0;
568
0
            for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ )
569
0
                if (!pDoc->ColHidden(nCol, nTab))
570
0
                {
571
0
                    sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab );
572
0
                    tools::Long nNextX
573
0
                        = nPosX + o3tl::convert(nDocW, o3tl::Length::twip, o3tl::Length::mm100);
574
575
0
                    tools::Long nPixelStart = pWindow->LogicToPixel( Size( nPosX, 0 ), aCellMapMode ).Width();
576
0
                    tools::Long nPixelEnd = pWindow->LogicToPixel( Size( nNextX, 0 ), aCellMapMode ).Width() - 1;
577
0
                    pColInfo[nColPos].Set( false, nCol,
578
0
                                                aMainRect.Left() + nPixelStart,
579
0
                                                aMainRect.Left() + nPixelEnd );
580
581
0
                    nPosX = nNextX;
582
0
                    ++nColPos;
583
0
                }
584
0
        }
585
0
        rInfo.SetColInfo( nColCount, pColInfo );
586
0
    }
587
0
    else
588
0
        rInfo.SetColInfo( 0, nullptr );
589
590
    //  get row info
591
592
0
    SCROW nRowCount = 0;
593
0
    if ( bHasHeaderRow )
594
0
        ++nRowCount;
595
0
    if ( bHasRepRows )
596
0
        nRowCount += pDoc->CountVisibleRows(nRepeatRowStart, nRepeatRowEnd, nTab);
597
0
    if ( bHasMainRows )
598
0
        nRowCount += pDoc->CountVisibleRows(nMainRowStart, nMainRowEnd, nTab);
599
600
0
    if ( nRowCount > 0 )
601
0
    {
602
0
        ScPreviewColRowInfo* pRowInfo = new ScPreviewColRowInfo[ nRowCount ];
603
0
        SCROW nRowPos = 0;
604
605
0
        if ( bHasHeaderRow )
606
0
        {
607
0
            pRowInfo[nRowPos].Set( true, 0, aHeaderRect.Top(), aHeaderRect.Bottom() );
608
0
            ++nRowPos;
609
0
        }
610
0
        if ( bHasRepRows )
611
0
        {
612
0
            tools::Long nPosY = 0;
613
0
            for (SCROW nRow = nRepeatRowStart; nRow <= nRepeatRowEnd; ++nRow)
614
0
            {
615
0
                if (pDoc->RowHidden(nRow, nTab))
616
0
                    continue;
617
618
0
                sal_uInt16 nDocH = pDoc->GetOriginalHeight( nRow, nTab );
619
0
                tools::Long nNextY
620
0
                    = nPosY + o3tl::convert(nDocH, o3tl::Length::twip, o3tl::Length::mm100);
621
622
0
                tools::Long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height();
623
0
                tools::Long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1;
624
0
                pRowInfo[nRowPos].Set( false, nRow,
625
0
                        aRepeatRect.Top() + nPixelStart,
626
0
                        aRepeatRect.Top() + nPixelEnd );
627
628
0
                nPosY = nNextY;
629
0
                ++nRowPos;
630
0
            }
631
0
        }
632
0
        if ( bHasMainRows )
633
0
        {
634
0
            tools::Long nPosY = 0;
635
0
            for (SCROW nRow = nMainRowStart; nRow <= nMainRowEnd; ++nRow)
636
0
            {
637
0
                if (pDoc->RowHidden(nRow, nTab))
638
0
                    continue;
639
640
0
                sal_uInt16 nDocH = pDoc->GetOriginalHeight( nRow, nTab );
641
0
                tools::Long nNextY
642
0
                    = nPosY + o3tl::convert(nDocH, o3tl::Length::twip, o3tl::Length::mm100);
643
644
0
                tools::Long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height();
645
0
                tools::Long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1;
646
0
                pRowInfo[nRowPos].Set( false, nRow,
647
0
                        aMainRect.Top() + nPixelStart,
648
0
                        aMainRect.Top() + nPixelEnd );
649
650
0
                nPosY = nNextY;
651
0
                ++nRowPos;
652
0
            }
653
0
        }
654
0
        rInfo.SetRowInfo( nRowCount, pRowInfo );
655
0
    }
656
0
    else
657
0
        rInfo.SetRowInfo( 0, nullptr );
658
659
    //  limit to visible area
660
661
0
    rInfo.SetTab( nTab );
662
0
    rInfo.LimitToArea( rVisiblePixel );
663
0
}
664
665
tools::Rectangle ScPreviewLocationData::GetHeaderCellOutputRect(const tools::Rectangle& rVisRect, const ScAddress& rCellPos, bool bColHeader) const
666
0
{
667
    // first a stupid implementation
668
    // NN says here should be done more
669
0
    tools::Rectangle aClipRect;
670
0
    ScPreviewTableInfo aTableInfo;
671
0
    GetTableInfo( rVisRect, aTableInfo );
672
673
0
    if ( (rCellPos.Col() >= 0) &&
674
0
        (rCellPos.Row() >= 0) && (rCellPos.Col() < aTableInfo.GetCols()) &&
675
0
        (rCellPos.Row() < aTableInfo.GetRows()) )
676
0
    {
677
0
        SCCOL nCol(0);
678
0
        SCROW nRow(0);
679
0
        if (bColHeader)
680
0
            nCol = rCellPos.Col();
681
0
        else
682
0
            nRow = rCellPos.Row();
683
0
        const ScPreviewColRowInfo& rColInfo = aTableInfo.GetColInfo()[nCol];
684
0
        const ScPreviewColRowInfo& rRowInfo = aTableInfo.GetRowInfo()[nRow];
685
686
0
        if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
687
0
            aClipRect = tools::Rectangle( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
688
0
    }
689
0
    return aClipRect;
690
0
}
691
692
tools::Rectangle ScPreviewLocationData::GetCellOutputRect(const ScAddress& rCellPos) const
693
0
{
694
    // first a stupid implementation
695
    // NN says here should be done more
696
0
    return GetCellPosition(rCellPos);
697
0
}
698
699
// GetMainCellRange is used for links in PDF export
700
701
bool ScPreviewLocationData::GetMainCellRange( ScRange& rRange, tools::Rectangle& rPixRect ) const
702
0
{
703
0
    for (auto const& it : m_Entries)
704
0
    {
705
0
        if ( it->eType == SC_PLOC_CELLRANGE && !it->bRepeatCol && !it->bRepeatRow )
706
0
        {
707
0
            rRange = it->aCellRange;
708
0
            rPixRect = it->aPixelRect;
709
0
            return true;
710
0
        }
711
0
    }
712
713
0
    return false;
714
0
}
715
716
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */