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