1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: adtabdlg.cxx,v $
10 * $Revision: 1.30.68.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
34 #include "adtabdlg.hxx"
35 #include "adtabdlg.hrc"
36 #include "sqlmessage.hxx"
37 #include <tools/debug.hxx>
38 #include <tools/diagnose_ex.h>
39 #include <svtools/localresaccess.hxx>
40 #include "dbaccess_helpid.hrc"
41 #include "dbu_resource.hrc"
42 #include "dbu_dlg.hrc"
43 #include <sfx2/sfxsids.hrc>
44 #include "QueryTableView.hxx"
45 #include "QueryDesignView.hxx"
46 #include "querycontroller.hxx"
47 #include <connectivity/dbtools.hxx>
48 #include "browserids.hxx"
49 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
50 #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
51 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
52 #include <com/sun/star/container/XNameAccess.hpp>
53 #include "UITools.hxx"
54 #include "imageprovider.hxx"
56 #include <comphelper/containermultiplexer.hxx>
57 #include "cppuhelper/basemutex.hxx"
61 using namespace dbaui
;
62 using namespace ::com::sun::star
;
63 using namespace ::com::sun::star::uno
;
64 using namespace ::com::sun::star::container
;
65 using namespace ::com::sun::star::sdb
;
66 using namespace ::com::sun::star::sdbc
;
67 using namespace ::com::sun::star::sdbcx
;
68 using namespace dbtools
;
70 //==============================================================================
71 //= TableObjectListFacade
72 //==============================================================================
73 TableObjectListFacade::~TableObjectListFacade()
77 //==============================================================================
79 //==============================================================================
80 class TableListFacade
: public ::cppu::BaseMutex
81 , public TableObjectListFacade
82 , public ::comphelper::OContainerListener
84 OTableTreeListBox
& m_rTableList
;
85 Reference
< XConnection
> m_xConnection
;
86 ::rtl::Reference
< comphelper::OContainerListenerAdapter
>
91 TableListFacade( OTableTreeListBox
& _rTableList
, const Reference
< XConnection
>& _rxConnection
)
92 : ::comphelper::OContainerListener(m_aMutex
)
93 ,m_rTableList( _rTableList
)
94 ,m_xConnection( _rxConnection
)
98 virtual ~TableListFacade();
102 virtual void updateTableObjectList( bool _bAllowViews
);
103 virtual String
getSelectedName( String
& _out_rAliasName
) const;
104 virtual bool isLeafSelected() const;
105 // OContainerListener
106 virtual void _elementInserted( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
107 virtual void _elementRemoved( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
108 virtual void _elementReplaced( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
111 TableListFacade::~TableListFacade()
113 if ( m_pContainerListener
.is() )
114 m_pContainerListener
->dispose();
116 //------------------------------------------------------------------------------
117 String
TableListFacade::getSelectedName( String
& _out_rAliasName
) const
119 SvLBoxEntry
* pEntry
= m_rTableList
.FirstSelected();
123 ::rtl::OUString aCatalog
, aSchema
, aTableName
;
124 SvLBoxEntry
* pSchema
= m_rTableList
.GetParent(pEntry
);
125 if(pSchema
&& pSchema
!= m_rTableList
.getAllObjectsEntry())
127 SvLBoxEntry
* pCatalog
= m_rTableList
.GetParent(pSchema
);
128 if(pCatalog
&& pCatalog
!= m_rTableList
.getAllObjectsEntry())
129 aCatalog
= m_rTableList
.GetEntryText(pCatalog
);
130 aSchema
= m_rTableList
.GetEntryText(pSchema
);
132 aTableName
= m_rTableList
.GetEntryText(pEntry
);
134 ::rtl::OUString aComposedName
;
137 Reference
< XDatabaseMetaData
> xMeta( m_xConnection
->getMetaData(), UNO_QUERY_THROW
);
138 if ( !aCatalog
.getLength()
139 && aSchema
.getLength()
140 && xMeta
->supportsCatalogsInDataManipulation()
141 && !xMeta
->supportsSchemasInDataManipulation() )
144 aSchema
= ::rtl::OUString();
147 aComposedName
= ::dbtools::composeTableName(
148 xMeta
, aCatalog
, aSchema
, aTableName
, sal_False
, ::dbtools::eInDataManipulation
);
150 catch ( const Exception
& )
152 DBG_UNHANDLED_EXCEPTION();
155 _out_rAliasName
= aTableName
;
156 return aComposedName
;
158 // -----------------------------------------------------------------------------
159 void TableListFacade::_elementInserted( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
)
161 updateTableObjectList(m_bAllowViews
);
163 // -----------------------------------------------------------------------------
164 void TableListFacade::_elementRemoved( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
)
166 updateTableObjectList(m_bAllowViews
);
168 // -----------------------------------------------------------------------------
169 void TableListFacade::_elementReplaced( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
)
172 //------------------------------------------------------------------------------
173 void TableListFacade::updateTableObjectList( bool _bAllowViews
)
175 m_bAllowViews
= _bAllowViews
;
176 m_rTableList
.Clear();
179 Reference
< XTablesSupplier
> xTableSupp( m_xConnection
, UNO_QUERY_THROW
);
181 Reference
< XViewsSupplier
> xViewSupp
;
182 Reference
< XNameAccess
> xTables
, xViews
;
183 Sequence
< ::rtl::OUString
> sTables
, sViews
;
185 xTables
= xTableSupp
->getTables();
188 if ( !m_pContainerListener
.is() )
190 Reference
< XContainer
> xContainer(xTables
,uno::UNO_QUERY
);
191 if ( xContainer
.is() )
192 m_pContainerListener
= new ::comphelper::OContainerListenerAdapter(this,xContainer
);
194 sTables
= xTables
->getElementNames();
195 } // if ( xTables.is() )
197 xViewSupp
.set( xTableSupp
, UNO_QUERY
);
198 if ( xViewSupp
.is() )
200 xViews
= xViewSupp
->getViews();
202 sViews
= xViews
->getElementNames();
205 // if no views are allowed remove the views also out the table name filter
208 const ::rtl::OUString
* pTableBegin
= sTables
.getConstArray();
209 const ::rtl::OUString
* pTableEnd
= pTableBegin
+ sTables
.getLength();
210 ::std::vector
< ::rtl::OUString
> aTables(pTableBegin
,pTableEnd
);
212 const ::rtl::OUString
* pViewBegin
= sViews
.getConstArray();
213 const ::rtl::OUString
* pViewEnd
= pViewBegin
+ sViews
.getLength();
214 ::comphelper::TStringMixEqualFunctor aEqualFunctor
;
215 for(;pViewBegin
!= pViewEnd
;++pViewBegin
)
216 aTables
.erase(::std::remove_if(aTables
.begin(),aTables
.end(),::std::bind2nd(aEqualFunctor
,*pViewBegin
)),aTables
.end());
217 ::rtl::OUString
* pTables
= aTables
.empty() ? 0 : &aTables
[0];
218 sTables
= Sequence
< ::rtl::OUString
>(pTables
, aTables
.size());
219 sViews
= Sequence
< ::rtl::OUString
>();
222 m_rTableList
.UpdateTableList( m_xConnection
, sTables
, sViews
);
223 SvLBoxEntry
* pEntry
= m_rTableList
.First();
224 while( pEntry
&& m_rTableList
.GetModel()->HasChilds( pEntry
) )
226 m_rTableList
.Expand( pEntry
);
227 pEntry
= m_rTableList
.Next( pEntry
);
230 m_rTableList
.Select(pEntry
);
232 catch( const Exception
& )
234 DBG_UNHANDLED_EXCEPTION();
238 //------------------------------------------------------------------------------
239 bool TableListFacade::isLeafSelected() const
241 SvLBoxEntry
* pEntry
= m_rTableList
.FirstSelected();
242 return pEntry
&& !m_rTableList
.GetModel()->HasChilds( pEntry
);
245 //==============================================================================
247 //==============================================================================
248 class QueryListFacade
: public ::cppu::BaseMutex
249 , public TableObjectListFacade
250 , public ::comphelper::OContainerListener
252 SvTreeListBox
& m_rQueryList
;
253 Reference
< XConnection
> m_xConnection
;
254 ::rtl::Reference
< comphelper::OContainerListenerAdapter
>
255 m_pContainerListener
;
258 QueryListFacade( SvTreeListBox
& _rQueryList
, const Reference
< XConnection
>& _rxConnection
)
259 : ::comphelper::OContainerListener(m_aMutex
)
260 ,m_rQueryList( _rQueryList
)
261 ,m_xConnection( _rxConnection
)
264 virtual ~QueryListFacade();
266 virtual void updateTableObjectList( bool _bAllowViews
);
267 virtual String
getSelectedName( String
& _out_rAliasName
) const;
268 virtual bool isLeafSelected() const;
269 // OContainerListener
270 virtual void _elementInserted( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
271 virtual void _elementRemoved( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
272 virtual void _elementReplaced( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
274 QueryListFacade::~QueryListFacade()
276 if ( m_pContainerListener
.is() )
277 m_pContainerListener
->dispose();
279 // -----------------------------------------------------------------------------
280 void QueryListFacade::_elementInserted( const container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
)
282 ::rtl::OUString sName
;
283 if ( _rEvent
.Accessor
>>= sName
)
284 m_rQueryList
.InsertEntry( sName
);
286 // -----------------------------------------------------------------------------
287 void QueryListFacade::_elementRemoved( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
)
289 updateTableObjectList(true);
291 // -----------------------------------------------------------------------------
292 void QueryListFacade::_elementReplaced( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
)
296 //------------------------------------------------------------------------------
297 void QueryListFacade::updateTableObjectList( bool /*_bAllowViews*/ )
299 m_rQueryList
.Clear();
302 ImageProvider
aImageProvider( m_xConnection
);
303 Image
aQueryImage( aImageProvider
.getDefaultImage( DatabaseObject::QUERY
, false ) );
304 Image
aQueryImageHC( aImageProvider
.getDefaultImage( DatabaseObject::QUERY
, true ) );
306 m_rQueryList
.SetDefaultExpandedEntryBmp( aQueryImage
, BMP_COLOR_NORMAL
);
307 m_rQueryList
.SetDefaultCollapsedEntryBmp( aQueryImage
, BMP_COLOR_NORMAL
);
308 m_rQueryList
.SetDefaultExpandedEntryBmp( aQueryImageHC
, BMP_COLOR_HIGHCONTRAST
);
309 m_rQueryList
.SetDefaultCollapsedEntryBmp( aQueryImageHC
, BMP_COLOR_HIGHCONTRAST
);
311 Reference
< XQueriesSupplier
> xSuppQueries( m_xConnection
, UNO_QUERY_THROW
);
312 Reference
< XNameAccess
> xQueries( xSuppQueries
->getQueries(), UNO_QUERY_THROW
);
313 if ( !m_pContainerListener
.is() )
315 Reference
< XContainer
> xContainer(xQueries
,UNO_QUERY_THROW
);
316 m_pContainerListener
= new ::comphelper::OContainerListenerAdapter(this,xContainer
);
318 Sequence
< ::rtl::OUString
> aQueryNames
= xQueries
->getElementNames();
320 const ::rtl::OUString
* pQuery
= aQueryNames
.getConstArray();
321 const ::rtl::OUString
* pQueryEnd
= aQueryNames
.getConstArray() + aQueryNames
.getLength();
322 while ( pQuery
!= pQueryEnd
)
323 m_rQueryList
.InsertEntry( *pQuery
++ );
325 catch( const Exception
& )
327 DBG_UNHANDLED_EXCEPTION();
331 //------------------------------------------------------------------------------
332 String
QueryListFacade::getSelectedName( String
& _out_rAliasName
) const
335 SvLBoxEntry
* pEntry
= m_rQueryList
.FirstSelected();
337 sSelected
= _out_rAliasName
= m_rQueryList
.GetEntryText( pEntry
);
341 //------------------------------------------------------------------------------
342 bool QueryListFacade::isLeafSelected() const
344 SvLBoxEntry
* pEntry
= m_rQueryList
.FirstSelected();
345 return pEntry
&& !m_rQueryList
.GetModel()->HasChilds( pEntry
);
348 //==============================================================================
350 //==============================================================================
351 //------------------------------------------------------------------------------
352 OAddTableDlg::OAddTableDlg( Window
* pParent
, IAddTableDialogContext
& _rContext
)
353 :ModelessDialog( pParent
, ModuleRes(DLG_JOIN_TABADD
) )
354 ,m_aCaseTables( this, ModuleRes( RB_CASE_TABLES
) )
355 ,m_aCaseQueries( this, ModuleRes( RB_CASE_QUERIES
) )
356 ,m_aTableList( this, NULL
, ModuleRes( LB_TABLE_OR_QUERY
), sal_False
)
357 ,m_aQueryList( this, ModuleRes( LB_TABLE_OR_QUERY
) )
358 ,aAddButton( this, ModuleRes( PB_ADDTABLE
) )
359 ,aCloseButton( this, ModuleRes( PB_CLOSE
) )
360 ,aHelpButton( this, ModuleRes( PB_HELP
) )
361 ,m_rContext( _rContext
)
363 // der Close-Button hat schon einen Standard-Help-Text, den ich aber hier nicht haben moechte, also den Text ruecksetzen
364 // und eine neue ID verteilen
365 aCloseButton
.SetHelpText(String());
366 aCloseButton
.SetHelpId(HID_JOINSH_ADDTAB_CLOSE
);
368 m_aTableList
.SetHelpId( HID_JOINSH_ADDTAB_TABLELIST
);
369 m_aQueryList
.SetHelpId( HID_JOINSH_ADDTAB_QUERYLIST
);
371 //////////////////////////////////////////////////////////////////////
372 m_aCaseTables
.SetClickHdl( LINK( this, OAddTableDlg
, OnTypeSelected
) );
373 m_aCaseQueries
.SetClickHdl( LINK( this, OAddTableDlg
, OnTypeSelected
) );
374 aAddButton
.SetClickHdl( LINK( this, OAddTableDlg
, AddClickHdl
) );
375 aCloseButton
.SetClickHdl( LINK( this, OAddTableDlg
, CloseClickHdl
) );
376 m_aTableList
.SetDoubleClickHdl( LINK( this, OAddTableDlg
, TableListDoubleClickHdl
) );
377 m_aTableList
.SetSelectHdl( LINK( this, OAddTableDlg
, TableListSelectHdl
) );
378 m_aQueryList
.SetDoubleClickHdl( LINK( this, OAddTableDlg
, TableListDoubleClickHdl
) );
379 m_aQueryList
.SetSelectHdl( LINK( this, OAddTableDlg
, TableListSelectHdl
) );
381 //////////////////////////////////////////////////////////////////////
382 m_aTableList
.EnableInplaceEditing( FALSE
);
383 m_aTableList
.SetWindowBits(WB_BORDER
| WB_HASLINES
|WB_HASBUTTONS
| WB_HASBUTTONSATROOT
| WB_HASLINESATROOT
| WB_SORT
| WB_HSCROLL
);
384 m_aTableList
.EnableCheckButton( NULL
); // do not show any buttons
385 m_aTableList
.SetSelectionMode( SINGLE_SELECTION
);
386 m_aTableList
.notifyHiContrastChanged();
387 m_aTableList
.suppressEmptyFolders();
389 //////////////////////////////////////////////////////////////////////
390 m_aQueryList
.EnableInplaceEditing( FALSE
);
391 m_aQueryList
.SetSelectionMode( SINGLE_SELECTION
);
393 //////////////////////////////////////////////////////////////////////
394 if ( !m_rContext
.allowQueries() )
396 m_aCaseTables
.Hide();
397 m_aCaseQueries
.Hide();
399 long nPixelDiff
= m_aTableList
.GetPosPixel().Y() - m_aCaseTables
.GetPosPixel().Y();
401 Point
aListPos( m_aTableList
.GetPosPixel() );
402 aListPos
.Y() -= nPixelDiff
;
404 Size
aListSize( m_aTableList
.GetSizePixel() );
405 aListSize
.Height() += nPixelDiff
;
407 m_aTableList
.SetPosSizePixel( aListPos
, aListSize
);
412 SetText( getDialogTitleForContext( m_rContext
) );
415 //------------------------------------------------------------------------------
416 OAddTableDlg::~OAddTableDlg()
418 m_rContext
.onWindowClosing( this );
421 //------------------------------------------------------------------------------
422 void OAddTableDlg::impl_switchTo( ObjectList _eList
)
427 m_aTableList
.Show( TRUE
); m_aCaseTables
.Check( TRUE
);
428 m_aQueryList
.Show( FALSE
); m_aCaseQueries
.Check( FALSE
);
429 m_pCurrentList
.reset( new TableListFacade( m_aTableList
, m_rContext
.getConnection() ) );
430 m_aTableList
.GrabFocus();
434 m_aTableList
.Show( FALSE
); m_aCaseTables
.Check( FALSE
);
435 m_aQueryList
.Show( TRUE
); m_aCaseQueries
.Check( TRUE
);
436 m_pCurrentList
.reset( new QueryListFacade( m_aQueryList
, m_rContext
.getConnection() ) );
437 m_aQueryList
.GrabFocus();
440 m_pCurrentList
->updateTableObjectList( m_rContext
.allowViews() );
443 //------------------------------------------------------------------------------
444 void OAddTableDlg::Update()
446 if ( !m_pCurrentList
.get() )
447 impl_switchTo( Tables
);
449 m_pCurrentList
->updateTableObjectList( m_rContext
.allowViews() );
452 //------------------------------------------------------------------------------
453 void OAddTableDlg::impl_addTable()
455 if ( m_pCurrentList
->isLeafSelected() )
457 String sSelectedName
, sAliasName
;
458 sSelectedName
= m_pCurrentList
->getSelectedName( sAliasName
);
460 m_rContext
.addTableWindow( sSelectedName
, sAliasName
);
464 //------------------------------------------------------------------------------
465 IMPL_LINK( OAddTableDlg
, AddClickHdl
, Button
*, /*pButton*/ )
467 TableListDoubleClickHdl(NULL
);
471 //------------------------------------------------------------------------------
472 IMPL_LINK( OAddTableDlg
, TableListDoubleClickHdl
, void*, /*EMPTY_ARG*/ )
474 if ( impl_isAddAllowed() )
477 if ( !impl_isAddAllowed() )
479 return 1L; // handled
482 return 0L; // not handled
485 //------------------------------------------------------------------------------
486 IMPL_LINK( OAddTableDlg
, TableListSelectHdl
, void*, /*EMPTY_ARG*/ )
488 aAddButton
.Enable( m_pCurrentList
->isLeafSelected() );
492 //------------------------------------------------------------------------------
493 IMPL_LINK( OAddTableDlg
, CloseClickHdl
, Button
*, /*pButton*/ )
498 //------------------------------------------------------------------------------
499 IMPL_LINK( OAddTableDlg
, OnTypeSelected
, void*, /*EMPTY_ARG*/ )
501 if ( m_aCaseTables
.IsChecked() )
502 impl_switchTo( Tables
);
504 impl_switchTo( Queries
);
508 //------------------------------------------------------------------------------
509 BOOL
OAddTableDlg::Close()
511 m_rContext
.onWindowClosing( this );
512 return ModelessDialog::Close();
515 //------------------------------------------------------------------------------
516 bool OAddTableDlg::impl_isAddAllowed()
518 return m_rContext
.allowAddition();
521 //------------------------------------------------------------------------------
522 String
OAddTableDlg::getDialogTitleForContext( IAddTableDialogContext
& _rContext
)
526 ::svt::OLocalResourceAccess
aLocalRes( ModuleRes( DLG_JOIN_TABADD
), RSC_MODELESSDIALOG
);
527 if ( _rContext
.allowQueries() )
528 sTitle
= String( ModuleRes( STR_ADD_TABLE_OR_QUERY
) );
530 sTitle
= String( ModuleRes( STR_ADD_TABLES
) );
535 // -----------------------------------------------------------------------------