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