Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/miscdlgs/datatableview.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 <datatableview.hxx>
21
22
#include <document.hxx>
23
#include <utility>
24
#include <viewdata.hxx>
25
#include <output.hxx>
26
#include <fillinfo.hxx>
27
#include <table.hxx>
28
29
#include <toolkit/helper/vclunohelper.hxx>
30
#include <vcl/seleng.hxx>
31
#include <sal/log.hxx>
32
33
constexpr double nPPTX = 0.06666;
34
constexpr double nPPTY = 0.06666;
35
36
constexpr sal_uInt16 nRowHeaderWidth = 100;
37
constexpr sal_uInt16 nColHeaderHeight = 20;
38
39
ScDataTableColView::ScDataTableColView(vcl::Window* pParent, ScDocument* pDoc, SelectionEngine* pSelectionEngine):
40
0
        ScHeaderControl(pParent, pSelectionEngine, pDoc->MaxCol()+1, false, nullptr),
41
0
        mpDoc(pDoc),
42
0
        mnCol(0)
43
0
{
44
0
}
Unexecuted instantiation: ScDataTableColView::ScDataTableColView(vcl::Window*, ScDocument*, SelectionEngine*)
Unexecuted instantiation: ScDataTableColView::ScDataTableColView(vcl::Window*, ScDocument*, SelectionEngine*)
45
46
void ScDataTableColView::SetPos(SCCOLROW nCol)
47
0
{
48
0
    mnCol = nCol;
49
0
}
50
51
SCCOLROW ScDataTableColView::GetPos() const
52
0
{
53
0
    return mnCol;
54
0
}
55
56
sal_uInt16 ScDataTableColView::GetEntrySize(SCCOLROW nPos) const
57
0
{
58
0
    return ScViewData::ToPixel(mpDoc->GetColWidth(nPos, 0), nPPTX);
59
0
}
60
61
OUString ScDataTableColView::GetEntryText(SCCOLROW nPos) const
62
0
{
63
0
    return "Col: " + OUString::number(nPos + 1);
64
0
}
65
66
bool ScDataTableColView::IsLayoutRTL() const
67
0
{
68
0
    return false;
69
0
}
70
71
void ScDataTableColView::SetEntrySize(SCCOLROW nPos, sal_uInt16 nColWidth)
72
0
{
73
0
    mpDoc->SetColWidthOnly(nPos, 0, nColWidth/nPPTX);
74
0
}
75
76
void ScDataTableColView::HideEntries(SCCOLROW nPos, SCCOLROW nEndPos)
77
0
{
78
0
    for (SCCOLROW nCol = nPos; nCol <= nEndPos; ++nCol)
79
0
    {
80
0
        mpDoc->ShowCol(nCol, 0, false);
81
0
    }
82
0
}
83
84
85
ScDataTableRowView::ScDataTableRowView(vcl::Window* pParent, ScDocument* pDoc, SelectionEngine* pSelectionEngine):
86
0
        ScHeaderControl(pParent, pSelectionEngine, pDoc->MaxRow()+1, true, nullptr),
87
0
        mpDoc(pDoc),
88
0
        mnRow(0)
89
0
{
90
0
}
Unexecuted instantiation: ScDataTableRowView::ScDataTableRowView(vcl::Window*, ScDocument*, SelectionEngine*)
Unexecuted instantiation: ScDataTableRowView::ScDataTableRowView(vcl::Window*, ScDocument*, SelectionEngine*)
91
92
void ScDataTableRowView::SetPos(SCCOLROW nRow)
93
0
{
94
0
    mnRow = nRow;
95
0
}
96
97
SCCOLROW ScDataTableRowView::GetPos() const
98
0
{
99
0
    return mnRow;
100
0
}
101
102
sal_uInt16 ScDataTableRowView::GetEntrySize(SCCOLROW nPos) const
103
0
{
104
0
    return ScViewData::ToPixel(mpDoc->GetRowHeight(nPos, SCTAB(0), true), nPPTX);
105
0
}
106
107
OUString ScDataTableRowView::GetEntryText(SCCOLROW nPos) const
108
0
{
109
0
    return OUString::number(nPos + 1);
110
0
}
111
112
bool ScDataTableRowView::IsLayoutRTL() const
113
0
{
114
0
    return false;
115
0
}
116
117
void ScDataTableRowView::SetEntrySize(SCCOLROW nPos, sal_uInt16 nColWidth)
118
0
{
119
0
    mpDoc->SetRowHeight(nPos, 0, nColWidth/nPPTX);
120
0
}
121
122
void ScDataTableRowView::HideEntries(SCCOLROW nPos, SCCOLROW nEndPos)
123
0
{
124
0
    for (SCCOLROW nCol = nPos; nCol <= nEndPos; ++nCol)
125
0
    {
126
0
        mpDoc->ShowRow(nCol, 0, false);
127
0
    }
128
0
}
129
130
ScDataTableView::ScDataTableView(const css::uno::Reference<css::awt::XWindow> &rParent, std::shared_ptr<ScDocument> pDoc) :
131
0
    Control(VCLUnoHelper::GetWindow(rParent)),
132
0
    mpDoc(std::move(pDoc)),
133
0
    mpSelectionEngine(new SelectionEngine(this)),
134
0
    mpColView(VclPtr<ScDataTableColView>::Create(this, mpDoc.get(), mpSelectionEngine.get())),
135
0
    mpRowView(VclPtr<ScDataTableRowView>::Create(this, mpDoc.get(), mpSelectionEngine.get())),
136
0
    mpVScroll(VclPtr<ScrollAdaptor>::Create(this, false)),
137
0
    mpHScroll(VclPtr<ScrollAdaptor>::Create(this, true)),
138
0
    mnScrollBarSize(mpVScroll->GetSizePixel().Width()),
139
0
    mnFirstVisibleRow(0),
140
0
    mnFirstVisibleCol(0)
141
0
{
142
0
    mpColView->setPosSizePixel(nRowHeaderWidth, 0, nRowHeaderWidth, nColHeaderHeight);
143
0
    mpRowView->setPosSizePixel(0, nColHeaderHeight, nRowHeaderWidth, nColHeaderHeight);
144
145
0
    mpVScroll->SetRangeMin(0);
146
0
    mpVScroll->SetRangeMax(100);
147
0
    mpVScroll->SetScrollHdl(LINK(this, ScDataTableView, VertScrollHdl));
148
149
0
    mpHScroll->SetRangeMin(0);
150
0
    mpHScroll->SetRangeMax(50);
151
0
    mpHScroll->SetScrollHdl(LINK(this, ScDataTableView, HorzScrollHdl));
152
153
0
    mpColView->Show();
154
0
    mpRowView->Show();
155
0
    mpVScroll->Show();
156
0
    mpHScroll->Show();
157
0
}
Unexecuted instantiation: ScDataTableView::ScDataTableView(com::sun::star::uno::Reference<com::sun::star::awt::XWindow> const&, std::__1::shared_ptr<ScDocument>)
Unexecuted instantiation: ScDataTableView::ScDataTableView(com::sun::star::uno::Reference<com::sun::star::awt::XWindow> const&, std::__1::shared_ptr<ScDocument>)
158
159
ScDataTableView::~ScDataTableView()
160
0
{
161
0
    disposeOnce();
162
0
}
163
164
void ScDataTableView::dispose()
165
0
{
166
0
    mpColView.disposeAndClear();
167
0
    mpRowView.disposeAndClear();
168
0
    mpVScroll.disposeAndClear();
169
0
    mpHScroll.disposeAndClear();
170
0
    Control::dispose();
171
0
}
172
173
void ScDataTableView::MouseButtonDown(const MouseEvent& rMEvt)
174
0
{
175
0
    if (!rMEvt.IsLeft())
176
0
        return;
177
178
0
    mpMouseEvent.reset(new MouseEvent(rMEvt));
179
0
}
180
181
namespace {
182
183
SCCOL findColFromPos(sal_uInt16 nPixelPos, const ScDocument* pDoc, SCCOL nStartCol = 0)
184
0
{
185
0
    nPixelPos -= nRowHeaderWidth;
186
0
    sal_uInt32 nPixelLength = 0;
187
0
    for (SCCOL nCol : pDoc->GetColumnsRange(0, nStartCol, pDoc->MaxCol()))
188
0
    {
189
0
        sal_uInt16 nColWidth = pDoc->GetColWidth(nCol, 0, true);
190
0
        sal_uInt32 nPixel = ScViewData::ToPixel(nColWidth, nPPTX);
191
0
        nPixelLength += nPixel;
192
193
0
        if (nPixelLength >= nPixelPos)
194
0
        {
195
0
            return nCol;
196
0
        }
197
0
    }
198
199
0
    SAL_WARN("sc", "Could not find the corresponding column");
200
0
    return pDoc->MaxCol();
201
0
}
202
203
SCROW findRowFromPos(sal_uInt16 nPixelPos, const ScDocument* pDoc, SCROW nStartRow = 0)
204
0
{
205
0
    nPixelPos -= nColHeaderHeight;
206
0
    sal_uInt32 nPixelLength = 0;
207
0
    for (SCROW nRow = nStartRow; nRow <= pDoc->MaxRow(); ++nRow)
208
0
    {
209
0
        sal_uInt16 nColWidth = pDoc->GetRowHeight(nRow, SCTAB(0), true);
210
0
        sal_uInt32 nPixel = ScViewData::ToPixel(nColWidth, nPPTX);
211
0
        nPixelLength += nPixel;
212
213
0
        if (nPixelLength >= nPixelPos)
214
0
        {
215
0
            return nRow;
216
0
        }
217
0
    }
218
219
0
    SAL_WARN("sc", "Could not find the corresponding row");
220
0
    return pDoc->MaxRow();
221
0
}
222
223
}
224
225
void ScDataTableView::MouseButtonUp(const MouseEvent& rMEvt)
226
0
{
227
0
    if (!rMEvt.IsLeft())
228
0
        return;
229
0
    if (!mpMouseEvent) // tdf#120528 The event originated in another window, like context menu
230
0
        return;
231
232
0
    SCCOL nStartCol = findColFromPos(mpMouseEvent->GetPosPixel().getX(), mpDoc.get());
233
0
    SCCOL nEndCol = findColFromPos(rMEvt.GetPosPixel().getX(), mpDoc.get());
234
0
    SCROW nStartRow = findRowFromPos(mpMouseEvent->GetPosPixel().getY(), mpDoc.get());
235
0
    SCROW nEndRow = findRowFromPos(rMEvt.GetPosPixel().getY(), mpDoc.get());
236
0
    PutInOrder(nStartCol, nEndCol);
237
0
    PutInOrder(nStartRow, nEndRow);
238
0
    mpColView->SetMark(true, nStartCol, nEndCol);
239
0
    mpRowView->SetMark(true, nStartRow, nEndRow);
240
241
0
    mpMouseEvent.reset();
242
0
}
243
244
void ScDataTableView::Resize()
245
0
{
246
0
    Size aSize = GetSizePixel();
247
0
    mpColView->setPosSizePixel(nRowHeaderWidth, 0, aSize.Width() - mnScrollBarSize, nColHeaderHeight);
248
0
    mpRowView->setPosSizePixel(0, nColHeaderHeight, nRowHeaderWidth, aSize.Height());
249
250
0
    mpVScroll->setPosSizePixel(aSize.Width() - mnScrollBarSize, nColHeaderHeight, mnScrollBarSize, aSize.Height() - nColHeaderHeight - mnScrollBarSize);
251
0
    mpHScroll->setPosSizePixel(nRowHeaderWidth, aSize.Height() - mnScrollBarSize, aSize.Width() - nRowHeaderWidth - mnScrollBarSize, mnScrollBarSize);
252
0
}
253
254
void ScDataTableView::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRectangle)
255
0
{
256
0
    Size aSize = GetSizePixel();
257
0
    SCCOL nMaxVisibleCol = findColFromPos(aSize.Width() - mnScrollBarSize, mpDoc.get(), mnFirstVisibleCol);
258
0
    SCROW nMaxVisibleRow = findRowFromPos(aSize.Height(), mpDoc.get(), mnFirstVisibleRow);
259
260
0
    ScTableInfo aTableInfo(mnFirstVisibleRow, nMaxVisibleRow, true);
261
0
    mpDoc->FillInfo(aTableInfo, mnFirstVisibleCol, mnFirstVisibleRow, nMaxVisibleCol, nMaxVisibleRow, 0, 0.06666, 0.06666, false, false);
262
0
    ScOutputData aOutput(&rRenderContext, OUTTYPE_WINDOW, aTableInfo, mpDoc.get(), 0,
263
0
            nRowHeaderWidth, nColHeaderHeight, mnFirstVisibleCol, mnFirstVisibleRow, nMaxVisibleCol, nMaxVisibleRow, nPPTX, nPPTY);
264
265
0
    aOutput.SetGridColor(COL_BLACK);
266
0
    aOutput.SetSolidBackground(true);
267
0
    aOutput.DrawClear();
268
0
    aOutput.DrawDocumentBackground();
269
0
    aOutput.DrawGrid(rRenderContext, true, false);
270
0
    aOutput.DrawStrings();
271
272
0
    Color aFaceColor(rRenderContext.GetSettings().GetStyleSettings().GetFaceColor());
273
0
    rRenderContext.SetLineColor(aFaceColor);
274
0
    rRenderContext.SetFillColor(aFaceColor);
275
0
    rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), Size(nRowHeaderWidth, nColHeaderHeight)));
276
0
    rRenderContext.DrawRect(tools::Rectangle(Point(aSize.Width() - mnScrollBarSize, aSize.Height() - mnScrollBarSize), Size(mnScrollBarSize, mnScrollBarSize)));
277
278
0
    Control::Paint(rRenderContext, rRectangle);
279
0
}
280
281
Size ScDataTableView::GetOptimalSize() const
282
0
{
283
0
    return Size(450, 400);
284
0
}
285
286
void ScDataTableView::getColRange(SCCOL& rStartCol, SCCOL& rEndCol) const
287
0
{
288
0
    SCCOLROW aStart = 0;
289
0
    SCCOLROW aEnd = 0;
290
0
    mpColView->GetMarkRange(aStart, aEnd);
291
0
    rStartCol = static_cast<SCCOL>(aStart);
292
0
    rEndCol = static_cast<SCCOL>(aEnd);
293
0
}
294
295
void ScDataTableView::getRowRange(SCROW& rStartCol, SCROW& rEndCol) const
296
0
{
297
0
    SCCOLROW aStart = 0;
298
0
    SCCOLROW aEnd = 0;
299
0
    mpRowView->GetMarkRange(aStart, aEnd);
300
0
    rStartCol = static_cast<SCROW>(aStart);
301
0
    rEndCol = static_cast<SCROW>(aEnd);
302
0
}
303
304
IMPL_LINK_NOARG(ScDataTableView, VertScrollHdl, weld::Scrollbar&, void)
305
0
{
306
0
    mnFirstVisibleRow = mpVScroll->GetThumbPos();
307
0
    mpVScroll->SetRangeMax(std::min(mpDoc->MaxRow(), static_cast<SCROW>(mnFirstVisibleRow + 100)));
308
0
    mpRowView->SetPos(mnFirstVisibleRow);
309
0
    Invalidate();
310
0
}
311
312
IMPL_LINK_NOARG(ScDataTableView, HorzScrollHdl, weld::Scrollbar&, void)
313
0
{
314
0
    mnFirstVisibleCol = mpHScroll->GetThumbPos();
315
0
    mpHScroll->SetRangeMax(std::min(mpDoc->MaxCol(), static_cast<SCCOL>(mnFirstVisibleCol + 50)));
316
0
    mpColView->SetPos(mnFirstVisibleCol);
317
0
    Invalidate();
318
0
}
319
320
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */