/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: */ |