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