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