1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 #include "adtabdlg.hxx"
21 #include "sqlmessage.hxx"
22 #include <tools/debug.hxx>
23 #include <tools/diagnose_ex.h>
24 #include <svtools/localresaccess.hxx>
25 #include "dbaccess_helpid.hrc"
26 #include "dbu_resource.hrc"
27 #include "dbu_dlg.hrc"
28 #include <sfx2/sfxsids.hrc>
29 #include "QueryTableView.hxx"
30 #include "QueryDesignView.hxx"
31 #include "querycontroller.hxx"
32 #include <connectivity/dbtools.hxx>
33 #include "browserids.hxx"
34 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
35 #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
36 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
37 #include <com/sun/star/container/XNameAccess.hpp>
38 #include "UITools.hxx"
39 #include "imageprovider.hxx"
40 #include <comphelper/containermultiplexer.hxx>
41 #include "cppuhelper/basemutex.hxx"
45 using namespace dbaui
;
46 using namespace ::com::sun::star
;
47 using namespace ::com::sun::star::uno
;
48 using namespace ::com::sun::star::container
;
49 using namespace ::com::sun::star::sdb
;
50 using namespace ::com::sun::star::sdbc
;
51 using namespace ::com::sun::star::sdbcx
;
52 using namespace dbtools
;
54 TableObjectListFacade::~TableObjectListFacade()
58 class TableListFacade
: public ::cppu::BaseMutex
59 , public TableObjectListFacade
60 , public ::comphelper::OContainerListener
62 OTableTreeListBox
& m_rTableList
;
63 Reference
< XConnection
> m_xConnection
;
64 ::rtl::Reference
< comphelper::OContainerListenerAdapter
>
69 TableListFacade( OTableTreeListBox
& _rTableList
, const Reference
< XConnection
>& _rxConnection
)
70 : ::comphelper::OContainerListener(m_aMutex
)
71 ,m_rTableList( _rTableList
)
72 ,m_xConnection( _rxConnection
)
76 virtual ~TableListFacade();
79 virtual void updateTableObjectList( bool _bAllowViews
) SAL_OVERRIDE
;
80 virtual OUString
getSelectedName( OUString
& _out_rAliasName
) const SAL_OVERRIDE
;
81 virtual bool isLeafSelected() const SAL_OVERRIDE
;
83 virtual void _elementInserted( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
84 virtual void _elementRemoved( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
85 virtual void _elementReplaced( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
88 TableListFacade::~TableListFacade()
90 if ( m_pContainerListener
.is() )
91 m_pContainerListener
->dispose();
94 OUString
TableListFacade::getSelectedName( OUString
& _out_rAliasName
) const
96 SvTreeListEntry
* pEntry
= m_rTableList
.FirstSelected();
100 OUString aCatalog
, aSchema
, aTableName
;
101 SvTreeListEntry
* pSchema
= m_rTableList
.GetParent(pEntry
);
102 if(pSchema
&& pSchema
!= m_rTableList
.getAllObjectsEntry())
104 SvTreeListEntry
* pCatalog
= m_rTableList
.GetParent(pSchema
);
105 if(pCatalog
&& pCatalog
!= m_rTableList
.getAllObjectsEntry())
106 aCatalog
= m_rTableList
.GetEntryText(pCatalog
);
107 aSchema
= m_rTableList
.GetEntryText(pSchema
);
109 aTableName
= m_rTableList
.GetEntryText(pEntry
);
111 OUString aComposedName
;
114 Reference
< XDatabaseMetaData
> xMeta( m_xConnection
->getMetaData(), UNO_QUERY_THROW
);
115 if ( aCatalog
.isEmpty()
116 && !aSchema
.isEmpty()
117 && xMeta
->supportsCatalogsInDataManipulation()
118 && !xMeta
->supportsSchemasInDataManipulation() )
124 aComposedName
= ::dbtools::composeTableName(
125 xMeta
, aCatalog
, aSchema
, aTableName
, false, ::dbtools::eInDataManipulation
);
127 catch ( const Exception
& )
129 DBG_UNHANDLED_EXCEPTION();
132 _out_rAliasName
= aTableName
;
133 return aComposedName
;
136 void TableListFacade::_elementInserted( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
138 updateTableObjectList(m_bAllowViews
);
141 void TableListFacade::_elementRemoved( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
143 updateTableObjectList(m_bAllowViews
);
146 void TableListFacade::_elementReplaced( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
150 void TableListFacade::updateTableObjectList( bool _bAllowViews
)
152 m_bAllowViews
= _bAllowViews
;
153 m_rTableList
.Clear();
156 Reference
< XTablesSupplier
> xTableSupp( m_xConnection
, UNO_QUERY_THROW
);
158 Reference
< XViewsSupplier
> xViewSupp
;
159 Reference
< XNameAccess
> xTables
, xViews
;
160 Sequence
< OUString
> sTables
, sViews
;
162 xTables
= xTableSupp
->getTables();
165 if ( !m_pContainerListener
.is() )
167 Reference
< XContainer
> xContainer(xTables
,uno::UNO_QUERY
);
168 if ( xContainer
.is() )
169 m_pContainerListener
= new ::comphelper::OContainerListenerAdapter(this,xContainer
);
171 sTables
= xTables
->getElementNames();
174 xViewSupp
.set( xTableSupp
, UNO_QUERY
);
175 if ( xViewSupp
.is() )
177 xViews
= xViewSupp
->getViews();
179 sViews
= xViews
->getElementNames();
182 // if no views are allowed remove the views also out the table name filter
185 const OUString
* pTableBegin
= sTables
.getConstArray();
186 const OUString
* pTableEnd
= pTableBegin
+ sTables
.getLength();
187 ::std::vector
< OUString
> aTables(pTableBegin
,pTableEnd
);
189 const OUString
* pViewBegin
= sViews
.getConstArray();
190 const OUString
* pViewEnd
= pViewBegin
+ sViews
.getLength();
191 ::comphelper::UStringMixEqual aEqualFunctor
;
192 for(;pViewBegin
!= pViewEnd
;++pViewBegin
)
193 aTables
.erase(::std::remove_if(aTables
.begin(),aTables
.end(),::std::bind2nd(aEqualFunctor
,*pViewBegin
)),aTables
.end());
194 sTables
= Sequence
< OUString
>(aTables
.data(), aTables
.size());
195 sViews
= Sequence
< OUString
>();
198 m_rTableList
.UpdateTableList( m_xConnection
, sTables
, sViews
);
199 SvTreeListEntry
* pEntry
= m_rTableList
.First();
200 while( pEntry
&& m_rTableList
.GetModel()->HasChildren( pEntry
) )
202 m_rTableList
.Expand( pEntry
);
203 pEntry
= m_rTableList
.Next( pEntry
);
206 m_rTableList
.Select(pEntry
);
208 catch( const Exception
& )
210 DBG_UNHANDLED_EXCEPTION();
214 bool TableListFacade::isLeafSelected() const
216 SvTreeListEntry
* pEntry
= m_rTableList
.FirstSelected();
217 return pEntry
&& !m_rTableList
.GetModel()->HasChildren( pEntry
);
220 class QueryListFacade
: public ::cppu::BaseMutex
221 , public TableObjectListFacade
222 , public ::comphelper::OContainerListener
224 SvTreeListBox
& m_rQueryList
;
225 Reference
< XConnection
> m_xConnection
;
226 ::rtl::Reference
< comphelper::OContainerListenerAdapter
>
227 m_pContainerListener
;
230 QueryListFacade( SvTreeListBox
& _rQueryList
, const Reference
< XConnection
>& _rxConnection
)
231 : ::comphelper::OContainerListener(m_aMutex
)
232 ,m_rQueryList( _rQueryList
)
233 ,m_xConnection( _rxConnection
)
236 virtual ~QueryListFacade();
239 virtual void updateTableObjectList( bool _bAllowViews
) SAL_OVERRIDE
;
240 virtual OUString
getSelectedName( OUString
& _out_rAliasName
) const SAL_OVERRIDE
;
241 virtual bool isLeafSelected() const SAL_OVERRIDE
;
242 // OContainerListener
243 virtual void _elementInserted( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
244 virtual void _elementRemoved( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
245 virtual void _elementReplaced( const ::com::sun::star::container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
248 QueryListFacade::~QueryListFacade()
250 if ( m_pContainerListener
.is() )
251 m_pContainerListener
->dispose();
254 void QueryListFacade::_elementInserted( const container::ContainerEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
257 if ( _rEvent
.Accessor
>>= sName
)
258 m_rQueryList
.InsertEntry( sName
);
261 void QueryListFacade::_elementRemoved( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
263 updateTableObjectList(true);
266 void QueryListFacade::_elementReplaced( const container::ContainerEvent
& /*_rEvent*/ ) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
270 void QueryListFacade::updateTableObjectList( bool /*_bAllowViews*/ )
272 m_rQueryList
.Clear();
275 ImageProvider
aImageProvider( m_xConnection
);
276 Image
aQueryImage( ImageProvider::getDefaultImage( css::sdb::application::DatabaseObject::QUERY
) );
278 m_rQueryList
.SetDefaultExpandedEntryBmp( aQueryImage
);
279 m_rQueryList
.SetDefaultCollapsedEntryBmp( aQueryImage
);
281 Reference
< XQueriesSupplier
> xSuppQueries( m_xConnection
, UNO_QUERY_THROW
);
282 Reference
< XNameAccess
> xQueries( xSuppQueries
->getQueries(), UNO_QUERY_THROW
);
283 if ( !m_pContainerListener
.is() )
285 Reference
< XContainer
> xContainer(xQueries
,UNO_QUERY_THROW
);
286 m_pContainerListener
= new ::comphelper::OContainerListenerAdapter(this,xContainer
);
288 Sequence
< OUString
> aQueryNames
= xQueries
->getElementNames();
290 const OUString
* pQuery
= aQueryNames
.getConstArray();
291 const OUString
* pQueryEnd
= aQueryNames
.getConstArray() + aQueryNames
.getLength();
292 while ( pQuery
!= pQueryEnd
)
293 m_rQueryList
.InsertEntry( *pQuery
++ );
295 catch( const Exception
& )
297 DBG_UNHANDLED_EXCEPTION();
301 OUString
QueryListFacade::getSelectedName( OUString
& _out_rAliasName
) const
304 SvTreeListEntry
* pEntry
= m_rQueryList
.FirstSelected();
306 sSelected
= _out_rAliasName
= m_rQueryList
.GetEntryText( pEntry
);
310 bool QueryListFacade::isLeafSelected() const
312 SvTreeListEntry
* pEntry
= m_rQueryList
.FirstSelected();
313 return pEntry
&& !m_rQueryList
.GetModel()->HasChildren( pEntry
);
316 OAddTableDlg::OAddTableDlg( vcl::Window
* pParent
, IAddTableDialogContext
& _rContext
)
317 : ModelessDialog(pParent
, "TablesJoinDialog", "dbaccess/ui/tablesjoindialog.ui")
318 , m_rContext(_rContext
)
320 get(m_pCaseTables
, "tables");
321 get(m_pCaseQueries
, "queries");
323 get(m_pTableList
, "tablelist");
324 get(m_pQueryList
, "querylist");
325 Size
aSize(LogicToPixel(Size(106 , 122), MAP_APPFONT
));
326 m_pTableList
->set_height_request(aSize
.Height());
327 m_pTableList
->set_width_request(aSize
.Width());
328 get(m_pQueryList
, "querylist");
329 m_pQueryList
->set_height_request(aSize
.Height());
330 m_pQueryList
->set_width_request(aSize
.Width());
332 get(m_pAddButton
, "add");
333 get(m_pCloseButton
, "close");
335 m_pCaseTables
->SetClickHdl( LINK( this, OAddTableDlg
, OnTypeSelected
) );
336 m_pCaseQueries
->SetClickHdl( LINK( this, OAddTableDlg
, OnTypeSelected
) );
337 m_pAddButton
->SetClickHdl( LINK( this, OAddTableDlg
, AddClickHdl
) );
338 m_pCloseButton
->SetClickHdl( LINK( this, OAddTableDlg
, CloseClickHdl
) );
339 m_pTableList
->SetDoubleClickHdl( LINK( this, OAddTableDlg
, TableListDoubleClickHdl
) );
340 m_pTableList
->SetSelectHdl( LINK( this, OAddTableDlg
, TableListSelectHdl
) );
341 m_pQueryList
->SetDoubleClickHdl( LINK( this, OAddTableDlg
, TableListDoubleClickHdl
) );
342 m_pQueryList
->SetSelectHdl( LINK( this, OAddTableDlg
, TableListSelectHdl
) );
344 m_pTableList
->EnableInplaceEditing( false );
345 m_pTableList
->SetStyle(m_pTableList
->GetStyle() | WB_BORDER
| WB_HASLINES
|WB_HASBUTTONS
| WB_HASBUTTONSATROOT
| WB_HASLINESATROOT
| WB_SORT
| WB_HSCROLL
);
346 m_pTableList
->EnableCheckButton( NULL
); // do not show any buttons
347 m_pTableList
->SetSelectionMode( SINGLE_SELECTION
);
348 m_pTableList
->notifyHiContrastChanged();
349 m_pTableList
->suppressEmptyFolders();
351 m_pQueryList
->EnableInplaceEditing( false );
352 m_pQueryList
->SetSelectionMode( SINGLE_SELECTION
);
354 if ( !m_rContext
.allowQueries() )
356 m_pCaseTables
->Hide();
357 m_pCaseQueries
->Hide();
360 SetText( getDialogTitleForContext( m_rContext
) );
363 OAddTableDlg::~OAddTableDlg()
368 void OAddTableDlg::dispose()
370 m_rContext
.onWindowClosing( this );
371 m_pCaseTables
.clear();
372 m_pCaseQueries
.clear();
373 m_pTableList
.clear();
374 m_pQueryList
.clear();
375 m_pAddButton
.clear();
376 m_pCloseButton
.clear();
377 ModelessDialog::dispose();
380 void OAddTableDlg::impl_switchTo( ObjectList _eList
)
385 m_pTableList
->Show( true ); m_pCaseTables
->Check( true );
386 m_pQueryList
->Show( false ); m_pCaseQueries
->Check( false );
387 m_xCurrentList
.reset( new TableListFacade( *m_pTableList
, m_rContext
.getConnection() ) );
388 m_pTableList
->GrabFocus();
392 m_pTableList
->Show( false ); m_pCaseTables
->Check( false );
393 m_pQueryList
->Show( true ); m_pCaseQueries
->Check( true );
394 m_xCurrentList
.reset( new QueryListFacade( *m_pQueryList
, m_rContext
.getConnection() ) );
395 m_pQueryList
->GrabFocus();
398 m_xCurrentList
->updateTableObjectList( m_rContext
.allowViews() );
401 void OAddTableDlg::Update()
403 if ( !m_xCurrentList
.get() )
404 impl_switchTo( Tables
);
406 m_xCurrentList
->updateTableObjectList( m_rContext
.allowViews() );
409 void OAddTableDlg::impl_addTable()
411 if ( m_xCurrentList
->isLeafSelected() )
413 OUString sSelectedName
, sAliasName
;
414 sSelectedName
= m_xCurrentList
->getSelectedName( sAliasName
);
416 m_rContext
.addTableWindow( sSelectedName
, sAliasName
);
420 IMPL_LINK( OAddTableDlg
, AddClickHdl
, Button
*, /*pButton*/ )
422 TableListDoubleClickHdl(NULL
);
426 IMPL_LINK_NOARG( OAddTableDlg
, TableListDoubleClickHdl
)
428 if ( impl_isAddAllowed() )
431 if ( !impl_isAddAllowed() )
433 return 1L; // handled
436 return 0L; // not handled
439 IMPL_LINK_NOARG( OAddTableDlg
, TableListSelectHdl
)
441 m_pAddButton
->Enable( m_xCurrentList
->isLeafSelected() );
445 IMPL_LINK( OAddTableDlg
, CloseClickHdl
, Button
*, /*pButton*/ )
450 IMPL_LINK_NOARG( OAddTableDlg
, OnTypeSelected
)
452 if ( m_pCaseTables
->IsChecked() )
453 impl_switchTo( Tables
);
455 impl_switchTo( Queries
);
459 bool OAddTableDlg::Close()
461 m_rContext
.onWindowClosing( this );
462 return ModelessDialog::Close();
465 bool OAddTableDlg::impl_isAddAllowed()
467 return m_rContext
.allowAddition();
470 OUString
OAddTableDlg::getDialogTitleForContext( IAddTableDialogContext
& _rContext
)
474 if ( _rContext
.allowQueries() )
475 sTitle
= ModuleRes( STR_ADD_TABLE_OR_QUERY
);
477 sTitle
= ModuleRes( STR_ADD_TABLES
);
482 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */