1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_DBACCESS_SOURCE_CORE_DATAACCESS_DOCUMENTDEFINITION_HXX
#define INCLUDED_DBACCESS_SOURCE_CORE_DATAACCESS_DOCUMENTDEFINITION_HXX

#include <cppuhelper/propshlp.hxx>
#include <cppuhelper/implbase4.hxx>
#include <ContentHelper.hxx>
#include <comphelper/propertystatecontainer.hxx>
#include <comphelper/proparrhlp.hxx>
#include <apitools.hxx>
#include <comphelper/uno3.hxx>
#include <com/sun/star/awt/XTopWindow.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/embed/XStateChangeListener.hpp>
#include <com/sun/star/embed/XEmbeddedObject.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/sdb/XSubDocument.hpp>
#include <com/sun/star/util/XCloseListener.hpp>
#include <com/sun/star/container/XHierarchicalName.hpp>
#include <rtl/ref.hxx>

namespace comphelper
{
    class NamedValueCollection;
}

namespace dbaccess
{

    class OInterceptor;
    class OEmbeddedClientHelper;
// ODocumentDefinition - a database "document" which is simply a link to a real
//                   document

typedef ::cppu::ImplHelper4 <   css::embed::XComponentSupplier
                            ,   css::sdb::XSubDocument
                            ,   css::util::XCloseListener
                            ,   css::container::XHierarchicalName
                            >   ODocumentDefinition_Base;

class ODocumentDefinition
        :public OContentHelper
        ,public ::comphelper::OPropertyStateContainer
        ,public ::comphelper::OPropertyArrayUsageHelper< ODocumentDefinition >
        ,public ODocumentDefinition_Base
{
    css::uno::Reference< css::embed::XEmbeddedObject>         m_xEmbeddedObject;
    css::uno::Reference< css::embed::XStateChangeListener >   m_xListener;
    css::uno::Reference< css::sdbc::XConnection >             m_xLastKnownConnection;

    rtl::Reference<OInterceptor>                              m_pInterceptor;
    bool                                                      m_bForm; // <TRUE/> if it is a form
    bool                                                      m_bOpenInDesign;
    bool                                                      m_bInExecute;
    bool                                                      m_bRemoveListener;
    rtl::Reference<OEmbeddedClientHelper>                     m_pClientHelper;

protected:
    virtual ~ODocumentDefinition() override;

public:

    ODocumentDefinition(
            const css::uno::Reference< css::uno::XInterface >& _rxContainer,
            const css::uno::Reference< css::uno::XComponentContext >&,
            const TContentPtr& _pImpl,
            bool _bForm
        );

    void    initialLoad(
                const css::uno::Sequence< sal_Int8 >& i_rClassID,
                const css::uno::Sequence< css::beans::PropertyValue >& i_rCreationArgs,
                const css::uno::Reference< css::sdbc::XConnection >& i_rConnection
            );

    virtual css::uno::Sequence<css::uno::Type> SAL_CALL getTypes() override;
    virtual css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override;

// css::uno::XInterface
    DECLARE_XINTERFACE( )<--- There is an unknown macro here somewhere. Configuration is required. If DECLARE_XINTERFACE is a macro then please configure it.<--- There is an unknown macro here somewhere. Configuration is required. If DECLARE_XINTERFACE is a macro then please configure it.

// css::beans::XPropertySet
    virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) override;

    // OPropertySetHelper
    virtual void SAL_CALL getFastPropertyValue(
                                css::uno::Any& o_rValue,
                                sal_Int32 i_nHandle
                            ) const override;

    // XComponentSupplier
    virtual css::uno::Reference< css::util::XCloseable > SAL_CALL getComponent(  ) override;

    // XSubDocument
    virtual css::uno::Reference< css::lang::XComponent > SAL_CALL open(  ) override;
    virtual css::uno::Reference< css::lang::XComponent > SAL_CALL openDesign(  ) override;
    virtual void SAL_CALL store(  ) override;
    virtual sal_Bool SAL_CALL close(  ) override;

    // XHierarchicalName
    virtual OUString SAL_CALL getHierarchicalName(  ) override;
    virtual OUString SAL_CALL composeHierarchicalName( const OUString& aRelativeName ) override;

// OPropertySetHelper
    virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;

    // XCommandProcessor
    virtual css::uno::Any SAL_CALL execute( const css::ucb::Command& aCommand, sal_Int32 CommandId, const css::uno::Reference< css::ucb::XCommandEnvironment >& Environment ) override ;

    // XRename
    virtual void SAL_CALL rename( const OUString& newName ) override;

    // XCloseListener
    virtual void SAL_CALL queryClosing( const css::lang::EventObject& Source, sal_Bool GetsOwnership ) override;
    virtual void SAL_CALL notifyClosing( const css::lang::EventObject& Source ) override;

    // XEventListener
    virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;

    /** returns the forms/reports container storage, depending on m_bForm. Our own storage
        inside this container storage is the one with the name as indicated by m_pImpl->m_aProps.sPersistentName.
    */
    css::uno::Reference< css::embed::XStorage >
        getContainerStorage() const;

    bool save(bool _bApprove, const css::uno::Reference<css::awt::XTopWindow>& rDialogParent);
    void saveAs();
    void closeObject();
    bool isModified();
    bool isNewReport() const { return !m_bForm && !m_pImpl->m_aProps.bAsTemplate; }

    static void fillReportData(
                    const css::uno::Reference< css::uno::XComponentContext > & _rxContext,
                    const css::uno::Reference< css::util::XCloseable >& _rxComponent,
                    const css::uno::Reference< css::sdbc::XConnection >& _rxActiveConnection
                );

    const css::uno::Reference< css::sdbc::XConnection >&
        getConnection() const { return m_xLastKnownConnection; }

    /** prepares closing the document component

        The method suspends the controller associated with the document, and saves the document
        if necessary.

        @return
            <TRUE/> if and only if the document component can be closed
    */
    bool prepareClose();

    static OUString GetDocumentServiceFromMediaType(
        const OUString& _rMediaType,
        const css::uno::Reference< css::uno::XComponentContext > & _rxContext,
        css::uno::Sequence< sal_Int8 >& _rClassId
    );
    static OUString GetDocumentServiceFromMediaType(
        const css::uno::Reference< css::embed::XStorage >& _rxContainerStorage,
        const OUString& _rEntityName,
        const css::uno::Reference< css::uno::XComponentContext > & _rxContext,
        css::uno::Sequence< sal_Int8 >& _rClassId
    );

    struct NotifierAccess { friend class NameChangeNotifier; private: NotifierAccess() { } };
    const OUString& getCurrentName() const { return m_pImpl->m_aProps.aTitle; }
    void firePropertyChange(
                  sal_Int32 i_nHandle,
            const css::uno::Any& i_rNewValue,
            const css::uno::Any& i_rOldValue,
                  bool i_bVetoable,
            const NotifierAccess&
        );

private:
    /** does necessary initializations after our embedded object has been switched to ACTIVE
    */
    void    impl_onActivateEmbeddedObject_nothrow( const bool i_bReactivated );

    /** initializes a newly created view/controller of a form which is displaying our embedded object

        Has only to be called if the respective embedded object has been loaded for design (and
        not for data entry)

        @param  _rxController
            the controller which belongs to the XModel of our (active) embedded object
    */
    static void impl_initFormEditView( const css::uno::Reference< css::frame::XController >& _rxController );

    /** removes the given frame from the desktop's frame collection
        @throws css::uno::RuntimeException
    */
    static void impl_removeFrameFromDesktop_throw(
                    const css::uno::Reference< css::uno::XComponentContext >& _rContxt,
                    const css::uno::Reference< css::frame::XFrame >& _rxFrame
                );

    /** opens the UI for this sub document
    */
    css::uno::Reference< css::lang::XComponent >
            impl_openUI_nolck_throw( bool _bForEditing );

    /** stores our document, if it's already loaded
    */
    void    impl_store_throw();

    /** closes our document, if it's open
    */
    bool    impl_close_throw();

    /** returns our component, creates it if necessary
    */
    css::uno::Reference< css::util::XCloseable >
            impl_getComponent_throw( const bool i_ForceCreate = true );

    /** shows or hides our component

        The embedded object must exist, and be in state LOADED, at least.
    */
    void    impl_showOrHideComponent_throw( const bool i_bShow );

    // OPropertyArrayUsageHelper
    virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const override;

    virtual void getPropertyDefaultByHandle( sal_Int32 _nHandle, css::uno::Any& _rDefault ) const override;

    // helper
    virtual void SAL_CALL disposing() override;

    // OContentHelper overridables
    virtual OUString determineContentType() const override;

    /** fills the load arguments
    */
    css::uno::Sequence< css::beans::PropertyValue >
        fillLoadArgs(
            const css::uno::Reference< css::sdbc::XConnection>& _xConnection,
            const bool _bSuppressMacros,
            const bool _bReadOnly,
            const css::uno::Sequence< css::beans::PropertyValue >& i_rOpenCommandArguments,
            css::uno::Sequence< css::beans::PropertyValue >& _out_rEmbeddedObjectDescriptor
        );

    /** splits the given arguments to an "open*" command into arguments for loading the document, and arguments to be
        put into the EmbeddedObjectDescriptor

        Any values already present in <code>o_rDocumentLoadArgs</code> and <code>o_rEmbeddedObjectDescriptor</code>
        will be overwritten by values from <code>i_rOpenCommandArguments</code>, if applicable, otherwise they will
        be preserved.

        @param i_rOpenCommandArguments
            the arguments passed to the "open*" command at the content
        @param o_rDocumentLoadArgs
            the arguments to be passed when actually loading the embedded document.
        @param o_rEmbeddedObjectDescriptor
            the EmbeddedObjectDescriptor to be passed when initializing the embedded object
    */
    static void separateOpenCommandArguments(
            const css::uno::Sequence< css::beans::PropertyValue >&    i_rOpenCommandArguments,
            ::comphelper::NamedValueCollection&                                                 o_rDocumentLoadArgs,
            ::comphelper::NamedValueCollection&                                                 o_rEmbeddedObjectDescriptor
        );

    /** loads the EmbeddedObject if not already loaded
        @param  _aClassID
            If set, it will be used to create the embedded object.
    */
    void loadEmbeddedObject(
                const css::uno::Reference< css::sdbc::XConnection>& _xConnection,
                const css::uno::Sequence< sal_Int8 >& _aClassID,
                const css::uno::Sequence< css::beans::PropertyValue >& _rAdditionalArgs,
                const bool _bSuppressMacros,
                const bool _bReadOnly
            );

    /** loads the embedded object for preview. Macros will be suppressed, and the document will
        be read-only.
    */
    void    loadEmbeddedObjectForPreview()
    {
        loadEmbeddedObject(
            nullptr,
            css::uno::Sequence< sal_Int8 >(),
            css::uno::Sequence< css::beans::PropertyValue >(),
            true,
            true
        );
    }

    /** searches for read-only flag in the args of the model and sets it to the given value,
        if the value was not found, it will be appended.
        @param  _bReadOnly
            If <TRUE/> the document will be switched to readonly mode
    */
    void updateDocumentTitle();

    void registerProperties();

    /** determines whether the document we represent supports embedded scripts and macros
    */
    bool objectSupportsEmbeddedScripts() const;

    //- commands

    void onCommandGetDocumentProperties( css::uno::Any& _rProps );
    /// @throws css::uno::Exception
    void onCommandInsert( const OUString& _sURL, const css::uno::Reference< css::ucb::XCommandEnvironment >& Environment );
    void onCommandPreview( css::uno::Any& _rImage );
    css::uno::Any
        onCommandOpenSomething(
            const css::uno::Any& _rArgument,
            const bool _bActivate,
            const css::uno::Reference< css::ucb::XCommandEnvironment >& _rxEnvironment
        );
private:
    using ::cppu::OPropertySetHelper::getFastPropertyValue;
};

class NameChangeNotifier
{
public:
    NameChangeNotifier(
        ODocumentDefinition& i_rDocumentDefinition,
        const OUString& i_rNewName,
        ::osl::ResettableMutexGuard& i_rClearForNotify
    );
    ~NameChangeNotifier();

private:
            ODocumentDefinition&            m_rDocumentDefinition;
    const   css::uno::Any                   m_aOldValue;
    const   css::uno::Any                   m_aNewValue;
    ::osl::ResettableMutexGuard&            m_rClearForNotify;

    void    impl_fireEvent_throw( const bool i_bVetoable );
};

}   // namespace dbaccess

#endif // INCLUDED_DBACCESS_SOURCE_CORE_DATAACCESS_DOCUMENTDEFINITION_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */