1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #pragma once
21 
22 #include <svx/fmgridcl.hxx>
23 
24 #include <svx/fmgridif.hxx>
25 
26 #include <com/sun/star/frame/XDispatch.hpp>
27 #include <com/sun/star/util/URL.hpp>
28 #include <comphelper/servicehelper.hxx>
29 #include <comphelper/uno3.hxx>
30 #include "sbamultiplex.hxx"
31 #include <svx/dataaccessdescriptor.hxx>
32 #include <rtl/ref.hxx>
33 #include <map>
34 #include <queue>
35 
36 class SvNumberFormatter;
37 
38 namespace com::sun::star {
39     namespace lang {
40         class XMultiServiceFactory;
41     }
42 }
43 
44 namespace dbaui
45 {
46     struct SbaURLCompare
47     {
operator ()dbaui::SbaURLCompare48         bool operator() (const css::util::URL& x, const css::util::URL& y) const { return x.Complete == y.Complete; }
49     };
50 
51     class SbaXStatusMultiplexer;
52     class SbaXGridControl
53                 :public FmXGridControl
54                 ,public css::frame::XDispatch
55     {
56         typedef std::map<css::util::URL, rtl::Reference<SbaXStatusMultiplexer>, SbaURLCompare> StatusMultiplexerArray;
57         StatusMultiplexerArray      m_aStatusMultiplexer;
58 
59     public:
60         SbaXGridControl(const css::uno::Reference< css::uno::XComponentContext >&);
61         virtual ~SbaXGridControl() override;
62 
63         // UNO
64         DECLARE_UNO3_DEFAULTS(SbaXGridControl, FmXGridControl)
65         virtual css::uno::Any  SAL_CALL queryInterface(const css::uno::Type& _rType) override;
66 
67         // XTypeProvider
68         virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes(  ) override;
69         virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId(  ) override;
70 
71         // css::lang::XServiceInfo
72         OUString SAL_CALL getImplementationName() override;
73         virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
74 
75         // css::frame::XDispatch
76         virtual void SAL_CALL dispatch(const css::util::URL& aURL, const css::uno::Sequence< css::beans::PropertyValue >& aArgs) override;
77         virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > & xControl, const css::util::URL& aURL) override;
78         virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener > & xControl, const css::util::URL& aURL) override;
79 
80         // css::lang::XComponent
81         virtual void SAL_CALL dispose() override;
82 
83         virtual void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > & rToolkit, const css::uno::Reference< css::awt::XWindowPeer > & rParentPeer) override;
84 
85     protected:
86         virtual rtl::Reference<FmXGridPeer> imp_CreatePeer(vcl::Window* pParent) override;
87     };
88 
89     // SbaXGridPeer
90 
91     class SbaXGridPeer final
92                 :public FmXGridPeer
93                 ,public css::frame::XDispatch
94     {
95         cppu::OMultiTypeInterfaceContainerHelperVar<
96             css::util::URL, void, SbaURLCompare>  m_aStatusListeners;
97 
98     public:
99         SbaXGridPeer(const css::uno::Reference< css::uno::XComponentContext >&);
100         virtual ~SbaXGridPeer() override;
101 
102         // UNO
acquire()103         virtual void SAL_CALL  acquire() noexcept override { FmXGridPeer::acquire(); }
release()104         virtual void SAL_CALL release() noexcept override { FmXGridPeer::release(); }
105         virtual css::uno::Any  SAL_CALL queryInterface(const css::uno::Type& _rType) override;
106 
107         virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override;
108 
109         UNO3_GETIMPLEMENTATION_DECL(SbaXGridPeer)
110 
111         // css::frame::XDispatch
112         virtual void SAL_CALL dispatch(const css::util::URL& aURL, const css::uno::Sequence< css::beans::PropertyValue >& aArgs) override;
113         virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > & xControl, const css::util::URL& aURL) override;
114         virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener > & xControl, const css::util::URL& aURL) override;
115 
116         // css::frame::XDispatchProvider
117         virtual css::uno::Reference< css::frame::XDispatch >  SAL_CALL queryDispatch(const css::util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags) override;
118 
119         // css::lang::XComponent
120         virtual void SAL_CALL dispose() override;
121 
122     private:
123         virtual VclPtr<FmGridControl>  imp_CreateControl(vcl::Window* pParent, WinBits nStyle) override;
124         void NotifyStatusChanged(const css::util::URL& aUrl, const css::uno::Reference< css::frame::XStatusListener > & xControl);
125 
126         // for any execution of XDispatch::dispatch
127         struct DispatchArgs
128         {
129             css::util::URL                                                 aURL;
130             css::uno::Sequence< css::beans::PropertyValue >   aArgs;
131         };
132         std::queue< DispatchArgs >    m_aDispatchArgs;
133         DECL_LINK( OnDispatchEvent, void*, void );
134 
135         // for dynamic states of our 4 dispatchable URLs
136         enum DispatchType
137         {
138             dtBrowserAttribs,
139             dtRowHeight,
140             dtColumnAttribs,
141             dtColumnWidth,
142 
143             dtUnknown
144         };
145         static DispatchType classifyDispatchURL( const css::util::URL& _rURL );
146 
147         typedef std::map<DispatchType, bool> MapDispatchToBool;
148         MapDispatchToBool   m_aDispatchStates;
149     };
150 
151     // SbaGridHeader
152 
153     class SbaGridHeader
154                 :public FmGridHeader
155                 ,public DragSourceHelper
156     {
157     public:
158         SbaGridHeader(BrowseBox* pParent);
159         virtual void dispose() override;
160         virtual ~SbaGridHeader() override;
161     protected:
162 
163         // FmGridHeader overridables
164         virtual void    PreExecuteColumnContextMenu(sal_uInt16 nColId, weld::Menu& rMenu,
165                                                     weld::Menu& rInsertMenu, weld::Menu& rChangeMenu,
166                                                     weld::Menu& rShowMenu) override;
167         virtual void    PostExecuteColumnContextMenu(sal_uInt16 nColId, const weld::Menu& rMenu, const OString& rExecutionResult) override;
168 
169     private:
170         // DragSourceHelper overridables
171         virtual void StartDrag( sal_Int8 _nAction, const Point& _rPosPixel ) override;
172 
173         // Window overridables
174         virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
175 
176         void ImplStartColumnDrag(sal_Int8 _nAction, const Point& _rMousePos);
177     };
178 
179     // interfaces for communication between the vcl grid control and a controller
180     class SbaGridListener
181     {
182     public:
183         virtual void RowChanged()       = 0;
184         virtual void ColumnChanged()    = 0;
185         virtual void SelectionChanged() = 0;
186         virtual void CellActivated()    = 0;
187         virtual void CellDeactivated()  = 0;
188         virtual void BeforeDrop()       = 0;
189         virtual void AfterDrop()        = 0;
190 
191     protected:
~SbaGridListener()192         ~SbaGridListener() {}
193     };
194 
195     // SbaGridControl
196     class SbaGridControl final : public FmGridControl
197     {
198         friend class SbaGridHeader;
199         friend class SbaXGridPeer;
200 
201     // Attributes
202         svx::ODataAccessDescriptor    m_aDataDescriptor;
203         SbaGridListener*              m_pMasterListener;
204 
205         ImplSVEvent *                 m_nAsyncDropEvent;
206 
207         bool                          m_bActivatingForDrop;
208 
209     public:
210         SbaGridControl(css::uno::Reference< css::uno::XComponentContext > const & _rM, Window* pParent, FmXGridPeer* _pPeer, WinBits nBits);
211         virtual ~SbaGridControl() override;
212         virtual void dispose() override;
213 
214         virtual void Select() override;
215 
SetMasterListener(SbaGridListener * pListener)216         void SetMasterListener(SbaGridListener* pListener)  { m_pMasterListener = pListener; }
217 
218         virtual void ActivateCell(sal_Int32 nRow, sal_uInt16 nCol, bool bSetCellFocus = true) override;
219         virtual void DeactivateCell(bool bUpdate = true) override;
220         using FmGridControl::ActivateCell;
221 
IsAllSelected() const222         bool IsAllSelected() const { return (GetSelectRowCount() == GetRowCount()) && (GetRowCount() > 0); }
223 
GetHeaderBar() const224         HeaderBar* GetHeaderBar() const { return FmGridControl::GetHeaderBar(); }
225 
226         /** return the description of the specified object.
227             @param  eObjType
228                 The type to ask for
229             @param  _nPosition
230                 The position of a tablecell (index position), header bar  column/row cell
231             @return
232                 The description of the specified object.
233         */
234         virtual OUString GetAccessibleObjectDescription( ::vcl::AccessibleBrowseBoxObjType eObjType,sal_Int32 _nPosition = -1) const override;
235 
236         using FmGridControl::DeleteSelectedRows;
237         /** copies the currently selected rows to the clipboard
238             @precond
239                 at least one row is selected
240         */
241         void CopySelectedRowsToClipboard();
242 
243     private:
244         // DragSourceHelper overridables
245         virtual void StartDrag( sal_Int8 _nAction, const Point& _rPosPixel ) override;
246 
247         // BrowseBox overridables
248         virtual sal_Int8 AcceptDrop( const BrowserAcceptDropEvent& rEvt ) override;
249         virtual sal_Int8 ExecuteDrop( const BrowserExecuteDropEvent& rEvt ) override;
250         virtual void    MouseButtonDown( const BrowserMouseEvent& rMEvt) override;
251 
252         // EditBrowseBox overridables
253         virtual VclPtr<BrowserHeader> imp_CreateHeaderBar(BrowseBox* pParent) override;
254         virtual ::svt::CellController* GetController(sal_Int32 nRow, sal_uInt16 nCol) override;
255 
256         // DbGridControl overridables
257         virtual void PreExecuteRowContextMenu(weld::Menu& rMenu) override;
258         virtual void PostExecuteRowContextMenu(const OString& rExecutionResult) override;
259 
260         // DbGridControl overridables
261         virtual void onRowChange() override;
262         virtual void onColumnChange() override;
263 
264         // get a fields property set from a model pos
265         css::uno::Reference< css::beans::XPropertySet >  getField(sal_uInt16 nModelPos);
266 
267         // get my data source
268         css::uno::Reference< css::beans::XPropertySet >  getDataSource() const;
269 
270         // drag events
271         void DoColumnDrag(sal_uInt16 nColumnPos);
272         void DoFieldDrag(sal_uInt16 nColumnPos, sal_Int16 nRowPos);
273 
274         void SetBrowserAttrs();
275         void SetColWidth(sal_uInt16 nColId);
276         void SetRowHeight();
277         void SetColAttrs(sal_uInt16 nColId);
278 
279         SvNumberFormatter* GetDatasourceFormatter();
280 
281         DECL_LINK(AsynchDropEvent, void*, void);
282 
283         bool IsReadOnlyDB() const;
284         void implTransferSelectedRows( sal_Int16 nRowPos, bool _bTrueIfClipboardFalseIfDrag );
285 
286         using FmGridControl::AcceptDrop;
287         using FmGridControl::ExecuteDrop;
288         using FmGridControl::MouseButtonDown;
289     };
290 }
291 
292 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
293