summaryrefslogtreecommitdiffstats
path: root/sc/source/ui/miscdlgs/datatableview.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/miscdlgs/datatableview.cxx')
-rw-r--r--sc/source/ui/miscdlgs/datatableview.cxx320
1 files changed, 320 insertions, 0 deletions
diff --git a/sc/source/ui/miscdlgs/datatableview.cxx b/sc/source/ui/miscdlgs/datatableview.cxx
new file mode 100644
index 000000000..d74df0e81
--- /dev/null
+++ b/sc/source/ui/miscdlgs/datatableview.cxx
@@ -0,0 +1,320 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <datatableview.hxx>
+
+#include <document.hxx>
+#include <utility>
+#include <viewdata.hxx>
+#include <output.hxx>
+#include <fillinfo.hxx>
+#include <table.hxx>
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/scrbar.hxx>
+#include <vcl/seleng.hxx>
+#include <sal/log.hxx>
+
+constexpr double nPPTX = 0.06666;
+constexpr double nPPTY = 0.06666;
+
+constexpr sal_uInt16 nRowHeaderWidth = 100;
+constexpr sal_uInt16 nColHeaderHeight = 20;
+constexpr sal_uInt16 nScrollBarSize = 10;
+
+ScDataTableColView::ScDataTableColView(vcl::Window* pParent, ScDocument* pDoc, SelectionEngine* pSelectionEngine):
+ ScHeaderControl(pParent, pSelectionEngine, pDoc->MaxCol()+1, false, nullptr),
+ mpDoc(pDoc),
+ mnCol(0)
+{
+}
+
+void ScDataTableColView::SetPos(SCCOLROW nCol)
+{
+ mnCol = nCol;
+}
+
+SCCOLROW ScDataTableColView::GetPos() const
+{
+ return mnCol;
+}
+
+sal_uInt16 ScDataTableColView::GetEntrySize(SCCOLROW nPos) const
+{
+ return ScViewData::ToPixel(mpDoc->GetColWidth(nPos, 0), nPPTX);
+}
+
+OUString ScDataTableColView::GetEntryText(SCCOLROW nPos) const
+{
+ return "Col: " + OUString::number(nPos + 1);
+}
+
+bool ScDataTableColView::IsLayoutRTL() const
+{
+ return false;
+}
+
+void ScDataTableColView::SetEntrySize(SCCOLROW nPos, sal_uInt16 nColWidth)
+{
+ mpDoc->SetColWidthOnly(nPos, 0, nColWidth/nPPTX);
+}
+
+void ScDataTableColView::HideEntries(SCCOLROW nPos, SCCOLROW nEndPos)
+{
+ for (SCCOLROW nCol = nPos; nCol <= nEndPos; ++nCol)
+ {
+ mpDoc->ShowCol(nCol, 0, false);
+ }
+}
+
+
+ScDataTableRowView::ScDataTableRowView(vcl::Window* pParent, ScDocument* pDoc, SelectionEngine* pSelectionEngine):
+ ScHeaderControl(pParent, pSelectionEngine, pDoc->MaxRow()+1, true, nullptr),
+ mpDoc(pDoc),
+ mnRow(0)
+{
+}
+
+void ScDataTableRowView::SetPos(SCCOLROW nRow)
+{
+ mnRow = nRow;
+}
+
+SCCOLROW ScDataTableRowView::GetPos() const
+{
+ return mnRow;
+}
+
+sal_uInt16 ScDataTableRowView::GetEntrySize(SCCOLROW nPos) const
+{
+ return ScViewData::ToPixel(mpDoc->GetRowHeight(nPos, SCTAB(0), true), nPPTX);
+}
+
+OUString ScDataTableRowView::GetEntryText(SCCOLROW nPos) const
+{
+ return OUString::number(nPos + 1);
+}
+
+bool ScDataTableRowView::IsLayoutRTL() const
+{
+ return false;
+}
+
+void ScDataTableRowView::SetEntrySize(SCCOLROW nPos, sal_uInt16 nColWidth)
+{
+ mpDoc->SetRowHeight(nPos, 0, nColWidth/nPPTX);
+}
+
+void ScDataTableRowView::HideEntries(SCCOLROW nPos, SCCOLROW nEndPos)
+{
+ for (SCCOLROW nCol = nPos; nCol <= nEndPos; ++nCol)
+ {
+ mpDoc->ShowRow(nCol, 0, false);
+ }
+}
+
+ScDataTableView::ScDataTableView(const css::uno::Reference<css::awt::XWindow> &rParent, std::shared_ptr<ScDocument> pDoc) :
+ Control(VCLUnoHelper::GetWindow(rParent)),
+ mpDoc(std::move(pDoc)),
+ mpSelectionEngine(new SelectionEngine(this)),
+ mpTopLeft(VclPtr<ScrollBarBox>::Create(this, WB_SIZEABLE)),
+ mpColView(VclPtr<ScDataTableColView>::Create(this, mpDoc.get(), mpSelectionEngine.get())),
+ mpRowView(VclPtr<ScDataTableRowView>::Create(this, mpDoc.get(), mpSelectionEngine.get())),
+ mpVScroll(VclPtr<ScrollBar>::Create(this, WinBits(WB_VSCROLL | WB_DRAG))),
+ mpHScroll(VclPtr<ScrollBar>::Create(this, WinBits(WB_HSCROLL | WB_DRAG))),
+ mnFirstVisibleRow(0),
+ mnFirstVisibleCol(0)
+{
+ mpTopLeft->setPosSizePixel(0, 0, nRowHeaderWidth, nColHeaderHeight);
+ mpColView->setPosSizePixel(nRowHeaderWidth, 0, nRowHeaderWidth, nColHeaderHeight);
+ mpRowView->setPosSizePixel(0, nColHeaderHeight, nRowHeaderWidth, nColHeaderHeight);
+
+ mpVScroll->SetRangeMin(0);
+ mpVScroll->SetRangeMax(100);
+ mpVScroll->SetEndScrollHdl(LINK(this, ScDataTableView, ScrollHdl));
+
+ mpHScroll->SetRangeMin(0);
+ mpHScroll->SetRangeMax(50);
+ mpHScroll->SetEndScrollHdl(LINK(this, ScDataTableView, ScrollHdl));
+
+ mpTopLeft->Show();
+ mpColView->Show();
+ mpRowView->Show();
+ mpVScroll->Show();
+ mpHScroll->Show();
+}
+
+ScDataTableView::~ScDataTableView()
+{
+ disposeOnce();
+}
+
+void ScDataTableView::dispose()
+{
+ mpTopLeft.disposeAndClear();
+ mpColView.disposeAndClear();
+ mpRowView.disposeAndClear();
+ mpVScroll.disposeAndClear();
+ mpHScroll.disposeAndClear();
+ Control::dispose();
+}
+
+void ScDataTableView::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ if (!rMEvt.IsLeft())
+ return;
+
+ mpMouseEvent.reset(new MouseEvent(rMEvt));
+}
+
+namespace {
+
+SCCOL findColFromPos(sal_uInt16 nPixelPos, const ScDocument* pDoc, SCCOL nStartCol = 0)
+{
+ nPixelPos -= nRowHeaderWidth;
+ sal_uInt32 nPixelLength = 0;
+ for (SCCOL nCol : pDoc->GetColumnsRange(0, nStartCol, pDoc->MaxCol()))
+ {
+ sal_uInt16 nColWidth = pDoc->GetColWidth(nCol, 0, true);
+ sal_uInt32 nPixel = ScViewData::ToPixel(nColWidth, nPPTX);
+ nPixelLength += nPixel;
+
+ if (nPixelLength >= nPixelPos)
+ {
+ return nCol;
+ }
+ }
+
+ SAL_WARN("sc", "Could not find the corresponding column");
+ return pDoc->MaxCol();
+}
+
+SCROW findRowFromPos(sal_uInt16 nPixelPos, const ScDocument* pDoc, SCROW nStartRow = 0)
+{
+ nPixelPos -= nColHeaderHeight;
+ sal_uInt32 nPixelLength = 0;
+ for (SCROW nRow = nStartRow; nRow <= pDoc->MaxRow(); ++nRow)
+ {
+ sal_uInt16 nColWidth = pDoc->GetRowHeight(nRow, SCTAB(0), true);
+ sal_uInt32 nPixel = ScViewData::ToPixel(nColWidth, nPPTX);
+ nPixelLength += nPixel;
+
+ if (nPixelLength >= nPixelPos)
+ {
+ return nRow;
+ }
+ }
+
+ SAL_WARN("sc", "Could not find the corresponding row");
+ return pDoc->MaxRow();
+}
+
+}
+
+void ScDataTableView::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ if (!rMEvt.IsLeft())
+ return;
+ if (!mpMouseEvent) // tdf#120528 The event originated in another window, like context menu
+ return;
+
+ SCCOL nStartCol = findColFromPos(mpMouseEvent->GetPosPixel().getX(), mpDoc.get());
+ SCCOL nEndCol = findColFromPos(rMEvt.GetPosPixel().getX(), mpDoc.get());
+ SCROW nStartRow = findRowFromPos(mpMouseEvent->GetPosPixel().getY(), mpDoc.get());
+ SCROW nEndRow = findRowFromPos(rMEvt.GetPosPixel().getY(), mpDoc.get());
+ PutInOrder(nStartCol, nEndCol);
+ PutInOrder(nStartRow, nEndRow);
+ mpColView->SetMark(true, nStartCol, nEndCol);
+ mpRowView->SetMark(true, nStartRow, nEndRow);
+
+ mpMouseEvent.reset();
+}
+
+void ScDataTableView::Resize()
+{
+ Size aSize = GetSizePixel();
+ mpTopLeft->setPosSizePixel(0, 0, nRowHeaderWidth, nColHeaderHeight);
+ mpColView->setPosSizePixel(nRowHeaderWidth, 0, aSize.Width() - nScrollBarSize, nColHeaderHeight);
+ mpRowView->setPosSizePixel(0, nColHeaderHeight, nRowHeaderWidth, aSize.Height());
+
+ mpVScroll->setPosSizePixel(aSize.Width() - nScrollBarSize, nColHeaderHeight, nScrollBarSize, aSize.Height() - nColHeaderHeight - nScrollBarSize);
+ mpHScroll->setPosSizePixel(nRowHeaderWidth, aSize.Height() - nScrollBarSize, aSize.Width() - nRowHeaderWidth - nScrollBarSize, nScrollBarSize);
+}
+
+void ScDataTableView::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRectangle)
+{
+ Size aSize = GetSizePixel();
+ SCCOL nMaxVisibleCol = findColFromPos(aSize.Width() - nScrollBarSize, mpDoc.get(), mnFirstVisibleCol);
+ SCROW nMaxVisibleRow = findRowFromPos(aSize.Height(), mpDoc.get(), mnFirstVisibleRow);
+
+ ScTableInfo aTableInfo;
+ mpDoc->FillInfo(aTableInfo, mnFirstVisibleCol, mnFirstVisibleRow, nMaxVisibleCol, nMaxVisibleRow, 0, 0.06666, 0.06666, false, false);
+ ScOutputData aOutput(&rRenderContext, OUTTYPE_WINDOW, aTableInfo, mpDoc.get(), 0,
+ nRowHeaderWidth, nColHeaderHeight, mnFirstVisibleCol, mnFirstVisibleRow, nMaxVisibleCol, nMaxVisibleRow, nPPTX, nPPTY);
+
+ aOutput.SetGridColor(COL_BLACK);
+ aOutput.SetSolidBackground(true);
+ aOutput.DrawClear();
+ aOutput.DrawDocumentBackground();
+ aOutput.DrawGrid(rRenderContext, true, false);
+ aOutput.DrawStrings();
+ Control::Paint(rRenderContext, rRectangle);
+}
+
+Size ScDataTableView::GetOptimalSize() const
+{
+ return Size(450, 400);
+}
+
+void ScDataTableView::getColRange(SCCOL& rStartCol, SCCOL& rEndCol) const
+{
+ SCCOLROW aStart = 0;
+ SCCOLROW aEnd = 0;
+ mpColView->GetMarkRange(aStart, aEnd);
+ rStartCol = static_cast<SCCOL>(aStart);
+ rEndCol = static_cast<SCCOL>(aEnd);
+}
+
+void ScDataTableView::getRowRange(SCROW& rStartCol, SCROW& rEndCol) const
+{
+ SCCOLROW aStart = 0;
+ SCCOLROW aEnd = 0;
+ mpRowView->GetMarkRange(aStart, aEnd);
+ rStartCol = static_cast<SCROW>(aStart);
+ rEndCol = static_cast<SCROW>(aEnd);
+}
+
+IMPL_LINK(ScDataTableView, ScrollHdl, ScrollBar*, pScrollBar, void)
+{
+ if (pScrollBar == mpVScroll.get())
+ {
+ mnFirstVisibleRow = pScrollBar->GetThumbPos();
+ pScrollBar->SetRangeMax(std::min(mpDoc->MaxRow(), static_cast<SCROW>(mnFirstVisibleRow + 100)));
+ mpRowView->SetPos(mnFirstVisibleRow);
+ }
+ else
+ {
+ mnFirstVisibleCol = pScrollBar->GetThumbPos();
+ pScrollBar->SetRangeMax(std::min(mpDoc->MaxCol(), static_cast<SCCOL>(mnFirstVisibleCol + 50)));
+ mpColView->SetPos(mnFirstVisibleCol);
+ }
+ Invalidate();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */