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 .
22 #include <AppElementType.hxx>
23 #include <callbacks.hxx>
24 #include <commontypes.hxx>
25 #include <dsntypes.hxx>
26 #include <dbaccess/genericcontroller.hxx>
27 #include <linkeddocuments.hxx>
28 #include <TableCopyHelper.hxx>
30 #include <com/sun/star/beans/XPropertyChangeListener.hpp>
31 #include <com/sun/star/container/XContainerListener.hpp>
32 #include <com/sun/star/sdb/application/XDatabaseDocumentUI.hpp>
33 #include <com/sun/star/ui/XContextMenuInterception.hpp>
35 #include <comphelper/namedvaluecollection.hxx>
36 #include <comphelper/uno3.hxx>
37 #include <cppuhelper/implbase5.hxx>
38 #include <comphelper/interfacecontainer2.hxx>
39 #include <vcl/transfer.hxx>
40 #include <svx/dataaccessdescriptor.hxx>
44 class TransferableHelper
;
45 class TransferableClipboardListener
;
47 namespace com::sun::star
{
59 class OComponentTransferable
;
71 class SubComponentManager
;
72 class OApplicationController
;
73 class OApplicationView
;
74 class OLinkedDocumentsAccess
;
75 class SelectionNotifier
;
77 typedef ::cppu::ImplHelper5
< css::container::XContainerListener
78 , css::beans::XPropertyChangeListener
79 , css::sdb::application::XDatabaseDocumentUI
80 , css::ui::XContextMenuInterception
81 , css::view::XSelectionSupplier
82 > OApplicationController_Base
;
85 class OApplicationController
86 :public OGenericUnoController
87 ,public OApplicationController_Base
88 ,public IControlActionListener
89 ,public IContextMenuProvider
92 typedef std::vector
< css::uno::Reference
< css::container::XContainer
> > TContainerVector
;
96 OTableCopyHelper::DropDescriptor m_aAsyncDrop
;
98 SharedConnection m_xDataSourceConnection
;
99 css::uno::Reference
< css::sdbc::XDatabaseMetaData
>
102 TransferableDataHelper m_aSystemClipboard
; // content of the clipboard
103 css::uno::Reference
< css::beans::XPropertySet
>
105 css::uno::Reference
< css::frame::XModel
>
107 ::comphelper::OInterfaceContainerHelper2
108 m_aContextMenuInterceptors
;
110 TContainerVector m_aCurrentContainers
; // the containers where we are listener on
111 ::rtl::Reference
< SubComponentManager
>
112 m_pSubComponentManager
;
113 ::dbaccess::ODsnTypeCollection
115 OTableCopyHelper m_aTableCopyHelper
;
116 rtl::Reference
<TransferableClipboardListener
>
117 m_pClipboardNotifier
; // notifier for changes in the clipboard
118 ImplSVEvent
* m_nAsyncDrop
;
119 OAsynchronousLink m_aSelectContainerEvent
;
120 PreviewMode m_ePreviewMode
; // the mode of the preview
121 ElementType m_eCurrentType
;
122 bool m_bNeedToReconnect
; // true when the settings of the data source were modified and the connection is no longer up to date
123 bool m_bSuspended
; // is true when the controller was already suspended
125 std::unique_ptr
< SelectionNotifier
>
126 m_pSelectionNotifier
;
127 typedef std::map
< ElementType
, std::vector
< OUString
> > SelectionByElementType
;
128 SelectionByElementType m_aPendingSelection
;
132 OApplicationView
* getContainer() const;
134 /** returns the database name
138 OUString
getDatabaseName() const;
140 /** return the element type for given container
141 @param _xContainer The container where the element type has to be found
142 @return the element type corresponding to the given container
144 static ElementType
getElementType(const css::uno::Reference
< css::container::XContainer
>& _xContainer
);
146 /** opens a new sub frame with a table/query/form/report/view, passing additional arguments
148 css::uno::Reference
< css::lang::XComponent
> openElementWithArguments(
149 const OUString
& _sName
,
151 ElementOpenMode _eOpenMode
,
152 sal_uInt16 _nInstigatorCommand
,
153 const ::comphelper::NamedValueCollection
& _rAdditionalArguments
156 /** opens a new frame for creation or auto pilot
158 Defines the type to open
159 @param i_rAdditionalArguments
160 Additional arguments to pass when creating the component
162 css::uno::Reference
< css::lang::XComponent
>
165 const ::comphelper::NamedValueCollection
& i_rAdditionalArguments
,
166 css::uno::Reference
< css::lang::XComponent
>& o_rDocumentDefinition
169 /** creates a new database object, using an auto pilot
171 Defines the type of the object to create
173 Our mutex must not be locked.
176 void newElementWithPilot( ElementType _eType
);
178 /** converts the query to a view
180 The name of the query.
182 void convertToView(const OUString
& _sName
);
184 /** checks if the connection for the selected data source is read only. If the connection doesn't exist, <TRUE/> will be returned.
186 <TRUE/> if read only or doesn't exist, otherwise <FALSE/>
188 bool isConnectionReadOnly() const;
190 /// fills the list with the selected entries.
191 void getSelectionElementNames( std::vector
< OUString
>& _rNames
) const;
193 /// deletes the entries selected.
194 void deleteEntries();
196 /// renames the selected entry in the detail page
199 /** deletes queries, forms, or reports
201 the type of the objects
203 The names of the elements to delete
205 determines whether the user must confirm the deletion
207 void deleteObjects( ElementType _eType
,
208 const std::vector
< OUString
>& _rList
,
215 void deleteTables(const std::vector
< OUString
>& _rList
);
217 /// copies the current object into clipboard
218 rtl::Reference
<TransferableHelper
> copyObject();
220 /// fills rExchange with current object if it's a Table or Query
221 bool copySQLObject(ODataClipboard
& rExchange
);
223 /// fills rExchange with current object if it's a Form or Report
224 bool copyDocObject(svx::OComponentTransferable
& rExchange
);
226 /// returns the nameaccess
227 css::uno::Reference
< css::container::XNameAccess
> getElements(ElementType _eType
);
229 /** returns the document access for the specific type
232 @return std::unique_ptr<OLinkedDocumentsAccess>
234 std::unique_ptr
<OLinkedDocumentsAccess
> getDocumentsAccess(ElementType _eType
);
236 /// returns the query definitions of the active data source.
237 css::uno::Reference
< css::container::XNameContainer
> getQueryDefinitions() const;
239 /** pastes a special format from the system clipboard to the currently selected object types
241 The format to be copied.
243 void pasteFormat(SotClipboardFormatId _nFormatId
);
245 /** pastes a query, form or report into the data source
247 The type of the object to paste.
250 @param _sParentFolder
251 The name of the parent folder if it exists.
253 if <TRUE/> the name of the content must be inserted without any change, otherwise not.
255 <TRUE/> if the paste operations was successful, otherwise <FALSE/>.
257 bool paste( ElementType _eType
, const svx::ODataAccessDescriptor
& _rPasteData
, const OUString
& _sParentFolder
= OUString(), bool _bMove
= false);
259 /// returns the system clipboard.
260 const TransferableDataHelper
& getViewClipboard() const { return m_aSystemClipboard
; }
262 /// returns <TRUE/> if the clipboard supports a table format, otherwise <FALSE/>.
263 bool isTableFormat() const;
265 /** fills the vector with all supported formats
267 The type for which we need the formats
269 The vector to be filled up.
271 static void getSupportedFormats(ElementType _eType
,std::vector
<SotClipboardFormatId
>& _rFormatIds
);
273 /** adds a listener to the current name access.
275 The collection where we want to listen on.
277 void addContainerListener(const css::uno::Reference
< css::container::XNameAccess
>& _xCollection
);
279 /** opens a uno dialog with the currently selected data source as initialize argument
281 The service name of the dialog to be executed.
283 void openDialog(const OUString
& _sServiceName
);
285 /** when the settings of the data source changed,
286 it opens a dialog which ask to close all depending documents, then recreate the connection.
287 The SolarMutex has to be locked before calling this.
289 void askToReconnect();
291 /** remember a newly opened sub document for later access
293 void onDocumentOpened(
294 const OUString
& _rName
,
295 const sal_Int32 _nType
,
296 const ElementOpenMode _eMode
,
297 const css::uno::Reference
< css::lang::XComponent
>& _xDocument
,
298 const css::uno::Reference
< css::lang::XComponent
>& _xDefinition
301 /** Inserts a new object into the hierarchy given be the type.
303 Where to insert the new item.
304 @param _sParentFolder
305 The name of the parent folder if it exists.
307 The content to insert.
309 if <TRUE/> the name of the content must be inserted without any change, otherwise not.
311 <TRUE/> if the insert operations was successful, otherwise <FALSE/>.
313 bool insertHierarchyElement( ElementType _eType
314 ,const OUString
& _sParentFolder
315 ,bool _bCollection
= true
316 ,const css::uno::Reference
< css::ucb::XContent
>& _xContent
= css::uno::Reference
< css::ucb::XContent
>()
317 ,bool _bMove
= false);
318 /** checks if delete command or rename command is allowed
322 If <TRUE> then the delete command should be checked.
324 <TRUE> if the command is allowed
326 bool isRenameDeleteAllowed(ElementType _eType
, bool _bDelete
) const;
327 /** all selected entries will be opened, or edited, or converted to a view
329 The slot which should be executed.
331 Defines the mode of opening. @see ElementOpenMode
333 void doAction(sal_uInt16 _nId
, ElementOpenMode _eOpenMode
);
335 /** returns the currently selected table or query name.
337 * \return the name of the currently table or query. If the tables or query container is selected otherwise an empty string will be returned.
339 OUString
getCurrentlySelectedName(sal_Int32
& _rnCommandType
) const;
341 /** shows the preview for the given entry
343 void showPreviewFor( const ElementType _eType
,const OUString
& _sName
);
345 /** called we were attached to a frame
347 In particular, this is called *after* the controller has been announced to the model
348 (XModel::connectController)
350 void onAttachedFrame();
352 /// determines whether the given table name denotes a view which can be altered
353 bool impl_isAlterableView_nothrow( const OUString
& _rTableOrViewName
) const;
355 /** verifies the object type denotes a valid DatabaseObject, and the object name denotes an existing
356 object of this type. Throws if not.
358 void impl_validateObjectTypeAndName_throw( const sal_Int32 _nObjectType
, const ::std::optional
< OUString
>& i_rObjectName
);
361 // initializing members
363 // state of a feature. 'feature' may be the handle of a css::util::URL somebody requested a dispatch interface for OR a toolbar slot.
364 virtual FeatureState
GetState(sal_uInt16 nId
) const override
;
366 virtual void Execute(sal_uInt16 nId
, const css::uno::Sequence
< css::beans::PropertyValue
>& aArgs
) override
;
368 // OGenericUnoController
369 virtual void onLoadedMenu( const css::uno::Reference
< css::frame::XLayoutManager
>& _xLayoutManager
) override
;
371 virtual css::uno::Reference
< css::frame::XModel
> getPrivateModel() const override
376 virtual ~OApplicationController() override
;
379 explicit OApplicationController(const css::uno::Reference
< css::uno::XComponentContext
>& _rxORB
);
381 DECLARE_XINTERFACE( )
382 DECLARE_XTYPEPROVIDER( )
385 virtual OUString SAL_CALL
getImplementationName() override
;
386 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
388 // css::frame::XController
389 virtual void SAL_CALL
attachFrame(const css::uno::Reference
< css::frame::XFrame
> & xFrame
) override
;
390 virtual sal_Bool SAL_CALL
suspend(sal_Bool bSuspend
) override
;
391 virtual sal_Bool SAL_CALL
attachModel(const css::uno::Reference
< css::frame::XModel
> & xModel
) override
;
392 virtual css::uno::Reference
< css::frame::XModel
> SAL_CALL
getModel() override
;
394 // css::container::XContainerListener
395 virtual void SAL_CALL
elementInserted(const css::container::ContainerEvent
& Event
) override
;
396 virtual void SAL_CALL
elementRemoved(const css::container::ContainerEvent
& Event
) override
;
397 virtual void SAL_CALL
elementReplaced(const css::container::ContainerEvent
& Event
) override
;
399 // XPropertyChangeListener
400 virtual void SAL_CALL
propertyChange( const css::beans::PropertyChangeEvent
& evt
) override
;
402 // XDatabaseDocumentUI
403 virtual css::uno::Reference
< css::sdbc::XDataSource
> SAL_CALL
getDataSource() override
;
404 virtual css::uno::Reference
< css::awt::XWindow
> SAL_CALL
getApplicationMainWindow() override
;
405 virtual css::uno::Reference
< css::sdbc::XConnection
> SAL_CALL
getActiveConnection() override
;
406 virtual css::uno::Sequence
< css::uno::Reference
< css::lang::XComponent
> > SAL_CALL
getSubComponents() override
;
407 virtual sal_Bool SAL_CALL
isConnected( ) override
;
408 // DO NOT CALL with getMutex() held!!
409 virtual void SAL_CALL
connect( ) override
;
410 virtual css::beans::Pair
< ::sal_Int32
, OUString
> SAL_CALL
identifySubComponent( const css::uno::Reference
< css::lang::XComponent
>& SubComponent
) override
;
411 virtual sal_Bool SAL_CALL
closeSubComponents( ) override
;
412 virtual css::uno::Reference
< css::lang::XComponent
> SAL_CALL
loadComponent( ::sal_Int32 ObjectType
, const OUString
& ObjectName
, sal_Bool ForEditing
) override
;
413 virtual css::uno::Reference
< css::lang::XComponent
> SAL_CALL
loadComponentWithArguments( ::sal_Int32 ObjectType
, const OUString
& ObjectName
, sal_Bool ForEditing
, const css::uno::Sequence
< css::beans::PropertyValue
>& Arguments
) override
;
414 virtual css::uno::Reference
< css::lang::XComponent
> SAL_CALL
createComponent( ::sal_Int32 ObjectType
, css::uno::Reference
< css::lang::XComponent
>& o_DocumentDefinition
) override
;
415 virtual css::uno::Reference
< css::lang::XComponent
> SAL_CALL
createComponentWithArguments( ::sal_Int32 ObjectType
, const css::uno::Sequence
< css::beans::PropertyValue
>& Arguments
, css::uno::Reference
< css::lang::XComponent
>& o_DocumentDefinition
) override
;
417 // XContextMenuInterception
418 virtual void SAL_CALL
registerContextMenuInterceptor( const css::uno::Reference
< css::ui::XContextMenuInterceptor
>& Interceptor
) override
;
419 virtual void SAL_CALL
releaseContextMenuInterceptor( const css::uno::Reference
< css::ui::XContextMenuInterceptor
>& Interceptor
) override
;
421 // XSelectionSupplier
422 virtual sal_Bool SAL_CALL
select( const css::uno::Any
& xSelection
) override
;
423 virtual css::uno::Any SAL_CALL
getSelection( ) override
;
424 virtual void SAL_CALL
addSelectionChangeListener( const css::uno::Reference
< css::view::XSelectionChangeListener
>& xListener
) override
;
425 virtual void SAL_CALL
removeSelectionChangeListener( const css::uno::Reference
< css::view::XSelectionChangeListener
>& xListener
) override
;
427 /** retrieves the current connection, creates it if necessary
429 If an error occurs, then this is either stored in the location pointed to by <arg>_pErrorInfo</arg>,
430 or, if <code>_pErrorInfo</code> is <NULL/>, then the error is displayed to the user.
432 DO NOT CALL with getMutex() held!!
434 const SharedConnection
& ensureConnection( ::dbtools::SQLExceptionInfo
* _pErrorInfo
= nullptr );
436 /** retrieves the current connection
438 const SharedConnection
& getConnection() const { return m_xDataSourceConnection
; }
440 /// determines whether we're currently connected to the database
441 bool isConnected() const { return m_xDataSourceConnection
.is(); }
443 /** refreshes the tables
445 void refreshTables();
447 /** called when an entry in a tree list box has been double-clicked
451 <TRUE/> if the double click event has been handled by the called, and should not
452 be processed further.
454 bool onEntryDoubleClick(const weld::TreeView
& rTree
);
456 /** called when a container (category) in the application view has been selected
460 <TRUE/> if the container could be changed otherwise <FALSE/>
462 bool onContainerSelect(ElementType _eType
);
464 /** called when an entry in a tree view has been selected
468 void onSelectionChanged();
470 /** called when a "Copy" command is executed in a tree view
474 /** called when a "Paste" command is executed in a tree view
478 /** called when a "Delete" command is executed in a tree view
480 void onDeleteEntry();
482 /// called when the preview mode was changed
483 void previewChanged( sal_Int32 _nMode
);
485 /// called when an object container of any kind was found during enumerating tree view elements
486 void containerFound( const css::uno::Reference
< css::container::XContainer
>& _xContainer
);
489 virtual bool isDataSourceReadOnly() const override
;
491 // IControlActionListener overridables
492 virtual bool requestQuickHelp(const void* pUserData
, OUString
& rText
) const override
;
493 virtual bool requestDrag(const weld::TreeIter
& rEntry
) override
;
494 virtual sal_Int8
queryDrop( const AcceptDropEvent
& _rEvt
, const DataFlavorExVector
& _rFlavors
) override
;
495 virtual sal_Int8
executeDrop( const ExecuteDropEvent
& _rEvt
) override
;
497 // IContextMenuProvider
498 virtual OUString
getContextMenuResourceName() const override
;
499 virtual IController
& getCommandController() override
;
500 virtual ::comphelper::OInterfaceContainerHelper2
*
501 getContextMenuInterceptors() override
;
502 virtual css::uno::Any
getCurrentSelection(weld::TreeView
& rControl
) const override
;
503 virtual vcl::Window
* getMenuParent() const override
;
504 virtual void adjustMenuPosition(const weld::TreeView
& rControl
, ::Point
& rPos
) const override
;
506 void OnInvalidateClipboard();
507 DECL_LINK( OnClipboardChanged
, TransferableDataHelper
*, void );
508 DECL_LINK( OnAsyncDrop
, void*, void );
509 DECL_LINK( OnCreateWithPilot
, void*, void );
510 DECL_LINK( OnSelectContainer
, void*, void );
511 void OnFirstControllerConnected();
514 using OGenericUnoController::connect
;
516 /** disconnects from our XConnection, and cleans up this connection
521 virtual bool Construct(vcl::Window
* pParent
) override
;
522 virtual void describeSupportedFeatures() override
;
526 virtual void SAL_CALL
disposing(const css::lang::EventObject
& Source
) override
;
529 virtual void SAL_CALL
disposing() override
;
534 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */