xref: /trunk/main/dbaccess/source/ui/misc/databaseobjectview.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_dbaccess.hxx"
30 
31 #include "databaseobjectview.hxx"
32 #include "dbustrings.hrc"
33 #include "asyncmodaldialog.hxx"
34 
35 /** === begin UNO includes === **/
36 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
37 #include <com/sun/star/frame/XDispatchProvider.hpp>
38 #include <com/sun/star/frame/XFrame.hpp>
39 #include <com/sun/star/frame/XFrames.hpp>
40 #include <com/sun/star/frame/FrameSearchFlag.hpp>
41 #include <com/sun/star/sdb/CommandType.hpp>
42 #include <com/sun/star/sdb/application/XTableUIProvider.hpp>
43 #include <com/sun/star/beans/NamedValue.hpp>
44 #include <com/sun/star/awt/Rectangle.hpp>
45 /** === end UNO includes === **/
46 
47 #include <comphelper/extract.hxx>
48 #include <comphelper/sequence.hxx>
49 #include <connectivity/dbtools.hxx>
50 #include <osl/diagnose.h>
51 #include <toolkit/helper/vclunohelper.hxx>
52 #include <tools/diagnose_ex.h>
53 #include <vcl/window.hxx>
54 
55 // .........................................................................
56 namespace dbaui
57 {
58 // .........................................................................
59 
60     using namespace ::com::sun::star::uno;
61     using namespace ::com::sun::star::sdbc;
62     using namespace ::com::sun::star::sdb;
63     using namespace ::com::sun::star::sdb::application;
64     using namespace ::com::sun::star::ui::dialogs;
65     using namespace ::com::sun::star::frame;
66     using namespace ::com::sun::star::lang;
67     using namespace ::com::sun::star::beans;
68     using namespace ::com::sun::star::awt;
69 
70     //======================================================================
71     //= DatabaseObjectView
72     //======================================================================
73     DatabaseObjectView::DatabaseObjectView( const Reference< XMultiServiceFactory >& _rxORB,
74             const Reference< XDatabaseDocumentUI >& _rxApplication,
75             const Reference< XFrame >& _rxParentFrame,
76             const ::rtl::OUString& _rComponentURL )
77         :m_xORB             ( _rxORB            )
78         ,m_xParentFrame     ( _rxParentFrame    )
79         ,m_xFrameLoader     (                   )
80         ,m_xApplication     ( _rxApplication    )
81         ,m_sComponentURL    ( _rComponentURL    )
82     {
83         OSL_ENSURE( m_xORB.is(), "DatabaseObjectView::DatabaseObjectView: invalid service factory!" );
84         OSL_ENSURE( m_xApplication.is(), "DatabaseObjectView::DatabaseObjectView: invalid connection!" );
85     }
86 
87     //----------------------------------------------------------------------
88     Reference< XConnection > DatabaseObjectView::getConnection() const
89     {
90         Reference< XConnection > xConnection;
91         if ( m_xApplication.is() )
92             xConnection = m_xApplication->getActiveConnection();
93         return xConnection;
94     }
95 
96     //----------------------------------------------------------------------
97     Reference< XComponent > DatabaseObjectView::createNew( const Reference< XDataSource >& _xDataSource, const ::comphelper::NamedValueCollection& i_rDispatchArgs )
98     {
99         return doCreateView( makeAny( _xDataSource ), ::rtl::OUString(), i_rDispatchArgs );
100     }
101 
102     //----------------------------------------------------------------------
103     Reference< XComponent > DatabaseObjectView::openExisting( const Any& _rDataSource, const ::rtl::OUString& _rName,
104             const ::comphelper::NamedValueCollection& i_rDispatchArgs )
105     {
106         return doCreateView( _rDataSource, _rName, i_rDispatchArgs );
107     }
108 
109     //----------------------------------------------------------------------
110     Reference< XComponent > DatabaseObjectView::doCreateView( const Any& _rDataSource, const ::rtl::OUString& _rObjectName,
111         const ::comphelper::NamedValueCollection& i_rCreationArgs )
112     {
113         ::comphelper::NamedValueCollection aDispatchArgs;
114 
115         aDispatchArgs.merge( i_rCreationArgs, false );    // false => do not overwrite
116         fillDispatchArgs( aDispatchArgs, _rDataSource, _rObjectName );
117         aDispatchArgs.merge( i_rCreationArgs, true );    // true => do overwrite
118 
119         return doDispatch( aDispatchArgs );
120     }
121 
122     //----------------------------------------------------------------------
123     Reference< XComponent > DatabaseObjectView::doDispatch( const ::comphelper::NamedValueCollection& i_rDispatchArgs )
124     {
125         Reference< XComponent > xReturn;
126         if ( m_xORB.is() )
127         {
128             try
129             {
130                 // if we have no externally provided frame, create one
131                 if ( !m_xFrameLoader.is() )
132                 {
133                     Reference< XSingleServiceFactory > xFact(m_xORB->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.TaskCreator")), UNO_QUERY_THROW);
134                     Sequence< Any > lArgs(2);
135                     NamedValue      aProp;
136                     sal_Int32       nArg = 0;
137 
138                     aProp.Name    = ::rtl::OUString::createFromAscii("ParentFrame");
139                     aProp.Value <<= m_xParentFrame;
140                     lArgs[nArg++] <<= aProp;
141 
142                     aProp.Name    = ::rtl::OUString::createFromAscii("TopWindow");
143                     aProp.Value <<= sal_True;
144                     lArgs[nArg++] <<= aProp;
145 
146                     m_xFrameLoader.set(xFact->createInstanceWithArguments(lArgs), UNO_QUERY_THROW);
147 
148                     // everything we load can be considered a "top level document", so set the respective bit at the window.
149                     // This, amongst other things, triggers that the component in this task participates in the
150                     // "ThisComponent"-game for the global application Basic.
151                     const Reference< XFrame > xFrame( m_xFrameLoader, UNO_QUERY_THROW );
152                     const Reference< XWindow > xFrameWindow( xFrame->getContainerWindow(), UNO_SET_THROW );
153                     Window* pContainerWindow = VCLUnoHelper::GetWindow( xFrameWindow );
154                     ENSURE_OR_THROW( pContainerWindow, "no implementation access to the frame's container window!" );
155                     pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WB_EXT_DOCUMENT );
156                 }
157 
158                 Reference< XComponentLoader > xFrameLoader( m_xFrameLoader, UNO_QUERY_THROW );
159                 xReturn = xFrameLoader->loadComponentFromURL(
160                     m_sComponentURL,
161                     ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_self")),
162                     0,
163                     i_rDispatchArgs.getPropertyValues()
164                 );
165             }
166             catch( const Exception& )
167             {
168                 DBG_UNHANDLED_EXCEPTION();
169             }
170         }
171         return xReturn;
172     }
173 
174     //----------------------------------------------------------------------
175     void DatabaseObjectView::fillDispatchArgs(
176             ::comphelper::NamedValueCollection& i_rDispatchArgs,
177             const Any& _aDataSource,
178             const ::rtl::OUString& /* _rName */
179         )
180     {
181         ::rtl::OUString sDataSource;
182         Reference<XDataSource> xDataSource;
183         if ( _aDataSource >>= sDataSource )
184         {
185             i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_DATASOURCENAME, sDataSource );
186         }
187         else if ( _aDataSource >>= xDataSource )
188         {
189             i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_DATASOURCE, xDataSource );
190         }
191 
192         i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_ACTIVE_CONNECTION, getConnection() );
193     }
194 
195     //======================================================================
196     //= QueryDesigner
197     //======================================================================
198     //----------------------------------------------------------------------
199     QueryDesigner::QueryDesigner( const Reference< XMultiServiceFactory >& _rxORB, const Reference< XDatabaseDocumentUI >& _rxApplication,
200         const Reference< XFrame >& _rxParentFrame, bool _bCreateView )
201         :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, _bCreateView ? URL_COMPONENT_VIEWDESIGN : URL_COMPONENT_QUERYDESIGN )
202         ,m_nCommandType( _bCreateView ? CommandType::TABLE : CommandType::QUERY )
203     {
204     }
205 
206     //----------------------------------------------------------------------
207     void QueryDesigner::fillDispatchArgs( ::comphelper::NamedValueCollection& i_rDispatchArgs, const Any& _aDataSource,
208         const ::rtl::OUString& _rObjectName )
209     {
210         DatabaseObjectView::fillDispatchArgs( i_rDispatchArgs, _aDataSource, _rObjectName );
211 
212         const bool bIncludeQueryName = 0 != _rObjectName.getLength();
213         const bool bGraphicalDesign = i_rDispatchArgs.getOrDefault( (::rtl::OUString)PROPERTY_GRAPHICAL_DESIGN, sal_True );
214         const bool bEditViewAsSQLCommand = ( m_nCommandType == CommandType::TABLE ) && !bGraphicalDesign;
215 
216         i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_COMMAND_TYPE, m_nCommandType );
217 
218         if ( bIncludeQueryName )
219         {
220             i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_COMMAND, _rObjectName );
221         }
222 
223         if ( bEditViewAsSQLCommand )
224         {
225             i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING, sal_False );
226         }
227     }
228 
229     //======================================================================
230     //= TableDesigner
231     //======================================================================
232     //----------------------------------------------------------------------
233     TableDesigner::TableDesigner( const Reference< XMultiServiceFactory >& _rxORB, const Reference< XDatabaseDocumentUI >& _rxApplication, const Reference< XFrame >& _rxParentFrame )
234         :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, static_cast< ::rtl::OUString >( URL_COMPONENT_TABLEDESIGN ) )
235     {
236     }
237 
238     //----------------------------------------------------------------------
239     void TableDesigner::fillDispatchArgs( ::comphelper::NamedValueCollection& i_rDispatchArgs, const Any& _aDataSource,
240         const ::rtl::OUString& _rObjectName )
241     {
242         DatabaseObjectView::fillDispatchArgs( i_rDispatchArgs, _aDataSource, _rObjectName );
243 
244         if ( 0 != _rObjectName.getLength() )
245         {
246             i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_CURRENTTABLE, _rObjectName );
247         }
248     }
249 
250     //----------------------------------------------------------------------
251     Reference< XComponent > TableDesigner::doCreateView( const Any& _rDataSource, const ::rtl::OUString& _rObjectName,
252         const ::comphelper::NamedValueCollection& i_rCreationArgs )
253     {
254         bool bIsNewDesign = ( _rObjectName.getLength() == 0 );
255 
256         // let's see whether the connection can provide a dedicated table desginer
257         Reference< XInterface > xDesigner;
258         if ( !bIsNewDesign )
259             xDesigner = impl_getConnectionProvidedDesigner_nothrow( _rObjectName );
260 
261         if ( !xDesigner.is() )
262             return DatabaseObjectView::doCreateView( _rDataSource, _rObjectName, i_rCreationArgs );
263 
264         // try whether the designer is a dialog
265         Reference< XExecutableDialog > xDialog( xDesigner, UNO_QUERY_THROW );
266         if ( xDialog.is() )
267         {
268             try { AsyncDialogExecutor::executeModalDialogAsync( xDialog ); }
269             catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
270             return NULL;
271         }
272 
273         Reference< XComponent > xDesignerComponent( xDesigner, UNO_QUERY );
274         OSL_ENSURE( xDesignerComponent.is(), "TableDesigner::doCreateView: a designer which is no dialog and no component?" );
275         return xDesignerComponent;
276     }
277 
278     //----------------------------------------------------------------------
279     Reference< XInterface > TableDesigner::impl_getConnectionProvidedDesigner_nothrow( const ::rtl::OUString& _rTableName )
280     {
281         Reference< XInterface > xDesigner;
282         try
283         {
284             Reference< XTableUIProvider > xTableUIProv( getConnection(), UNO_QUERY );
285             if ( xTableUIProv.is() )
286                 xDesigner = xTableUIProv->getTableEditor( getApplicationUI(), _rTableName );
287         }
288         catch( const Exception& )
289         {
290             DBG_UNHANDLED_EXCEPTION();
291         }
292         return xDesigner;
293     }
294 
295     //======================================================================
296     //= ResultSetBrowser
297     //======================================================================
298     //----------------------------------------------------------------------
299     ResultSetBrowser::ResultSetBrowser( const Reference< XMultiServiceFactory >& _rxORB, const Reference< XDatabaseDocumentUI >& _rxApplication, const Reference< XFrame >& _rxParentFrame,
300             sal_Bool _bTable )
301         :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, static_cast < ::rtl::OUString >( URL_COMPONENT_DATASOURCEBROWSER ) )
302         ,m_bTable(_bTable)
303     {
304     }
305 
306     //----------------------------------------------------------------------
307     void ResultSetBrowser::fillDispatchArgs( ::comphelper::NamedValueCollection& i_rDispatchArgs, const Any& _aDataSource,
308         const ::rtl::OUString& _rQualifiedName)
309     {
310         DatabaseObjectView::fillDispatchArgs( i_rDispatchArgs, _aDataSource, _rQualifiedName );
311         OSL_ENSURE( 0 != _rQualifiedName.getLength(),"A Table name must be set");
312         ::rtl::OUString sCatalog;
313         ::rtl::OUString sSchema;
314         ::rtl::OUString sTable;
315         if ( m_bTable )
316             ::dbtools::qualifiedNameComponents( getConnection()->getMetaData(), _rQualifiedName, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation );
317 
318         i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_COMMAND_TYPE, (m_bTable ? CommandType::TABLE : CommandType::QUERY) );
319         i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_COMMAND, _rQualifiedName );
320         i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_ENABLE_BROWSER, sal_False );
321 
322         if ( m_bTable )
323         {
324             i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_UPDATE_CATALOGNAME, sCatalog );
325             i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_UPDATE_SCHEMANAME, sSchema );
326             i_rDispatchArgs.put( (::rtl::OUString)PROPERTY_UPDATE_TABLENAME, sTable );
327         }
328     }
329 
330     //======================================================================
331     //= RelationDesigner
332     //======================================================================
333     //----------------------------------------------------------------------
334     RelationDesigner::RelationDesigner( const Reference< XMultiServiceFactory >& _rxORB, const Reference< XDatabaseDocumentUI >& _rxApplication, const Reference< XFrame >& _rxParentFrame )
335         :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, static_cast< ::rtl::OUString >( URL_COMPONENT_RELATIONDESIGN ) )
336     {
337     }
338 // .........................................................................
339 }   // namespace dbaui
340 // .........................................................................
341 
342