Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "browserids.hxx"
21 : #include "dbaccess_helpid.hrc"
22 : #include "dbexchange.hxx"
23 : #include "dbtreelistbox.hxx"
24 : #include "dbtreemodel.hxx"
25 : #include "dbtreeview.hxx"
26 : #include "dbu_brw.hrc"
27 : #include "dbu_reghelper.hxx"
28 : #include "dbustrings.hrc"
29 : #include "dlgsave.hxx"
30 : #include "uiservices.hxx"
31 : #include "HtmlReader.hxx"
32 : #include "imageprovider.hxx"
33 : #include "listviewitems.hxx"
34 : #include "QEnumTypes.hxx"
35 : #include "RtfReader.hxx"
36 : #include "sbagrid.hrc"
37 : #include "sbagrid.hxx"
38 : #include "sqlmessage.hxx"
39 : #include "TokenWriter.hxx"
40 : #include "UITools.hxx"
41 : #include "unodatbr.hxx"
42 : #include "WColumnSelect.hxx"
43 : #include "WCopyTable.hxx"
44 : #include "WCPage.hxx"
45 : #include "WExtendPages.hxx"
46 : #include "WNameMatch.hxx"
47 :
48 : #include <com/sun/star/awt/LineEndFormat.hpp>
49 : #include <com/sun/star/awt/MouseWheelBehavior.hpp>
50 : #include <com/sun/star/awt/TextAlign.hpp>
51 : #include <com/sun/star/awt/VisualEffect.hpp>
52 : #include <com/sun/star/beans/NamedValue.hpp>
53 : #include <com/sun/star/beans/PropertyValue.hpp>
54 : #include <com/sun/star/container/XNameContainer.hpp>
55 : #include <com/sun/star/form/XForm.hpp>
56 : #include <com/sun/star/form/XGridColumnFactory.hpp>
57 : #include <com/sun/star/form/XLoadable.hpp>
58 : #include <com/sun/star/form/XReset.hpp>
59 : #include <com/sun/star/frame/Desktop.hpp>
60 : #include <com/sun/star/frame/FrameSearchFlag.hpp>
61 : #include <com/sun/star/frame/XLayoutManager.hpp>
62 : #include <com/sun/star/lang/DisposedException.hpp>
63 : #include <com/sun/star/i18n/Collator.hpp>
64 : #include <com/sun/star/sdb/CommandType.hpp>
65 : #include <com/sun/star/sdb/SQLContext.hpp>
66 : #include <com/sun/star/sdb/XBookmarksSupplier.hpp>
67 : #include <com/sun/star/sdb/XCompletedConnection.hpp>
68 : #include <com/sun/star/sdb/XDatabaseRegistrations.hpp>
69 : #include <com/sun/star/sdb/XDocumentDataSource.hpp>
70 : #include <com/sun/star/sdb/XParametersSupplier.hpp>
71 : #include <com/sun/star/sdb/XQueriesSupplier.hpp>
72 : #include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
73 : #include <com/sun/star/sdb/XResultSetAccess.hpp>
74 : #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
75 : #include <com/sun/star/sdb/application/NamedDatabaseObject.hpp>
76 : #include <com/sun/star/sdbc/ColumnValue.hpp>
77 : #include <com/sun/star/sdbc/DataType.hpp>
78 : #include <com/sun/star/sdbc/FetchDirection.hpp>
79 : #include <com/sun/star/sdbc/SQLWarning.hpp>
80 : #include <com/sun/star/sdbc/XDataSource.hpp>
81 : #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
82 : #include <com/sun/star/sdbc/XWarningsSupplier.hpp>
83 : #include <com/sun/star/sdbcx/Privilege.hpp>
84 : #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
85 : #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
86 : #include <com/sun/star/sdbcx/XDrop.hpp>
87 : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
88 : #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
89 : #include <com/sun/star/task/InteractionHandler.hpp>
90 : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
91 : #include <com/sun/star/util/XFlushable.hpp>
92 : #include <com/sun/star/document/MacroExecMode.hpp>
93 : #include <com/sun/star/frame/XComponentLoader.hpp>
94 : #include <com/sun/star/ui/XContextMenuInterceptor.hpp>
95 :
96 : #include <comphelper/processfactory.hxx>
97 : #include <comphelper/extract.hxx>
98 : #include <comphelper/sequence.hxx>
99 : #include <comphelper/types.hxx>
100 : #include <connectivity/dbexception.hxx>
101 : #include <cppuhelper/exc_hlp.hxx>
102 : #include <cppuhelper/implbase2.hxx>
103 : #include <cppuhelper/typeprovider.hxx>
104 : #include <sfx2/app.hxx>
105 : #include <sfx2/dispatch.hxx>
106 : #include <sot/storage.hxx>
107 : #include <svl/filenotation.hxx>
108 : #include <svl/intitem.hxx>
109 : #include <unotools/moduleoptions.hxx>
110 : #include <svtools/svlbitm.hxx>
111 : #include <svtools/treelistbox.hxx>
112 : #include "svtools/treelistentry.hxx"
113 : #include <svx/algitem.hxx>
114 : #include <svx/dataaccessdescriptor.hxx>
115 : #include <svx/databaseregistrationui.hxx>
116 : #include <toolkit/helper/vclunohelper.hxx>
117 : #include <tools/diagnose_ex.h>
118 : #include <osl/diagnose.h>
119 : #include <tools/multisel.hxx>
120 : #include <tools/urlobj.hxx>
121 : #include <unotools/confignode.hxx>
122 : #include <vcl/msgbox.hxx>
123 : #include <vcl/split.hxx>
124 : #include <vcl/stdtext.hxx>
125 : #include <vcl/svapp.hxx>
126 : #include <vcl/toolbox.hxx>
127 : #include <vcl/waitobj.hxx>
128 : #include <vcl/wrkwin.hxx>
129 : #include <vcl/settings.hxx>
130 :
131 : #include <memory>
132 :
133 : using namespace ::com::sun::star::uno;
134 : using namespace ::com::sun::star::awt;
135 : using namespace ::com::sun::star::sdb;
136 : using namespace ::com::sun::star::sdb::application;
137 : using namespace ::com::sun::star::sdbc;
138 : using namespace ::com::sun::star::sdbcx;
139 : using namespace ::com::sun::star::beans;
140 : using namespace ::com::sun::star::util;
141 : using namespace ::com::sun::star::frame;
142 : using namespace ::com::sun::star::container;
143 : using namespace ::com::sun::star::lang;
144 : using namespace ::com::sun::star::ui::dialogs;
145 : using namespace ::com::sun::star::task;
146 : using namespace ::com::sun::star::form;
147 : using namespace ::com::sun::star::io;
148 : using namespace ::com::sun::star::i18n;
149 : using namespace ::com::sun::star::view;
150 : using namespace ::com::sun::star::datatransfer;
151 : using namespace ::com::sun::star::document;
152 : using namespace ::com::sun::star::ui;
153 : using namespace ::dbtools;
154 : using namespace ::comphelper;
155 : using namespace ::svx;
156 :
157 : // SbaTableQueryBrowser
158 12 : extern "C" void SAL_CALL createRegistryInfo_OBrowser()
159 : {
160 12 : static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::SbaTableQueryBrowser > aAutoRegistration;
161 12 : }
162 :
163 : namespace dbaui
164 : {
165 :
166 : namespace DatabaseObject = css::sdb::application::DatabaseObject;
167 : namespace DatabaseObjectContainer = css::sdb::application::DatabaseObjectContainer;
168 :
169 124 : void SafeAddPropertyListener(const Reference< XPropertySet > & xSet, const OUString& rPropName, XPropertyChangeListener* pListener)
170 : {
171 124 : Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
172 124 : if (xInfo->hasPropertyByName(rPropName))
173 107 : xSet->addPropertyChangeListener(rPropName, pListener);
174 124 : }
175 :
176 124 : void SafeRemovePropertyListener(const Reference< XPropertySet > & xSet, const OUString& rPropName, XPropertyChangeListener* pListener)
177 : {
178 124 : Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
179 124 : if (xInfo->hasPropertyByName(rPropName))
180 107 : xSet->removePropertyChangeListener(rPropName, pListener);
181 124 : }
182 :
183 1 : OUString SAL_CALL SbaTableQueryBrowser::getImplementationName() throw(RuntimeException, std::exception)
184 : {
185 1 : return getImplementationName_Static();
186 : }
187 :
188 1 : ::comphelper::StringSequence SAL_CALL SbaTableQueryBrowser::getSupportedServiceNames() throw(RuntimeException, std::exception)
189 : {
190 1 : return getSupportedServiceNames_Static();
191 : }
192 :
193 25 : OUString SbaTableQueryBrowser::getImplementationName_Static() throw(RuntimeException)
194 : {
195 25 : return OUString("org.openoffice.comp.dbu.ODatasourceBrowser");
196 : }
197 :
198 13 : ::comphelper::StringSequence SbaTableQueryBrowser::getSupportedServiceNames_Static() throw(RuntimeException)
199 : {
200 13 : ::comphelper::StringSequence aSupported(1);
201 13 : aSupported[0] = "com.sun.star.sdb.DataSourceBrowser";
202 13 : return aSupported;
203 : }
204 :
205 2 : Reference< XInterface > SAL_CALL SbaTableQueryBrowser::Create(const Reference<XMultiServiceFactory >& _rxFactory)
206 : {
207 2 : SolarMutexGuard aGuard;
208 2 : return *(new SbaTableQueryBrowser(comphelper::getComponentContext(_rxFactory)));
209 : }
210 :
211 2 : SbaTableQueryBrowser::SbaTableQueryBrowser(const Reference< XComponentContext >& _rM)
212 : :SbaXDataBrowserController(_rM)
213 2 : ,m_aSelectionListeners( getMutex() )
214 2 : ,m_aContextMenuInterceptors( getMutex() )
215 : ,m_aTableCopyHelper(this)
216 : ,m_pTreeView(NULL)
217 : ,m_pSplitter(NULL)
218 : ,m_pTreeModel(NULL)
219 : ,m_pCurrentlyDisplayed(NULL)
220 : ,m_nAsyncDrop(0)
221 : ,m_nBorder(1)
222 : ,m_bQueryEscapeProcessing( false )
223 : ,m_bShowMenu(false)
224 : ,m_bInSuspend(false)
225 6 : ,m_bEnableBrowser(true)
226 : {
227 2 : }
228 :
229 6 : SbaTableQueryBrowser::~SbaTableQueryBrowser()
230 : {
231 2 : if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
232 : {
233 : SAL_WARN("dbaccess.ui", "Please check who doesn't dispose this component!");
234 : // increment ref count to prevent double call of Dtor
235 0 : osl_atomic_increment( &m_refCount );
236 0 : dispose();
237 : }
238 4 : }
239 :
240 114 : Any SAL_CALL SbaTableQueryBrowser::queryInterface(const Type& _rType) throw (RuntimeException, std::exception)
241 : {
242 114 : if ( _rType.equals( cppu::UnoType<XScriptInvocationContext>::get() ) )
243 : {
244 : OSL_PRECOND( !!m_aDocScriptSupport, "SbaTableQueryBrowser::queryInterface: did not initialize this, yet!" );
245 0 : if ( !!m_aDocScriptSupport && *m_aDocScriptSupport )
246 0 : return makeAny( Reference< XScriptInvocationContext >( this ) );
247 0 : return Any();
248 : }
249 :
250 114 : Any aReturn = SbaXDataBrowserController::queryInterface(_rType);
251 114 : if (!aReturn.hasValue())
252 10 : aReturn = SbaTableQueryBrowser_Base::queryInterface(_rType);
253 114 : return aReturn;
254 : }
255 :
256 0 : Sequence< Type > SAL_CALL SbaTableQueryBrowser::getTypes( ) throw (RuntimeException, std::exception)
257 : {
258 : Sequence< Type > aTypes( ::comphelper::concatSequences(
259 : SbaXDataBrowserController::getTypes(),
260 : SbaTableQueryBrowser_Base::getTypes()
261 0 : ) );
262 :
263 : OSL_PRECOND( !!m_aDocScriptSupport, "SbaTableQueryBrowser::getTypes: did not initialize this, yet!" );
264 0 : if ( !m_aDocScriptSupport || !*m_aDocScriptSupport )
265 : {
266 0 : Sequence< Type > aStrippedTypes( aTypes.getLength() - 1 );
267 : ::std::remove_copy_if(
268 : aTypes.getConstArray(),
269 0 : aTypes.getConstArray() + aTypes.getLength(),
270 : aStrippedTypes.getArray(),
271 0 : ::std::bind2nd( ::std::equal_to< Type >(), cppu::UnoType<XScriptInvocationContext>::get() )
272 0 : );
273 0 : aTypes = aStrippedTypes;
274 : }
275 0 : return aTypes;
276 : }
277 :
278 0 : Sequence< sal_Int8 > SAL_CALL SbaTableQueryBrowser::getImplementationId( ) throw (RuntimeException, std::exception)
279 : {
280 0 : return css::uno::Sequence<sal_Int8>();
281 : }
282 :
283 2 : void SAL_CALL SbaTableQueryBrowser::disposing()
284 : {
285 2 : SolarMutexGuard aGuard;
286 : // doin' a lot of VCL stuff here -> lock the SolarMutex
287 :
288 : // kiss our listeners goodbye
289 4 : com::sun::star::lang::EventObject aEvt(*this);
290 2 : m_aSelectionListeners.disposeAndClear(aEvt);
291 2 : m_aContextMenuInterceptors.disposeAndClear(aEvt);
292 :
293 : // reset the content's tree view: it holds a reference to our model which is to be deleted immediately,
294 : // and it will live longer than we do.
295 2 : if (getBrowserView())
296 1 : getBrowserView()->setTreeView(NULL);
297 :
298 2 : clearTreeModel();
299 : // clear the tree model
300 : {
301 2 : ::std::unique_ptr<SvTreeList> aTemp(m_pTreeModel);
302 2 : m_pTreeModel = NULL;
303 : }
304 :
305 : // remove ourself as status listener
306 2 : implRemoveStatusListeners();
307 :
308 : // remove the container listener from the database context
309 : try
310 : {
311 2 : Reference< XDatabaseRegistrations > xDatabaseRegistrations( m_xDatabaseContext, UNO_QUERY_THROW );
312 1 : xDatabaseRegistrations->removeDatabaseRegistrationsListener( this );
313 : }
314 1 : catch( const Exception& )
315 : {
316 : DBG_UNHANDLED_EXCEPTION();
317 : }
318 :
319 : // check out from all the objects we are listening
320 : // the frame
321 2 : if (m_xCurrentFrameParent.is())
322 1 : m_xCurrentFrameParent->removeFrameActionListener(static_cast<com::sun::star::frame::XFrameActionListener*>(this));
323 4 : SbaXDataBrowserController::disposing();
324 2 : }
325 :
326 1 : bool SbaTableQueryBrowser::Construct(vcl::Window* pParent)
327 : {
328 1 : if ( !SbaXDataBrowserController::Construct( pParent ) )
329 0 : return false;
330 :
331 : try
332 : {
333 1 : Reference< XDatabaseRegistrations > xDatabaseRegistrations( m_xDatabaseContext, UNO_QUERY_THROW );
334 1 : xDatabaseRegistrations->addDatabaseRegistrationsListener( this );
335 :
336 : // the collator for the string compares
337 1 : m_xCollator = Collator::create( getORB() );
338 1 : m_xCollator->loadDefaultCollator( Application::GetSettings().GetLanguageTag().getLocale(), 0 );
339 : }
340 0 : catch(const Exception&)
341 : {
342 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::Construct: could not create (or start listening at) the database context!");
343 : }
344 : // some help ids
345 1 : if (getBrowserView() && getBrowserView()->getVclControl())
346 : {
347 :
348 : // create controls and set sizes
349 1 : const long nFrameWidth = getBrowserView()->LogicToPixel( ::Size( 3, 0 ), MAP_APPFONT ).Width();
350 :
351 1 : m_pSplitter = VclPtr<Splitter>::Create(getBrowserView(),WB_HSCROLL);
352 1 : m_pSplitter->SetPosSizePixel( ::Point(0,0), ::Size(nFrameWidth,0) );
353 1 : m_pSplitter->SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetDialogColor() ) );
354 :
355 1 : m_pTreeView = VclPtr<DBTreeView>::Create(getBrowserView(), WB_TABSTOP | WB_BORDER);
356 1 : m_pTreeView->SetPreExpandHandler(LINK(this, SbaTableQueryBrowser, OnExpandEntry));
357 :
358 1 : m_pTreeView->setCopyHandler(LINK(this, SbaTableQueryBrowser, OnCopyEntry));
359 :
360 1 : m_pTreeView->getListBox().setContextMenuProvider( this );
361 1 : m_pTreeView->getListBox().setControlActionListener( this );
362 1 : m_pTreeView->SetHelpId(HID_CTL_TREEVIEW);
363 :
364 : // a default pos for the splitter, so that the listbox is about 80 (logical) pixels wide
365 1 : m_pSplitter->SetSplitPosPixel( getBrowserView()->LogicToPixel( ::Size( 80, 0 ), MAP_APPFONT ).Width() );
366 :
367 1 : getBrowserView()->setSplitter(m_pSplitter);
368 1 : getBrowserView()->setTreeView(m_pTreeView);
369 :
370 : // fill view with data
371 1 : m_pTreeModel = new SvTreeList;
372 1 : m_pTreeModel->SetSortMode(SortAscending);
373 1 : m_pTreeModel->SetCompareHdl(LINK(this, SbaTableQueryBrowser, OnTreeEntryCompare));
374 1 : m_pTreeView->setModel(m_pTreeModel);
375 1 : m_pTreeView->setSelChangeHdl( LINK( this, SbaTableQueryBrowser, OnSelectionChange ) );
376 :
377 : // TODO
378 1 : getBrowserView()->getVclControl()->GetDataWindow().SetUniqueId(UID_DATABROWSE_DATAWINDOW);
379 1 : getBrowserView()->getVclControl()->SetHelpId(HID_CTL_TABBROWSER);
380 1 : getBrowserView()->SetUniqueId(UID_CTL_CONTENT);
381 1 : if (getBrowserView()->getVclControl()->GetHeaderBar())
382 1 : getBrowserView()->getVclControl()->GetHeaderBar()->SetHelpId(HID_DATABROWSE_HEADER);
383 1 : InvalidateFeature(ID_BROWSER_EXPLORER);
384 : }
385 :
386 1 : return true;
387 : }
388 :
389 : namespace
390 : {
391 : struct SelectValueByName : public ::std::unary_function< OUString, Any >
392 : {
393 3 : const Any& operator()( OUString const& i_name ) const
394 : {
395 3 : return m_rCollection.get( i_name );
396 : }
397 :
398 1 : SelectValueByName( ::comphelper::NamedValueCollection const& i_collection )
399 1 : :m_rCollection( i_collection )
400 : {
401 1 : }
402 :
403 : ::comphelper::NamedValueCollection const& m_rCollection;
404 : };
405 : }
406 :
407 1 : void SbaTableQueryBrowser::impl_sanitizeRowSetClauses_nothrow()
408 : {
409 : try
410 : {
411 1 : Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW );
412 1 : bool bEscapeProcessing = false;
413 1 : OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bEscapeProcessing );
414 1 : if ( !bEscapeProcessing )
415 : // don't touch or interpret anything if escape processing is disabled
416 0 : return;
417 :
418 2 : Reference< XSingleSelectQueryComposer > xComposer( createParser_nothrow() );
419 1 : if ( !xComposer.is() )
420 : // can't do anything. Already reported via assertion in createParser_nothrow.
421 0 : return;
422 :
423 : // the tables participating in the statement
424 2 : const Reference< XTablesSupplier > xSuppTables( xComposer, UNO_QUERY_THROW );
425 2 : const Reference< XNameAccess > xTableNames( xSuppTables->getTables(), UNO_QUERY_THROW );
426 :
427 : // the columns participating in the statement
428 2 : const Reference< XColumnsSupplier > xSuppColumns( xComposer, UNO_QUERY_THROW );
429 2 : const Reference< XNameAccess > xColumnNames( xSuppColumns->getColumns(), UNO_QUERY_THROW );
430 :
431 : // check if the order columns apply to tables which really exist in the statement
432 2 : const Reference< XIndexAccess > xOrderColumns( xComposer->getOrderColumns(), UNO_SET_THROW );
433 1 : const sal_Int32 nOrderColumns( xOrderColumns->getCount() );
434 1 : bool invalidColumn = nOrderColumns == 0;
435 2 : for ( sal_Int32 c=0; ( c < nOrderColumns ) && !invalidColumn; ++c )
436 : {
437 1 : const Reference< XPropertySet > xOrderColumn( xOrderColumns->getByIndex(c), UNO_QUERY_THROW );
438 2 : OUString sTableName;
439 1 : OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_TABLENAME ) >>= sTableName );
440 2 : OUString sColumnName;
441 1 : OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_NAME ) >>= sColumnName );
442 :
443 1 : if ( sTableName.isEmpty() )
444 : {
445 0 : if ( !xColumnNames->hasByName( sColumnName ) )
446 : {
447 0 : invalidColumn = true;
448 0 : break;
449 : }
450 : }
451 : else
452 : {
453 1 : if ( !xTableNames->hasByName( sTableName ) )
454 : {
455 0 : invalidColumn = true;
456 0 : break;
457 : }
458 :
459 1 : const Reference< XColumnsSupplier > xSuppTableColumns( xTableNames->getByName( sTableName ), UNO_QUERY_THROW );
460 2 : const Reference< XNameAccess > xTableColumnNames( xSuppTableColumns->getColumns(), UNO_QUERY_THROW );
461 1 : if ( !xTableColumnNames->hasByName( sColumnName ) )
462 : {
463 0 : invalidColumn = true;
464 0 : break;
465 1 : }
466 : }
467 1 : }
468 :
469 1 : if ( invalidColumn )
470 : {
471 : // reset the complete order statement at both the row set and the parser
472 0 : const OUString sEmptyOrder;
473 0 : xRowSetProps->setPropertyValue( PROPERTY_ORDER, makeAny( sEmptyOrder ) );
474 0 : xComposer->setOrder( sEmptyOrder );
475 1 : }
476 :
477 : // check if the columns participating in the filter refer to existing tables
478 : // TODO: there's no API at all for this. The method which comes nearest to what we need is
479 : // "getStructuredFilter", but it returns pure column names only. That is, for a statement like
480 : // "SELECT * FROM <table> WHERE <other_table>.<column> = <value>", it will return "<column>". But
481 : // there's no API at all to retrieve the information about "<other_table>" - which is what would
482 : // be needed here.
483 : // That'd be a chance to replace getStructuredFilter with something more reasonable. This method
484 : // has at least one other problem: For a clause like "<column> != <value>", it will return "<column>"
485 : // as column name, "NOT_EQUAL" as operator, and "!= <value>" as value, effectively duplicating the
486 : // information about the operator, and beding all clients to manually remove the "!=" from the value
487 : // string.
488 : // So, what really would be handy, is some
489 : // XNormalizedFilter getNormalizedFilter();
490 : // with
491 : // interface XDisjunctiveFilterExpression
492 : // {
493 : // XConjunctiveFilterTerm getTerm( int index );
494 : // }
495 : // interface XConjunctiveFilterTerm
496 : // {
497 : // ComparisonPredicate getPredicate( int index );
498 : // }
499 : // struct ComparisonPredicate
500 : // {
501 : // XComparisonOperand Lhs;
502 : // SQLFilterOperator Operator;
503 : // XComparisonOperand Rhs;
504 : // }
505 : // interface XComparisonOperand
506 : // {
507 : // SQLFilterOperand Type;
508 : // XPropertySet getColumn();
509 : // string getLiteral();
510 : // ...
511 : // }
512 : // enum SQLFilterOperand { Column, Literal, ... }
513 : // ... or something like this ....
514 : }
515 0 : catch( const Exception& )
516 : {
517 : DBG_UNHANDLED_EXCEPTION();
518 : }
519 : }
520 :
521 2 : bool SbaTableQueryBrowser::InitializeForm( const Reference< XPropertySet > & i_formProperties )
522 : {
523 2 : if(!m_pCurrentlyDisplayed)
524 1 : return true;
525 :
526 : // this method set all format settings from the orignal table or query
527 : try
528 : {
529 1 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
530 1 : ENSURE_OR_RETURN_FALSE( pData, "SbaTableQueryBrowser::InitializeForm: No user data set at the currently displayed entry!" );
531 1 : ENSURE_OR_RETURN_FALSE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeForm: No table available!" );
532 :
533 1 : Reference< XPropertySetInfo > xPSI( pData->xObjectProperties->getPropertySetInfo(), UNO_SET_THROW );
534 :
535 2 : ::comphelper::NamedValueCollection aPropertyValues;
536 :
537 : const OUString aTransferProperties[] =
538 : {
539 : OUString(PROPERTY_APPLYFILTER),
540 : OUString(PROPERTY_FILTER),
541 : OUString(PROPERTY_HAVING_CLAUSE),
542 : OUString(PROPERTY_ORDER)
543 2 : };
544 5 : for (size_t i = 0; i < SAL_N_ELEMENTS(aTransferProperties); ++i)
545 : {
546 4 : if ( !xPSI->hasPropertyByName( aTransferProperties[i] ) )
547 1 : continue;
548 3 : aPropertyValues.put( aTransferProperties[i], pData->xObjectProperties->getPropertyValue( aTransferProperties[i] ) );
549 : }
550 :
551 2 : ::std::vector< OUString > aNames( aPropertyValues.getNames() );
552 1 : ::std::sort(aNames.begin(), aNames.end());
553 2 : Sequence< OUString > aPropNames( aNames.size() );
554 1 : ::std::copy( aNames.begin(), aNames.end(), aPropNames.getArray() );
555 :
556 2 : Sequence< Any > aPropValues( aNames.size() );
557 1 : ::std::transform( aNames.begin(), aNames.end(), aPropValues.getArray(), SelectValueByName( aPropertyValues ) );
558 :
559 2 : Reference< XMultiPropertySet > xFormMultiSet( i_formProperties, UNO_QUERY_THROW );
560 1 : xFormMultiSet->setPropertyValues( aPropNames, aPropValues );
561 :
562 2 : impl_sanitizeRowSetClauses_nothrow();
563 : }
564 0 : catch ( const Exception& )
565 : {
566 : DBG_UNHANDLED_EXCEPTION();
567 0 : return false;
568 : }
569 :
570 1 : return true;
571 : }
572 :
573 0 : void SbaTableQueryBrowser::initializePreviewMode()
574 : {
575 0 : if ( getBrowserView() && getBrowserView()->getVclControl() )
576 : {
577 0 : getBrowserView()->getVclControl()->AlwaysEnableInput( false );
578 0 : getBrowserView()->getVclControl()->EnableInput( false );
579 0 : getBrowserView()->getVclControl()->ForceHideScrollbars( true );
580 : }
581 0 : Reference< XPropertySet > xDataSourceSet(getRowSet(), UNO_QUERY);
582 0 : if ( xDataSourceSet.is() )
583 : {
584 0 : xDataSourceSet->setPropertyValue("AllowInserts",makeAny(sal_False));
585 0 : xDataSourceSet->setPropertyValue("AllowUpdates",makeAny(sal_False));
586 0 : xDataSourceSet->setPropertyValue("AllowDeletes",makeAny(sal_False));
587 0 : }
588 0 : }
589 :
590 1 : bool SbaTableQueryBrowser::InitializeGridModel(const Reference< ::com::sun::star::form::XFormComponent > & xGrid)
591 : {
592 : try
593 : {
594 1 : Reference< ::com::sun::star::form::XGridColumnFactory > xColFactory(xGrid, UNO_QUERY);
595 2 : Reference< XNameContainer > xColContainer(xGrid, UNO_QUERY);
596 1 : clearGridColumns( xColContainer );
597 :
598 2 : Reference< XChild > xGridAsChild(xGrid, UNO_QUERY);
599 2 : Reference< XLoadable > xFormAsLoadable;
600 1 : if (xGridAsChild.is())
601 1 : xFormAsLoadable.set(xGridAsChild->getParent(), css::uno::UNO_QUERY);
602 1 : if (xFormAsLoadable.is() && xFormAsLoadable->isLoaded())
603 : {
604 : // set the formats from the table
605 1 : if(m_pCurrentlyDisplayed)
606 : {
607 1 : Sequence< OUString> aProperties(6 + ( m_bPreview ? 5 : 0 ));
608 2 : Sequence< Any> aValues(7 + ( m_bPreview ? 5 : 0 ));
609 :
610 1 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
611 : OSL_ENSURE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeGridModel: No table available!" );
612 1 : if ( !pData->xObjectProperties.is() )
613 0 : return false;
614 :
615 1 : OUString* pStringIter = aProperties.getArray();
616 1 : Any* pValueIter = aValues.getArray();
617 1 : if ( m_bPreview )
618 : {
619 0 : *pStringIter++ = "AlwaysShowCursor";
620 0 : *pValueIter++ <<= sal_False;
621 0 : *pStringIter++ = PROPERTY_BORDER;
622 0 : *pValueIter++ <<= sal_Int16(0);
623 : }
624 :
625 1 : *pStringIter++ = PROPERTY_FONT;
626 1 : *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_FONT);
627 1 : *pStringIter++ = PROPERTY_TEXTEMPHASIS;
628 1 : *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTEMPHASIS);
629 1 : *pStringIter++ = PROPERTY_TEXTRELIEF;
630 1 : *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTRELIEF);
631 1 : if ( m_bPreview )
632 : {
633 0 : *pStringIter++ = "HasNavigationBar";
634 0 : *pValueIter++ <<= sal_False;
635 0 : *pStringIter++ = "HasRecordMarker";
636 0 : *pValueIter++ <<= sal_False;
637 : }
638 1 : *pStringIter++ = PROPERTY_ROW_HEIGHT;
639 1 : *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_ROW_HEIGHT);
640 1 : if ( m_bPreview )
641 : {
642 0 : *pStringIter++ = "Tabstop";
643 0 : *pValueIter++ <<= sal_False;
644 : }
645 1 : *pStringIter++ = PROPERTY_TEXTCOLOR;
646 1 : *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTCOLOR);
647 1 : *pStringIter++ = PROPERTY_TEXTLINECOLOR;
648 1 : *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTLINECOLOR);
649 :
650 2 : Reference< XMultiPropertySet > xFormMultiSet(xGrid, UNO_QUERY);
651 2 : xFormMultiSet->setPropertyValues(aProperties, aValues);
652 : }
653 :
654 : // get the formats supplier of the database we're working with
655 1 : Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier = getNumberFormatter()->getNumberFormatsSupplier();
656 :
657 2 : Reference<XConnection> xConnection;
658 2 : Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
659 1 : xRowSetProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xConnection;
660 : OSL_ENSURE(xConnection.is(),"A ActiveConnection should normally exists!");
661 :
662 2 : Reference<XChild> xChild(xConnection,UNO_QUERY);
663 2 : Reference<XPropertySet> xDataSourceProp(xChild->getParent(),UNO_QUERY);
664 1 : bool bSuppressVersionCol = false;
665 1 : OSL_VERIFY( xDataSourceProp->getPropertyValue( PROPERTY_SUPPRESSVERSIONCL ) >>= bSuppressVersionCol );
666 :
667 : // insert the column into the gridcontrol so that we see something :-)
668 2 : OUString aCurrentModelType;
669 2 : Reference<XColumnsSupplier> xSupCols(getRowSet(),UNO_QUERY);
670 2 : Reference<XNameAccess> xColumns = xSupCols->getColumns();
671 2 : Sequence< OUString> aNames = xColumns->getElementNames();
672 1 : const OUString* pIter = aNames.getConstArray();
673 1 : const OUString* pEnd = pIter + aNames.getLength();
674 :
675 2 : OUString sDefaultProperty;
676 2 : Reference< XPropertySet > xColumn;
677 2 : Reference< XPropertySetInfo > xColPSI;
678 32 : for (sal_uInt16 i=0; pIter != pEnd; ++i,++pIter)
679 : {
680 31 : xColumn.set( xColumns->getByName( *pIter ), UNO_QUERY_THROW );
681 31 : xColPSI.set( xColumn->getPropertySetInfo(), UNO_SET_THROW );
682 :
683 : // ignore the column when it is a rowversion one
684 62 : if ( bSuppressVersionCol
685 93 : && xColPSI->hasPropertyByName( PROPERTY_ISROWVERSION )
686 93 : && ::cppu::any2bool( xColumn->getPropertyValue( PROPERTY_ISROWVERSION ) )
687 : )
688 0 : continue;
689 :
690 : // use the result set column's type to determine the type of grid column to create
691 31 : bool bFormattedIsNumeric = true;
692 31 : sal_Int32 nType = ::comphelper::getINT32( xColumn->getPropertyValue( PROPERTY_TYPE ) );
693 :
694 31 : ::std::vector< NamedValue > aInitialValues;
695 62 : ::std::vector< OUString > aCopyProperties;
696 62 : Any aDefault;
697 :
698 31 : switch(nType)
699 : {
700 : case DataType::BIT:
701 : case DataType::BOOLEAN:
702 : {
703 0 : aCurrentModelType = "CheckBox";
704 0 : aInitialValues.push_back( NamedValue( OUString( "VisualEffect" ), makeAny( VisualEffect::FLAT ) ) );
705 0 : sDefaultProperty = PROPERTY_DEFAULTSTATE;
706 :
707 0 : sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN;
708 0 : OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_ISNULLABLE ) >>= nNullable );
709 : aInitialValues.push_back( NamedValue(
710 : OUString( "TriState" ),
711 0 : makeAny( ColumnValue::NO_NULLS != nNullable )
712 0 : ) );
713 0 : if ( ColumnValue::NO_NULLS == nNullable )
714 0 : aDefault <<= (sal_Int16)TRISTATE_FALSE;
715 : }
716 0 : break;
717 :
718 : case DataType::LONGVARCHAR:
719 : case DataType::CLOB:
720 17 : aInitialValues.push_back( NamedValue( OUString( "MultiLine" ), makeAny( true ) ) );
721 : // NO break!
722 : case DataType::BINARY:
723 : case DataType::VARBINARY:
724 : case DataType::LONGVARBINARY:
725 17 : aCurrentModelType = "TextField";
726 17 : sDefaultProperty = PROPERTY_DEFAULTTEXT;
727 17 : break;
728 :
729 : case DataType::VARCHAR:
730 : case DataType::CHAR:
731 14 : bFormattedIsNumeric = false;
732 : // NO break!
733 : default:
734 14 : aCurrentModelType = "FormattedField";
735 14 : sDefaultProperty = PROPERTY_EFFECTIVEDEFAULT;
736 :
737 14 : if ( xSupplier.is() )
738 14 : aInitialValues.push_back( NamedValue( OUString("FormatsSupplier"), makeAny( xSupplier ) ) );
739 14 : aInitialValues.push_back( NamedValue( OUString("TreatAsNumber"), makeAny( bFormattedIsNumeric ) ) );
740 14 : aCopyProperties.push_back( static_cast<const OUString&>(PROPERTY_FORMATKEY) );
741 14 : break;
742 : }
743 :
744 31 : aInitialValues.push_back( NamedValue( PROPERTY_CONTROLSOURCE, makeAny( *pIter ) ) );
745 31 : OUString sLabel;
746 31 : xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel;
747 31 : if ( !sLabel.isEmpty() )
748 31 : aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( sLabel ) ) );
749 : else
750 0 : aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( *pIter ) ) );
751 :
752 62 : Reference< XPropertySet > xGridCol( xColFactory->createColumn( aCurrentModelType ), UNO_SET_THROW );
753 62 : Reference< XPropertySetInfo > xGridColPSI( xGridCol->getPropertySetInfo(), UNO_SET_THROW );
754 :
755 : // calculate the default
756 31 : if ( xGridColPSI->hasPropertyByName( PROPERTY_CONTROLDEFAULT ) )
757 : {
758 0 : aDefault = xColumn->getPropertyValue( PROPERTY_CONTROLDEFAULT );
759 : // default value
760 0 : if ( nType == DataType::BIT || nType == DataType::BOOLEAN )
761 : {
762 0 : if ( aDefault.hasValue() )
763 0 : aDefault <<= (comphelper::getString(aDefault).toInt32() == 0) ? (sal_Int16)TRISTATE_FALSE : (sal_Int16)TRISTATE_TRUE;
764 : else
765 0 : aDefault <<= ((sal_Int16)TRISTATE_INDET);
766 : }
767 : }
768 :
769 31 : if ( aDefault.hasValue() )
770 0 : aInitialValues.push_back( NamedValue( sDefaultProperty, aDefault ) );
771 :
772 : // transfer properties from the definition to the UNO-model :
773 31 : aCopyProperties.push_back( static_cast<const OUString&>(PROPERTY_HIDDEN) );
774 31 : aCopyProperties.push_back( static_cast<const OUString&>(PROPERTY_WIDTH) );
775 :
776 : // help text to display for the column
777 62 : Any aDescription;
778 31 : if ( xColPSI->hasPropertyByName( PROPERTY_HELPTEXT ) )
779 31 : aDescription = xColumn->getPropertyValue( PROPERTY_HELPTEXT );
780 62 : OUString sTemp;
781 31 : aDescription >>= sTemp;
782 31 : if ( sTemp.isEmpty() )
783 31 : xColumn->getPropertyValue( PROPERTY_DESCRIPTION ) >>= sTemp;
784 :
785 31 : aDescription <<= sTemp;
786 31 : aInitialValues.push_back( NamedValue( PROPERTY_HELPTEXT, aDescription ) );
787 :
788 : // ... horizontal justify
789 62 : Any aAlign; aAlign <<= sal_Int16( 0 );
790 62 : Any aColAlign( xColumn->getPropertyValue( PROPERTY_ALIGN ) );
791 31 : if ( aColAlign.hasValue() )
792 30 : aAlign <<= sal_Int16( ::comphelper::getINT32( aColAlign ) );
793 31 : aInitialValues.push_back( NamedValue( PROPERTY_ALIGN, aAlign ) );
794 :
795 : // don't allow the mouse to scroll in the cells
796 31 : if ( xGridColPSI->hasPropertyByName( PROPERTY_MOUSE_WHEEL_BEHAVIOR ) )
797 14 : aInitialValues.push_back( NamedValue( PROPERTY_MOUSE_WHEEL_BEHAVIOR, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) ) );
798 :
799 : // now set all those values
800 642 : for ( ::std::vector< NamedValue >::const_iterator property = aInitialValues.begin();
801 428 : property != aInitialValues.end();
802 : ++property
803 : )
804 : {
805 183 : xGridCol->setPropertyValue( property->Name, property->Value );
806 : }
807 321 : for ( ::std::vector< OUString >::const_iterator copyPropertyName = aCopyProperties.begin();
808 214 : copyPropertyName != aCopyProperties.end();
809 : ++copyPropertyName
810 : )
811 76 : xGridCol->setPropertyValue( *copyPropertyName, xColumn->getPropertyValue( *copyPropertyName ) );
812 :
813 31 : xColContainer->insertByName(*pIter, makeAny(xGridCol));
814 63 : }
815 1 : }
816 : }
817 0 : catch(const Exception&)
818 : {
819 : DBG_UNHANDLED_EXCEPTION();
820 0 : return false;
821 : }
822 :
823 1 : return true;
824 : }
825 :
826 0 : Reference<XPropertySet> getColumnHelper(SvTreeListEntry* _pCurrentlyDisplayed,const Reference<XPropertySet>& _rxSource)
827 : {
828 0 : Reference<XPropertySet> xRet;
829 0 : if(_pCurrentlyDisplayed)
830 : {
831 0 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pCurrentlyDisplayed->GetUserData());
832 0 : Reference<XColumnsSupplier> xColumnsSup(pData->xObjectProperties,UNO_QUERY);
833 0 : Reference<XNameAccess> xNames = xColumnsSup->getColumns();
834 0 : OUString aName;
835 0 : _rxSource->getPropertyValue(PROPERTY_NAME) >>= aName;
836 0 : if(xNames.is() && xNames->hasByName(aName))
837 0 : xRet.set(xNames->getByName(aName),UNO_QUERY);
838 : }
839 0 : return xRet;
840 : }
841 :
842 3 : void SbaTableQueryBrowser::transferChangedControlProperty(const OUString& _rProperty, const Any& _rNewValue)
843 : {
844 3 : if(m_pCurrentlyDisplayed)
845 : {
846 3 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
847 3 : Reference< XPropertySet > xObjectProps(pData->xObjectProperties, UNO_QUERY);
848 : OSL_ENSURE(xObjectProps.is(),"SbaTableQueryBrowser::transferChangedControlProperty: no table/query object!");
849 3 : if (xObjectProps.is())
850 3 : xObjectProps->setPropertyValue(_rProperty, _rNewValue);
851 : }
852 3 : }
853 :
854 4 : void SbaTableQueryBrowser::propertyChange(const PropertyChangeEvent& evt) throw(::com::sun::star::uno::RuntimeException, std::exception)
855 : {
856 4 : SbaXDataBrowserController::propertyChange(evt);
857 :
858 : try
859 : {
860 4 : Reference< XPropertySet > xSource(evt.Source, UNO_QUERY);
861 4 : if (!xSource.is())
862 4 : return;
863 :
864 : // one of the many properties which require us to update the definition ?
865 : // a column's width ?
866 4 : else if (evt.PropertyName == PROPERTY_WIDTH)
867 : { // a column width has changed -> update the model
868 : // (the update of the view is done elsewhere)
869 0 : Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
870 0 : if(xProp.is())
871 : {
872 0 : if(!evt.NewValue.hasValue())
873 0 : xProp->setPropertyValue(PROPERTY_WIDTH,makeAny((sal_Int32)227));
874 : else
875 0 : xProp->setPropertyValue(PROPERTY_WIDTH,evt.NewValue);
876 0 : }
877 : }
878 :
879 : // a column's 'visible' state ?
880 4 : else if (evt.PropertyName == PROPERTY_HIDDEN)
881 : {
882 0 : Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
883 0 : if(xProp.is())
884 0 : xProp->setPropertyValue(PROPERTY_HIDDEN,evt.NewValue);
885 : }
886 :
887 : // a columns alignment ?
888 4 : else if (evt.PropertyName == PROPERTY_ALIGN)
889 : {
890 0 : Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
891 : try
892 : {
893 0 : if(xProp.is())
894 : {
895 0 : if(evt.NewValue.hasValue())
896 : {
897 0 : sal_Int16 nAlign = 0;
898 0 : if(evt.NewValue >>= nAlign)
899 0 : xProp->setPropertyValue(PROPERTY_ALIGN,makeAny(sal_Int32(nAlign)));
900 : else
901 0 : xProp->setPropertyValue(PROPERTY_ALIGN,evt.NewValue);
902 : }
903 : else
904 0 : xProp->setPropertyValue(PROPERTY_ALIGN,makeAny(::com::sun::star::awt::TextAlign::LEFT));
905 : }
906 : }
907 0 : catch( const Exception& )
908 : {
909 : DBG_UNHANDLED_EXCEPTION();
910 0 : }
911 : }
912 :
913 : // a column's format ?
914 8 : else if ( evt.PropertyName == PROPERTY_FORMATKEY
915 4 : && (TypeClass_LONG == evt.NewValue.getValueTypeClass())
916 : )
917 : {
918 : // update the model (means the definition object)
919 0 : Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
920 0 : if(xProp.is())
921 0 : xProp->setPropertyValue(PROPERTY_FORMATKEY,evt.NewValue);
922 : }
923 :
924 : // some table definition properties ?
925 : // the height of the rows in the grid ?
926 4 : else if (evt.PropertyName == PROPERTY_ROW_HEIGHT)
927 : {
928 0 : if(m_pCurrentlyDisplayed)
929 : {
930 0 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
931 : OSL_ENSURE( pData->xObjectProperties.is(), "No table available!" );
932 :
933 0 : bool bDefault = !evt.NewValue.hasValue();
934 0 : if (bDefault)
935 0 : pData->xObjectProperties->setPropertyValue(PROPERTY_ROW_HEIGHT,makeAny((sal_Int32)45));
936 : else
937 0 : pData->xObjectProperties->setPropertyValue(PROPERTY_ROW_HEIGHT,evt.NewValue);
938 : }
939 : }
940 :
941 8 : else if ( evt.PropertyName == PROPERTY_FONT // the font ?
942 3 : || evt.PropertyName == PROPERTY_TEXTCOLOR // the text color ?
943 3 : || evt.PropertyName == PROPERTY_FILTER // the filter ?
944 3 : || evt.PropertyName == PROPERTY_HAVING_CLAUSE // the having clause ?
945 3 : || evt.PropertyName == PROPERTY_ORDER // the sort ?
946 2 : || evt.PropertyName == PROPERTY_APPLYFILTER // the appliance of the filter ?
947 1 : || evt.PropertyName == PROPERTY_TEXTLINECOLOR // the text line color ?
948 1 : || evt.PropertyName == PROPERTY_TEXTEMPHASIS // the text emphasis ?
949 5 : || evt.PropertyName == PROPERTY_TEXTRELIEF // the text relief ?
950 : )
951 : {
952 3 : transferChangedControlProperty(evt.PropertyName, evt.NewValue);
953 4 : }
954 : }
955 0 : catch( const Exception& )
956 : {
957 : DBG_UNHANDLED_EXCEPTION();
958 : }
959 : }
960 :
961 0 : sal_Bool SbaTableQueryBrowser::suspend(sal_Bool bSuspend) throw( RuntimeException, std::exception )
962 : {
963 0 : SolarMutexGuard aSolarGuard;
964 0 : ::osl::MutexGuard aGuard( getMutex() );
965 0 : if ( getView() && getView()->IsInModalMode() )
966 0 : return sal_False;
967 0 : bool bRet = false;
968 0 : if ( !m_bInSuspend )
969 : {
970 0 : m_bInSuspend = true;
971 0 : if ( rBHelper.bDisposed )
972 0 : throw DisposedException( OUString(), *this );
973 :
974 0 : bRet = SbaXDataBrowserController::suspend(bSuspend);
975 0 : if ( bRet && getView() )
976 0 : getView()->Hide();
977 :
978 0 : m_bInSuspend = false;
979 : }
980 :
981 0 : return bRet;
982 : }
983 :
984 4 : void SAL_CALL SbaTableQueryBrowser::statusChanged( const FeatureStateEvent& _rEvent ) throw(RuntimeException, std::exception)
985 : {
986 : // search the external dispatcher causing this call
987 4 : Reference< XDispatch > xSource(_rEvent.Source, UNO_QUERY);
988 4 : ExternalFeaturesMap::iterator aLoop;
989 30 : for ( aLoop = m_aExternalFeatures.begin();
990 20 : aLoop != m_aExternalFeatures.end();
991 : ++aLoop
992 : )
993 : {
994 10 : if ( _rEvent.FeatureURL.Complete == aLoop->second.aURL.Complete)
995 : {
996 : OSL_ENSURE( xSource.get() == aLoop->second.xDispatcher.get(), "SbaTableQueryBrowser::statusChanged: inconsistent!" );
997 : // update the enabled state
998 4 : aLoop->second.bEnabled = _rEvent.IsEnabled;
999 :
1000 4 : switch ( aLoop->first )
1001 : {
1002 : case ID_BROWSER_DOCUMENT_DATASOURCE:
1003 : {
1004 : // if it's the slot for the document data source, remember the state
1005 1 : Sequence< PropertyValue > aDescriptor;
1006 : #if OSL_DEBUG_LEVEL > 0
1007 : bool bProperFormat =
1008 : #endif
1009 1 : _rEvent.State >>= aDescriptor;
1010 : OSL_ENSURE(bProperFormat, "SbaTableQueryBrowser::statusChanged: need a data access descriptor here!");
1011 1 : m_aDocumentDataSource.initializeFrom(aDescriptor);
1012 :
1013 : OSL_ENSURE( ( m_aDocumentDataSource.has(daDataSource)
1014 : || m_aDocumentDataSource.has(daDatabaseLocation)
1015 : )
1016 : && m_aDocumentDataSource.has(daCommand)
1017 : && m_aDocumentDataSource.has(daCommandType),
1018 : "SbaTableQueryBrowser::statusChanged: incomplete descriptor!");
1019 :
1020 : // check if we know the object which is set as document data source
1021 1 : checkDocumentDataSource();
1022 : }
1023 1 : break;
1024 :
1025 : default:
1026 : // update the toolbox
1027 3 : implCheckExternalSlot( aLoop->first );
1028 3 : break;
1029 : }
1030 4 : break;
1031 : }
1032 : }
1033 :
1034 4 : OSL_ENSURE(aLoop != m_aExternalFeatures.end(), "SbaTableQueryBrowser::statusChanged: don't know who sent this!");
1035 4 : }
1036 :
1037 1 : void SbaTableQueryBrowser::checkDocumentDataSource()
1038 : {
1039 1 : SvTreeListEntry* pDataSourceEntry = NULL;
1040 1 : SvTreeListEntry* pContainerEntry = NULL;
1041 1 : SvTreeListEntry* pObjectEntry = getObjectEntry( m_aDocumentDataSource, &pDataSourceEntry, &pContainerEntry, false );
1042 1 : bool bKnownDocDataSource = (NULL != pObjectEntry);
1043 1 : if (!bKnownDocDataSource)
1044 : {
1045 1 : if (NULL != pDataSourceEntry)
1046 : { // at least the data source is known
1047 0 : if (NULL != pContainerEntry)
1048 0 : bKnownDocDataSource = true; // assume we know it.
1049 : // TODO: should we expand the object container? This may be too expensive just for checking ....
1050 : else
1051 : {
1052 0 : if ((NULL == pObjectEntry) && m_aDocumentDataSource.has(daCommandType) && m_aDocumentDataSource.has(daCommand))
1053 : { // maybe we have a command to be displayed ?
1054 0 : sal_Int32 nCommandType = CommandType::TABLE;
1055 0 : m_aDocumentDataSource[daCommandType] >>= nCommandType;
1056 :
1057 0 : OUString sCommand;
1058 0 : m_aDocumentDataSource[daCommand] >>= sCommand;
1059 :
1060 0 : bKnownDocDataSource = (CommandType::COMMAND == nCommandType) && (!sCommand.isEmpty());
1061 : }
1062 : }
1063 : }
1064 : }
1065 :
1066 1 : if ( !bKnownDocDataSource )
1067 1 : m_aExternalFeatures[ ID_BROWSER_DOCUMENT_DATASOURCE ].bEnabled = false;
1068 :
1069 : // update the toolbox
1070 1 : implCheckExternalSlot(ID_BROWSER_DOCUMENT_DATASOURCE);
1071 1 : }
1072 :
1073 3 : void SbaTableQueryBrowser::extractDescriptorProps(const svx::ODataAccessDescriptor& _rDescriptor, OUString& _rDataSource, OUString& _rCommand, sal_Int32& _rCommandType, bool& _rEscapeProcessing)
1074 : {
1075 3 : _rDataSource = _rDescriptor.getDataSource();
1076 3 : if ( _rDescriptor.has(daCommand) )
1077 3 : _rDescriptor[daCommand] >>= _rCommand;
1078 3 : if ( _rDescriptor.has(daCommandType) )
1079 3 : _rDescriptor[daCommandType] >>= _rCommandType;
1080 :
1081 : // escape processing is the only one allowed not to be present
1082 3 : _rEscapeProcessing = true;
1083 3 : if (_rDescriptor.has(daEscapeProcessing))
1084 0 : _rEscapeProcessing = ::cppu::any2bool(_rDescriptor[daEscapeProcessing]);
1085 3 : }
1086 :
1087 : namespace
1088 : {
1089 3 : bool getDataSourceDisplayName_isURL( const OUString& _rDS, OUString& _rDisplayName, OUString& _rUniqueId )
1090 : {
1091 3 : INetURLObject aURL( _rDS );
1092 3 : if ( aURL.GetProtocol() != INetProtocol::NotValid )
1093 : {
1094 0 : _rDisplayName = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET);
1095 0 : _rUniqueId = aURL.GetMainURL( INetURLObject::NO_DECODE );
1096 0 : return true;
1097 : }
1098 3 : _rDisplayName = _rDS;
1099 3 : _rUniqueId.clear();
1100 3 : return false;
1101 : }
1102 :
1103 : struct FilterByEntryDataId : public IEntryFilter
1104 : {
1105 : OUString sId;
1106 2 : FilterByEntryDataId( const OUString& _rId ) : sId( _rId ) { }
1107 :
1108 2 : virtual ~FilterByEntryDataId() {}
1109 :
1110 : virtual bool includeEntry( SvTreeListEntry* _pEntry ) const SAL_OVERRIDE;
1111 : };
1112 :
1113 1 : bool FilterByEntryDataId::includeEntry( SvTreeListEntry* _pEntry ) const
1114 : {
1115 1 : DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( _pEntry->GetUserData() );
1116 1 : return ( !pData || ( pData->sAccessor == sId ) );
1117 : }
1118 : }
1119 :
1120 2 : OUString SbaTableQueryBrowser::getDataSourceAcessor( SvTreeListEntry* _pDataSourceEntry ) const
1121 : {
1122 : OSL_ENSURE( _pDataSourceEntry, "SbaTableQueryBrowser::getDataSourceAcessor: invalid entry!" );
1123 :
1124 2 : DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( _pDataSourceEntry->GetUserData() );
1125 : OSL_ENSURE( pData, "SbaTableQueryBrowser::getDataSourceAcessor: invalid entry data!" );
1126 : OSL_ENSURE( pData->eType == etDatasource, "SbaTableQueryBrowser::getDataSourceAcessor: entry does not denote a data source!" );
1127 2 : return !pData->sAccessor.isEmpty() ? OUString(pData->sAccessor) : GetEntryText( _pDataSourceEntry );
1128 : }
1129 :
1130 2 : SvTreeListEntry* SbaTableQueryBrowser::getObjectEntry(const OUString& _rDataSource, const OUString& _rCommand, sal_Int32 _nCommandType,
1131 : SvTreeListEntry** _ppDataSourceEntry, SvTreeListEntry** _ppContainerEntry, bool _bExpandAncestors,
1132 : const SharedConnection& _rxConnection )
1133 : {
1134 2 : if (_ppDataSourceEntry)
1135 2 : *_ppDataSourceEntry = NULL;
1136 2 : if (_ppContainerEntry)
1137 2 : *_ppContainerEntry = NULL;
1138 :
1139 2 : SvTreeListEntry* pObject = NULL;
1140 2 : if ( m_pTreeView )
1141 : {
1142 : // look for the data source entry
1143 4 : OUString sDisplayName, sDataSourceId;
1144 2 : bool bIsDataSourceURL = getDataSourceDisplayName_isURL( _rDataSource, sDisplayName, sDataSourceId );
1145 : // the display name may differ from the URL for readability reasons
1146 : // #i33699#
1147 :
1148 4 : FilterByEntryDataId aFilter( sDataSourceId );
1149 2 : SvTreeListEntry* pDataSource = m_pTreeView->getListBox().GetEntryPosByName( sDisplayName, NULL, &aFilter );
1150 2 : if ( !pDataSource ) // check if the data source name is a file location
1151 : {
1152 1 : if ( bIsDataSourceURL )
1153 : {
1154 : // special case, the data source is a URL
1155 : // add new entries to the list box model
1156 0 : implAddDatasource( _rDataSource, _rxConnection );
1157 0 : pDataSource = m_pTreeView->getListBox().GetEntryPosByName( sDisplayName, NULL, &aFilter );
1158 : OSL_ENSURE( pDataSource, "SbaTableQueryBrowser::getObjectEntry: hmm - did not find it again!" );
1159 : }
1160 : }
1161 2 : if (_ppDataSourceEntry)
1162 : // (caller wants to have it ...)
1163 2 : *_ppDataSourceEntry = pDataSource;
1164 :
1165 2 : if (pDataSource)
1166 : {
1167 : // expand if required so
1168 1 : if (_bExpandAncestors)
1169 1 : m_pTreeView->getListBox().Expand(pDataSource);
1170 :
1171 : // look for the object container
1172 1 : SvTreeListEntry* pCommandType = NULL;
1173 1 : switch (_nCommandType)
1174 : {
1175 : case CommandType::TABLE:
1176 1 : pCommandType = m_pTreeView->getListBox().GetModel()->GetEntry(pDataSource, CONTAINER_TABLES);
1177 1 : break;
1178 :
1179 : case CommandType::QUERY:
1180 0 : pCommandType = m_pTreeView->getListBox().GetModel()->GetEntry(pDataSource, CONTAINER_QUERIES);
1181 0 : break;
1182 : }
1183 :
1184 1 : if (_ppContainerEntry)
1185 1 : *_ppContainerEntry = pCommandType;
1186 :
1187 1 : if (pCommandType)
1188 : {
1189 : // expand if required so
1190 1 : if (_bExpandAncestors)
1191 : {
1192 1 : m_pTreeView->getListBox().Expand(pCommandType);
1193 : }
1194 :
1195 : // look for the object
1196 1 : OUString sCommand = _rCommand;
1197 1 : sal_Int32 nIndex = 0;
1198 1 : do
1199 : {
1200 1 : OUString sPath;
1201 1 : switch (_nCommandType)
1202 : {
1203 : case CommandType::TABLE:
1204 1 : sPath = sCommand;
1205 1 : nIndex = -1;
1206 1 : break;
1207 :
1208 : default:
1209 : assert(false);
1210 : // in non-debug builds, fall through.
1211 : case CommandType::QUERY:
1212 0 : sPath = sCommand.getToken( 0, '/', nIndex );
1213 0 : break;
1214 : }
1215 1 : pObject = m_pTreeView->getListBox().GetEntryPosByName(sPath, pCommandType);
1216 1 : pCommandType = pObject;
1217 1 : if ( nIndex >= 0 )
1218 : {
1219 0 : if (ensureEntryObject(pObject))
1220 : {
1221 0 : DBTreeListUserData* pParentData = static_cast< DBTreeListUserData* >( pObject->GetUserData() );
1222 0 : Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY );
1223 0 : sal_Int32 nIndex2 = nIndex;
1224 0 : sPath = sCommand.getToken( 0, '/', nIndex2 );
1225 : try
1226 : {
1227 0 : if ( xCollection->hasByName(sPath) )
1228 : {
1229 0 : if(!m_pTreeView->getListBox().GetEntryPosByName(sPath,pObject))
1230 : {
1231 0 : Reference<XNameAccess> xChild(xCollection->getByName(sPath),UNO_QUERY);
1232 0 : DBTreeListUserData* pEntryData = new DBTreeListUserData;
1233 0 : pEntryData->eType = etQuery;
1234 0 : if ( xChild.is() )
1235 : {
1236 0 : pEntryData->eType = etQueryContainer;
1237 : }
1238 0 : implAppendEntry( pObject, sPath, pEntryData, pEntryData->eType );
1239 : }
1240 : }
1241 : }
1242 0 : catch(const Exception&)
1243 : {
1244 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::populateTree: could not fill the tree");
1245 0 : }
1246 : }
1247 1 : }
1248 : }
1249 2 : while ( nIndex >= 0 );
1250 : }
1251 2 : }
1252 : }
1253 2 : return pObject;
1254 : }
1255 :
1256 1 : SvTreeListEntry* SbaTableQueryBrowser::getObjectEntry(const svx::ODataAccessDescriptor& _rDescriptor,
1257 : SvTreeListEntry** _ppDataSourceEntry, SvTreeListEntry** _ppContainerEntry,
1258 : bool _bExpandAncestors)
1259 : {
1260 : // extract the props from the descriptor
1261 1 : OUString sDataSource;
1262 2 : OUString sCommand;
1263 1 : sal_Int32 nCommandType = CommandType::COMMAND;
1264 1 : bool bEscapeProcessing = true;
1265 1 : extractDescriptorProps(_rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing);
1266 :
1267 2 : return getObjectEntry( sDataSource, sCommand, nCommandType, _ppDataSourceEntry, _ppContainerEntry, _bExpandAncestors, SharedConnection() );
1268 : }
1269 :
1270 1 : void SbaTableQueryBrowser::connectExternalDispatches()
1271 : {
1272 1 : Reference< XDispatchProvider > xProvider( getFrame(), UNO_QUERY );
1273 : OSL_ENSURE(xProvider.is(), "SbaTableQueryBrowser::connectExternalDispatches: no DispatchProvider !");
1274 1 : if (xProvider.is())
1275 : {
1276 1 : if ( m_aExternalFeatures.empty() )
1277 : {
1278 : const sal_Char* pURLs[] = {
1279 : ".uno:DataSourceBrowser/DocumentDataSource",
1280 : ".uno:DataSourceBrowser/FormLetter",
1281 : ".uno:DataSourceBrowser/InsertColumns",
1282 : ".uno:DataSourceBrowser/InsertContent",
1283 1 : };
1284 : const sal_uInt16 nIds[] = {
1285 : ID_BROWSER_DOCUMENT_DATASOURCE,
1286 : ID_BROWSER_FORMLETTER,
1287 : ID_BROWSER_INSERTCOLUMNS,
1288 : ID_BROWSER_INSERTCONTENT
1289 1 : };
1290 :
1291 5 : for ( size_t i=0; i < sizeof( pURLs ) / sizeof( pURLs[0] ); ++i )
1292 : {
1293 4 : URL aURL;
1294 4 : aURL.Complete = OUString::createFromAscii( pURLs[i] );
1295 4 : if ( m_xUrlTransformer.is() )
1296 4 : m_xUrlTransformer->parseStrict( aURL );
1297 4 : m_aExternalFeatures[ nIds[ i ] ] = ExternalFeature( aURL );
1298 4 : }
1299 : }
1300 :
1301 15 : for ( ExternalFeaturesMap::iterator feature = m_aExternalFeatures.begin();
1302 10 : feature != m_aExternalFeatures.end();
1303 : ++feature
1304 : )
1305 : {
1306 16 : feature->second.xDispatcher = xProvider->queryDispatch(
1307 4 : feature->second.aURL, OUString("_parent"), FrameSearchFlag::PARENT
1308 8 : );
1309 :
1310 4 : if ( feature->second.xDispatcher.get() == static_cast< XDispatch* >( this ) )
1311 : {
1312 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::connectExternalDispatches: this should not happen anymore!" );
1313 : // (nowadays, the URLs aren't in our SupportedFeatures list anymore, so we should
1314 : // not supply a dispatcher for this)
1315 0 : feature->second.xDispatcher.clear();
1316 : }
1317 :
1318 4 : if ( feature->second.xDispatcher.is() )
1319 : {
1320 : try
1321 : {
1322 4 : feature->second.xDispatcher->addStatusListener( this, feature->second.aURL );
1323 : }
1324 0 : catch( const Exception& )
1325 : {
1326 : DBG_UNHANDLED_EXCEPTION();
1327 : }
1328 : }
1329 :
1330 4 : implCheckExternalSlot( feature->first );
1331 : }
1332 1 : }
1333 1 : }
1334 :
1335 8 : void SbaTableQueryBrowser::implCheckExternalSlot( sal_uInt16 _nId )
1336 : {
1337 8 : if ( !m_xMainToolbar.is() )
1338 8 : return;
1339 :
1340 8 : vcl::Window* pToolboxWindow = VCLUnoHelper::GetWindow( m_xMainToolbar );
1341 8 : ToolBox* pToolbox = dynamic_cast< ToolBox* >( pToolboxWindow );
1342 : OSL_ENSURE( pToolbox, "SbaTableQueryBrowser::implCheckExternalSlot: cannot obtain the toolbox window!" );
1343 :
1344 : // check if we have to hide this item from the toolbox
1345 8 : if ( pToolbox )
1346 : {
1347 8 : bool bHaveDispatcher = m_aExternalFeatures[ _nId ].xDispatcher.is();
1348 8 : if ( bHaveDispatcher != pToolbox->IsItemVisible( _nId ) )
1349 8 : bHaveDispatcher ? pToolbox->ShowItem( _nId ) : pToolbox->HideItem( _nId );
1350 : }
1351 :
1352 : // and invalidate this feature in general
1353 8 : InvalidateFeature( _nId );
1354 : }
1355 :
1356 1 : void SAL_CALL SbaTableQueryBrowser::disposing( const com::sun::star::lang::EventObject& _rSource ) throw(RuntimeException, std::exception)
1357 : {
1358 : // our frame ?
1359 1 : Reference< ::com::sun::star::frame::XFrame > xSourceFrame(_rSource.Source, UNO_QUERY);
1360 1 : if (m_xCurrentFrameParent.is() && (xSourceFrame == m_xCurrentFrameParent))
1361 0 : m_xCurrentFrameParent->removeFrameActionListener(static_cast<com::sun::star::frame::XFrameActionListener*>(this));
1362 : else
1363 : {
1364 : // search the external dispatcher causing this call in our map
1365 1 : Reference< XDispatch > xSource(_rSource.Source, UNO_QUERY);
1366 1 : if(xSource.is())
1367 : {
1368 0 : ExternalFeaturesMap::iterator aLoop = m_aExternalFeatures.begin();
1369 0 : ExternalFeaturesMap::iterator aEnd = m_aExternalFeatures.end();
1370 0 : while (aLoop != aEnd)
1371 : {
1372 0 : ExternalFeaturesMap::iterator aI = aLoop++;
1373 0 : if ( aI->second.xDispatcher.get() == xSource.get() )
1374 : {
1375 0 : sal_uInt16 nSlot = aI->first;
1376 :
1377 : // remove it
1378 0 : m_aExternalFeatures.erase(aI);
1379 :
1380 : // maybe update the UI
1381 0 : implCheckExternalSlot(nSlot);
1382 :
1383 : // continue, the same XDispatch may be resposible for more than one URL
1384 : }
1385 : }
1386 : }
1387 : else
1388 : {
1389 1 : Reference<XConnection> xCon(_rSource.Source, UNO_QUERY);
1390 1 : if ( xCon.is() && m_pTreeView )
1391 : { // our connection is in dispose so we have to find the entry equal with this connection
1392 : // and close it what means to collapse the entry
1393 : // get the top-level representing the removed data source
1394 0 : SvTreeListEntry* pDSLoop = m_pTreeView->getListBox().FirstChild(NULL);
1395 0 : while (pDSLoop)
1396 : {
1397 0 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pDSLoop->GetUserData());
1398 0 : if ( pData && pData->xConnection == xCon )
1399 : {
1400 : // we set the connection to null to avoid a second disposing of the connection
1401 0 : pData->xConnection.clear();
1402 0 : closeConnection(pDSLoop,false);
1403 0 : break;
1404 : }
1405 :
1406 0 : pDSLoop = SvTreeList::NextSibling(pDSLoop);
1407 : }
1408 : }
1409 : else
1410 1 : SbaXDataBrowserController::disposing(_rSource);
1411 1 : }
1412 1 : }
1413 1 : }
1414 :
1415 4 : void SbaTableQueryBrowser::implRemoveStatusListeners()
1416 : {
1417 : // clear all old dispatches
1418 24 : for ( ExternalFeaturesMap::const_iterator aLoop = m_aExternalFeatures.begin();
1419 16 : aLoop != m_aExternalFeatures.end();
1420 : ++aLoop
1421 : )
1422 : {
1423 4 : if ( aLoop->second.xDispatcher.is() )
1424 : {
1425 : try
1426 : {
1427 4 : aLoop->second.xDispatcher->removeStatusListener( this, aLoop->second.aURL );
1428 : }
1429 0 : catch (Exception&)
1430 : {
1431 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::implRemoveStatusListeners: could not remove a status listener!");
1432 : }
1433 : }
1434 : }
1435 4 : m_aExternalFeatures.clear();
1436 4 : }
1437 :
1438 2 : sal_Bool SAL_CALL SbaTableQueryBrowser::select( const Any& _rSelection ) throw (IllegalArgumentException, RuntimeException, std::exception)
1439 : {
1440 2 : SolarMutexGuard aGuard;
1441 : // doin' a lot of VCL stuff here -> lock the SolarMutex
1442 :
1443 4 : Sequence< PropertyValue > aDescriptorSequence;
1444 2 : if (!(_rSelection >>= aDescriptorSequence))
1445 0 : throw IllegalArgumentException(OUString(), *this, 1);
1446 : // TODO: error message
1447 :
1448 4 : ODataAccessDescriptor aDescriptor;
1449 : try
1450 : {
1451 2 : aDescriptor = ODataAccessDescriptor(aDescriptorSequence);
1452 : }
1453 0 : catch(const Exception&)
1454 : {
1455 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::select: could not extract the descriptor!");
1456 : }
1457 :
1458 : // check the precense of the props we need
1459 2 : if ( !(aDescriptor.has(daDataSource) || aDescriptor.has(daDatabaseLocation)) || !aDescriptor.has(daCommand) || !aDescriptor.has(daCommandType))
1460 0 : throw IllegalArgumentException(OUString(), *this, 1);
1461 : // TODO: error message
1462 :
1463 4 : return implSelect(aDescriptor,true);
1464 : }
1465 :
1466 0 : Any SAL_CALL SbaTableQueryBrowser::getSelection( ) throw (RuntimeException, std::exception)
1467 : {
1468 0 : Any aReturn;
1469 :
1470 : try
1471 : {
1472 0 : Reference< XLoadable > xLoadable(getRowSet(), UNO_QUERY);
1473 0 : if (xLoadable.is() && xLoadable->isLoaded())
1474 : {
1475 0 : Reference< XPropertySet > aFormProps(getRowSet(), UNO_QUERY);
1476 0 : ODataAccessDescriptor aDescriptor(aFormProps);
1477 : // remove properties which are not part of our "selection"
1478 0 : aDescriptor.erase(daConnection);
1479 0 : aDescriptor.erase(daCursor);
1480 :
1481 0 : aReturn <<= aDescriptor.createPropertyValueSequence();
1482 0 : }
1483 : }
1484 0 : catch( const Exception& )
1485 : {
1486 : DBG_UNHANDLED_EXCEPTION();
1487 : }
1488 :
1489 0 : return aReturn;
1490 : }
1491 :
1492 0 : void SAL_CALL SbaTableQueryBrowser::addSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException, std::exception)
1493 : {
1494 0 : m_aSelectionListeners.addInterface(_rxListener);
1495 0 : }
1496 :
1497 0 : void SAL_CALL SbaTableQueryBrowser::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException, std::exception)
1498 : {
1499 0 : m_aSelectionListeners.removeInterface(_rxListener);
1500 0 : }
1501 :
1502 1 : void SbaTableQueryBrowser::attachFrame(const Reference< ::com::sun::star::frame::XFrame > & _xFrame) throw( RuntimeException, std::exception )
1503 : {
1504 1 : implRemoveStatusListeners();
1505 :
1506 1 : if (m_xCurrentFrameParent.is())
1507 0 : m_xCurrentFrameParent->removeFrameActionListener(static_cast<com::sun::star::frame::XFrameActionListener*>(this));
1508 :
1509 1 : SbaXDataBrowserController::attachFrame(_xFrame);
1510 :
1511 1 : Reference< XFrame > xCurrentFrame( getFrame() );
1512 1 : if ( xCurrentFrame.is() )
1513 : {
1514 1 : m_xCurrentFrameParent = xCurrentFrame->findFrame(OUString("_parent"),FrameSearchFlag::PARENT);
1515 1 : if ( m_xCurrentFrameParent.is() )
1516 1 : m_xCurrentFrameParent->addFrameActionListener(static_cast<com::sun::star::frame::XFrameActionListener*>(this));
1517 :
1518 : // obtain our toolbox
1519 : try
1520 : {
1521 1 : Reference< XPropertySet > xFrameProps( m_aCurrentFrame.getFrame(), UNO_QUERY_THROW );
1522 : Reference< XLayoutManager > xLayouter(
1523 1 : xFrameProps->getPropertyValue("LayoutManager"),
1524 2 : UNO_QUERY );
1525 :
1526 1 : if ( xLayouter.is() )
1527 : {
1528 : Reference< XUIElement > xUI(
1529 1 : xLayouter->getElement( OUString( "private:resource/toolbar/toolbar" ) ),
1530 1 : UNO_SET_THROW );
1531 1 : m_xMainToolbar.set(xUI->getRealInterface(), css::uno::UNO_QUERY);
1532 1 : OSL_ENSURE( m_xMainToolbar.is(), "SbaTableQueryBrowser::attachFrame: where's my toolbox?" );
1533 1 : }
1534 : }
1535 0 : catch( const Exception& )
1536 : {
1537 : DBG_UNHANDLED_EXCEPTION();
1538 : }
1539 : }
1540 :
1541 : // get the dispatchers for the external slots
1542 1 : connectExternalDispatches();
1543 1 : }
1544 :
1545 1 : void SbaTableQueryBrowser::addModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel)
1546 : {
1547 1 : SbaXDataBrowserController::addModelListeners(_xGridControlModel);
1548 1 : Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY);
1549 1 : if (xSourceSet.is())
1550 : {
1551 1 : xSourceSet->addPropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this));
1552 1 : xSourceSet->addPropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this));
1553 1 : xSourceSet->addPropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this));
1554 1 : xSourceSet->addPropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this));
1555 1 : xSourceSet->addPropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this));
1556 1 : xSourceSet->addPropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this));
1557 1 : }
1558 :
1559 1 : }
1560 :
1561 2 : void SbaTableQueryBrowser::removeModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel)
1562 : {
1563 2 : SbaXDataBrowserController::removeModelListeners(_xGridControlModel);
1564 2 : Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY);
1565 2 : if (xSourceSet.is())
1566 : {
1567 1 : xSourceSet->removePropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this));
1568 1 : xSourceSet->removePropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this));
1569 1 : xSourceSet->removePropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this));
1570 1 : xSourceSet->removePropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this));
1571 1 : xSourceSet->removePropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this));
1572 1 : xSourceSet->removePropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this));
1573 2 : }
1574 2 : }
1575 :
1576 2 : void SbaTableQueryBrowser::RowChanged()
1577 : {
1578 2 : if(getBrowserView())
1579 : {
1580 2 : SbaGridControl* pControl = getBrowserView()->getVclControl();
1581 2 : if (!pControl->IsEditing())
1582 2 : InvalidateFeature(ID_BROWSER_COPY);
1583 : }
1584 2 : SbaXDataBrowserController::RowChanged();
1585 2 : }
1586 :
1587 3 : void SbaTableQueryBrowser::ColumnChanged()
1588 : {
1589 3 : if(getBrowserView())
1590 : {
1591 3 : SbaGridControl* pControl = getBrowserView()->getVclControl();
1592 3 : if (!pControl->IsEditing())
1593 2 : InvalidateFeature(ID_BROWSER_COPY);
1594 : }
1595 3 : SbaXDataBrowserController::ColumnChanged();
1596 3 : }
1597 :
1598 31 : void SbaTableQueryBrowser::AddColumnListener(const Reference< XPropertySet > & xCol)
1599 : {
1600 31 : SbaXDataBrowserController::AddColumnListener(xCol);
1601 31 : SafeAddPropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this));
1602 31 : SafeAddPropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this));
1603 31 : SafeAddPropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this));
1604 31 : SafeAddPropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this));
1605 31 : }
1606 :
1607 31 : void SbaTableQueryBrowser::RemoveColumnListener(const Reference< XPropertySet > & xCol)
1608 : {
1609 31 : SbaXDataBrowserController::RemoveColumnListener(xCol);
1610 31 : SafeRemovePropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this));
1611 31 : SafeRemovePropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this));
1612 31 : SafeRemovePropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this));
1613 31 : SafeRemovePropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this));
1614 31 : }
1615 :
1616 0 : void SbaTableQueryBrowser::criticalFail()
1617 : {
1618 0 : SbaXDataBrowserController::criticalFail();
1619 0 : unloadAndCleanup( false );
1620 0 : }
1621 :
1622 1 : void SbaTableQueryBrowser::LoadFinished(bool _bWasSynch)
1623 : {
1624 1 : SbaXDataBrowserController::LoadFinished(_bWasSynch);
1625 :
1626 1 : m_sQueryCommand.clear();
1627 1 : m_bQueryEscapeProcessing = false;
1628 :
1629 1 : if (isValid() && !loadingCancelled())
1630 : {
1631 : // did we load a query?
1632 : bool bTemporary; // needed because we m_bQueryEscapeProcessing is only one bit wide (and we want to pass it by reference)
1633 1 : if ( implGetQuerySignature( m_sQueryCommand, bTemporary ) )
1634 0 : m_bQueryEscapeProcessing = bTemporary;
1635 : }
1636 :
1637 : // if the form has been loaded, this means that our "selection" has changed
1638 1 : com::sun::star::lang::EventObject aEvent( *this );
1639 1 : m_aSelectionListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvent );
1640 1 : }
1641 :
1642 24 : bool SbaTableQueryBrowser::getExternalSlotState( sal_uInt16 _nId ) const
1643 : {
1644 24 : bool bEnabled = false;
1645 24 : ExternalFeaturesMap::const_iterator aPos = m_aExternalFeatures.find( _nId );
1646 24 : if ( ( m_aExternalFeatures.end() != aPos ) && aPos->second.xDispatcher.is() )
1647 24 : bEnabled = aPos->second.bEnabled;
1648 24 : return bEnabled;
1649 : }
1650 :
1651 219 : FeatureState SbaTableQueryBrowser::GetState(sal_uInt16 nId) const
1652 : {
1653 219 : FeatureState aReturn;
1654 : // (disabled automatically)
1655 :
1656 : // no chance without a view
1657 219 : if (!getBrowserView() || !getBrowserView()->getVclControl())
1658 0 : return aReturn;
1659 :
1660 219 : switch ( nId )
1661 : {
1662 : case ID_TREE_ADMINISTRATE:
1663 0 : aReturn.bEnabled = true;
1664 0 : return aReturn;
1665 :
1666 : case ID_BROWSER_CLOSE:
1667 : // the close button should always be enabled
1668 4 : aReturn.bEnabled = !m_bEnableBrowser;
1669 4 : return aReturn;
1670 :
1671 : // "toggle explorer" is always enabled (if we have a explorer)
1672 : case ID_BROWSER_EXPLORER:
1673 7 : aReturn.bEnabled = m_bEnableBrowser;
1674 7 : aReturn.bChecked = haveExplorer();
1675 7 : return aReturn;
1676 :
1677 : case ID_BROWSER_REMOVEFILTER:
1678 8 : return SbaXDataBrowserController::GetState( nId );
1679 :
1680 : case ID_BROWSER_COPY:
1681 16 : if ( !m_pTreeView->HasChildPathFocus() )
1682 : // handled below
1683 16 : break;
1684 : // NO break!
1685 : case ID_TREE_CLOSE_CONN:
1686 : case ID_TREE_EDIT_DATABASE:
1687 : {
1688 0 : SvTreeListEntry* pCurrentEntry( m_pTreeView->getListBox().GetCurEntry() );
1689 0 : EntryType eType = getEntryType( pCurrentEntry );
1690 0 : if ( eType == etUnknown )
1691 0 : return aReturn;
1692 :
1693 0 : SvTreeListEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent( pCurrentEntry );
1694 : DBTreeListUserData* pDSData
1695 : = pDataSourceEntry
1696 : ? static_cast< DBTreeListUserData* >( pDataSourceEntry->GetUserData() )
1697 0 : : NULL;
1698 :
1699 0 : if ( nId == ID_TREE_CLOSE_CONN )
1700 : {
1701 0 : aReturn.bEnabled = ( pDSData != NULL ) && pDSData->xConnection.is();
1702 : }
1703 0 : else if ( nId == ID_TREE_EDIT_DATABASE )
1704 : {
1705 : ::utl::OConfigurationTreeRoot aConfig( ::utl::OConfigurationTreeRoot::createWithComponentContext( getORB(),
1706 0 : OUString( "/org.openoffice.Office.DataAccess/Policies/Features/Common" ) ) );
1707 0 : bool bHaveEditDatabase( true );
1708 0 : OSL_VERIFY( aConfig.getNodeValue( "EditDatabaseFromDataSourceView" ) >>= bHaveEditDatabase );
1709 0 : aReturn.bEnabled = getORB().is() && ( pDataSourceEntry != NULL ) && bHaveEditDatabase;
1710 : }
1711 0 : else if ( nId == ID_BROWSER_COPY )
1712 : {
1713 0 : aReturn.bEnabled = isEntryCopyAllowed( pCurrentEntry );
1714 : }
1715 :
1716 0 : return aReturn;
1717 : }
1718 : }
1719 :
1720 : // all slots not handled above are not available if no form is loaded
1721 200 : if (!isLoaded())
1722 58 : return aReturn;
1723 :
1724 : try
1725 : {
1726 142 : bool bHandled = false;
1727 142 : switch (nId)
1728 : {
1729 : case ID_BROWSER_DOCUMENT_DATASOURCE:
1730 : // the slot is enabled if we have an external dispatcher able to handle it,
1731 : // and the dispatcher must have enabled the slot in general
1732 6 : aReturn.bEnabled = getExternalSlotState( ID_BROWSER_DOCUMENT_DATASOURCE );
1733 6 : bHandled = true;
1734 6 : break;
1735 : case ID_BROWSER_REFRESH:
1736 3 : aReturn.bEnabled = true;
1737 3 : bHandled = true;
1738 3 : break;
1739 : }
1740 :
1741 142 : if (bHandled)
1742 9 : return aReturn;
1743 :
1744 : // no chance without valid models
1745 133 : if (isValid() && !isValidCursor() && nId != ID_BROWSER_CLOSE)
1746 0 : return aReturn;
1747 :
1748 133 : switch (nId)
1749 : {
1750 : case ID_BROWSER_INSERTCOLUMNS:
1751 : case ID_BROWSER_INSERTCONTENT:
1752 : case ID_BROWSER_FORMLETTER:
1753 : {
1754 : // the slot is enabled if we have an external dispatcher able to handle it,
1755 : // and the dispatcher must have enabled the slot in general
1756 18 : aReturn.bEnabled = getExternalSlotState( nId );
1757 :
1758 : // for the Insert* slots, we need at least one selected row
1759 18 : if (ID_BROWSER_FORMLETTER != nId)
1760 12 : aReturn.bEnabled = aReturn.bEnabled && getBrowserView()->getVclControl()->GetSelectRowCount();
1761 :
1762 : // disabled for native queries which are not saved within the database
1763 18 : Reference< XPropertySet > xDataSource(getRowSet(), UNO_QUERY);
1764 : try
1765 : {
1766 18 : aReturn.bEnabled = aReturn.bEnabled && xDataSource.is();
1767 :
1768 18 : if (xDataSource.is())
1769 : {
1770 18 : sal_Int32 nType = ::comphelper::getINT32(xDataSource->getPropertyValue(PROPERTY_COMMAND_TYPE));
1771 18 : aReturn.bEnabled = aReturn.bEnabled && ((::comphelper::getBOOL(xDataSource->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) || (nType == ::com::sun::star::sdb::CommandType::QUERY)));
1772 : }
1773 : }
1774 0 : catch(DisposedException&)
1775 : {
1776 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::GetState: object already disposed!");
1777 : }
1778 0 : catch( const Exception& )
1779 : {
1780 : DBG_UNHANDLED_EXCEPTION();
1781 18 : }
1782 : }
1783 18 : break;
1784 :
1785 : case ID_BROWSER_TITLE:
1786 : {
1787 3 : Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
1788 3 : sal_Int32 nCommandType = CommandType::TABLE;
1789 3 : xProp->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nCommandType;
1790 6 : OUString sTitle;
1791 3 : switch (nCommandType)
1792 : {
1793 : case CommandType::TABLE:
1794 3 : sTitle = OUString(ModuleRes(STR_TBL_TITLE)); break;
1795 : case CommandType::QUERY:
1796 : case CommandType::COMMAND:
1797 0 : sTitle = OUString(ModuleRes(STR_QRY_TITLE)); break;
1798 : default:
1799 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::GetState: unknown command type!");
1800 : }
1801 3 : OUString aName;
1802 3 : xProp->getPropertyValue(PROPERTY_COMMAND) >>= aName;
1803 6 : OUString sObject(aName);
1804 :
1805 3 : aReturn.sTitle = sTitle.replaceFirst(OUString('#'), sObject);
1806 9 : aReturn.bEnabled = true;
1807 : }
1808 3 : break;
1809 : case ID_BROWSER_TABLEATTR:
1810 : case ID_BROWSER_ROWHEIGHT:
1811 : case ID_BROWSER_COLATTRSET:
1812 : case ID_BROWSER_COLWIDTH:
1813 0 : aReturn.bEnabled = getBrowserView() && getBrowserView()->getVclControl() && isValid() && isValidCursor();
1814 : // aReturn.bEnabled &= getDefinition() && !getDefinition()->GetDatabase()->IsReadOnly();
1815 0 : break;
1816 :
1817 : case ID_BROWSER_COPY:
1818 : OSL_ENSURE( !m_pTreeView->HasChildPathFocus(), "SbaTableQueryBrowser::GetState( ID_BROWSER_COPY ): this should have been handled above!" );
1819 14 : if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing())
1820 : {
1821 0 : SbaGridControl* pControl = getBrowserView()->getVclControl();
1822 0 : if ( pControl->GetSelectRowCount() )
1823 : {
1824 0 : aReturn.bEnabled = m_aCurrentFrame.isActive();
1825 0 : break;
1826 : }
1827 : else
1828 0 : aReturn.bEnabled = pControl->canCopyCellText(pControl->GetCurRow(), pControl->GetCurColumnId());
1829 0 : break;
1830 : }
1831 : // NO break here
1832 : default:
1833 112 : return SbaXDataBrowserController::GetState(nId);
1834 : }
1835 : }
1836 0 : catch(const Exception&)
1837 : {
1838 : DBG_UNHANDLED_EXCEPTION();
1839 : }
1840 :
1841 21 : return aReturn;
1842 :
1843 : }
1844 :
1845 0 : void SbaTableQueryBrowser::Execute(sal_uInt16 nId, const Sequence< PropertyValue >& aArgs)
1846 : {
1847 0 : switch (nId)
1848 : {
1849 : default:
1850 0 : SbaXDataBrowserController::Execute(nId,aArgs);
1851 0 : break;
1852 :
1853 : case ID_TREE_EDIT_DATABASE:
1854 0 : implAdministrate( m_pTreeView->getListBox().GetCurEntry() );
1855 0 : break;
1856 :
1857 : case ID_TREE_CLOSE_CONN:
1858 0 : openHelpAgent( OString( HID_DSBROWSER_DISCONNECTING ));
1859 0 : closeConnection( m_pTreeView->getListBox().GetRootLevelParent( m_pTreeView->getListBox().GetCurEntry() ) );
1860 0 : break;
1861 :
1862 : case ID_TREE_ADMINISTRATE:
1863 0 : svx::administrateDatabaseRegistration( getView() );
1864 0 : break;
1865 :
1866 : case ID_BROWSER_REFRESH:
1867 : {
1868 0 : if ( !SaveModified( ) )
1869 : // nothing to do
1870 0 : break;
1871 :
1872 0 : bool bFullReinit = false;
1873 : // check if the query signature (if the form is based on a query) has changed
1874 0 : if ( !m_sQueryCommand.isEmpty() )
1875 : {
1876 0 : OUString sNewQueryCommand;
1877 : bool bNewQueryEP;
1878 :
1879 : #if OSL_DEBUG_LEVEL > 0
1880 : bool bIsQuery =
1881 : #endif
1882 0 : implGetQuerySignature( sNewQueryCommand, bNewQueryEP );
1883 : OSL_ENSURE( bIsQuery, "SbaTableQueryBrowser::Execute: was a query before, but is not anymore?" );
1884 :
1885 0 : bFullReinit = ( sNewQueryCommand != m_sQueryCommand ) || ( m_bQueryEscapeProcessing != bNewQueryEP );
1886 : }
1887 0 : if ( !bFullReinit )
1888 : {
1889 : // let the base class do a simple reload
1890 0 : SbaXDataBrowserController::Execute(nId,aArgs);
1891 0 : break;
1892 : }
1893 : // NO break here!
1894 : }
1895 :
1896 : case ID_BROWSER_REFRESH_REBUILD:
1897 : {
1898 0 : if ( !SaveModified() )
1899 : // nothing to do
1900 0 : break;
1901 :
1902 0 : SvTreeListEntry* pSelected = m_pCurrentlyDisplayed;
1903 : // unload
1904 0 : unloadAndCleanup( false );
1905 :
1906 : // reselect the entry
1907 0 : if ( pSelected )
1908 : {
1909 0 : implSelect( pSelected );
1910 : }
1911 : else
1912 : {
1913 0 : Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
1914 0 : implSelect(svx::ODataAccessDescriptor(xProp));
1915 : }
1916 : }
1917 0 : break;
1918 :
1919 : case ID_BROWSER_EXPLORER:
1920 0 : toggleExplorer();
1921 0 : break;
1922 :
1923 : case ID_BROWSER_DOCUMENT_DATASOURCE:
1924 0 : implSelect(m_aDocumentDataSource);
1925 0 : break;
1926 :
1927 : case ID_BROWSER_INSERTCOLUMNS:
1928 : case ID_BROWSER_INSERTCONTENT:
1929 : case ID_BROWSER_FORMLETTER:
1930 0 : if (getBrowserView() && isValidCursor())
1931 : {
1932 : // the URL the slot id is assigned to
1933 : OSL_ENSURE( m_aExternalFeatures.find( nId ) != m_aExternalFeatures.end(),
1934 : "SbaTableQueryBrowser::Execute( ID_BROWSER_?): how could this ever be enabled?" );
1935 0 : URL aParentUrl = m_aExternalFeatures[ nId ].aURL;
1936 :
1937 : // let the dispatcher execute the slot
1938 0 : Reference< XDispatch > xDispatch( m_aExternalFeatures[ nId ].xDispatcher );
1939 0 : if (xDispatch.is())
1940 : {
1941 : // set the properties for the dispatch
1942 :
1943 : // first fill the selection
1944 0 : SbaGridControl* pGrid = getBrowserView()->getVclControl();
1945 0 : MultiSelection* pSelection = const_cast<MultiSelection*>(pGrid->GetSelection());
1946 0 : Sequence< Any > aSelection;
1947 0 : if ( !pGrid->IsAllSelected() )
1948 : { // transfer the selected rows only if not all rows are selected
1949 : // (all rows means the whole table)
1950 : // #i3832#
1951 0 : if (pSelection != NULL)
1952 : {
1953 0 : aSelection.realloc(pSelection->GetSelectCount());
1954 0 : long nIdx = pSelection->FirstSelected();
1955 0 : Any* pSelectionNos = aSelection.getArray();
1956 0 : while (nIdx >= 0)
1957 : {
1958 0 : *pSelectionNos++ <<= (sal_Int32)(nIdx + 1);
1959 0 : nIdx = pSelection->NextSelected();
1960 : }
1961 : }
1962 : }
1963 :
1964 0 : Reference< XResultSet > xCursorClone;
1965 : try
1966 : {
1967 0 : Reference< XResultSetAccess > xResultSetAccess(getRowSet(),UNO_QUERY);
1968 0 : if (xResultSetAccess.is())
1969 0 : xCursorClone = xResultSetAccess->createResultSet();
1970 : }
1971 0 : catch(DisposedException&)
1972 : {
1973 : SAL_WARN("dbaccess.ui", "Object already disposed!");
1974 : }
1975 0 : catch(const Exception&)
1976 : {
1977 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::Execute(ID_BROWSER_?): could not clone the cursor!");
1978 : }
1979 :
1980 0 : Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
1981 :
1982 : try
1983 : {
1984 0 : ODataAccessDescriptor aDescriptor;
1985 0 : OUString sDataSourceName;
1986 0 : xProp->getPropertyValue(PROPERTY_DATASOURCENAME) >>= sDataSourceName;
1987 :
1988 0 : aDescriptor.setDataSource(sDataSourceName);
1989 0 : aDescriptor[daCommand] = xProp->getPropertyValue(PROPERTY_COMMAND);
1990 0 : aDescriptor[daCommandType] = xProp->getPropertyValue(PROPERTY_COMMAND_TYPE);
1991 0 : aDescriptor[daConnection] = xProp->getPropertyValue(PROPERTY_ACTIVE_CONNECTION);
1992 0 : aDescriptor[daCursor] <<= xCursorClone;
1993 0 : if ( aSelection.getLength() )
1994 : {
1995 0 : aDescriptor[daSelection] <<= aSelection;
1996 0 : aDescriptor[daBookmarkSelection] <<= sal_False;
1997 : // these are selection indices
1998 : // before we change this, all clients have to be adjusted
1999 : // so that they recognize the new BookmarkSelection property!
2000 : }
2001 :
2002 0 : xDispatch->dispatch(aParentUrl, aDescriptor.createPropertyValueSequence());
2003 : }
2004 0 : catch( const Exception& )
2005 : {
2006 : DBG_UNHANDLED_EXCEPTION();
2007 0 : }
2008 0 : }
2009 : }
2010 0 : break;
2011 :
2012 : case ID_BROWSER_CLOSE:
2013 0 : closeTask();
2014 : // if it's not 0, such a async close is already pending
2015 0 : break;
2016 :
2017 : case ID_BROWSER_COPY:
2018 0 : if(m_pTreeView->HasChildPathFocus())
2019 : {
2020 0 : copyEntry(m_pTreeView->getListBox().GetCurEntry());
2021 : }
2022 0 : else if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing() && getBrowserView()->getVclControl()->GetSelectRowCount() < 1)
2023 : {
2024 0 : SbaGridControl* pControl = getBrowserView()->getVclControl();
2025 0 : pControl->copyCellText(pControl->GetCurRow(), pControl->GetCurColumnId());
2026 : }
2027 : else
2028 0 : SbaXDataBrowserController::Execute(nId,aArgs);
2029 0 : break;
2030 : }
2031 0 : }
2032 :
2033 0 : void SbaTableQueryBrowser::implAddDatasource( const OUString& _rDataSourceName, const SharedConnection& _rxConnection )
2034 : {
2035 0 : Image a, b, c;
2036 0 : OUString d, e;
2037 0 : implAddDatasource( _rDataSourceName, a, d, b, e, c, _rxConnection );
2038 0 : }
2039 :
2040 1 : void SbaTableQueryBrowser::implAddDatasource(const OUString& _rDbName, Image& _rDbImage,
2041 : OUString& _rQueryName, Image& _rQueryImage, OUString& _rTableName, Image& _rTableImage,
2042 : const SharedConnection& _rxConnection)
2043 : {
2044 1 : SolarMutexGuard aGuard;
2045 : // initialize the names/images if necessary
2046 1 : if (_rQueryName.isEmpty())
2047 1 : _rQueryName = OUString(ModuleRes(RID_STR_QUERIES_CONTAINER));
2048 1 : if (_rTableName.isEmpty())
2049 1 : _rTableName = OUString(ModuleRes(RID_STR_TABLES_CONTAINER));
2050 :
2051 2 : ImageProvider aImageProvider;
2052 1 : if (!_rQueryImage)
2053 1 : _rQueryImage = ImageProvider::getFolderImage( DatabaseObject::QUERY );
2054 1 : if (!_rTableImage)
2055 1 : _rTableImage = ImageProvider::getFolderImage( DatabaseObject::TABLE );
2056 :
2057 1 : if (!_rDbImage)
2058 1 : _rDbImage = ImageProvider::getDatabaseImage();
2059 :
2060 : // add the entry for the data source
2061 : // special handling for data sources denoted by URLs - we do not want to display this ugly URL, do we?
2062 : // #i33699#
2063 2 : OUString sDSDisplayName, sDataSourceId;
2064 1 : getDataSourceDisplayName_isURL( _rDbName, sDSDisplayName, sDataSourceId );
2065 :
2066 1 : SvTreeListEntry* pDatasourceEntry = m_pTreeView->getListBox().InsertEntry( sDSDisplayName, _rDbImage, _rDbImage, NULL, false );
2067 1 : DBTreeListUserData* pDSData = new DBTreeListUserData;
2068 1 : pDSData->eType = etDatasource;
2069 1 : pDSData->sAccessor = sDataSourceId;
2070 1 : pDSData->xConnection = _rxConnection;
2071 1 : pDatasourceEntry->SetUserData(pDSData);
2072 :
2073 : // the child for the queries container
2074 : {
2075 1 : DBTreeListUserData* pQueriesData = new DBTreeListUserData;
2076 1 : pQueriesData->eType = etQueryContainer;
2077 :
2078 1 : m_pTreeView->getListBox().InsertEntry(
2079 : _rQueryName, _rQueryImage, _rQueryImage, pDatasourceEntry,
2080 1 : true /*ChildrenOnDemand*/, TREELIST_APPEND, pQueriesData );
2081 : }
2082 :
2083 : // the child for the tables container
2084 : {
2085 1 : DBTreeListUserData* pTablesData = new DBTreeListUserData;
2086 1 : pTablesData->eType = etTableContainer;
2087 :
2088 1 : m_pTreeView->getListBox().InsertEntry(
2089 : _rTableName, _rTableImage, _rTableImage, pDatasourceEntry,
2090 1 : true /*ChildrenOnDemand*/, TREELIST_APPEND, pTablesData );
2091 1 : }
2092 :
2093 1 : }
2094 :
2095 1 : void SbaTableQueryBrowser::initializeTreeModel()
2096 : {
2097 1 : if (m_xDatabaseContext.is())
2098 : {
2099 2 : Image aDBImage, aQueriesImage, aTablesImage;
2100 2 : OUString sQueriesName, sTablesName;
2101 :
2102 : // fill the model with the names of the registered datasources
2103 2 : Sequence< OUString > aDatasources = m_xDatabaseContext->getElementNames();
2104 1 : const OUString* pIter = aDatasources.getConstArray();
2105 1 : const OUString* pEnd = pIter + aDatasources.getLength();
2106 2 : for (; pIter != pEnd; ++pIter)
2107 2 : implAddDatasource( *pIter, aDBImage, sQueriesName, aQueriesImage, sTablesName, aTablesImage, SharedConnection() );
2108 : }
2109 1 : }
2110 :
2111 1 : void SbaTableQueryBrowser::populateTree(const Reference<XNameAccess>& _xNameAccess,
2112 : SvTreeListEntry* _pParent,
2113 : EntryType _eEntryType)
2114 : {
2115 1 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pParent->GetUserData());
2116 1 : if(pData) // don't ask if the nameaccess is already set see OnExpandEntry views and tables
2117 1 : pData->xContainer = _xNameAccess;
2118 :
2119 : try
2120 : {
2121 1 : Sequence< OUString > aNames = _xNameAccess->getElementNames();
2122 1 : const OUString* pIter = aNames.getConstArray();
2123 1 : const OUString* pEnd = pIter + aNames.getLength();
2124 2 : for (; pIter != pEnd; ++pIter)
2125 : {
2126 1 : if( !m_pTreeView->getListBox().GetEntryPosByName(*pIter,_pParent))
2127 : {
2128 1 : DBTreeListUserData* pEntryData = new DBTreeListUserData;
2129 1 : pEntryData->eType = _eEntryType;
2130 1 : if ( _eEntryType == etQuery )
2131 : {
2132 0 : Reference<XNameAccess> xChild(_xNameAccess->getByName(*pIter),UNO_QUERY);
2133 0 : if ( xChild.is() )
2134 0 : pEntryData->eType = etQueryContainer;
2135 : }
2136 1 : implAppendEntry( _pParent, *pIter, pEntryData, pEntryData->eType );
2137 : }
2138 1 : }
2139 : }
2140 0 : catch(const Exception&)
2141 : {
2142 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::populateTree: could not fill the tree");
2143 : }
2144 1 : }
2145 :
2146 1 : SvTreeListEntry* SbaTableQueryBrowser::implAppendEntry( SvTreeListEntry* _pParent, const OUString& _rName, void* _pUserData, EntryType _eEntryType )
2147 : {
2148 1 : ::std::unique_ptr< ImageProvider > pImageProvider( getImageProviderFor( _pParent ) );
2149 :
2150 2 : Image aImage;
2151 1 : pImageProvider->getImages( _rName, getDatabaseObjectType( _eEntryType ), aImage );
2152 :
2153 1 : SvTreeListEntry* pNewEntry = m_pTreeView->getListBox().InsertEntry( _rName, _pParent, _eEntryType == etQueryContainer , TREELIST_APPEND, _pUserData );
2154 :
2155 1 : m_pTreeView->getListBox().SetExpandedEntryBmp( pNewEntry, aImage );
2156 1 : m_pTreeView->getListBox().SetCollapsedEntryBmp( pNewEntry, aImage );
2157 :
2158 2 : return pNewEntry;
2159 : }
2160 :
2161 2 : IMPL_LINK(SbaTableQueryBrowser, OnExpandEntry, SvTreeListEntry*, _pParent)
2162 : {
2163 1 : if (_pParent->HasChildren())
2164 : // nothing to do...
2165 0 : return 1L;
2166 :
2167 1 : SvTreeListEntry* pFirstParent = m_pTreeView->getListBox().GetRootLevelParent(_pParent);
2168 : OSL_ENSURE(pFirstParent,"SbaTableQueryBrowser::OnExpandEntry: No rootlevelparent!");
2169 :
2170 1 : DBTreeListUserData* pData = static_cast< DBTreeListUserData* >(_pParent->GetUserData());
2171 : assert(pData && "SbaTableQueryBrowser::OnExpandEntry: No user data!");
2172 : #if OSL_DEBUG_LEVEL > 0
2173 : SvLBoxString* pString = static_cast<SvLBoxString*>(pFirstParent->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING));
2174 : OSL_ENSURE(pString,"SbaTableQueryBrowser::OnExpandEntry: No string item!");
2175 : #endif
2176 :
2177 1 : if (etTableContainer == pData->eType)
2178 : {
2179 1 : WaitObject aWaitCursor(getBrowserView());
2180 :
2181 : // it could be that we already have a connection
2182 2 : SharedConnection xConnection;
2183 1 : ensureConnection( pFirstParent, xConnection );
2184 :
2185 1 : if ( xConnection.is() )
2186 : {
2187 1 : SQLExceptionInfo aInfo;
2188 : try
2189 : {
2190 1 : Reference< XWarningsSupplier > xWarnings(xConnection, UNO_QUERY);
2191 1 : if (xWarnings.is())
2192 1 : xWarnings->clearWarnings();
2193 :
2194 : // first insert the views because the tables can also include
2195 : // views but that time the bitmap is the wrong one
2196 : // the nameaccess will be overwritten in populateTree
2197 2 : Reference<XViewsSupplier> xViewSup(xConnection,UNO_QUERY);
2198 1 : if(xViewSup.is())
2199 0 : populateTree( xViewSup->getViews(), _pParent, etTableOrView );
2200 :
2201 2 : Reference<XTablesSupplier> xTabSup(xConnection,UNO_QUERY);
2202 1 : if(xTabSup.is())
2203 : {
2204 1 : populateTree( xTabSup->getTables(), _pParent, etTableOrView );
2205 1 : Reference<XContainer> xCont(xTabSup->getTables(),UNO_QUERY);
2206 1 : if(xCont.is())
2207 : // add as listener to know when elements are inserted or removed
2208 1 : xCont->addContainerListener(this);
2209 : }
2210 :
2211 1 : if (xWarnings.is())
2212 : {
2213 1 : SQLExceptionInfo aWarnings(xWarnings->getWarnings());
2214 : #if 0
2215 : // Obviously this if test is always false. So to avoid a Clang warning
2216 : // "use of logical '&&' with constant operand" I put this in #if
2217 : // 0. Yeah, I know it is fairly likely nobody will ever read this
2218 : // comment and make a decision what to do here, so I could as well
2219 : // have just binned this...
2220 : if (aWarnings.isValid() && sal_False)
2221 : {
2222 : SQLContext aContext;
2223 : aContext.Message = String(ModuleRes(STR_OPENTABLES_WARNINGS));
2224 : aContext.Details = String(ModuleRes(STR_OPENTABLES_WARNINGS_DETAILS));
2225 : aContext.NextException = aWarnings.get();
2226 : aWarnings = aContext;
2227 : showError(aWarnings);
2228 : }
2229 : #endif
2230 : // TODO: we need a better concept for these warnings:
2231 : // something like "don't show any warnings for this datasource, again" would be nice
2232 : // But this requires an extension of the InteractionHandler and an additional property on the data source
2233 1 : }
2234 : }
2235 0 : catch(const SQLContext& e) { aInfo = e; }
2236 0 : catch(const SQLWarning& e) { aInfo = e; }
2237 0 : catch(const SQLException& e) { aInfo = e; }
2238 0 : catch(const WrappedTargetException& e)
2239 : {
2240 0 : SQLException aSql;
2241 0 : if(e.TargetException >>= aSql)
2242 0 : aInfo = aSql;
2243 : else
2244 0 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::OnExpandEntry: something strange happened!");
2245 : }
2246 0 : catch( const Exception& )
2247 : {
2248 : DBG_UNHANDLED_EXCEPTION();
2249 : }
2250 1 : if (aInfo.isValid())
2251 0 : showError(aInfo);
2252 : }
2253 : else
2254 1 : return 0L;
2255 : // 0 indicates that an error occurred
2256 : }
2257 : else
2258 : { // we have to expand the queries or bookmarks
2259 0 : if (ensureEntryObject(_pParent))
2260 : {
2261 0 : DBTreeListUserData* pParentData = static_cast< DBTreeListUserData* >( _pParent->GetUserData() );
2262 0 : Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY );
2263 0 : populateTree( xCollection, _pParent, etQuery );
2264 : }
2265 : }
2266 1 : return 1L;
2267 : }
2268 :
2269 0 : bool SbaTableQueryBrowser::ensureEntryObject( SvTreeListEntry* _pEntry )
2270 : {
2271 : OSL_ENSURE(_pEntry, "SbaTableQueryBrowser::ensureEntryObject: invalid argument!");
2272 0 : if (!_pEntry)
2273 0 : return false;
2274 :
2275 0 : EntryType eType = getEntryType( _pEntry );
2276 :
2277 : // the user data of the entry
2278 0 : DBTreeListUserData* pEntryData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData());
2279 : OSL_ENSURE(pEntryData,"ensureEntryObject: user data should already be set!");
2280 :
2281 0 : SvTreeListEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent(_pEntry);
2282 :
2283 0 : bool bSuccess = false;
2284 0 : switch (eType)
2285 : {
2286 : case etQueryContainer:
2287 0 : if ( pEntryData->xContainer.is() )
2288 : {
2289 : // nothing to do
2290 0 : bSuccess = true;
2291 0 : break;
2292 : }
2293 :
2294 : {
2295 0 : SvTreeListEntry* pParent = m_pTreeView->getListBox().GetParent(_pEntry);
2296 0 : if ( pParent != pDataSourceEntry )
2297 : {
2298 0 : SvLBoxString* pString = static_cast<SvLBoxString*>(_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING));
2299 : OSL_ENSURE(pString,"There must be a string item!");
2300 0 : OUString aName(pString->GetText());
2301 0 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pParent->GetUserData());
2302 : try
2303 : {
2304 0 : Reference< XNameAccess > xNameAccess(pData->xContainer,UNO_QUERY);
2305 0 : if ( xNameAccess.is() )
2306 0 : pEntryData->xContainer.set(xNameAccess->getByName(aName),UNO_QUERY);
2307 : }
2308 0 : catch(const Exception& )
2309 : {
2310 : DBG_UNHANDLED_EXCEPTION();
2311 : }
2312 :
2313 0 : bSuccess = pEntryData->xContainer.is();
2314 : }
2315 : else
2316 : {
2317 : try
2318 : {
2319 0 : Reference< XQueryDefinitionsSupplier > xQuerySup;
2320 0 : m_xDatabaseContext->getByName( getDataSourceAcessor( pDataSourceEntry ) ) >>= xQuerySup;
2321 0 : if (xQuerySup.is())
2322 : {
2323 0 : Reference< XNameAccess > xQueryDefs = xQuerySup->getQueryDefinitions();
2324 0 : Reference< XContainer > xCont(xQueryDefs, UNO_QUERY);
2325 0 : if (xCont.is())
2326 : // add as listener to get notified if elements are inserted or removed
2327 0 : xCont->addContainerListener(this);
2328 :
2329 0 : pEntryData->xContainer = xQueryDefs;
2330 0 : bSuccess = pEntryData->xContainer.is();
2331 : }
2332 : else {
2333 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::ensureEntryObject: no XQueryDefinitionsSupplier interface!");
2334 0 : }
2335 : }
2336 0 : catch( const Exception& )
2337 : {
2338 : DBG_UNHANDLED_EXCEPTION();
2339 : }
2340 : }
2341 : }
2342 0 : break;
2343 :
2344 : default:
2345 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::ensureEntryObject: ooops ... missing some implementation here!");
2346 : // TODO ...
2347 0 : break;
2348 : }
2349 :
2350 0 : return bSuccess;
2351 : }
2352 :
2353 2 : bool SbaTableQueryBrowser::implSelect(const svx::ODataAccessDescriptor& _rDescriptor, bool _bSelectDirect)
2354 : {
2355 : // extract the props
2356 2 : OUString sDataSource;
2357 4 : OUString sCommand;
2358 2 : sal_Int32 nCommandType = CommandType::COMMAND;
2359 2 : bool bEscapeProcessing = true;
2360 2 : extractDescriptorProps(_rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing);
2361 :
2362 : // select it
2363 4 : return implSelect( sDataSource, sCommand, nCommandType, bEscapeProcessing, SharedConnection(), _bSelectDirect );
2364 : }
2365 :
2366 1 : bool SbaTableQueryBrowser::implLoadAnything(const OUString& _rDataSourceName, const OUString& _rCommand,
2367 : const sal_Int32 _nCommandType, const bool _bEscapeProcessing, const SharedConnection& _rxConnection)
2368 : {
2369 : try
2370 : {
2371 1 : Reference<XPropertySet> xProp( getRowSet(), UNO_QUERY_THROW );
2372 2 : Reference< XLoadable > xLoadable( xProp, UNO_QUERY_THROW );
2373 : // the values allowing the RowSet to re-execute
2374 1 : xProp->setPropertyValue(PROPERTY_DATASOURCENAME, makeAny(_rDataSourceName));
2375 1 : if(_rxConnection.is())
2376 1 : xProp->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( _rxConnection.getTyped() ) );
2377 :
2378 : // set this _before_ setting the connection, else the rowset would rebuild it ...
2379 1 : xProp->setPropertyValue(PROPERTY_COMMAND_TYPE, makeAny(_nCommandType));
2380 1 : xProp->setPropertyValue(PROPERTY_COMMAND, makeAny(_rCommand));
2381 1 : xProp->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, css::uno::makeAny(_bEscapeProcessing));
2382 1 : if ( m_bPreview )
2383 : {
2384 0 : xProp->setPropertyValue(PROPERTY_FETCHDIRECTION, makeAny(FetchDirection::FORWARD));
2385 : }
2386 :
2387 : // the formatter depends on the data source we're working on, so rebuild it here ...
2388 1 : initFormatter();
2389 :
2390 : // switch the grid to design mode while loading
2391 1 : getBrowserView()->getGridControl()->setDesignMode(sal_True);
2392 1 : InitializeForm( xProp );
2393 :
2394 1 : bool bSuccess = true;
2395 :
2396 : {
2397 : {
2398 1 : Reference< XNameContainer > xColContainer(getFormComponent(), UNO_QUERY);
2399 : // first we have to clear the grid
2400 1 : clearGridColumns(xColContainer);
2401 : }
2402 1 : FormErrorHelper aHelper(this);
2403 : // load the form
2404 1 : bSuccess = reloadForm(xLoadable);
2405 :
2406 : // initialize the model
2407 1 : InitializeGridModel(getFormComponent());
2408 :
2409 2 : Any aVal = xProp->getPropertyValue(PROPERTY_ISNEW);
2410 1 : if (aVal.hasValue() && ::comphelper::getBOOL(aVal))
2411 : {
2412 : // then set the default values and the parameters given from the parent
2413 0 : Reference< XReset> xReset(xProp, UNO_QUERY);
2414 0 : xReset->reset();
2415 : }
2416 :
2417 1 : if ( m_bPreview )
2418 0 : initializePreviewMode();
2419 :
2420 2 : LoadFinished(true);
2421 : }
2422 :
2423 1 : InvalidateAll();
2424 2 : return bSuccess;
2425 : }
2426 0 : catch( const SQLException& )
2427 : {
2428 0 : Any aException( ::cppu::getCaughtException() );
2429 0 : showError( SQLExceptionInfo( aException ) );
2430 : }
2431 0 : catch( const WrappedTargetException& e )
2432 : {
2433 0 : SQLException aSql;
2434 0 : if ( e.TargetException.isExtractableTo( ::cppu::UnoType< SQLException >::get() ) )
2435 0 : showError( SQLExceptionInfo( e.TargetException ) );
2436 : else
2437 : {
2438 : DBG_UNHANDLED_EXCEPTION();
2439 0 : }
2440 : }
2441 0 : catch(const Exception&)
2442 : {
2443 : DBG_UNHANDLED_EXCEPTION();
2444 : }
2445 :
2446 0 : InvalidateAll();
2447 0 : return false;
2448 : }
2449 :
2450 3 : bool SbaTableQueryBrowser::implSelect(const OUString& _rDataSourceName, const OUString& _rCommand,
2451 : const sal_Int32 _nCommandType, const bool _bEscapeProcessing,
2452 : const SharedConnection& _rxConnection,
2453 : bool _bSelectDirect)
2454 : {
2455 3 : if (_rDataSourceName.getLength() && _rCommand.getLength() && (-1 != _nCommandType))
2456 : {
2457 1 : SvTreeListEntry* pDataSource = NULL;
2458 1 : SvTreeListEntry* pCommandType = NULL;
2459 1 : SvTreeListEntry* pCommand = getObjectEntry( _rDataSourceName, _rCommand, _nCommandType, &pDataSource, &pCommandType, true, _rxConnection );
2460 :
2461 1 : if (pCommand)
2462 : {
2463 1 : bool bSuccess = true;
2464 1 : if ( _bSelectDirect )
2465 : {
2466 1 : bSuccess = implSelect( pCommand );
2467 : }
2468 : else
2469 : {
2470 0 : m_pTreeView->getListBox().Select( pCommand );
2471 : }
2472 :
2473 1 : if ( bSuccess )
2474 : {
2475 1 : m_pTreeView->getListBox().MakeVisible(pCommand);
2476 1 : m_pTreeView->getListBox().SetCursor(pCommand);
2477 : }
2478 : }
2479 0 : else if (!pCommandType)
2480 : {
2481 0 : if ( m_pCurrentlyDisplayed )
2482 : { // tell the old entry (if any) it has been deselected
2483 0 : selectPath(m_pCurrentlyDisplayed, false);
2484 0 : m_pCurrentlyDisplayed = NULL;
2485 : }
2486 :
2487 : // we have a command and need to display this in the rowset
2488 0 : return implLoadAnything(_rDataSourceName, _rCommand, _nCommandType, _bEscapeProcessing, _rxConnection);
2489 : }
2490 : }
2491 3 : return false;
2492 : }
2493 :
2494 0 : IMPL_LINK_NOARG(SbaTableQueryBrowser, OnSelectionChange)
2495 : {
2496 0 : return implSelect( m_pTreeView->getListBox().FirstSelected() ) ? 1L : 0L;
2497 : }
2498 :
2499 2 : SvTreeListEntry* SbaTableQueryBrowser::implGetConnectionEntry(SvTreeListEntry* _pEntry) const
2500 : {
2501 2 : SvTreeListEntry* pCurrentEntry = _pEntry;
2502 2 : DBTreeListUserData* pEntryData = static_cast< DBTreeListUserData* >( pCurrentEntry->GetUserData() );
2503 6 : while(pEntryData->eType != etDatasource )
2504 : {
2505 2 : pCurrentEntry = m_pTreeModel->GetParent(pCurrentEntry);
2506 2 : pEntryData = static_cast< DBTreeListUserData* >( pCurrentEntry->GetUserData() );
2507 : }
2508 2 : return pCurrentEntry;
2509 : }
2510 :
2511 1 : bool SbaTableQueryBrowser::implSelect( SvTreeListEntry* _pEntry )
2512 : {
2513 1 : if ( !_pEntry )
2514 0 : return false;
2515 :
2516 1 : DBTreeListUserData* pEntryData = static_cast< DBTreeListUserData* >( _pEntry->GetUserData() );
2517 1 : switch (pEntryData->eType)
2518 : {
2519 : case etTableOrView:
2520 : case etQuery:
2521 1 : break;
2522 : default:
2523 : // nothing to do
2524 0 : return false;
2525 : }
2526 :
2527 : OSL_ENSURE(m_pTreeModel->HasParent(_pEntry), "SbaTableQueryBrowser::implSelect: invalid entry (1)!");
2528 : OSL_ENSURE(m_pTreeModel->HasParent(m_pTreeModel->GetParent(_pEntry)), "SbaTableQueryBrowser::implSelect: invalid entry (2)!");
2529 :
2530 : // get the entry for the tables or queries
2531 1 : SvTreeListEntry* pContainer = m_pTreeModel->GetParent(_pEntry);
2532 1 : DBTreeListUserData* pContainerData = static_cast<DBTreeListUserData*>(pContainer->GetUserData());
2533 :
2534 : // get the entry for the datasource
2535 1 : SvTreeListEntry* pConnection = implGetConnectionEntry(pContainer);
2536 1 : DBTreeListUserData* pConData = static_cast<DBTreeListUserData*>(pConnection->GetUserData());
2537 :
2538 : // reinitialize the rowset
2539 : // but first check if it is necessary
2540 : // get all old properties
2541 1 : Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
2542 2 : OUString aOldName;
2543 1 : xRowSetProps->getPropertyValue(PROPERTY_COMMAND) >>= aOldName;
2544 1 : sal_Int32 nOldType = 0;
2545 1 : xRowSetProps->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nOldType;
2546 2 : Reference<XConnection> xOldConnection(xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY);
2547 :
2548 : // the name of the table or query
2549 1 : SvLBoxString* pString = static_cast<SvLBoxString*>(_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING));
2550 : OSL_ENSURE(pString,"There must be a string item!");
2551 2 : const OUString sSimpleName = pString->GetText();
2552 2 : OUStringBuffer sNameBuffer(sSimpleName);
2553 1 : if ( etQueryContainer == pContainerData->eType )
2554 : {
2555 0 : SvTreeListEntry* pTemp = pContainer;
2556 0 : while( m_pTreeModel->GetParent(pTemp) != pConnection )
2557 : {
2558 0 : sNameBuffer.insert(0,'/');
2559 0 : pString = static_cast<SvLBoxString*>(pTemp->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING));
2560 : OSL_ENSURE(pString,"There must be a string item!");
2561 0 : sNameBuffer.insert(0,pString->GetText());
2562 0 : pTemp = m_pTreeModel->GetParent(pTemp);
2563 : }
2564 : }
2565 2 : OUString aName = sNameBuffer.makeStringAndClear();
2566 :
2567 1 : sal_Int32 nCommandType = ( etTableContainer == pContainerData->eType)
2568 : ? CommandType::TABLE
2569 1 : : CommandType::QUERY;
2570 :
2571 : // check if need to rebuild the rowset
2572 1 : bool bRebuild = ( xOldConnection != pConData->xConnection )
2573 0 : || ( nOldType != nCommandType )
2574 1 : || ( aName != aOldName );
2575 :
2576 2 : Reference< ::com::sun::star::form::XLoadable > xLoadable = getLoadable();
2577 1 : bRebuild |= !xLoadable->isLoaded();
2578 1 : bool bSuccess = true;
2579 1 : if ( bRebuild )
2580 : {
2581 : try
2582 : {
2583 1 : WaitObject aWaitCursor(getBrowserView());
2584 :
2585 : // tell the old entry it has been deselected
2586 1 : selectPath(m_pCurrentlyDisplayed, false);
2587 1 : m_pCurrentlyDisplayed = NULL;
2588 :
2589 : // not really loaded
2590 1 : m_pCurrentlyDisplayed = _pEntry;
2591 : // tell the new entry it has been selected
2592 1 : selectPath(m_pCurrentlyDisplayed, true);
2593 :
2594 : // get the name of the data source currently selected
2595 1 : ensureConnection( m_pCurrentlyDisplayed, pConData->xConnection );
2596 :
2597 1 : if ( !pConData->xConnection.is() )
2598 : {
2599 0 : unloadAndCleanup( false );
2600 0 : return false;
2601 : }
2602 :
2603 2 : Reference<XNameAccess> xNameAccess;
2604 1 : switch(nCommandType)
2605 : {
2606 : case CommandType::TABLE:
2607 : {
2608 : // only for tables
2609 1 : if ( !pContainerData->xContainer.is() )
2610 : {
2611 0 : Reference<XTablesSupplier> xSup( pConData->xConnection, UNO_QUERY );
2612 0 : if(xSup.is())
2613 0 : xNameAccess = xSup->getTables();
2614 :
2615 0 : pContainerData->xContainer = xNameAccess;
2616 : }
2617 : else
2618 1 : xNameAccess.set( pContainerData->xContainer, UNO_QUERY );
2619 : }
2620 1 : break;
2621 : case CommandType::QUERY:
2622 : {
2623 0 : if ( pContainerData->xContainer.is() )
2624 0 : xNameAccess.set( pContainerData->xContainer, UNO_QUERY );
2625 : else
2626 : {
2627 0 : Reference<XQueriesSupplier> xSup( pConData->xConnection, UNO_QUERY );
2628 0 : if(xSup.is())
2629 0 : xNameAccess = xSup->getQueries();
2630 : }
2631 : }
2632 0 : break;
2633 : }
2634 1 : OUString sStatus(ModuleRes( CommandType::TABLE == nCommandType ? STR_LOADING_TABLE : STR_LOADING_QUERY ));
2635 1 : sStatus = sStatus.replaceFirst("$name$", aName);
2636 2 : BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sStatus);
2637 :
2638 1 : bool bEscapeProcessing = true;
2639 1 : if(xNameAccess.is() && xNameAccess->hasByName(sSimpleName))
2640 : {
2641 1 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData());
2642 1 : if ( !pData->xObjectProperties.is() )
2643 : {
2644 1 : Reference<XInterface> xObject;
2645 1 : if(xNameAccess->getByName(sSimpleName) >>= xObject) // remember the table or query object
2646 : {
2647 1 : pData->xObjectProperties.set(xObject, css::uno::UNO_QUERY);
2648 : // if the query contains a parameterized statement and preview is enabled we won't get any data.
2649 1 : if ( nCommandType == CommandType::QUERY && xObject.is() )
2650 : {
2651 0 : Reference<XPropertySet> xObjectProps(xObject,UNO_QUERY);
2652 0 : xObjectProps->getPropertyValue(PROPERTY_ESCAPE_PROCESSING) >>= bEscapeProcessing;
2653 0 : if ( m_bPreview )
2654 : {
2655 0 : OUString sSql;
2656 0 : xObjectProps->getPropertyValue(PROPERTY_COMMAND) >>= sSql;
2657 0 : Reference< XMultiServiceFactory > xFactory( pConData->xConnection, UNO_QUERY );
2658 0 : if (xFactory.is())
2659 : {
2660 : try
2661 : {
2662 0 : Reference<XSingleSelectQueryAnalyzer> xAnalyzer(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY);
2663 0 : if ( xAnalyzer.is() )
2664 : {
2665 0 : xAnalyzer->setQuery(sSql);
2666 0 : Reference<XParametersSupplier> xParSup(xAnalyzer,UNO_QUERY);
2667 0 : if ( xParSup->getParameters()->getCount() > 0 )
2668 : {
2669 0 : OUString sFilter = " WHERE ";
2670 0 : sFilter = sFilter + xAnalyzer->getFilter();
2671 0 : OUString sReplace(sSql);
2672 0 : sReplace = sReplace.replaceFirst(sFilter,OUString());
2673 0 : xAnalyzer->setQuery(sReplace);
2674 0 : Reference<XSingleSelectQueryComposer> xComposer(xAnalyzer,UNO_QUERY);
2675 0 : xComposer->setFilter(OUString("0=1"));
2676 0 : aName = xAnalyzer->getQuery();
2677 0 : nCommandType = CommandType::COMMAND;
2678 0 : }
2679 0 : }
2680 : }
2681 0 : catch (Exception&)
2682 : {
2683 : DBG_UNHANDLED_EXCEPTION();
2684 : }
2685 0 : }
2686 0 : }
2687 : }
2688 1 : }
2689 : }
2690 : }
2691 :
2692 2 : OUString sDataSourceName( getDataSourceAcessor( pConnection ) );
2693 1 : bSuccess = implLoadAnything( sDataSourceName, aName, nCommandType, bEscapeProcessing, pConData->xConnection );
2694 1 : if ( !bSuccess )
2695 : { // clean up
2696 0 : criticalFail();
2697 2 : }
2698 : }
2699 0 : catch(const SQLException& e)
2700 : {
2701 0 : showError(SQLExceptionInfo(e));
2702 : // reset the values
2703 0 : xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2704 0 : xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2705 : }
2706 0 : catch(WrappedTargetException& e)
2707 : {
2708 0 : SQLException aSql;
2709 0 : if(e.TargetException >>= aSql)
2710 0 : showError(SQLExceptionInfo(aSql));
2711 : else
2712 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::implSelect: something strange happened!");
2713 : // reset the values
2714 0 : xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2715 0 : xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2716 : }
2717 0 : catch(const Exception&)
2718 : {
2719 : // reset the values
2720 0 : xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2721 0 : xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2722 : }
2723 : }
2724 2 : return bSuccess;
2725 : }
2726 :
2727 31 : SvTreeListEntry* SbaTableQueryBrowser::getEntryFromContainer(const Reference<XNameAccess>& _rxNameAccess)
2728 : {
2729 31 : DBTreeListBox& rListBox = m_pTreeView->getListBox();
2730 31 : SvTreeListEntry* pContainer = NULL;
2731 31 : SvTreeListEntry* pDSLoop = rListBox.FirstChild(NULL);
2732 93 : while (pDSLoop)
2733 : {
2734 31 : pContainer = rListBox.GetEntry(pDSLoop, CONTAINER_QUERIES);
2735 31 : DBTreeListUserData* pQueriesData = static_cast<DBTreeListUserData*>(pContainer->GetUserData());
2736 31 : if ( pQueriesData && pQueriesData->xContainer == _rxNameAccess )
2737 0 : break;
2738 :
2739 31 : pContainer = rListBox.GetEntry(pDSLoop, CONTAINER_TABLES);
2740 31 : DBTreeListUserData* pTablesData = static_cast<DBTreeListUserData*>(pContainer->GetUserData());
2741 31 : if ( pTablesData && pTablesData->xContainer == _rxNameAccess )
2742 0 : break;
2743 :
2744 31 : pDSLoop = SvTreeList::NextSibling(pDSLoop);
2745 31 : pContainer = NULL;
2746 : }
2747 31 : return pContainer;
2748 : }
2749 :
2750 31 : void SAL_CALL SbaTableQueryBrowser::elementInserted( const ContainerEvent& _rEvent ) throw(RuntimeException, std::exception)
2751 : {
2752 31 : SolarMutexGuard aSolarGuard;
2753 :
2754 62 : Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY);
2755 : // first search for a definition container where we can insert this element
2756 :
2757 31 : SvTreeListEntry* pEntry = getEntryFromContainer(xNames);
2758 31 : if(pEntry) // found one
2759 : {
2760 : // insert the new entry into the tree
2761 0 : DBTreeListUserData* pContainerData = static_cast<DBTreeListUserData*>(pEntry->GetUserData());
2762 : OSL_ENSURE(pContainerData, "elementInserted: There must be user data for this type!");
2763 :
2764 0 : DBTreeListUserData* pNewData = new DBTreeListUserData;
2765 0 : bool bIsTable = etTableContainer == pContainerData->eType;
2766 0 : if ( bIsTable )
2767 : {
2768 0 : _rEvent.Element >>= pNewData->xObjectProperties;// remember the new element
2769 0 : pNewData->eType = etTableOrView;
2770 : }
2771 : else
2772 : {
2773 0 : if ((sal_Int32)m_pTreeView->getListBox().GetChildCount(pEntry) < ( xNames->getElementNames().getLength() - 1 ) )
2774 : {
2775 : // the item inserts its children on demand, but it has not been expanded yet. So ensure here and
2776 : // now that it has all items
2777 0 : populateTree(xNames, pEntry, etQuery );
2778 : }
2779 0 : pNewData->eType = etQuery;
2780 : }
2781 0 : implAppendEntry( pEntry, ::comphelper::getString( _rEvent.Accessor ), pNewData, pNewData->eType );
2782 : }
2783 : else
2784 62 : SbaXDataBrowserController::elementInserted(_rEvent);
2785 31 : }
2786 :
2787 0 : bool SbaTableQueryBrowser::isCurrentlyDisplayedChanged(const OUString& _sName,SvTreeListEntry* _pContainer)
2788 : {
2789 : return m_pCurrentlyDisplayed
2790 0 : && getEntryType(m_pCurrentlyDisplayed) == getChildType(_pContainer)
2791 0 : && m_pTreeView->getListBox().GetParent(m_pCurrentlyDisplayed) == _pContainer
2792 0 : && m_pTreeView->getListBox().GetEntryText(m_pCurrentlyDisplayed) == _sName;
2793 : }
2794 :
2795 0 : void SAL_CALL SbaTableQueryBrowser::elementRemoved( const ContainerEvent& _rEvent ) throw(RuntimeException, std::exception)
2796 : {
2797 0 : SolarMutexGuard aSolarGuard;
2798 :
2799 0 : Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY);
2800 : // get the top-level representing the removed data source
2801 : // and search for the queries and tables
2802 0 : SvTreeListEntry* pContainer = getEntryFromContainer(xNames);
2803 0 : if ( pContainer )
2804 : { // a query or table has been removed
2805 0 : OUString aName = ::comphelper::getString(_rEvent.Accessor);
2806 :
2807 0 : if ( isCurrentlyDisplayedChanged( aName, pContainer) )
2808 : { // the element displayed currently has been replaced
2809 :
2810 : // we need to remember the old value
2811 0 : SvTreeListEntry* pTemp = m_pCurrentlyDisplayed;
2812 :
2813 : // unload
2814 0 : unloadAndCleanup( false ); // don't dispose the connection
2815 :
2816 0 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pTemp->GetUserData());
2817 0 : pTemp->SetUserData(NULL);
2818 0 : delete pData;
2819 : // the data could be null because we have a table which isn't correct
2820 0 : m_pTreeModel->Remove(pTemp);
2821 : }
2822 : else
2823 : {
2824 : // remove the entry from the model
2825 0 : SvTreeListEntry* pChild = m_pTreeModel->FirstChild(pContainer);
2826 0 : while(pChild)
2827 : {
2828 0 : if (m_pTreeView->getListBox().GetEntryText(pChild) == aName)
2829 : {
2830 0 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pChild->GetUserData());
2831 0 : pChild->SetUserData(NULL);
2832 0 : delete pData;
2833 0 : m_pTreeModel->Remove(pChild);
2834 0 : break;
2835 : }
2836 0 : pChild = SvTreeList::NextSibling(pChild);
2837 : }
2838 : }
2839 :
2840 : // maybe the object which is part of the document data source has been removed
2841 0 : checkDocumentDataSource();
2842 : }
2843 : else
2844 0 : SbaXDataBrowserController::elementRemoved(_rEvent);
2845 0 : }
2846 :
2847 0 : void SAL_CALL SbaTableQueryBrowser::elementReplaced( const ContainerEvent& _rEvent ) throw(RuntimeException, std::exception)
2848 : {
2849 0 : SolarMutexGuard aSolarGuard;
2850 :
2851 0 : Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY);
2852 0 : SvTreeListEntry* pContainer = getEntryFromContainer(xNames);
2853 0 : if ( pContainer )
2854 : { // a table or query as been replaced
2855 0 : OUString aName = ::comphelper::getString(_rEvent.Accessor);
2856 :
2857 0 : if ( isCurrentlyDisplayedChanged( aName, pContainer) )
2858 : { // the element displayed currently has been replaced
2859 :
2860 : // we need to remember the old value
2861 0 : SvTreeListEntry* pTemp = m_pCurrentlyDisplayed;
2862 0 : unloadAndCleanup( false ); // don't dispose the connection
2863 :
2864 0 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pTemp->GetUserData());
2865 0 : if (pData)
2866 : {
2867 0 : if ( etTableOrView == pData->eType )
2868 : { // only insert userdata when we have a table because the query is only a commanddefinition object and not a query
2869 0 : _rEvent.Element >>= pData->xObjectProperties; // remember the new element
2870 : }
2871 : else
2872 : {
2873 0 : pTemp->SetUserData(NULL);
2874 0 : delete pData;
2875 : }
2876 : }
2877 : }
2878 : else
2879 : {
2880 : // find the entry for this name
2881 0 : SvTreeListEntry* pChild = m_pTreeModel->FirstChild(pContainer);
2882 0 : while(pChild)
2883 : {
2884 0 : if (m_pTreeView->getListBox().GetEntryText(pChild) == aName)
2885 : {
2886 0 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pChild->GetUserData());
2887 0 : if (pData)
2888 : {
2889 0 : if ( etTableOrView == pData->eType )
2890 : { // only insert userdata when we have a table because the query is only a commanddefinition object and not a query
2891 0 : _rEvent.Element >>= pData->xObjectProperties; // remember the new element
2892 : }
2893 : else
2894 : {
2895 0 : pChild->SetUserData(NULL);
2896 0 : delete pData;
2897 : }
2898 : }
2899 0 : break;
2900 : }
2901 0 : pChild = SvTreeList::NextSibling(pChild);
2902 : }
2903 : }
2904 :
2905 : // maybe the object which is part of the document data source has been removed
2906 0 : checkDocumentDataSource();
2907 : }
2908 0 : else if (xNames.get() == m_xDatabaseContext.get())
2909 : { // a datasource has been replaced in the context
2910 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::elementReplaced: no support for replaced data sources!");
2911 : // very suspicious: the database context should not allow to replace data source, only to register
2912 : // and revoke them
2913 : }
2914 : else
2915 0 : SbaXDataBrowserController::elementReplaced(_rEvent);
2916 0 : }
2917 :
2918 1 : void SbaTableQueryBrowser::impl_releaseConnection( SharedConnection& _rxConnection )
2919 : {
2920 : // remove as event listener
2921 1 : Reference< XComponent > xComponent( _rxConnection, UNO_QUERY );
2922 1 : if ( xComponent.is() )
2923 : {
2924 1 : Reference< XEventListener > xListener( static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY );
2925 1 : xComponent->removeEventListener( xListener );
2926 : }
2927 :
2928 : try
2929 : {
2930 : // temporary (hopefully!) hack for #i55274#
2931 1 : Reference< XFlushable > xFlush( _rxConnection, UNO_QUERY );
2932 1 : if ( xFlush.is() )
2933 0 : xFlush->flush();
2934 : }
2935 0 : catch( const Exception& )
2936 : {
2937 : DBG_UNHANDLED_EXCEPTION();
2938 : }
2939 :
2940 : // clear
2941 1 : _rxConnection.clear();
2942 : // will implicitly dispose if we have the ownership, since xConnection is a SharedConnection
2943 1 : }
2944 :
2945 0 : void SbaTableQueryBrowser::disposeConnection( SvTreeListEntry* _pDSEntry )
2946 : {
2947 : OSL_ENSURE( _pDSEntry, "SbaTableQueryBrowser::disposeConnection: invalid entry (NULL)!" );
2948 : OSL_ENSURE( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::disposeConnection: invalid entry (not top-level)!" );
2949 :
2950 0 : if ( _pDSEntry )
2951 : {
2952 0 : DBTreeListUserData* pTreeListData = static_cast< DBTreeListUserData* >( _pDSEntry->GetUserData() );
2953 0 : if ( pTreeListData )
2954 0 : impl_releaseConnection( pTreeListData->xConnection );
2955 : }
2956 0 : }
2957 :
2958 0 : void SbaTableQueryBrowser::closeConnection(SvTreeListEntry* _pDSEntry, bool _bDisposeConnection)
2959 : {
2960 : OSL_ENSURE(_pDSEntry, "SbaTableQueryBrowser::closeConnection: invalid entry (NULL)!");
2961 : OSL_ENSURE( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::closeConnection: invalid entry (not top-level)!");
2962 :
2963 : // if one of the entries of the given DS is displayed currently, unload the form
2964 0 : if (m_pCurrentlyDisplayed && (m_pTreeView->getListBox().GetRootLevelParent(m_pCurrentlyDisplayed) == _pDSEntry))
2965 0 : unloadAndCleanup(_bDisposeConnection);
2966 :
2967 : // collapse the query/table container
2968 0 : for (SvTreeListEntry* pContainers = m_pTreeModel->FirstChild(_pDSEntry); pContainers; pContainers = SvTreeList::NextSibling(pContainers))
2969 : {
2970 0 : SvTreeListEntry* pElements = m_pTreeModel->FirstChild(pContainers);
2971 0 : if ( pElements )
2972 0 : m_pTreeView->getListBox().Collapse(pContainers);
2973 0 : m_pTreeView->getListBox().EnableExpandHandler(pContainers);
2974 : // and delete their children (they are connection-relative)
2975 0 : for (; pElements; )
2976 : {
2977 0 : SvTreeListEntry* pRemove = pElements;
2978 0 : pElements = SvTreeList::NextSibling(pElements);
2979 0 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pRemove->GetUserData());
2980 0 : pRemove->SetUserData(NULL);
2981 0 : delete pData;
2982 0 : m_pTreeModel->Remove(pRemove);
2983 : }
2984 : }
2985 : // collapse the entry itself
2986 0 : m_pTreeView->getListBox().Collapse(_pDSEntry);
2987 :
2988 : // dispose/reset the connection
2989 0 : if ( _bDisposeConnection )
2990 0 : disposeConnection( _pDSEntry );
2991 0 : }
2992 :
2993 0 : void SbaTableQueryBrowser::unloadAndCleanup( bool _bDisposeConnection )
2994 : {
2995 0 : if (!m_pCurrentlyDisplayed)
2996 : // nothing to do
2997 0 : return;
2998 :
2999 0 : SvTreeListEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent(m_pCurrentlyDisplayed);
3000 :
3001 : // de-select the path for the currently displayed table/query
3002 0 : if (m_pCurrentlyDisplayed)
3003 : {
3004 0 : selectPath(m_pCurrentlyDisplayed, false);
3005 : }
3006 0 : m_pCurrentlyDisplayed = NULL;
3007 :
3008 : try
3009 : {
3010 : // get the active connection. We need to dispose it.
3011 0 : Reference< XPropertySet > xRowSetProps(getRowSet(),UNO_QUERY);
3012 0 : Reference< XConnection > xConn;
3013 0 : xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION) >>= xConn;
3014 : #if OSL_DEBUG_LEVEL > 1
3015 : {
3016 : Reference< XComponent > xComp(
3017 : xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),
3018 : css::uno::UNO_QUERY);
3019 : }
3020 : #endif
3021 :
3022 : // unload the form
3023 0 : Reference< XLoadable > xLoadable = getLoadable();
3024 0 : if (xLoadable->isLoaded())
3025 0 : xLoadable->unload();
3026 :
3027 : // clear the grid control
3028 0 : Reference< XNameContainer > xConta(getControlModel(),UNO_QUERY);
3029 0 : clearGridColumns(xConta);
3030 :
3031 : // dispose the connection
3032 0 : if(_bDisposeConnection)
3033 0 : disposeConnection( pDSEntry );
3034 : }
3035 0 : catch(SQLException& e)
3036 : {
3037 0 : showError(SQLExceptionInfo(e));
3038 : }
3039 0 : catch(WrappedTargetException& e)
3040 : {
3041 0 : SQLException aSql;
3042 0 : if(e.TargetException >>= aSql)
3043 0 : showError(SQLExceptionInfo(aSql));
3044 : else
3045 0 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::unloadAndCleanup: something strange happened!");
3046 : }
3047 0 : catch(const Exception&)
3048 : {
3049 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::unloadAndCleanup: could not reset the form");
3050 : }
3051 : }
3052 :
3053 : namespace
3054 : {
3055 0 : Reference< XInterface > lcl_getDataSource( const Reference< XDatabaseContext >& _rxDatabaseContext,
3056 : const OUString& _rDataSourceName, const Reference< XConnection >& _rxConnection )
3057 : {
3058 0 : Reference< XDataSource > xDataSource;
3059 : try
3060 : {
3061 0 : if ( !_rDataSourceName.isEmpty() && _rxDatabaseContext->hasByName( _rDataSourceName ) )
3062 0 : xDataSource.set( _rxDatabaseContext->getByName( _rDataSourceName ), UNO_QUERY_THROW );
3063 :
3064 0 : if ( !xDataSource.is() )
3065 : {
3066 0 : Reference< XChild > xConnAsChild( _rxConnection, UNO_QUERY );
3067 0 : if ( xConnAsChild.is() )
3068 0 : xDataSource.set( xConnAsChild->getParent(), UNO_QUERY_THROW );
3069 : }
3070 : }
3071 0 : catch( const Exception& )
3072 : {
3073 : DBG_UNHANDLED_EXCEPTION();
3074 : }
3075 0 : return xDataSource.get();
3076 : }
3077 : }
3078 :
3079 1 : void SbaTableQueryBrowser::impl_initialize()
3080 : {
3081 1 : SolarMutexGuard aGuard;
3082 : // doin' a lot of VCL stuff here -> lock the SolarMutex
3083 :
3084 : // first initialize the parent
3085 1 : SbaXDataBrowserController::impl_initialize();
3086 :
3087 2 : Reference<XConnection> xForeignConnection;
3088 2 : Reference< XFrame > xFrame;
3089 :
3090 2 : OUString aTableName, aCatalogName, aSchemaName;
3091 :
3092 1 : bool bEscapeProcessing = true;
3093 1 : sal_Int32 nInitialDisplayCommandType = CommandType::COMMAND;
3094 2 : OUString sInitialDataSourceName;
3095 2 : OUString sInitialCommand;
3096 :
3097 1 : const NamedValueCollection& rArguments( getInitParams() );
3098 :
3099 1 : rArguments.get_ensureType( OUString(PROPERTY_DATASOURCENAME), sInitialDataSourceName );
3100 1 : rArguments.get_ensureType( OUString(PROPERTY_COMMAND_TYPE), nInitialDisplayCommandType );
3101 1 : rArguments.get_ensureType( OUString(PROPERTY_COMMAND), sInitialCommand );
3102 1 : rArguments.get_ensureType( OUString(PROPERTY_ACTIVE_CONNECTION), xForeignConnection );
3103 1 : rArguments.get_ensureType( OUString(PROPERTY_UPDATE_CATALOGNAME), aCatalogName );
3104 1 : rArguments.get_ensureType( OUString(PROPERTY_UPDATE_SCHEMANAME), aSchemaName );
3105 1 : rArguments.get_ensureType( OUString(PROPERTY_UPDATE_TABLENAME), aTableName );
3106 1 : rArguments.get_ensureType( OUString(PROPERTY_ESCAPE_PROCESSING), bEscapeProcessing );
3107 1 : rArguments.get_ensureType( "Frame", xFrame );
3108 1 : rArguments.get_ensureType( OUString(PROPERTY_SHOWMENU), m_bShowMenu );
3109 :
3110 : // disable the browser if either of ShowTreeViewButton (compatibility name) or EnableBrowser
3111 : // is present and set to FALSE
3112 4 : bool bDisableBrowser = !rArguments.getOrDefault( "ShowTreeViewButton", sal_True ) // compatibility name
3113 3 : || !rArguments.getOrDefault( OUString(PROPERTY_ENABLE_BROWSER), sal_True );
3114 : OSL_ENSURE( !rArguments.has( "ShowTreeViewButton" ),
3115 : "SbaTableQueryBrowser::impl_initialize: ShowTreeViewButton is superseded by EnableBrowser!" );
3116 1 : m_bEnableBrowser = !bDisableBrowser;
3117 :
3118 : // hide the tree view it is disabled in general, or if the settings tell to hide it initially
3119 1 : bool bHideTreeView = ( !m_bEnableBrowser )
3120 3 : || !rArguments.getOrDefault( "ShowTreeView", sal_True ) // compatibility name
3121 3 : || !rArguments.getOrDefault( OUString(PROPERTY_SHOW_BROWSER), sal_True );
3122 : OSL_ENSURE( !rArguments.has( "ShowTreeView" ),
3123 : "SbaTableQueryBrowser::impl_initialize: ShowTreeView is superseded by ShowBrowser!" );
3124 :
3125 1 : if ( bHideTreeView )
3126 0 : hideExplorer();
3127 : else
3128 1 : showExplorer();
3129 :
3130 1 : if ( m_bPreview )
3131 : {
3132 : try
3133 : {
3134 0 : Sequence< OUString> aProperties(5);
3135 0 : Sequence< Any> aValues(5);
3136 :
3137 0 : OUString* pStringIter = aProperties.getArray();
3138 0 : Any* pValueIter = aValues.getArray();
3139 0 : *pStringIter++ = "AlwaysShowCursor";
3140 0 : *pValueIter++ <<= sal_False;
3141 0 : *pStringIter++ = PROPERTY_BORDER;
3142 0 : *pValueIter++ <<= sal_Int16(0);
3143 :
3144 0 : *pStringIter++ = "HasNavigationBar";
3145 0 : *pValueIter++ <<= sal_False;
3146 0 : *pStringIter++ = "HasRecordMarker";
3147 0 : *pValueIter++ <<= sal_False;
3148 :
3149 0 : *pStringIter++ = "Tabstop";
3150 0 : *pValueIter++ <<= sal_False;
3151 :
3152 0 : Reference< XMultiPropertySet > xFormMultiSet(getFormComponent(), UNO_QUERY);
3153 0 : if ( xFormMultiSet.is() )
3154 0 : xFormMultiSet->setPropertyValues(aProperties, aValues);
3155 : }
3156 0 : catch(const Exception&)
3157 : {
3158 : DBG_UNHANDLED_EXCEPTION();
3159 : }
3160 : }
3161 :
3162 : // are we loaded into a (sub)frame of an embedded document (i.e. a form belonging to a database
3163 : // document)?
3164 1 : bool bSubFrameOfEmbeddedDocument = false;
3165 1 : if ( xFrame.is() )
3166 : {
3167 1 : Reference<XFramesSupplier> xSup = xFrame->getCreator();
3168 2 : Reference<XController> xCont = xSup.is() ? xSup->getController() : Reference<XController>();
3169 :
3170 2 : bSubFrameOfEmbeddedDocument = xCont.is() && ::dbtools::isEmbeddedInDatabase( xCont->getModel(), xForeignConnection );
3171 : }
3172 :
3173 : // if we have a connection at this point, it was either passed from outside, our
3174 : // determined from a outer DB document. In both cases, do not dispose it later on.
3175 2 : SharedConnection xConnection( xForeignConnection, SharedConnection::NoTakeOwnership );
3176 :
3177 : // should we display all registered databases in the left hand side tree?
3178 : // or only *one* special?
3179 1 : bool bLimitedTreeEntries = false;
3180 : // if we're part of a frame which is a secondary frame of a database document, then only
3181 : // display the database for this document, not all registered ones
3182 1 : bLimitedTreeEntries |= bSubFrameOfEmbeddedDocument;
3183 : // if the tree view is not to be displayed at all, then only display the data source
3184 : // which was given as initial selection
3185 1 : bLimitedTreeEntries |= !m_bEnableBrowser;
3186 :
3187 1 : if ( bLimitedTreeEntries )
3188 : {
3189 0 : if ( xConnection.is() )
3190 : {
3191 0 : startConnectionListening( xConnection );
3192 :
3193 : // if no initial name was given, try to obtain one from the data source
3194 0 : if ( sInitialDataSourceName.isEmpty() )
3195 : {
3196 0 : Reference< XChild > xChild( xConnection, UNO_QUERY );
3197 0 : Reference< XPropertySet > xDataSourceProperties;
3198 0 : if ( xChild.is() )
3199 0 : xDataSourceProperties.set(xChild->getParent(), css::uno::UNO_QUERY);
3200 0 : if ( xDataSourceProperties.is() )
3201 : {
3202 : try
3203 : {
3204 0 : OSL_VERIFY( xDataSourceProperties->getPropertyValue( PROPERTY_NAME ) >>= sInitialDataSourceName );
3205 : }
3206 0 : catch( const Exception& )
3207 : {
3208 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::impl_initialize: a connection parent which does not have a 'Name'!??" );
3209 : }
3210 0 : }
3211 : }
3212 : }
3213 :
3214 0 : implAddDatasource( sInitialDataSourceName, xConnection );
3215 0 : m_pTreeView->getListBox().Expand( m_pTreeView->getListBox().First() );
3216 : }
3217 : else
3218 1 : initializeTreeModel();
3219 :
3220 1 : if ( m_bEnableBrowser )
3221 : {
3222 1 : m_aDocScriptSupport = ::boost::optional< bool >( false );
3223 : }
3224 : else
3225 : {
3226 : // we are not used as "browser", but as mere view for a single table/query/command. In particular,
3227 : // there is a specific database document which we belong to.
3228 : Reference< XOfficeDatabaseDocument > xDocument( getDataSourceOrModel(
3229 0 : lcl_getDataSource( m_xDatabaseContext, sInitialDataSourceName, xConnection ) ), UNO_QUERY );
3230 0 : m_aDocScriptSupport = ::boost::optional< bool >( Reference< XEmbeddedScripts >( xDocument, UNO_QUERY ).is() );
3231 : }
3232 :
3233 1 : if ( implSelect( sInitialDataSourceName, sInitialCommand, nInitialDisplayCommandType, bEscapeProcessing, xConnection, true ) )
3234 : {
3235 : try
3236 : {
3237 0 : Reference< XPropertySet > xRowSetProps(getRowSet(), UNO_QUERY);
3238 0 : xRowSetProps->setPropertyValue(PROPERTY_UPDATE_CATALOGNAME,makeAny(aCatalogName));
3239 0 : xRowSetProps->setPropertyValue(PROPERTY_UPDATE_SCHEMANAME,makeAny(aSchemaName));
3240 0 : xRowSetProps->setPropertyValue(PROPERTY_UPDATE_TABLENAME,makeAny(aTableName));
3241 :
3242 : }
3243 0 : catch(const Exception&)
3244 : {
3245 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::impl_initialize: could not set the update related names!");
3246 : }
3247 : }
3248 :
3249 2 : InvalidateAll();
3250 1 : }
3251 :
3252 8 : bool SbaTableQueryBrowser::haveExplorer() const
3253 : {
3254 8 : return m_pTreeView && m_pTreeView->IsVisible();
3255 : }
3256 :
3257 0 : void SbaTableQueryBrowser::hideExplorer()
3258 : {
3259 0 : if (!haveExplorer())
3260 0 : return;
3261 0 : if (!getBrowserView())
3262 0 : return;
3263 :
3264 0 : m_pTreeView->Hide();
3265 0 : m_pSplitter->Hide();
3266 0 : getBrowserView()->Resize();
3267 :
3268 0 : InvalidateFeature(ID_BROWSER_EXPLORER);
3269 : }
3270 :
3271 1 : void SbaTableQueryBrowser::showExplorer()
3272 : {
3273 1 : if (haveExplorer())
3274 0 : return;
3275 :
3276 1 : if (!getBrowserView())
3277 0 : return;
3278 :
3279 1 : m_pTreeView->Show();
3280 1 : m_pSplitter->Show();
3281 1 : getBrowserView()->Resize();
3282 :
3283 1 : InvalidateFeature(ID_BROWSER_EXPLORER);
3284 : }
3285 :
3286 2 : bool SbaTableQueryBrowser::ensureConnection(SvTreeListEntry* _pAnyEntry, SharedConnection& _rConnection)
3287 : {
3288 2 : SvTreeListEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent(_pAnyEntry);
3289 : DBTreeListUserData* pDSData =
3290 : pDSEntry
3291 : ? static_cast<DBTreeListUserData*>(pDSEntry->GetUserData())
3292 2 : : NULL;
3293 :
3294 2 : return ensureConnection( pDSEntry, pDSData, _rConnection );
3295 : }
3296 :
3297 1 : ::std::unique_ptr< ImageProvider > SbaTableQueryBrowser::getImageProviderFor( SvTreeListEntry* _pAnyEntry )
3298 : {
3299 1 : ::std::unique_ptr< ImageProvider > pImageProvider( new ImageProvider );
3300 2 : SharedConnection xConnection;
3301 1 : if ( getExistentConnectionFor( _pAnyEntry, xConnection ) )
3302 1 : pImageProvider.reset( new ImageProvider( xConnection ) );
3303 2 : return pImageProvider;
3304 : }
3305 :
3306 1 : bool SbaTableQueryBrowser::getExistentConnectionFor( SvTreeListEntry* _pAnyEntry, SharedConnection& _rConnection )
3307 : {
3308 1 : SvTreeListEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent( _pAnyEntry );
3309 : DBTreeListUserData* pDSData =
3310 : pDSEntry
3311 : ? static_cast< DBTreeListUserData* >( pDSEntry->GetUserData() )
3312 1 : : NULL;
3313 1 : if ( pDSData )
3314 1 : _rConnection = pDSData->xConnection;
3315 1 : return _rConnection.is();
3316 : }
3317 :
3318 : #if OSL_DEBUG_LEVEL > 0
3319 : bool SbaTableQueryBrowser::impl_isDataSourceEntry( SvTreeListEntry* _pEntry ) const
3320 : {
3321 : return m_pTreeModel->GetRootLevelParent( _pEntry ) == _pEntry;
3322 : }
3323 :
3324 : #endif
3325 :
3326 2 : bool SbaTableQueryBrowser::ensureConnection( SvTreeListEntry* _pDSEntry, void* pDSData, SharedConnection& _rConnection )
3327 : {
3328 : OSL_ENSURE( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::ensureConnection: this entry does not denote a data source!" );
3329 2 : if(_pDSEntry)
3330 : {
3331 2 : DBTreeListUserData* pTreeListData = static_cast<DBTreeListUserData*>(pDSData);
3332 2 : OUString aDSName = GetEntryText(_pDSEntry);
3333 :
3334 2 : if ( pTreeListData )
3335 2 : _rConnection = pTreeListData->xConnection;
3336 :
3337 2 : if ( !_rConnection.is() && pTreeListData )
3338 : {
3339 : // show the "connecting to ..." status
3340 1 : OUString sConnecting(ModuleRes(STR_CONNECTING_DATASOURCE));
3341 1 : sConnecting = sConnecting.replaceFirst("$name$", aDSName);
3342 2 : BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sConnecting);
3343 :
3344 : // build a string showing context information in case of error
3345 2 : OUString sConnectingContext( ModuleRes( STR_COULDNOTCONNECT_DATASOURCE ) );
3346 1 : sConnectingContext = sConnectingContext.replaceFirst("$name$", aDSName);
3347 :
3348 : // connect
3349 : _rConnection.reset(
3350 : connect( getDataSourceAcessor( _pDSEntry ), sConnectingContext, NULL ),
3351 : SharedConnection::TakeOwnership
3352 1 : );
3353 :
3354 : // remember the connection
3355 2 : pTreeListData->xConnection = _rConnection;
3356 2 : }
3357 : }
3358 :
3359 2 : return _rConnection.is();
3360 : }
3361 :
3362 2 : IMPL_LINK( SbaTableQueryBrowser, OnTreeEntryCompare, const SvSortData*, _pSortData )
3363 : {
3364 1 : const SvTreeListEntry* pLHS = static_cast<const SvTreeListEntry*>(_pSortData->pLeft);
3365 1 : const SvTreeListEntry* pRHS = static_cast<const SvTreeListEntry*>(_pSortData->pRight);
3366 : OSL_ENSURE(pLHS && pRHS, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid tree entries!");
3367 : // we want the table entry and the end so we have to do a check
3368 :
3369 1 : if (isContainer(pRHS))
3370 : {
3371 : // don't use getEntryType (directly or indirecly) for the LHS:
3372 : // LHS is currently being inserted, so it is not "completely valid" at the moment
3373 :
3374 1 : const EntryType eRight = getEntryType(pRHS);
3375 1 : if (etTableContainer == eRight)
3376 : // every other container should be placed _before_ the bookmark container
3377 0 : return -1;
3378 :
3379 1 : const OUString sLeft = m_pTreeView->getListBox().GetEntryText(const_cast<SvTreeListEntry*>(pLHS));
3380 :
3381 1 : EntryType eLeft = etTableContainer;
3382 1 : if (OUString(ModuleRes(RID_STR_TABLES_CONTAINER)) == sLeft)
3383 1 : eLeft = etTableContainer;
3384 0 : else if (OUString(ModuleRes(RID_STR_QUERIES_CONTAINER)) == sLeft)
3385 0 : eLeft = etQueryContainer;
3386 :
3387 1 : if ( eLeft == eRight )
3388 0 : return 0;
3389 :
3390 1 : if ( ( eLeft == etTableContainer ) && ( eRight == etQueryContainer ) )
3391 1 : return 1;
3392 :
3393 0 : if ( ( eLeft == etQueryContainer ) && ( eRight == etTableContainer ) )
3394 0 : return -1;
3395 :
3396 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::OnTreeEntryCompare: unexpected case!" );
3397 0 : return 0;
3398 : }
3399 :
3400 0 : const SvLBoxString* pLeftTextItem = static_cast<const SvLBoxString*>(pLHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
3401 0 : const SvLBoxString* pRightTextItem = static_cast<const SvLBoxString*>(pRHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
3402 : OSL_ENSURE(pLeftTextItem && pRightTextItem, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid text items!");
3403 :
3404 0 : OUString sLeftText = pLeftTextItem->GetText();
3405 0 : OUString sRightText = pRightTextItem->GetText();
3406 :
3407 0 : sal_Int32 nCompareResult = 0; // equal by default
3408 :
3409 0 : if (m_xCollator.is())
3410 : {
3411 : try
3412 : {
3413 0 : nCompareResult = m_xCollator->compareString(sLeftText, sRightText);
3414 : }
3415 0 : catch(const Exception&)
3416 : {
3417 : }
3418 : }
3419 : else
3420 : // default behaviour if we do not have a collator -> do the simple string compare
3421 0 : nCompareResult = sLeftText.compareTo(sRightText);
3422 :
3423 0 : return nCompareResult;
3424 : }
3425 :
3426 0 : void SbaTableQueryBrowser::implAdministrate( SvTreeListEntry* _pApplyTo )
3427 : {
3428 : OSL_PRECOND( _pApplyTo, "SbaTableQueryBrowser::implAdministrate: illegal entry!" );
3429 0 : if ( !_pApplyTo )
3430 0 : return;
3431 :
3432 : try
3433 : {
3434 : // get the desktop object
3435 0 : sal_Int32 nFrameSearchFlag = FrameSearchFlag::ALL | FrameSearchFlag::GLOBAL ;
3436 0 : Reference< XDesktop2 > xFrameLoader = Desktop::create( getORB() );
3437 :
3438 : // the initial selection
3439 0 : SvTreeListEntry* pTopLevelSelected = _pApplyTo;
3440 0 : while (pTopLevelSelected && m_pTreeView->getListBox().GetParent(pTopLevelSelected))
3441 0 : pTopLevelSelected = m_pTreeView->getListBox().GetParent(pTopLevelSelected);
3442 0 : OUString sInitialSelection;
3443 0 : if (pTopLevelSelected)
3444 0 : sInitialSelection = getDataSourceAcessor( pTopLevelSelected );
3445 :
3446 0 : Reference< XDataSource > xDataSource( getDataSourceByName( sInitialSelection, getView(), getORB(), NULL ) );
3447 0 : Reference< XModel > xDocumentModel( getDataSourceOrModel( xDataSource ), UNO_QUERY );
3448 :
3449 0 : if ( xDocumentModel.is() )
3450 : {
3451 : Reference< XInteractionHandler2 > xInteractionHandler(
3452 0 : InteractionHandler::createWithParent(getORB(), 0) );
3453 :
3454 0 : ::comphelper::NamedValueCollection aLoadArgs;
3455 0 : aLoadArgs.put( "Model", xDocumentModel );
3456 0 : aLoadArgs.put( "InteractionHandler", xInteractionHandler );
3457 0 : aLoadArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG );
3458 :
3459 0 : Sequence< PropertyValue > aLoadArgPV;
3460 0 : aLoadArgs >>= aLoadArgPV;
3461 :
3462 0 : xFrameLoader->loadComponentFromURL(
3463 0 : xDocumentModel->getURL(),
3464 : OUString("_default"),
3465 : nFrameSearchFlag,
3466 : aLoadArgPV
3467 0 : );
3468 0 : }
3469 : }
3470 0 : catch( const Exception& )
3471 : {
3472 : DBG_UNHANDLED_EXCEPTION();
3473 : }
3474 : }
3475 :
3476 0 : bool SbaTableQueryBrowser::requestQuickHelp( const SvTreeListEntry* _pEntry, OUString& _rText ) const
3477 : {
3478 0 : const DBTreeListUserData* pData = static_cast< const DBTreeListUserData* >( _pEntry->GetUserData() );
3479 0 : if ( ( pData->eType == etDatasource ) && !pData->sAccessor.isEmpty() )
3480 : {
3481 0 : _rText = ::svt::OFileNotation( pData->sAccessor ).get( ::svt::OFileNotation::N_SYSTEM );
3482 0 : return true;
3483 : }
3484 0 : return false;
3485 : }
3486 :
3487 0 : PopupMenu* SbaTableQueryBrowser::getContextMenu( Control& _rControl ) const
3488 : {
3489 : OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl,
3490 : "SbaTableQueryBrowser::getContextMenu: where does this come from?" );
3491 0 : if ( &m_pTreeView->getListBox() != &_rControl )
3492 0 : return NULL;
3493 :
3494 0 : return new PopupMenu( ModuleRes( MENU_BROWSER_DEFAULTCONTEXT ) );
3495 : }
3496 :
3497 0 : IController& SbaTableQueryBrowser::getCommandController()
3498 : {
3499 0 : return *this;
3500 : }
3501 :
3502 0 : ::cppu::OInterfaceContainerHelper* SbaTableQueryBrowser::getContextMenuInterceptors()
3503 : {
3504 0 : return &m_aContextMenuInterceptors;
3505 : }
3506 :
3507 0 : Any SbaTableQueryBrowser::getCurrentSelection( Control& _rControl ) const
3508 : {
3509 : OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl,
3510 : "SbaTableQueryBrowser::getCurrentSelection: where does this come from?" );
3511 :
3512 0 : if ( &m_pTreeView->getListBox() != &_rControl )
3513 0 : return Any();
3514 :
3515 0 : SvTreeListEntry* pSelected = m_pTreeView->getListBox().FirstSelected();
3516 0 : if ( !pSelected )
3517 0 : return Any();
3518 :
3519 : OSL_ENSURE( m_pTreeView->getListBox().NextSelected( pSelected ) == NULL,
3520 : "SbaTableQueryBrowser::getCurrentSelection: single-selection is expected here!" );
3521 :
3522 0 : NamedDatabaseObject aSelectedObject;
3523 0 : DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pSelected->GetUserData() );
3524 0 : aSelectedObject.Type = static_cast< sal_Int32 >( pData->eType );
3525 :
3526 0 : switch ( aSelectedObject.Type )
3527 : {
3528 : case DatabaseObject::QUERY:
3529 : case DatabaseObject::TABLE:
3530 0 : aSelectedObject.Name = m_pTreeView->getListBox().GetEntryText( pSelected );
3531 0 : break;
3532 :
3533 : case DatabaseObjectContainer::DATA_SOURCE:
3534 : case DatabaseObjectContainer::QUERIES:
3535 : case DatabaseObjectContainer::TABLES:
3536 0 : aSelectedObject.Name = getDataSourceAcessor( pSelected );
3537 0 : break;
3538 :
3539 : default:
3540 : SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::getCurrentSelection: invalid (unexpected) object type!" );
3541 0 : break;
3542 : }
3543 :
3544 0 : return makeAny( aSelectedObject );
3545 : }
3546 :
3547 1 : bool SbaTableQueryBrowser::implGetQuerySignature( OUString& _rCommand, bool& _bEscapeProcessing )
3548 : {
3549 1 : _rCommand.clear();
3550 1 : _bEscapeProcessing = false;
3551 :
3552 : try
3553 : {
3554 : // contain the dss (data source signature) of the form
3555 1 : OUString sDataSourceName;
3556 1 : OUString sCommand;
3557 1 : sal_Int32 nCommandType = CommandType::COMMAND;
3558 1 : Reference< XPropertySet > xRowsetProps( getRowSet(), UNO_QUERY );
3559 1 : ODataAccessDescriptor aDesc( xRowsetProps );
3560 1 : sDataSourceName = aDesc.getDataSource();
3561 1 : aDesc[ daCommand ] >>= sCommand;
3562 1 : aDesc[ daCommandType ] >>= nCommandType;
3563 :
3564 : // do we need to do anything?
3565 1 : if ( CommandType::QUERY != nCommandType )
3566 1 : return false;
3567 :
3568 : // get the query object
3569 0 : Reference< XQueryDefinitionsSupplier > xSuppQueries;
3570 0 : Reference< XNameAccess > xQueries;
3571 0 : Reference< XPropertySet > xQuery;
3572 0 : m_xDatabaseContext->getByName( sDataSourceName ) >>= xSuppQueries;
3573 0 : if ( xSuppQueries.is() )
3574 0 : xQueries = xSuppQueries->getQueryDefinitions();
3575 0 : if ( xQueries.is() )
3576 0 : xQueries->getByName( sCommand ) >>= xQuery;
3577 : OSL_ENSURE( xQuery.is(), "SbaTableQueryBrowser::implGetQuerySignature: could not retrieve the query object!" );
3578 :
3579 : // get the two properties we need
3580 0 : if ( xQuery.is() )
3581 : {
3582 0 : xQuery->getPropertyValue( PROPERTY_COMMAND ) >>= _rCommand;
3583 0 : _bEscapeProcessing = ::cppu::any2bool( xQuery->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) );
3584 0 : return true;
3585 0 : }
3586 : }
3587 0 : catch( const Exception& )
3588 : {
3589 : DBG_UNHANDLED_EXCEPTION();
3590 : }
3591 :
3592 0 : return false;
3593 : }
3594 :
3595 2 : void SbaTableQueryBrowser::frameAction(const ::com::sun::star::frame::FrameActionEvent& aEvent) throw( RuntimeException, std::exception )
3596 : {
3597 2 : if (aEvent.Frame == m_xCurrentFrameParent)
3598 : {
3599 1 : if(aEvent.Action == FrameAction_COMPONENT_DETACHING)
3600 1 : implRemoveStatusListeners();
3601 0 : else if (aEvent.Action == FrameAction_COMPONENT_REATTACHED)
3602 0 : connectExternalDispatches();
3603 : }
3604 : else
3605 1 : SbaXDataBrowserController::frameAction(aEvent);
3606 :
3607 2 : }
3608 :
3609 2 : void SbaTableQueryBrowser::clearGridColumns(const Reference< XNameContainer >& _xColContainer)
3610 : {
3611 : // first we have to clear the grid
3612 2 : Sequence< OUString > aNames = _xColContainer->getElementNames();
3613 2 : const OUString* pIter = aNames.getConstArray();
3614 2 : const OUString* pEnd = pIter + aNames.getLength();
3615 4 : Reference< XInterface > xColumn;
3616 2 : for (; pIter != pEnd;++pIter)
3617 : {
3618 0 : _xColContainer->getByName(*pIter) >>= xColumn;
3619 0 : _xColContainer->removeByName(*pIter);
3620 0 : ::comphelper::disposeComponent(xColumn);
3621 2 : }
3622 2 : }
3623 :
3624 1 : void SbaTableQueryBrowser::loadMenu(const Reference< XFrame >& _xFrame)
3625 : {
3626 1 : if ( m_bShowMenu )
3627 : {
3628 0 : OGenericUnoController::loadMenu(_xFrame);
3629 : }
3630 1 : else if ( !m_bPreview )
3631 : {
3632 1 : Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager = getLayoutManager(_xFrame);
3633 :
3634 1 : if ( xLayoutManager.is() )
3635 : {
3636 1 : xLayoutManager->lock();
3637 1 : xLayoutManager->createElement( OUString( "private:resource/toolbar/toolbar" ));
3638 1 : xLayoutManager->unlock();
3639 1 : xLayoutManager->doLayout();
3640 : }
3641 1 : onLoadedMenu( xLayoutManager );
3642 : }
3643 1 : }
3644 :
3645 2 : OUString SbaTableQueryBrowser::getPrivateTitle() const
3646 : {
3647 2 : OUString sTitle;
3648 2 : if ( m_pCurrentlyDisplayed )
3649 : {
3650 1 : SvTreeListEntry* pContainer = m_pTreeModel->GetParent(m_pCurrentlyDisplayed);
3651 : // get the entry for the datasource
3652 1 : SvTreeListEntry* pConnection = implGetConnectionEntry(pContainer);
3653 1 : OUString sName = m_pTreeView->getListBox().GetEntryText(m_pCurrentlyDisplayed);
3654 1 : sTitle = GetEntryText( pConnection );
3655 2 : INetURLObject aURL(sTitle);
3656 1 : if ( aURL.GetProtocol() != INetProtocol::NotValid )
3657 0 : sTitle = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET);
3658 1 : if ( !sName.isEmpty() )
3659 : {
3660 1 : sName += " - ";
3661 1 : sName += sTitle;
3662 1 : sTitle = sName;
3663 1 : }
3664 : }
3665 :
3666 2 : return sTitle;
3667 : }
3668 :
3669 0 : bool SbaTableQueryBrowser::preReloadForm()
3670 : {
3671 0 : bool bIni = false;
3672 0 : if ( !m_pCurrentlyDisplayed )
3673 : {
3674 : // switch the grid to design mode while loading
3675 0 : getBrowserView()->getGridControl()->setDesignMode(sal_True);
3676 : // we had an invalid statement so we need to connect the column models
3677 0 : Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
3678 0 : svx::ODataAccessDescriptor aDesc(xRowSetProps);
3679 : // extract the props
3680 0 : OUString sDataSource;
3681 0 : OUString sCommand;
3682 0 : sal_Int32 nCommandType = CommandType::COMMAND;
3683 0 : bool bEscapeProcessing = true;
3684 0 : extractDescriptorProps(aDesc, sDataSource, sCommand, nCommandType, bEscapeProcessing);
3685 0 : if ( !sDataSource.isEmpty() && !sCommand.isEmpty() && (-1 != nCommandType) )
3686 : {
3687 0 : SvTreeListEntry* pDataSource = NULL;
3688 0 : SvTreeListEntry* pCommandType = NULL;
3689 0 : m_pCurrentlyDisplayed = getObjectEntry( sDataSource, sCommand, nCommandType, &pDataSource, &pCommandType, true, SharedConnection() );
3690 0 : bIni = true;
3691 0 : }
3692 : }
3693 0 : return bIni;
3694 : }
3695 :
3696 0 : void SbaTableQueryBrowser::postReloadForm()
3697 : {
3698 0 : InitializeGridModel(getFormComponent());
3699 0 : LoadFinished(true);
3700 0 : }
3701 :
3702 0 : Reference< XEmbeddedScripts > SAL_CALL SbaTableQueryBrowser::getScriptContainer() throw (RuntimeException, std::exception)
3703 : {
3704 : // update our database document
3705 0 : Reference< XModel > xDocument;
3706 : try
3707 : {
3708 0 : Reference< XPropertySet > xCursorProps( getRowSet(), UNO_QUERY_THROW );
3709 0 : Reference< XConnection > xConnection( xCursorProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ), UNO_QUERY );
3710 0 : if ( xConnection.is() )
3711 : {
3712 0 : Reference< XChild > xChild( xConnection, UNO_QUERY_THROW );
3713 0 : Reference< XDocumentDataSource > xDataSource( xChild->getParent(), UNO_QUERY_THROW );
3714 0 : xDocument.set( xDataSource->getDatabaseDocument(), UNO_QUERY_THROW );
3715 0 : }
3716 : }
3717 0 : catch( const Exception& )
3718 : {
3719 : DBG_UNHANDLED_EXCEPTION();
3720 : }
3721 0 : Reference< XEmbeddedScripts > xScripts( xDocument, UNO_QUERY );
3722 : OSL_ENSURE( xScripts.is() || !xDocument.is(),
3723 : "SbaTableQueryBrowser::getScriptContainer: invalid database document!" );
3724 0 : return xScripts;
3725 : }
3726 :
3727 0 : void SAL_CALL SbaTableQueryBrowser::registerContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException, std::exception)
3728 : {
3729 0 : if ( _Interceptor.is() )
3730 0 : m_aContextMenuInterceptors.addInterface( _Interceptor );
3731 0 : }
3732 :
3733 0 : void SAL_CALL SbaTableQueryBrowser::releaseContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException, std::exception)
3734 : {
3735 0 : if ( _Interceptor.is() )
3736 0 : m_aContextMenuInterceptors.removeInterface( _Interceptor );
3737 0 : }
3738 :
3739 0 : void SAL_CALL SbaTableQueryBrowser::registeredDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException, std::exception)
3740 : {
3741 0 : SolarMutexGuard aGuard;
3742 0 : implAddDatasource( _Event.Name, SharedConnection() );
3743 0 : }
3744 :
3745 0 : void SbaTableQueryBrowser::impl_cleanupDataSourceEntry( const OUString& _rDataSourceName )
3746 : {
3747 : // get the top-level representing the removed data source
3748 0 : SvTreeListEntry* pDataSourceEntry = m_pTreeView->getListBox().FirstChild( NULL );
3749 0 : while ( pDataSourceEntry )
3750 : {
3751 0 : if ( m_pTreeView->getListBox().GetEntryText( pDataSourceEntry ) == _rDataSourceName )
3752 0 : break;
3753 :
3754 0 : pDataSourceEntry = SvTreeList::NextSibling( pDataSourceEntry );
3755 : }
3756 :
3757 : OSL_ENSURE( pDataSourceEntry, "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: do not know this data source!" );
3758 0 : if ( !pDataSourceEntry )
3759 0 : return;
3760 :
3761 0 : if ( isSelected( pDataSourceEntry ) )
3762 : { // a table or query belonging to the deleted data source is currently being displayed.
3763 : OSL_ENSURE( m_pTreeView->getListBox().GetRootLevelParent( m_pCurrentlyDisplayed ) == pDataSourceEntry,
3764 : "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (1)!" );
3765 0 : unloadAndCleanup( true );
3766 : }
3767 : else
3768 : OSL_ENSURE(
3769 : ( NULL == m_pCurrentlyDisplayed )
3770 : || ( m_pTreeView->getListBox().GetRootLevelParent( m_pCurrentlyDisplayed ) != pDataSourceEntry ),
3771 : "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (2)!");
3772 :
3773 : // delete any user data of the child entries of the to-be-removed entry
3774 : std::pair<SvTreeListEntries::iterator, SvTreeListEntries::iterator> aIters =
3775 0 : m_pTreeModel->GetChildIterators(pDataSourceEntry);
3776 :
3777 0 : SvTreeListEntries::iterator it = aIters.first, itEnd = aIters.second;
3778 :
3779 0 : for (; it != itEnd; ++it)
3780 : {
3781 0 : SvTreeListEntry* pEntry = &(*it);
3782 0 : const DBTreeListUserData* pData = static_cast<const DBTreeListUserData*>(pEntry->GetUserData());
3783 0 : pEntry->SetUserData(NULL);
3784 0 : delete pData;
3785 : }
3786 :
3787 : // remove the entry
3788 0 : DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pDataSourceEntry->GetUserData() );
3789 0 : pDataSourceEntry->SetUserData( NULL );
3790 0 : delete pData;
3791 0 : m_pTreeModel->Remove( pDataSourceEntry );
3792 : }
3793 :
3794 0 : void SAL_CALL SbaTableQueryBrowser::revokedDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException, std::exception)
3795 : {
3796 0 : SolarMutexGuard aGuard;
3797 :
3798 0 : impl_cleanupDataSourceEntry( _Event.Name );
3799 :
3800 : // maybe the object which is part of the document data source has been removed
3801 0 : checkDocumentDataSource();
3802 0 : }
3803 :
3804 0 : void SAL_CALL SbaTableQueryBrowser::changedDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException, std::exception)
3805 : {
3806 0 : SolarMutexGuard aGuard;
3807 :
3808 : // in case the data source was expanded, and connected, we need to clean it up
3809 : // for simplicity, just do as if the data source were completely removed and re-added
3810 0 : impl_cleanupDataSourceEntry( _Event.Name );
3811 0 : implAddDatasource( _Event.Name, SharedConnection() );
3812 0 : }
3813 :
3814 36 : } // namespace dbaui
3815 :
3816 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|