calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / dbaccess / source / core / inc / ModelImpl.hxx
blobfdaf89f1511d7acf594f08ecc6a40a2e05110cdd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #pragma once
22 #include "ContentHelper.hxx"
23 #include "documentevents.hxx"
25 #include <com/sun/star/beans/PropertyValue.hpp>
26 #include <com/sun/star/beans/XPropertyBag.hpp>
27 #include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
28 #include <com/sun/star/embed/XStorage.hpp>
29 #include <com/sun/star/frame/XModel.hpp>
30 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
31 #include <com/sun/star/script/XStorageBasedLibraryContainer.hpp>
32 #include <com/sun/star/sdbc/XDataSource.hpp>
33 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
35 #include <comphelper/namedvaluecollection.hxx>
36 #include <cppuhelper/weakref.hxx>
37 #include <vcl/svapp.hxx>
38 #include <sfx2/docmacromode.hxx>
39 #include <sfx2/docstoragemodifylistener.hxx>
40 #include <unotools/sharedunocomponent.hxx>
41 #include <rtl/ref.hxx>
42 #include <o3tl/enumarray.hxx>
44 namespace comphelper
46 class NamedValueCollection;
49 namespace dbaccess
52 typedef std::vector< css::uno::WeakReference< css::sdbc::XConnection > > OWeakConnectionArray;
54 struct AsciiPropertyValue
56 // note: the canonic member order would be AsciiName / DefaultValue, but
57 // this crashes on unxlngi6.pro, since there's a bug which somehow results in
58 // getDefaultDataSourceSettings returning corrupted Any instances then.
59 css::uno::Any DefaultValue;
60 const char* AsciiName;
61 const css::uno::Type& ValueType;
63 AsciiPropertyValue()
64 :DefaultValue( )
65 ,AsciiName( nullptr )
66 ,ValueType( ::cppu::UnoType<void>::get() )
70 AsciiPropertyValue( const char* _pAsciiName, const css::uno::Any& _rDefaultValue )
71 :DefaultValue( _rDefaultValue )
72 ,AsciiName( _pAsciiName )
73 ,ValueType( _rDefaultValue.getValueType() )
75 OSL_ENSURE( ValueType.getTypeClass() != css::uno::TypeClass_VOID,
76 "AsciiPropertyValue::AsciiPropertyValue: NULL values not allowed here, use the other CTOR for this!" );
78 AsciiPropertyValue( const char* _pAsciiName, const css::uno::Type& _rValeType )
79 :DefaultValue()
80 ,AsciiName( _pAsciiName )
81 ,ValueType( _rValeType )
83 OSL_ENSURE( ValueType.getTypeClass() != css::uno::TypeClass_VOID,
84 "AsciiPropertyValue::AsciiPropertyValue: VOID property values not supported!" );
88 class ODatabaseContext;
89 class OSharedConnectionManager;
91 // ODatabaseModelImpl
92 typedef ::utl::SharedUNOComponent< css::embed::XStorage > SharedStorage;
94 class ODatabaseContext;
95 class DocumentStorageAccess;
96 class OSharedConnectionManager;
98 class ODatabaseModelImpl :public ::sfx2::IMacroDocumentAccess
99 ,public ::sfx2::IModifiableDocument
101 public:
103 enum class ObjectType
105 Form = 0,
106 Report = 1,
107 Query = 2,
108 Table = 3,
109 LAST = Table
112 enum class EmbeddedMacros
114 // the database document (storage) itself contains macros
115 DocumentWide,
116 // there are sub document( storage)s containing macros
117 SubDocument,
118 // there are no known macro( storage)s
119 NONE
122 private:
123 css::uno::WeakReference< css::frame::XModel > m_xModel;
124 css::uno::WeakReference< css::sdbc::XDataSource > m_xDataSource;
126 rtl::Reference<DocumentStorageAccess> m_pStorageAccess;
127 o3tl::enumarray< ObjectType, TContentPtr > m_aContainer; // one for each ObjectType
128 ::sfx2::DocumentMacroMode m_aMacroMode;
129 sal_Int16 m_nImposedMacroExecMode;
131 css::uno::Reference< css::script::XStorageBasedLibraryContainer > m_xBasicLibraries;
132 css::uno::Reference< css::script::XStorageBasedLibraryContainer > m_xDialogLibraries;
134 SharedStorage m_xDocumentStorage;
135 ::rtl::Reference< ::sfx2::DocumentStorageModifyListener > m_pStorageModifyListener;
136 ODatabaseContext& m_rDBContext;
137 DocumentEventsData m_aDocumentEvents;
139 ::comphelper::NamedValueCollection m_aMediaDescriptor;
140 /// the URL the document was loaded from
141 OUString m_sDocFileLocation;
143 oslInterlockedCount m_refCount;
145 /// do we have any object (forms/reports) which contains macros?
146 ::std::optional< EmbeddedMacros > m_aEmbeddedMacros;
148 /// true if setting the Modified flag of the document is currently locked
149 bool m_bModificationLock;
151 /// true if and only if a database document existed previously (though meanwhile disposed), and was already initialized
152 bool m_bDocumentInitialized;
154 /** the URL which the document should report as its URL
156 This might differ from ->m_sDocFileLocation in case the document was loaded
157 as part of a crash recovery process. In this case, ->m_sDocFileLocation points to
158 the temporary file where the DB had been saved to, after a crash.
159 ->m_sDocumentURL then is the URL of the document which actually had
160 been recovered.
162 OUString m_sDocumentURL;
164 SignatureState m_nScriptingSignatureState;
166 public:
167 OWeakConnectionArray m_aConnections;
168 const css::uno::Reference< css::uno::XComponentContext > m_aContext;
170 public:
171 css::uno::WeakReference< css::container::XNameAccess > m_xCommandDefinitions;
172 css::uno::WeakReference< css::container::XNameAccess > m_xTableDefinitions;
174 css::uno::Reference< css::util::XNumberFormatsSupplier >
175 m_xNumberFormatsSupplier;
176 OUString m_sConnectURL;
177 OUString m_sName; // transient, our creator has to tell us the title
178 OUString m_sUser;
179 OUString m_aPassword; // transient !
180 OUString m_sFailedPassword;
181 css::uno::Sequence< css::beans::PropertyValue>
182 m_aLayoutInformation;
183 sal_Int32 m_nLoginTimeout;
184 bool m_bReadOnly : 1;
185 bool m_bPasswordRequired : 1;
186 bool m_bSuppressVersionColumns : 1;
187 bool m_bModified : 1;
188 bool m_bDocumentReadOnly : 1;
189 bool m_bMacroCallsSeenWhileLoading : 1;
190 css::uno::Reference< css::beans::XPropertyBag >
191 m_xSettings;
192 css::uno::Sequence< OUString > m_aTableFilter;
193 css::uno::Sequence< OUString > m_aTableTypeFilter;
194 OSharedConnectionManager* m_pSharedConnectionManager;
195 css::uno::Reference< css::lang::XEventListener >
196 m_xSharedConnectionManager;
197 css::uno::Reference<css::awt::XWindow>
198 m_xDialogParent;
199 sal_uInt16 m_nControllerLockCount;
201 void reset();
203 /** determines whether the database document has an embedded data storage
205 bool isEmbeddedDatabase() const { return m_sConnectURL.startsWith("sdbc:embedded:"); }
207 /** stores the embedded storage ("database")
209 @param _bPreventRootCommits
210 Normally, committing the embedded storage results in also committing the root storage
211 - this is an automatism for data safety reasons.
212 If you pass <TRUE/> here, committing the root storage is prevented for this particular
213 call.
214 @return <TRUE/> if the storage could be committed, otherwise <FALSE/>
216 bool commitEmbeddedStorage( bool _bPreventRootCommits = false );
218 /// commits all sub storages
219 void commitStorages();
221 ODatabaseModelImpl(
222 const css::uno::Reference< css::uno::XComponentContext >& _rxContext,
223 ODatabaseContext& _pDBContext
225 virtual ~ODatabaseModelImpl();
227 ODatabaseModelImpl(
228 OUString _sRegistrationName,
229 const css::uno::Reference< css::uno::XComponentContext >& _rxContext,
230 ODatabaseContext& _rDBContext
233 // XEventListener
234 /// @throws css::uno::RuntimeException
235 void disposing( const css::lang::EventObject& Source );
237 void setModified( bool bModified );
239 void dispose();
241 const OUString& getURL() const { return m_sDocumentURL; }
242 const OUString& getDocFileLocation() const { return m_sDocFileLocation; }
244 css::uno::Reference< css::embed::XStorage >
245 getStorage( const ObjectType _eType );
247 // helper
248 const css::uno::Reference< css::util::XNumberFormatsSupplier >&
249 getNumberFormatsSupplier();
251 DocumentEventsData&
252 getDocumentEvents() { return m_aDocumentEvents; }
254 const ::comphelper::NamedValueCollection&
255 getMediaDescriptor() const { return m_aMediaDescriptor; }
257 void setResource(
258 const OUString& _rURL,
259 const css::uno::Sequence< css::beans::PropertyValue >& _rArgs
261 void setDocFileLocation(
262 const OUString& i_rLoadedFrom
265 static ::comphelper::NamedValueCollection
266 stripLoadArguments( const ::comphelper::NamedValueCollection& _rArguments );
268 // other stuff
270 // disposes all elements in m_aStorages, and clears it
271 void disposeStorages();
273 /// creates a ->css::embed::StorageFactory
274 css::uno::Reference< css::lang::XSingleServiceFactory >
275 createStorageFactory() const;
277 /// commits our storage
278 void commitRootStorage();
280 /// commits a given storage if it's not readonly, ignoring (but asserting) all errors
281 bool commitStorageIfWriteable_ignoreErrors(
282 const css::uno::Reference< css::embed::XStorage >& _rxStorage
285 void clearConnections();
287 css::uno::Reference< css::embed::XStorage > const & getOrCreateRootStorage();
288 css::uno::Reference< css::embed::XStorage > const & getRootStorage() const { return m_xDocumentStorage.getTyped(); }
289 void resetRootStorage() { impl_switchToStorage_throw( nullptr ); }
291 /** returns the data source. If it doesn't exist it will be created
293 css::uno::Reference< css::sdbc::XDataSource> getOrCreateDataSource();
295 /** returns the model, if there already exists one
297 css::uno::Reference< css::frame::XModel > getModel_noCreate() const;
299 /** returns a new ->ODatabaseDocument
301 @precond
302 No ->ODatabaseDocument exists so far
304 @seealso
305 getModel_noCreate
307 css::uno::Reference< css::frame::XModel > createNewModel_deliverOwnership();
309 struct ResetModelAccess { friend class ODatabaseDocument; private: ResetModelAccess() { } };
311 /** resets the model to NULL
313 Only to be called when the model is being disposed
315 void modelIsDisposing( const bool _wasInitialized, ResetModelAccess );
317 bool hadInitializedDocument() const { return m_bDocumentInitialized; }
319 DocumentStorageAccess*
320 getDocumentStorageAccess();
322 css::uno::Reference< css::document::XDocumentSubStorageSupplier >
323 getDocumentSubStorageSupplier();
325 void acquire();
327 void release();
329 /// returns all known data source settings, including their default values
330 static const AsciiPropertyValue* getDefaultDataSourceSettings();
332 /** retrieves the requested container of objects (forms/reports/tables/queries)
334 TContentPtr& getObjectContainer( const ObjectType _eType );
336 /** returns the name of the storage which is used to stored objects of the given type, if applicable
338 static OUString
339 getObjectContainerStorageName( const ObjectType _eType );
341 /** determines whether a given object storage contains macros
343 static bool objectHasMacros(
344 const css::uno::Reference< css::embed::XStorage >& _rxContainerStorage,
345 const OUString& _rPersistentName
348 /** determines which kind of embedded macros are present in the document
350 EmbeddedMacros determineEmbeddedMacros();
352 /** checks our document's macro execution mode, using the interaction handler as supplied with our
353 load arguments
355 bool checkMacrosOnLoading();
357 /** adjusts our document's macro execution mode, without using any UI, assuming the user
358 would reject execution of macros, if she would have been asked.
360 If checkMacrosOnLoading has been called before (and thus the macro execution mode
361 is already adjusted), then the current execution mode is simply returned.
363 @return
364 whether or not macro execution is allowed
366 bool adjustMacroMode_AutoReject();
368 /** resets our macro execute mode, so next time the checkMacrosOnLoading is called, it will
369 behave as if it has never been called before
371 void resetMacroExecutionMode();
373 /** ensures that ->m_xBasicLibraries resp. m_xDialogLibraries exists
375 @return
376 the requested library container. Is never <NULL/>.
378 @throws RuntimeException
379 if something does wrong, which indicates a server error in the installation
381 css::uno::Reference< css::script::XStorageBasedLibraryContainer >
382 getLibraryContainer( bool _bScript );
384 /** lets our library containers store themself into the given root storage
386 void storeLibraryContainersTo( const css::uno::Reference< css::embed::XStorage >& _rxToRootStorage );
388 /** rebases the document to the given storage
390 No actual committing, copying, saving, whatsoever happens. The storage is just remembered as the documents
391 new storage, nothing more.
393 @throws css::lang::IllegalArgumentException
394 if the given storage is <NULL/>
395 @throws css::lang::RuntimeException
396 if any of the invoked operations does so
398 css::uno::Reference< css::embed::XStorage >
399 switchToStorage(
400 const css::uno::Reference< css::embed::XStorage >& _rxNewRootStorage
403 /** returns the macro mode imposed by an external instance, which passed it to attachResource
405 sal_Int16 getImposedMacroExecMode() const
407 return m_nImposedMacroExecMode;
409 void setImposedMacroExecMode( const sal_Int16 _nMacroMode )
411 m_nImposedMacroExecMode = _nMacroMode;
414 public:
415 // IMacroDocumentAccess overridables
416 virtual sal_Int16 getCurrentMacroExecMode() const override;
417 virtual void setCurrentMacroExecMode( sal_uInt16 ) override;
418 virtual OUString getDocumentLocation() const override;
419 virtual bool documentStorageHasMacros() const override;
420 virtual bool macroCallsSeenWhileLoading() const override;
421 virtual css::uno::Reference< css::document::XEmbeddedScripts > getEmbeddedDocumentScripts() const override;
422 virtual SignatureState getScriptingSignatureState() override;
423 virtual bool hasTrustedScriptingSignature( bool bAllowUIToAddAuthor ) override;
425 // IModifiableDocument
426 virtual void storageIsModified() override;
428 // don't use directly, use the ModifyLock class instead
429 void lockModify() { m_bModificationLock = true; }
430 void unlockModify() { m_bModificationLock = false; }
431 bool isModifyLocked() const { return m_bModificationLock; }
433 weld::Window* GetFrameWeld();
435 private:
436 void impl_construct_nothrow();
437 css::uno::Reference< css::embed::XStorage > const &
438 impl_switchToStorage_throw( const css::uno::Reference< css::embed::XStorage >& _rxNewRootStorage );
440 /** switches to the given document URL, which denotes the logical URL of the document, not necessarily the
441 URL where the doc was loaded/recovered from
443 void impl_switchToLogicalURL(
444 const OUString& i_rDocumentURL
449 /** a small base class for UNO components whose functionality depends on an ODatabaseModelImpl
451 class ModelDependentComponent
453 protected:
454 ::rtl::Reference< ODatabaseModelImpl > m_pImpl;
455 ::osl::Mutex m_aMutex; // only use this to init WeakComponentImplHelper
457 protected:
458 explicit ModelDependentComponent( ::rtl::Reference< ODatabaseModelImpl > _model );
459 virtual ~ModelDependentComponent();
461 /** returns the component itself
463 virtual css::uno::Reference< css::uno::XInterface > getThis() const = 0;
465 ::osl::Mutex& getMutex()
467 return m_aMutex;
470 public:
471 /// checks whether the component is already disposed, throws a DisposedException if so
472 void checkDisposed() const
474 if ( !m_pImpl.is() )
475 throw css::lang::DisposedException( "Component is already disposed.", getThis() );
478 void lockModify()
480 m_pImpl->lockModify();
483 void unlockModify()
485 m_pImpl->unlockModify();
489 class ModifyLock
491 public:
492 explicit ModifyLock( ModelDependentComponent& _component )
493 :m_rComponent( _component )
495 m_rComponent.lockModify();
498 ~ModifyLock()
500 m_rComponent.unlockModify();
503 private:
504 ModelDependentComponent& m_rComponent;
507 /** a guard for public methods of objects dependent on an ODatabaseModelImpl instance
509 Just put this guard onto the stack at the beginning of your method. Don't bother yourself
510 with a MutexGuard, checks for being disposed, and the like.
512 class ModelMethodGuard
514 private:
515 // to avoid deadlocks, lock SolarMutex
516 SolarMutexResettableGuard m_SolarGuard;
518 public:
519 /** constructs the guard
521 @param _component
522 the component whose functionality depends on an ODatabaseModelImpl instance
524 @throws css::lang::DisposedException
525 If the given component is already disposed
527 explicit ModelMethodGuard( const ModelDependentComponent& _component )
529 _component.checkDisposed();
532 void clear()
534 // note: this only releases *once* so may still be locked
535 m_SolarGuard.clear();
538 void reset()
540 m_SolarGuard.reset();
544 } // namespace dbaccess
546 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */