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 #ifndef INCLUDED_SVX_SOURCE_INC_FMEXCH_HXX
20 #define INCLUDED_SVX_SOURCE_INC_FMEXCH_HXX
21 
22 #include <sal/config.h>
23 
24 #include <set>
25 
26 #include <sot/exchange.hxx>
27 #include <vcl/transfer.hxx>
28 #include <com/sun/star/uno/Sequence.hxx>
29 #include <com/sun/star/container/XNameContainer.hpp>
30 #include <com/sun/star/form/XForms.hpp>
31 #include <rtl/ref.hxx>
32 #include <tools/link.hxx>
33 #include <vcl/window.hxx>
34 #include <svx/svxdllapi.h>
35 
36 class SvTreeListEntry;
37 class SvTreeListBox;
38 
39 namespace svxform
40 {
41 
42 
43     typedef ::std::set< SvTreeListEntry* >  ListBoxEntrySet;
44 
45 
46     //= OLocalExchange
47 
48     class SVX_DLLPUBLIC OLocalExchange : public TransferableHelper
49     {
50     private:
51         Link<OLocalExchange&,void>  m_aClipboardListener;
52         bool            m_bDragging         : 1;
53         bool            m_bClipboardOwner   : 1;
54 
55     public:
56         class GrantAccess
57         {
58             friend class OLocalExchangeHelper;
59         };
60 
61     public:
62         OLocalExchange( );
63 
isDragging() const64         bool        isDragging() const { return m_bDragging; }
isClipboardOwner() const65         bool        isClipboardOwner() const { return m_bClipboardOwner; }
66 
67         void        startDrag( vcl::Window* pWindow, sal_Int8 nDragSourceActions, const GrantAccess& );
68         void        copyToClipboard( vcl::Window* _pWindow, const GrantAccess& );
69 
setClipboardListener(const Link<OLocalExchange &,void> & _rListener)70         void        setClipboardListener( const Link<OLocalExchange&,void>& _rListener ) { m_aClipboardListener = _rListener; }
71 
72         void        clear();
73 
74         static  bool    hasFormat( const DataFlavorExVector& _rFormats, SotClipboardFormatId _nFormatId );
75 
76     protected:
77         // XClipboardOwner
78         virtual void SAL_CALL lostOwnership( const css::uno::Reference< css::datatransfer::clipboard::XClipboard >& _rxClipboard, const css::uno::Reference< css::datatransfer::XTransferable >& _rxTrans ) override;
79 
80         // TransferableHelper
81         virtual void        DragFinished( sal_Int8 nDropAction ) override;
82         virtual bool GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& rDestDoc ) override;
83 
84     private:
85          // don't allow this base class method to be called from outside
86         using TransferableHelper::StartDrag;
87     };
88 
89 
90     //= OLocalExchangeHelper
91 
92     /// a helper for navigator windows (SvTreeListBox'es) which allow DnD within themself
93     class SVX_DLLPUBLIC OLocalExchangeHelper
94     {
95     protected:
96         VclPtr<vcl::Window>            m_pDragSource;
97         rtl::Reference<OLocalExchange> m_xTransferable;
98 
99     public:
100         OLocalExchangeHelper( vcl::Window* _pDragSource );
101         virtual ~OLocalExchangeHelper();
102 
103         void        prepareDrag( );
104 
105         void        startDrag( sal_Int8 nDragSourceActions );
106         void        copyToClipboard( ) const;
107 
isDragSource() const108         bool    isDragSource() const { return m_xTransferable.is() && m_xTransferable->isDragging(); }
isClipboardOwner() const109         bool    isClipboardOwner() const { return m_xTransferable.is() && m_xTransferable->isClipboardOwner(); }
isDataExchangeActive() const110         bool    isDataExchangeActive( ) const { return isDragSource() || isClipboardOwner(); }
clear()111         void        clear() { if ( isDataExchangeActive() ) m_xTransferable->clear(); }
112 
setClipboardListener(const Link<OLocalExchange &,void> & _rListener)113         SVX_DLLPRIVATE void     setClipboardListener( const Link<OLocalExchange&,void>& _rListener ) { if ( m_xTransferable.is() ) m_xTransferable->setClipboardListener( _rListener ); }
114 
115     protected:
116         SVX_DLLPRIVATE virtual OLocalExchange* createExchange() const = 0;
117 
118     protected:
119         SVX_DLLPRIVATE void implReset();
120     };
121 
122     class OControlTransferData
123     {
124     private:
125         DataFlavorExVector  m_aCurrentFormats;
126 
127     protected:
128         ListBoxEntrySet     m_aSelectedEntries;
129         css::uno::Sequence< css::uno::Sequence< sal_uInt32 > >
130                             m_aControlPaths;
131         css::uno::Sequence< css::uno::Reference< css::uno::XInterface > >
132                             m_aHiddenControlModels;
133 
134         css::uno::Reference< css::form::XForms >
135                             m_xFormsRoot;       // the root of the forms collection where the entries we represent reside
136                                                 // this uniquely identifies the page and the document
137 
138         SvTreeListEntry*        m_pFocusEntry;
139 
140     protected:
141         // updates m_aCurrentFormats with all formats we currently could supply
142         void    updateFormats( );
143 
144     public:
145         OControlTransferData( );
146 
147         // ctor to construct the data from an arbitrary Transferable (usually clipboard data)
148         OControlTransferData(
149             const css::uno::Reference< css::datatransfer::XTransferable >& _rxTransferable
150         );
151 
152         inline const DataFlavorExVector&    GetDataFlavorExVector() const;
153 
154         void addSelectedEntry( SvTreeListEntry* _pEntry );
155         void setFocusEntry( SvTreeListEntry* _pFocusEntry );
156 
157         /** notifies the data transfer object that a certain entry has been removed from the owning tree
158 
159             In case the removed entry is part of the transfer object's selection, the entry is removed from
160             the selection.
161 
162             @param  _pEntry
163             @return the number of entries remaining in the selection.
164         */
165         size_t  onEntryRemoved( SvTreeListEntry* _pEntry );
166 
setFormsRoot(const css::uno::Reference<css::form::XForms> & _rxFormsRoot)167         void setFormsRoot(
168             const css::uno::Reference< css::form::XForms >& _rxFormsRoot
169             ) { m_xFormsRoot = _rxFormsRoot; }
170 
171         void buildPathFormat(SvTreeListBox const * pTreeBox, SvTreeListEntry const * pRoot);
172             // assembles m_aControlPaths from m_aSelectedEntries
173             // (it is assumed that the entries are sorted in m_aSelectedEntries with respect to the neighbor relationship)
174 
175 
176         void buildListFromPath(SvTreeListBox const * pTreeBox, SvTreeListEntry* pRoot);
177             // The reverse way: throws everything out of m_aSelectedEntries and rebuilds it using m_aControlPaths
178 
179         void addHiddenControlsFormat(const css::uno::Sequence< css::uno::Reference< css::uno::XInterface > >& seqInterfaces);
180             // adds an SVX_FML_HIDDEN_CONTROLS format and remembers the passed interfaces for it
181             // (it is NOT checked whether actually only hidden controls are denominated
182             // by this - the caller must ensure that)
183 
selected() const184         const ListBoxEntrySet&      selected() const { return m_aSelectedEntries; }
185         const css::uno::Sequence< css::uno::Reference< css::uno::XInterface > >&
hiddenControls() const186                                     hiddenControls() const { return m_aHiddenControlModels; }
187 
188         const css::uno::Reference< css::form::XForms >&
getFormsRoot() const189                                 getFormsRoot() const { return m_xFormsRoot; }
190     };
191 
192 
GetDataFlavorExVector() const193     inline const DataFlavorExVector& OControlTransferData::GetDataFlavorExVector() const
194     {
195         const_cast< OControlTransferData* >( this )->updateFormats( );
196         return m_aCurrentFormats;
197     }
198 
199     class OControlExchange : public OLocalExchange, public OControlTransferData
200     {
201     public:
202         OControlExchange( );
203 
204     public:
205         static SotClipboardFormatId getFieldExchangeFormatId( );
206         static SotClipboardFormatId getControlPathFormatId( );
207         static SotClipboardFormatId getHiddenControlModelsFormatId( );
208 
209         inline static bool  hasFieldExchangeFormat( const DataFlavorExVector& _rFormats );
210         inline static bool  hasControlPathFormat( const DataFlavorExVector& _rFormats );
211         inline static bool  hasHiddenControlModelsFormat( const DataFlavorExVector& _rFormats );
212 
213     protected:
214         virtual bool GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& rDestDoc ) override;
215         virtual void        AddSupportedFormats() override;
216     };
217 
218     class OControlExchangeHelper : public OLocalExchangeHelper
219     {
220     public:
OControlExchangeHelper(vcl::Window * _pDragSource)221         OControlExchangeHelper(vcl::Window* _pDragSource) : OLocalExchangeHelper(_pDragSource) { }
222 
operator ->() const223         OControlExchange* operator->() const { return static_cast< OControlExchange* >( m_xTransferable.get() ); }
operator *() const224         OControlExchange& operator*() const { return *static_cast< OControlExchange* >( m_xTransferable.get() ); }
225 
226     protected:
227         virtual OLocalExchange* createExchange() const override;
228     };
229 
230 
hasFieldExchangeFormat(const DataFlavorExVector & _rFormats)231     inline bool OControlExchange::hasFieldExchangeFormat( const DataFlavorExVector& _rFormats )
232     {
233         return hasFormat( _rFormats, getFieldExchangeFormatId() );
234     }
235 
hasControlPathFormat(const DataFlavorExVector & _rFormats)236     inline bool OControlExchange::hasControlPathFormat( const DataFlavorExVector& _rFormats )
237     {
238         return hasFormat( _rFormats, getControlPathFormatId() );
239     }
240 
hasHiddenControlModelsFormat(const DataFlavorExVector & _rFormats)241     inline bool OControlExchange::hasHiddenControlModelsFormat( const DataFlavorExVector& _rFormats )
242     {
243         return hasFormat( _rFormats, getHiddenControlModelsFormatId() );
244     }
245 
246 
247 }
248 
249 
250 #endif
251 
252 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
253