diff options
author | Caolán McNamara <caolanm@redhat.com> | 2022-08-05 14:46:37 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2022-08-06 13:09:49 +0200 |
commit | 4d96e375c28f9fe2dded40cba4ee8c67f77817f3 (patch) | |
tree | d5f3be07570199a4019863482d6b67a9e140a57a /svtools | |
parent | 488b69db9844e40fb432b847a271a92fd9e7414a (diff) |
move SVTXGridControl to toolkit
Change-Id: I513a2885027d0295f70e7c64269d1653a6c2642b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137870
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'svtools')
30 files changed, 0 insertions, 9864 deletions
diff --git a/svtools/Library_svt.mk b/svtools/Library_svt.mk index 9050425d3dd8..bc7d07b3bd48 100644 --- a/svtools/Library_svt.mk +++ b/svtools/Library_svt.mk @@ -145,14 +145,6 @@ $(eval $(call gb_Library_add_exception_objects,svt,\ svtools/source/svrtf/rtfkeywd \ svtools/source/svrtf/rtfout \ svtools/source/svrtf/svparser \ - svtools/source/table/defaultinputhandler \ - svtools/source/table/gridtablerenderer \ - svtools/source/table/tablecontrol \ - svtools/source/table/tablecontrol_impl \ - svtools/source/table/tabledatawindow \ - svtools/source/table/mousefunction \ - svtools/source/table/cellvalueconversion \ - svtools/source/table/tablegeometry \ svtools/source/uno/addrtempuno \ svtools/source/uno/fpicker \ svtools/source/uno/framestatuslistener \ @@ -161,12 +153,8 @@ $(eval $(call gb_Library_add_exception_objects,svt,\ svtools/source/uno/popupmenucontrollerbase \ svtools/source/uno/popupwindowcontroller \ svtools/source/uno/statusbarcontroller \ - svtools/source/uno/svtxgridcontrol \ svtools/source/uno/toolboxcontroller \ - svtools/source/uno/unocontroltablemodel \ - svtools/source/uno/unogridcolumnfacade \ svtools/source/uno/unoevent \ - svtools/source/uno/unoiface \ svtools/source/uno/unoimap \ svtools/source/uno/wizard/unowizard \ svtools/source/uno/wizard/wizardpagecontroller \ diff --git a/svtools/inc/mousefunction.hxx b/svtools/inc/mousefunction.hxx deleted file mode 100644 index 00313b0f4497..000000000000 --- a/svtools/inc/mousefunction.hxx +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include "table/tabletypes.hxx" - -#include <salhelper/simplereferenceobject.hxx> - -class MouseEvent; - -namespace svt::table -{ -class ITableControl; - -//= FunctionResult - -enum FunctionResult -{ - ActivateFunction, - ContinueFunction, - DeactivateFunction, - - SkipFunction -}; - -//= MouseFunction - -class MouseFunction : public ::salhelper::SimpleReferenceObject -{ -public: - MouseFunction() {} - MouseFunction(const MouseFunction&) = delete; - MouseFunction& operator=(const MouseFunction&) = delete; - virtual FunctionResult handleMouseMove(ITableControl& i_tableControl, MouseEvent const& i_event) - = 0; - virtual FunctionResult handleMouseDown(ITableControl& i_tableControl, MouseEvent const& i_event) - = 0; - virtual FunctionResult handleMouseUp(ITableControl& i_tableControl, MouseEvent const& i_event) - = 0; - -protected: - virtual ~MouseFunction() override {} -}; - -//= ColumnResize - -class ColumnResize final : public MouseFunction -{ -public: - ColumnResize() - : m_nResizingColumn(COL_INVALID) - { - } - -public: - // MouseFunction - virtual FunctionResult handleMouseMove(ITableControl& i_tableControl, - MouseEvent const& i_event) override; - virtual FunctionResult handleMouseDown(ITableControl& i_tableControl, - MouseEvent const& i_event) override; - virtual FunctionResult handleMouseUp(ITableControl& i_tableControl, - MouseEvent const& i_event) override; - -private: - ColPos m_nResizingColumn; -}; - -//= RowSelection - -class RowSelection final : public MouseFunction -{ -public: - RowSelection() - : m_bActive(false) - { - } - -public: - // MouseFunction - virtual FunctionResult handleMouseMove(ITableControl& i_tableControl, - MouseEvent const& i_event) override; - virtual FunctionResult handleMouseDown(ITableControl& i_tableControl, - MouseEvent const& i_event) override; - virtual FunctionResult handleMouseUp(ITableControl& i_tableControl, - MouseEvent const& i_event) override; - -private: - bool m_bActive; -}; - -//= ColumnSortHandler - -class ColumnSortHandler final : public MouseFunction -{ -public: - ColumnSortHandler() - : m_nActiveColumn(COL_INVALID) - { - } - -public: - // MouseFunction - virtual FunctionResult handleMouseMove(ITableControl& i_tableControl, - MouseEvent const& i_event) override; - virtual FunctionResult handleMouseDown(ITableControl& i_tableControl, - MouseEvent const& i_event) override; - virtual FunctionResult handleMouseUp(ITableControl& i_tableControl, - MouseEvent const& i_event) override; - -private: - ColPos m_nActiveColumn; -}; - -} // namespace svt::table - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/inc/table/defaultinputhandler.hxx b/svtools/inc/table/defaultinputhandler.hxx deleted file mode 100644 index add1a06935a0..000000000000 --- a/svtools/inc/table/defaultinputhandler.hxx +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <table/tableinputhandler.hxx> -#include <rtl/ref.hxx> -#include <mousefunction.hxx> - -#include <vector> - - -namespace svt::table -{ - - class DefaultInputHandler final : public ITableInputHandler - { - public: - DefaultInputHandler(); - virtual ~DefaultInputHandler() override; - - virtual bool MouseMove ( ITableControl& _rControl, const MouseEvent& rMEvt ) override; - virtual bool MouseButtonDown ( ITableControl& _rControl, const MouseEvent& rMEvt ) override; - virtual bool MouseButtonUp ( ITableControl& _rControl, const MouseEvent& rMEvt ) override; - virtual bool KeyInput ( ITableControl& _rControl, const KeyEvent& rKEvt ) override; - virtual bool GetFocus ( ITableControl& _rControl ) override; - virtual bool LoseFocus ( ITableControl& _rControl ) override; - - private: - bool delegateMouseEvent( ITableControl& i_control, const MouseEvent& i_event, - FunctionResult ( MouseFunction::*i_handlerMethod )( ITableControl&, const MouseEvent& ) ); - - rtl::Reference< MouseFunction > pActiveFunction; - std::vector< rtl::Reference< MouseFunction > > aMouseFunctions; - }; - - -} // namespace svt::table - - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/inc/table/gridtablerenderer.hxx b/svtools/inc/table/gridtablerenderer.hxx deleted file mode 100644 index e372de3241e5..000000000000 --- a/svtools/inc/table/gridtablerenderer.hxx +++ /dev/null @@ -1,116 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <table/tablemodel.hxx> -#include <vcl/image.hxx> - -#include <memory> - - -namespace svt::table -{ - - - struct GridTableRenderer_Impl; - - - //= GridTableRenderer - - /** a default implementation for the ->ITableRenderer interface - - This class is able to paint a table grid, table headers, and cell - backgrounds according to the selected/active state of cells. - */ - class GridTableRenderer final : public ITableRenderer - { - private: - ::std::unique_ptr< GridTableRenderer_Impl > m_pImpl; - - public: - /** creates a table renderer associated with the given model - - @param _rModel - the model which should be rendered. The caller is responsible - for lifetime control, that is, the model instance must live - at least as long as the renderer instance lives - */ - GridTableRenderer( ITableModel& _rModel ); - virtual ~GridTableRenderer() override; - - /** determines whether or not to paint grid lines - */ - bool useGridLines() const; - - /** controls whether or not to paint grid lines - */ - void useGridLines( bool const i_use ); - - public: - // ITableRenderer overridables - virtual void PaintHeaderArea( - vcl::RenderContext& _rDevice, const tools::Rectangle& _rArea, - bool _bIsColHeaderArea, bool _bIsRowHeaderArea, - const StyleSettings& _rStyle ) override; - virtual void PaintColumnHeader( ColPos _nCol, - vcl::RenderContext& _rDevice, const tools::Rectangle& _rArea, - const StyleSettings& _rStyle ) override; - virtual void PrepareRow( RowPos _nRow, bool i_hasControlFocus, bool _bSelected, - vcl::RenderContext& _rDevice, const tools::Rectangle& _rRowArea, - const StyleSettings& _rStyle ) override; - virtual void PaintRowHeader( - vcl::RenderContext& _rDevice, const tools::Rectangle& _rArea, - const StyleSettings& _rStyle ) override; - virtual void PaintCell( ColPos const i_col, - bool i_hasControlFocus, bool _bSelected, - vcl::RenderContext& _rDevice, const tools::Rectangle& _rArea, - const StyleSettings& _rStyle ) override; - virtual void ShowCellCursor( vcl::Window& _rView, const tools::Rectangle& _rCursorRect) override; - virtual void HideCellCursor( vcl::Window& _rView ) override; - virtual bool FitsIntoCell( - css::uno::Any const & i_cellContent, - OutputDevice& i_targetDevice, tools::Rectangle const & i_targetArea - ) const override; - virtual bool GetFormattedCellString( - css::uno::Any const & i_cellValue, - OUString & o_cellString - ) const override; - - private: - struct CellRenderContext; - - void impl_paintCellContent( - CellRenderContext const & i_context - ); - void impl_paintCellImage( - CellRenderContext const & i_context, - Image const & i_image - ); - void impl_paintCellText( - CellRenderContext const & i_context, - OUString const & i_text - ); - }; - -} // namespace svt::table - - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/inc/table/tablecontrol.hxx b/svtools/inc/table/tablecontrol.hxx deleted file mode 100644 index 82a1ddbead69..000000000000 --- a/svtools/inc/table/tablecontrol.hxx +++ /dev/null @@ -1,173 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <table/tablemodel.hxx> -#include <vcl/accessibletable.hxx> - -#include <vcl/ctrl.hxx> -#include <vcl/seleng.hxx> - -#include <memory> - -namespace svt::table -{ - class TableControl_Impl; - - - //= TableControl - - /** a basic control which manages table-like data, i.e. a number of cells - organized in <code>m</code> rows and <code>n</code> columns. - - The control itself does not do any assumptions about the concrete data - it displays, this is encapsulated in an instance supporting the - ->ITableModel interface. - - Also, the control does not do any assumptions about how the model's - content is rendered. This is the responsibility of a component - supporting the ->ITableRenderer interface (the renderer is obtained from - the model). - - The control supports the concept of a <em>current</em> (or <em>active</em> - cell). - The control supports accessibility, this is encapsulated in IAccessibleTable - */ - class TableControl final : public Control, public vcl::table::IAccessibleTable - { - private: - std::shared_ptr<TableControl_Impl> m_pImpl; - - - public: - TableControl( vcl::Window* _pParent, WinBits _nStyle ); - virtual ~TableControl() override; - virtual void dispose() override; - - /// sets a new table model - void SetModel( const PTableModel& _pModel ); - /// retrieves the current table model - PTableModel GetModel() const; - - /** retrieves the current row - - The current row is the one which contains the active cell. - - @return - the row index of the active cell, or ->ROW_INVALID - if there is no active cell, e.g. because the table does - not contain any rows or columns. - */ - sal_Int32 GetCurrentRow() const override; - - ITableControl& - getTableControlInterface(); - - /** retrieves the current column - - The current col is the one which contains the active cell. - - @return - the column index of the active cell, or ->COL_INVALID - if there is no active cell, e.g. because the table does - not contain any rows or columns. - */ - sal_Int32 GetCurrentColumn() const override; - - /** activates the cell at the given position - */ - void GoTo( ColPos _nColumnPos, RowPos _nRow); - - virtual void Resize() override; - void Select(); - - /**after removing a row, updates the vector which contains the selected rows - if the row, which should be removed, is selected, it will be erased from the vector - */ - SelectionEngine* getSelEngine(); - vcl::Window& getDataWindow(); - - // Window overridables - virtual void GetFocus() override; - virtual void LoseFocus() override; - virtual void KeyInput( const KeyEvent& rKEvt ) override; - virtual void StateChanged( StateChangedType i_nStateChange ) override; - - /** Creates and returns the accessible object of the whole GridControl. */ - virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessible() override; - virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessibleControl( sal_Int32 _nIndex ) override; - virtual OUString GetAccessibleObjectName(vcl::table::AccessibleTableControlObjType eObjType, sal_Int32 _nRow, sal_Int32 _nCol) const override; - virtual void GoToCell( sal_Int32 _nColumnPos, sal_Int32 _nRow ) override; - virtual OUString GetAccessibleObjectDescription(vcl::table::AccessibleTableControlObjType eObjType) const override; - virtual void FillAccessibleStateSet( sal_Int64& rStateSet, vcl::table::AccessibleTableControlObjType eObjType ) const override; - - // temporary methods - // Those do not really belong into the public API - they're intended for firing A11Y-related events. However, - // firing those events should be an implementation internal to the TableControl resp. TableControl_Impl, - // instead of something triggered externally. - void commitCellEventIfAccessibleAlive( sal_Int16 const i_eventID, const css::uno::Any& i_newValue, const css::uno::Any& i_oldValue ); - void commitTableEventIfAccessibleAlive( sal_Int16 const i_eventID, const css::uno::Any& i_newValue, const css::uno::Any& i_oldValue ); - - - // IAccessibleTable - virtual tools::Rectangle GetWindowExtentsRelative(const vcl::Window *pRelativeWindow) const override; - virtual void GrabFocus() override; - virtual css::uno::Reference< css::accessibility::XAccessible > GetAccessible() override; - virtual vcl::Window* GetAccessibleParentWindow() const override; - virtual vcl::Window* GetWindowInstance() override; - virtual sal_Int32 GetAccessibleControlCount() const override; - virtual bool ConvertPointToControlIndex( sal_Int32& _rnIndex, const Point& _rPoint ) override; - virtual sal_Int32 GetRowCount() const override; - virtual sal_Int32 GetColumnCount() const override; - virtual bool ConvertPointToCellAddress( sal_Int32& _rnRow, sal_Int32& _rnColPos, const Point& _rPoint ) override; - virtual tools::Rectangle calcHeaderRect( bool _bIsColumnBar ) override; - virtual tools::Rectangle calcHeaderCellRect( bool _bIsColumnBar, sal_Int32 nPos) override; - virtual tools::Rectangle calcTableRect() override; - virtual tools::Rectangle calcCellRect( sal_Int32 _nRowPos, sal_Int32 _nColPos ) override; - virtual tools::Rectangle GetFieldCharacterBounds(sal_Int32 _nRow,sal_Int32 _nColumnPos,sal_Int32 nIndex) override; - virtual sal_Int32 GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint) override; - virtual void FillAccessibleStateSetForCell( sal_Int64& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumnPos ) const override; - virtual OUString GetRowName(sal_Int32 _nIndex) const override; - virtual OUString GetColumnName( sal_Int32 _nIndex ) const override; - virtual bool HasRowHeader() override; - virtual bool HasColHeader() override; - virtual OUString GetAccessibleCellText(sal_Int32 _nRowPos, sal_Int32 _nColPos) const override; - - virtual sal_Int32 GetSelectedRowCount() const override; - virtual sal_Int32 GetSelectedRowIndex( sal_Int32 const i_selectionIndex ) const override; - virtual bool IsRowSelected( sal_Int32 const i_rowIndex ) const override; - virtual void SelectRow( sal_Int32 const i_rowIndex, bool const i_select ) override; - virtual void SelectAllRows( bool const i_select ) override; - - - private: - DECL_LINK( ImplSelectHdl, LinkParamNone*, void ); - - private: - TableControl( const TableControl& ) = delete; - TableControl& operator=( const TableControl& ) = delete; - }; - - -} // namespace svt::table - - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/inc/table/tablecontrolinterface.hxx b/svtools/inc/table/tablecontrolinterface.hxx deleted file mode 100644 index 6a592728494e..000000000000 --- a/svtools/inc/table/tablecontrolinterface.hxx +++ /dev/null @@ -1,237 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <sal/types.h> -#include <vcl/seleng.hxx> -#include <vcl/window.hxx> - -#include <table/tabletypes.hxx> -#include <table/tablemodel.hxx> - -namespace svt::table -{ - //= TableControlAction - enum TableControlAction - { - /// moves the cursor in the table control one row up, if possible, by keeping the current column - cursorUp, - /// moves the cursor in the table control one row down, if possible, by keeping the current column - cursorDown, - /// moves the cursor in the table control one column to the left, if possible, by keeping the current row - cursorLeft, - /// moves the cursor in the table control one column to the right, if possible, by keeping the current row - cursorRight, - /// moves the cursor to the beginning of the current line - cursorToLineStart, - /// moves the cursor to the end of the current line - cursorToLineEnd, - /// moves the cursor to the first row, keeping the current column - cursorToFirstLine, - /// moves the cursor to the last row, keeping the current column - cursorToLastLine, - /// moves the cursor one page up, keeping the current column - cursorPageUp, - /// moves the cursor one page down, keeping the current column - cursorPageDown, - /// moves the cursor to the top-most, left-most cell - cursorTopLeft, - /// moves the cursor to the bottom-most, right-most cell - cursorBottomRight, - /// selects the row, where the actual cursor is - cursorSelectRow, - /// selects the rows, above the actual cursor is - cursorSelectRowUp, - /// selects the row, beneath the actual cursor is - cursorSelectRowDown, - /// selects the row, from the actual cursor till top - cursorSelectRowAreaTop, - /// selects the row, from the actual cursor till bottom - cursorSelectRowAreaBottom, - - /// invalid and final enumeration value, not to be actually used - invalidTableControlAction - }; - - - //= TableCellArea - - enum TableCellArea - { - CellContent, - ColumnDivider - }; - - - //= TableCell - - struct TableCell - { - ColPos nColumn; - RowPos nRow; - TableCellArea eArea; - - TableCell( ColPos const i_column, RowPos const i_row ) - :nColumn( i_column ) - ,nRow( i_row ) - ,eArea( CellContent ) - { - } - }; - - - //= ColumnMetrics - - struct ColumnMetrics - { - /** the start of the column, in pixels. Might be negative, in case the column is scrolled out of the visible - area. Note: see below. - */ - tools::Long nStartPixel; - - /** the end of the column, in pixels, plus 1. Effectively, this is the accumulated width of all columns - up to the current one. - - Huh? Earlier you said that the nStartPixel of columns - scrolled out (to the left) of the visible area is - negative. Also, where is the promise that there is no gap - between columns? The above claim would be true only if the - first column always started at zero, and there is never a - gap. So these doc comments are inconsistent. How - surprising. - */ - tools::Long nEndPixel; - - ColumnMetrics() - :nStartPixel(0) - ,nEndPixel(0) - { - } - - ColumnMetrics( tools::Long const i_start, tools::Long const i_end ) - :nStartPixel( i_start ) - ,nEndPixel( i_end ) - { - } - }; - - - //= TableArea - - enum class TableArea - { - ColumnHeaders, - RowHeaders, - All - }; - - - //= ITableControl - - /** defines a callback interface to be implemented by a concrete table control - */ - class SAL_NO_VTABLE ITableControl - { - public: - /** hides the cell cursor - - The method cares for successive calls, that is, for every call to - ->hideCursor(), you need one call to ->showCursor. Only if the number - of both calls matches, the cursor is really shown. - - @see showCursor - */ - virtual void hideCursor() = 0; - - /** shows the cell cursor - - @see hideCursor - */ - virtual void showCursor() = 0; - - /** dispatches an action to the table control - - @return - <TRUE/> if the action could be dispatched successfully, <FALSE/> otherwise. Usual - failure conditions include some other instance vetoing the action, or impossibility - to execute the action at all (for instance moving up one row when already positioned - on the very first row). - - @see TableControlAction - */ - virtual bool dispatchAction( TableControlAction _eAction ) = 0; - - /** returns selection engine*/ - virtual SelectionEngine* getSelEngine() = 0; - - /** returns the table model - - The returned model is guaranteed to not be <NULL/>. - */ - virtual PTableModel getModel() const = 0; - - /// returns the index of the currently active column - virtual ColPos getCurrentColumn() const = 0; - - /// returns the index of the currently active row - virtual RowPos getCurrentRow() const = 0; - - /// activates the given cell - virtual void activateCell( ColPos const i_col, RowPos const i_row ) = 0; - - /// retrieves the size of the table window, in pixels - virtual ::Size getTableSizePixel() const = 0; - - /// sets a new mouse pointer for the table window - virtual void setPointer( PointerStyle i_pointer ) = 0; - - /// captures the mouse to the table window - virtual void captureMouse() = 0; - - /// releases the mouse, after it had previously been captured - virtual void releaseMouse() = 0; - - /// invalidates the table window - virtual void invalidate( TableArea const i_what ) = 0; - - /// calculates a width, given in pixels, into an AppFont-based width - virtual tools::Long pixelWidthToAppFont( tools::Long const i_pixels ) const = 0; - - /// shows a tracking rectangle - virtual void showTracking( tools::Rectangle const & i_location, ShowTrackFlags const i_flags ) = 0; - - /// hides a previously shown tracking rectangle - virtual void hideTracking() = 0; - - /// does a hit test for the given pixel coordinates - virtual TableCell hitTest( const Point& rPoint ) const = 0; - - /// retrieves the metrics for a given column - virtual ColumnMetrics getColumnMetrics( ColPos const i_column ) const = 0; - - /// determines whether a given row is selected - virtual bool isRowSelected( RowPos _nRow ) const = 0; - - virtual ~ITableControl() {}; - }; - -} // namespace svt::table - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/inc/table/tableinputhandler.hxx b/svtools/inc/table/tableinputhandler.hxx deleted file mode 100644 index 9d11df38db3d..000000000000 --- a/svtools/inc/table/tableinputhandler.hxx +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <memory> - -class MouseEvent; -class KeyEvent; - - -namespace svt::table -{ - - - class ITableControl; - - - //= ITableInputHandler - - /** interface for components handling input in a ->TableControl - */ - class ITableInputHandler - { - public: - // all those methods have the same semantics as the equal-named methods of ->Window, - // with the additional option to return a boolean value indicating whether - // the event should be further processed by the ->Window implementations (<FALSE/>), - // or whether it has been sufficiently handled by the ->ITableInputHandler instance - // (<FALSE/>). - - virtual bool MouseMove ( ITableControl& _rControl, const MouseEvent& rMEvt ) = 0; - virtual bool MouseButtonDown ( ITableControl& _rControl, const MouseEvent& rMEvt ) = 0; - virtual bool MouseButtonUp ( ITableControl& _rControl, const MouseEvent& rMEvt ) = 0; - virtual bool KeyInput ( ITableControl& _rControl, const KeyEvent& rKEvt ) = 0; - virtual bool GetFocus ( ITableControl& _rControl ) = 0; - virtual bool LoseFocus ( ITableControl& _rControl ) = 0; - - virtual ~ITableInputHandler() { } - }; - typedef std::shared_ptr< ITableInputHandler > PTableInputHandler; - - -} // namespace svt::table - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/inc/table/tablemodel.hxx b/svtools/inc/table/tablemodel.hxx deleted file mode 100644 index b3bcc36e9f8c..000000000000 --- a/svtools/inc/table/tablemodel.hxx +++ /dev/null @@ -1,454 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <svtools/svtdllapi.h> -#include <table/tabletypes.hxx> -#include <table/tablerenderer.hxx> -#include <table/tableinputhandler.hxx> - -#include <com/sun/star/style/VerticalAlignment.hpp> -#include <com/sun/star/style/HorizontalAlignment.hpp> - -#include <sal/types.h> - -#include <optional> -#include <memory> -#include <vector> -#include <o3tl/typed_flags_set.hxx> - -namespace svt::table { class ITableDataSort; } - -class Color; - -enum class ColumnAttributeGroup -{ - NONE = 0x00, - /// denotes column attributes related to the width of the column - WIDTH = 0x01, - /// denotes column attributes related to the appearance of the column, i.e. those relevant for rendering - APPEARANCE = 0x02, - /// denotes the entirety of column attributes - ALL = 0x03, -}; -namespace o3tl -{ - template<> struct typed_flags<ColumnAttributeGroup> : is_typed_flags<ColumnAttributeGroup, 0x03> {}; -} - - -namespace svt::table -{ - //= ScrollbarVisibility - enum ScrollbarVisibility - { - /** enumeration value denoting that a scrollbar should never be visible, even - if needed normally - */ - ScrollbarShowNever, - /** enumeration value denoting that a scrollbar should be visible when needed only - */ - ScrollbarShowSmart, - /** enumeration value denoting that a scrollbar should always be visible, even - if not needed normally - */ - ScrollbarShowAlways - }; - - - //= ITableModelListener - - /** declares an interface to be implemented by components interested in - changes in an ->ITableModel - */ - class SAL_NO_VTABLE ITableModelListener : public std::enable_shared_from_this< ITableModelListener > - { - public: - /** notifies the listener that one or more rows have been inserted into - the table - - @param first - the index of the first newly inserted row - @param last - the index of the last newly inserted row. Must not be smaller - than ->first - */ - virtual void rowsInserted( RowPos first, RowPos last ) = 0; - - /** notifies the listener that one or more rows have been removed from - the table - - @param first - the old index of the first removed row. If this is <code>-1</code>, then all - rows have been removed from the model. - @param last - the old index of the last removed row. Must not be smaller - than ->first - */ - virtual void rowsRemoved( RowPos first, RowPos last ) = 0; - - /** notifies the listener that one or more columns have been inserted into - the table - */ - virtual void columnInserted() = 0; - - /** notifies the listener that one or more columns have been removed from - the table - */ - virtual void columnRemoved() = 0; - - /** notifies the listener that all columns have been removed from the model - */ - virtual void allColumnsRemoved() = 0; - - /** notifies the listener that a rectangular cell range in the table - has been updated - - Listeners are required to discard any possibly cached information - they have about the cells in question, in particular any possibly - cached cell values. - */ - virtual void cellsUpdated( RowPos const i_firstRow, RowPos const i_lastRow ) = 0; - - /** notifies the listener that attributes of a given column changed - - @param i_column - the position of the column whose attributes changed - @param i_attributeGroup - a combination of one or more <code>COL_ATTRS_*</code> flags, denoting the attribute group(s) - in which changes occurred. - */ - virtual void columnChanged( ColPos const i_column, ColumnAttributeGroup const i_attributeGroup ) = 0; - - /** notifies the listener that the metrics of the table changed. - - Metrics here include the column header height, the row header width, the row height, and the presence - of both the row and column header. - */ - virtual void tableMetricsChanged() = 0; - - /// deletes the listener instance - virtual ~ITableModelListener(){}; - }; - typedef std::shared_ptr< ITableModelListener > PTableModelListener; - - - //= IColumnModel - - /** interface to be implemented by table column models - */ - class SAL_NO_VTABLE IColumnModel - { - public: - /** returns the name of the column - - Column names should be human-readable, but not necessarily unique - within a given table. - - @see setName - */ - virtual OUString getName() const = 0; - - /** retrieves the help text to be displayed for the column. - */ - virtual OUString getHelpText() const = 0; - - /** determines whether the column can be interactively resized - - @see getMinWidth - @see getMaxWidth - @see getWidth - */ - virtual bool isResizable() const = 0; - - /** denotes the relative flexibility of the column - - This flexibility is taken into account when a table control auto-resizes its columns, because the available - space changed. In this case, the columns grow or shrink according to their flexibility. - - A value of 0 means the column is not auto-resized at all. - */ - virtual sal_Int32 getFlexibility() const = 0; - - /** returns the width of the column, in app-font units - - The returned value must be a positive ->TableMetrics value. - - @see setWidth - @see getMinWidth - @see getMaxWidth - */ - virtual TableMetrics getWidth() const = 0; - - /** sets a new width for the column - - @param _nWidth - the new width, app-font units - - @see getWidth - */ - virtual void setWidth( TableMetrics _nWidth ) = 0; - - /** returns the minimum width of the column, in app-font units, or 0 if the column - does not have a minimal width - - @see setMinWidth - @see getMaxWidth - @see getWidth - */ - virtual TableMetrics getMinWidth() const = 0; - - /** returns the maximum width of the column, in app-font units, or 0 if the column - does not have a minimal width - - @see setMaxWidth - @see getMinWidth - @see getWidth - */ - virtual TableMetrics getMaxWidth() const = 0; - - /** retrieves the horizontal alignment to be used for content in this cell - */ - virtual css::style::HorizontalAlignment getHorizontalAlign() = 0; - - /// deletes the column model instance - virtual ~IColumnModel() { } - }; - typedef std::shared_ptr< IColumnModel > PColumnModel; - - - //= ITableModel - - /** declares the interface to implement by an abstract table model - */ - class SAL_NO_VTABLE SVT_DLLPUBLIC ITableModel - { - public: - /** returns the number of columns in the table - */ - virtual TableSize getColumnCount() const = 0; - - /** returns the number of rows in the table - */ - virtual TableSize getRowCount() const = 0; - - /** determines whether the table has column headers - - If this method returns <TRUE/>, the renderer returned by - ->getRenderer must be able to render column headers. - - @see IColumnRenderer - */ - virtual bool hasColumnHeaders() const = 0; - - /** determines whether the table has row headers - - If this method returns <TRUE/>, the renderer returned by - ->getRenderer must be able to render row headers. - - @see IColumnRenderer - */ - virtual bool hasRowHeaders() const = 0; - - /** returns a model for a certain column - - @param column - the index of the column in question. Must be greater than or - equal 0, and smaller than the return value of ->getColumnCount() - - @return - the model of the column in question. Must not be <NULL/> - */ - virtual PColumnModel getColumnModel( ColPos column ) = 0; - - /** returns a renderer which is able to paint the table represented - by this table model - - @return the renderer to use. Must not be <NULL/> - */ - virtual PTableRenderer getRenderer() const = 0; - - /** returns the component handling input in a view associated with the model - */ - virtual PTableInputHandler getInputHandler() const = 0; - - /** determines the height of rows in the table. - - @return - the logical height of rows in the table, in app-font units. The height must be - greater 0. - */ - virtual TableMetrics getRowHeight() const = 0; - - /** determines the height of the column header row - - This method is not to be called if ->hasColumnHeaders() - returned <FALSE/>. - - @return - the logical height of the column header row, in app-font units. - Must be greater than 0. - */ - virtual TableMetrics getColumnHeaderHeight() const = 0; - - /** determines the width of the row header column - - This method is not to be called if ->hasRowHeaders() - returned <FALSE/>. - - @return - the logical width of the row header column, in app-font units. - Must be greater than 0. - */ - virtual TableMetrics getRowHeaderWidth() const = 0; - - /** returns the visibility mode of the vertical scrollbar - */ - virtual ScrollbarVisibility getVerticalScrollbarVisibility() const = 0; - - /** returns the visibility mode of the horizontal scrollbar - */ - virtual ScrollbarVisibility getHorizontalScrollbarVisibility() const = 0; - - /** adds a listener to be notified of changes in the table model - */ - virtual void addTableModelListener( const PTableModelListener& i_listener ) = 0; - - /** remove a listener to be notified of changes in the table model - */ - virtual void removeTableModelListener( const PTableModelListener& i_listener ) = 0; - - /** retrieves the content of the given cell - */ - virtual void getCellContent( ColPos const i_col, RowPos const i_row, css::uno::Any& o_cellContent ) = 0; - - /** returns an object which should be displayed as tooltip for the given cell - - At the moment, only string-convertible values are supported here. In the future, one might imagine displaying - scaled-down versions of a graphic in a cell, and a larger version of that very graphic as tooltip. - - If no tooltip object is provided, then the cell content is used, and displayed as tooltip for the cell - if and only if it doesn't fit into the cell's space itself. - - @param i_col - The column index of the cell in question. COL_ROW_HEADERS is a valid argument here. - @param i_row - The row index of the cell in question. - @param o_cellToolTip - takes the tooltip object upon return. - */ - virtual void getCellToolTip( ColPos const i_col, RowPos const i_row, css::uno::Any & o_cellToolTip ) = 0; - - /** retrieves title of a given row - */ - virtual css::uno::Any getRowHeading( RowPos const i_rowPos ) const = 0; - - /** returns the color to be used for rendering the grid lines. - - If this value is not set, a default color from the style settings will be used. - */ - virtual ::std::optional< ::Color > getLineColor() const = 0; - - /** returns the color to be used for rendering the header background. - - If this value is not set, a default color from the style settings will be used. - */ - virtual ::std::optional< ::Color > getHeaderBackgroundColor() const = 0; - - /** returns the color to be used for rendering the header text. - - If this value is not set, a default color from the style settings will be used. - */ - virtual ::std::optional< ::Color > getHeaderTextColor() const = 0; - - /** returns the color to be used for the background of selected cells, when the control has the focus - - If this value is not set, a default color from the style settings will be used. - */ - virtual ::std::optional< ::Color > getActiveSelectionBackColor() const = 0; - - /** returns the color to be used for the background of selected cells, when the control does not have the focus - - If this value is not set, a default color from the style settings will be used. - */ - virtual ::std::optional< ::Color > getInactiveSelectionBackColor() const = 0; - - /** returns the color to be used for the text of selected cells, when the control has the focus - - If this value is not set, a default color from the style settings will be used. - */ - virtual ::std::optional< ::Color > getActiveSelectionTextColor() const = 0; - - /** returns the color to be used for the text of selected cells, when the control does not have the focus - - If this value is not set, a default color from the style settings will be used. - */ - virtual ::std::optional< ::Color > getInactiveSelectionTextColor() const = 0; - - /** returns the color to be used for rendering cell texts. - - If this value is not set, a default color from the style settings will be used. - */ - virtual ::std::optional< ::Color > getTextColor() const = 0; - - /** returns the color to be used for text lines (underline, strikethrough) when rendering cell text. - - If this value is not set, a default color from the style settings will be used. - */ - virtual ::std::optional< ::Color > getTextLineColor() const = 0; - - /** returns the colors to be used for the row backgrounds. - - If this value is not set, every second row will have a background color derived from the style settings's - selection color, the other rows will not have a special background at all. - - If this value is an empty sequence, the rows will not have a special background at all, instead the - normal background of the complete control will be used. - - If value is a non-empty sequence, then rows will have the background colors as specified in the sequence, - in alternating order. - */ - virtual ::std::optional< ::std::vector< ::Color > > - getRowBackgroundColors() const = 0; - - /** determines the vertical alignment of content within a cell - */ - virtual css::style::VerticalAlignment getVerticalAlign() const = 0; - - /** returns an adapter to the sorting functionality of the model - - It is legitimate to return <NULL/> here, in this case, the table model does not support sorting. - */ - virtual ITableDataSort* getSortAdapter() = 0; - - /** returns enabled state. - */ - virtual bool isEnabled() const = 0; - - /// destroys the table model instance - virtual ~ITableModel() { } - }; - typedef std::shared_ptr< ITableModel > PTableModel; - - -} // namespace svt::table - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/inc/table/tablerenderer.hxx b/svtools/inc/table/tablerenderer.hxx deleted file mode 100644 index c43bac81875d..000000000000 --- a/svtools/inc/table/tablerenderer.hxx +++ /dev/null @@ -1,249 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <table/tabletypes.hxx> - -#include <rtl/ustring.hxx> - -#include <memory> - -namespace com :: sun :: star :: uno { class Any; } -namespace tools { class Rectangle; } -namespace vcl { class Window; } - -class OutputDevice; -class StyleSettings; -namespace vcl { - typedef OutputDevice RenderContext; -}; - - -namespace svt::table -{ - - - //= ITableRenderer - - /** interface to implement by components rendering a ->TableControl - */ - class SAL_NO_VTABLE ITableRenderer - { - public: - - /** paints a (part of) header area - - There are two header areas in a table control: - <ul><li>The row containing all column headers, i.e. <em>above</em> all rows containing the data</li> - <li>The column containing all row headers. i.e. <em>left of</em> all columns containing the data</li> - </ul> - - A header area is more than the union of the single column/row headers. - - First, there might be less columns than fit into the view - in this case, right - beside the right-most column, there's still room which belongs to the column header - area, but is not occupied by any particular column header.<br/> - An equivalent statement holds for the row header area, if there are fewer rows than - fit into the view. - - Second, if the table control has both a row header and a column header, - the intersection between those both belongs to both the column header area and the - row header area, but not to any particular column or row header. - - There are two flags specifying whether the to-be-painted area is part of the column - and/or row header area. - <ul><li>If both are <TRUE/>, the intersection of both areas is to be painted.</li> - <li>If ->_bIsColHeaderArea is <TRUE/> and ->_bIsRowHeaderArea is <FALSE/>, - then ->_rArea denotes the column header area <em>excluding</em> the - intersection between row and column header area.</li> - <li>Equivalently for ->_bIsColHeaderArea being <FALSE/> and ->_bIsRowHeaderArea - being <TRUE/></li> - </ul> - Note that it's not possible for both ->_bIsColHeaderArea and ->_bIsRowHeaderArea - to be <FALSE/> at the same time. - - @param _rDevice - the device to paint onto - @param _rArea - the area to paint into - @param _bIsColHeaderArea - <TRUE/> if and only if ->_rArea is part of the column header area. - @param _bIsRowHeaderArea - <TRUE/> if and only if ->_rArea is part of the row header area. - @param _rStyle - the style to be used for drawing - */ - virtual void PaintHeaderArea( - vcl::RenderContext& _rDevice, const tools::Rectangle& _rArea, - bool _bIsColHeaderArea, bool _bIsRowHeaderArea, - const StyleSettings& _rStyle ) = 0; - - /** paints the header for a given column - - @param _nCol - the index of the column to paint - @param _rDevice - denotes the device to paint onto - @param _rArea - the are into which the column header should be painted - @param _rStyle - the style to be used for drawing - */ - virtual void PaintColumnHeader( ColPos _nCol, - vcl::RenderContext& _rDevice, const tools::Rectangle& _rArea, - const StyleSettings& _rStyle ) = 0; - - /** prepares a row for painting - - Painting a table means painting rows as necessary, in an increasing - order. The assumption is that retrieving data for two different rows - is (potentially) more expensive than retrieving data for two different - columns. Thus, the renderer will get the chance to "seek" to a certain - row, and then has to render all cells in this row, before another - row is going to be painted. - - @param _nRow - the row which is going to be painted. The renderer should - at least remember this row, since subsequent calls to - ->PaintRowHeader(), ->PaintCell(), and ->FinishRow() will - not pass this parameter again. - - However, the renderer is also allowed to render any - cell-independent content of this row. - - @param i_hasControlFocus - <TRUE/> if and only if the table control currently has the focus - @param _bSelected - <TRUE/> if and only if the row to be prepared is - selected currently. - @param _rDevice - denotes the device to paint onto - @param _rRowArea - the are into which the row should be painted. This excludes - the row header area, if applicable. - @param _rStyle - the style to be used for drawing - */ - virtual void PrepareRow( RowPos _nRow, bool i_hasControlFocus, bool _bSelected, - vcl::RenderContext& _rDevice, const tools::Rectangle& _rRowArea, - const StyleSettings& _rStyle ) = 0; - - /** paints the header of a row - - The row to be painted is denoted by the most recent call to - ->PrepareRow. - - @param _rDevice - denotes the device to paint onto - @param _rArea - the are into which the row header should be painted - @param _rStyle - the style to be used for drawing - */ - virtual void PaintRowHeader( - vcl::RenderContext& _rDevice, tools::Rectangle const & _rArea, - StyleSettings const & _rStyle ) = 0; - - /** paints a certain cell - - The row to be painted is denoted by the most recent call to - ->PrepareRow. - - @param _bSelected - <TRUE/> if and only if the cell to be painted is - selected currently. This is the case if either - the row or the column of the cell is currently selected. - <br/> - Note that this flag is equal to the respective flag in the - previous ->PrepareRow call, it's passed here for convenience - only. - @param i_hasControlFocus - <TRUE/> if and only if the table control currently has the focus - <br/> - Note that this flag is equal to the respective flag in the - previous ->PrepareRow call, it's passed here for convenience - only. - @param _rDevice - denotes the device to paint onto - @param _rArea - the are into which the cell should be painted - @param _rStyle - the style to be used for drawing - */ - virtual void PaintCell( ColPos const i_col, - bool i_hasControlFocus, bool _bSelected, - vcl::RenderContext& _rDevice, const tools::Rectangle& _rArea, - const StyleSettings& _rStyle ) = 0; - - /** draws a cell cursor in the given rectangle - - The cell cursor is used to indicate the active/current cell - of a table control. - */ - virtual void ShowCellCursor( vcl::Window& _rView, const tools::Rectangle& _rCursorRect) = 0; - - /** hides the cell cursor previously drawn into the given rectangle - - The cell cursor is used to indicate the active/current cell - of a table control. - */ - virtual void HideCellCursor( vcl::Window& _rView ) = 0; - - /** checks whether a given cell content fits into a given target area on a given device. - - @param i_targetDevice - denotes the target device for the assumed rendering operation - - @param i_targetArea - denotes the area within the target device for the assumed rendering operation. - - @return - <TRUE/> if and only if the given cell content could be rendered into the given device and the - given area. - */ - virtual bool FitsIntoCell( - css::uno::Any const & i_cellContent, - OutputDevice& i_targetDevice, tools::Rectangle const & i_targetArea - ) const = 0; - - /** attempts to format the content of the given cell as string - - @param i_cellValue - the value for which an attempt for a string conversion should be made - @param o_cellString - the cell content, formatted as string - @return - <TRUE/> if and only if the content could be formatted as string - */ - virtual bool GetFormattedCellString( - css::uno::Any const & i_cellValue, - OUString & o_cellString - ) const = 0; - - /// deletes the renderer instance - virtual ~ITableRenderer() { } - }; - typedef std::shared_ptr< ITableRenderer > PTableRenderer; - - -} // namespace svt::table - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/inc/table/tablesort.hxx b/svtools/inc/table/tablesort.hxx deleted file mode 100644 index 699086352c9c..000000000000 --- a/svtools/inc/table/tablesort.hxx +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <table/tabletypes.hxx> - - -namespace svt::table -{ - - - //= ColumnSortDirection - - enum ColumnSortDirection - { - ColumnSortAscending, - ColumnSortDescending - }; - - - //= ColumnSort - - struct ColumnSort - { - ColPos nColumnPos; - ColumnSortDirection eSortDirection; - - ColumnSort() - :nColumnPos( COL_INVALID ) - ,eSortDirection( ColumnSortAscending ) - { - } - - }; - - - //= ITableDataSort - - /** provides sorting functionality for the data underlying an ITableModel - */ - class SAL_NO_VTABLE ITableDataSort - { - public: - /** sorts the rows in the model by the given column's data, in the given direction. - */ - virtual void sortByColumn( ColPos const i_column, ColumnSortDirection const i_sortDirection ) = 0; - - /** retrieves the current sort order of the data - - If the <code>nColumnIndex</code> member of the returned structure is <code>COL_INVALID</code>, then - the data is currently not sorted. - */ - virtual ColumnSort getCurrentSortOrder() const = 0; - - protected: - ~ITableDataSort() {} - }; - - -} // namespace svt::table - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/inc/table/tabletypes.hxx b/svtools/inc/table/tabletypes.hxx deleted file mode 100644 index 8fdb18a830d8..000000000000 --- a/svtools/inc/table/tabletypes.hxx +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <sal/types.h> - - -namespace svt::table -{ - - /// a value denoting the size of a table - typedef sal_Int32 TableSize; - - /// a value denoting a column position within a table - typedef sal_Int32 ColPos; - /// a value denoting a row position within a table - typedef sal_Int32 RowPos; - - typedef sal_Int32 TableMetrics; - -/// denotes the column containing the row headers -#define COL_ROW_HEADERS (::svt::table::ColPos(-1)) -/// denotes the row containing the column headers -#define ROW_COL_HEADERS (::svt::table::RowPos(-1)) - -/// denotes an invalid column index -#define COL_INVALID (::svt::table::ColPos(-2)) -/// denotes an invalid row index -#define ROW_INVALID (::svt::table::RowPos(-2)) - - -} // namespace svt::table - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/table/cellvalueconversion.cxx b/svtools/source/table/cellvalueconversion.cxx deleted file mode 100644 index 53177af0d88f..000000000000 --- a/svtools/source/table/cellvalueconversion.cxx +++ /dev/null @@ -1,376 +0,0 @@ -/* -*- 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 "cellvalueconversion.hxx" - -#include <com/sun/star/util/NumberFormatsSupplier.hpp> -#include <com/sun/star/util/NumberFormatter.hpp> -#include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/util/Date.hpp> -#include <com/sun/star/util/Time.hpp> -#include <com/sun/star/util/DateTime.hpp> -#include <com/sun/star/util/XNumberFormatTypes.hpp> -#include <com/sun/star/util/NumberFormat.hpp> -#include <sal/log.hxx> -#include <tools/date.hxx> -#include <tools/time.hxx> -#include <tools/diagnose_ex.h> -#include <tools/long.hxx> -#include <unotools/syslocale.hxx> -#include <i18nlangtag/languagetag.hxx> -#include <comphelper/processfactory.hxx> - -#include <limits> -#include <memory> - -namespace svt -{ -using namespace ::com::sun::star::uno; -using ::com::sun::star::util::XNumberFormatter; -using ::com::sun::star::util::NumberFormatter; -using ::com::sun::star::util::XNumberFormatsSupplier; -using ::com::sun::star::util::NumberFormatsSupplier; -using ::com::sun::star::beans::XPropertySet; -using ::com::sun::star::lang::Locale; -using ::com::sun::star::util::DateTime; -using ::com::sun::star::util::XNumberFormatTypes; - -namespace NumberFormat = ::com::sun::star::util::NumberFormat; - -//= helper - -namespace -{ -double lcl_convertDateToDays(sal_uInt16 const i_day, sal_uInt16 const i_month, - sal_Int16 const i_year) -{ - tools::Long const nNullDateDays = ::Date::DateToDays(1, 1, 1900); - tools::Long const nValueDateDays = ::Date::DateToDays(i_day, i_month, i_year); - - return nValueDateDays - nNullDateDays; -} - -double lcl_convertTimeToDays(tools::Long const i_hours, tools::Long const i_minutes, - tools::Long const i_seconds, tools::Long const i_100thSeconds) -{ - return tools::Time(i_hours, i_minutes, i_seconds, i_100thSeconds).GetTimeInDays(); -} -} - -//= StandardFormatNormalizer - -StandardFormatNormalizer::StandardFormatNormalizer(Reference<XNumberFormatter> const& i_formatter, - ::sal_Int32 const i_numberFormatType) - : m_nFormatKey(0) -{ - try - { - ENSURE_OR_THROW(i_formatter.is(), "StandardFormatNormalizer: no formatter!"); - Reference<XNumberFormatsSupplier> const xSupplier(i_formatter->getNumberFormatsSupplier(), - UNO_SET_THROW); - Reference<XNumberFormatTypes> const xTypes(xSupplier->getNumberFormats(), UNO_QUERY_THROW); - m_nFormatKey = xTypes->getStandardFormat(i_numberFormatType, - SvtSysLocale().GetLanguageTag().getLocale()); - } - catch (const Exception&) - { - DBG_UNHANDLED_EXCEPTION("svtools.table"); - } -} - -//= DoubleNormalization - -namespace -{ -class DoubleNormalization : public StandardFormatNormalizer -{ -public: - explicit DoubleNormalization(Reference<XNumberFormatter> const& i_formatter) - : StandardFormatNormalizer(i_formatter, NumberFormat::NUMBER) - { - } - - virtual double convertToDouble(Any const& i_value) const override - { - double returnValue = std::numeric_limits<double>::quiet_NaN(); - OSL_VERIFY(i_value >>= returnValue); - return returnValue; - } -}; - -//= IntegerNormalization - -class IntegerNormalization : public StandardFormatNormalizer -{ -public: - explicit IntegerNormalization(Reference<XNumberFormatter> const& i_formatter) - : StandardFormatNormalizer(i_formatter, NumberFormat::NUMBER) - { - } - - virtual double convertToDouble(Any const& i_value) const override - { - sal_Int64 value(0); - OSL_VERIFY(i_value >>= value); - return value; - } -}; - -//= BooleanNormalization - -class BooleanNormalization : public StandardFormatNormalizer -{ -public: - explicit BooleanNormalization(Reference<XNumberFormatter> const& i_formatter) - : StandardFormatNormalizer(i_formatter, NumberFormat::LOGICAL) - { - } - - virtual double convertToDouble(Any const& i_value) const override - { - bool value(false); - OSL_VERIFY(i_value >>= value); - return value ? 1 : 0; - } -}; - -//= DateTimeNormalization - -class DateTimeNormalization : public StandardFormatNormalizer -{ -public: - explicit DateTimeNormalization(Reference<XNumberFormatter> const& i_formatter) - : StandardFormatNormalizer(i_formatter, NumberFormat::DATETIME) - { - } - - virtual double convertToDouble(Any const& i_value) const override - { - double returnValue = std::numeric_limits<double>::quiet_NaN(); - - // extract actual UNO value - DateTime aDateTimeValue; - ENSURE_OR_RETURN(i_value >>= aDateTimeValue, "allowed for DateTime values only", - returnValue); - - // date part - returnValue - = lcl_convertDateToDays(aDateTimeValue.Day, aDateTimeValue.Month, aDateTimeValue.Year); - - // time part - returnValue += lcl_convertTimeToDays(aDateTimeValue.Hours, aDateTimeValue.Minutes, - aDateTimeValue.Seconds, aDateTimeValue.NanoSeconds); - - // done - return returnValue; - } -}; - -//= DateNormalization - -class DateNormalization : public StandardFormatNormalizer -{ -public: - explicit DateNormalization(Reference<XNumberFormatter> const& i_formatter) - : StandardFormatNormalizer(i_formatter, NumberFormat::DATE) - { - } - - virtual double convertToDouble(Any const& i_value) const override - { - double returnValue = std::numeric_limits<double>::quiet_NaN(); - - // extract - css::util::Date aDateValue; - ENSURE_OR_RETURN(i_value >>= aDateValue, "allowed for Date values only", returnValue); - - // convert - returnValue = lcl_convertDateToDays(aDateValue.Day, aDateValue.Month, aDateValue.Year); - - // done - return returnValue; - } -}; - -//= TimeNormalization - -class TimeNormalization : public StandardFormatNormalizer -{ -public: - explicit TimeNormalization(Reference<XNumberFormatter> const& i_formatter) - : StandardFormatNormalizer(i_formatter, NumberFormat::TIME) - { - } - - virtual double convertToDouble(Any const& i_value) const override - { - double returnValue = std::numeric_limits<double>::quiet_NaN(); - - // extract - css::util::Time aTimeValue; - ENSURE_OR_RETURN(i_value >>= aTimeValue, "allowed for tools::Time values only", - returnValue); - - // convert - returnValue += lcl_convertTimeToDays(aTimeValue.Hours, aTimeValue.Minutes, - aTimeValue.Seconds, aTimeValue.NanoSeconds); - - // done - return returnValue; - } -}; -} - -//= operations - -bool CellValueConversion::ensureNumberFormatter() -{ - if (bAttemptedFormatterCreation) - return xNumberFormatter.is(); - bAttemptedFormatterCreation = true; - - try - { - Reference<XComponentContext> xContext = ::comphelper::getProcessComponentContext(); - // a number formatter - Reference<XNumberFormatter> const xFormatter(NumberFormatter::create(xContext), - UNO_QUERY_THROW); - - // a supplier of number formats - Locale aLocale = SvtSysLocale().GetLanguageTag().getLocale(); - - Reference<XNumberFormatsSupplier> const xSupplier - = NumberFormatsSupplier::createWithLocale(xContext, aLocale); - - // ensure a NullDate we will assume later on - css::util::Date const aNullDate(1, 1, 1900); - Reference<XPropertySet> const xFormatSettings(xSupplier->getNumberFormatSettings(), - UNO_SET_THROW); - xFormatSettings->setPropertyValue("NullDate", Any(aNullDate)); - - // knit - xFormatter->attachNumberFormatsSupplier(xSupplier); - - // done - xNumberFormatter = xFormatter; - } - catch (const Exception&) - { - DBG_UNHANDLED_EXCEPTION("svtools.table"); - } - - return xNumberFormatter.is(); -} - -bool CellValueConversion::getValueNormalizer(Type const& i_valueType, - std::shared_ptr<StandardFormatNormalizer>& o_formatter) -{ - auto pos = aNormalizers.find(i_valueType.getTypeName()); - if (pos == aNormalizers.end()) - { - // never encountered this type before - o_formatter.reset(); - - OUString const sTypeName(i_valueType.getTypeName()); - TypeClass const eTypeClass = i_valueType.getTypeClass(); - - if (sTypeName == ::cppu::UnoType<DateTime>::get().getTypeName()) - { - o_formatter = std::make_shared<DateTimeNormalization>(xNumberFormatter); - } - else if (sTypeName == ::cppu::UnoType<css::util::Date>::get().getTypeName()) - { - o_formatter = std::make_shared<DateNormalization>(xNumberFormatter); - } - else if (sTypeName == ::cppu::UnoType<css::util::Time>::get().getTypeName()) - { - o_formatter = std::make_shared<TimeNormalization>(xNumberFormatter); - } - else if (sTypeName == ::cppu::UnoType<sal_Bool>::get().getTypeName()) - { - o_formatter = std::make_shared<BooleanNormalization>(xNumberFormatter); - } - else if (sTypeName == ::cppu::UnoType<double>::get().getTypeName() - || sTypeName == ::cppu::UnoType<float>::get().getTypeName()) - { - o_formatter = std::make_shared<DoubleNormalization>(xNumberFormatter); - } - else if ((eTypeClass == TypeClass_BYTE) || (eTypeClass == TypeClass_SHORT) - || (eTypeClass == TypeClass_UNSIGNED_SHORT) || (eTypeClass == TypeClass_LONG) - || (eTypeClass == TypeClass_UNSIGNED_LONG) || (eTypeClass == TypeClass_HYPER)) - { - o_formatter = std::make_shared<IntegerNormalization>(xNumberFormatter); - } - else - { - SAL_WARN("svtools.table", "unsupported type '" << sTypeName << "'!"); - } - aNormalizers[sTypeName] = o_formatter; - } - else - o_formatter = pos->second; - - return bool(o_formatter); -} - -//= CellValueConversion - -CellValueConversion::CellValueConversion() - : xNumberFormatter() - , bAttemptedFormatterCreation(false) - , aNormalizers() -{ -} - -CellValueConversion::~CellValueConversion() {} - -OUString CellValueConversion::convertToString(const Any& i_value) -{ - OUString sStringValue; - if (!i_value.hasValue()) - return sStringValue; - - if (!(i_value >>= sStringValue)) - { - if (ensureNumberFormatter()) - { - std::shared_ptr<StandardFormatNormalizer> pNormalizer; - if (getValueNormalizer(i_value.getValueType(), pNormalizer)) - { - try - { - double const formatterCompliantValue = pNormalizer->convertToDouble(i_value); - sal_Int32 const formatKey = pNormalizer->getFormatKey(); - sStringValue = xNumberFormatter->convertNumberToString(formatKey, - formatterCompliantValue); - } - catch (const Exception&) - { - DBG_UNHANDLED_EXCEPTION("svtools.table"); - } - } - } - } - - return sStringValue; -} - -} // namespace svt - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/table/cellvalueconversion.hxx b/svtools/source/table/cellvalueconversion.hxx deleted file mode 100644 index 2e05707e5bab..000000000000 --- a/svtools/source/table/cellvalueconversion.hxx +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <com/sun/star/util/XNumberFormatter.hpp> -#include <com/sun/star/uno/Any.hxx> -#include <unordered_map> -#include <memory> - -namespace svt -{ -class StandardFormatNormalizer -{ -public: - /** converts the given <code>Any</code> into a <code>double</code> value to be fed into a number formatter - */ - virtual double convertToDouble(css::uno::Any const& i_value) const = 0; - - /** returns the format key to be used for formatting values - */ - sal_Int32 getFormatKey() const { return m_nFormatKey; } - -protected: - StandardFormatNormalizer(css::uno::Reference<css::util::XNumberFormatter> const& i_formatter, - ::sal_Int32 const i_numberFormatType); - - virtual ~StandardFormatNormalizer() {} - -private: - ::sal_Int32 m_nFormatKey; -}; - -class CellValueConversion -{ -public: - CellValueConversion(); - ~CellValueConversion(); - - OUString convertToString(const css::uno::Any& i_cellValue); - -private: - bool ensureNumberFormatter(); - bool getValueNormalizer(css::uno::Type const& i_valueType, - std::shared_ptr<StandardFormatNormalizer>& o_formatter); - - typedef std::unordered_map<OUString, std::shared_ptr<StandardFormatNormalizer>> NormalizerCache; - - css::uno::Reference<css::util::XNumberFormatter> xNumberFormatter; - bool bAttemptedFormatterCreation; - NormalizerCache aNormalizers; -}; - -} // namespace svt - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/table/defaultinputhandler.cxx b/svtools/source/table/defaultinputhandler.cxx deleted file mode 100644 index 0263b29689f5..000000000000 --- a/svtools/source/table/defaultinputhandler.cxx +++ /dev/null @@ -1,186 +0,0 @@ -/* -*- 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 <table/defaultinputhandler.hxx> -#include <table/tablecontrolinterface.hxx> - -#include <vcl/event.hxx> -#include <osl/diagnose.h> - - -namespace svt::table -{ - - - //= DefaultInputHandler - - - DefaultInputHandler::DefaultInputHandler() - { - aMouseFunctions.push_back( new ColumnResize ); - aMouseFunctions.push_back( new RowSelection ); - aMouseFunctions.push_back( new ColumnSortHandler ); - } - - - DefaultInputHandler::~DefaultInputHandler() - { - } - - - bool DefaultInputHandler::delegateMouseEvent( ITableControl& i_control, const MouseEvent& i_event, - FunctionResult ( MouseFunction::*i_handlerMethod )( ITableControl&, const MouseEvent& ) ) - { - if ( pActiveFunction.is() ) - { - bool furtherHandler = false; - switch ( (pActiveFunction.get()->*i_handlerMethod)( i_control, i_event ) ) - { - case ActivateFunction: - OSL_ENSURE( false, "lcl_delegateMouseEvent: unexpected - function already *is* active!" ); - break; - case ContinueFunction: - break; - case DeactivateFunction: - pActiveFunction.clear(); - break; - case SkipFunction: - furtherHandler = true; - break; - } - if ( !furtherHandler ) - // handled the event - return true; - } - - // ask all other handlers - bool handled = false; - for (auto const& mouseFunction : aMouseFunctions) - { - if (handled) - break; - if (mouseFunction == pActiveFunction) - // we already invoked this function - continue; - - switch ( (mouseFunction.get()->*i_handlerMethod)( i_control, i_event ) ) - { - case ActivateFunction: - pActiveFunction = mouseFunction; - handled = true; - break; - case ContinueFunction: - case DeactivateFunction: - OSL_ENSURE( false, "lcl_delegateMouseEvent: unexpected: inactive handler cannot be continued or deactivated!" ); - break; - case SkipFunction: - handled = false; - break; - } - } - return handled; - } - - - bool DefaultInputHandler::MouseMove( ITableControl& i_tableControl, const MouseEvent& i_event ) - { - return delegateMouseEvent( i_tableControl, i_event, &MouseFunction::handleMouseMove ); - } - - - bool DefaultInputHandler::MouseButtonDown( ITableControl& i_tableControl, const MouseEvent& i_event ) - { - return delegateMouseEvent( i_tableControl, i_event, &MouseFunction::handleMouseDown ); - } - - - bool DefaultInputHandler::MouseButtonUp( ITableControl& i_tableControl, const MouseEvent& i_event ) - { - return delegateMouseEvent( i_tableControl, i_event, &MouseFunction::handleMouseUp ); - } - - - bool DefaultInputHandler::KeyInput( ITableControl& _rControl, const KeyEvent& rKEvt ) - { - bool bHandled = false; - - const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode(); - sal_uInt16 nKeyCode = rKeyCode.GetCode(); - - struct ActionMapEntry - { - sal_uInt16 nKeyCode; - sal_uInt16 nKeyModifier; - TableControlAction eAction; - } - static const aKnownActions[] = { - { KEY_DOWN, 0, cursorDown }, - { KEY_UP, 0, cursorUp }, - { KEY_LEFT, 0, cursorLeft }, - { KEY_RIGHT, 0, cursorRight }, - { KEY_HOME, 0, cursorToLineStart }, - { KEY_END, 0, cursorToLineEnd }, - { KEY_PAGEUP, 0, cursorPageUp }, - { KEY_PAGEDOWN, 0, cursorPageDown }, - { KEY_PAGEUP, KEY_MOD1, cursorToFirstLine }, - { KEY_PAGEDOWN, KEY_MOD1, cursorToLastLine }, - { KEY_HOME, KEY_MOD1, cursorTopLeft }, - { KEY_END, KEY_MOD1, cursorBottomRight }, - { KEY_SPACE, KEY_MOD1, cursorSelectRow }, - { KEY_UP, KEY_SHIFT, cursorSelectRowUp }, - { KEY_DOWN, KEY_SHIFT, cursorSelectRowDown }, - { KEY_END, KEY_SHIFT, cursorSelectRowAreaBottom }, - { KEY_HOME, KEY_SHIFT, cursorSelectRowAreaTop }, - - { 0, 0, invalidTableControlAction } - }; - - const ActionMapEntry* pActions = aKnownActions; - for ( ; pActions->eAction != invalidTableControlAction; ++pActions ) - { - if ( ( pActions->nKeyCode == nKeyCode ) && ( pActions->nKeyModifier == rKeyCode.GetModifier() ) ) - { - bHandled = _rControl.dispatchAction( pActions->eAction ); - break; - } - } - - return bHandled; - } - - - bool DefaultInputHandler::GetFocus( ITableControl& _rControl ) - { - _rControl.showCursor(); - return false; // continue processing - } - - - bool DefaultInputHandler::LoseFocus( ITableControl& _rControl ) - { - _rControl.hideCursor(); - return false; // continue processing - } - - -} // namespace svt::table - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/table/gridtablerenderer.cxx b/svtools/source/table/gridtablerenderer.cxx deleted file mode 100644 index f814fc64d708..000000000000 --- a/svtools/source/table/gridtablerenderer.cxx +++ /dev/null @@ -1,598 +0,0 @@ -/* -*- 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 "cellvalueconversion.hxx" -#include <table/gridtablerenderer.hxx> -#include <table/tablesort.hxx> - -#include <com/sun/star/graphic/XGraphic.hpp> - -#include <tools/debug.hxx> -#include <tools/diagnose_ex.h> -#include <vcl/window.hxx> -#include <vcl/image.hxx> -#include <vcl/virdev.hxx> -#include <vcl/decoview.hxx> -#include <vcl/settings.hxx> - - -namespace svt::table -{ - using ::css::uno::Any; - using ::css::uno::Reference; - using ::css::uno::UNO_QUERY; - using ::css::uno::XInterface; - using ::css::uno::TypeClass_INTERFACE; - using ::css::graphic::XGraphic; - using ::css::style::HorizontalAlignment; - using ::css::style::HorizontalAlignment_CENTER; - using ::css::style::HorizontalAlignment_RIGHT; - using ::css::style::VerticalAlignment; - using ::css::style::VerticalAlignment_MIDDLE; - using ::css::style::VerticalAlignment_BOTTOM; - - - //= CachedSortIndicator - - namespace { - - class CachedSortIndicator - { - public: - CachedSortIndicator() - : m_lastHeaderHeight( 0 ) - , m_lastArrowColor( COL_TRANSPARENT ) - { - } - - BitmapEx const & getBitmapFor(vcl::RenderContext const & i_device, tools::Long const i_headerHeight, - StyleSettings const & i_style, bool const i_sortAscending); - - private: - tools::Long m_lastHeaderHeight; - Color m_lastArrowColor; - BitmapEx m_sortAscending; - BitmapEx m_sortDescending; - }; - - } - - BitmapEx const & CachedSortIndicator::getBitmapFor(vcl::RenderContext const& i_device, tools::Long const i_headerHeight, - StyleSettings const & i_style, bool const i_sortAscending ) - { - BitmapEx& rBitmap(i_sortAscending ? m_sortAscending : m_sortDescending); - if (rBitmap.IsEmpty() || (i_headerHeight != m_lastHeaderHeight) || (i_style.GetActiveColor() != m_lastArrowColor)) - { - tools::Long const nSortIndicatorWidth = 2 * i_headerHeight / 3; - tools::Long const nSortIndicatorHeight = 2 * nSortIndicatorWidth / 3; - - Point const aBitmapPos( 0, 0 ); - Size const aBitmapSize( nSortIndicatorWidth, nSortIndicatorHeight ); - ScopedVclPtrInstance< VirtualDevice > aDevice(i_device, DeviceFormat::DEFAULT, - DeviceFormat::DEFAULT); - aDevice->SetOutputSizePixel( aBitmapSize ); - - DecorationView aDecoView(aDevice.get()); - aDecoView.DrawSymbol(tools::Rectangle(aBitmapPos, aBitmapSize), - i_sortAscending ? SymbolType::SPIN_UP : SymbolType::SPIN_DOWN, - i_style.GetActiveColor()); - - rBitmap = aDevice->GetBitmapEx(aBitmapPos, aBitmapSize); - m_lastHeaderHeight = i_headerHeight; - m_lastArrowColor = i_style.GetActiveColor(); - } - return rBitmap; - } - - - //= GridTableRenderer_Impl - - struct GridTableRenderer_Impl - { - ITableModel& rModel; - RowPos nCurrentRow; - bool bUseGridLines; - CachedSortIndicator aSortIndicator; - CellValueConversion aStringConverter; - - explicit GridTableRenderer_Impl( ITableModel& _rModel ) - : rModel( _rModel ) - , nCurrentRow( ROW_INVALID ) - , bUseGridLines( true ) - , aSortIndicator( ) - , aStringConverter() - { - } - }; - - - //= helper - - namespace - { - tools::Rectangle lcl_getContentArea( GridTableRenderer_Impl const & i_impl, tools::Rectangle const & i_cellArea ) - { - tools::Rectangle aContentArea( i_cellArea ); - if ( i_impl.bUseGridLines ) - { - aContentArea.AdjustRight( -1 ); - aContentArea.AdjustBottom( -1 ); - } - return aContentArea; - } - tools::Rectangle lcl_getTextRenderingArea( tools::Rectangle const & i_contentArea ) - { - tools::Rectangle aTextArea( i_contentArea ); - aTextArea.AdjustLeft(2 ); aTextArea.AdjustRight( -2 ); - aTextArea.AdjustTop( 1 ); aTextArea.AdjustBottom( -1 ); - return aTextArea; - } - - DrawTextFlags lcl_getAlignmentTextDrawFlags( GridTableRenderer_Impl const & i_impl, ColPos const i_columnPos ) - { - DrawTextFlags nVertFlag = DrawTextFlags::Top; - VerticalAlignment const eVertAlign = i_impl.rModel.getVerticalAlign(); - switch ( eVertAlign ) - { - case VerticalAlignment_MIDDLE: nVertFlag = DrawTextFlags::VCenter; break; - case VerticalAlignment_BOTTOM: nVertFlag = DrawTextFlags::Bottom; break; - default: - break; - } - - DrawTextFlags nHorzFlag = DrawTextFlags::Left; - HorizontalAlignment const eHorzAlign = i_impl.rModel.getColumnCount() > 0 - ? i_impl.rModel.getColumnModel( i_columnPos )->getHorizontalAlign() - : HorizontalAlignment_CENTER; - switch ( eHorzAlign ) - { - case HorizontalAlignment_CENTER: nHorzFlag = DrawTextFlags::Center; break; - case HorizontalAlignment_RIGHT: nHorzFlag = DrawTextFlags::Right; break; - default: - break; - } - - return nVertFlag | nHorzFlag; - } - - } - - - //= GridTableRenderer - - - GridTableRenderer::GridTableRenderer( ITableModel& _rModel ) - :m_pImpl( new GridTableRenderer_Impl( _rModel ) ) - { - } - - - GridTableRenderer::~GridTableRenderer() - { - } - - - bool GridTableRenderer::useGridLines() const - { - return m_pImpl->bUseGridLines; - } - - - void GridTableRenderer::useGridLines( bool const i_use ) - { - m_pImpl->bUseGridLines = i_use; - } - - - namespace - { - Color lcl_getEffectiveColor(std::optional<Color> const& i_modelColor, - StyleSettings const& i_styleSettings, - Color const& (StyleSettings::*i_getDefaultColor) () const) - { - if (!!i_modelColor) - return *i_modelColor; - return (i_styleSettings.*i_getDefaultColor)(); - } - } - - - void GridTableRenderer::PaintHeaderArea(vcl::RenderContext& rRenderContext, const tools::Rectangle& _rArea, - bool _bIsColHeaderArea, bool _bIsRowHeaderArea, const StyleSettings& _rStyle) - { - OSL_PRECOND(_bIsColHeaderArea || _bIsRowHeaderArea, "GridTableRenderer::PaintHeaderArea: invalid area flags!"); - - rRenderContext.Push(vcl::PushFlags::FILLCOLOR | vcl::PushFlags::LINECOLOR); - - Color const background = lcl_getEffectiveColor(m_pImpl->rModel.getHeaderBackgroundColor(), - _rStyle, &StyleSettings::GetDialogColor); - rRenderContext.SetFillColor(background); - - rRenderContext.SetLineColor(); - rRenderContext.DrawRect(_rArea); - - // delimiter lines at bottom/right - std::optional<Color> aLineColor(m_pImpl->rModel.getLineColor()); - Color const lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor; - rRenderContext.SetLineColor(lineColor); - rRenderContext.DrawLine(_rArea.BottomLeft(), _rArea.BottomRight()); - rRenderContext.DrawLine(_rArea.BottomRight(), _rArea.TopRight()); - - rRenderContext.Pop(); - } - - - void GridTableRenderer::PaintColumnHeader( - ColPos _nCol, - vcl::RenderContext& rRenderContext, - const tools::Rectangle& _rArea, const StyleSettings& _rStyle) - { - rRenderContext.Push(vcl::PushFlags::LINECOLOR); - - OUString sHeaderText; - PColumnModel const pColumn = m_pImpl->rModel.getColumnModel( _nCol ); - DBG_ASSERT( pColumn, "GridTableRenderer::PaintColumnHeader: invalid column model object!" ); - if ( pColumn ) - sHeaderText = pColumn->getName(); - - Color const textColor = lcl_getEffectiveColor( m_pImpl->rModel.getTextColor(), _rStyle, &StyleSettings::GetFieldTextColor ); - rRenderContext.SetTextColor(textColor); - - tools::Rectangle const aTextRect( lcl_getTextRenderingArea( lcl_getContentArea( *m_pImpl, _rArea ) ) ); - DrawTextFlags nDrawTextFlags = lcl_getAlignmentTextDrawFlags( *m_pImpl, _nCol ) | DrawTextFlags::Clip; - if (!m_pImpl->rModel.isEnabled()) - nDrawTextFlags |= DrawTextFlags::Disable; - rRenderContext.DrawText( aTextRect, sHeaderText, nDrawTextFlags ); - - std::optional<Color> const aLineColor( m_pImpl->rModel.getLineColor() ); - Color const lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor; - rRenderContext.SetLineColor( lineColor ); - rRenderContext.DrawLine( _rArea.BottomRight(), _rArea.TopRight()); - rRenderContext.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); - - // draw sort indicator if the model data is sorted by the given column - ITableDataSort const * pSortAdapter = m_pImpl->rModel.getSortAdapter(); - ColumnSort aCurrentSortOrder; - if ( pSortAdapter != nullptr ) - aCurrentSortOrder = pSortAdapter->getCurrentSortOrder(); - if ( aCurrentSortOrder.nColumnPos == _nCol ) - { - tools::Long const nHeaderHeight( _rArea.GetHeight() ); - BitmapEx const aIndicatorBitmap = m_pImpl->aSortIndicator.getBitmapFor(rRenderContext, nHeaderHeight, _rStyle, - aCurrentSortOrder.eSortDirection == ColumnSortAscending); - Size const aBitmapSize( aIndicatorBitmap.GetSizePixel() ); - tools::Long const nSortIndicatorPaddingX = 2; - tools::Long const nSortIndicatorPaddingY = ( nHeaderHeight - aBitmapSize.Height() ) / 2; - - if ( nDrawTextFlags & DrawTextFlags::Right ) - { - // text is right aligned => draw the sort indicator at the left hand side - rRenderContext.DrawBitmapEx(Point(_rArea.Left() + nSortIndicatorPaddingX, _rArea.Top() + nSortIndicatorPaddingY), - aIndicatorBitmap); - } - else - { - // text is left-aligned or centered => draw the sort indicator at the right hand side - rRenderContext.DrawBitmapEx(Point(_rArea.Right() - nSortIndicatorPaddingX - aBitmapSize.Width(), nSortIndicatorPaddingY), - aIndicatorBitmap); - } - } - - rRenderContext.Pop(); - } - - - void GridTableRenderer::PrepareRow(RowPos _nRow, bool i_hasControlFocus, bool _bSelected, vcl::RenderContext& rRenderContext, - const tools::Rectangle& _rRowArea, const StyleSettings& _rStyle) - { - // remember the row for subsequent calls to the other ->ITableRenderer methods - m_pImpl->nCurrentRow = _nRow; - - rRenderContext.Push(vcl::PushFlags::FILLCOLOR | vcl::PushFlags::LINECOLOR); - - Color backgroundColor = _rStyle.GetFieldColor(); - - Color const activeSelectionBackColor = lcl_getEffectiveColor(m_pImpl->rModel.getActiveSelectionBackColor(), - _rStyle, &StyleSettings::GetHighlightColor); - if (_bSelected) - { - // selected rows use the background color from the style - backgroundColor = i_hasControlFocus - ? activeSelectionBackColor - : lcl_getEffectiveColor(m_pImpl->rModel.getInactiveSelectionBackColor(), _rStyle, &StyleSettings::GetDeactiveColor); - } - else - { - std::optional< std::vector<Color> > aRowColors = m_pImpl->rModel.getRowBackgroundColors(); - if (!aRowColors) - { - // use alternating default colors - Color const fieldColor = _rStyle.GetFieldColor(); - if (_rStyle.GetHighContrastMode() || ((m_pImpl->nCurrentRow % 2) == 0)) - { - backgroundColor = fieldColor; - } - else - { - Color hilightColor = activeSelectionBackColor; - hilightColor.SetRed( 9 * ( fieldColor.GetRed() - hilightColor.GetRed() ) / 10 + hilightColor.GetRed() ); - hilightColor.SetGreen( 9 * ( fieldColor.GetGreen() - hilightColor.GetGreen() ) / 10 + hilightColor.GetGreen() ); - hilightColor.SetBlue( 9 * ( fieldColor.GetBlue() - hilightColor.GetBlue() ) / 10 + hilightColor.GetBlue() ); - backgroundColor = hilightColor; - } - } - else - { - if (aRowColors->empty()) - { - // all colors have the same background color - backgroundColor = _rStyle.GetFieldColor(); - } - else - { - backgroundColor = aRowColors->at(m_pImpl->nCurrentRow % aRowColors->size()); - } - } - } - - rRenderContext.SetLineColor(); - rRenderContext.SetFillColor(backgroundColor); - rRenderContext.DrawRect(_rRowArea); - - rRenderContext.Pop(); - } - - - void GridTableRenderer::PaintRowHeader(vcl::RenderContext& rRenderContext, - const tools::Rectangle& _rArea, const StyleSettings& _rStyle) - { - rRenderContext.Push( vcl::PushFlags::LINECOLOR | vcl::PushFlags::TEXTCOLOR ); - - std::optional<Color> const aLineColor( m_pImpl->rModel.getLineColor() ); - Color const lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor; - rRenderContext.SetLineColor(lineColor); - rRenderContext.DrawLine(_rArea.BottomLeft(), _rArea.BottomRight()); - - Any const rowHeading( m_pImpl->rModel.getRowHeading( m_pImpl->nCurrentRow ) ); - OUString const rowTitle( m_pImpl->aStringConverter.convertToString( rowHeading ) ); - if (!rowTitle.isEmpty()) - { - Color const textColor = lcl_getEffectiveColor(m_pImpl->rModel.getHeaderTextColor(), - _rStyle, &StyleSettings::GetFieldTextColor); - rRenderContext.SetTextColor(textColor); - - tools::Rectangle const aTextRect(lcl_getTextRenderingArea(lcl_getContentArea(*m_pImpl, _rArea))); - DrawTextFlags nDrawTextFlags = lcl_getAlignmentTextDrawFlags(*m_pImpl, 0) | DrawTextFlags::Clip; - if (!m_pImpl->rModel.isEnabled()) - nDrawTextFlags |= DrawTextFlags::Disable; - // TODO: is using the horizontal alignment of the 0'th column a good idea here? This is pretty ... arbitrary .. - rRenderContext.DrawText(aTextRect, rowTitle, nDrawTextFlags); - } - - rRenderContext.Pop(); - } - - - struct GridTableRenderer::CellRenderContext - { - OutputDevice& rDevice; - tools::Rectangle const aContentArea; - StyleSettings const & rStyle; - ColPos const nColumn; - bool const bSelected; - bool const bHasControlFocus; - - CellRenderContext( OutputDevice& i_device, tools::Rectangle const & i_contentArea, - StyleSettings const & i_style, ColPos const i_column, bool const i_selected, bool const i_hasControlFocus ) - :rDevice( i_device ) - ,aContentArea( i_contentArea ) - ,rStyle( i_style ) - ,nColumn( i_column ) - ,bSelected( i_selected ) - ,bHasControlFocus( i_hasControlFocus ) - { - } - }; - - - void GridTableRenderer::PaintCell(ColPos const i_column, bool _bSelected, bool i_hasControlFocus, - vcl::RenderContext& rRenderContext, const tools::Rectangle& _rArea, const StyleSettings& _rStyle) - { - rRenderContext.Push(vcl::PushFlags::LINECOLOR | vcl::PushFlags::FILLCOLOR); - - tools::Rectangle const aContentArea(lcl_getContentArea(*m_pImpl, _rArea)); - CellRenderContext const aCellRenderContext(rRenderContext, aContentArea, _rStyle, i_column, _bSelected, i_hasControlFocus); - impl_paintCellContent(aCellRenderContext); - - if ( m_pImpl->bUseGridLines ) - { - ::std::optional< ::Color > aLineColor( m_pImpl->rModel.getLineColor() ); - ::Color lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor; - - if ( _bSelected && !aLineColor ) - { - // if no line color is specified by the model, use the usual selection color for lines in selected cells - lineColor = i_hasControlFocus - ? lcl_getEffectiveColor( m_pImpl->rModel.getActiveSelectionBackColor(), _rStyle, &StyleSettings::GetHighlightColor ) - : lcl_getEffectiveColor( m_pImpl->rModel.getInactiveSelectionBackColor(), _rStyle, &StyleSettings::GetDeactiveColor ); - } - - rRenderContext.SetLineColor( lineColor ); - rRenderContext.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); - rRenderContext.DrawLine( _rArea.BottomRight(), _rArea.TopRight() ); - } - - rRenderContext.Pop(); - } - - - void GridTableRenderer::impl_paintCellImage( CellRenderContext const & i_context, Image const & i_image ) - { - Point imagePos( Point( i_context.aContentArea.Left(), i_context.aContentArea.Top() ) ); - Size imageSize = i_image.GetSizePixel(); - if ( i_context.aContentArea.GetWidth() > imageSize.Width() ) - { - const HorizontalAlignment eHorzAlign = m_pImpl->rModel.getColumnModel( i_context.nColumn )->getHorizontalAlign(); - switch ( eHorzAlign ) - { - case HorizontalAlignment_CENTER: - imagePos.AdjustX(( i_context.aContentArea.GetWidth() - imageSize.Width() ) / 2 ); - break; - case HorizontalAlignment_RIGHT: - imagePos.setX( i_context.aContentArea.Right() - imageSize.Width() ); - break; - default: - break; - } - - } - else - imageSize.setWidth( i_context.aContentArea.GetWidth() ); - - if ( i_context.aContentArea.GetHeight() > imageSize.Height() ) - { - const VerticalAlignment eVertAlign = m_pImpl->rModel.getVerticalAlign(); - switch ( eVertAlign ) - { - case VerticalAlignment_MIDDLE: - imagePos.AdjustY(( i_context.aContentArea.GetHeight() - imageSize.Height() ) / 2 ); - break; - case VerticalAlignment_BOTTOM: - imagePos.setY( i_context.aContentArea.Bottom() - imageSize.Height() ); - break; - default: - break; - } - } - else - imageSize.setHeight( i_context.aContentArea.GetHeight() - 1 ); - DrawImageFlags const nStyle = m_pImpl->rModel.isEnabled() ? DrawImageFlags::NONE : DrawImageFlags::Disable; - i_context.rDevice.DrawImage( imagePos, imageSize, i_image, nStyle ); - } - - - void GridTableRenderer::impl_paintCellContent( CellRenderContext const & i_context ) - { - Any aCellContent; - m_pImpl->rModel.getCellContent( i_context.nColumn, m_pImpl->nCurrentRow, aCellContent ); - - if ( aCellContent.getValueTypeClass() == TypeClass_INTERFACE ) - { - Reference< XInterface > const xContentInterface( aCellContent, UNO_QUERY ); - if ( !xContentInterface.is() ) - // allowed. kind of. - return; - - Reference< XGraphic > const xGraphic( aCellContent, UNO_QUERY ); - ENSURE_OR_RETURN_VOID( xGraphic.is(), "GridTableRenderer::impl_paintCellContent: only XGraphic interfaces (or NULL) are supported for painting." ); - - const Image aImage( xGraphic ); - impl_paintCellImage( i_context, aImage ); - return; - } - - const OUString sText( m_pImpl->aStringConverter.convertToString( aCellContent ) ); - impl_paintCellText( i_context, sText ); - } - - - void GridTableRenderer::impl_paintCellText( CellRenderContext const & i_context, OUString const & i_text ) - { - if ( i_context.bSelected ) - { - ::Color const textColor = i_context.bHasControlFocus - ? lcl_getEffectiveColor( m_pImpl->rModel.getActiveSelectionTextColor(), i_context.rStyle, &StyleSettings::GetHighlightTextColor ) - : lcl_getEffectiveColor( m_pImpl->rModel.getInactiveSelectionTextColor(), i_context.rStyle, &StyleSettings::GetDeactiveTextColor ); - i_context.rDevice.SetTextColor( textColor ); - } - else - { - ::Color const textColor = lcl_getEffectiveColor( m_pImpl->rModel.getTextColor(), i_context.rStyle, &StyleSettings::GetFieldTextColor ); - i_context.rDevice.SetTextColor( textColor ); - } - - tools::Rectangle const textRect( lcl_getTextRenderingArea( i_context.aContentArea ) ); - DrawTextFlags nDrawTextFlags = lcl_getAlignmentTextDrawFlags( *m_pImpl, i_context.nColumn ) | DrawTextFlags::Clip; - if ( !m_pImpl->rModel.isEnabled() ) - nDrawTextFlags |= DrawTextFlags::Disable; - i_context.rDevice.DrawText( textRect, i_text, nDrawTextFlags ); - } - - - void GridTableRenderer::ShowCellCursor( vcl::Window& _rView, const tools::Rectangle& _rCursorRect) - { - _rView.ShowFocus( _rCursorRect ); - } - - - void GridTableRenderer::HideCellCursor( vcl::Window& _rView ) - { - _rView.HideFocus(); - } - - - bool GridTableRenderer::FitsIntoCell( Any const & i_cellContent, - OutputDevice& i_targetDevice, tools::Rectangle const & i_targetArea ) const - { - if ( !i_cellContent.hasValue() ) - return true; - - if ( i_cellContent.getValueTypeClass() == TypeClass_INTERFACE ) - { - Reference< XInterface > const xContentInterface( i_cellContent, UNO_QUERY ); - if ( !xContentInterface.is() ) - return true; - - Reference< XGraphic > const xGraphic( i_cellContent, UNO_QUERY ); - if ( xGraphic.is() ) - // for the moment, assume it fits. We can always scale it down during painting ... - return true; - - OSL_ENSURE( false, "GridTableRenderer::FitsIntoCell: only XGraphic interfaces (or NULL) are supported for painting." ); - return true; - } - - OUString const sText( m_pImpl->aStringConverter.convertToString( i_cellContent ) ); - if ( sText.isEmpty() ) - return true; - - tools::Rectangle const aTargetArea( lcl_getTextRenderingArea( lcl_getContentArea( *m_pImpl, i_targetArea ) ) ); - - tools::Long const nTextHeight = i_targetDevice.GetTextHeight(); - if ( nTextHeight > aTargetArea.GetHeight() ) - return false; - - tools::Long const nTextWidth = i_targetDevice.GetTextWidth( sText ); - return nTextWidth <= aTargetArea.GetWidth(); - } - - - bool GridTableRenderer::GetFormattedCellString( Any const & i_cellValue, OUString & o_cellString ) const - { - o_cellString = m_pImpl->aStringConverter.convertToString( i_cellValue ); - - return true; - } - - -} // namespace svt::table - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/table/mousefunction.cxx b/svtools/source/table/mousefunction.cxx deleted file mode 100644 index 8bb30390a286..000000000000 --- a/svtools/source/table/mousefunction.cxx +++ /dev/null @@ -1,274 +0,0 @@ -/* -*- 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 <mousefunction.hxx> -#include <table/tablecontrolinterface.hxx> -#include <table/tablesort.hxx> - -#include <tools/diagnose_ex.h> -#include <vcl/ptrstyle.hxx> - -namespace svt::table -{ - - - //= ColumnResize - - - FunctionResult ColumnResize::handleMouseMove( ITableControl& i_tableControl, MouseEvent const & i_event ) - { - Point const aPoint = i_event.GetPosPixel(); - - if ( m_nResizingColumn == COL_INVALID ) - { - // if we hit a column divider, change the mouse pointer accordingly - PointerStyle aNewPointer( PointerStyle::Arrow ); - TableCell const tableCell = i_tableControl.hitTest( aPoint ); - if ( ( tableCell.nRow == ROW_COL_HEADERS ) && ( tableCell.eArea == ColumnDivider ) ) - { - aNewPointer = PointerStyle::HSplit; - } - i_tableControl.setPointer( aNewPointer ); - - return SkipFunction; // TODO: is this correct? - } - - ::Size const tableSize = i_tableControl.getTableSizePixel(); - - // set proper pointer - PointerStyle aNewPointer( PointerStyle::Arrow ); - ColumnMetrics const & columnMetrics( i_tableControl.getColumnMetrics( m_nResizingColumn ) ); - if ( ( aPoint.X() > tableSize.Width() ) - || ( aPoint.X() < columnMetrics.nStartPixel ) - ) - { - aNewPointer = PointerStyle::NotAllowed; - } - else - { - aNewPointer = PointerStyle::HSplit; - } - i_tableControl.setPointer( aNewPointer ); - - // show tracking line - i_tableControl.hideTracking(); - i_tableControl.showTracking( - tools::Rectangle( - Point( aPoint.X(), 0 ), - Size( 1, tableSize.Height() ) - ), - ShowTrackFlags::Split | ShowTrackFlags::TrackWindow - ); - - return ContinueFunction; - } - - - FunctionResult ColumnResize::handleMouseDown( ITableControl& i_tableControl, MouseEvent const & i_event ) - { - if ( m_nResizingColumn != COL_INVALID ) - { - OSL_ENSURE( false, "ColumnResize::handleMouseDown: suspicious: MouseButtonDown while still tracking?" ); - return ContinueFunction; - } - - TableCell const tableCell( i_tableControl.hitTest( i_event.GetPosPixel() ) ); - if ( tableCell.nRow == ROW_COL_HEADERS ) - { - if ( ( tableCell.nColumn != COL_INVALID ) - && ( tableCell.eArea == ColumnDivider ) - ) - { - m_nResizingColumn = tableCell.nColumn; - i_tableControl.captureMouse(); - return ActivateFunction; - } - } - - return SkipFunction; - } - - - FunctionResult ColumnResize::handleMouseUp( ITableControl& i_tableControl, MouseEvent const & i_event ) - { - if ( m_nResizingColumn == COL_INVALID ) - return SkipFunction; - - Point const aPoint = i_event.GetPosPixel(); - - i_tableControl.hideTracking(); - PColumnModel const pColumn = i_tableControl.getModel()->getColumnModel( m_nResizingColumn ); - tools::Long const maxWidthLogical = pColumn->getMaxWidth(); - tools::Long const minWidthLogical = pColumn->getMinWidth(); - - // new position of mouse - tools::Long const requestedEnd = aPoint.X(); - - // old position of right border - tools::Long const oldEnd = i_tableControl.getColumnMetrics( m_nResizingColumn ).nEndPixel; - - // position of left border if cursor in the to-be-resized column - tools::Long const columnStart = i_tableControl.getColumnMetrics( m_nResizingColumn ).nStartPixel; - tools::Long const requestedWidth = requestedEnd - columnStart; - // TODO: this is not correct, strictly: It assumes that the mouse was pressed exactly on the "end" pos, - // but for a while now, we have relaxed this, and allow clicking a few pixels aside, too - - if ( requestedEnd >= columnStart ) - { - tools::Long requestedWidthLogical = i_tableControl.pixelWidthToAppFont( requestedWidth ); - // respect column width limits - if ( oldEnd > requestedEnd ) - { - // column has become smaller, check against minimum width - if ( ( minWidthLogical != 0 ) && ( requestedWidthLogical < minWidthLogical ) ) - requestedWidthLogical = minWidthLogical; - } - else if ( oldEnd < requestedEnd ) - { - // column has become larger, check against max width - if ( ( maxWidthLogical != 0 ) && ( requestedWidthLogical >= maxWidthLogical ) ) - requestedWidthLogical = maxWidthLogical; - } - pColumn->setWidth( requestedWidthLogical ); - i_tableControl.invalidate( TableArea::All ); - } - - i_tableControl.setPointer( PointerStyle::Arrow ); - i_tableControl.releaseMouse(); - - m_nResizingColumn = COL_INVALID; - return DeactivateFunction; - } - - - //= RowSelection - - - FunctionResult RowSelection::handleMouseMove( ITableControl&, MouseEvent const & ) - { - return SkipFunction; - } - - - FunctionResult RowSelection::handleMouseDown( ITableControl& i_tableControl, MouseEvent const & i_event ) - { - bool handled = false; - - TableCell const tableCell( i_tableControl.hitTest( i_event.GetPosPixel() ) ); - if ( tableCell.nRow >= 0 ) - { - if ( i_tableControl.getSelEngine()->GetSelectionMode() == SelectionMode::NONE ) - { - i_tableControl.activateCell( tableCell.nColumn, tableCell.nRow ); - handled = true; - } - else - { - handled = i_tableControl.getSelEngine()->SelMouseButtonDown( i_event ); - } - } - - if ( handled ) - m_bActive = true; - return handled ? ActivateFunction : SkipFunction; - } - - - FunctionResult RowSelection::handleMouseUp( ITableControl& i_tableControl, MouseEvent const & i_event ) - { - TableCell const tableCell = i_tableControl.hitTest( i_event.GetPosPixel() ); - if ( tableCell.nRow >= 0 ) - { - if ( i_tableControl.getSelEngine()->GetSelectionMode() != SelectionMode::NONE ) - { - i_tableControl.getSelEngine()->SelMouseButtonUp( i_event ); - } - } - if ( m_bActive ) - { - m_bActive = false; - return DeactivateFunction; - } - return SkipFunction; - } - - - //= ColumnSortHandler - - - FunctionResult ColumnSortHandler::handleMouseMove( ITableControl&, MouseEvent const & ) - { - return SkipFunction; - } - - - FunctionResult ColumnSortHandler::handleMouseDown( ITableControl& i_tableControl, MouseEvent const & i_event ) - { - if ( m_nActiveColumn != COL_INVALID ) - { - OSL_ENSURE( false, "ColumnSortHandler::handleMouseDown: called while already active - suspicious!" ); - return ContinueFunction; - } - - if ( i_tableControl.getModel()->getSortAdapter() == nullptr ) - // no sorting support at the model - return SkipFunction; - - TableCell const tableCell( i_tableControl.hitTest( i_event.GetPosPixel() ) ); - if ( ( tableCell.nRow != ROW_COL_HEADERS ) || ( tableCell.nColumn < 0 ) ) - return SkipFunction; - - // TODO: ensure the column header is rendered in some special way, indicating its current state - - m_nActiveColumn = tableCell.nColumn; - return ActivateFunction; - } - - - FunctionResult ColumnSortHandler::handleMouseUp( ITableControl& i_tableControl, MouseEvent const & i_event ) - { - if ( m_nActiveColumn == COL_INVALID ) - return SkipFunction; - - TableCell const tableCell( i_tableControl.hitTest( i_event.GetPosPixel() ) ); - if ( ( tableCell.nRow == ROW_COL_HEADERS ) && ( tableCell.nColumn == m_nActiveColumn ) ) - { - ITableDataSort* pSort = i_tableControl.getModel()->getSortAdapter(); - ENSURE_OR_RETURN( pSort != nullptr, "ColumnSortHandler::handleMouseUp: somebody is mocking with us!", DeactivateFunction ); - // in handleMousButtonDown, the model claimed to have sort support ... - - ColumnSortDirection eSortDirection = ColumnSortAscending; - ColumnSort const aCurrentSort = pSort->getCurrentSortOrder(); - if ( aCurrentSort.nColumnPos == m_nActiveColumn ) - // invert existing sort order - eSortDirection = ( aCurrentSort.eSortDirection == ColumnSortAscending ) ? ColumnSortDescending : ColumnSortAscending; - - pSort->sortByColumn( m_nActiveColumn, eSortDirection ); - } - - m_nActiveColumn = COL_INVALID; - return DeactivateFunction; - } - - -} // namespace svt::table - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/table/tablecontrol.cxx b/svtools/source/table/tablecontrol.cxx deleted file mode 100644 index 5ed46f9d4d6b..000000000000 --- a/svtools/source/table/tablecontrol.cxx +++ /dev/null @@ -1,637 +0,0 @@ -/* -*- 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 <table/tablecontrol.hxx> - -#include "tablecontrol_impl.hxx" -#include "tabledatawindow.hxx" - -#include <com/sun/star/accessibility/AccessibleStateType.hpp> -#include <com/sun/star/accessibility/AccessibleEventId.hpp> - -#include <sal/log.hxx> -#include <tools/diagnose_ex.h> -#include <vcl/settings.hxx> -#include <vcl/vclevent.hxx> - -using namespace ::com::sun::star::uno; -using ::com::sun::star::accessibility::XAccessible; -using namespace ::com::sun::star::accessibility; -using namespace ::com::sun::star::lang; - -namespace svt::table -{ - - - namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId; - - - //= TableControl - - - TableControl::TableControl( vcl::Window* _pParent, WinBits _nStyle ) - :Control( _pParent, _nStyle ) - ,m_pImpl( std::make_shared<TableControl_Impl>( *this ) ) - { - TableDataWindow& rDataWindow = m_pImpl->getDataWindow(); - rDataWindow.SetSelectHdl( LINK( this, TableControl, ImplSelectHdl ) ); - - // by default, use the background as determined by the style settings - const Color aWindowColor( GetSettings().GetStyleSettings().GetFieldColor() ); - SetBackground( Wallpaper( aWindowColor ) ); - GetOutDev()->SetFillColor( aWindowColor ); - - SetCompoundControl( true ); - } - - - TableControl::~TableControl() - { - disposeOnce(); - } - - void TableControl::dispose() - { - CallEventListeners( VclEventId::ObjectDying ); - - m_pImpl->setModel( PTableModel() ); - m_pImpl->disposeAccessible(); - m_pImpl.reset(); - Control::dispose(); - } - - - void TableControl::GetFocus() - { - if ( !m_pImpl || !m_pImpl->getInputHandler()->GetFocus( *m_pImpl ) ) - Control::GetFocus(); - } - - - void TableControl::LoseFocus() - { - if ( !m_pImpl || !m_pImpl->getInputHandler()->LoseFocus( *m_pImpl ) ) - Control::LoseFocus(); - } - - - void TableControl::KeyInput( const KeyEvent& rKEvt ) - { - if ( !m_pImpl->getInputHandler()->KeyInput( *m_pImpl, rKEvt ) ) - Control::KeyInput( rKEvt ); - else - { - if ( m_pImpl->isAccessibleAlive() ) - { - m_pImpl->commitCellEvent( AccessibleEventId::STATE_CHANGED, - Any( AccessibleStateType::FOCUSED ), - Any() - ); - // Huh? What the heck? Why do we unconditionally notify a STATE_CHANGE/FOCUSED after each and every - // (handled) key stroke? - - m_pImpl->commitTableEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, - Any(), - Any() - ); - // ditto: Why do we notify this unconditionally? We should find the right place to notify the - // ACTIVE_DESCENDANT_CHANGED event. - // Also, we should check if STATE_CHANGED/FOCUSED is really necessary: finally, the children are - // transient, aren't they? - } - } - } - - - void TableControl::StateChanged( StateChangedType i_nStateChange ) - { - Control::StateChanged( i_nStateChange ); - - // forward certain settings to the data window - switch ( i_nStateChange ) - { - case StateChangedType::ControlFocus: - m_pImpl->invalidateSelectedRows(); - break; - - case StateChangedType::ControlBackground: - if ( IsControlBackground() ) - getDataWindow().SetControlBackground( GetControlBackground() ); - else - getDataWindow().SetControlBackground(); - break; - - case StateChangedType::ControlForeground: - if ( IsControlForeground() ) - getDataWindow().SetControlForeground( GetControlForeground() ); - else - getDataWindow().SetControlForeground(); - break; - - case StateChangedType::ControlFont: - if ( IsControlFont() ) - getDataWindow().SetControlFont( GetControlFont() ); - else - getDataWindow().SetControlFont(); - break; - default:; - } - } - - - void TableControl::Resize() - { - Control::Resize(); - m_pImpl->onResize(); - } - - - void TableControl::SetModel( const PTableModel& _pModel ) - { - m_pImpl->setModel( _pModel ); - } - - - PTableModel TableControl::GetModel() const - { - return m_pImpl->getModel(); - } - - - sal_Int32 TableControl::GetCurrentRow() const - { - return m_pImpl->getCurrentRow(); - } - - - sal_Int32 TableControl::GetCurrentColumn() const - { - return m_pImpl->getCurrentColumn(); - } - - - void TableControl::GoTo( ColPos _nColumn, RowPos _nRow ) - { - m_pImpl->goTo( _nColumn, _nRow ); - } - - - void TableControl::GoToCell(sal_Int32 _nColPos, sal_Int32 _nRowPos) - { - m_pImpl->goTo( _nColPos, _nRowPos ); - } - - - sal_Int32 TableControl::GetSelectedRowCount() const - { - return sal_Int32( m_pImpl->getSelectedRowCount() ); - } - - - sal_Int32 TableControl::GetSelectedRowIndex( sal_Int32 const i_selectionIndex ) const - { - return m_pImpl->getSelectedRowIndex( i_selectionIndex ); - } - - - bool TableControl::IsRowSelected( sal_Int32 const i_rowIndex ) const - { - return m_pImpl->isRowSelected( i_rowIndex ); - } - - - void TableControl::SelectRow( sal_Int32 const i_rowIndex, bool const i_select ) - { - ENSURE_OR_RETURN_VOID( ( i_rowIndex >= 0 ) && ( i_rowIndex < m_pImpl->getModel()->getRowCount() ), - "TableControl::SelectRow: invalid row index!" ); - - if ( i_select ) - { - if ( !m_pImpl->markRowAsSelected( i_rowIndex ) ) - // nothing to do - return; - } - else - { - m_pImpl->markRowAsDeselected( i_rowIndex ); - } - - m_pImpl->invalidateRowRange( i_rowIndex, i_rowIndex ); - Select(); - } - - - void TableControl::SelectAllRows( bool const i_select ) - { - if ( i_select ) - { - if ( !m_pImpl->markAllRowsAsSelected() ) - // nothing to do - return; - } - else - { - if ( !m_pImpl->markAllRowsAsDeselected() ) - // nothing to do - return; - } - - - Invalidate(); - // TODO: can't we do better than this, and invalidate only the rows which changed? - Select(); - } - - - ITableControl& TableControl::getTableControlInterface() - { - return *m_pImpl; - } - - - SelectionEngine* TableControl::getSelEngine() - { - return m_pImpl->getSelEngine(); - } - - - vcl::Window& TableControl::getDataWindow() - { - return m_pImpl->getDataWindow(); - } - - - Reference< XAccessible > TableControl::CreateAccessible() - { - vcl::Window* pParent = GetAccessibleParentWindow(); - ENSURE_OR_RETURN( pParent, "TableControl::CreateAccessible - parent not found", nullptr ); - - return m_pImpl->getAccessible( *pParent ); - } - - - Reference<XAccessible> TableControl::CreateAccessibleControl( sal_Int32 ) - { - SAL_WARN( "svtools", "TableControl::CreateAccessibleControl: to be overwritten!" ); - return nullptr; - } - - - OUString TableControl::GetAccessibleObjectName( vcl::table::AccessibleTableControlObjType eObjType, sal_Int32 _nRow, sal_Int32 _nCol) const - { - OUString aRetText; - //Window* pWin; - switch( eObjType ) - { - case vcl::table::TCTYPE_GRIDCONTROL: - aRetText = "Grid control"; - break; - case vcl::table::TCTYPE_TABLE: - aRetText = "Grid control"; - break; - case vcl::table::TCTYPE_ROWHEADERBAR: - aRetText = "RowHeaderBar"; - break; - case vcl::table::TCTYPE_COLUMNHEADERBAR: - aRetText = "ColumnHeaderBar"; - break; - case vcl::table::TCTYPE_TABLECELL: - //the name of the cell consists of column name and row name if defined - //if the name is equal to cell content, it'll be read twice - if(GetModel()->hasColumnHeaders()) - { - aRetText = GetColumnName(_nCol) + " , "; - } - if(GetModel()->hasRowHeaders()) - { - aRetText += GetRowName(_nRow) + " , "; - } - //aRetText = GetAccessibleCellText(_nRow, _nCol); - break; - case vcl::table::TCTYPE_ROWHEADERCELL: - aRetText = GetRowName(_nRow); - break; - case vcl::table::TCTYPE_COLUMNHEADERCELL: - aRetText = GetColumnName(_nCol); - break; - default: - OSL_FAIL("GridControl::GetAccessibleName: invalid enum!"); - } - return aRetText; - } - - - OUString TableControl::GetAccessibleObjectDescription( vcl::table::AccessibleTableControlObjType eObjType ) const - { - OUString aRetText; - switch( eObjType ) - { - case vcl::table::TCTYPE_GRIDCONTROL: - aRetText = "Grid control description"; - break; - case vcl::table::TCTYPE_TABLE: - aRetText = "TABLE description"; - break; - case vcl::table::TCTYPE_ROWHEADERBAR: - aRetText = "ROWHEADERBAR description"; - break; - case vcl::table::TCTYPE_COLUMNHEADERBAR: - aRetText = "COLUMNHEADERBAR description"; - break; - case vcl::table::TCTYPE_TABLECELL: - // the description of the cell consists of column name and row name if defined - // if the name is equal to cell content, it'll be read twice - if ( GetModel()->hasColumnHeaders() ) - { - aRetText = GetColumnName( GetCurrentColumn() ) + " , "; - } - if ( GetModel()->hasRowHeaders() ) - { - aRetText += GetRowName( GetCurrentRow() ); - } - break; - case vcl::table::TCTYPE_ROWHEADERCELL: - aRetText = "ROWHEADERCELL description"; - break; - case vcl::table::TCTYPE_COLUMNHEADERCELL: - aRetText = "COLUMNHEADERCELL description"; - break; - } - return aRetText; - } - - - OUString TableControl::GetRowName( sal_Int32 _nIndex) const - { - OUString sRowName; - GetModel()->getRowHeading( _nIndex ) >>= sRowName; - return sRowName; - } - - - OUString TableControl::GetColumnName( sal_Int32 _nIndex) const - { - return GetModel()->getColumnModel(_nIndex)->getName(); - } - - - OUString TableControl::GetAccessibleCellText( sal_Int32 _nRowPos, sal_Int32 _nColPos) const - { - return m_pImpl->getCellContentAsString( _nRowPos, _nColPos ); - } - - - void TableControl::FillAccessibleStateSet( - sal_Int64& rStateSet, - vcl::table::AccessibleTableControlObjType eObjType ) const - { - switch( eObjType ) - { - case vcl::table::TCTYPE_GRIDCONTROL: - case vcl::table::TCTYPE_TABLE: - - rStateSet |= AccessibleStateType::FOCUSABLE; - - if ( m_pImpl->getSelEngine()->GetSelectionMode() == SelectionMode::Multiple ) - rStateSet |= AccessibleStateType::MULTI_SELECTABLE; - - if ( HasChildPathFocus() ) - rStateSet |= AccessibleStateType::FOCUSED; - - if ( IsActive() ) - rStateSet |= AccessibleStateType::ACTIVE; - - if ( m_pImpl->getDataWindow().IsEnabled() ) - { - rStateSet |= AccessibleStateType::ENABLED; - rStateSet |= AccessibleStateType::SENSITIVE; - } - - if ( IsReallyVisible() ) - rStateSet |= AccessibleStateType::VISIBLE; - - if ( eObjType == vcl::table::TCTYPE_TABLE ) - rStateSet |= AccessibleStateType::MANAGES_DESCENDANTS; - break; - - case vcl::table::TCTYPE_ROWHEADERBAR: - rStateSet |= AccessibleStateType::VISIBLE; - rStateSet |= AccessibleStateType::MANAGES_DESCENDANTS; - break; - - case vcl::table::TCTYPE_COLUMNHEADERBAR: - rStateSet |= AccessibleStateType::VISIBLE; - rStateSet |= AccessibleStateType::MANAGES_DESCENDANTS; - break; - - case vcl::table::TCTYPE_TABLECELL: - { - rStateSet |= AccessibleStateType::FOCUSABLE; - if ( HasChildPathFocus() ) - rStateSet |= AccessibleStateType::FOCUSED; - rStateSet |= AccessibleStateType::ACTIVE; - rStateSet |= AccessibleStateType::TRANSIENT; - rStateSet |= AccessibleStateType::SELECTABLE; - rStateSet |= AccessibleStateType::VISIBLE; - rStateSet |= AccessibleStateType::SHOWING; - if ( IsRowSelected( GetCurrentRow() ) ) - // Hmm? Wouldn't we expect the affected row to be a parameter to this function? - rStateSet |= AccessibleStateType::SELECTED; - } - break; - - case vcl::table::TCTYPE_ROWHEADERCELL: - rStateSet |= AccessibleStateType::VISIBLE; - rStateSet |= AccessibleStateType::TRANSIENT; - break; - - case vcl::table::TCTYPE_COLUMNHEADERCELL: - rStateSet |= AccessibleStateType::VISIBLE; - break; - } - } - - void TableControl::commitCellEventIfAccessibleAlive( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue ) - { - if ( m_pImpl->isAccessibleAlive() ) - m_pImpl->commitCellEvent( i_eventID, i_newValue, i_oldValue ); - } - - void TableControl::commitTableEventIfAccessibleAlive( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue ) - { - if ( m_pImpl->isAccessibleAlive() ) - m_pImpl->commitTableEvent( i_eventID, i_newValue, i_oldValue ); - } - - tools::Rectangle TableControl::GetWindowExtentsRelative(const vcl::Window *pRelativeWindow) const - { - return Control::GetWindowExtentsRelative( pRelativeWindow ); - } - - void TableControl::GrabFocus() - { - Control::GrabFocus(); - } - - Reference< XAccessible > TableControl::GetAccessible() - { - return Control::GetAccessible(); - } - - vcl::Window* TableControl::GetAccessibleParentWindow() const - { - return Control::GetAccessibleParentWindow(); - } - - vcl::Window* TableControl::GetWindowInstance() - { - return this; - } - - - bool TableControl::HasRowHeader() - { - return GetModel()->hasRowHeaders(); - } - - - bool TableControl::HasColHeader() - { - return GetModel()->hasColumnHeaders(); - } - - - sal_Int32 TableControl::GetAccessibleControlCount() const - { - // TC_TABLE is always defined, no matter whether empty or not - sal_Int32 count = 1; - if ( GetModel()->hasRowHeaders() ) - ++count; - if ( GetModel()->hasColumnHeaders() ) - ++count; - return count; - } - - - bool TableControl::ConvertPointToControlIndex( sal_Int32& _rnIndex, const Point& _rPoint ) - { - sal_Int32 nRow = m_pImpl->getRowAtPoint( _rPoint ); - sal_Int32 nCol = m_pImpl->getColAtPoint( _rPoint ); - _rnIndex = nRow * GetColumnCount() + nCol; - return nRow >= 0; - } - - - sal_Int32 TableControl::GetRowCount() const - { - return GetModel()->getRowCount(); - } - - - sal_Int32 TableControl::GetColumnCount() const - { - return GetModel()->getColumnCount(); - } - - - bool TableControl::ConvertPointToCellAddress( sal_Int32& _rnRow, sal_Int32& _rnColPos, const Point& _rPoint ) - { - _rnRow = m_pImpl->getRowAtPoint( _rPoint ); - _rnColPos = m_pImpl->getColAtPoint( _rPoint ); - return _rnRow >= 0; - } - - - void TableControl::FillAccessibleStateSetForCell( sal_Int64& _rStateSet, sal_Int32 _nRow, sal_uInt16 ) const - { - if ( IsRowSelected( _nRow ) ) - _rStateSet |= AccessibleStateType::SELECTED; - if ( HasChildPathFocus() ) - _rStateSet |= AccessibleStateType::FOCUSED; - else // only transient when column is not focused - _rStateSet |= AccessibleStateType::TRANSIENT; - - _rStateSet |= AccessibleStateType::VISIBLE; - _rStateSet |= AccessibleStateType::SHOWING; - _rStateSet |= AccessibleStateType::ENABLED; - _rStateSet |= AccessibleStateType::SENSITIVE; - _rStateSet |= AccessibleStateType::ACTIVE; - } - - - tools::Rectangle TableControl::GetFieldCharacterBounds(sal_Int32,sal_Int32,sal_Int32 nIndex) - { - return GetCharacterBounds(nIndex); - } - - - sal_Int32 TableControl::GetFieldIndexAtPoint(sal_Int32,sal_Int32,const Point& _rPoint) - { - return GetIndexForPoint(_rPoint); - } - - - tools::Rectangle TableControl::calcHeaderRect(bool _bIsColumnBar ) - { - return m_pImpl->calcHeaderRect( !_bIsColumnBar ); - } - - - tools::Rectangle TableControl::calcHeaderCellRect( bool _bIsColumnBar, sal_Int32 nPos ) - { - return m_pImpl->calcHeaderCellRect( _bIsColumnBar, nPos ); - } - - - tools::Rectangle TableControl::calcTableRect() - { - return m_pImpl->calcTableRect(); - } - - - tools::Rectangle TableControl::calcCellRect( sal_Int32 _nRowPos, sal_Int32 _nColPos ) - { - return m_pImpl->calcCellRect( _nRowPos, _nColPos ); - } - - - IMPL_LINK_NOARG(TableControl, ImplSelectHdl, LinkParamNone*, void) - { - Select(); - } - - - void TableControl::Select() - { - ImplCallEventListenersAndHandler( VclEventId::TableRowSelect, nullptr ); - - if ( m_pImpl->isAccessibleAlive() ) - { - m_pImpl->commitAccessibleEvent( AccessibleEventId::SELECTION_CHANGED ); - - m_pImpl->commitTableEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), Any() ); - // TODO: why do we notify this when the *selection* changed? Shouldn't we find a better place for this, - // actually, when the active descendant, i.e. the current cell, *really* changed? - } - } - -} // namespace svt::table - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/table/tablecontrol_impl.cxx b/svtools/source/table/tablecontrol_impl.cxx deleted file mode 100644 index c82a272762cd..000000000000 --- a/svtools/source/table/tablecontrol_impl.cxx +++ /dev/null @@ -1,2552 +0,0 @@ -/* -*- 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 <table/tablecontrol.hxx> -#include <table/defaultinputhandler.hxx> -#include <table/tablemodel.hxx> - -#include "tabledatawindow.hxx" -#include "tablecontrol_impl.hxx" -#include "tablegeometry.hxx" - -#include <com/sun/star/accessibility/XAccessible.hpp> -#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> -#include <com/sun/star/accessibility/AccessibleEventId.hpp> -#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp> - -#include <comphelper/flagguard.hxx> -#include <vcl/accessiblefactory.hxx> -#include <vcl/scrbar.hxx> -#include <vcl/seleng.hxx> -#include <vcl/settings.hxx> -#include <vcl/image.hxx> -#include <tools/diagnose_ex.h> -#include <tools/debug.hxx> - -#include <cstdlib> -#include <numeric> - -#define MIN_COLUMN_WIDTH_PIXEL 4 - - -namespace svt::table -{ - - - using ::com::sun::star::accessibility::AccessibleTableModelChange; - using ::com::sun::star::uno::Any; - using ::com::sun::star::accessibility::XAccessible; - using ::com::sun::star::uno::Reference; - - namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId; - namespace AccessibleTableModelChangeType = ::com::sun::star::accessibility::AccessibleTableModelChangeType; - - - //= SuppressCursor - - namespace { - - class SuppressCursor - { - private: - ITableControl& m_rTable; - - public: - explicit SuppressCursor( ITableControl& _rTable ) - :m_rTable( _rTable ) - { - m_rTable.hideCursor(); - } - ~SuppressCursor() - { - m_rTable.showCursor(); - } - }; - - - //= EmptyTableModel - - /** default implementation of an ->ITableModel, used as fallback when no - real model is present - - Instances of this class are static in any way, and provide the least - necessary default functionality for a table model. - */ - class EmptyTableModel : public ITableModel - { - public: - EmptyTableModel() - { - } - - // ITableModel overridables - virtual TableSize getColumnCount() const override - { - return 0; - } - virtual TableSize getRowCount() const override - { - return 0; - } - virtual bool hasColumnHeaders() const override - { - return false; - } - virtual bool hasRowHeaders() const override - { - return false; - } - virtual PColumnModel getColumnModel( ColPos ) override - { - OSL_FAIL( "EmptyTableModel::getColumnModel: invalid call!" ); - return PColumnModel(); - } - virtual PTableRenderer getRenderer() const override - { - return PTableRenderer(); - } - virtual PTableInputHandler getInputHandler() const override - { - return PTableInputHandler(); - } - virtual TableMetrics getRowHeight() const override - { - return 5 * 100; - } - virtual TableMetrics getColumnHeaderHeight() const override - { - return 0; - } - virtual TableMetrics getRowHeaderWidth() const override - { - return 0; - } - virtual ScrollbarVisibility getVerticalScrollbarVisibility() const override - { - return ScrollbarShowNever; - } - virtual ScrollbarVisibility getHorizontalScrollbarVisibility() const override - { - return ScrollbarShowNever; - } - virtual void addTableModelListener( const PTableModelListener& ) override {} - virtual void removeTableModelListener( const PTableModelListener& ) override {} - virtual ::std::optional< ::Color > getLineColor() const override - { - return ::std::optional< ::Color >(); - } - virtual ::std::optional< ::Color > getHeaderBackgroundColor() const override - { - return ::std::optional< ::Color >(); - } - virtual ::std::optional< ::Color > getHeaderTextColor() const override - { - return ::std::optional< ::Color >(); - } - virtual ::std::optional< ::Color > getActiveSelectionBackColor() const override - { - return ::std::optional< ::Color >(); - } - virtual ::std::optional< ::Color > getInactiveSelectionBackColor() const override - { - return ::std::optional< ::Color >(); - } - virtual ::std::optional< ::Color > getActiveSelectionTextColor() const override - { - return ::std::optional< ::Color >(); - } - virtual ::std::optional< ::Color > getInactiveSelectionTextColor() const override - { - return ::std::optional< ::Color >(); - } - virtual ::std::optional< ::Color > getTextColor() const override - { - return ::std::optional< ::Color >(); - } - virtual ::std::optional< ::Color > getTextLineColor() const override - { - return ::std::optional< ::Color >(); - } - virtual ::std::optional< ::std::vector< ::Color > > getRowBackgroundColors() const override - { - return ::std::optional< ::std::vector< ::Color > >(); - } - virtual css::style::VerticalAlignment getVerticalAlign() const override - { - return css::style::VerticalAlignment(0); - } - virtual ITableDataSort* getSortAdapter() override - { - return nullptr; - } - virtual bool isEnabled() const override - { - return true; - } - virtual void getCellContent( ColPos const, RowPos const, css::uno::Any& o_cellContent ) override - { - o_cellContent.clear(); - } - virtual void getCellToolTip( ColPos const, RowPos const, css::uno::Any& ) override - { - } - virtual Any getRowHeading( RowPos const ) const override - { - return Any(); - } - }; - - } - - TableControl_Impl::TableControl_Impl( TableControl& _rAntiImpl ) - :m_rAntiImpl ( _rAntiImpl ) - ,m_pModel ( std::make_shared<EmptyTableModel>() ) - ,m_pInputHandler ( ) - ,m_nRowHeightPixel ( 15 ) - ,m_nColHeaderHeightPixel( 0 ) - ,m_nRowHeaderWidthPixel ( 0 ) - ,m_nColumnCount ( 0 ) - ,m_nRowCount ( 0 ) - ,m_nCurColumn ( COL_INVALID ) - ,m_nCurRow ( ROW_INVALID ) - ,m_nLeftColumn ( 0 ) - ,m_nTopRow ( 0 ) - ,m_nCursorHidden ( 1 ) - ,m_pDataWindow ( VclPtr<TableDataWindow>::Create( *this ) ) - ,m_pVScroll ( nullptr ) - ,m_pHScroll ( nullptr ) - ,m_pScrollCorner ( nullptr ) - ,m_aSelectedRows ( ) - ,m_pTableFunctionSet ( new TableFunctionSet( this ) ) - ,m_nAnchor ( -1 ) - ,m_bUpdatingColWidths ( false ) - ,m_pAccessibleTable ( nullptr ) - { - m_pSelEngine.reset( new SelectionEngine( m_pDataWindow.get(), m_pTableFunctionSet.get() ) ); - m_pSelEngine->SetSelectionMode(SelectionMode::Single); - m_pDataWindow->SetPosPixel( Point( 0, 0 ) ); - m_pDataWindow->Show(); - } - - TableControl_Impl::~TableControl_Impl() - { - m_pVScroll.disposeAndClear(); - m_pHScroll.disposeAndClear(); - m_pScrollCorner.disposeAndClear(); - m_pDataWindow.disposeAndClear(); - m_pTableFunctionSet.reset(); - m_pSelEngine.reset(); - } - - void TableControl_Impl::setModel( const PTableModel& _pModel ) - { - SuppressCursor aHideCursor( *this ); - - if ( m_pModel ) - m_pModel->removeTableModelListener( shared_from_this() ); - - m_pModel = _pModel; - if ( !m_pModel) - m_pModel = std::make_shared<EmptyTableModel>(); - - m_pModel->addTableModelListener( shared_from_this() ); - - m_nCurRow = ROW_INVALID; - m_nCurColumn = COL_INVALID; - - // recalc some model-dependent cached info - impl_ni_updateCachedModelValues(); - impl_ni_relayout(); - - // completely invalidate - m_rAntiImpl.Invalidate(); - - // reset cursor to (0,0) - if ( m_nRowCount ) m_nCurRow = 0; - if ( m_nColumnCount ) m_nCurColumn = 0; - } - - - namespace - { - bool lcl_adjustSelectedRows( ::std::vector< RowPos >& io_selectionIndexes, RowPos const i_firstAffectedRowIndex, TableSize const i_offset ) - { - bool didChanges = false; - for (auto & selectionIndex : io_selectionIndexes) - { - if ( selectionIndex < i_firstAffectedRowIndex ) - continue; - selectionIndex += i_offset; - didChanges = true; - } - return didChanges; - } - } - - - void TableControl_Impl::rowsInserted( RowPos i_first, RowPos i_last ) - { - OSL_PRECOND( i_last >= i_first, "TableControl_Impl::rowsInserted: invalid row indexes!" ); - - TableSize const insertedRows = i_last - i_first + 1; - - // adjust selection, if necessary - bool const selectionChanged = lcl_adjustSelectedRows( m_aSelectedRows, i_first, insertedRows ); - - // adjust our cached row count - m_nRowCount = m_pModel->getRowCount(); - - // if the rows have been inserted before the current row, adjust this - if ( i_first <= m_nCurRow ) - goTo( m_nCurColumn, m_nCurRow + insertedRows ); - - // relayout, since the scrollbar need might have changed - impl_ni_relayout(); - - // notify A1YY events - if ( impl_isAccessibleAlive() ) - { - impl_commitAccessibleEvent( AccessibleEventId::TABLE_MODEL_CHANGED, - Any( AccessibleTableModelChange( AccessibleTableModelChangeType::ROWS_INSERTED, i_first, i_last, -1, -1 ) ) - ); - } - - // schedule repaint - invalidateRowRange( i_first, ROW_INVALID ); - - // call selection handlers, if necessary - if ( selectionChanged ) - m_rAntiImpl.Select(); - } - - - void TableControl_Impl::rowsRemoved( RowPos i_first, RowPos i_last ) - { - sal_Int32 firstRemovedRow = i_first; - sal_Int32 lastRemovedRow = i_last; - - // adjust selection, if necessary - bool selectionChanged = false; - if ( i_first == -1 ) - { - selectionChanged = markAllRowsAsDeselected(); - - firstRemovedRow = 0; - lastRemovedRow = m_nRowCount - 1; - } - else - { - ENSURE_OR_RETURN_VOID( i_last >= i_first, "TableControl_Impl::rowsRemoved: illegal indexes!" ); - - for ( sal_Int32 row = i_first; row <= i_last; ++row ) - { - if ( markRowAsDeselected( row ) ) - selectionChanged = true; - } - - if ( lcl_adjustSelectedRows( m_aSelectedRows, i_last + 1, i_first - i_last - 1 ) ) - selectionChanged = true; - } - - // adjust cached row count - m_nRowCount = m_pModel->getRowCount(); - - // adjust the current row, if it is larger than the row count now - if ( m_nCurRow >= m_nRowCount ) - { - if ( m_nRowCount > 0 ) - goTo( m_nCurColumn, m_nRowCount - 1 ); - else - { - m_nCurRow = ROW_INVALID; - m_nTopRow = 0; - } - } - else if ( m_nRowCount == 0 ) - { - m_nTopRow = 0; - } - - - // relayout, since the scrollbar need might have changed - impl_ni_relayout(); - - // notify A11Y events - if ( impl_isAccessibleAlive() ) - { - commitTableEvent( - AccessibleEventId::TABLE_MODEL_CHANGED, - Any( AccessibleTableModelChange( - AccessibleTableModelChangeType::ROWS_REMOVED, - firstRemovedRow, - lastRemovedRow, - -1, - -1 - ) ), - Any() - ); - } - - // schedule a repaint - invalidateRowRange( firstRemovedRow, ROW_INVALID ); - - // call selection handlers, if necessary - if ( selectionChanged ) - m_rAntiImpl.Select(); - } - - - void TableControl_Impl::columnInserted() - { - m_nColumnCount = m_pModel->getColumnCount(); - impl_ni_relayout(); - - m_rAntiImpl.Invalidate(); - } - - - void TableControl_Impl::columnRemoved() - { - m_nColumnCount = m_pModel->getColumnCount(); - - // adjust the current column, if it is larger than the column count now - if ( m_nCurColumn >= m_nColumnCount ) - { - if ( m_nColumnCount > 0 ) - goTo( m_nCurColumn - 1, m_nCurRow ); - else - m_nCurColumn = COL_INVALID; - } - - impl_ni_relayout(); - - m_rAntiImpl.Invalidate(); - } - - - void TableControl_Impl::allColumnsRemoved() - { - m_nColumnCount = m_pModel->getColumnCount(); - impl_ni_relayout(); - - m_rAntiImpl.Invalidate(); - } - - - void TableControl_Impl::cellsUpdated( RowPos const i_firstRow, RowPos const i_lastRow ) - { - invalidateRowRange( i_firstRow, i_lastRow ); - } - - - void TableControl_Impl::tableMetricsChanged() - { - impl_ni_updateCachedTableMetrics(); - impl_ni_relayout(); - m_rAntiImpl.Invalidate(); - } - - - void TableControl_Impl::impl_invalidateColumn( ColPos const i_column ) - { - tools::Rectangle const aAllCellsArea( impl_getAllVisibleCellsArea() ); - - const TableColumnGeometry aColumn( *this, aAllCellsArea, i_column ); - if ( aColumn.isValid() ) - m_rAntiImpl.Invalidate( aColumn.getRect() ); - } - - - void TableControl_Impl::columnChanged( ColPos const i_column, ColumnAttributeGroup const i_attributeGroup ) - { - ColumnAttributeGroup nGroup( i_attributeGroup ); - if ( nGroup & ColumnAttributeGroup::APPEARANCE ) - { - impl_invalidateColumn( i_column ); - nGroup &= ~ColumnAttributeGroup::APPEARANCE; - } - - if ( nGroup & ColumnAttributeGroup::WIDTH ) - { - if ( !m_bUpdatingColWidths ) - { - impl_ni_relayout( i_column ); - invalidate( TableArea::All ); - } - - nGroup &= ~ColumnAttributeGroup::WIDTH; - } - - OSL_ENSURE( ( nGroup == ColumnAttributeGroup::NONE ) || ( i_attributeGroup == ColumnAttributeGroup::ALL ), - "TableControl_Impl::columnChanged: don't know how to handle this change!" ); - } - - - tools::Rectangle TableControl_Impl::impl_getAllVisibleCellsArea() const - { - tools::Rectangle aArea( Point( 0, 0 ), Size( 0, 0 ) ); - - // determine the right-most border of the last column which is - // at least partially visible - aArea.SetRight( m_nRowHeaderWidthPixel ); - if ( !m_aColumnWidths.empty() ) - { - // the number of pixels which are scrolled out of the left hand - // side of the window - const tools::Long nScrolledOutLeft = m_nLeftColumn == 0 ? 0 : m_aColumnWidths[ m_nLeftColumn - 1 ].getEnd(); - - ColumnPositions::const_reverse_iterator loop = m_aColumnWidths.rbegin(); - do - { - aArea.SetRight(loop->getEnd() - nScrolledOutLeft); - ++loop; - } - while ( ( loop != m_aColumnWidths.rend() ) - && ( loop->getEnd() - nScrolledOutLeft >= aArea.Right() ) - ); - } - // so far, aArea.Right() denotes the first pixel *after* the cell area - aArea.AdjustRight( -1 ); - - // determine the last row which is at least partially visible - aArea.SetBottom( - m_nColHeaderHeightPixel - + impl_getVisibleRows( true ) * m_nRowHeightPixel - - 1 ); - - return aArea; - } - - - tools::Rectangle TableControl_Impl::impl_getAllVisibleDataCellArea() const - { - tools::Rectangle aArea( impl_getAllVisibleCellsArea() ); - aArea.SetLeft( m_nRowHeaderWidthPixel ); - aArea.SetTop( m_nColHeaderHeightPixel ); - return aArea; - } - - - void TableControl_Impl::impl_ni_updateCachedTableMetrics() - { - m_nRowHeightPixel = m_rAntiImpl.LogicToPixel(Size(0, m_pModel->getRowHeight()), MapMode(MapUnit::MapAppFont)).Height(); - - m_nColHeaderHeightPixel = 0; - if ( m_pModel->hasColumnHeaders() ) - m_nColHeaderHeightPixel = m_rAntiImpl.LogicToPixel(Size(0, m_pModel->getColumnHeaderHeight()), MapMode(MapUnit::MapAppFont)).Height(); - - m_nRowHeaderWidthPixel = 0; - if ( m_pModel->hasRowHeaders() ) - m_nRowHeaderWidthPixel = m_rAntiImpl.LogicToPixel(Size(m_pModel->getRowHeaderWidth(), 0), MapMode(MapUnit::MapAppFont)).Width(); - } - - - void TableControl_Impl::impl_ni_updateCachedModelValues() - { - m_pInputHandler = m_pModel->getInputHandler(); - if ( !m_pInputHandler ) - m_pInputHandler = std::make_shared<DefaultInputHandler>(); - - m_nColumnCount = m_pModel->getColumnCount(); - if ( m_nLeftColumn >= m_nColumnCount ) - m_nLeftColumn = ( m_nColumnCount > 0 ) ? m_nColumnCount - 1 : 0; - - m_nRowCount = m_pModel->getRowCount(); - if ( m_nTopRow >= m_nRowCount ) - m_nTopRow = ( m_nRowCount > 0 ) ? m_nRowCount - 1 : 0; - - impl_ni_updateCachedTableMetrics(); - } - - - namespace - { - - /// determines whether a scrollbar is needed for the given values - bool lcl_determineScrollbarNeed( tools::Long const i_position, ScrollbarVisibility const i_visibility, - tools::Long const i_availableSpace, tools::Long const i_neededSpace ) - { - if ( i_visibility == ScrollbarShowNever ) - return false; - if ( i_visibility == ScrollbarShowAlways ) - return true; - if ( i_position > 0 ) - return true; - if ( i_availableSpace >= i_neededSpace ) - return false; - return true; - } - - - void lcl_setButtonRepeat( vcl::Window& _rWindow ) - { - AllSettings aSettings = _rWindow.GetSettings(); - MouseSettings aMouseSettings = aSettings.GetMouseSettings(); - - aMouseSettings.SetButtonRepeat( 0 ); - aSettings.SetMouseSettings( aMouseSettings ); - - _rWindow.SetSettings( aSettings, true ); - } - - - bool lcl_updateScrollbar( vcl::Window& _rParent, VclPtr<ScrollBar>& _rpBar, - bool const i_needBar, tools::Long _nVisibleUnits, - tools::Long _nPosition, tools::Long _nRange, - bool _bHorizontal, const Link<ScrollBar*,void>& _rScrollHandler ) - { - // do we currently have the scrollbar? - bool bHaveBar = _rpBar != nullptr; - - // do we need to correct the scrollbar visibility? - if ( bHaveBar && !i_needBar ) - { - if ( _rpBar->IsTracking() ) - _rpBar->EndTracking(); - _rpBar.disposeAndClear(); - } - else if ( !bHaveBar && i_needBar ) - { - _rpBar = VclPtr<ScrollBar>::Create( - - &_rParent, - WB_DRAG | ( _bHorizontal ? WB_HSCROLL : WB_VSCROLL ) - ); - _rpBar->SetScrollHdl( _rScrollHandler ); - // get some speed into the scrolling... - lcl_setButtonRepeat( *_rpBar ); - } - - if ( _rpBar ) - { - _rpBar->SetRange( Range( 0, _nRange ) ); - _rpBar->SetVisibleSize( _nVisibleUnits ); - _rpBar->SetPageSize( _nVisibleUnits ); - _rpBar->SetLineSize( 1 ); - _rpBar->SetThumbPos( _nPosition ); - _rpBar->Show(); - } - - return ( bHaveBar != i_needBar ); - } - - - /** returns the number of rows fitting into the given range, - for the given row height. Partially fitting rows are counted, too, if the - respective parameter says so. - */ - TableSize lcl_getRowsFittingInto( tools::Long _nOverallHeight, tools::Long _nRowHeightPixel, bool _bAcceptPartialRow ) - { - return _bAcceptPartialRow - ? ( _nOverallHeight + ( _nRowHeightPixel - 1 ) ) / _nRowHeightPixel - : _nOverallHeight / _nRowHeightPixel; - } - - - /** returns the number of columns fitting into the given area, - with the first visible column as given. Partially fitting columns are counted, too, - if the respective parameter says so. - */ - TableSize lcl_getColumnsVisibleWithin( const tools::Rectangle& _rArea, ColPos _nFirstVisibleColumn, - const TableControl_Impl& _rControl, bool _bAcceptPartialRow ) - { - TableSize visibleColumns = 0; - TableColumnGeometry aColumn( _rControl, _rArea, _nFirstVisibleColumn ); - while ( aColumn.isValid() ) - { - if ( !_bAcceptPartialRow ) - if ( aColumn.getRect().Right() > _rArea.Right() ) - // this column is only partially visible, and this is not allowed - break; - - aColumn.moveRight(); - ++visibleColumns; - } - return visibleColumns; - } - - } - - - tools::Long TableControl_Impl::impl_ni_calculateColumnWidths( ColPos const i_assumeInflexibleColumnsUpToIncluding, - bool const i_assumeVerticalScrollbar, ::std::vector< tools::Long >& o_newColWidthsPixel ) const - { - // the available horizontal space - tools::Long gridWidthPixel = m_rAntiImpl.GetOutputSizePixel().Width(); - ENSURE_OR_RETURN( !!m_pModel, "TableControl_Impl::impl_ni_calculateColumnWidths: not allowed without a model!", gridWidthPixel ); - if ( m_pModel->hasRowHeaders() && ( gridWidthPixel != 0 ) ) - { - gridWidthPixel -= m_nRowHeaderWidthPixel; - } - - if ( i_assumeVerticalScrollbar && ( m_pModel->getVerticalScrollbarVisibility() != ScrollbarShowNever ) ) - { - tools::Long nScrollbarMetrics = m_rAntiImpl.GetSettings().GetStyleSettings().GetScrollBarSize(); - gridWidthPixel -= nScrollbarMetrics; - } - - // no need to do anything without columns - TableSize const colCount = m_pModel->getColumnCount(); - if ( colCount == 0 ) - return gridWidthPixel; - - // collect some meta data for our columns: - // - their current (pixel) metrics - tools::Long accumulatedCurrentWidth = 0; - ::std::vector< tools::Long > currentColWidths; - currentColWidths.reserve( colCount ); - typedef ::std::vector< ::std::pair< tools::Long, long > > ColumnLimits; - ColumnLimits effectiveColumnLimits; - effectiveColumnLimits.reserve( colCount ); - tools::Long accumulatedMinWidth = 0; - tools::Long accumulatedMaxWidth = 0; - // - their relative flexibility - ::std::vector< ::sal_Int32 > columnFlexibilities; - columnFlexibilities.reserve( colCount ); - tools::Long flexibilityDenominator = 0; - size_t flexibleColumnCount = 0; - for ( ColPos col = 0; col < colCount; ++col ) - { - PColumnModel const pColumn = m_pModel->getColumnModel( col ); - ENSURE_OR_THROW( !!pColumn, "invalid column returned by the model!" ); - - // current width - tools::Long const currentWidth = appFontWidthToPixel( pColumn->getWidth() ); - currentColWidths.push_back( currentWidth ); - - // accumulated width - accumulatedCurrentWidth += currentWidth; - - // flexibility - ::sal_Int32 flexibility = pColumn->getFlexibility(); - OSL_ENSURE( flexibility >= 0, "TableControl_Impl::impl_ni_calculateColumnWidths: a column's flexibility should be non-negative." ); - if ( ( flexibility < 0 ) // normalization - || ( !pColumn->isResizable() ) // column not resizable => no auto-resize - || ( col <= i_assumeInflexibleColumnsUpToIncluding ) // column shall be treated as inflexible => respect this - ) - flexibility = 0; - - // min/max width - tools::Long effectiveMin = currentWidth, effectiveMax = currentWidth; - // if the column is not flexible, it will not be asked for min/max, but we assume the current width as limit then - if ( flexibility > 0 ) - { - tools::Long const minWidth = appFontWidthToPixel( pColumn->getMinWidth() ); - if ( minWidth > 0 ) - effectiveMin = minWidth; - else - effectiveMin = MIN_COLUMN_WIDTH_PIXEL; - - tools::Long const maxWidth = appFontWidthToPixel( pColumn->getMaxWidth() ); - OSL_ENSURE( minWidth <= maxWidth, "TableControl_Impl::impl_ni_calculateColumnWidths: pretty undecided 'bout its width limits, this column!" ); - if ( ( maxWidth > 0 ) && ( maxWidth >= minWidth ) ) - effectiveMax = maxWidth; - else - effectiveMax = gridWidthPixel; // TODO: any better guess here? - - if ( effectiveMin == effectiveMax ) - // if the min and the max are identical, this implies no flexibility at all - flexibility = 0; - } - - columnFlexibilities.push_back( flexibility ); - flexibilityDenominator += flexibility; - if ( flexibility > 0 ) - ++flexibleColumnCount; - - effectiveColumnLimits.emplace_back( effectiveMin, effectiveMax ); - accumulatedMinWidth += effectiveMin; - accumulatedMaxWidth += effectiveMax; - } - - o_newColWidthsPixel = currentColWidths; - if ( flexibilityDenominator == 0 ) - { - // no column is flexible => don't adjust anything - } - else if ( gridWidthPixel > accumulatedCurrentWidth ) - { // we have space to give away ... - tools::Long distributePixel = gridWidthPixel - accumulatedCurrentWidth; - if ( gridWidthPixel > accumulatedMaxWidth ) - { - // ... but the column's maximal widths are still less than we have - // => set them all to max - for ( svt::table::TableSize i = 0; i < colCount; ++i ) - { - o_newColWidthsPixel[i] = effectiveColumnLimits[i].second; - } - } - else - { - bool startOver = false; - do - { - startOver = false; - // distribute the remaining space amongst all columns with a positive flexibility - for ( size_t i=0; i<o_newColWidthsPixel.size() && !startOver; ++i ) - { - tools::Long const columnFlexibility = columnFlexibilities[i]; - if ( columnFlexibility == 0 ) - continue; - - tools::Long newColWidth = currentColWidths[i] + columnFlexibility * distributePixel / flexibilityDenominator; - - if ( newColWidth > effectiveColumnLimits[i].second ) - { // that was too much, we hit the col's maximum - // set the new width to exactly this maximum - newColWidth = effectiveColumnLimits[i].second; - // adjust the flexibility denominator ... - flexibilityDenominator -= columnFlexibility; - columnFlexibilities[i] = 0; - --flexibleColumnCount; - // ... and the remaining width ... - tools::Long const difference = newColWidth - currentColWidths[i]; - distributePixel -= difference; - // ... this way, we ensure that the width not taken up by this column is consumed by the other - // flexible ones (if there are some) - - // and start over with the first column, since there might be earlier columns which need - // to be recalculated now - startOver = true; - } - - o_newColWidthsPixel[i] = newColWidth; - } - } - while ( startOver ); - - // are there pixels left (might be caused by rounding errors)? - distributePixel = gridWidthPixel - ::std::accumulate( o_newColWidthsPixel.begin(), o_newColWidthsPixel.end(), 0 ); - while ( ( distributePixel > 0 ) && ( flexibleColumnCount > 0 ) ) - { - // yes => ignore relative flexibilities, and subsequently distribute single pixels to all flexible - // columns which did not yet reach their maximum. - for ( size_t i=0; ( i < o_newColWidthsPixel.size() ) && ( distributePixel > 0 ); ++i ) - { - if ( columnFlexibilities[i] == 0 ) - continue; - - OSL_ENSURE( o_newColWidthsPixel[i] <= effectiveColumnLimits[i].second, - "TableControl_Impl::impl_ni_calculateColumnWidths: inconsistency!" ); - if ( o_newColWidthsPixel[i] >= effectiveColumnLimits[i].first ) - { - columnFlexibilities[i] = 0; - --flexibleColumnCount; - continue; - } - - ++o_newColWidthsPixel[i]; - --distributePixel; - } - } - } - } - else if ( gridWidthPixel < accumulatedCurrentWidth ) - { // we need to take away some space from the columns which allow it ... - tools::Long takeAwayPixel = accumulatedCurrentWidth - gridWidthPixel; - if ( gridWidthPixel < accumulatedMinWidth ) - { - // ... but the column's minimal widths are still more than we have - // => set them all to min - for ( svt::table::TableSize i = 0; i < colCount; ++i ) - { - o_newColWidthsPixel[i] = effectiveColumnLimits[i].first; - } - } - else - { - bool startOver = false; - do - { - startOver = false; - // take away the space we need from the columns with a positive flexibility - for ( size_t i=0; i<o_newColWidthsPixel.size() && !startOver; ++i ) - { - tools::Long const columnFlexibility = columnFlexibilities[i]; - if ( columnFlexibility == 0 ) - continue; - - tools::Long newColWidth = currentColWidths[i] - columnFlexibility * takeAwayPixel / flexibilityDenominator; - - if ( newColWidth < effectiveColumnLimits[i].first ) - { // that was too much, we hit the col's minimum - // set the new width to exactly this minimum - newColWidth = effectiveColumnLimits[i].first; - // adjust the flexibility denominator ... - flexibilityDenominator -= columnFlexibility; - columnFlexibilities[i] = 0; - --flexibleColumnCount; - // ... and the remaining width ... - tools::Long const difference = currentColWidths[i] - newColWidth; - takeAwayPixel -= difference; - - // and start over with the first column, since there might be earlier columns which need - // to be recalculated now - startOver = true; - } - - o_newColWidthsPixel[i] = newColWidth; - } - } - while ( startOver ); - - // are there pixels left (might be caused by rounding errors)? - takeAwayPixel = ::std::accumulate( o_newColWidthsPixel.begin(), o_newColWidthsPixel.end(), 0 ) - gridWidthPixel; - while ( ( takeAwayPixel > 0 ) && ( flexibleColumnCount > 0 ) ) - { - // yes => ignore relative flexibilities, and subsequently take away pixels from all flexible - // columns which did not yet reach their minimum. - for ( size_t i=0; ( i < o_newColWidthsPixel.size() ) && ( takeAwayPixel > 0 ); ++i ) - { - if ( columnFlexibilities[i] == 0 ) - continue; - - OSL_ENSURE( o_newColWidthsPixel[i] >= effectiveColumnLimits[i].first, - "TableControl_Impl::impl_ni_calculateColumnWidths: inconsistency!" ); - if ( o_newColWidthsPixel[i] <= effectiveColumnLimits[i].first ) - { - columnFlexibilities[i] = 0; - --flexibleColumnCount; - continue; - } - - --o_newColWidthsPixel[i]; - --takeAwayPixel; - } - } - } - } - - return gridWidthPixel; - } - - - void TableControl_Impl::impl_ni_relayout( ColPos const i_assumeInflexibleColumnsUpToIncluding ) - { - ENSURE_OR_RETURN_VOID( !m_bUpdatingColWidths, "TableControl_Impl::impl_ni_relayout: recursive call detected!" ); - - m_aColumnWidths.resize( 0 ); - if ( !m_pModel ) - return; - - ::comphelper::FlagRestorationGuard const aWidthUpdateFlag( m_bUpdatingColWidths, true ); - SuppressCursor aHideCursor( *this ); - - // layouting steps: - - // 1. adjust column widths, leaving space for a vertical scrollbar - // 2. determine need for a vertical scrollbar - // - V-YES: all fine, result from 1. is still valid - // - V-NO: result from 1. is still under consideration - - // 3. determine need for a horizontal scrollbar - // - H-NO: all fine, result from 2. is still valid - // - H-YES: reconsider need for a vertical scrollbar, if result of 2. was V-NO - // - V-YES: all fine, result from 1. is still valid - // - V-NO: redistribute the remaining space (if any) amongst all columns which allow it - - ::std::vector< tools::Long > newWidthsPixel; - tools::Long gridWidthPixel = impl_ni_calculateColumnWidths( i_assumeInflexibleColumnsUpToIncluding, true, newWidthsPixel ); - - // the width/height of a scrollbar, needed several times below - tools::Long const nScrollbarMetrics = m_rAntiImpl.GetSettings().GetStyleSettings().GetScrollBarSize(); - - // determine the playground for the data cells (excluding headers) - // TODO: what if the control is smaller than needed for the headers/scrollbars? - tools::Rectangle aDataCellPlayground( Point( 0, 0 ), m_rAntiImpl.GetOutputSizePixel() ); - aDataCellPlayground.SetLeft( m_nRowHeaderWidthPixel ); - aDataCellPlayground.SetTop( m_nColHeaderHeightPixel ); - - OSL_ENSURE( ( m_nRowCount == m_pModel->getRowCount() ) && ( m_nColumnCount == m_pModel->getColumnCount() ), - "TableControl_Impl::impl_ni_relayout: how is this expected to work with invalid data?" ); - tools::Long const nAllColumnsWidth = ::std::accumulate( newWidthsPixel.begin(), newWidthsPixel.end(), 0 ); - - ScrollbarVisibility const eVertScrollbar = m_pModel->getVerticalScrollbarVisibility(); - ScrollbarVisibility const eHorzScrollbar = m_pModel->getHorizontalScrollbarVisibility(); - - // do we need a vertical scrollbar? - bool bNeedVerticalScrollbar = lcl_determineScrollbarNeed( - m_nTopRow, eVertScrollbar, aDataCellPlayground.GetHeight(), m_nRowHeightPixel * m_nRowCount ); - bool bFirstRoundVScrollNeed = false; - if ( bNeedVerticalScrollbar ) - { - aDataCellPlayground.AdjustRight( -nScrollbarMetrics ); - bFirstRoundVScrollNeed = true; - } - - // do we need a horizontal scrollbar? - bool const bNeedHorizontalScrollbar = lcl_determineScrollbarNeed( - m_nLeftColumn, eHorzScrollbar, aDataCellPlayground.GetWidth(), nAllColumnsWidth ); - if ( bNeedHorizontalScrollbar ) - { - aDataCellPlayground.AdjustBottom( -nScrollbarMetrics ); - - // now that we just found that we need a horizontal scrollbar, - // the need for a vertical one may have changed, since the horizontal - // SB might just occupy enough space so that not all rows do fit - // anymore - if ( !bFirstRoundVScrollNeed ) - { - bNeedVerticalScrollbar = lcl_determineScrollbarNeed( - m_nTopRow, eVertScrollbar, aDataCellPlayground.GetHeight(), m_nRowHeightPixel * m_nRowCount ); - if ( bNeedVerticalScrollbar ) - { - aDataCellPlayground.AdjustRight( -nScrollbarMetrics ); - } - } - } - - // the initial call to impl_ni_calculateColumnWidths assumed that we need a vertical scrollbar. If, by now, - // we know that this is not the case, re-calculate the column widths. - if ( !bNeedVerticalScrollbar ) - gridWidthPixel = impl_ni_calculateColumnWidths( i_assumeInflexibleColumnsUpToIncluding, false, newWidthsPixel ); - - // update the column objects with the new widths we finally calculated - TableSize const colCount = m_pModel->getColumnCount(); - m_aColumnWidths.reserve( colCount ); - tools::Long accumulatedWidthPixel = m_nRowHeaderWidthPixel; - bool anyColumnWidthChanged = false; - for ( ColPos col = 0; col < colCount; ++col ) - { - const tools::Long columnStart = accumulatedWidthPixel; - const tools::Long columnEnd = columnStart + newWidthsPixel[col]; - m_aColumnWidths.emplace_back( columnStart, columnEnd ); - accumulatedWidthPixel = columnEnd; - - // and don't forget to forward this to the column models - PColumnModel const pColumn = m_pModel->getColumnModel( col ); - ENSURE_OR_THROW( !!pColumn, "invalid column returned by the model!" ); - - tools::Long const oldColumnWidthAppFont = pColumn->getWidth(); - tools::Long const newColumnWidthAppFont = pixelWidthToAppFont( newWidthsPixel[col] ); - pColumn->setWidth( newColumnWidthAppFont ); - - anyColumnWidthChanged |= ( oldColumnWidthAppFont != newColumnWidthAppFont ); - } - - // if the column widths changed, ensure everything is repainted - if ( anyColumnWidthChanged ) - invalidate( TableArea::All ); - - // if the column resizing happened to leave some space at the right, but there are columns - // scrolled out to the left, scroll them in - while ( ( m_nLeftColumn > 0 ) - && ( accumulatedWidthPixel - m_aColumnWidths[ m_nLeftColumn - 1 ].getStart() <= gridWidthPixel ) - ) - { - --m_nLeftColumn; - } - - // now adjust the column metrics, since they currently ignore the horizontal scroll position - if ( m_nLeftColumn > 0 ) - { - const tools::Long offsetPixel = m_aColumnWidths[ 0 ].getStart() - m_aColumnWidths[ m_nLeftColumn ].getStart(); - for (auto & columnWidth : m_aColumnWidths) - { - columnWidth.move( offsetPixel ); - } - } - - // show or hide the scrollbars as needed, and position the data window - impl_ni_positionChildWindows( aDataCellPlayground, bNeedVerticalScrollbar, bNeedHorizontalScrollbar ); - } - - - void TableControl_Impl::impl_ni_positionChildWindows( tools::Rectangle const & i_dataCellPlayground, - bool const i_verticalScrollbar, bool const i_horizontalScrollbar ) - { - tools::Long const nScrollbarMetrics = m_rAntiImpl.GetSettings().GetStyleSettings().GetScrollBarSize(); - - // create or destroy the vertical scrollbar, as needed - lcl_updateScrollbar( - m_rAntiImpl, - m_pVScroll, - i_verticalScrollbar, - lcl_getRowsFittingInto( i_dataCellPlayground.GetHeight(), m_nRowHeightPixel, false ), - // visible units - m_nTopRow, // current position - m_nRowCount, // range - false, // vertical - LINK( this, TableControl_Impl, OnScroll ) // scroll handler - ); - - // position it - if ( m_pVScroll ) - { - tools::Rectangle aScrollbarArea( - Point( i_dataCellPlayground.Right() + 1, 0 ), - Size( nScrollbarMetrics, i_dataCellPlayground.Bottom() + 1 ) - ); - m_pVScroll->SetPosSizePixel( - aScrollbarArea.TopLeft(), aScrollbarArea.GetSize() ); - } - - // create or destroy the horizontal scrollbar, as needed - lcl_updateScrollbar( - m_rAntiImpl, - m_pHScroll, - i_horizontalScrollbar, - lcl_getColumnsVisibleWithin( i_dataCellPlayground, m_nLeftColumn, *this, false ), - // visible units - m_nLeftColumn, // current position - m_nColumnCount, // range - true, // horizontal - LINK( this, TableControl_Impl, OnScroll ) // scroll handler - ); - - // position it - if ( m_pHScroll ) - { - TableSize const nVisibleUnits = lcl_getColumnsVisibleWithin( i_dataCellPlayground, m_nLeftColumn, *this, false ); - TableMetrics const nRange = m_nColumnCount; - if( m_nLeftColumn + nVisibleUnits == nRange - 1 ) - { - if ( m_aColumnWidths[ nRange - 1 ].getStart() - m_aColumnWidths[ m_nLeftColumn ].getEnd() + m_aColumnWidths[ nRange-1 ].getWidth() > i_dataCellPlayground.GetWidth() ) - { - m_pHScroll->SetVisibleSize( nVisibleUnits -1 ); - m_pHScroll->SetPageSize( nVisibleUnits - 1 ); - } - } - tools::Rectangle aScrollbarArea( - Point( 0, i_dataCellPlayground.Bottom() + 1 ), - Size( i_dataCellPlayground.Right() + 1, nScrollbarMetrics ) - ); - m_pHScroll->SetPosSizePixel( - aScrollbarArea.TopLeft(), aScrollbarArea.GetSize() ); - } - - // the corner window connecting the two scrollbars in the lower right corner - bool bHaveScrollCorner = nullptr != m_pScrollCorner; - bool bNeedScrollCorner = ( nullptr != m_pHScroll ) && ( nullptr != m_pVScroll ); - if ( bHaveScrollCorner && !bNeedScrollCorner ) - { - m_pScrollCorner.disposeAndClear(); - } - else if ( !bHaveScrollCorner && bNeedScrollCorner ) - { - m_pScrollCorner = VclPtr<ScrollBarBox>::Create( &m_rAntiImpl ); - m_pScrollCorner->SetSizePixel( Size( nScrollbarMetrics, nScrollbarMetrics ) ); - m_pScrollCorner->SetPosPixel( Point( i_dataCellPlayground.Right() + 1, i_dataCellPlayground.Bottom() + 1 ) ); - m_pScrollCorner->Show(); - } - else if(bHaveScrollCorner && bNeedScrollCorner) - { - m_pScrollCorner->SetPosPixel( Point( i_dataCellPlayground.Right() + 1, i_dataCellPlayground.Bottom() + 1 ) ); - m_pScrollCorner->Show(); - } - - // resize the data window - m_pDataWindow->SetSizePixel( Size( - i_dataCellPlayground.GetWidth() + m_nRowHeaderWidthPixel, - i_dataCellPlayground.GetHeight() + m_nColHeaderHeightPixel - ) ); - } - - - void TableControl_Impl::onResize() - { - impl_ni_relayout(); - checkCursorPosition(); - } - - - void TableControl_Impl::doPaintContent(vcl::RenderContext& rRenderContext, const tools::Rectangle& _rUpdateRect) - { - if (!getModel()) - return; - PTableRenderer pRenderer = getModel()->getRenderer(); - DBG_ASSERT(!!pRenderer, "TableDataWindow::doPaintContent: invalid renderer!"); - if (!pRenderer) - return; - - // our current style settings, to be passed to the renderer - const StyleSettings& rStyle = rRenderContext.GetSettings().GetStyleSettings(); - m_nRowCount = m_pModel->getRowCount(); - // the area occupied by all (at least partially) visible cells, including - // headers - tools::Rectangle const aAllCellsWithHeaders( impl_getAllVisibleCellsArea() ); - - // draw the header column area - if (m_pModel->hasColumnHeaders()) - { - TableRowGeometry const aHeaderRow(*this, tools::Rectangle(Point(0, 0), aAllCellsWithHeaders.BottomRight()), ROW_COL_HEADERS); - tools::Rectangle const aColRect(aHeaderRow.getRect()); - pRenderer->PaintHeaderArea(rRenderContext, aColRect, true, false, rStyle); - // Note that strictly, aHeaderRow.getRect() also contains the intersection between column - // and row header area. However, below we go to paint this intersection, again, - // so this hopefully doesn't hurt if we already paint it here. - - for (TableCellGeometry aCell(aHeaderRow, m_nLeftColumn); aCell.isValid(); aCell.moveRight()) - { - if (_rUpdateRect.GetIntersection(aCell.getRect()).IsEmpty()) - continue; - - pRenderer->PaintColumnHeader(aCell.getColumn(), rRenderContext, aCell.getRect(), rStyle); - } - } - // the area occupied by the row header, if any - tools::Rectangle aRowHeaderArea; - if (m_pModel->hasRowHeaders()) - { - aRowHeaderArea = aAllCellsWithHeaders; - aRowHeaderArea.SetRight( m_nRowHeaderWidthPixel - 1 ); - - TableSize const nVisibleRows = impl_getVisibleRows(true); - TableSize nActualRows = nVisibleRows; - if (m_nTopRow + nActualRows > m_nRowCount) - nActualRows = m_nRowCount - m_nTopRow; - aRowHeaderArea.SetBottom( m_nColHeaderHeightPixel + m_nRowHeightPixel * nActualRows - 1 ); - - pRenderer->PaintHeaderArea(rRenderContext, aRowHeaderArea, false, true, rStyle); - // Note that strictly, aRowHeaderArea also contains the intersection between column - // and row header area. However, below we go to paint this intersection, again, - // so this hopefully doesn't hurt if we already paint it here. - - if (m_pModel->hasColumnHeaders()) - { - TableCellGeometry const aIntersection(*this, tools::Rectangle(Point(0, 0), aAllCellsWithHeaders.BottomRight()), - COL_ROW_HEADERS, ROW_COL_HEADERS); - tools::Rectangle const aInters(aIntersection.getRect()); - pRenderer->PaintHeaderArea(rRenderContext, aInters, true, true, rStyle); - } - } - - // draw the table content row by row - TableSize colCount = getModel()->getColumnCount(); - - // paint all rows - tools::Rectangle const aAllDataCellsArea(impl_getAllVisibleDataCellArea()); - for (TableRowGeometry aRowIterator(*this, aAllCellsWithHeaders, getTopRow()); aRowIterator.isValid(); aRowIterator.moveDown()) - { - if (_rUpdateRect.GetIntersection(aRowIterator.getRect() ).IsEmpty()) - continue; - - bool const isControlFocused = m_rAntiImpl.HasControlFocus(); - bool const isSelectedRow = isRowSelected(aRowIterator.getRow()); - - tools::Rectangle const aRect = aRowIterator.getRect().GetIntersection(aAllDataCellsArea); - - // give the renderer a chance to prepare the row - pRenderer->PrepareRow(aRowIterator.getRow(), isControlFocused, isSelectedRow, rRenderContext, aRect, rStyle); - - // paint the row header - if (m_pModel->hasRowHeaders()) - { - const tools::Rectangle aCurrentRowHeader(aRowHeaderArea.GetIntersection(aRowIterator.getRect())); - pRenderer->PaintRowHeader(rRenderContext, aCurrentRowHeader, rStyle); - } - - if (!colCount) - continue; - - // paint all cells in this row - for (TableCellGeometry aCell(aRowIterator, m_nLeftColumn); aCell.isValid(); aCell.moveRight()) - { - pRenderer->PaintCell(aCell.getColumn(), isSelectedRow, isControlFocused, - rRenderContext, aCell.getRect(), rStyle); - } - } - } - - void TableControl_Impl::hideCursor() - { - if ( ++m_nCursorHidden == 1 ) - impl_ni_doSwitchCursor( false ); - } - - - void TableControl_Impl::showCursor() - { - DBG_ASSERT( m_nCursorHidden > 0, "TableControl_Impl::showCursor: cursor not hidden!" ); - if ( --m_nCursorHidden == 0 ) - impl_ni_doSwitchCursor( true ); - } - - - bool TableControl_Impl::dispatchAction( TableControlAction _eAction ) - { - bool bSuccess = false; - bool selectionChanged = false; - - switch ( _eAction ) - { - case cursorDown: - if ( m_pSelEngine->GetSelectionMode() == SelectionMode::Single ) - { - //if other rows already selected, deselect them - if(!m_aSelectedRows.empty()) - { - invalidateSelectedRows(); - m_aSelectedRows.clear(); - } - if ( m_nCurRow < m_nRowCount-1 ) - { - ++m_nCurRow; - m_aSelectedRows.push_back(m_nCurRow); - } - else - m_aSelectedRows.push_back(m_nCurRow); - invalidateRow( m_nCurRow ); - ensureVisible(m_nCurColumn,m_nCurRow); - selectionChanged = true; - bSuccess = true; - } - else - { - if ( m_nCurRow < m_nRowCount - 1 ) - bSuccess = goTo( m_nCurColumn, m_nCurRow + 1 ); - } - break; - - case cursorUp: - if(m_pSelEngine->GetSelectionMode() == SelectionMode::Single) - { - if(!m_aSelectedRows.empty()) - { - invalidateSelectedRows(); - m_aSelectedRows.clear(); - } - if(m_nCurRow>0) - { - --m_nCurRow; - m_aSelectedRows.push_back(m_nCurRow); - invalidateRow( m_nCurRow ); - } - else - { - m_aSelectedRows.push_back(m_nCurRow); - invalidateRow( m_nCurRow ); - } - ensureVisible(m_nCurColumn,m_nCurRow); - selectionChanged = true; - bSuccess = true; - } - else - { - if ( m_nCurRow > 0 ) - bSuccess = goTo( m_nCurColumn, m_nCurRow - 1 ); - } - break; - case cursorLeft: - if ( m_nCurColumn > 0 ) - bSuccess = goTo( m_nCurColumn - 1, m_nCurRow ); - else - if ( ( m_nCurColumn == 0) && ( m_nCurRow > 0 ) ) - bSuccess = goTo( m_nColumnCount - 1, m_nCurRow - 1 ); - break; - - case cursorRight: - if ( m_nCurColumn < m_nColumnCount - 1 ) - bSuccess = goTo( m_nCurColumn + 1, m_nCurRow ); - else - if ( ( m_nCurColumn == m_nColumnCount - 1 ) && ( m_nCurRow < m_nRowCount - 1 ) ) - bSuccess = goTo( 0, m_nCurRow + 1 ); - break; - - case cursorToLineStart: - bSuccess = goTo( 0, m_nCurRow ); - break; - - case cursorToLineEnd: - bSuccess = goTo( m_nColumnCount - 1, m_nCurRow ); - break; - - case cursorToFirstLine: - bSuccess = goTo( m_nCurColumn, 0 ); - break; - - case cursorToLastLine: - bSuccess = goTo( m_nCurColumn, m_nRowCount - 1 ); - break; - - case cursorPageUp: - { - RowPos nNewRow = ::std::max( RowPos(0), m_nCurRow - impl_getVisibleRows( false ) ); - bSuccess = goTo( m_nCurColumn, nNewRow ); - } - break; - - case cursorPageDown: - { - RowPos nNewRow = ::std::min( m_nRowCount - 1, m_nCurRow + impl_getVisibleRows( false ) ); - bSuccess = goTo( m_nCurColumn, nNewRow ); - } - break; - - case cursorTopLeft: - bSuccess = goTo( 0, 0 ); - break; - - case cursorBottomRight: - bSuccess = goTo( m_nColumnCount - 1, m_nRowCount - 1 ); - break; - - case cursorSelectRow: - { - if(m_pSelEngine->GetSelectionMode() == SelectionMode::NONE) - return false; - //pos is the position of the current row in the vector of selected rows, if current row is selected - int pos = getRowSelectedNumber(m_aSelectedRows, m_nCurRow); - //if current row is selected, it should be deselected, when ALT+SPACE are pressed - if(pos>-1) - { - m_aSelectedRows.erase(m_aSelectedRows.begin()+pos); - if(m_aSelectedRows.empty() && m_nAnchor != -1) - m_nAnchor = -1; - } - //else select the row->put it in the vector - else - m_aSelectedRows.push_back(m_nCurRow); - invalidateRow( m_nCurRow ); - selectionChanged = true; - bSuccess = true; - } - break; - case cursorSelectRowUp: - { - if(m_pSelEngine->GetSelectionMode() == SelectionMode::NONE) - return false; - else if(m_pSelEngine->GetSelectionMode() == SelectionMode::Single) - { - //if there are other selected rows, deselect them - return false; - } - else - { - //there are other selected rows - if(!m_aSelectedRows.empty()) - { - //the anchor wasn't set -> a region is not selected, that's why clear all selection - //and select the current row - if(m_nAnchor==-1) - { - invalidateSelectedRows(); - m_aSelectedRows.clear(); - m_aSelectedRows.push_back(m_nCurRow); - invalidateRow( m_nCurRow ); - } - else - { - //a region is already selected, prevRow is last selected row and the row above - nextRow - should be selected - int prevRow = getRowSelectedNumber(m_aSelectedRows, m_nCurRow); - int nextRow = getRowSelectedNumber(m_aSelectedRows, m_nCurRow-1); - if(prevRow>-1) - { - //if m_nCurRow isn't the upper one, can move up, otherwise not - if(m_nCurRow>0) - m_nCurRow--; - else - return true; - //if nextRow already selected, deselect it, otherwise select it - if(nextRow>-1 && m_aSelectedRows[nextRow] == m_nCurRow) - { - m_aSelectedRows.erase(m_aSelectedRows.begin()+prevRow); - invalidateRow( m_nCurRow + 1 ); - } - else - { - m_aSelectedRows.push_back(m_nCurRow); - invalidateRow( m_nCurRow ); - } - } - else - { - if(m_nCurRow>0) - { - m_aSelectedRows.push_back(m_nCurRow); - m_nCurRow--; - m_aSelectedRows.push_back(m_nCurRow); - invalidateSelectedRegion( m_nCurRow+1, m_nCurRow ); - } - } - } - } - else - { - //if nothing is selected and the current row isn't the upper one - //select the current and one row above - //otherwise select only the upper row - if(m_nCurRow>0) - { - m_aSelectedRows.push_back(m_nCurRow); - m_nCurRow--; - m_aSelectedRows.push_back(m_nCurRow); - invalidateSelectedRegion( m_nCurRow+1, m_nCurRow ); - } - else - { - m_aSelectedRows.push_back(m_nCurRow); - invalidateRow( m_nCurRow ); - } - } - m_pSelEngine->SetAnchor(true); - m_nAnchor = m_nCurRow; - ensureVisible(m_nCurColumn, m_nCurRow); - selectionChanged = true; - bSuccess = true; - } - } - break; - case cursorSelectRowDown: - { - if(m_pSelEngine->GetSelectionMode() == SelectionMode::NONE) - bSuccess = false; - else if(m_pSelEngine->GetSelectionMode() == SelectionMode::Single) - { - bSuccess = false; - } - else - { - if(!m_aSelectedRows.empty()) - { - //the anchor wasn't set -> a region is not selected, that's why clear all selection - //and select the current row - if(m_nAnchor==-1) - { - invalidateSelectedRows(); - m_aSelectedRows.clear(); - m_aSelectedRows.push_back(m_nCurRow); - invalidateRow( m_nCurRow ); - } - else - { - //a region is already selected, prevRow is last selected row and the row beneath - nextRow - should be selected - int prevRow = getRowSelectedNumber(m_aSelectedRows, m_nCurRow); - int nextRow = getRowSelectedNumber(m_aSelectedRows, m_nCurRow+1); - if(prevRow>-1) - { - //if m_nCurRow isn't the last one, can move down, otherwise not - if(m_nCurRow<m_nRowCount-1) - m_nCurRow++; - else - return true; - //if next row already selected, deselect it, otherwise select it - if(nextRow>-1 && m_aSelectedRows[nextRow] == m_nCurRow) - { - m_aSelectedRows.erase(m_aSelectedRows.begin()+prevRow); - invalidateRow( m_nCurRow - 1 ); - } - else - { - m_aSelectedRows.push_back(m_nCurRow); - invalidateRow( m_nCurRow ); - } - } - else - { - if(m_nCurRow<m_nRowCount-1) - { - m_aSelectedRows.push_back(m_nCurRow); - m_nCurRow++; - m_aSelectedRows.push_back(m_nCurRow); - invalidateSelectedRegion( m_nCurRow-1, m_nCurRow ); - } - } - } - } - else - { - //there wasn't any selection, select current and row beneath, otherwise only row beneath - if(m_nCurRow<m_nRowCount-1) - { - m_aSelectedRows.push_back(m_nCurRow); - m_nCurRow++; - m_aSelectedRows.push_back(m_nCurRow); - invalidateSelectedRegion( m_nCurRow-1, m_nCurRow ); - } - else - { - m_aSelectedRows.push_back(m_nCurRow); - invalidateRow( m_nCurRow ); - } - } - m_pSelEngine->SetAnchor(true); - m_nAnchor = m_nCurRow; - ensureVisible(m_nCurColumn, m_nCurRow); - selectionChanged = true; - bSuccess = true; - } - } - break; - - case cursorSelectRowAreaTop: - { - if(m_pSelEngine->GetSelectionMode() == SelectionMode::NONE) - bSuccess = false; - else if(m_pSelEngine->GetSelectionMode() == SelectionMode::Single) - bSuccess = false; - else - { - //select the region between the current and the upper row - RowPos iter = m_nCurRow; - invalidateSelectedRegion( m_nCurRow, 0 ); - //put the rows in vector - while(iter>=0) - { - if ( !isRowSelected( iter ) ) - m_aSelectedRows.push_back(iter); - --iter; - } - m_nCurRow = 0; - m_nAnchor = m_nCurRow; - m_pSelEngine->SetAnchor(true); - ensureVisible(m_nCurColumn, 0); - selectionChanged = true; - bSuccess = true; - } - } - break; - - case cursorSelectRowAreaBottom: - { - if(m_pSelEngine->GetSelectionMode() == SelectionMode::NONE) - return false; - else if(m_pSelEngine->GetSelectionMode() == SelectionMode::Single) - return false; - //select the region between the current and the last row - RowPos iter = m_nCurRow; - invalidateSelectedRegion( m_nCurRow, m_nRowCount-1 ); - //put the rows in the vector - while(iter<=m_nRowCount) - { - if ( !isRowSelected( iter ) ) - m_aSelectedRows.push_back(iter); - ++iter; - } - m_nCurRow = m_nRowCount-1; - m_nAnchor = m_nCurRow; - m_pSelEngine->SetAnchor(true); - ensureVisible(m_nCurColumn, m_nRowCount-1); - selectionChanged = true; - bSuccess = true; - } - break; - default: - OSL_FAIL( "TableControl_Impl::dispatchAction: unsupported action!" ); - break; - } - - if ( bSuccess && selectionChanged ) - { - m_rAntiImpl.Select(); - } - - return bSuccess; - } - - - void TableControl_Impl::impl_ni_doSwitchCursor( bool _bShow ) - { - PTableRenderer pRenderer = m_pModel ? m_pModel->getRenderer() : PTableRenderer(); - if ( pRenderer ) - { - tools::Rectangle aCellRect; - impl_getCellRect( m_nCurColumn, m_nCurRow, aCellRect ); - if ( _bShow ) - pRenderer->ShowCellCursor( *m_pDataWindow, aCellRect ); - else - pRenderer->HideCellCursor( *m_pDataWindow ); - } - } - - - void TableControl_Impl::impl_getCellRect( ColPos _nColumn, RowPos _nRow, tools::Rectangle& _rCellRect ) const - { - if ( !m_pModel - || ( COL_INVALID == _nColumn ) - || ( ROW_INVALID == _nRow ) - ) - { - _rCellRect.SetEmpty(); - return; - } - - TableCellGeometry aCell( *this, impl_getAllVisibleCellsArea(), _nColumn, _nRow ); - _rCellRect = aCell.getRect(); - } - - - RowPos TableControl_Impl::getRowAtPoint( const Point& rPoint ) const - { - return impl_getRowForAbscissa( rPoint.Y() ); - } - - - ColPos TableControl_Impl::getColAtPoint( const Point& rPoint ) const - { - return impl_getColumnForOrdinate( rPoint.X() ); - } - - - TableCell TableControl_Impl::hitTest( Point const & i_point ) const - { - TableCell aCell( getColAtPoint( i_point ), getRowAtPoint( i_point ) ); - if ( aCell.nColumn > COL_ROW_HEADERS ) - { - PColumnModel const pColumn = m_pModel->getColumnModel( aCell.nColumn ); - MutableColumnMetrics const & rColInfo( m_aColumnWidths[ aCell.nColumn ] ); - if ( ( rColInfo.getEnd() - 3 <= i_point.X() ) - && ( rColInfo.getEnd() >= i_point.X() ) - && pColumn->isResizable() - ) - { - aCell.eArea = ColumnDivider; - } - } - return aCell; - } - - - ColumnMetrics TableControl_Impl::getColumnMetrics( ColPos const i_column ) const - { - ENSURE_OR_RETURN( ( i_column >= 0 ) && ( i_column < m_pModel->getColumnCount() ), - "TableControl_Impl::getColumnMetrics: illegal column index!", ColumnMetrics() ); - return m_aColumnWidths[ i_column ]; - } - - - PTableModel TableControl_Impl::getModel() const - { - return m_pModel; - } - - - ColPos TableControl_Impl::getCurrentColumn() const - { - return m_nCurColumn; - } - - - RowPos TableControl_Impl::getCurrentRow() const - { - return m_nCurRow; - } - - - ::Size TableControl_Impl::getTableSizePixel() const - { - return m_pDataWindow->GetOutputSizePixel(); - } - - - void TableControl_Impl::setPointer( PointerStyle i_pointer ) - { - m_pDataWindow->SetPointer( i_pointer ); - } - - - void TableControl_Impl::captureMouse() - { - m_pDataWindow->CaptureMouse(); - } - - - void TableControl_Impl::releaseMouse() - { - m_pDataWindow->ReleaseMouse(); - } - - - void TableControl_Impl::invalidate( TableArea const i_what ) - { - switch ( i_what ) - { - case TableArea::ColumnHeaders: - m_pDataWindow->Invalidate( calcHeaderRect( true ) ); - break; - - case TableArea::RowHeaders: - m_pDataWindow->Invalidate( calcHeaderRect( false ) ); - break; - - case TableArea::All: - m_pDataWindow->Invalidate(); - m_pDataWindow->GetParent()->Invalidate( InvalidateFlags::Transparent ); - break; - } - } - - - tools::Long TableControl_Impl::pixelWidthToAppFont( tools::Long const i_pixels ) const - { - return m_pDataWindow->PixelToLogic(Size(i_pixels, 0), MapMode(MapUnit::MapAppFont)).Width(); - } - - - tools::Long TableControl_Impl::appFontWidthToPixel( tools::Long const i_appFontUnits ) const - { - return m_pDataWindow->LogicToPixel(Size(i_appFontUnits, 0), MapMode(MapUnit::MapAppFont)).Width(); - } - - - void TableControl_Impl::hideTracking() - { - m_pDataWindow->HideTracking(); - } - - - void TableControl_Impl::showTracking( tools::Rectangle const & i_location, ShowTrackFlags const i_flags ) - { - m_pDataWindow->ShowTracking( i_location, i_flags ); - } - - - void TableControl_Impl::activateCell( ColPos const i_col, RowPos const i_row ) - { - goTo( i_col, i_row ); - } - - - void TableControl_Impl::invalidateSelectedRegion( RowPos _nPrevRow, RowPos _nCurRow ) - { - // get the visible area of the table control and set the Left and right border of the region to be repainted - tools::Rectangle const aAllCells( impl_getAllVisibleCellsArea() ); - - tools::Rectangle aInvalidateRect; - aInvalidateRect.SetLeft( aAllCells.Left() ); - aInvalidateRect.SetRight( aAllCells.Right() ); - // if only one row is selected - if ( _nPrevRow == _nCurRow ) - { - tools::Rectangle aCellRect; - impl_getCellRect( m_nCurColumn, _nCurRow, aCellRect ); - aInvalidateRect.SetTop( aCellRect.Top() ); - aInvalidateRect.SetBottom( aCellRect.Bottom() ); - } - //if the region is above the current row - else if(_nPrevRow < _nCurRow ) - { - tools::Rectangle aCellRect; - impl_getCellRect( m_nCurColumn, _nPrevRow, aCellRect ); - aInvalidateRect.SetTop( aCellRect.Top() ); - impl_getCellRect( m_nCurColumn, _nCurRow, aCellRect ); - aInvalidateRect.SetBottom( aCellRect.Bottom() ); - } - //if the region is beneath the current row - else - { - tools::Rectangle aCellRect; - impl_getCellRect( m_nCurColumn, _nCurRow, aCellRect ); - aInvalidateRect.SetTop( aCellRect.Top() ); - impl_getCellRect( m_nCurColumn, _nPrevRow, aCellRect ); - aInvalidateRect.SetBottom( aCellRect.Bottom() ); - } - - invalidateRect(aInvalidateRect); - } - - void TableControl_Impl::invalidateRect(const tools::Rectangle &rInvalidateRect) - { - m_pDataWindow->Invalidate( rInvalidateRect, - m_pDataWindow->GetControlBackground().IsTransparent() ? InvalidateFlags::Transparent : InvalidateFlags::NONE ); - } - - - void TableControl_Impl::invalidateSelectedRows() - { - for (auto const& selectedRow : m_aSelectedRows) - { - invalidateRow(selectedRow); - } - } - - - void TableControl_Impl::invalidateRowRange( RowPos const i_firstRow, RowPos const i_lastRow ) - { - RowPos const firstRow = i_firstRow < m_nTopRow ? m_nTopRow : i_firstRow; - RowPos const lastVisibleRow = m_nTopRow + impl_getVisibleRows( true ) - 1; - RowPos const lastRow = ( ( i_lastRow == ROW_INVALID ) || ( i_lastRow > lastVisibleRow ) ) ? lastVisibleRow : i_lastRow; - - tools::Rectangle aInvalidateRect; - - tools::Rectangle const aVisibleCellsArea( impl_getAllVisibleCellsArea() ); - TableRowGeometry aRow( *this, aVisibleCellsArea, firstRow, true ); - while ( aRow.isValid() && ( aRow.getRow() <= lastRow ) ) - { - aInvalidateRect.Union( aRow.getRect() ); - aRow.moveDown(); - } - - if ( i_lastRow == ROW_INVALID ) - aInvalidateRect.SetBottom( m_pDataWindow->GetOutputSizePixel().Height() ); - - invalidateRect(aInvalidateRect); - } - - - void TableControl_Impl::checkCursorPosition() - { - - TableSize nVisibleRows = impl_getVisibleRows(true); - TableSize nVisibleCols = impl_getVisibleColumns(true); - if ( ( m_nTopRow + nVisibleRows > m_nRowCount ) - && ( m_nRowCount >= nVisibleRows ) - ) - { - --m_nTopRow; - } - else - { - m_nTopRow = 0; - } - - if ( ( m_nLeftColumn + nVisibleCols > m_nColumnCount ) - && ( m_nColumnCount >= nVisibleCols ) - ) - { - --m_nLeftColumn; - } - else - { - m_nLeftColumn = 0; - } - - m_pDataWindow->Invalidate(); - } - - - TableSize TableControl_Impl::impl_getVisibleRows( bool _bAcceptPartialRow ) const - { - DBG_ASSERT( m_pDataWindow, "TableControl_Impl::impl_getVisibleRows: no data window!" ); - - return lcl_getRowsFittingInto( - m_pDataWindow->GetOutputSizePixel().Height() - m_nColHeaderHeightPixel, - m_nRowHeightPixel, - _bAcceptPartialRow - ); - } - - - TableSize TableControl_Impl::impl_getVisibleColumns( bool _bAcceptPartialCol ) const - { - DBG_ASSERT( m_pDataWindow, "TableControl_Impl::impl_getVisibleColumns: no data window!" ); - - return lcl_getColumnsVisibleWithin( - tools::Rectangle( Point( 0, 0 ), m_pDataWindow->GetOutputSizePixel() ), - m_nLeftColumn, - *this, - _bAcceptPartialCol - ); - } - - - bool TableControl_Impl::goTo( ColPos _nColumn, RowPos _nRow ) - { - // TODO: give veto listeners a chance - - if ( ( _nColumn < 0 ) || ( _nColumn >= m_nColumnCount ) - || ( _nRow < 0 ) || ( _nRow >= m_nRowCount ) - ) - { - OSL_ENSURE( false, "TableControl_Impl::goTo: invalid row or column index!" ); - return false; - } - - SuppressCursor aHideCursor( *this ); - m_nCurColumn = _nColumn; - m_nCurRow = _nRow; - - // ensure that the new cell is visible - ensureVisible( m_nCurColumn, m_nCurRow ); - return true; - } - - - void TableControl_Impl::ensureVisible( ColPos _nColumn, RowPos _nRow ) - { - DBG_ASSERT( ( _nColumn >= 0 ) && ( _nColumn < m_nColumnCount ) - && ( _nRow >= 0 ) && ( _nRow < m_nRowCount ), - "TableControl_Impl::ensureVisible: invalid coordinates!" ); - - SuppressCursor aHideCursor( *this ); - - if ( _nColumn < m_nLeftColumn ) - impl_scrollColumns( _nColumn - m_nLeftColumn ); - else - { - TableSize nVisibleColumns = impl_getVisibleColumns( false/*bAcceptPartialVisibility*/ ); - if ( _nColumn > m_nLeftColumn + nVisibleColumns - 1 ) - { - impl_scrollColumns( _nColumn - ( m_nLeftColumn + nVisibleColumns - 1 ) ); - // TODO: since not all columns have the same width, this might in theory result - // in the column still not being visible. - } - } - - if ( _nRow < m_nTopRow ) - impl_scrollRows( _nRow - m_nTopRow ); - else - { - TableSize nVisibleRows = impl_getVisibleRows( false/*_bAcceptPartialVisibility*/ ); - if ( _nRow > m_nTopRow + nVisibleRows - 1 ) - impl_scrollRows( _nRow - ( m_nTopRow + nVisibleRows - 1 ) ); - } - } - - - OUString TableControl_Impl::getCellContentAsString( RowPos const i_row, ColPos const i_col ) - { - Any aCellValue; - m_pModel->getCellContent( i_col, i_row, aCellValue ); - - OUString sCellStringContent; - m_pModel->getRenderer()->GetFormattedCellString( aCellValue, sCellStringContent ); - - return sCellStringContent; - } - - - TableSize TableControl_Impl::impl_ni_ScrollRows( TableSize _nRowDelta ) - { - // compute new top row - RowPos nNewTopRow = - ::std::max( - ::std::min( static_cast<RowPos>( m_nTopRow + _nRowDelta ), static_cast<RowPos>( m_nRowCount - 1 ) ), - RowPos(0) - ); - - RowPos nOldTopRow = m_nTopRow; - m_nTopRow = nNewTopRow; - - // if updates are enabled currently, scroll the viewport - if ( m_nTopRow != nOldTopRow ) - { - SuppressCursor aHideCursor( *this ); - // TODO: call an onStartScroll at our listener (or better an own onStartScroll, - // which hides the cursor and then calls the listener) - // Same for onEndScroll - - // scroll the view port, if possible - tools::Long nPixelDelta = m_nRowHeightPixel * ( m_nTopRow - nOldTopRow ); - - tools::Rectangle aDataArea( Point( 0, m_nColHeaderHeightPixel ), m_pDataWindow->GetOutputSizePixel() ); - - if ( m_pDataWindow->GetBackground().IsScrollable() - && std::abs( nPixelDelta ) < aDataArea.GetHeight() - ) - { - m_pDataWindow->Scroll( 0, static_cast<tools::Long>(-nPixelDelta), aDataArea, ScrollFlags::Clip | ScrollFlags::Update | ScrollFlags::Children); - } - else - { - m_pDataWindow->Invalidate( InvalidateFlags::Update ); - m_pDataWindow->GetParent()->Invalidate( InvalidateFlags::Transparent ); - } - - // update the position at the vertical scrollbar - if ( m_pVScroll != nullptr ) - m_pVScroll->SetThumbPos( m_nTopRow ); - } - - // The scroll bar availability might change when we scrolled. - // For instance, imagine a view with 10 rows, if which 5 fit into the window, numbered 1 to 10. - // Now let - // - the user scroll to row number 6, so the last 5 rows are visible - // - somebody remove the last 4 rows - // - the user scroll to row number 5 being the top row, so the last two rows are visible - // - somebody remove row number 6 - // - the user scroll to row number 1 - // => in this case, the need for the scrollbar vanishes immediately. - if ( m_nTopRow == 0 ) - m_rAntiImpl.PostUserEvent( LINK( this, TableControl_Impl, OnUpdateScrollbars ) ); - - return static_cast<TableSize>( m_nTopRow - nOldTopRow ); - } - - - TableSize TableControl_Impl::impl_scrollRows( TableSize const i_rowDelta ) - { - return impl_ni_ScrollRows( i_rowDelta ); - } - - - TableSize TableControl_Impl::impl_ni_ScrollColumns( TableSize _nColumnDelta ) - { - // compute new left column - const ColPos nNewLeftColumn = - ::std::max( - ::std::min( static_cast<ColPos>( m_nLeftColumn + _nColumnDelta ), static_cast<ColPos>( m_nColumnCount - 1 ) ), - ColPos(0) - ); - - const ColPos nOldLeftColumn = m_nLeftColumn; - m_nLeftColumn = nNewLeftColumn; - - // if updates are enabled currently, scroll the viewport - if ( m_nLeftColumn != nOldLeftColumn ) - { - SuppressCursor aHideCursor( *this ); - // TODO: call an onStartScroll at our listener (or better an own onStartScroll, - // which hides the cursor and then calls the listener) - // Same for onEndScroll - - // scroll the view port, if possible - const tools::Rectangle aDataArea( Point( m_nRowHeaderWidthPixel, 0 ), m_pDataWindow->GetOutputSizePixel() ); - - tools::Long nPixelDelta = - m_aColumnWidths[ nOldLeftColumn ].getStart() - - m_aColumnWidths[ m_nLeftColumn ].getStart(); - - // update our column positions - // Do this *before* scrolling, as ScrollFlags::Update will trigger a paint, which already needs the correct - // information in m_aColumnWidths - for (auto & columnWidth : m_aColumnWidths) - { - columnWidth.move(nPixelDelta); - } - - // scroll the window content (if supported and possible), or invalidate the complete window - if ( m_pDataWindow->GetBackground().IsScrollable() - && std::abs( nPixelDelta ) < aDataArea.GetWidth() - ) - { - m_pDataWindow->Scroll( nPixelDelta, 0, aDataArea, ScrollFlags::Clip | ScrollFlags::Update ); - } - else - { - m_pDataWindow->Invalidate( InvalidateFlags::Update ); - m_pDataWindow->GetParent()->Invalidate( InvalidateFlags::Transparent ); - } - - // update the position at the horizontal scrollbar - if ( m_pHScroll != nullptr ) - m_pHScroll->SetThumbPos( m_nLeftColumn ); - } - - // The scroll bar availability might change when we scrolled. This is because we do not hide - // the scrollbar when it is, in theory, unnecessary, but currently at a position > 0. In this case, it will - // be auto-hidden when it's scrolled back to pos 0. - if ( m_nLeftColumn == 0 ) - m_rAntiImpl.PostUserEvent( LINK( this, TableControl_Impl, OnUpdateScrollbars ) ); - - return static_cast<TableSize>( m_nLeftColumn - nOldLeftColumn ); - } - - - TableSize TableControl_Impl::impl_scrollColumns( TableSize const i_columnDelta ) - { - return impl_ni_ScrollColumns( i_columnDelta ); - } - - - SelectionEngine* TableControl_Impl::getSelEngine() - { - return m_pSelEngine.get(); - } - - bool TableControl_Impl::isRowSelected( RowPos i_row ) const - { - return ::std::find( m_aSelectedRows.begin(), m_aSelectedRows.end(), i_row ) != m_aSelectedRows.end(); - } - - - RowPos TableControl_Impl::getSelectedRowIndex( size_t const i_selectionIndex ) const - { - if ( i_selectionIndex < m_aSelectedRows.size() ) - return m_aSelectedRows[ i_selectionIndex ]; - return ROW_INVALID; - } - - - int TableControl_Impl::getRowSelectedNumber(const ::std::vector<RowPos>& selectedRows, RowPos current) - { - std::vector<RowPos>::const_iterator it = ::std::find(selectedRows.begin(),selectedRows.end(),current); - if ( it != selectedRows.end() ) - { - return it - selectedRows.begin(); - } - return -1; - } - - - ColPos TableControl_Impl::impl_getColumnForOrdinate( tools::Long const i_ordinate ) const - { - if ( ( m_aColumnWidths.empty() ) || ( i_ordinate < 0 ) ) - return COL_INVALID; - - if ( i_ordinate < m_nRowHeaderWidthPixel ) - return COL_ROW_HEADERS; - - ColumnPositions::const_iterator lowerBound = ::std::lower_bound( - m_aColumnWidths.begin(), - m_aColumnWidths.end(), - MutableColumnMetrics(i_ordinate+1, i_ordinate+1), - ColumnInfoPositionLess() - ); - if ( lowerBound == m_aColumnWidths.end() ) - { - // point is *behind* the start of the last column ... - if ( i_ordinate < m_aColumnWidths.rbegin()->getEnd() ) - // ... but still before its end - return m_nColumnCount - 1; - return COL_INVALID; - } - return lowerBound - m_aColumnWidths.begin(); - } - - - RowPos TableControl_Impl::impl_getRowForAbscissa( tools::Long const i_abscissa ) const - { - if ( i_abscissa < 0 ) - return ROW_INVALID; - - if ( i_abscissa < m_nColHeaderHeightPixel ) - return ROW_COL_HEADERS; - - tools::Long const abscissa = i_abscissa - m_nColHeaderHeightPixel; - tools::Long const row = m_nTopRow + abscissa / m_nRowHeightPixel; - return row < m_pModel->getRowCount() ? row : ROW_INVALID; - } - - - bool TableControl_Impl::markRowAsDeselected( RowPos const i_rowIndex ) - { - ::std::vector< RowPos >::iterator selPos = ::std::find( m_aSelectedRows.begin(), m_aSelectedRows.end(), i_rowIndex ); - if ( selPos == m_aSelectedRows.end() ) - return false; - - m_aSelectedRows.erase( selPos ); - return true; - } - - - bool TableControl_Impl::markRowAsSelected( RowPos const i_rowIndex ) - { - if ( isRowSelected( i_rowIndex ) ) - return false; - - SelectionMode const eSelMode = getSelEngine()->GetSelectionMode(); - switch ( eSelMode ) - { - case SelectionMode::Single: - if ( !m_aSelectedRows.empty() ) - { - OSL_ENSURE( m_aSelectedRows.size() == 1, "TableControl::markRowAsSelected: SingleSelection with more than one selected element?" ); - m_aSelectedRows[0] = i_rowIndex; - break; - } - [[fallthrough]]; - - case SelectionMode::Multiple: - m_aSelectedRows.push_back( i_rowIndex ); - break; - - default: - OSL_ENSURE( false, "TableControl_Impl::markRowAsSelected: unsupported selection mode!" ); - return false; - } - - return true; - } - - - bool TableControl_Impl::markAllRowsAsDeselected() - { - if ( m_aSelectedRows.empty() ) - return false; - - m_aSelectedRows.clear(); - return true; - } - - - bool TableControl_Impl::markAllRowsAsSelected() - { - SelectionMode const eSelMode = getSelEngine()->GetSelectionMode(); - ENSURE_OR_RETURN_FALSE( eSelMode == SelectionMode::Multiple, "TableControl_Impl::markAllRowsAsSelected: unsupported selection mode!" ); - - if ( m_aSelectedRows.size() == size_t( m_pModel->getRowCount() ) ) - { - #if OSL_DEBUG_LEVEL > 0 - for ( TableSize row = 0; row < m_pModel->getRowCount(); ++row ) - { - OSL_ENSURE( isRowSelected( row ), "TableControl_Impl::markAllRowsAsSelected: inconsistency in the selected rows!" ); - } - #endif - // already all rows marked as selected - return false; - } - - m_aSelectedRows.clear(); - for ( RowPos i=0; i < m_pModel->getRowCount(); ++i ) - m_aSelectedRows.push_back(i); - - return true; - } - - - void TableControl_Impl::commitAccessibleEvent( sal_Int16 const i_eventID ) - { - impl_commitAccessibleEvent( i_eventID, Any() ); - } - - - void TableControl_Impl::commitCellEvent( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue ) - { - if ( impl_isAccessibleAlive() ) - m_pAccessibleTable->commitCellEvent( i_eventID, i_newValue, i_oldValue ); - } - - - void TableControl_Impl::commitTableEvent( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue ) - { - if ( impl_isAccessibleAlive() ) - m_pAccessibleTable->commitTableEvent( i_eventID, i_newValue, i_oldValue ); - } - - - tools::Rectangle TableControl_Impl::calcHeaderRect(bool bColHeader) - { - tools::Rectangle const aRectTableWithHeaders( impl_getAllVisibleCellsArea() ); - Size const aSizeTableWithHeaders( aRectTableWithHeaders.GetSize() ); - if ( bColHeader ) - return tools::Rectangle( aRectTableWithHeaders.TopLeft(), Size( aSizeTableWithHeaders.Width(), m_nColHeaderHeightPixel ) ); - else - return tools::Rectangle( aRectTableWithHeaders.TopLeft(), Size( m_nRowHeaderWidthPixel, aSizeTableWithHeaders.Height() ) ); - } - - - tools::Rectangle TableControl_Impl::calcHeaderCellRect( bool bColHeader, sal_Int32 nPos ) - { - tools::Rectangle const aHeaderRect = calcHeaderRect( bColHeader ); - TableCellGeometry const aGeometry( - *this, aHeaderRect, - bColHeader ? nPos : COL_ROW_HEADERS, - bColHeader ? ROW_COL_HEADERS : nPos - ); - return aGeometry.getRect(); - } - - - tools::Rectangle TableControl_Impl::calcTableRect() const - { - return impl_getAllVisibleDataCellArea(); - } - - - tools::Rectangle TableControl_Impl::calcCellRect( sal_Int32 nRow, sal_Int32 nCol ) const - { - tools::Rectangle aCellRect; - impl_getCellRect( nRow, nCol, aCellRect ); - return aCellRect; - } - - - IMPL_LINK_NOARG( TableControl_Impl, OnUpdateScrollbars, void*, void ) - { - // TODO: can't we simply use lcl_updateScrollbar here, so the scrollbars ranges are updated, instead of - // doing a complete re-layout? - impl_ni_relayout(); - } - - - IMPL_LINK( TableControl_Impl, OnScroll, ScrollBar*, _pScrollbar, void ) - { - DBG_ASSERT( ( _pScrollbar == m_pVScroll ) || ( _pScrollbar == m_pHScroll ), - "TableControl_Impl::OnScroll: where did this come from?" ); - - if ( _pScrollbar == m_pVScroll ) - impl_ni_ScrollRows( _pScrollbar->GetDelta() ); - else - impl_ni_ScrollColumns( _pScrollbar->GetDelta() ); - } - - - Reference< XAccessible > TableControl_Impl::getAccessible( vcl::Window& i_parentWindow ) - { - DBG_TESTSOLARMUTEX(); - if ( m_pAccessibleTable == nullptr ) - { - Reference< XAccessible > const xAccParent = i_parentWindow.GetAccessible(); - if ( xAccParent.is() ) - { - m_pAccessibleTable = m_aFactoryAccess.getFactory().createAccessibleTableControl( - xAccParent, m_rAntiImpl - ); - } - } - - Reference< XAccessible > xAccessible; - if ( m_pAccessibleTable ) - xAccessible = m_pAccessibleTable->getMyself(); - return xAccessible; - } - - - void TableControl_Impl::disposeAccessible() - { - if ( m_pAccessibleTable ) - m_pAccessibleTable->DisposeAccessImpl(); - m_pAccessibleTable = nullptr; - } - - - bool TableControl_Impl::impl_isAccessibleAlive() const - { - return ( nullptr != m_pAccessibleTable ) && m_pAccessibleTable->isAlive(); - } - - - void TableControl_Impl::impl_commitAccessibleEvent( sal_Int16 const i_eventID, Any const & i_newValue ) - { - if ( impl_isAccessibleAlive() ) - m_pAccessibleTable->commitEvent( i_eventID, i_newValue ); - } - - - //= TableFunctionSet - - - TableFunctionSet::TableFunctionSet(TableControl_Impl* _pTableControl) - :m_pTableControl( _pTableControl) - ,m_nCurrentRow( ROW_INVALID ) - { - } - - TableFunctionSet::~TableFunctionSet() - { - } - - void TableFunctionSet::BeginDrag() - { - } - - void TableFunctionSet::CreateAnchor() - { - m_pTableControl->setAnchor( m_pTableControl->getCurRow() ); - } - - - void TableFunctionSet::DestroyAnchor() - { - m_pTableControl->setAnchor( ROW_INVALID ); - } - - - void TableFunctionSet::SetCursorAtPoint(const Point& rPoint, bool bDontSelectAtCursor) - { - // newRow is the row which includes the point, getCurRow() is the last selected row, before the mouse click - RowPos newRow = m_pTableControl->getRowAtPoint( rPoint ); - if ( newRow == ROW_COL_HEADERS ) - newRow = m_pTableControl->getTopRow(); - - ColPos newCol = m_pTableControl->getColAtPoint( rPoint ); - if ( newCol == COL_ROW_HEADERS ) - newCol = m_pTableControl->getLeftColumn(); - - if ( ( newRow == ROW_INVALID ) || ( newCol == COL_INVALID ) ) - return; - - if ( bDontSelectAtCursor ) - { - if ( m_pTableControl->getSelectedRowCount() > 1 ) - m_pTableControl->getSelEngine()->AddAlways(true); - } - else if ( m_pTableControl->getAnchor() == m_pTableControl->getCurRow() ) - { - //selected region lies above the last selection - if( m_pTableControl->getCurRow() >= newRow) - { - //put selected rows in vector - while ( m_pTableControl->getAnchor() >= newRow ) - { - m_pTableControl->markRowAsSelected( m_pTableControl->getAnchor() ); - m_pTableControl->setAnchor( m_pTableControl->getAnchor() - 1 ); - } - m_pTableControl->setAnchor( m_pTableControl->getAnchor() + 1 ); - } - //selected region lies beneath the last selected row - else - { - while ( m_pTableControl->getAnchor() <= newRow ) - { - m_pTableControl->markRowAsSelected( m_pTableControl->getAnchor() ); - m_pTableControl->setAnchor( m_pTableControl->getAnchor() + 1 ); - } - m_pTableControl->setAnchor( m_pTableControl->getAnchor() - 1 ); - } - m_pTableControl->invalidateSelectedRegion( m_pTableControl->getCurRow(), newRow ); - } - //no region selected - else - { - if ( !m_pTableControl->hasRowSelection() ) - m_pTableControl->markRowAsSelected( newRow ); - else - { - if ( m_pTableControl->getSelEngine()->GetSelectionMode() == SelectionMode::Single ) - { - DeselectAll(); - m_pTableControl->markRowAsSelected( newRow ); - } - else - { - m_pTableControl->markRowAsSelected( newRow ); - } - } - if ( m_pTableControl->getSelectedRowCount() > 1 && m_pTableControl->getSelEngine()->GetSelectionMode() != SelectionMode::Single ) - m_pTableControl->getSelEngine()->AddAlways(true); - - m_pTableControl->invalidateRow( newRow ); - } - m_pTableControl->goTo( newCol, newRow ); - } - - bool TableFunctionSet::IsSelectionAtPoint( const Point& rPoint ) - { - m_pTableControl->getSelEngine()->AddAlways(false); - if ( !m_pTableControl->hasRowSelection() ) - return false; - else - { - RowPos curRow = m_pTableControl->getRowAtPoint( rPoint ); - m_pTableControl->setAnchor( ROW_INVALID ); - bool selected = m_pTableControl->isRowSelected( curRow ); - m_nCurrentRow = curRow; - return selected; - } - } - - void TableFunctionSet::DeselectAtPoint( const Point& ) - { - m_pTableControl->invalidateRow( m_nCurrentRow ); - m_pTableControl->markRowAsDeselected( m_nCurrentRow ); - } - - - void TableFunctionSet::DeselectAll() - { - if ( m_pTableControl->hasRowSelection() ) - { - for ( size_t i=0; i<m_pTableControl->getSelectedRowCount(); ++i ) - { - RowPos const rowIndex = m_pTableControl->getSelectedRowIndex(i); - m_pTableControl->invalidateRow( rowIndex ); - } - - m_pTableControl->markAllRowsAsDeselected(); - } - } - - -} // namespace svt::table - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/table/tablecontrol_impl.hxx b/svtools/source/table/tablecontrol_impl.hxx deleted file mode 100644 index 727dea92ba94..000000000000 --- a/svtools/source/table/tablecontrol_impl.hxx +++ /dev/null @@ -1,479 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <table/tablemodel.hxx> -#include <table/tablecontrolinterface.hxx> - -#include <vcl/svtaccessiblefactory.hxx> -#include <vcl/accessibletable.hxx> - -#include <vcl/seleng.hxx> - -#include <vector> - -class ScrollBar; -class ScrollBarBox; - -namespace svt::table -{ - struct MutableColumnMetrics : public ColumnMetrics - { - MutableColumnMetrics() - :ColumnMetrics() - { - } - - MutableColumnMetrics( tools::Long const i_startPixel, tools::Long const i_endPixel ) - :ColumnMetrics( i_startPixel, i_endPixel ) - { - } - - tools::Long getStart() const { return nStartPixel; } - tools::Long getEnd() const { return nEndPixel; } - - void move( tools::Long const i_offset ) { nStartPixel += i_offset; nEndPixel += i_offset; } - - tools::Long getWidth() const { return nEndPixel - nStartPixel; } - }; - - struct ColumnInfoPositionLess - { - bool operator()( MutableColumnMetrics const& i_lhs, MutableColumnMetrics const& i_rhs ) - { - return i_lhs.getEnd() < i_rhs.getStart(); - } - }; - - typedef ::std::vector< MutableColumnMetrics > ColumnPositions; - - class TableControl; - class TableDataWindow; - class TableFunctionSet; - - - //= TableControl_Impl - - class TableControl_Impl :public ITableControl - ,public ITableModelListener - { - friend class TableGeometry; - friend class TableRowGeometry; - friend class TableColumnGeometry; - friend class SuspendInvariants; - - private: - /// the control whose impl-instance we implement - TableControl& m_rAntiImpl; - /// the model of the table control - PTableModel m_pModel; - /// the input handler to use, usually the input handler as provided by ->m_pModel - PTableInputHandler m_pInputHandler; - /// info about the widths of our columns - ColumnPositions m_aColumnWidths; - - /// the height of a single row in the table, measured in pixels - tools::Long m_nRowHeightPixel; - /// the height of the column header row in the table, measured in pixels - tools::Long m_nColHeaderHeightPixel; - /// the width of the row header column in the table, measured in pixels - tools::Long m_nRowHeaderWidthPixel; - - /// the number of columns in the table control. Cached model value. - TableSize m_nColumnCount; - - /// the number of rows in the table control. Cached model value. - TableSize m_nRowCount; - - ColPos m_nCurColumn; - RowPos m_nCurRow; - ColPos m_nLeftColumn; - RowPos m_nTopRow; - - sal_Int32 m_nCursorHidden; - - /** the window to contain all data content, including header bars - - The window's upper left corner is at position (0,0), relative to the - table control, which is the direct parent of the data window. - */ - VclPtr<TableDataWindow> m_pDataWindow; - /// the vertical scrollbar, if any - VclPtr<ScrollBar> m_pVScroll; - /// the horizontal scrollbar, if any - VclPtr<ScrollBar> m_pHScroll; - VclPtr<ScrollBarBox> m_pScrollCorner; - //selection engine - for determining selection range, e.g. single, multiple - std::unique_ptr<SelectionEngine> m_pSelEngine; - //vector which contains the selected rows - std::vector<RowPos> m_aSelectedRows; - //part of selection engine - std::unique_ptr<TableFunctionSet> m_pTableFunctionSet; - //part of selection engine - RowPos m_nAnchor; - bool m_bUpdatingColWidths; - - vcl::AccessibleFactoryAccess m_aFactoryAccess; - vcl::table::IAccessibleTableControl* m_pAccessibleTable; - - public: - void setModel( const PTableModel& _pModel ); - - const PTableInputHandler& getInputHandler() const { return m_pInputHandler; } - - RowPos getCurRow() const { return m_nCurRow; } - - RowPos getAnchor() const { return m_nAnchor; } - void setAnchor( RowPos const i_anchor ) { m_nAnchor = i_anchor; } - - RowPos getTopRow() const { return m_nTopRow; } - ColPos getLeftColumn() const { return m_nLeftColumn; } - - const TableControl& getAntiImpl() const { return m_rAntiImpl; } - TableControl& getAntiImpl() { return m_rAntiImpl; } - - public: - explicit TableControl_Impl( TableControl& _rAntiImpl ); - virtual ~TableControl_Impl() override; - - /** to be called when the anti-impl instance has been resized - */ - void onResize(); - - /** paints the table control content which intersects with the given rectangle - */ - void doPaintContent(vcl::RenderContext& rRenderContext, const tools::Rectangle& _rUpdateRect); - - /** moves the cursor to the cell with the given coordinates - - To ease the caller's code, the coordinates must not necessarily denote a - valid position. If they don't, <FALSE/> will be returned. - */ - bool goTo( ColPos _nColumn, RowPos _nRow ); - - /** ensures that the given coordinate is visible - @param _nColumn - the column position which should be visible. Must be non-negative, and smaller - than the column count. - @param _nRow - the row position which should be visibleMust be non-negative, and smaller - than the row count. - */ - void ensureVisible( ColPos _nColumn, RowPos _nRow ); - - /** retrieves the content of the given cell, converted to a string - */ - OUString getCellContentAsString( RowPos const i_row, ColPos const i_col ); - - /** returns the position of the current row in the selection vector */ - static int getRowSelectedNumber(const ::std::vector<RowPos>& selectedRows, RowPos current); - - void invalidateRect(const tools::Rectangle &rInvalidateRect); - - /** ??? */ - void invalidateSelectedRegion( RowPos _nPrevRow, RowPos _nCurRow ); - - /** invalidates the part of the data window which is covered by the given rows - @param i_firstRow - the index of the first row to include in the invalidation - @param i_lastRow - the index of the last row to include in the invalidation, or ROW_INVALID if the invalidation - should happen down to the bottom of the data window. - */ - void invalidateRowRange( RowPos const i_firstRow, RowPos const i_lastRow ); - - /** invalidates the part of the data window which is covered by the given row - */ - void invalidateRow( RowPos const i_row ) { invalidateRowRange( i_row, i_row ); } - - /** invalidates all selected rows - */ - void invalidateSelectedRows(); - - void checkCursorPosition(); - - bool hasRowSelection() const { return !m_aSelectedRows.empty(); } - size_t getSelectedRowCount() const { return m_aSelectedRows.size(); } - RowPos getSelectedRowIndex( size_t const i_selectionIndex ) const; - - /** removes the given row index from m_aSelectedRows - - @return - <TRUE/> if and only if the row was previously marked as selected - */ - bool markRowAsDeselected( RowPos const i_rowIndex ); - - /** marks the given row as selected, by putting it into m_aSelectedRows - @return - <TRUE/> if and only if the row was previously <em>not</em> marked as selected - */ - bool markRowAsSelected( RowPos const i_rowIndex ); - - /** marks all rows as deselected - @return - <TRUE/> if and only if the selection actually changed by this operation - */ - bool markAllRowsAsDeselected(); - - /** marks all rows as selected - @return - <FALSE/> if and only if all rows were selected already. - */ - bool markAllRowsAsSelected(); - - void commitAccessibleEvent( sal_Int16 const i_eventID ); - void commitCellEvent( sal_Int16 const i_eventID, const css::uno::Any& i_newValue, const css::uno::Any& i_oldValue ); - void commitTableEvent( sal_Int16 const i_eventID, const css::uno::Any& i_newValue, const css::uno::Any& i_oldValue ); - - // ITableControl - virtual void hideCursor() override; - virtual void showCursor() override; - virtual bool dispatchAction( TableControlAction _eAction ) override; - virtual SelectionEngine* getSelEngine() override; - virtual PTableModel getModel() const override; - virtual ColPos getCurrentColumn() const override; - virtual RowPos getCurrentRow() const override; - virtual void activateCell( ColPos const i_col, RowPos const i_row ) override; - virtual ::Size getTableSizePixel() const override; - virtual void setPointer( PointerStyle i_pointer ) override; - virtual void captureMouse() override; - virtual void releaseMouse() override; - virtual void invalidate( TableArea const i_what ) override; - virtual tools::Long pixelWidthToAppFont( tools::Long const i_pixels ) const override; - virtual void hideTracking() override; - virtual void showTracking( tools::Rectangle const & i_location, ShowTrackFlags const i_flags ) override; - RowPos getRowAtPoint( const Point& rPoint ) const; - ColPos getColAtPoint( const Point& rPoint ) const; - virtual TableCell hitTest( const Point& rPoint ) const override; - virtual ColumnMetrics getColumnMetrics( ColPos const i_column ) const override; - virtual bool isRowSelected( RowPos i_row ) const override; - - - tools::Long appFontWidthToPixel( tools::Long const i_appFontUnits ) const; - - TableDataWindow& getDataWindow() { return *m_pDataWindow; } - const TableDataWindow& getDataWindow() const { return *m_pDataWindow; } - ScrollBar* getHorzScrollbar() { return m_pHScroll; } - ScrollBar* getVertScrollbar() { return m_pVScroll; } - - tools::Rectangle calcHeaderRect( bool bColHeader ); - tools::Rectangle calcHeaderCellRect( bool bColHeader, sal_Int32 nPos ); - tools::Rectangle calcTableRect() const; - tools::Rectangle calcCellRect( sal_Int32 nRow, sal_Int32 nCol ) const; - - // A11Y - css::uno::Reference< css::accessibility::XAccessible > - getAccessible( vcl::Window& i_parentWindow ); - void disposeAccessible(); - - bool isAccessibleAlive() const { return impl_isAccessibleAlive(); } - - // ITableModelListener - virtual void rowsInserted( RowPos first, RowPos last ) override; - virtual void rowsRemoved( RowPos first, RowPos last ) override; - virtual void columnInserted() override; - virtual void columnRemoved() override; - virtual void allColumnsRemoved() override; - virtual void cellsUpdated( RowPos const i_firstRow, RowPos const i_lastRow ) override; - virtual void columnChanged( ColPos const i_column, ColumnAttributeGroup const i_attributeGroup ) override; - virtual void tableMetricsChanged() override; - - private: - bool impl_isAccessibleAlive() const; - void impl_commitAccessibleEvent( - sal_Int16 const i_eventID, - css::uno::Any const & i_newValue - ); - - /** toggles the cursor visibility - - The method is not bound to the classes public invariants, as it's used in - situations where the they must not necessarily be fulfilled. - */ - void impl_ni_doSwitchCursor( bool _bOn ); - - /** returns the number of visible rows. - - @param _bAcceptPartialRow - specifies whether a possible only partially visible last row is - counted, too. - */ - TableSize impl_getVisibleRows( bool _bAcceptPartialRow ) const; - - /** returns the number of visible columns - - The value may change with different horizontal scroll positions, as - different columns have different widths. For instance, if your control is - 100 pixels wide, and has three columns of width 50, 50, 100, respectively, - then this method will return either "2" or "1", depending on which column - is the first visible one. - - @param _bAcceptPartialRow - specifies whether a possible only partially visible last row is - counted, too. - */ - TableSize impl_getVisibleColumns( bool _bAcceptPartialCol ) const; - - /** determines the rectangle occupied by the given cell - */ - void impl_getCellRect( ColPos _nColumn, RowPos _nRow, tools::Rectangle& _rCellRect ) const; - - /** updates all cached model values - - The method is not bound to the classes public invariants, as it's used in - situations where the they must not necessarily be fulfilled. - */ - void impl_ni_updateCachedModelValues(); - - /** updates the cached table metrics (row height etc.) - */ - void impl_ni_updateCachedTableMetrics(); - - /** does a relayout of the table control - - Column widths, and consequently the availability of the vertical and horizontal scrollbar, are updated - with a call to this method. - - @param i_assumeInflexibleColumnsUpToIncluding - the index of a column up to which all columns should be considered as inflexible, or - <code>COL_INVALID</code>. - */ - void impl_ni_relayout( ColPos const i_assumeInflexibleColumnsUpToIncluding = COL_INVALID ); - - /** calculates the new width of our columns, taking into account their min and max widths, and their relative - flexibility. - - @param i_assumeInflexibleColumnsUpToIncluding - the index of a column up to which all columns should be considered as inflexible, or - <code>COL_INVALID</code>. - - @param i_assumeVerticalScrollbar - controls whether or not we should assume the presence of a vertical scrollbar. If <true/>, and - if the model has a VerticalScrollbarVisibility != ScrollbarShowNever, the method will leave - space for a vertical scrollbar. - - @return - the overall width of the grid, which is available for columns - */ - tools::Long impl_ni_calculateColumnWidths( - ColPos const i_assumeInflexibleColumnsUpToIncluding, - bool const i_assumeVerticalScrollbar, - ::std::vector< tools::Long >& o_newColWidthsPixel - ) const; - - /** positions all child windows, e.g. the both scrollbars, the corner window, and the data window - */ - void impl_ni_positionChildWindows( - tools::Rectangle const & i_dataCellPlayground, - bool const i_verticalScrollbar, - bool const i_horizontalScrollbar - ); - - /** scrolls the view by the given number of rows - - The method is not bound to the classes public invariants, as it's used in - situations where the they must not necessarily be fulfilled. - - @return - the number of rows by which the viewport was scrolled. This may differ - from the given numbers to scroll in case the begin or the end of the - row range were reached. - */ - TableSize impl_ni_ScrollRows( TableSize _nRowDelta ); - - /** equivalent to impl_ni_ScrollRows, but checks the instances invariants beforehand (in a non-product build only) - */ - TableSize impl_scrollRows( TableSize const i_rowDelta ); - - /** scrolls the view by the given number of columns - - The method is not bound to the classes public invariants, as it's used in - situations where the they must not necessarily be fulfilled. - - @return - the number of columns by which the viewport was scrolled. This may differ - from the given numbers to scroll in case the begin or the end of the - column range were reached. - */ - TableSize impl_ni_ScrollColumns( TableSize _nColumnDelta ); - - /** equivalent to impl_ni_ScrollColumns, but checks the instances invariants beforehand (in a non-product build only) - */ - TableSize impl_scrollColumns( TableSize const i_columnDelta ); - - /** retrieves the area occupied by the totality of (at least partially) visible cells - - The returned area includes row and column headers. Also, it takes into - account the fact that there might be less columns than would normally - find room in the control. - - As a result of respecting the partial visibility of rows and columns, - the returned area might be larger than the data window's output size. - */ - tools::Rectangle impl_getAllVisibleCellsArea() const; - - /** retrieves the area occupied by all (at least partially) visible data cells. - - Effectively, the returned area is the same as returned by ->impl_getAllVisibleCellsArea, - minus the row and column header areas. - */ - tools::Rectangle impl_getAllVisibleDataCellArea() const; - - /** retrieves the column which covers the given ordinate - */ - ColPos impl_getColumnForOrdinate( tools::Long const i_ordinate ) const; - - /** retrieves the row which covers the given abscissa - */ - RowPos impl_getRowForAbscissa( tools::Long const i_abscissa ) const; - - /// invalidates the window area occupied by the given column - void impl_invalidateColumn( ColPos const i_column ); - - DECL_LINK( OnScroll, ScrollBar*, void ); - DECL_LINK( OnUpdateScrollbars, void*, void ); - }; - - //see seleng.hxx, seleng.cxx, FunctionSet overridables, part of selection engine - class TableFunctionSet : public FunctionSet - { - private: - TableControl_Impl* m_pTableControl; - RowPos m_nCurrentRow; - - public: - explicit TableFunctionSet(TableControl_Impl* _pTableControl); - virtual ~TableFunctionSet() override; - - virtual void BeginDrag() override; - virtual void CreateAnchor() override; - virtual void DestroyAnchor() override; - virtual void SetCursorAtPoint(const Point& rPoint, bool bDontSelectAtCursor = false) override; - virtual bool IsSelectionAtPoint( const Point& rPoint ) override; - virtual void DeselectAtPoint( const Point& rPoint ) override; - virtual void DeselectAll() override; - }; - - -} // namespace svt::table - - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/table/tabledatawindow.cxx b/svtools/source/table/tabledatawindow.cxx deleted file mode 100644 index 701b9ea4321b..000000000000 --- a/svtools/source/table/tabledatawindow.cxx +++ /dev/null @@ -1,201 +0,0 @@ -/* -*- 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 <table/tablecontrol.hxx> - -#include "tabledatawindow.hxx" -#include "tablecontrol_impl.hxx" -#include "tablegeometry.hxx" - -#include <vcl/help.hxx> -#include <vcl/scrbar.hxx> -#include <vcl/settings.hxx> -#include <vcl/commandevent.hxx> - -namespace svt::table -{ - using css::uno::Any; - - TableDataWindow::TableDataWindow( TableControl_Impl& _rTableControl ) - :Window( &_rTableControl.getAntiImpl() ) - ,m_rTableControl( _rTableControl ) - { - // by default, use the background as determined by the style settings - const Color aWindowColor( GetSettings().GetStyleSettings().GetFieldColor() ); - SetBackground( Wallpaper( aWindowColor ) ); - GetOutDev()->SetFillColor( aWindowColor ); - } - - TableDataWindow::~TableDataWindow() - { - disposeOnce(); - } - - void TableDataWindow::dispose() - { - impl_hideTipWindow(); - Window::dispose(); - } - - void TableDataWindow::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rUpdateRect ) - { - m_rTableControl.doPaintContent(rRenderContext, rUpdateRect); - } - - void TableDataWindow::RequestHelp( const HelpEvent& rHEvt ) - { - HelpEventMode const nHelpMode = rHEvt.GetMode(); - if ( IsMouseCaptured() - || !( nHelpMode & HelpEventMode::QUICK ) - ) - { - Window::RequestHelp( rHEvt ); - return; - } - - OUString sHelpText; - QuickHelpFlags nHelpStyle = QuickHelpFlags::NONE; - - Point const aMousePos( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) ); - RowPos const hitRow = m_rTableControl.getRowAtPoint( aMousePos ); - ColPos const hitCol = m_rTableControl.getColAtPoint( aMousePos ); - - PTableModel const pTableModel( m_rTableControl.getModel() ); - if ( ( hitCol >= 0 ) && ( hitCol < pTableModel->getColumnCount() ) ) - { - if ( hitRow == ROW_COL_HEADERS ) - { - sHelpText = pTableModel->getColumnModel( hitCol )->getHelpText(); - } - else if ( ( hitRow >= 0 ) && ( hitRow < pTableModel->getRowCount() ) ) - { - Any aCellToolTip; - pTableModel->getCellToolTip( hitCol, hitRow, aCellToolTip ); - if ( !aCellToolTip.hasValue() ) - { - // use the cell content - pTableModel->getCellContent( hitCol, hitRow, aCellToolTip ); - - // use the cell content as tool tip only if it doesn't fit into the cell. - tools::Rectangle const aWindowRect( Point( 0, 0 ), GetOutputSizePixel() ); - TableCellGeometry const aCell( m_rTableControl, aWindowRect, hitCol, hitRow ); - tools::Rectangle const aCellRect( aCell.getRect() ); - - PTableRenderer const pRenderer = pTableModel->getRenderer(); - if ( pRenderer->FitsIntoCell( aCellToolTip, *GetOutDev(), aCellRect ) ) - aCellToolTip.clear(); - } - - pTableModel->getRenderer()->GetFormattedCellString( aCellToolTip, sHelpText ); - - if ( sHelpText.indexOf( '\n' ) >= 0 ) - nHelpStyle = QuickHelpFlags::TipStyleBalloon; - } - } - - if ( !sHelpText.isEmpty() ) - { - // hide the standard (singleton) help window, so we do not have two help windows open at the same time - Help::HideBalloonAndQuickHelp(); - - tools::Rectangle const aControlScreenRect( - OutputToScreenPixel( Point( 0, 0 ) ), - GetOutputSizePixel() - ); - - Help::ShowQuickHelp(this, aControlScreenRect, sHelpText, nHelpStyle); - } - else - { - impl_hideTipWindow(); - Window::RequestHelp( rHEvt ); - } - } - - void TableDataWindow::impl_hideTipWindow() - { - Help::HideBalloonAndQuickHelp(); - } - - void TableDataWindow::MouseMove( const MouseEvent& rMEvt ) - { - if ( rMEvt.IsLeaveWindow() ) - impl_hideTipWindow(); - - if ( !m_rTableControl.getInputHandler()->MouseMove( m_rTableControl, rMEvt ) ) - { - Window::MouseMove( rMEvt ); - } - } - - void TableDataWindow::MouseButtonDown( const MouseEvent& rMEvt ) - { - impl_hideTipWindow(); - - Point const aPoint = rMEvt.GetPosPixel(); - RowPos const hitRow = m_rTableControl.getRowAtPoint( aPoint ); - bool const wasRowSelected = m_rTableControl.isRowSelected( hitRow ); - size_t const nPrevSelRowCount = m_rTableControl.getSelectedRowCount(); - - if ( !m_rTableControl.getInputHandler()->MouseButtonDown( m_rTableControl, rMEvt ) ) - { - Window::MouseButtonDown( rMEvt ); - return; - } - - bool const isRowSelected = m_rTableControl.isRowSelected( hitRow ); - size_t const nCurSelRowCount = m_rTableControl.getSelectedRowCount(); - if ( isRowSelected != wasRowSelected || nCurSelRowCount != nPrevSelRowCount ) - { - m_aSelectHdl.Call( nullptr ); - } - } - - - void TableDataWindow::MouseButtonUp( const MouseEvent& rMEvt ) - { - if ( !m_rTableControl.getInputHandler()->MouseButtonUp( m_rTableControl, rMEvt ) ) - Window::MouseButtonUp( rMEvt ); - - m_rTableControl.getAntiImpl().GrabFocus(); - } - - - bool TableDataWindow::EventNotify(NotifyEvent& rNEvt ) - { - bool bDone = false; - if ( rNEvt.GetType() == MouseNotifyEvent::COMMAND ) - { - const CommandEvent& rCEvt = *rNEvt.GetCommandEvent(); - if ( rCEvt.GetCommand() == CommandEventId::Wheel ) - { - const CommandWheelData* pData = rCEvt.GetWheelData(); - if( !pData->GetModifier() && ( pData->GetMode() == CommandWheelMode::SCROLL ) ) - { - bDone = HandleScrollCommand( rCEvt, m_rTableControl.getHorzScrollbar(), m_rTableControl.getVertScrollbar() ); - } - } - } - return bDone || Window::EventNotify( rNEvt ); - } - -} // namespace svt::table - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/table/tabledatawindow.hxx b/svtools/source/table/tabledatawindow.hxx deleted file mode 100644 index e42a054939db..000000000000 --- a/svtools/source/table/tabledatawindow.hxx +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <vcl/window.hxx> - - -namespace svt::table -{ - class TableControl_Impl; - class TableFunctionSet; - - /** the window containing the content area (including headers) of - a table control - */ - class TableDataWindow : public vcl::Window - { - friend class TableFunctionSet; - private: - TableControl_Impl& m_rTableControl; - Link<LinkParamNone*,void> m_aSelectHdl; - - public: - explicit TableDataWindow( TableControl_Impl& _rTableControl ); - virtual ~TableDataWindow() override; - virtual void dispose() override; - - void SetSelectHdl(const Link<LinkParamNone*,void>& rLink) - { - m_aSelectHdl = rLink; - } - - // Window overridables - virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override; - virtual void MouseMove( const MouseEvent& rMEvt) override; - virtual void MouseButtonDown( const MouseEvent& rMEvt) override; - virtual void MouseButtonUp( const MouseEvent& rMEvt) override; - virtual bool EventNotify(NotifyEvent& rNEvt) override; - virtual void RequestHelp( const HelpEvent& rHEvt ) override; - - private: - static void impl_hideTipWindow(); - }; - -} // namespace svt::table - - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/table/tablegeometry.cxx b/svtools/source/table/tablegeometry.cxx deleted file mode 100644 index 5b18826c50f7..000000000000 --- a/svtools/source/table/tablegeometry.cxx +++ /dev/null @@ -1,154 +0,0 @@ -/* -*- 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 "tablegeometry.hxx" -#include "tablecontrol_impl.hxx" - - -namespace svt::table -{ - - - //= TableRowGeometry - - - TableRowGeometry::TableRowGeometry( TableControl_Impl const & _rControl, tools::Rectangle const & _rBoundaries, - RowPos const _nRow, bool const i_allowVirtualRows ) - :TableGeometry( _rControl, _rBoundaries ) - ,m_nRowPos( _nRow ) - ,m_bAllowVirtualRows( i_allowVirtualRows ) - { - if ( m_nRowPos == ROW_COL_HEADERS ) - { - m_aRect.SetTop( 0 ); - m_aRect.SetBottom( m_rControl.m_nColHeaderHeightPixel - 1 ); - } - else - { - impl_initRect(); - } - } - - - void TableRowGeometry::impl_initRect() - { - if ( ( m_nRowPos >= m_rControl.m_nTopRow ) && impl_isValidRow( m_nRowPos ) ) - { - m_aRect.SetTop( m_rControl.m_nColHeaderHeightPixel + ( m_nRowPos - m_rControl.m_nTopRow ) * m_rControl.m_nRowHeightPixel ); - m_aRect.SetBottom( m_aRect.Top() + m_rControl.m_nRowHeightPixel - 1 ); - } - else - m_aRect.SetEmpty(); - } - - - bool TableRowGeometry::impl_isValidRow( RowPos const i_row ) const - { - return m_bAllowVirtualRows || ( i_row < m_rControl.m_pModel->getRowCount() ); - } - - - bool TableRowGeometry::moveDown() - { - if ( m_nRowPos == ROW_COL_HEADERS ) - { - m_nRowPos = m_rControl.m_nTopRow; - impl_initRect(); - } - else - { - if ( impl_isValidRow( ++m_nRowPos ) ) - m_aRect.Move( 0, m_rControl.m_nRowHeightPixel ); - else - m_aRect.SetEmpty(); - } - return isValid(); - } - - - //= TableColumnGeometry - - - TableColumnGeometry::TableColumnGeometry( TableControl_Impl const & _rControl, tools::Rectangle const & _rBoundaries, - ColPos const _nCol ) - :TableGeometry( _rControl, _rBoundaries ) - ,m_nColPos( _nCol ) - { - if ( m_nColPos == COL_ROW_HEADERS ) - { - m_aRect.SetLeft( 0 ); - m_aRect.SetRight( m_rControl.m_nRowHeaderWidthPixel - 1 ); - } - else - { - impl_initRect(); - } - } - - - void TableColumnGeometry::impl_initRect() - { - ColPos nLeftColumn = m_rControl.m_nLeftColumn; - if ( ( m_nColPos >= nLeftColumn ) && impl_isValidColumn( m_nColPos ) ) - { - m_aRect.SetLeft( m_rControl.m_nRowHeaderWidthPixel ); - // TODO: take into account any possibly frozen columns - - for ( ColPos col = nLeftColumn; col < m_nColPos; ++col ) - m_aRect.AdjustLeft(m_rControl.m_aColumnWidths[ col ].getWidth() ); - m_aRect.SetRight( m_aRect.Left() + m_rControl.m_aColumnWidths[ m_nColPos ].getWidth() - 1 ); - } - else - m_aRect.SetEmpty(); - } - - - bool TableColumnGeometry::impl_isValidColumn( ColPos const i_column ) const - { - return i_column < ColPos( m_rControl.m_aColumnWidths.size() ); - } - - - bool TableColumnGeometry::moveRight() - { - if ( m_nColPos == COL_ROW_HEADERS ) - { - m_nColPos = m_rControl.m_nLeftColumn; - impl_initRect(); - } - else - { - if ( impl_isValidColumn( ++m_nColPos ) ) - { - m_aRect.SetLeft( m_aRect.Right() + 1 ); - m_aRect.AdjustRight(m_rControl.m_aColumnWidths[ m_nColPos ].getWidth() ); - } - else - m_aRect.SetEmpty(); - } - - return isValid(); - } - - -} // namespace svt::table - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/table/tablegeometry.hxx b/svtools/source/table/tablegeometry.hxx deleted file mode 100644 index 9fb6d03f0d68..000000000000 --- a/svtools/source/table/tablegeometry.hxx +++ /dev/null @@ -1,158 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <table/tabletypes.hxx> - -#include <tools/gen.hxx> - - -namespace svt::table -{ - - - class TableControl_Impl; - - - //= TableGeometry - - class TableGeometry - { - protected: - const TableControl_Impl& m_rControl; - const tools::Rectangle& m_rBoundaries; - tools::Rectangle m_aRect; - - protected: - TableGeometry( - const TableControl_Impl& _rControl, - const tools::Rectangle& _rBoundaries - ) - :m_rControl( _rControl ) - ,m_rBoundaries( _rBoundaries ) - ,m_aRect( _rBoundaries ) - { - } - - public: - // attribute access - const TableControl_Impl& getControl() const { return m_rControl; } - - // status - const tools::Rectangle& getRect() const { return m_aRect; } - bool isValid() const { return !m_aRect.GetIntersection( m_rBoundaries ).IsEmpty(); } - }; - - - //= TableRowGeometry - - class TableRowGeometry final : public TableGeometry - { - public: - TableRowGeometry( - TableControl_Impl const & _rControl, - tools::Rectangle const & _rBoundaries, - RowPos const _nRow, - bool const i_allowVirtualRows = false - // allow rows >= getRowCount()? - ); - - // status - RowPos getRow() const { return m_nRowPos; } - // operations - bool moveDown(); - - private: - void impl_initRect(); - bool impl_isValidRow( RowPos const i_row ) const; - - RowPos m_nRowPos; - bool m_bAllowVirtualRows; - }; - - - //= TableColumnGeometry - - class TableColumnGeometry final : public TableGeometry - { - public: - TableColumnGeometry( - TableControl_Impl const & _rControl, - tools::Rectangle const & _rBoundaries, - ColPos const _nCol - ); - - // status - ColPos getCol() const { return m_nColPos; } - // operations - bool moveRight(); - - private: - void impl_initRect(); - bool impl_isValidColumn( ColPos const i_column ) const; - - ColPos m_nColPos; - }; - - - //= TableCellGeometry - - /** a helper representing geometry information of a cell - */ - class TableCellGeometry - { - private: - TableRowGeometry m_aRow; - TableColumnGeometry m_aCol; - - public: - TableCellGeometry( - TableControl_Impl const & _rControl, - tools::Rectangle const & _rBoundaries, - ColPos const _nCol, - RowPos const _nRow - ) - :m_aRow( _rControl, _rBoundaries, _nRow, false/*allowVirtualCells*/ ) - ,m_aCol( _rControl, _rBoundaries, _nCol ) - { - } - - TableCellGeometry( - const TableRowGeometry& _rRow, - ColPos _nCol - ) - :m_aRow( _rRow ) - ,m_aCol( _rRow.getControl(), _rRow.getRect(), _nCol ) - { - } - - tools::Rectangle getRect() const { return m_aRow.getRect().GetIntersection( m_aCol.getRect() ); } - ColPos getColumn() const { return m_aCol.getCol(); } - bool isValid() const { return !getRect().IsEmpty(); } - - bool moveRight() {return m_aCol.moveRight(); } - }; - - -} // namespace svt::table - - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/uno/svtxgridcontrol.cxx b/svtools/source/uno/svtxgridcontrol.cxx deleted file mode 100644 index 4aee46f2c9ea..000000000000 --- a/svtools/source/uno/svtxgridcontrol.cxx +++ /dev/null @@ -1,909 +0,0 @@ -/* -*- 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 "svtxgridcontrol.hxx" -#include <com/sun/star/view/SelectionType.hpp> -#include <table/tablecontrolinterface.hxx> -#include <table/gridtablerenderer.hxx> -#include <table/tablecontrol.hxx> -#include "unocontroltablemodel.hxx" -#include <sal/log.hxx> -#include <tools/diagnose_ex.h> -#include <toolkit/helper/property.hxx> -#include <com/sun/star/awt/grid/XGridColumn.hpp> -#include <com/sun/star/awt/grid/GridInvalidDataException.hpp> -#include <com/sun/star/awt/grid/GridInvalidModelException.hpp> -#include <com/sun/star/accessibility/AccessibleEventId.hpp> -#include <com/sun/star/accessibility/AccessibleStateType.hpp> -#include <com/sun/star/util/Color.hpp> -#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> - -#include <vcl/svapp.hxx> - -#include <algorithm> - -using css::uno::Reference; -using css::uno::Exception; -using css::uno::UNO_QUERY; -using css::uno::UNO_QUERY_THROW; -using css::uno::Any; -using css::uno::Sequence; -using css::awt::grid::XGridSelectionListener; -using css::style::VerticalAlignment; -using css::style::VerticalAlignment_TOP; -using css::view::SelectionType; -using css::view::SelectionType_NONE; -using css::view::SelectionType_RANGE; -using css::view::SelectionType_SINGLE; -using css::view::SelectionType_MULTI; -using css::awt::grid::XGridDataModel; -using css::awt::grid::GridInvalidDataException; -using css::lang::EventObject; -using css::lang::IndexOutOfBoundsException; -using css::awt::grid::XGridColumnModel; -using css::awt::grid::GridSelectionEvent; -using css::awt::grid::XGridColumn; -using css::container::ContainerEvent; -using css::awt::grid::GridDataEvent; -using css::awt::grid::GridInvalidModelException; - -namespace AccessibleEventId = css::accessibility::AccessibleEventId; -namespace AccessibleStateType = css::accessibility::AccessibleStateType; - -using namespace ::svt::table; - - -SVTXGridControl::SVTXGridControl() - :m_xTableModel( std::make_shared<UnoControlTableModel>() ) - ,m_bTableModelInitCompleted( false ) - ,m_aSelectionListeners( *this ) -{ -} - - -SVTXGridControl::~SVTXGridControl() -{ -} - - -void SVTXGridControl::SetWindow( const VclPtr< vcl::Window > &pWindow ) -{ - SVTXGridControl_Base::SetWindow( pWindow ); - impl_checkTableModelInit(); -} - - -void SVTXGridControl::impl_checkColumnIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_columnIndex ) const -{ - if ( ( i_columnIndex < 0 ) || ( i_columnIndex >= i_table.GetColumnCount() ) ) - throw IndexOutOfBoundsException( OUString(), *const_cast< SVTXGridControl* >( this ) ); -} - - -void SVTXGridControl::impl_checkRowIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_rowIndex ) const -{ - if ( ( i_rowIndex < 0 ) || ( i_rowIndex >= i_table.GetRowCount() ) ) - throw IndexOutOfBoundsException( OUString(), *const_cast< SVTXGridControl* >( this ) ); -} - - -sal_Int32 SAL_CALL SVTXGridControl::getRowAtPoint(::sal_Int32 x, ::sal_Int32 y) -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN( pTable, "SVTXGridControl::getRowAtPoint: no control (anymore)!", -1 ); - - TableCell const tableCell = pTable->getTableControlInterface().hitTest( Point( x, y ) ); - return ( tableCell.nRow >= 0 ) ? tableCell.nRow : -1; -} - - -sal_Int32 SAL_CALL SVTXGridControl::getColumnAtPoint(::sal_Int32 x, ::sal_Int32 y) -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN( pTable, "SVTXGridControl::getColumnAtPoint: no control (anymore)!", -1 ); - - TableCell const tableCell = pTable->getTableControlInterface().hitTest( Point( x, y ) ); - return ( tableCell.nColumn >= 0 ) ? tableCell.nColumn : -1; -} - - -sal_Int32 SAL_CALL SVTXGridControl::getCurrentColumn( ) -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN( pTable, "SVTXGridControl::getCurrentColumn: no control (anymore)!", -1 ); - - sal_Int32 const nColumn = pTable->GetCurrentColumn(); - return ( nColumn >= 0 ) ? nColumn : -1; -} - - -sal_Int32 SAL_CALL SVTXGridControl::getCurrentRow( ) -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN( pTable, "SVTXGridControl::getCurrentRow: no control (anymore)!", -1 ); - - sal_Int32 const nRow = pTable->GetCurrentRow(); - return ( nRow >= 0 ) ? nRow : -1; -} - - -void SAL_CALL SVTXGridControl::goToCell( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::getCurrentRow: no control (anymore)!" ); - - impl_checkColumnIndex_throw( *pTable, i_columnIndex ); - impl_checkRowIndex_throw( *pTable, i_rowIndex ); - - pTable->GoTo( i_columnIndex, i_rowIndex ); -} - - -void SAL_CALL SVTXGridControl::addSelectionListener(const Reference< XGridSelectionListener > & listener) -{ - m_aSelectionListeners.addInterface(listener); -} - - -void SAL_CALL SVTXGridControl::removeSelectionListener(const Reference< XGridSelectionListener > & listener) -{ - m_aSelectionListeners.removeInterface(listener); -} - - -void SVTXGridControl::setProperty( const OUString& PropertyName, const Any& aValue) -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::setProperty: no control (anymore)!" ); - - switch( GetPropertyId( PropertyName ) ) - { - case BASEPROPERTY_ROW_HEADER_WIDTH: - { - sal_Int32 rowHeaderWidth( -1 ); - aValue >>= rowHeaderWidth; - if ( rowHeaderWidth <= 0 ) - { - SAL_WARN( "svtools.uno", "SVTXGridControl::setProperty: illegal row header width!" ); - break; - } - - m_xTableModel->setRowHeaderWidth( rowHeaderWidth ); - // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed - pTable->Invalidate(); - } - break; - - case BASEPROPERTY_COLUMN_HEADER_HEIGHT: - { - sal_Int32 columnHeaderHeight = 0; - if ( !aValue.hasValue() ) - { - columnHeaderHeight = pTable->PixelToLogic(Size(0, pTable->GetTextHeight() + 3), MapMode(MapUnit::MapAppFont)).Height(); - } - else - { - aValue >>= columnHeaderHeight; - } - if ( columnHeaderHeight <= 0 ) - { - SAL_WARN( "svtools.uno", "SVTXGridControl::setProperty: illegal column header width!" ); - break; - } - - m_xTableModel->setColumnHeaderHeight( columnHeaderHeight ); - // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed - pTable->Invalidate(); - } - break; - - case BASEPROPERTY_USE_GRID_LINES: - { - GridTableRenderer* pGridRenderer = dynamic_cast< GridTableRenderer* >( - m_xTableModel->getRenderer().get() ); - if ( !pGridRenderer ) - { - SAL_WARN( "svtools.uno", "SVTXGridControl::setProperty(UseGridLines): invalid renderer!" ); - break; - } - - bool bUseGridLines = false; - OSL_VERIFY( aValue >>= bUseGridLines ); - pGridRenderer->useGridLines( bUseGridLines ); - pTable->Invalidate(); - } - break; - - case BASEPROPERTY_ROW_HEIGHT: - { - sal_Int32 rowHeight = 0; - if ( !aValue.hasValue() ) - { - rowHeight = pTable->PixelToLogic(Size(0, pTable->GetTextHeight() + 3), MapMode(MapUnit::MapAppFont)).Height(); - } - else - { - aValue >>= rowHeight; - } - m_xTableModel->setRowHeight( rowHeight ); - if ( rowHeight <= 0 ) - { - SAL_WARN( "svtools.uno", "SVTXGridControl::setProperty: illegal row height!" ); - break; - } - - // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed - pTable->Invalidate(); - } - break; - - case BASEPROPERTY_BACKGROUNDCOLOR: - { - // let the base class handle this for the TableControl - VCLXWindow::setProperty( PropertyName, aValue ); - // and forward to the grid control's data window - if ( pTable->IsBackground() ) - pTable->getDataWindow().SetBackground( pTable->GetBackground() ); - else - pTable->getDataWindow().SetBackground(); - } - break; - - case BASEPROPERTY_GRID_SELECTIONMODE: - { - SelectionType eSelectionType; - if( aValue >>= eSelectionType ) - { - SelectionMode eSelMode; - switch( eSelectionType ) - { - case SelectionType_SINGLE: eSelMode = SelectionMode::Single; break; - case SelectionType_RANGE: eSelMode = SelectionMode::Range; break; - case SelectionType_MULTI: eSelMode = SelectionMode::Multiple; break; - default: eSelMode = SelectionMode::NONE; break; - } - if( pTable->getSelEngine()->GetSelectionMode() != eSelMode ) - pTable->getSelEngine()->SetSelectionMode( eSelMode ); - } - break; - } - case BASEPROPERTY_HSCROLL: - { - bool bHScroll = true; - if( aValue >>= bHScroll ) - m_xTableModel->setHorizontalScrollbarVisibility( bHScroll ? ScrollbarShowAlways : ScrollbarShowSmart ); - break; - } - - case BASEPROPERTY_VSCROLL: - { - bool bVScroll = true; - if( aValue >>= bVScroll ) - { - m_xTableModel->setVerticalScrollbarVisibility( bVScroll ? ScrollbarShowAlways : ScrollbarShowSmart ); - } - break; - } - - case BASEPROPERTY_GRID_SHOWROWHEADER: - { - bool rowHeader = true; - if( aValue >>= rowHeader ) - { - m_xTableModel->setRowHeaders(rowHeader); - } - break; - } - - case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS: - m_xTableModel->setRowBackgroundColors( aValue ); - pTable->Invalidate(); - break; - - case BASEPROPERTY_GRID_LINE_COLOR: - m_xTableModel->setLineColor( aValue ); - pTable->Invalidate(); - break; - - case BASEPROPERTY_GRID_HEADER_BACKGROUND: - m_xTableModel->setHeaderBackgroundColor( aValue ); - pTable->Invalidate(); - break; - - case BASEPROPERTY_GRID_HEADER_TEXT_COLOR: - m_xTableModel->setHeaderTextColor( aValue ); - pTable->Invalidate(); - break; - - case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR: - m_xTableModel->setActiveSelectionBackColor( aValue ); - pTable->Invalidate(); - break; - - case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR: - m_xTableModel->setInactiveSelectionBackColor( aValue ); - pTable->Invalidate(); - break; - - case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR: - m_xTableModel->setActiveSelectionTextColor( aValue ); - pTable->Invalidate(); - break; - - case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR: - m_xTableModel->setInactiveSelectionTextColor( aValue ); - pTable->Invalidate(); - break; - - - case BASEPROPERTY_TEXTCOLOR: - m_xTableModel->setTextColor( aValue ); - pTable->Invalidate(); - break; - - case BASEPROPERTY_TEXTLINECOLOR: - m_xTableModel->setTextLineColor( aValue ); - pTable->Invalidate(); - break; - - case BASEPROPERTY_VERTICALALIGN: - { - VerticalAlignment eAlign( VerticalAlignment_TOP ); - if ( aValue >>= eAlign ) - m_xTableModel->setVerticalAlign( eAlign ); - break; - } - - case BASEPROPERTY_GRID_SHOWCOLUMNHEADER: - { - bool colHeader = true; - if( aValue >>= colHeader ) - { - m_xTableModel->setColumnHeaders(colHeader); - } - break; - } - case BASEPROPERTY_GRID_DATAMODEL: - { - Reference< XGridDataModel > const xDataModel( aValue, UNO_QUERY ); - if ( !xDataModel.is() ) - throw GridInvalidDataException("Invalid data model.", *this ); - - m_xTableModel->setDataModel( xDataModel ); - impl_checkTableModelInit(); - } - break; - - case BASEPROPERTY_GRID_COLUMNMODEL: - { - // obtain new col model - Reference< XGridColumnModel > const xColumnModel( aValue, UNO_QUERY ); - if ( !xColumnModel.is() ) - throw GridInvalidModelException("Invalid column model.", *this ); - - // remove all old columns - m_xTableModel->removeAllColumns(); - - // announce to the TableModel - m_xTableModel->setColumnModel( xColumnModel ); - impl_checkTableModelInit(); - - // add new columns - impl_updateColumnsFromModel_nothrow(); - break; - } - default: - VCLXWindow::setProperty( PropertyName, aValue ); - break; - } -} - - -void SVTXGridControl::impl_checkTableModelInit() -{ - if ( !(!m_bTableModelInitCompleted && m_xTableModel->hasColumnModel() && m_xTableModel->hasDataModel()) ) - return; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - if ( !pTable ) - return; - - pTable->SetModel( PTableModel( m_xTableModel ) ); - - m_bTableModelInitCompleted = true; - - // ensure default columns exist, if they have not previously been added - Reference< XGridDataModel > const xDataModel( m_xTableModel->getDataModel(), css::uno::UNO_SET_THROW ); - Reference< XGridColumnModel > const xColumnModel( m_xTableModel->getColumnModel(), css::uno::UNO_SET_THROW ); - - sal_Int32 const nDataColumnCount = xDataModel->getColumnCount(); - if ( ( nDataColumnCount > 0 ) && ( xColumnModel->getColumnCount() == 0 ) ) - xColumnModel->setDefaultColumns( nDataColumnCount ); - // this will trigger notifications, which in turn will let us update our m_xTableModel -} - -namespace -{ - void lcl_convertColor( ::std::optional< ::Color > const & i_color, Any & o_colorValue ) - { - if ( !i_color ) - o_colorValue.clear(); - else - o_colorValue <<= sal_Int32(*i_color); - } -} - -Any SVTXGridControl::getProperty( const OUString& PropertyName ) -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN( pTable, "SVTXGridControl::getProperty: no control (anymore)!", Any() ); - - Any aPropertyValue; - - const sal_uInt16 nPropId = GetPropertyId( PropertyName ); - switch(nPropId) - { - case BASEPROPERTY_GRID_SELECTIONMODE: - { - SelectionType eSelectionType; - - SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode(); - switch( eSelMode ) - { - case SelectionMode::Single: eSelectionType = SelectionType_SINGLE; break; - case SelectionMode::Range: eSelectionType = SelectionType_RANGE; break; - case SelectionMode::Multiple:eSelectionType = SelectionType_MULTI; break; - default: eSelectionType = SelectionType_NONE; break; - } - aPropertyValue <<= eSelectionType; - break; - } - - case BASEPROPERTY_GRID_SHOWROWHEADER: - aPropertyValue <<= m_xTableModel->hasRowHeaders(); - break; - - case BASEPROPERTY_GRID_SHOWCOLUMNHEADER: - aPropertyValue <<= m_xTableModel->hasColumnHeaders(); - break; - - case BASEPROPERTY_GRID_DATAMODEL: - aPropertyValue <<= m_xTableModel->getDataModel(); - break; - - case BASEPROPERTY_GRID_COLUMNMODEL: - aPropertyValue <<= m_xTableModel->getColumnModel(); - break; - - case BASEPROPERTY_HSCROLL: - { - bool const bHasScrollbar = ( m_xTableModel->getHorizontalScrollbarVisibility() != ScrollbarShowNever ); - aPropertyValue <<= bHasScrollbar; - break; - } - - case BASEPROPERTY_VSCROLL: - { - bool const bHasScrollbar = ( m_xTableModel->getVerticalScrollbarVisibility() != ScrollbarShowNever ); - aPropertyValue <<= bHasScrollbar; - break; - } - - case BASEPROPERTY_USE_GRID_LINES: - { - GridTableRenderer* pGridRenderer = dynamic_cast< GridTableRenderer* >( - m_xTableModel->getRenderer().get() ); - if ( !pGridRenderer ) - { - SAL_WARN( "svtools.uno", "SVTXGridControl::getProperty(UseGridLines): invalid renderer!" ); - break; - } - - aPropertyValue <<= pGridRenderer->useGridLines(); - } - break; - - case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS: - { - ::std::optional< ::std::vector< ::Color > > aColors( m_xTableModel->getRowBackgroundColors() ); - if ( !aColors ) - aPropertyValue.clear(); - else - { - Sequence< css::util::Color > aAPIColors( aColors->size() ); - std::transform(aColors->begin(), aColors->end(), aAPIColors.getArray(), - [](const auto& color) { return sal_Int32(color); }); - aPropertyValue <<= aAPIColors; - } - } - break; - - case BASEPROPERTY_GRID_LINE_COLOR: - lcl_convertColor( m_xTableModel->getLineColor(), aPropertyValue ); - break; - - case BASEPROPERTY_GRID_HEADER_BACKGROUND: - lcl_convertColor( m_xTableModel->getHeaderBackgroundColor(), aPropertyValue ); - break; - - case BASEPROPERTY_GRID_HEADER_TEXT_COLOR: - lcl_convertColor( m_xTableModel->getHeaderTextColor(), aPropertyValue ); - break; - - case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR: - lcl_convertColor( m_xTableModel->getActiveSelectionBackColor(), aPropertyValue ); - break; - - case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR: - lcl_convertColor( m_xTableModel->getInactiveSelectionBackColor(), aPropertyValue ); - break; - - case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR: - lcl_convertColor( m_xTableModel->getActiveSelectionTextColor(), aPropertyValue ); - break; - - case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR: - lcl_convertColor( m_xTableModel->getInactiveSelectionTextColor(), aPropertyValue ); - break; - - case BASEPROPERTY_TEXTCOLOR: - lcl_convertColor( m_xTableModel->getTextColor(), aPropertyValue ); - break; - - case BASEPROPERTY_TEXTLINECOLOR: - lcl_convertColor( m_xTableModel->getTextLineColor(), aPropertyValue ); - break; - - default: - aPropertyValue = VCLXWindow::getProperty( PropertyName ); - break; - } - - return aPropertyValue; -} - - -void SAL_CALL SVTXGridControl::rowsInserted( const GridDataEvent& i_event ) -{ - SolarMutexGuard aGuard; - m_xTableModel->notifyRowsInserted( i_event ); -} - - -void SAL_CALL - SVTXGridControl::rowsRemoved( const GridDataEvent& i_event ) -{ - SolarMutexGuard aGuard; - m_xTableModel->notifyRowsRemoved( i_event ); -} - - -void SAL_CALL SVTXGridControl::dataChanged( const GridDataEvent& i_event ) -{ - SolarMutexGuard aGuard; - - m_xTableModel->notifyDataChanged( i_event ); - - // if the data model is sortable, a dataChanged event is also fired in case the sort order changed. - // So, just in case, invalidate the column header area, too. - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::dataChanged: no control (anymore)!" ); - pTable->getTableControlInterface().invalidate( TableArea::ColumnHeaders ); -} - - -void SAL_CALL SVTXGridControl::rowHeadingChanged( const GridDataEvent& ) -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::rowHeadingChanged: no control (anymore)!" ); - - // TODO: we could do better than this - invalidate the header area only - pTable->getTableControlInterface().invalidate( TableArea::RowHeaders ); -} - - -void SAL_CALL SVTXGridControl::elementInserted( const ContainerEvent& i_event ) -{ - SolarMutexGuard aGuard; - - Reference< XGridColumn > const xGridColumn( i_event.Element, UNO_QUERY_THROW ); - - sal_Int32 nIndex( m_xTableModel->getColumnCount() ); - OSL_VERIFY( i_event.Accessor >>= nIndex ); - m_xTableModel->insertColumn( nIndex, xGridColumn ); -} - - -void SAL_CALL SVTXGridControl::elementRemoved( const ContainerEvent& i_event ) -{ - SolarMutexGuard aGuard; - - sal_Int32 nIndex( -1 ); - OSL_VERIFY( i_event.Accessor >>= nIndex ); - m_xTableModel->removeColumn( nIndex ); -} - - -void SAL_CALL SVTXGridControl::elementReplaced( const ContainerEvent& ) -{ - OSL_ENSURE( false, "SVTXGridControl::elementReplaced: not implemented!" ); - // at the moment, the XGridColumnModel API does not allow replacing columns - // TODO: replace the respective column in our table model -} - - -void SAL_CALL SVTXGridControl::disposing( const EventObject& Source ) -{ - VCLXWindow::disposing( Source ); -} - - -void SAL_CALL SVTXGridControl::selectRow( ::sal_Int32 i_rowIndex ) -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::selectRow: no control (anymore)!" ); - - impl_checkRowIndex_throw( *pTable, i_rowIndex ); - - pTable->SelectRow( i_rowIndex, true ); -} - - -void SAL_CALL SVTXGridControl::selectAllRows() -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::selectAllRows: no control (anymore)!" ); - - pTable->SelectAllRows( true ); -} - - -void SAL_CALL SVTXGridControl::deselectRow( ::sal_Int32 i_rowIndex ) -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::deselectRow: no control (anymore)!" ); - - impl_checkRowIndex_throw( *pTable, i_rowIndex ); - - pTable->SelectRow( i_rowIndex, false ); -} - - -void SAL_CALL SVTXGridControl::deselectAllRows() -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::deselectAllRows: no control (anymore)!" ); - - pTable->SelectAllRows( false ); -} - - -Sequence< ::sal_Int32 > SAL_CALL SVTXGridControl::getSelectedRows() -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN( pTable, "SVTXGridControl::getSelectedRows: no control (anymore)!", Sequence< sal_Int32 >() ); - - sal_Int32 selectionCount = pTable->GetSelectedRowCount(); - Sequence< sal_Int32 > selectedRows( selectionCount ); - auto selectedRowsRange = asNonConstRange(selectedRows); - for ( sal_Int32 i=0; i<selectionCount; ++i ) - selectedRowsRange[i] = pTable->GetSelectedRowIndex(i); - return selectedRows; -} - - -sal_Bool SAL_CALL SVTXGridControl::hasSelectedRows() -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN( pTable, "SVTXGridControl::hasSelectedRows: no control (anymore)!", true ); - - return pTable->GetSelectedRowCount() > 0; -} - - -sal_Bool SAL_CALL SVTXGridControl::isRowSelected( ::sal_Int32 index ) -{ - SolarMutexGuard aGuard; - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN( pTable, "SVTXGridControl::isRowSelected: no control (anymore)!", false ); - - return pTable->IsRowSelected( index ); -} - - -void SVTXGridControl::dispose() -{ - EventObject aObj; - aObj.Source = static_cast<cppu::OWeakObject*>(this); - m_aSelectionListeners.disposeAndClear( aObj ); - VCLXWindow::dispose(); -} - - -void SVTXGridControl::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) -{ - SolarMutexGuard aGuard; - - Reference< XWindow > xKeepAlive( this ); - - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::ProcessWindowEvent: no control (anymore)!" ); - - bool handled = false; - switch ( rVclWindowEvent.GetId() ) - { - case VclEventId::TableRowSelect: - { - if ( m_aSelectionListeners.getLength() ) - ImplCallItemListeners(); - handled = true; - } - break; - - case VclEventId::ControlGetFocus: - { - // TODO: this doesn't belong here. It belongs into the TableControl/_Impl, so A11Y also - // works when the control is used outside the UNO context - if ( pTable->GetRowCount()>0 ) - { - pTable->commitCellEventIfAccessibleAlive( - AccessibleEventId::STATE_CHANGED, - Any( AccessibleStateType::FOCUSED ), - Any() - ); - pTable->commitTableEventIfAccessibleAlive( - AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, - Any(), - Any() - ); - } - else - { - pTable->commitTableEventIfAccessibleAlive( - AccessibleEventId::STATE_CHANGED, - Any( AccessibleStateType::FOCUSED ), - Any() - ); - } - } - break; - - case VclEventId::ControlLoseFocus: - { - // TODO: this doesn't belong here. It belongs into the TableControl/_Impl, so A11Y also - // works when the control is used outside the UNO context - if ( pTable->GetRowCount()>0 ) - { - pTable->commitCellEventIfAccessibleAlive( - AccessibleEventId::STATE_CHANGED, - Any(), - Any( AccessibleStateType::FOCUSED ) - ); - } - else - { - pTable->commitTableEventIfAccessibleAlive( - AccessibleEventId::STATE_CHANGED, - Any(), - Any( AccessibleStateType::FOCUSED ) - ); - } - } - break; - - default: break; - } - - if ( !handled ) - VCLXWindow::ProcessWindowEvent( rVclWindowEvent ); -} - - -void SVTXGridControl::setEnable( sal_Bool bEnable ) -{ - SolarMutexGuard aGuard; - - m_xTableModel->setEnabled( bEnable ); - VclPtr<vcl::Window> pWindow = GetWindow(); - if ( pWindow ) - { - pWindow->Enable( bEnable ); - pWindow->EnableInput( bEnable ); - pWindow->Invalidate(); - } -} - - -void SVTXGridControl::ImplCallItemListeners() -{ - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::ImplCallItemListeners: no control (anymore)!" ); - - if ( m_aSelectionListeners.getLength() ) - { - GridSelectionEvent aEvent; - aEvent.Source = static_cast<cppu::OWeakObject*>(this); - - sal_Int32 const nSelectedRowCount( pTable->GetSelectedRowCount() ); - aEvent.SelectedRowIndexes.realloc( nSelectedRowCount ); - auto pSelectedRowIndexes = aEvent.SelectedRowIndexes.getArray(); - for ( sal_Int32 i=0; i<nSelectedRowCount; ++i ) - pSelectedRowIndexes[i] = pTable->GetSelectedRowIndex( i ); - m_aSelectionListeners.selectionChanged( aEvent ); - } -} - - -void SVTXGridControl::impl_updateColumnsFromModel_nothrow() -{ - Reference< XGridColumnModel > const xColumnModel( m_xTableModel->getColumnModel() ); - ENSURE_OR_RETURN_VOID( xColumnModel.is(), "no model!" ); - VclPtr< TableControl > pTable = GetAsDynamic< TableControl >(); - ENSURE_OR_RETURN_VOID( pTable, "no table!" ); - - try - { - const Sequence< Reference< XGridColumn > > columns = xColumnModel->getColumns(); - for ( auto const & colRef : columns ) - { - if ( !colRef.is() ) - { - SAL_WARN( "svtools.uno", "illegal column!" ); - continue; - } - - m_xTableModel->appendColumn( colRef ); - } - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("svtools.uno"); - } -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/uno/svtxgridcontrol.hxx b/svtools/source/uno/svtxgridcontrol.hxx deleted file mode 100644 index 9e4fd85fee89..000000000000 --- a/svtools/source/uno/svtxgridcontrol.hxx +++ /dev/null @@ -1,110 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include "unocontroltablemodel.hxx" -#include <table/tablecontrol.hxx> -#include <com/sun/star/awt/grid/XGridControl.hpp> -#include <com/sun/star/awt/grid/XGridRowSelection.hpp> -#include <com/sun/star/awt/grid/XGridDataListener.hpp> -#include <com/sun/star/awt/grid/GridDataEvent.hpp> -#include <com/sun/star/awt/grid/XGridSelectionListener.hpp> -#include <com/sun/star/container/XContainerListener.hpp> -#include <toolkit/awt/vclxwindow.hxx> -#include <cppuhelper/implbase.hxx> -#include <toolkit/helper/listenermultiplexer.hxx> - - -namespace svt::table { - class TableControl; -} - -typedef ::cppu::ImplInheritanceHelper < VCLXWindow - , css::awt::grid::XGridControl - , css::awt::grid::XGridRowSelection - , css::awt::grid::XGridDataListener - , css::container::XContainerListener - > SVTXGridControl_Base; -class SVTXGridControl final : public SVTXGridControl_Base -{ -public: - SVTXGridControl(); - virtual ~SVTXGridControl() override; - - // XGridDataListener - virtual void SAL_CALL rowsInserted( const css::awt::grid::GridDataEvent& Event ) override; - virtual void SAL_CALL rowsRemoved( const css::awt::grid::GridDataEvent& Event ) override; - virtual void SAL_CALL dataChanged( const css::awt::grid::GridDataEvent& Event ) override; - virtual void SAL_CALL rowHeadingChanged( const css::awt::grid::GridDataEvent& Event ) override; - - // XContainerListener - virtual void SAL_CALL elementInserted( const css::container::ContainerEvent& Event ) override; - virtual void SAL_CALL elementRemoved( const css::container::ContainerEvent& Event ) override; - virtual void SAL_CALL elementReplaced( const css::container::ContainerEvent& Event ) override; - - // XEventListener - virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; - - // XGridControl - virtual ::sal_Int32 SAL_CALL getRowAtPoint(::sal_Int32 x, ::sal_Int32 y) override; - virtual ::sal_Int32 SAL_CALL getColumnAtPoint(::sal_Int32 x, ::sal_Int32 y) override; - virtual ::sal_Int32 SAL_CALL getCurrentColumn( ) override; - virtual ::sal_Int32 SAL_CALL getCurrentRow( ) override; - virtual void SAL_CALL goToCell( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) override; - - // XGridRowSelection - virtual void SAL_CALL selectRow( ::sal_Int32 i_rowIndex ) override; - virtual void SAL_CALL selectAllRows() override; - virtual void SAL_CALL deselectRow( ::sal_Int32 i_rowIndex ) override; - virtual void SAL_CALL deselectAllRows() override; - virtual css::uno::Sequence< ::sal_Int32 > SAL_CALL getSelectedRows() override; - virtual sal_Bool SAL_CALL hasSelectedRows() override; - virtual sal_Bool SAL_CALL isRowSelected(::sal_Int32 index) override; - virtual void SAL_CALL addSelectionListener(const css::uno::Reference< css::awt::grid::XGridSelectionListener > & listener) override; - virtual void SAL_CALL removeSelectionListener(const css::uno::Reference< css::awt::grid::XGridSelectionListener > & listener) override; - - void SAL_CALL setProperty( const OUString& PropertyName, const css::uno::Any& Value ) override; - css::uno::Any SAL_CALL getProperty( const OUString& PropertyName ) override; - - // css::lang::XComponent - void SAL_CALL dispose( ) override; - - // XWindow - void SAL_CALL setEnable( sal_Bool bEnable ) override; - -private: - // VCLXWindow - virtual void SetWindow( const VclPtr< vcl::Window > &pWindow ) override; - - void impl_updateColumnsFromModel_nothrow(); - void impl_checkTableModelInit(); - - void impl_checkColumnIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_columnIndex ) const; - void impl_checkRowIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_rowIndex ) const; - - virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) override; - void ImplCallItemListeners(); - - std::shared_ptr< ::svt::table::UnoControlTableModel > m_xTableModel; - bool m_bTableModelInitCompleted; - SelectionListenerMultiplexer m_aSelectionListeners; -}; - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/uno/unocontroltablemodel.cxx b/svtools/source/uno/unocontroltablemodel.cxx deleted file mode 100644 index 14f9c6977fca..000000000000 --- a/svtools/source/uno/unocontroltablemodel.cxx +++ /dev/null @@ -1,835 +0,0 @@ -/* -*- 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 "unocontroltablemodel.hxx" -#include "unogridcolumnfacade.hxx" - -#include <table/defaultinputhandler.hxx> -#include <table/gridtablerenderer.hxx> - -#include <com/sun/star/awt/grid/XSortableGridData.hpp> -#include <com/sun/star/util/Color.hpp> -#include <o3tl/safeint.hxx> -#include <sal/log.hxx> -#include <cppuhelper/weakref.hxx> -#include <tools/debug.hxx> -#include <tools/diagnose_ex.h> - - -namespace svt::table -{ - - - using css::uno::Reference; - using css::uno::Sequence; - using css::uno::UNO_QUERY_THROW; - using css::uno::UNO_QUERY; - using css::awt::grid::XGridColumn; - using css::uno::Exception; - using css::awt::grid::XGridDataModel; - using css::awt::grid::XGridColumnModel; - using css::uno::Any; - using css::style::VerticalAlignment_TOP; - using css::style::VerticalAlignment; - using css::uno::WeakReference; - using css::awt::grid::GridDataEvent; - using css::awt::grid::XSortableGridData; - using css::beans::Pair; - - - //= UnoControlTableModel -#define DBG_CHECK_ME() \ - DBG_TESTSOLARMUTEX(); \ - - UnoControlTableModel::UnoControlTableModel() - :aColumns ( ) - ,bHasColumnHeaders ( true ) - ,bHasRowHeaders ( false ) - ,eVScrollMode ( ScrollbarShowNever ) - ,eHScrollMode ( ScrollbarShowNever ) - ,pRenderer ( ) - ,pInputHandler ( ) - ,nRowHeight ( 10 ) - ,nColumnHeaderHeight ( 10 ) - ,nRowHeaderWidth ( 10 ) - ,m_aGridLineColor ( ) - ,m_aHeaderBackgroundColor ( ) - ,m_aHeaderTextColor ( ) - ,m_aActiveSelectionBackColor ( ) - ,m_aInactiveSelectionBackColor ( ) - ,m_aActiveSelectionTextColor ( ) - ,m_aInactiveSelectionTextColor ( ) - ,m_aTextColor ( ) - ,m_aTextLineColor ( ) - ,m_aRowColors ( ) - ,m_eVerticalAlign ( VerticalAlignment_TOP ) - ,bEnabled ( true ) - { - pRenderer = std::make_shared<GridTableRenderer>( *this ); - pInputHandler = std::make_shared<DefaultInputHandler>(); - } - - - UnoControlTableModel::~UnoControlTableModel() - { - } - - - TableSize UnoControlTableModel::getColumnCount() const - { - DBG_CHECK_ME(); - return static_cast<TableSize>(aColumns.size()); - } - - - TableSize UnoControlTableModel::getRowCount() const - { - DBG_CHECK_ME(); - - TableSize nRowCount = 0; - try - { - Reference< XGridDataModel > const xDataModel( m_aDataModel ); - ENSURE_OR_THROW( xDataModel.is(), "no data model anymore!" ); - nRowCount = xDataModel->getRowCount(); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("svtools.uno"); - } - return nRowCount; - } - - - bool UnoControlTableModel::hasColumnHeaders() const - { - DBG_CHECK_ME(); - return bHasColumnHeaders; - } - - - bool UnoControlTableModel::hasRowHeaders() const - { - DBG_CHECK_ME(); - return bHasRowHeaders; - } - - - void UnoControlTableModel::setRowHeaders(bool _bRowHeaders) - { - DBG_CHECK_ME(); - if ( bHasRowHeaders == _bRowHeaders ) - return; - - bHasRowHeaders = _bRowHeaders; - impl_notifyTableMetricsChanged(); - } - - - void UnoControlTableModel::setColumnHeaders(bool _bColumnHeaders) - { - DBG_CHECK_ME(); - if ( bHasColumnHeaders == _bColumnHeaders ) - return; - - bHasColumnHeaders = _bColumnHeaders; - impl_notifyTableMetricsChanged(); - } - - - PColumnModel UnoControlTableModel::getColumnModel( ColPos column ) - { - DBG_CHECK_ME(); - ENSURE_OR_RETURN( ( column >= 0 ) && ( column < getColumnCount() ), - "DefaultTableModel::getColumnModel: invalid index!", PColumnModel() ); - return aColumns[ column ]; - } - - - void UnoControlTableModel::appendColumn( Reference< XGridColumn > const & i_column ) - { - DBG_CHECK_ME(); - insertColumn( aColumns.size(), i_column ); - } - - - void UnoControlTableModel::insertColumn( ColPos const i_position, Reference< XGridColumn > const & i_column ) - { - DBG_CHECK_ME(); - ENSURE_OR_RETURN_VOID( ( i_position >= 0 ) && ( o3tl::make_unsigned( i_position ) <= aColumns.size() ), - "UnoControlTableModel::insertColumn: illegal position!" ); - - const PColumnModel pColumn = std::make_shared<UnoGridColumnFacade>( *this, i_column ); - aColumns.insert( aColumns.begin() + i_position, pColumn ); - - // notify listeners - ModellListeners aListeners( m_aListeners ); - for (auto const& listener : aListeners) - { - listener->columnInserted(); - } - } - - - void UnoControlTableModel::removeColumn( ColPos const i_position ) - { - DBG_CHECK_ME(); - ENSURE_OR_RETURN_VOID( ( i_position >= 0 ) && ( o3tl::make_unsigned( i_position ) <= aColumns.size() ), - "UnoControlTableModel::removeColumn: illegal position!" ); - - // remove the column - ColumnModels::iterator pos = aColumns.begin() + i_position; - const PColumnModel pColumn = *pos; - aColumns.erase( pos ); - - // notify listeners - ModellListeners aListeners( m_aListeners ); - for (auto const& listener : aListeners) - { - listener->columnRemoved(); - } - - // dispose the column - UnoGridColumnFacade* pColumnImpl = dynamic_cast< UnoGridColumnFacade* >( pColumn.get() ); - OSL_ENSURE( pColumnImpl != nullptr, "UnoControlTableModel::removeColumn: illegal column implementation!" ); - if ( pColumnImpl ) - pColumnImpl->dispose(); - } - - - void UnoControlTableModel::removeAllColumns() - { - DBG_CHECK_ME(); - if ( aColumns.empty() ) - return; - - // dispose the column instances - for (auto const& col : aColumns) - { - UnoGridColumnFacade* pColumn = dynamic_cast< UnoGridColumnFacade* >( col.get() ); - if ( !pColumn ) - { - SAL_WARN( "svtools.uno", "UnoControlTableModel::removeAllColumns: illegal column implementation!" ); - continue; - } - - pColumn->dispose(); - } - aColumns.clear(); - - // notify listeners - ModellListeners aListeners( m_aListeners ); - for (auto const& listener : aListeners) - { - listener->allColumnsRemoved(); - } - } - - - void UnoControlTableModel::impl_notifyTableMetricsChanged() const - { - ModellListeners aListeners( m_aListeners ); - for (auto const& listener : aListeners) - { - listener->tableMetricsChanged(); - } - } - - - PTableRenderer UnoControlTableModel::getRenderer() const - { - DBG_CHECK_ME(); - return pRenderer; - } - - - PTableInputHandler UnoControlTableModel::getInputHandler() const - { - DBG_CHECK_ME(); - return pInputHandler; - } - - - TableMetrics UnoControlTableModel::getRowHeight() const - { - DBG_CHECK_ME(); - return nRowHeight; - } - - - void UnoControlTableModel::setRowHeight(TableMetrics _nRowHeight) - { - DBG_CHECK_ME(); - if ( nRowHeight == _nRowHeight ) - return; - - nRowHeight = _nRowHeight; - impl_notifyTableMetricsChanged(); - } - - - TableMetrics UnoControlTableModel::getColumnHeaderHeight() const - { - DBG_CHECK_ME(); - DBG_ASSERT( hasColumnHeaders(), "DefaultTableModel::getColumnHeaderHeight: invalid call!" ); - return nColumnHeaderHeight; - } - - - TableMetrics UnoControlTableModel::getRowHeaderWidth() const - { - DBG_CHECK_ME(); - DBG_ASSERT( hasRowHeaders(), "DefaultTableModel::getRowHeaderWidth: invalid call!" ); - return nRowHeaderWidth; - } - - void UnoControlTableModel::setColumnHeaderHeight(TableMetrics _nHeight) - { - DBG_CHECK_ME(); - if ( nColumnHeaderHeight == _nHeight ) - return; - - nColumnHeaderHeight = _nHeight; - impl_notifyTableMetricsChanged(); - } - - - void UnoControlTableModel::setRowHeaderWidth(TableMetrics _nWidth) - { - DBG_CHECK_ME(); - if ( nRowHeaderWidth == _nWidth ) - return; - - nRowHeaderWidth = _nWidth; - impl_notifyTableMetricsChanged(); - } - - - ScrollbarVisibility UnoControlTableModel::getVerticalScrollbarVisibility() const - { - DBG_CHECK_ME(); - return eVScrollMode; - } - - - ScrollbarVisibility UnoControlTableModel::getHorizontalScrollbarVisibility() const - { - DBG_CHECK_ME(); - return eHScrollMode; - } - - - void UnoControlTableModel::addTableModelListener( const PTableModelListener& i_listener ) - { - DBG_CHECK_ME(); - ENSURE_OR_RETURN_VOID( !!i_listener, "illegal NULL listener" ); - m_aListeners.push_back( i_listener ); - } - - - void UnoControlTableModel::removeTableModelListener( const PTableModelListener& i_listener ) - { - DBG_CHECK_ME(); - auto lookup = std::find(m_aListeners.begin(), m_aListeners.end(), i_listener); - if (lookup != m_aListeners.end()) - { - m_aListeners.erase( lookup ); - return; - } - OSL_ENSURE( false, "UnoControlTableModel::removeTableModelListener: listener is not registered - sure you're doing the right thing here?" ); - } - - - void UnoControlTableModel::setVerticalScrollbarVisibility( ScrollbarVisibility const i_visibility ) - { - DBG_CHECK_ME(); - eVScrollMode = i_visibility; - } - - - void UnoControlTableModel::setHorizontalScrollbarVisibility( ScrollbarVisibility const i_visibility ) - { - DBG_CHECK_ME(); - eHScrollMode = i_visibility; - } - - - void UnoControlTableModel::setDataModel( Reference< XGridDataModel > const & i_gridDataModel ) - { - DBG_CHECK_ME(); - m_aDataModel = i_gridDataModel; - // TODO: register as listener, so we're notified of row/data changes, and can multiplex them to our - // own listeners - } - - - Reference< XGridDataModel > UnoControlTableModel::getDataModel() const - { - Reference< XGridDataModel > const xDataModel( m_aDataModel ); - return xDataModel; - } - - - bool UnoControlTableModel::hasDataModel() const - { - return getDataModel().is(); - } - - - void UnoControlTableModel::setColumnModel( Reference< XGridColumnModel > const & i_gridColumnModel ) - { - DBG_CHECK_ME(); - m_aColumnModel = i_gridColumnModel; - } - - - Reference< XGridColumnModel > UnoControlTableModel::getColumnModel() const - { - Reference< XGridColumnModel > const xColumnModel( m_aColumnModel ); - return xColumnModel; - } - - - bool UnoControlTableModel::hasColumnModel() const - { - return getColumnModel().is(); - } - - - void UnoControlTableModel::getCellContent( ColPos const i_col, RowPos const i_row, Any& o_cellContent ) - { - DBG_CHECK_ME(); - - o_cellContent.clear(); - try - { - Reference< XGridDataModel > const xDataModel( m_aDataModel ); - ENSURE_OR_RETURN_VOID( xDataModel.is(), "UnoControlTableModel::getCellContent: no data model anymore!" ); - - PColumnModel const pColumn = getColumnModel( i_col ); - UnoGridColumnFacade* pColumnImpl = dynamic_cast< UnoGridColumnFacade* >( pColumn.get() ); - ENSURE_OR_RETURN_VOID( pColumnImpl != nullptr, "UnoControlTableModel::getCellContent: no (valid) column at this position!" ); - sal_Int32 const nDataColumnIndex = pColumnImpl->getDataColumnIndex() >= 0 ? pColumnImpl->getDataColumnIndex() : i_col; - - if ( nDataColumnIndex >= xDataModel->getColumnCount() ) - { - // this is allowed, in case the column model has been dynamically extended, but the data model does - // not (yet?) know about it. - // So, handle it gracefully. - #if OSL_DEBUG_LEVEL > 0 - Reference< XGridColumnModel > const xColumnModel( m_aColumnModel ); - OSL_ENSURE( xColumnModel.is() && i_col < xColumnModel->getColumnCount(), - "UnoControlTableModel::getCellContent: request a column's value which the ColumnModel doesn't know about!" ); - #endif - } - else - { - o_cellContent = xDataModel->getCellData( nDataColumnIndex, i_row ); - } - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("svtools.uno"); - } - } - - - void UnoControlTableModel::getCellToolTip( ColPos const i_col, RowPos const i_row, Any& o_cellToolTip ) - { - DBG_CHECK_ME(); - try - { - Reference< XGridDataModel > const xDataModel( m_aDataModel ); - ENSURE_OR_THROW( xDataModel.is(), "no data model anymore!" ); - - o_cellToolTip = xDataModel->getCellToolTip( i_col, i_row ); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("svtools.uno"); - } - } - - - Any UnoControlTableModel::getRowHeading( RowPos const i_rowPos ) const - { - DBG_CHECK_ME(); - - Any aRowHeading; - - Reference< XGridDataModel > const xDataModel( m_aDataModel ); - ENSURE_OR_RETURN( xDataModel.is(), "UnoControlTableModel::getRowHeading: no data model anymore!", aRowHeading ); - - try - { - aRowHeading = xDataModel->getRowHeading( i_rowPos ); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("svtools.uno"); - } - return aRowHeading; - } - - - namespace - { - void lcl_setColor( Any const & i_color, ::std::optional< ::Color > & o_convertedColor ) - { - if ( !i_color.hasValue() ) - o_convertedColor.reset(); - else - { - Color nColor = COL_TRANSPARENT; - if ( i_color >>= nColor ) - { - o_convertedColor = nColor; - } - else - { - OSL_ENSURE( false, "lcl_setColor: could not extract color value!" ); - } - } - } - } - - - ::std::optional< ::Color > UnoControlTableModel::getLineColor() const - { - DBG_CHECK_ME(); - return m_aGridLineColor; - } - - - void UnoControlTableModel::setLineColor( Any const & i_color ) - { - DBG_CHECK_ME(); - lcl_setColor( i_color, m_aGridLineColor ); - } - - - ::std::optional< ::Color > UnoControlTableModel::getHeaderBackgroundColor() const - { - DBG_CHECK_ME(); - return m_aHeaderBackgroundColor; - } - - - void UnoControlTableModel::setHeaderBackgroundColor( Any const & i_color ) - { - DBG_CHECK_ME(); - lcl_setColor( i_color, m_aHeaderBackgroundColor ); - } - - - ::std::optional< ::Color > UnoControlTableModel::getHeaderTextColor() const - { - DBG_CHECK_ME(); - return m_aHeaderTextColor; - } - - - ::std::optional< ::Color > UnoControlTableModel::getActiveSelectionBackColor() const - { - DBG_CHECK_ME(); - return m_aActiveSelectionBackColor; - } - - - ::std::optional< ::Color > UnoControlTableModel::getInactiveSelectionBackColor() const - { - DBG_CHECK_ME(); - return m_aInactiveSelectionBackColor; - } - - - ::std::optional< ::Color > UnoControlTableModel::getActiveSelectionTextColor() const - { - DBG_CHECK_ME(); - return m_aActiveSelectionTextColor; - } - - - ::std::optional< ::Color > UnoControlTableModel::getInactiveSelectionTextColor() const - { - DBG_CHECK_ME(); - return m_aInactiveSelectionTextColor; - } - - - void UnoControlTableModel::setHeaderTextColor( Any const & i_color ) - { - DBG_CHECK_ME(); - lcl_setColor( i_color, m_aHeaderTextColor ); - } - - - void UnoControlTableModel::setActiveSelectionBackColor( Any const & i_color ) - { - DBG_CHECK_ME(); - lcl_setColor( i_color, m_aActiveSelectionBackColor ); - } - - - void UnoControlTableModel::setInactiveSelectionBackColor( Any const & i_color ) - { - DBG_CHECK_ME(); - lcl_setColor( i_color, m_aInactiveSelectionBackColor ); - } - - - void UnoControlTableModel::setActiveSelectionTextColor( Any const & i_color ) - { - DBG_CHECK_ME(); - lcl_setColor( i_color, m_aActiveSelectionTextColor ); - } - - - void UnoControlTableModel::setInactiveSelectionTextColor( Any const & i_color ) - { - DBG_CHECK_ME(); - lcl_setColor( i_color, m_aInactiveSelectionTextColor ); - } - - - ::std::optional< ::Color > UnoControlTableModel::getTextColor() const - { - DBG_CHECK_ME(); - return m_aTextColor; - } - - - void UnoControlTableModel::setTextColor( Any const & i_color ) - { - DBG_CHECK_ME(); - lcl_setColor( i_color, m_aTextColor ); - } - - - ::std::optional< ::Color > UnoControlTableModel::getTextLineColor() const - { - DBG_CHECK_ME(); - return m_aTextColor; - } - - - void UnoControlTableModel::setTextLineColor( Any const & i_color ) - { - DBG_CHECK_ME(); - lcl_setColor( i_color, m_aTextLineColor ); - } - - - ::std::optional< ::std::vector< ::Color > > UnoControlTableModel::getRowBackgroundColors() const - { - DBG_CHECK_ME(); - return m_aRowColors; - } - - - void UnoControlTableModel::setRowBackgroundColors( css::uno::Any const & i_APIValue ) - { - DBG_CHECK_ME(); - Sequence< css::util::Color > aAPIColors; - if ( !( i_APIValue >>= aAPIColors ) ) - m_aRowColors.reset(); - else - { - ::std::vector< ::Color > aColors( aAPIColors.getLength() ); - std::transform(std::cbegin(aAPIColors), std::cend(aAPIColors), aColors.begin(), - [](const css::util::Color& rAPIColor) -> ::Color { return Color(ColorTransparency, rAPIColor); }); - m_aRowColors = aColors; - } - } - - - VerticalAlignment UnoControlTableModel::getVerticalAlign() const - { - DBG_CHECK_ME(); - return m_eVerticalAlign; - } - - - void UnoControlTableModel::setVerticalAlign( VerticalAlignment _xAlign ) - { - DBG_CHECK_ME(); - m_eVerticalAlign = _xAlign; - } - - - ColPos UnoControlTableModel::getColumnPos( UnoGridColumnFacade const & i_column ) const - { - DBG_CHECK_ME(); - ColPos nPos = 0; - for (auto const& col : aColumns) - { - if ( &i_column == col.get() ) - return nPos; - ++nPos; - } - OSL_ENSURE( false, "UnoControlTableModel::getColumnPos: column not found!" ); - return COL_INVALID; - } - - - ITableDataSort* UnoControlTableModel::getSortAdapter() - { - DBG_CHECK_ME(); - - Reference< XSortableGridData > const xSortAccess( getDataModel(), UNO_QUERY ); - if ( xSortAccess.is() ) - return this; - return nullptr; - } - - - bool UnoControlTableModel::isEnabled() const - { - DBG_CHECK_ME(); - return bEnabled; - } - - - void UnoControlTableModel::setEnabled( bool _bEnabled ) - { - DBG_CHECK_ME(); - bEnabled = _bEnabled; - } - - - void UnoControlTableModel::sortByColumn( ColPos const i_column, ColumnSortDirection const i_sortDirection ) - { - DBG_CHECK_ME(); - - try - { - Reference< XSortableGridData > const xSortAccess( getDataModel(), UNO_QUERY_THROW ); - xSortAccess->sortByColumn( i_column, i_sortDirection == ColumnSortAscending ); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("svtools.uno"); - } - } - - - ColumnSort UnoControlTableModel::getCurrentSortOrder() const - { - DBG_CHECK_ME(); - - ColumnSort currentSort; - try - { - Reference< XSortableGridData > const xSortAccess( getDataModel(), UNO_QUERY_THROW ); - Pair< ::sal_Int32, sal_Bool > const aCurrentSortOrder( xSortAccess->getCurrentSortOrder() ); - currentSort.nColumnPos = aCurrentSortOrder.First; - currentSort.eSortDirection = aCurrentSortOrder.Second ? ColumnSortAscending : ColumnSortDescending; - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("svtools.uno"); - } - return currentSort; - } - - - void UnoControlTableModel::notifyColumnChange( ColPos const i_columnPos, ColumnAttributeGroup const i_attributeGroup ) const - { - DBG_CHECK_ME(); - ENSURE_OR_RETURN_VOID( ( i_columnPos >= 0 ) && ( i_columnPos < getColumnCount() ), - "UnoControlTableModel::notifyColumnChange: invalid column index!" ); - - ModellListeners aListeners( m_aListeners ); - for (auto const& listener : aListeners) - { - listener->columnChanged( i_columnPos, i_attributeGroup ); - } - } - - - void UnoControlTableModel::notifyRowsInserted( GridDataEvent const & i_event ) const - { - // check sanity of the event - ENSURE_OR_RETURN_VOID( i_event.FirstRow >= 0, "UnoControlTableModel::notifyRowsInserted: invalid first row!" ); - ENSURE_OR_RETURN_VOID( i_event.LastRow >= i_event.FirstRow, "UnoControlTableModel::notifyRowsInserted: invalid row indexes!" ); - - // check own sanity - Reference< XGridColumnModel > const xColumnModel( m_aColumnModel ); - ENSURE_OR_RETURN_VOID( xColumnModel.is(), "UnoControlTableModel::notifyRowsInserted: no column model anymore!" ); - - Reference< XGridDataModel > const xDataModel( m_aDataModel ); - ENSURE_OR_RETURN_VOID( xDataModel.is(), "UnoControlTableModel::notifyRowsInserted: no data model anymore!" ); - - // implicitly add columns to the column model - // TODO: is this really a good idea? - sal_Int32 const dataColumnCount = xDataModel->getColumnCount(); - OSL_ENSURE( dataColumnCount > 0, "UnoControlTableModel::notifyRowsInserted: no columns at all?" ); - - sal_Int32 const modelColumnCount = xColumnModel->getColumnCount(); - if ( ( modelColumnCount == 0 ) && ( dataColumnCount > 0 ) ) - { - // TODO: shouldn't we clear the mutexes guard for this call? - xColumnModel->setDefaultColumns( dataColumnCount ); - } - - // multiplex the event to our own listeners - ModellListeners aListeners( m_aListeners ); - for (auto const& listener : aListeners) - { - listener->rowsInserted( i_event.FirstRow, i_event.LastRow ); - } - } - - - void UnoControlTableModel::notifyRowsRemoved( GridDataEvent const & i_event ) const - { - ModellListeners aListeners( m_aListeners ); - for (auto const& listener : aListeners) - { - listener->rowsRemoved( i_event.FirstRow, i_event.LastRow ); - } - } - - - void UnoControlTableModel::notifyDataChanged( css::awt::grid::GridDataEvent const & i_event ) const - { - RowPos const firstRow = i_event.FirstRow == -1 ? 0 : i_event.FirstRow; - RowPos const lastRow = i_event.FirstRow == -1 ? getRowCount() - 1 : i_event.LastRow; - - ModellListeners aListeners( m_aListeners ); - for (auto const& listener : aListeners) - { - listener->cellsUpdated( firstRow, lastRow ); - } - } - - - void UnoControlTableModel::notifyAllDataChanged() const - { - ModellListeners aListeners( m_aListeners ); - for (auto const& listener : aListeners) - { - listener->cellsUpdated( 0, getRowCount() - 1 ); - } - } - - -} // svt::table - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/uno/unocontroltablemodel.hxx b/svtools/source/uno/unocontroltablemodel.hxx deleted file mode 100644 index 4a69357626ae..000000000000 --- a/svtools/source/uno/unocontroltablemodel.hxx +++ /dev/null @@ -1,181 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <table/tablemodel.hxx> -#include <table/tablesort.hxx> -#include <tools/color.hxx> - -#include <com/sun/star/awt/grid/GridDataEvent.hpp> -#include <com/sun/star/awt/grid/XGridColumnModel.hpp> -#include <com/sun/star/awt/grid/XGridDataModel.hpp> -#include <com/sun/star/awt/grid/XGridColumn.hpp> -#include <com/sun/star/awt/grid/XGridColumn.hpp> -#include <com/sun/star/style/VerticalAlignment.hpp> -#include <cppuhelper/weakref.hxx> - - -namespace svt::table -{ - - - //= UnoControlTableModel - - class UnoGridColumnFacade; - class UnoControlTableModel : public ITableModel, public ITableDataSort - { - public: - UnoControlTableModel(); - virtual ~UnoControlTableModel() override; - - public: - // ITableModel overridables - virtual TableSize getColumnCount() const override; - virtual TableSize getRowCount() const override; - virtual bool hasColumnHeaders() const override; - virtual bool hasRowHeaders() const override; - virtual PColumnModel getColumnModel( ColPos column ) override; - virtual PTableRenderer getRenderer() const override; - virtual PTableInputHandler getInputHandler() const override; - virtual TableMetrics getRowHeight() const override; - virtual TableMetrics getColumnHeaderHeight() const override; - virtual TableMetrics getRowHeaderWidth() const override; - virtual ScrollbarVisibility getVerticalScrollbarVisibility() const override; - virtual ScrollbarVisibility getHorizontalScrollbarVisibility() const override; - virtual void addTableModelListener( const PTableModelListener& i_listener ) override; - virtual void removeTableModelListener( const PTableModelListener& i_listener ) override; - virtual void getCellContent( ColPos const i_col, RowPos const i_row, css::uno::Any& o_cellContent ) override; - virtual void getCellToolTip( ColPos const i_col, RowPos const i_row, css::uno::Any & o_cellToolTip ) override; - virtual css::uno::Any getRowHeading( RowPos const i_rowPos ) const override; - virtual ::std::optional< ::Color > getLineColor() const override; - virtual ::std::optional< ::Color > getHeaderBackgroundColor() const override; - virtual ::std::optional< ::Color > getHeaderTextColor() const override; - virtual ::std::optional< ::Color > getActiveSelectionBackColor() const override; - virtual ::std::optional< ::Color > getInactiveSelectionBackColor() const override; - virtual ::std::optional< ::Color > getActiveSelectionTextColor() const override; - virtual ::std::optional< ::Color > getInactiveSelectionTextColor() const override; - virtual ::std::optional< ::Color > getTextColor() const override; - virtual ::std::optional< ::Color > getTextLineColor() const override; - virtual ::std::optional< ::std::vector< ::Color > > - getRowBackgroundColors() const override; - virtual css::style::VerticalAlignment - getVerticalAlign() const override; - virtual ITableDataSort* getSortAdapter() override; - virtual bool isEnabled() const override; - - // ITableDataSort overridables - virtual void sortByColumn( ColPos const i_column, ColumnSortDirection const i_sortDirection ) override; - virtual ColumnSort getCurrentSortOrder() const override; - - // column write access - void appendColumn( css::uno::Reference< css::awt::grid::XGridColumn > const & i_column ); - void insertColumn( ColPos const i_position, css::uno::Reference< css::awt::grid::XGridColumn > const & i_column ); - void removeColumn( ColPos const i_position ); - void removeAllColumns(); - - // other operations - void setVerticalScrollbarVisibility( ScrollbarVisibility const i_visibility ); - void setHorizontalScrollbarVisibility( ScrollbarVisibility const i_visibility ); - - void setDataModel( css::uno::Reference< css::awt::grid::XGridDataModel > const & i_gridDataModel ); - bool hasDataModel() const; - css::uno::Reference< css::awt::grid::XGridDataModel > - getDataModel() const; - void setColumnModel( css::uno::Reference< css::awt::grid::XGridColumnModel > const & i_gridColumnModel ); - bool hasColumnModel() const; - css::uno::Reference< css::awt::grid::XGridColumnModel > - getColumnModel() const; - - void setRowHeaders(bool _bRowHeaders); - void setColumnHeaders(bool _bColumnHeaders); - - void setRowHeight( TableMetrics _nHeight ); - void setRowHeaderWidth( TableMetrics _nWidth ); - void setColumnHeaderHeight( TableMetrics _nHeight ); - - void setLineColor( css::uno::Any const & i_color ); - void setHeaderBackgroundColor( css::uno::Any const & i_color ); - void setHeaderTextColor( css::uno::Any const & i_color ); - void setActiveSelectionBackColor( css::uno::Any const & i_color ); - void setInactiveSelectionBackColor( css::uno::Any const & i_color ); - void setActiveSelectionTextColor( css::uno::Any const & i_color ); - void setInactiveSelectionTextColor( css::uno::Any const & i_color ); - void setTextColor( css::uno::Any const & i_color ); - void setTextLineColor( css::uno::Any const & i_color ); - void setRowBackgroundColors( css::uno::Any const & i_APIValue ); - - void setVerticalAlign(css::style::VerticalAlignment _rAlign); - void setEnabled( bool _bEnabled ); - - // multiplexing of XGridDataListener events - void notifyRowsInserted( css::awt::grid::GridDataEvent const & i_event ) const; - void notifyRowsRemoved( css::awt::grid::GridDataEvent const & i_event ) const; - void notifyDataChanged( css::awt::grid::GridDataEvent const & i_event ) const; - - /// retrieves the index of a column within the model - ColPos getColumnPos( UnoGridColumnFacade const & i_column ) const; - - /// notifies a change in a column belonging to the model - void notifyColumnChange( ColPos const i_columnPos, ColumnAttributeGroup const i_attributeGroup ) const; - - /** notifies a change in all data represented by the model. To be used if you cannot specified the changed data - in more detail. - */ - void notifyAllDataChanged() const; - - private: - void impl_notifyTableMetricsChanged() const; - - typedef ::std::vector< PTableModelListener > ModellListeners; - typedef ::std::vector< PColumnModel > ColumnModels; - - ColumnModels aColumns; - bool bHasColumnHeaders; - bool bHasRowHeaders; - ScrollbarVisibility eVScrollMode; - ScrollbarVisibility eHScrollMode; - PTableRenderer pRenderer; - PTableInputHandler pInputHandler; - TableMetrics nRowHeight; - TableMetrics nColumnHeaderHeight; - TableMetrics nRowHeaderWidth; - ::std::optional< ::Color > m_aGridLineColor; - ::std::optional< ::Color > m_aHeaderBackgroundColor; - ::std::optional< ::Color > m_aHeaderTextColor; - ::std::optional< ::Color > m_aActiveSelectionBackColor; - ::std::optional< ::Color > m_aInactiveSelectionBackColor; - ::std::optional< ::Color > m_aActiveSelectionTextColor; - ::std::optional< ::Color > m_aInactiveSelectionTextColor; - ::std::optional< ::Color > m_aTextColor; - ::std::optional< ::Color > m_aTextLineColor; - ::std::optional< ::std::vector< ::Color > > m_aRowColors; - css::style::VerticalAlignment m_eVerticalAlign; - bool bEnabled; - ModellListeners m_aListeners; - css::uno::WeakReference< css::awt::grid::XGridDataModel > m_aDataModel; - css::uno::WeakReference< css::awt::grid::XGridColumnModel > m_aColumnModel; - }; - - -} // svt::table - - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/uno/unogridcolumnfacade.cxx b/svtools/source/uno/unogridcolumnfacade.cxx deleted file mode 100644 index c41600ceee3b..000000000000 --- a/svtools/source/uno/unogridcolumnfacade.cxx +++ /dev/null @@ -1,310 +0,0 @@ -/* -*- 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 "unogridcolumnfacade.hxx" -#include "unocontroltablemodel.hxx" - -#include <com/sun/star/awt/grid/XGridColumn.hpp> -#include <com/sun/star/awt/grid/XGridColumnListener.hpp> - -#include <tools/debug.hxx> -#include <tools/diagnose_ex.h> -#include <vcl/svapp.hxx> -#include <cppuhelper/implbase.hxx> - - -namespace svt::table -{ - - - using css::uno::Reference; - using css::awt::grid::XGridColumn; - using css::uno::Exception; - using css::awt::grid::XGridColumnListener; - using css::lang::EventObject; - using css::awt::grid::GridColumnEvent; - using css::style::HorizontalAlignment_LEFT; - using css::style::HorizontalAlignment; - - - namespace - { - template< class T1, class T2 > - void lcl_set( Reference< XGridColumn > const & i_column, void ( SAL_CALL XGridColumn::*i_setter )( T1 ), - T2 i_value ) - { - try - { - (i_column.get()->*i_setter) ( i_value ); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("svtools.uno"); - } - } - - template< class ATTRIBUTE_TYPE > - ATTRIBUTE_TYPE lcl_get( Reference< XGridColumn > const & i_column, ATTRIBUTE_TYPE ( SAL_CALL XGridColumn::*i_getter )() ) - { - ATTRIBUTE_TYPE value = ATTRIBUTE_TYPE(); - try - { - value = (i_column.get()->*i_getter)(); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("svtools.uno"); - } - return value; - } - } - - - //= ColumnChangeMultiplexer - - typedef ::cppu::WeakImplHelper < XGridColumnListener - > ColumnChangeMultiplexer_Base; - class ColumnChangeMultiplexer :public ColumnChangeMultiplexer_Base - { - public: - explicit ColumnChangeMultiplexer( UnoGridColumnFacade& i_colImpl ); - ColumnChangeMultiplexer(const ColumnChangeMultiplexer&) = delete; - ColumnChangeMultiplexer& operator=(const ColumnChangeMultiplexer&) = delete; - - void dispose(); - - protected: - virtual ~ColumnChangeMultiplexer() override; - - // XGridColumnListener - virtual void SAL_CALL columnChanged( const GridColumnEvent& i_event ) override; - - // XEventListener - virtual void SAL_CALL disposing( const EventObject& i_event ) override; - - private: - UnoGridColumnFacade* m_pColumnImplementation; - }; - - - ColumnChangeMultiplexer::ColumnChangeMultiplexer( UnoGridColumnFacade& i_colImpl ) - :m_pColumnImplementation( &i_colImpl ) - { - } - - - ColumnChangeMultiplexer::~ColumnChangeMultiplexer() - { - } - - - void ColumnChangeMultiplexer::dispose() - { - DBG_TESTSOLARMUTEX(); - m_pColumnImplementation = nullptr; - } - - - void SAL_CALL ColumnChangeMultiplexer::columnChanged( const GridColumnEvent& i_event ) - { - if ( i_event.AttributeName == "DataColumnIndex" ) - { - SolarMutexGuard aGuard; - if ( m_pColumnImplementation != nullptr ) - m_pColumnImplementation->dataColumnIndexChanged(); - return; - } - - ColumnAttributeGroup nChangedAttributes( ColumnAttributeGroup::NONE ); - - if ( i_event.AttributeName == "HorizontalAlign" ) - nChangedAttributes |= ColumnAttributeGroup::APPEARANCE; - - if ( i_event.AttributeName == "ColumnWidth" - || i_event.AttributeName == "MaxWidth" - || i_event.AttributeName == "MinWidth" - || i_event.AttributeName == "PreferredWidth" - || i_event.AttributeName == "Resizeable" - || i_event.AttributeName == "Flexibility" - ) - nChangedAttributes |= ColumnAttributeGroup::WIDTH; - - OSL_ENSURE( nChangedAttributes != ColumnAttributeGroup::NONE, - "ColumnChangeMultiplexer::columnChanged: unknown column attributed changed!" ); - - SolarMutexGuard aGuard; - if ( m_pColumnImplementation != nullptr ) - m_pColumnImplementation->columnChanged( nChangedAttributes ); - } - - - void SAL_CALL ColumnChangeMultiplexer::disposing( const EventObject& ) - { - } - - - //= UnoGridColumnFacade - - - UnoGridColumnFacade::UnoGridColumnFacade( UnoControlTableModel const & i_owner, Reference< XGridColumn > const & i_gridColumn ) - :m_pOwner( &i_owner ) - ,m_nDataColumnIndex( -1 ) - ,m_xGridColumn( i_gridColumn, css::uno::UNO_SET_THROW ) - ,m_pChangeMultiplexer( new ColumnChangeMultiplexer( *this ) ) - { - m_xGridColumn->addGridColumnListener( m_pChangeMultiplexer ); - impl_updateDataColumnIndex_nothrow(); - } - - - UnoGridColumnFacade::~UnoGridColumnFacade() - { - } - - - void UnoGridColumnFacade::dispose() - { - DBG_TESTSOLARMUTEX(); - ENSURE_OR_RETURN_VOID( m_pOwner != nullptr, "UnoGridColumnFacade::dispose: already disposed!" ); - - m_xGridColumn->removeGridColumnListener( m_pChangeMultiplexer ); - m_pChangeMultiplexer->dispose(); - m_pChangeMultiplexer.clear(); - m_xGridColumn.clear(); - m_pOwner = nullptr; - } - - - void UnoGridColumnFacade::impl_updateDataColumnIndex_nothrow() - { - m_nDataColumnIndex = -1; - ENSURE_OR_RETURN_VOID( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!" ); - try - { - m_nDataColumnIndex = m_xGridColumn->getDataColumnIndex(); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("svtools.uno"); - } - } - - - void UnoGridColumnFacade::dataColumnIndexChanged() - { - DBG_TESTSOLARMUTEX(); - impl_updateDataColumnIndex_nothrow(); - if ( m_pOwner != nullptr ) - m_pOwner->notifyAllDataChanged(); - } - - - void UnoGridColumnFacade::columnChanged( ColumnAttributeGroup const i_attributeGroup ) - { - DBG_TESTSOLARMUTEX(); - if ( m_pOwner != nullptr ) - m_pOwner->notifyColumnChange( m_pOwner->getColumnPos( *this ), i_attributeGroup ); - } - - - OUString UnoGridColumnFacade::getName() const - { - OUString sName; - ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", sName ); - try - { - sName = m_xGridColumn->getTitle(); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("svtools.uno"); - } - return sName; - } - - - OUString UnoGridColumnFacade::getHelpText() const - { - OUString sHelpText; - ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", sHelpText ); - try - { - sHelpText = m_xGridColumn->getHelpText(); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("svtools.uno"); - } - return sHelpText; - } - - - bool UnoGridColumnFacade::isResizable() const - { - ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", false ); - return lcl_get( m_xGridColumn, &XGridColumn::getResizeable ); - } - - - sal_Int32 UnoGridColumnFacade::getFlexibility() const - { - ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", 1 ); - return lcl_get( m_xGridColumn, &XGridColumn::getFlexibility ); - } - - - TableMetrics UnoGridColumnFacade::getWidth() const - { - ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", 0 ); - return lcl_get( m_xGridColumn, &XGridColumn::getColumnWidth ); - } - - - void UnoGridColumnFacade::setWidth( TableMetrics _nWidth ) - { - ENSURE_OR_RETURN_VOID( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!" ); - lcl_set( m_xGridColumn, &XGridColumn::setColumnWidth, _nWidth ); - } - - - TableMetrics UnoGridColumnFacade::getMinWidth() const - { - ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", 0 ); - return lcl_get( m_xGridColumn, &XGridColumn::getMinWidth ); - } - - - TableMetrics UnoGridColumnFacade::getMaxWidth() const - { - ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", 0 ); - return lcl_get( m_xGridColumn, &XGridColumn::getMaxWidth ); - } - - - css::style::HorizontalAlignment UnoGridColumnFacade::getHorizontalAlign() - { - ENSURE_OR_RETURN( m_xGridColumn.is(), "UnoGridColumnFacade: already disposed!", HorizontalAlignment_LEFT ); - return lcl_get( m_xGridColumn, &XGridColumn::getHorizontalAlign ); - } - - -} // svt::table - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/uno/unogridcolumnfacade.hxx b/svtools/source/uno/unogridcolumnfacade.hxx deleted file mode 100644 index 672397276b90..000000000000 --- a/svtools/source/uno/unogridcolumnfacade.hxx +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- 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 . - */ - -#pragma once - -#include <table/tablemodel.hxx> - -#include <com/sun/star/awt/grid/XGridColumn.hpp> -#include <com/sun/star/style/HorizontalAlignment.hpp> - -#include <rtl/ref.hxx> - - -namespace svt::table -{ - - - //= UnoGridColumnFacade - - class ColumnChangeMultiplexer; - class UnoControlTableModel; - class UnoGridColumnFacade :public IColumnModel - { - public: - UnoGridColumnFacade( - UnoControlTableModel const & i_owner, - css::uno::Reference< css::awt::grid::XGridColumn > const & i_gridColumn - ); - virtual ~UnoGridColumnFacade() override; - UnoGridColumnFacade(const UnoGridColumnFacade&) = delete; - UnoGridColumnFacade& operator=(const UnoGridColumnFacade&) = delete; - - // IColumnModel overridables - virtual OUString getName() const override; - virtual OUString getHelpText() const override; - virtual bool isResizable() const override; - virtual sal_Int32 getFlexibility() const override; - virtual TableMetrics getWidth() const override; - virtual void setWidth( TableMetrics _nWidth ) override; - virtual TableMetrics getMinWidth() const override; - virtual TableMetrics getMaxWidth() const override; - virtual css::style::HorizontalAlignment getHorizontalAlign() override; - - /** disposes the column wrapper - - Note that the XGridColumn which is wrapped by the instance is <strong>not</strong> disposed, as we - do not own it. - */ - void dispose(); - - sal_Int32 - getDataColumnIndex() const { return m_nDataColumnIndex; } - - // callbacks for the XGridColumnListener - void columnChanged( ColumnAttributeGroup const i_attributeGroup ); - void dataColumnIndexChanged(); - - private: - void impl_updateDataColumnIndex_nothrow(); - - private: - UnoControlTableModel const * m_pOwner; - sal_Int32 m_nDataColumnIndex; - css::uno::Reference< css::awt::grid::XGridColumn > m_xGridColumn; - ::rtl::Reference< ColumnChangeMultiplexer > m_pChangeMultiplexer; - }; - - -} // svt::table - - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/uno/unoiface.cxx b/svtools/source/uno/unoiface.cxx deleted file mode 100644 index 71bc18150c08..000000000000 --- a/svtools/source/uno/unoiface.cxx +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- 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 <unoiface.hxx> -#include "svtxgridcontrol.hxx" -#include <table/tablecontrol.hxx> - -// help function for the toolkit... - -extern "C" { - -SAL_DLLPUBLIC_EXPORT vcl::Window* CreateWindow( rtl::Reference<VCLXWindow>* ppNewComp, const css::awt::WindowDescriptor* pDescriptor, vcl::Window* pParent, WinBits nWinBits ) -{ - vcl::Window* pWindow = nullptr; - OUString aServiceName( pDescriptor->WindowServiceName ); - if ( aServiceName.equalsIgnoreAsciiCase( "Grid" ) ) - { - if ( pParent ) - { - pWindow = VclPtr< ::svt::table::TableControl>::Create(pParent, nWinBits); - *ppNewComp = new SVTXGridControl; - } - else - { - *ppNewComp = nullptr; - return nullptr; - } - } - return pWindow; -} - -} // extern "C" - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |