diff options
author | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2017-08-27 10:55:55 +0200 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2017-08-29 12:17:09 +0200 |
commit | 80798551e77dab68b49c3e19fad5b455afe0ef45 (patch) | |
tree | b3943f17c797465c104829418348c87d9fc19170 /sc/source | |
parent | 218ca21147c0a8c7da4691ed63915499cfc1c80e (diff) |
external data: add a simple table view for spreadsheet data
Change-Id: I3c22a908c5e1dd1a02494931478ca7e29ecea0c2
Reviewed-on: https://gerrit.libreoffice.org/41599
Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
Tested-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
Diffstat (limited to 'sc/source')
-rw-r--r-- | sc/source/ui/inc/datatableview.hxx | 109 | ||||
-rw-r--r-- | sc/source/ui/miscdlgs/datatableview.cxx | 280 |
2 files changed, 389 insertions, 0 deletions
diff --git a/sc/source/ui/inc/datatableview.hxx b/sc/source/ui/inc/datatableview.hxx new file mode 100644 index 000000000000..2057032624b2 --- /dev/null +++ b/sc/source/ui/inc/datatableview.hxx @@ -0,0 +1,109 @@ +/* -*- 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 . + */ + +#ifndef INCLUDED_SC_SOURCE_UI_INC_DATATABELVIEW_HXX +#define INCLUDED_SC_SOURCE_UI_INC_DATATABELVIEW_HXX + +#include <vcl/ctrl.hxx> + +#include "scdllapi.h" +#include "types.hxx" +#include "hdrcont.hxx" + +class ScDocument; + +class ScDataTableColView : public ScHeaderControl +{ + ScDocument* mpDoc; + SCCOL mnCol; + +public: + + ScDataTableColView(vcl::Window* pParent, ScDocument* pDoc, SelectionEngine* pSelectionEngine); + + void SetPos(SCCOLROW nRow); + + virtual SCCOLROW GetPos() const override; + virtual sal_uInt16 GetEntrySize(SCCOLROW nPos) const override; + virtual OUString GetEntryText(SCCOLROW nPos) const override; + virtual bool IsLayoutRTL() const override; + virtual void SetEntrySize(SCCOLROW nPos, sal_uInt16 nWidth) override; + virtual void HideEntries(SCCOLROW nPos, SCCOLROW nEndPos) override; +}; + +class ScDataTableRowView : public ScHeaderControl +{ + ScDocument* mpDoc; + SCROW mnRow; + +public: + + ScDataTableRowView(vcl::Window* pParent, ScDocument* pDoc, SelectionEngine* pSelectionEngine); + + void SetPos(SCCOLROW nRow); + + virtual SCCOLROW GetPos() const override; + virtual sal_uInt16 GetEntrySize(SCCOLROW nPos) const override; + virtual OUString GetEntryText(SCCOLROW nPos) const override; + virtual bool IsLayoutRTL() const override; + virtual void SetEntrySize(SCCOLROW nPos, sal_uInt16 nWidth) override; + virtual void HideEntries(SCCOLROW nPos, SCCOLROW nEndPos) override; +}; + +/* + * A simple UI component that presents a data table. + * + * Shares as much code as possible with the normal + * Calc grid rendering. + * + * This class should only depend on ScDocument and not + * on some of the Calc view shells. + */ +class SC_DLLPUBLIC ScDataTableView : public Control +{ + std::shared_ptr<ScDocument> mpDoc; + std::unique_ptr<SelectionEngine> mpSelectionEngine; + VclPtr<ScDataTableColView> mpColView; + VclPtr<ScDataTableRowView> mpRowView; + VclPtr<ScrollBar> mpVScroll; + VclPtr<ScrollBar> mpHScroll; + + SCROW mnFirstVisibleRow; + SCCOL mnFirstVisibleCol; + + std::unique_ptr<MouseEvent> mpMouseEvent; + + DECL_LINK( ScrollHdl, ScrollBar*, void ); + +public: + ScDataTableView(vcl::Window* pParent, std::shared_ptr<ScDocument> pDoc); + + ~ScDataTableView() override; + + virtual void dispose() override; + + virtual void MouseButtonDown(const MouseEvent& rMEvt) override; + virtual void MouseButtonUp(const MouseEvent& rMEvt) override; + virtual void Resize() override; + virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/miscdlgs/datatableview.cxx b/sc/source/ui/miscdlgs/datatableview.cxx new file mode 100644 index 000000000000..2d8c65267180 --- /dev/null +++ b/sc/source/ui/miscdlgs/datatableview.cxx @@ -0,0 +1,280 @@ +/* -*- 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 "viewdata.hxx" +#include "output.hxx" +#include "fillinfo.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, 1024, 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); +} + +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, 1024, 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); +} + +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(vcl::Window* pParent, std::shared_ptr<ScDocument> pDoc): + Control(pParent), + mpDoc(pDoc), + mpSelectionEngine(new SelectionEngine(this)), + 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) +{ + 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)); + + mpColView->Show(); + mpRowView->Show(); + mpVScroll->Show(); + mpHScroll->Show(); +} + +ScDataTableView::~ScDataTableView() +{ + disposeOnce(); +} + +void ScDataTableView::dispose() +{ + 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, ScDocument* pDoc, SCCOL nStartCol = 0) +{ + nPixelPos -= nRowHeaderWidth; + sal_uInt32 nPixelLength = 0; + for (SCCOL nCol = nStartCol; nCol <= MAXCOL; ++nCol) + { + 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 -1; +} + +SCROW findRowFromPos(sal_uInt16 nPixelPos, ScDocument* pDoc, SCROW nStartRow = 0) +{ + nPixelPos -= nColHeaderHeight; + sal_uInt32 nPixelLength = 0; + for (SCROW nRow = nStartRow; nRow <= 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 -1; +} + +} + +void ScDataTableView::MouseButtonUp(const MouseEvent& rMEvt) +{ + 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(); + 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); + SCCOL 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); +} + +IMPL_LINK(ScDataTableView, ScrollHdl, ScrollBar*, pScrollBar, void) +{ + if (pScrollBar == mpVScroll.get()) + { + mnFirstVisibleRow = pScrollBar->GetThumbPos(); + pScrollBar->SetRangeMax(mnFirstVisibleRow + 100); + mpRowView->SetPos(mnFirstVisibleRow); + } + else + { + mnFirstVisibleCol = pScrollBar->GetThumbPos(); + pScrollBar->SetRangeMax(mnFirstVisibleCol + 50); + mpColView->SetPos(mnFirstVisibleCol); + } + Invalidate(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |