1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
23 #include "brwctrlr.hxx"
24 #include <com/sun/star/frame/XStatusListener.hpp>
25 #include <com/sun/star/frame/XDispatch.hpp>
26 #include <com/sun/star/i18n/XCollator.hpp>
27 #include <com/sun/star/view/XSelectionSupplier.hpp>
28 #include <com/sun/star/awt/XWindow.hpp>
29 #include <com/sun/star/document/XScriptInvocationContext.hpp>
30 #include <com/sun/star/ui/XContextMenuInterception.hpp>
31 #include <com/sun/star/sdb/application/DatabaseObject.hpp>
32 #include <com/sun/star/sdb/application/DatabaseObjectContainer.hpp>
33 #include <com/sun/star/sdb/XDatabaseRegistrationsListener.hpp>
34 #include <comphelper/interfacecontainer2.hxx>
35 #include <cppuhelper/implbase5.hxx>
36 #include "callbacks.hxx"
38 #include <vcl/transfer.hxx>
39 #include <svx/dataaccessdescriptor.hxx>
40 #include "TableCopyHelper.hxx"
41 #include "commontypes.hxx"
46 namespace com::sun::star::container
{ class XNameContainer
; }
50 struct DBTreeEditedEntry
;
51 struct DBTreeListUserData
;
54 typedef ::cppu::ImplHelper5
< css::frame::XStatusListener
55 , css::view::XSelectionSupplier
56 , css::document::XScriptInvocationContext
57 , css::ui::XContextMenuInterception
58 , css::sdb::XDatabaseRegistrationsListener
59 > SbaTableQueryBrowser_Base
;
60 class SbaTableQueryBrowser final
61 :public SbaXDataBrowserController
62 ,public SbaTableQueryBrowser_Base
63 ,public IControlActionListener
64 ,public IContextMenuProvider
66 css::uno::Reference
< css::i18n::XCollator
> m_xCollator
;
67 css::uno::Reference
< css::frame::XFrame
> m_xCurrentFrameParent
;
68 css::uno::Reference
< css::awt::XWindow
> m_xMainToolbar
;
70 struct ExternalFeature
73 css::uno::Reference
< css::frame::XDispatch
>
77 ExternalFeature() : bEnabled( false ) { }
78 ExternalFeature( css::util::URL _aURL
) : aURL(std::move( _aURL
)), bEnabled( false ) { }
81 typedef std::map
< sal_uInt16
, ExternalFeature
> ExternalFeaturesMap
;
82 ExternalFeaturesMap m_aExternalFeatures
;
84 svx::ODataAccessDescriptor m_aDocumentDataSource
;
85 // if we're part of a document, this is the state of the DocumentDataSource slot
87 ::comphelper::OInterfaceContainerHelper2 m_aSelectionListeners
;
88 ::comphelper::OInterfaceContainerHelper2 m_aContextMenuInterceptors
;
90 OTableCopyHelper::DropDescriptor m_aAsyncDrop
;
91 OTableCopyHelper m_aTableCopyHelper
;
93 OUString m_sQueryCommand
; // the command of the query currently loaded (if any)
94 //OUString m_sToBeLoaded; // contains the element name which should be loaded if any
96 VclPtr
<InterimDBTreeListBox
> m_pTreeView
; // contains the datasources of the registry
97 VclPtr
<Splitter
> m_pSplitter
;
98 std::unique_ptr
<weld::TreeIter
> m_xCurrentlyDisplayed
;
99 ImplSVEvent
* m_nAsyncDrop
;
101 bool m_bQueryEscapeProcessing
: 1; // the escape processing flag of the query currently loaded (if any)
102 bool m_bShowMenu
; // if sal_True the menu should be visible otherwise not
104 bool m_bEnableBrowser
;
105 ::std::optional
< bool >
106 m_aDocScriptSupport
; // relevant if and only if we are associated with exactly one DBDoc
108 virtual OUString
getPrivateTitle( ) const override
;
111 SbaTableQueryBrowser(const css::uno::Reference
< css::uno::XComponentContext
>& _rM
);
112 virtual ~SbaTableQueryBrowser() override
;
116 // don't change the above definitions! There are places (in particular SbaTableQueryBrowser::getCurrentSelection)
117 // which rely on the fact that the EntryType values really equal the DatabaseObject(Container) values!
118 etDatasource
= css::sdb::application::DatabaseObjectContainer::DATA_SOURCE
,
119 etQueryContainer
= css::sdb::application::DatabaseObjectContainer::QUERIES
,
120 etTableContainer
= css::sdb::application::DatabaseObjectContainer::TABLES
,
121 etQuery
= css::sdb::application::DatabaseObject::QUERY
,
122 etTableOrView
= css::sdb::application::DatabaseObject::TABLE
,
126 /** returns a DatabaseObject value corresponding to the given EntryType
128 the entry type. Must not be etUnknown.
130 static sal_Int32
getDatabaseObjectType( EntryType _eType
);
132 DECLARE_UNO3_DEFAULTS(SbaTableQueryBrowser
,SbaXDataBrowserController
)
134 virtual bool Construct(vcl::Window
* pParent
) override
;
136 virtual css::uno::Any SAL_CALL
queryInterface(const css::uno::Type
& _rType
) override
;
139 virtual css::uno::Sequence
< css::uno::Type
> SAL_CALL
getTypes( ) override
;
140 virtual css::uno::Sequence
< sal_Int8
> SAL_CALL
getImplementationId( ) override
;
142 // css::beans::XPropertyChangeListener
143 virtual void SAL_CALL
propertyChange(const css::beans::PropertyChangeEvent
& evt
) override
;
145 // css::frame::XController
146 virtual sal_Bool SAL_CALL
suspend(sal_Bool bSuspend
) override
;
147 virtual void SAL_CALL
attachFrame(const css::uno::Reference
< css::frame::XFrame
> & xFrame
) override
;
149 // css::lang::XComponent
150 virtual void SAL_CALL
disposing() override
;
153 virtual void SAL_CALL
statusChanged( const css::frame::FeatureStateEvent
& Event
) override
;
156 virtual void SAL_CALL
disposing( const css::lang::EventObject
& Source
) override
;
158 // XSelectionSupplier
159 virtual sal_Bool SAL_CALL
select( const css::uno::Any
& aSelection
) override
;
160 virtual css::uno::Any SAL_CALL
getSelection( ) override
;
161 virtual void SAL_CALL
addSelectionChangeListener( const css::uno::Reference
< css::view::XSelectionChangeListener
>& xListener
) override
;
162 virtual void SAL_CALL
removeSelectionChangeListener( const css::uno::Reference
< css::view::XSelectionChangeListener
>& xListener
) override
;
165 virtual OUString SAL_CALL
getImplementationName() override
;
166 virtual css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
;
168 // XContainerListener
169 virtual void SAL_CALL
elementInserted( const css::container::ContainerEvent
& Event
) override
;
170 virtual void SAL_CALL
elementRemoved( const css::container::ContainerEvent
& Event
) override
;
171 virtual void SAL_CALL
elementReplaced( const css::container::ContainerEvent
& Event
) override
;
172 // css::frame::XFrameActionListener
173 virtual void SAL_CALL
frameAction(const css::frame::FrameActionEvent
& aEvent
) override
;
175 // XScriptInvocationContext
176 virtual css::uno::Reference
< css::document::XEmbeddedScripts
> SAL_CALL
getScriptContainer() override
;
178 // XContextMenuInterception
179 virtual void SAL_CALL
registerContextMenuInterceptor( const css::uno::Reference
< css::ui::XContextMenuInterceptor
>& Interceptor
) override
;
180 virtual void SAL_CALL
releaseContextMenuInterceptor( const css::uno::Reference
< css::ui::XContextMenuInterceptor
>& Interceptor
) override
;
182 // XDatabaseRegistrationsListener
183 virtual void SAL_CALL
registeredDatabaseLocation( const css::sdb::DatabaseRegistrationEvent
& Event
) override
;
184 virtual void SAL_CALL
revokedDatabaseLocation( const css::sdb::DatabaseRegistrationEvent
& Event
) override
;
185 virtual void SAL_CALL
changedDatabaseLocation( const css::sdb::DatabaseRegistrationEvent
& Event
) override
;
188 // SbaXDataBrowserController overridable
189 virtual bool InitializeForm( const css::uno::Reference
< css::beans::XPropertySet
>& i_formProperties
) override
;
191 void InitializeGridModel(const css::uno::Reference
< css::form::XFormComponent
> & xGrid
);
193 virtual bool preReloadForm() override
;
194 virtual void postReloadForm() override
;
196 virtual void addModelListeners(const css::uno::Reference
< css::awt::XControlModel
> & _xGridControlModel
) override
;
197 virtual void removeModelListeners(const css::uno::Reference
< css::awt::XControlModel
> & _xGridControlModel
) override
;
199 virtual void AddColumnListener(const css::uno::Reference
< css::beans::XPropertySet
> & xCol
) override
;
200 virtual void RemoveColumnListener(const css::uno::Reference
< css::beans::XPropertySet
> & xCol
) override
;
202 virtual void LoadFinished(bool _bWasSynch
) override
;
204 virtual void criticalFail() override
;
206 virtual void describeSupportedFeatures() override
;
207 virtual FeatureState
GetState(sal_uInt16 nId
) const override
;
208 virtual void Execute(sal_uInt16 nId
, const css::uno::Sequence
< css::beans::PropertyValue
>& aArgs
) override
;
210 // IControlActionListener overridables
211 virtual bool requestQuickHelp(const void* pUserData
, OUString
& rText
) const override
;
212 virtual bool requestDrag(const weld::TreeIter
& rEntry
) override
;
213 virtual sal_Int8
queryDrop( const AcceptDropEvent
& _rEvt
, const DataFlavorExVector
& _rFlavors
) override
;
214 virtual sal_Int8
executeDrop( const ExecuteDropEvent
& _rEvt
) override
;
216 // IContextMenuProvider
217 virtual OUString
getContextMenuResourceName() const override
;
218 virtual IController
& getCommandController() override
;
219 virtual ::comphelper::OInterfaceContainerHelper2
*
220 getContextMenuInterceptors() override
;
221 virtual css::uno::Any
getCurrentSelection(weld::TreeView
& rControl
) const override
;
222 virtual vcl::Window
* getMenuParent() const override
;
223 virtual void adjustMenuPosition(const weld::TreeView
& rControl
, ::Point
& rPos
) const override
;
225 virtual void impl_initialize(const ::comphelper::NamedValueCollection
& rArguments
) override
;
227 // SbaGridListener overridables
228 virtual void RowChanged() override
;
229 virtual void ColumnChanged() override
;
230 virtual void SelectionChanged() override
;
232 // methods for showing/hiding the explorer part
233 bool haveExplorer() const;
236 void toggleExplorer() { if (haveExplorer()) hideExplorer(); else showExplorer(); }
238 // methods for handling the 'selection' (painting them bold) of SvLBoxEntries
239 // returns <TRUE/> if the entry is selected (which means it's part of the selected path)
240 bool isSelected(const weld::TreeIter
& rEntry
) const;
241 // select the entry (and only the entry, not the whole path)
242 void select(const weld::TreeIter
* pEntry
, bool bSelect
);
243 // select the path of the entry (which must be an entry without children)
244 void selectPath(const weld::TreeIter
* pEntry
, bool bSelect
= true);
246 virtual void loadMenu(const css::uno::Reference
< css::frame::XFrame
>& _xFrame
) override
;
248 // check the state of the external slot given, update any UI elements if necessary
249 void implCheckExternalSlot( sal_uInt16 _nId
);
251 // connect to the external dispatchers (if any)
252 void connectExternalDispatches();
254 /** get the state of an external slot
255 <p>The slot is available if an external dispatcher is responsible for it, _and_ if this dispatcher
256 told us the slot is available.</p>
258 bool getExternalSlotState( sal_uInt16 _nId
) const;
260 /** add an entry (including the subentries for queries/tables) to the list model
262 <p>The given names and images may be empty, in this case they're filled with the correct
263 values. This way they may be reused for the next call, which saves some resource manager calls.</p>
265 void implAddDatasource(const OUString
& _rDbName
, OUString
& _rDbImage
,
266 OUString
& _rQueryName
, OUString
& _rQueryImage
,
267 OUString
& _rTableName
, OUString
& _rTableImage
,
268 const SharedConnection
& _rxConnection
271 void implAddDatasource( const OUString
& _rDataSourceName
, const SharedConnection
& _rxConnection
);
273 /// removes (and cleans up) the entry for the given data source
274 void impl_cleanupDataSourceEntry( std::u16string_view _rDataSourceName
);
276 /// clears the tree list box
277 void clearTreeModel();
279 /** unloads the form, empties the grid model, cleans up anything related to the currently displayed object
280 @param _bDisposeConnection
281 <TRUE/> if the connection should be disposed
283 <TRUE/> if the currently displayed object (if any) should be flushed
285 void unloadAndCleanup( bool _bDisposeConnection
= true );
287 // disposes the connection associated with the given entry (which must represent a data source)
288 void disposeConnection(const weld::TreeIter
* xpDSEntry
);
290 /// flushes and disposes the given connection, and de-registers as listener
291 void impl_releaseConnection( SharedConnection
& _rxConnection
);
293 /** close the connection (and collapse the list entries) of the given list entries
295 void closeConnection(const weld::TreeIter
& rEntry
, bool bDisposeConnection
= true);
297 void populateTree(const css::uno::Reference
< css::container::XNameAccess
>& xNameAccess
, const weld::TreeIter
& rParent
, EntryType eEntryType
);
298 void initializeTreeModel();
300 /** search in the tree for query- or tablecontainer equal to this interface and return
303 std::unique_ptr
<weld::TreeIter
> getEntryFromContainer(const css::uno::Reference
<css::container::XNameAccess
>& rxNameAccess
);
305 // return true when there is connection available
306 bool ensureConnection(const weld::TreeIter
* pDSEntry
, void * pDSData
, SharedConnection
& rConnection
);
307 bool ensureConnection(const weld::TreeIter
* pAnyEntry
, SharedConnection
& rConnection
);
309 bool getExistentConnectionFor(const weld::TreeIter
* pDSEntry
, SharedConnection
& rConnection
);
310 /** returns an image provider which works with the connection belonging to the given entry
312 std::unique_ptr
<ImageProvider
> getImageProviderFor(const weld::TreeIter
* pAnyEntry
);
314 void implAdministrate(const weld::TreeIter
& rApplyTo
);
316 bool implCopyObject(ODataClipboard
& rExchange
, const weld::TreeIter
& rApplyTo
, sal_Int32 nCommandType
);
318 EntryType
getEntryType(const weld::TreeIter
& rEntry
) const;
319 EntryType
getChildType(const weld::TreeIter
& rEntry
) const;
320 static bool isObject( EntryType _eType
) { return ( etTableOrView
== _eType
) || ( etQuery
== _eType
); }
321 static bool isContainer( EntryType _eType
) { return (etTableContainer
== _eType
) || (etQueryContainer
== _eType
); }
322 bool isContainer(const weld::TreeIter
& rEntry
) const { return isContainer(getEntryType(rEntry
)); }
324 // ensure that the xObject for the given entry is set on the user data
325 bool ensureEntryObject(const weld::TreeIter
& rEntry
);
327 // get the display text of the entry given
328 OUString
GetEntryText(const weld::TreeIter
& rEntry
) const;
330 // is called when a table or a query was selected
331 DECL_LINK( OnSelectionChange
, LinkParamNone
*, void );
332 DECL_LINK( OnExpandEntry
, const weld::TreeIter
&, bool );
334 DECL_LINK( OnCopyEntry
, LinkParamNone
*, void );
336 int OnTreeEntryCompare(const weld::TreeIter
& rLHS
, const weld::TreeIter
& rRHS
);
338 DECL_LINK( OnAsyncDrop
, void*, void );
340 void implRemoveStatusListeners();
342 bool implSelect(const svx::ODataAccessDescriptor
& _rDescriptor
, bool _bSelectDirect
= false);
343 bool implSelect(const weld::TreeIter
* pEntry
);
345 /// selects the entry given and loads the grid control with the object's data
347 const OUString
& _rDataSourceName
,
348 const OUString
& _rCommand
,
349 const sal_Int32 _nCommandType
,
350 const bool _bEscapeProcessing
,
351 const SharedConnection
& _rxConnection
,
355 std::unique_ptr
<weld::TreeIter
> implGetConnectionEntry(const weld::TreeIter
& rEntry
) const;
356 /// inserts an entry into the tree
357 std::unique_ptr
<weld::TreeIter
> implAppendEntry(
358 const weld::TreeIter
* pParent
,
359 const OUString
& rName
,
360 const DBTreeListUserData
* pUserData
);
362 /// loads the grid control with the data object specified (which may be a table, a query or a command)
363 bool implLoadAnything(const OUString
& _rDataSourceName
, const OUString
& _rCommand
,
364 const sal_Int32 _nCommandType
, const bool _bEscapeProcessing
, const SharedConnection
& _rxConnection
);
366 /** retrieves the tree entry for the object described by <arg>_rDescriptor</arg>
368 the object descriptor
369 @param ppDataSourceEntry
370 If not <NULL/>, the data source tree entry will be returned here
371 @param ppContainerEntry
372 If not <NULL/>, the object container tree entry will be returned here
374 std::unique_ptr
<weld::TreeIter
> getObjectEntry(const svx::ODataAccessDescriptor
& rDescriptor
,
375 std::unique_ptr
<weld::TreeIter
>* ppDataSourceEntry
, std::unique_ptr
<weld::TreeIter
>* ppContainerEntry
377 /** retrieves the tree entry for the object described by data source name, command and command type
385 the object descriptor
386 @param ppDataSourceEntry
387 If not <NULL/>, the data source tree entry will be returned here
388 @param ppContainerEntry
389 If not <NULL/>, the object container tree entry will be returned here
390 @param bExpandAncestors
391 If <TRUE/>, all ancestor on the way to the entry will be expanded
393 std::unique_ptr
<weld::TreeIter
> getObjectEntry(
394 const OUString
& rDataSource
, const OUString
& rCommand
, sal_Int32 nCommandType
,
395 std::unique_ptr
<weld::TreeIter
>* ppDataSourceEntry
, std::unique_ptr
<weld::TreeIter
>* ppContainerEntry
,
396 bool _bExpandAncestors
= true,
397 const SharedConnection
& rxConnection
= SharedConnection()
400 /// checks if m_aDocumentDataSource describes a known object
401 void checkDocumentDataSource();
403 static void extractDescriptorProps(const svx::ODataAccessDescriptor
& _rDescriptor
,
404 OUString
& _rDataSource
, OUString
& _rCommand
, sal_Int32
& _rCommandType
, bool& _rEscapeProcessing
);
406 void transferChangedControlProperty(const OUString
& _rProperty
, const css::uno::Any
& _rNewValue
);
408 // checks whether the given tree entry denotes a data source
409 bool impl_isDataSourceEntry(const weld::TreeIter
* pEntry
) const;
411 /// retrieves the data source URL/name for the given entry representing a data source
412 OUString
getDataSourceAccessor(const weld::TreeIter
& rDataSourceEntry
) const;
414 /** get the signature (command/escape processing) of the query the form is based on
415 <p>If the for is not based on a query or not even loaded, nothing happens and <FALSE/> is returned.</p>
417 bool implGetQuerySignature( OUString
& _rCommand
, bool& _bEscapeProcessing
);
419 bool isEntryCopyAllowed(const weld::TreeIter
& rEntry
) const;
421 void copyEntry(const weld::TreeIter
& rEntry
);
423 // remove all grid columns and dispose them
424 static void clearGridColumns(const css::uno::Reference
< css::container::XNameContainer
>& _xColContainer
);
426 /** checks if the currently displayed entry changed
428 Name of the changed entry
430 The container of the displayed entry
432 <TRUE/> if it is the currently displayed otherwise <FALSE/>
434 bool isCurrentlyDisplayedChanged(std::u16string_view rName
, const weld::TreeIter
& rContainer
);
436 /** called whenever the content of the browser is used for preview, as the very last action
439 void initializePreviewMode();
441 /** checks whether the Order/Filter clauses set at our row set are valid, removes them if not so
443 void impl_sanitizeRowSetClauses_nothrow();
448 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */