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