1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "adtabdlg.hxx"
31 #include "adtabdlg.hrc"
32 #include "sqlmessage.hxx"
33 #include <tools/debug.hxx>
34 #include <tools/diagnose_ex.h>
35 #include <svtools/localresaccess.hxx>
36 #include "dbaccess_helpid.hrc"
37 #include "dbu_resource.hrc"
38 #include "dbu_dlg.hrc"
39 #include <sfx2/sfxsids.hrc>
40 #include "QueryTableView.hxx"
41 #include "QueryDesignView.hxx"
42 #include "querycontroller.hxx"
43 #include <connectivity/dbtools.hxx>
44 #include "browserids.hxx"
45 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
46 #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
47 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
48 #include <com/sun/star/container/XNameAccess.hpp>
49 #include "UITools.hxx"
50 #include "imageprovider.hxx"
52 #include <comphelper/containermultiplexer.hxx>
53 #include "cppuhelper/basemutex.hxx"
57 using namespace dbaui
;
58 using namespace ::com::sun::star
;
59 using namespace ::com::sun::star::uno
;
60 using namespace ::com::sun::star::container
;
61 using namespace ::com::sun::star::sdb
;
62 using namespace ::com::sun::star::sdbc
;
63 using namespace ::com::sun::star::sdbcx
;
64 using namespace dbtools
;
66 //==============================================================================
67 //= TableObjectListFacade
68 //==============================================================================
69 TableObjectListFacade::~TableObjectListFacade()
73 //==============================================================================
75 //==============================================================================
76 class TableListFacade
: public ::cppu::BaseMutex
77 , public TableObjectListFacade
78 , public ::comphelper::OContainerListener
80 OTableTreeListBox
& m_rTableList
;
81 Reference
< XConnection
> m_xConnection
;
82 ::rtl::Reference
< comphelper::OContainerListenerAdapter
>
87 TableListFacade( OTableTreeListBox
& _rTableList
, const Reference
< XConnection
>& _rxConnection
)
88 : ::comphelper::OContainerListener(m_aMutex
)
89 ,m_rTableList( _rTableList
)
90 ,m_xConnection( _rxConnection
)
94 virtual ~TableListFacade();
98 virtual void updateTableObjectList( bool _bAllowViews
);
99 virtual String
getSelectedName( String
& _out_rAliasName
) const;
100 virtual bool isLeafSelected() const;
101 // OContainerListener
102 virtual void _elementInserted( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
103 virtual void _elementRemoved( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
104 virtual void _elementReplaced( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
107 TableListFacade::~TableListFacade()
109 if ( m_pContainerListener
.is() )
110 m_pContainerListener
->dispose();
112 //------------------------------------------------------------------------------
113 String
TableListFacade::getSelectedName( String
& _out_rAliasName
) const
115 SvLBoxEntry
* pEntry
= m_rTableList
.FirstSelected();
119 ::rtl::OUString aCatalog
, aSchema
, aTableName
;
120 SvLBoxEntry
* pSchema
= m_rTableList
.GetParent(pEntry
);
121 if(pSchema
&& pSchema
!= m_rTableList
.getAllObjectsEntry())
123 SvLBoxEntry
* pCatalog
= m_rTableList
.GetParent(pSchema
);
124 if(pCatalog
&& pCatalog
!= m_rTableList
.getAllObjectsEntry())
125 aCatalog
= m_rTableList
.GetEntryText(pCatalog
);
126 aSchema
= m_rTableList
.GetEntryText(pSchema
);
128 aTableName
= m_rTableList
.GetEntryText(pEntry
);
130 ::rtl::OUString aComposedName
;
133 Reference
< XDatabaseMetaData
> xMeta( m_xConnection
->getMetaData(), UNO_QUERY_THROW
);
134 if ( aCatalog
.isEmpty()
135 && !aSchema
.isEmpty()
136 && xMeta
->supportsCatalogsInDataManipulation()
137 && !xMeta
->supportsSchemasInDataManipulation() )
140 aSchema
= ::rtl::OUString();
143 aComposedName
= ::dbtools::composeTableName(
144 xMeta
, aCatalog
, aSchema
, aTableName
, sal_False
, ::dbtools::eInDataManipulation
);
146 catch ( const Exception
& )
148 DBG_UNHANDLED_EXCEPTION();
151 _out_rAliasName
= aTableName
;
152 return aComposedName
;
154 // -----------------------------------------------------------------------------
155 void TableListFacade::_elementInserted( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
)
157 updateTableObjectList(m_bAllowViews
);
159 // -----------------------------------------------------------------------------
160 void TableListFacade::_elementRemoved( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
)
162 updateTableObjectList(m_bAllowViews
);
164 // -----------------------------------------------------------------------------
165 void TableListFacade::_elementReplaced( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
)
168 //------------------------------------------------------------------------------
169 void TableListFacade::updateTableObjectList( bool _bAllowViews
)
171 m_bAllowViews
= _bAllowViews
;
172 m_rTableList
.Clear();
175 Reference
< XTablesSupplier
> xTableSupp( m_xConnection
, UNO_QUERY_THROW
);
177 Reference
< XViewsSupplier
> xViewSupp
;
178 Reference
< XNameAccess
> xTables
, xViews
;
179 Sequence
< ::rtl::OUString
> sTables
, sViews
;
181 xTables
= xTableSupp
->getTables();
184 if ( !m_pContainerListener
.is() )
186 Reference
< XContainer
> xContainer(xTables
,uno::UNO_QUERY
);
187 if ( xContainer
.is() )
188 m_pContainerListener
= new ::comphelper::OContainerListenerAdapter(this,xContainer
);
190 sTables
= xTables
->getElementNames();
193 xViewSupp
.set( xTableSupp
, UNO_QUERY
);
194 if ( xViewSupp
.is() )
196 xViews
= xViewSupp
->getViews();
198 sViews
= xViews
->getElementNames();
201 // if no views are allowed remove the views also out the table name filter
204 const ::rtl::OUString
* pTableBegin
= sTables
.getConstArray();
205 const ::rtl::OUString
* pTableEnd
= pTableBegin
+ sTables
.getLength();
206 ::std::vector
< ::rtl::OUString
> aTables(pTableBegin
,pTableEnd
);
208 const ::rtl::OUString
* pViewBegin
= sViews
.getConstArray();
209 const ::rtl::OUString
* pViewEnd
= pViewBegin
+ sViews
.getLength();
210 ::comphelper::TStringMixEqualFunctor aEqualFunctor
;
211 for(;pViewBegin
!= pViewEnd
;++pViewBegin
)
212 aTables
.erase(::std::remove_if(aTables
.begin(),aTables
.end(),::std::bind2nd(aEqualFunctor
,*pViewBegin
)),aTables
.end());
213 ::rtl::OUString
* pTables
= aTables
.empty() ? 0 : &aTables
[0];
214 sTables
= Sequence
< ::rtl::OUString
>(pTables
, aTables
.size());
215 sViews
= Sequence
< ::rtl::OUString
>();
218 m_rTableList
.UpdateTableList( m_xConnection
, sTables
, sViews
);
219 SvLBoxEntry
* pEntry
= m_rTableList
.First();
220 while( pEntry
&& m_rTableList
.GetModel()->HasChildren( pEntry
) )
222 m_rTableList
.Expand( pEntry
);
223 pEntry
= m_rTableList
.Next( pEntry
);
226 m_rTableList
.Select(pEntry
);
228 catch( const Exception
& )
230 DBG_UNHANDLED_EXCEPTION();
234 //------------------------------------------------------------------------------
235 bool TableListFacade::isLeafSelected() const
237 SvLBoxEntry
* pEntry
= m_rTableList
.FirstSelected();
238 return pEntry
&& !m_rTableList
.GetModel()->HasChildren( pEntry
);
241 //==============================================================================
243 //==============================================================================
244 class QueryListFacade
: public ::cppu::BaseMutex
245 , public TableObjectListFacade
246 , public ::comphelper::OContainerListener
248 SvTreeListBox
& m_rQueryList
;
249 Reference
< XConnection
> m_xConnection
;
250 ::rtl::Reference
< comphelper::OContainerListenerAdapter
>
251 m_pContainerListener
;
254 QueryListFacade( SvTreeListBox
& _rQueryList
, const Reference
< XConnection
>& _rxConnection
)
255 : ::comphelper::OContainerListener(m_aMutex
)
256 ,m_rQueryList( _rQueryList
)
257 ,m_xConnection( _rxConnection
)
260 virtual ~QueryListFacade();
262 virtual void updateTableObjectList( bool _bAllowViews
);
263 virtual String
getSelectedName( String
& _out_rAliasName
) const;
264 virtual bool isLeafSelected() const;
265 // OContainerListener
266 virtual void _elementInserted( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
267 virtual void _elementRemoved( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
268 virtual void _elementReplaced( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
270 QueryListFacade::~QueryListFacade()
272 if ( m_pContainerListener
.is() )
273 m_pContainerListener
->dispose();
275 // -----------------------------------------------------------------------------
276 void QueryListFacade::_elementInserted( const container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
)
278 ::rtl::OUString sName
;
279 if ( _rEvent
.Accessor
>>= sName
)
280 m_rQueryList
.InsertEntry( sName
);
282 // -----------------------------------------------------------------------------
283 void QueryListFacade::_elementRemoved( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
)
285 updateTableObjectList(true);
287 // -----------------------------------------------------------------------------
288 void QueryListFacade::_elementReplaced( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
)
292 //------------------------------------------------------------------------------
293 void QueryListFacade::updateTableObjectList( bool /*_bAllowViews*/ )
295 m_rQueryList
.Clear();
298 ImageProvider
aImageProvider( m_xConnection
);
299 Image
aQueryImage( aImageProvider
.getDefaultImage( DatabaseObject::QUERY
) );
301 m_rQueryList
.SetDefaultExpandedEntryBmp( aQueryImage
);
302 m_rQueryList
.SetDefaultCollapsedEntryBmp( aQueryImage
);
304 Reference
< XQueriesSupplier
> xSuppQueries( m_xConnection
, UNO_QUERY_THROW
);
305 Reference
< XNameAccess
> xQueries( xSuppQueries
->getQueries(), UNO_QUERY_THROW
);
306 if ( !m_pContainerListener
.is() )
308 Reference
< XContainer
> xContainer(xQueries
,UNO_QUERY_THROW
);
309 m_pContainerListener
= new ::comphelper::OContainerListenerAdapter(this,xContainer
);
311 Sequence
< ::rtl::OUString
> aQueryNames
= xQueries
->getElementNames();
313 const ::rtl::OUString
* pQuery
= aQueryNames
.getConstArray();
314 const ::rtl::OUString
* pQueryEnd
= aQueryNames
.getConstArray() + aQueryNames
.getLength();
315 while ( pQuery
!= pQueryEnd
)
316 m_rQueryList
.InsertEntry( *pQuery
++ );
318 catch( const Exception
& )
320 DBG_UNHANDLED_EXCEPTION();
324 //------------------------------------------------------------------------------
325 String
QueryListFacade::getSelectedName( String
& _out_rAliasName
) const
328 SvLBoxEntry
* pEntry
= m_rQueryList
.FirstSelected();
330 sSelected
= _out_rAliasName
= m_rQueryList
.GetEntryText( pEntry
);
334 //------------------------------------------------------------------------------
335 bool QueryListFacade::isLeafSelected() const
337 SvLBoxEntry
* pEntry
= m_rQueryList
.FirstSelected();
338 return pEntry
&& !m_rQueryList
.GetModel()->HasChildren( pEntry
);
341 //==============================================================================
343 //==============================================================================
344 //------------------------------------------------------------------------------
345 OAddTableDlg::OAddTableDlg( Window
* pParent
, IAddTableDialogContext
& _rContext
)
346 :ModelessDialog( pParent
, ModuleRes(DLG_JOIN_TABADD
) )
347 ,m_aCaseTables( this, ModuleRes( RB_CASE_TABLES
) )
348 ,m_aCaseQueries( this, ModuleRes( RB_CASE_QUERIES
) )
349 ,m_aTableList( this, NULL
, ModuleRes( LB_TABLE_OR_QUERY
), sal_False
)
350 ,m_aQueryList( this, ModuleRes( LB_TABLE_OR_QUERY
) )
351 ,aAddButton( this, ModuleRes( PB_ADDTABLE
) )
352 ,aCloseButton( this, ModuleRes( PB_CLOSE
) )
353 ,aHelpButton( this, ModuleRes( PB_HELP
) )
354 ,m_rContext( _rContext
)
356 // der Close-Button hat schon einen Standard-Help-Text, den ich aber hier nicht haben moechte, also den Text ruecksetzen
357 // und eine neue ID verteilen
358 aCloseButton
.SetHelpText(String());
359 aCloseButton
.SetHelpId(HID_JOINSH_ADDTAB_CLOSE
);
361 m_aTableList
.SetHelpId( HID_JOINSH_ADDTAB_TABLELIST
);
362 m_aQueryList
.SetHelpId( HID_JOINSH_ADDTAB_QUERYLIST
);
364 //////////////////////////////////////////////////////////////////////
365 m_aCaseTables
.SetClickHdl( LINK( this, OAddTableDlg
, OnTypeSelected
) );
366 m_aCaseQueries
.SetClickHdl( LINK( this, OAddTableDlg
, OnTypeSelected
) );
367 aAddButton
.SetClickHdl( LINK( this, OAddTableDlg
, AddClickHdl
) );
368 aCloseButton
.SetClickHdl( LINK( this, OAddTableDlg
, CloseClickHdl
) );
369 m_aTableList
.SetDoubleClickHdl( LINK( this, OAddTableDlg
, TableListDoubleClickHdl
) );
370 m_aTableList
.SetSelectHdl( LINK( this, OAddTableDlg
, TableListSelectHdl
) );
371 m_aQueryList
.SetDoubleClickHdl( LINK( this, OAddTableDlg
, TableListDoubleClickHdl
) );
372 m_aQueryList
.SetSelectHdl( LINK( this, OAddTableDlg
, TableListSelectHdl
) );
374 //////////////////////////////////////////////////////////////////////
375 m_aTableList
.EnableInplaceEditing( sal_False
);
376 m_aTableList
.SetStyle(m_aTableList
.GetStyle() | WB_BORDER
| WB_HASLINES
|WB_HASBUTTONS
| WB_HASBUTTONSATROOT
| WB_HASLINESATROOT
| WB_SORT
| WB_HSCROLL
);
377 m_aTableList
.EnableCheckButton( NULL
); // do not show any buttons
378 m_aTableList
.SetSelectionMode( SINGLE_SELECTION
);
379 m_aTableList
.notifyHiContrastChanged();
380 m_aTableList
.suppressEmptyFolders();
382 //////////////////////////////////////////////////////////////////////
383 m_aQueryList
.EnableInplaceEditing( sal_False
);
384 m_aQueryList
.SetSelectionMode( SINGLE_SELECTION
);
386 //////////////////////////////////////////////////////////////////////
387 if ( !m_rContext
.allowQueries() )
389 m_aCaseTables
.Hide();
390 m_aCaseQueries
.Hide();
392 long nPixelDiff
= m_aTableList
.GetPosPixel().Y() - m_aCaseTables
.GetPosPixel().Y();
394 Point
aListPos( m_aTableList
.GetPosPixel() );
395 aListPos
.Y() -= nPixelDiff
;
397 Size
aListSize( m_aTableList
.GetSizePixel() );
398 aListSize
.Height() += nPixelDiff
;
400 m_aTableList
.SetPosSizePixel( aListPos
, aListSize
);
405 SetText( getDialogTitleForContext( m_rContext
) );
408 //------------------------------------------------------------------------------
409 OAddTableDlg::~OAddTableDlg()
411 m_rContext
.onWindowClosing( this );
414 //------------------------------------------------------------------------------
415 void OAddTableDlg::impl_switchTo( ObjectList _eList
)
420 m_aTableList
.Show( sal_True
); m_aCaseTables
.Check( sal_True
);
421 m_aQueryList
.Show( sal_False
); m_aCaseQueries
.Check( sal_False
);
422 m_pCurrentList
.reset( new TableListFacade( m_aTableList
, m_rContext
.getConnection() ) );
423 m_aTableList
.GrabFocus();
427 m_aTableList
.Show( sal_False
); m_aCaseTables
.Check( sal_False
);
428 m_aQueryList
.Show( sal_True
); m_aCaseQueries
.Check( sal_True
);
429 m_pCurrentList
.reset( new QueryListFacade( m_aQueryList
, m_rContext
.getConnection() ) );
430 m_aQueryList
.GrabFocus();
433 m_pCurrentList
->updateTableObjectList( m_rContext
.allowViews() );
436 //------------------------------------------------------------------------------
437 void OAddTableDlg::Update()
439 if ( !m_pCurrentList
.get() )
440 impl_switchTo( Tables
);
442 m_pCurrentList
->updateTableObjectList( m_rContext
.allowViews() );
445 //------------------------------------------------------------------------------
446 void OAddTableDlg::impl_addTable()
448 if ( m_pCurrentList
->isLeafSelected() )
450 String sSelectedName
, sAliasName
;
451 sSelectedName
= m_pCurrentList
->getSelectedName( sAliasName
);
453 m_rContext
.addTableWindow( sSelectedName
, sAliasName
);
457 //------------------------------------------------------------------------------
458 IMPL_LINK( OAddTableDlg
, AddClickHdl
, Button
*, /*pButton*/ )
460 TableListDoubleClickHdl(NULL
);
464 //------------------------------------------------------------------------------
465 IMPL_LINK( OAddTableDlg
, TableListDoubleClickHdl
, void*, /*EMPTY_ARG*/ )
467 if ( impl_isAddAllowed() )
470 if ( !impl_isAddAllowed() )
472 return 1L; // handled
475 return 0L; // not handled
478 //------------------------------------------------------------------------------
479 IMPL_LINK( OAddTableDlg
, TableListSelectHdl
, void*, /*EMPTY_ARG*/ )
481 aAddButton
.Enable( m_pCurrentList
->isLeafSelected() );
485 //------------------------------------------------------------------------------
486 IMPL_LINK( OAddTableDlg
, CloseClickHdl
, Button
*, /*pButton*/ )
491 //------------------------------------------------------------------------------
492 IMPL_LINK( OAddTableDlg
, OnTypeSelected
, void*, /*EMPTY_ARG*/ )
494 if ( m_aCaseTables
.IsChecked() )
495 impl_switchTo( Tables
);
497 impl_switchTo( Queries
);
501 //------------------------------------------------------------------------------
502 sal_Bool
OAddTableDlg::Close()
504 m_rContext
.onWindowClosing( this );
505 return ModelessDialog::Close();
508 //------------------------------------------------------------------------------
509 bool OAddTableDlg::impl_isAddAllowed()
511 return m_rContext
.allowAddition();
514 //------------------------------------------------------------------------------
515 String
OAddTableDlg::getDialogTitleForContext( IAddTableDialogContext
& _rContext
)
519 ::svt::OLocalResourceAccess
aLocalRes( ModuleRes( DLG_JOIN_TABADD
), RSC_MODELESSDIALOG
);
520 if ( _rContext
.allowQueries() )
521 sTitle
= String( ModuleRes( STR_ADD_TABLE_OR_QUERY
) );
523 sTitle
= String( ModuleRes( STR_ADD_TABLES
) );
528 // -----------------------------------------------------------------------------
530 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */