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_extensions.hxx" 30 #include <vcl/waitobj.hxx> 31 #include <cppuhelper/interfacecontainer.hxx> 32 #include <com/sun/star/util/URL.hpp> 33 #include <osl/mutex.hxx> 34 #include <vcl/msgbox.hxx> 35 #include <tools/debug.hxx> 36 #include <vcl/stdtext.hxx> 37 #include <comphelper/types.hxx> 38 #include <comphelper/sequence.hxx> 39 #include "framectr.hxx" 40 #include "datman.hxx" 41 #include "bibresid.hxx" 42 #include "bib.hrc" 43 #include <toolkit/helper/vclunohelper.hxx> 44 #include "bibconfig.hxx" 45 #include <cppuhelper/implbase1.hxx> // helper for implementations 46 #include <vcl/svapp.hxx> 47 #include "bibliography.hrc" 48 #include <comphelper/processfactory.hxx> 49 #include <com/sun/star/form/XConfirmDeleteListener.hpp> 50 #include <com/sun/star/form/runtime/XFormController.hpp> 51 #include <com/sun/star/beans/PropertyState.hpp> 52 #include <com/sun/star/beans/PropertyValue.hpp> 53 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> 54 #include <com/sun/star/sdbcx/Privilege.hpp> 55 #include <com/sun/star/sdbc/XResultSetUpdate.hpp> 56 #include <com/sun/star/sdb/RowChangeAction.hpp> 57 #include <com/sun/star/frame/CommandGroup.hpp> 58 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> 59 #include <sot/exchange.hxx> 60 #include <sot/formats.hxx> 61 #include <vcl/edit.hxx> 62 #include <vos/mutex.hxx> 63 64 #include <hash_map> 65 66 using namespace osl; 67 using namespace cppu; 68 using namespace rtl; 69 using namespace com::sun::star::sdbc; 70 using namespace com::sun::star::frame; 71 using namespace com::sun::star::uno; 72 using namespace com::sun::star; 73 74 #define C2U(cChar) OUString::createFromAscii(cChar) 75 76 struct DispatchInfo 77 { 78 const char* pCommand; 79 sal_Int16 nGroupId; 80 sal_Bool bActiveConnection; 81 }; 82 83 struct CacheDispatchInfo 84 { 85 sal_Int16 nGroupId; 86 sal_Bool bActiveConnection; 87 }; 88 89 // Attention: commands must be sorted by command groups. Implementation is dependent 90 // on this!! 91 static DispatchInfo SupportedCommandsArray[] = 92 { 93 { ".uno:Undo" , frame::CommandGroup::EDIT , sal_False }, 94 { ".uno:Cut" , frame::CommandGroup::EDIT , sal_False }, 95 { ".uno:Copy" , frame::CommandGroup::EDIT , sal_False }, 96 { ".uno:Paste" , frame::CommandGroup::EDIT , sal_False }, 97 { ".uno:SelectAll" , frame::CommandGroup::EDIT , sal_False }, 98 { ".uno:CloseDoc" , frame::CommandGroup::DOCUMENT , sal_False }, 99 { ".uno:StatusBarVisible" , frame::CommandGroup::VIEW , sal_False }, 100 { ".uno:AvailableToolbars" , frame::CommandGroup::VIEW , sal_False }, 101 { ".uno:Bib/standardFilter" , frame::CommandGroup::DATA , sal_True }, 102 { ".uno:Bib/DeleteRecord" , frame::CommandGroup::DATA , sal_True }, 103 { ".uno:Bib/InsertRecord" , frame::CommandGroup::DATA , sal_True }, 104 { ".uno:Bib/query" , frame::CommandGroup::DATA , sal_True }, 105 { ".uno:Bib/autoFilter" , frame::CommandGroup::DATA , sal_True }, 106 { ".uno:Bib/source" , frame::CommandGroup::DATA , sal_True }, 107 { ".uno:Bib/removeFilter" , frame::CommandGroup::DATA , sal_True }, 108 { ".uno:Bib/sdbsource" , frame::CommandGroup::DATA , sal_True }, 109 { ".uno:Bib/Mapping" , frame::CommandGroup::DATA , sal_True }, 110 { 0 , 0 , sal_False } 111 }; 112 113 typedef ::std::hash_map< ::rtl::OUString, CacheDispatchInfo, rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > CmdToInfoCache; 114 115 SV_IMPL_PTRARR( BibStatusDispatchArr, BibStatusDispatchPtr ); 116 117 const CmdToInfoCache& GetCommandToInfoCache() 118 { 119 static sal_Bool bCacheInitialized = sal_False; 120 static CmdToInfoCache aCmdToInfoCache; 121 122 if ( !bCacheInitialized ) 123 { 124 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 125 if ( !bCacheInitialized ) 126 { 127 sal_Int32 i( 0 ); 128 while ( SupportedCommandsArray[i].pCommand != 0 ) 129 { 130 rtl::OUString aCommand( rtl::OUString::createFromAscii( SupportedCommandsArray[i].pCommand )); 131 132 CacheDispatchInfo aDispatchInfo; 133 aDispatchInfo.nGroupId = SupportedCommandsArray[i].nGroupId; 134 aDispatchInfo.bActiveConnection = SupportedCommandsArray[i].bActiveConnection; 135 aCmdToInfoCache.insert( CmdToInfoCache::value_type( aCommand, aDispatchInfo )); 136 ++i; 137 } 138 bCacheInitialized = sal_True; 139 } 140 } 141 142 return aCmdToInfoCache; 143 } 144 145 146 class BibFrameCtrl_Impl : public cppu::WeakImplHelper1 < XFrameActionListener > 147 { 148 public: 149 Mutex aMutex; 150 OMultiTypeInterfaceContainerHelper aLC; 151 152 BibFrameController_Impl* pController; 153 154 BibFrameCtrl_Impl() 155 : aLC( aMutex ) 156 , pController(0) 157 {} 158 159 ~BibFrameCtrl_Impl(); 160 161 virtual void SAL_CALL frameAction(const FrameActionEvent& aEvent) throw( RuntimeException ); 162 virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); 163 }; 164 165 166 BibFrameCtrl_Impl::~BibFrameCtrl_Impl() 167 { 168 } 169 170 void BibFrameCtrl_Impl::frameAction(const FrameActionEvent& aEvent) throw( uno::RuntimeException ) 171 { 172 if ( pController && aEvent.Frame == pController->getFrame()) 173 { 174 if(aEvent.Action == FrameAction_FRAME_ACTIVATED) 175 { 176 pController->activate(); 177 } 178 else if(aEvent.Action == FrameAction_FRAME_DEACTIVATING) 179 { 180 pController->deactivate(); 181 } 182 } 183 } 184 185 void BibFrameCtrl_Impl::disposing( const lang::EventObject& /*Source*/ ) 186 throw (::com::sun::star::uno::RuntimeException) 187 { 188 vos::OGuard aGuard(Application::GetSolarMutex()); 189 if ( pController ) 190 pController->getFrame()->removeFrameActionListener( this ); 191 } 192 193 BibFrameController_Impl::BibFrameController_Impl( const uno::Reference< awt::XWindow > & xComponent, 194 BibDataManager* pDataManager) 195 :xWindow( xComponent ) 196 ,m_xDatMan( pDataManager ) 197 ,pDatMan( pDataManager ) 198 ,pBibMod(NULL) 199 { 200 Window* pParent = VCLUnoHelper::GetWindow( xWindow ); 201 pParent->SetUniqueId(UID_BIB_FRAME_WINDOW); 202 bDisposing=sal_False; 203 bHierarchical=sal_True; 204 pImp = new BibFrameCtrl_Impl; 205 pImp->pController = this; 206 pImp->acquire(); 207 } 208 209 BibFrameController_Impl::~BibFrameController_Impl() 210 { 211 pImp->pController = NULL; 212 pImp->release(); 213 delete pDatMan; 214 if(pBibMod) 215 CloseBibModul(pBibMod); 216 } 217 218 ::rtl::OUString SAL_CALL BibFrameController_Impl::getImplementationName() throw (::com::sun::star::uno::RuntimeException) 219 { 220 return ::rtl::OUString::createFromAscii("com.sun.star.comp.extensions.Bibliography"); 221 } 222 223 sal_Bool SAL_CALL BibFrameController_Impl::supportsService( const ::rtl::OUString& sServiceName ) throw (::com::sun::star::uno::RuntimeException) 224 { 225 return ( 226 sServiceName.equalsAscii("com.sun.star.frame.Bibliography") || 227 sServiceName.equalsAscii("com.sun.star.frame.Controller") 228 ); 229 } 230 231 ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL BibFrameController_Impl::getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException) 232 { 233 // return only top level services ... 234 // base services are included there and should be asked by uno-rtti. 235 ::com::sun::star::uno::Sequence< ::rtl::OUString > lNames(1); 236 lNames[0] = ::rtl::OUString::createFromAscii("com.sun.star.frame.Bibliography"); 237 return lNames; 238 } 239 240 void BibFrameController_Impl::attachFrame( const uno::Reference< XFrame > & xArg ) throw (::com::sun::star::uno::RuntimeException) 241 { 242 xFrame = xArg; 243 xFrame->addFrameActionListener( pImp ); 244 } 245 246 sal_Bool BibFrameController_Impl::attachModel( const uno::Reference< XModel > & /*xModel*/ ) throw (::com::sun::star::uno::RuntimeException) 247 { 248 return sal_False; 249 } 250 251 sal_Bool BibFrameController_Impl::suspend( sal_Bool bSuspend ) throw (::com::sun::star::uno::RuntimeException) 252 { 253 if ( bSuspend ) 254 getFrame()->removeFrameActionListener( pImp ); 255 else 256 getFrame()->addFrameActionListener( pImp ); 257 return sal_True; 258 } 259 260 uno::Any BibFrameController_Impl::getViewData() throw (::com::sun::star::uno::RuntimeException) 261 { 262 return uno::Any(); 263 } 264 265 void BibFrameController_Impl::restoreViewData( const uno::Any& /*Value*/ ) throw (::com::sun::star::uno::RuntimeException) 266 { 267 } 268 269 uno::Reference< XFrame > BibFrameController_Impl::getFrame() throw (::com::sun::star::uno::RuntimeException) 270 { 271 return xFrame; 272 } 273 274 uno::Reference< XModel > BibFrameController_Impl::getModel() throw (::com::sun::star::uno::RuntimeException) 275 { 276 return uno::Reference< XModel > (); 277 } 278 279 void BibFrameController_Impl::dispose() throw (::com::sun::star::uno::RuntimeException) 280 { 281 bDisposing = sal_True; 282 lang::EventObject aObject; 283 aObject.Source = (XController*)this; 284 pImp->aLC.disposeAndClear(aObject); 285 m_xDatMan = 0; 286 pDatMan = 0; 287 aStatusListeners.DeleteAndDestroy( 0, aStatusListeners.Count() ); 288 } 289 290 void BibFrameController_Impl::addEventListener( const uno::Reference< lang::XEventListener > & aListener ) throw (::com::sun::star::uno::RuntimeException) 291 { 292 pImp->aLC.addInterface( ::getCppuType((const Reference< lang::XEventListener >*)0), aListener ); 293 } 294 295 void BibFrameController_Impl::removeEventListener( const uno::Reference< lang::XEventListener > & aListener ) throw (::com::sun::star::uno::RuntimeException) 296 { 297 pImp->aLC.removeInterface( ::getCppuType((const Reference< lang::XEventListener >*)0), aListener ); 298 } 299 300 uno::Reference< frame::XDispatch > BibFrameController_Impl::queryDispatch( const util::URL& aURL, const rtl::OUString& /*aTarget*/, sal_Int32 /*nSearchFlags*/ ) throw (::com::sun::star::uno::RuntimeException) 301 { 302 if ( !bDisposing ) 303 { 304 const CmdToInfoCache& rCmdCache = GetCommandToInfoCache(); 305 CmdToInfoCache::const_iterator pIter = rCmdCache.find( aURL.Complete ); 306 if ( pIter != rCmdCache.end() ) 307 { 308 if (( pDatMan->HasActiveConnection() ) || 309 ( !pIter->second.bActiveConnection )) 310 return (frame::XDispatch*) this; 311 } 312 } 313 314 return uno::Reference< frame::XDispatch > (); 315 } 316 317 uno::Sequence<uno::Reference< XDispatch > > BibFrameController_Impl::queryDispatches( const uno::Sequence<DispatchDescriptor>& aDescripts ) throw (::com::sun::star::uno::RuntimeException) 318 { 319 uno::Sequence< uno::Reference< XDispatch > > aDispatches( aDescripts.getLength() ); 320 for ( sal_Int32 i=0; i<aDescripts.getLength(); ++i ) 321 aDispatches[i] = queryDispatch( aDescripts[i].FeatureURL, aDescripts[i].FrameName, aDescripts[i].SearchFlags ); 322 return aDispatches; 323 } 324 325 uno::Sequence< ::sal_Int16 > SAL_CALL BibFrameController_Impl::getSupportedCommandGroups() 326 throw (::com::sun::star::uno::RuntimeException) 327 { 328 uno::Sequence< ::sal_Int16 > aDispatchInfo( 4 ); 329 330 aDispatchInfo[0] = frame::CommandGroup::EDIT; 331 aDispatchInfo[1] = frame::CommandGroup::DOCUMENT; 332 aDispatchInfo[2] = frame::CommandGroup::DATA; 333 aDispatchInfo[3] = frame::CommandGroup::VIEW; 334 335 return aDispatchInfo; 336 } 337 338 uno::Sequence< frame::DispatchInformation > SAL_CALL BibFrameController_Impl::getConfigurableDispatchInformation( ::sal_Int16 nCommandGroup ) 339 throw (::com::sun::star::uno::RuntimeException) 340 { 341 const CmdToInfoCache& rCmdCache = GetCommandToInfoCache(); 342 343 sal_Bool bGroupFound( sal_False ); 344 frame::DispatchInformation aDispatchInfo; 345 std::list< frame::DispatchInformation > aDispatchInfoList; 346 347 if (( nCommandGroup == frame::CommandGroup::EDIT ) || 348 ( nCommandGroup == frame::CommandGroup::DOCUMENT ) || 349 ( nCommandGroup == frame::CommandGroup::DATA ) || 350 ( nCommandGroup == frame::CommandGroup::VIEW )) 351 { 352 CmdToInfoCache::const_iterator pIter = rCmdCache.begin(); 353 while ( pIter != rCmdCache.end() ) 354 { 355 if ( pIter->second.nGroupId == nCommandGroup ) 356 { 357 bGroupFound = sal_True; 358 aDispatchInfo.Command = pIter->first; 359 aDispatchInfo.GroupId = pIter->second.nGroupId; 360 aDispatchInfoList.push_back( aDispatchInfo ); 361 } 362 else if ( bGroupFound ) 363 break; 364 365 ++pIter; 366 } 367 } 368 369 ::com::sun::star::uno::Sequence< ::com::sun::star::frame::DispatchInformation > aSeq = 370 comphelper::containerToSequence< ::com::sun::star::frame::DispatchInformation, std::list< ::com::sun::star::frame::DispatchInformation > >( aDispatchInfoList ); 371 372 return aSeq; 373 } 374 375 sal_Bool canInsertRecords(const Reference< beans::XPropertySet>& _rxCursorSet) 376 { 377 sal_Int32 nPriv = 0; 378 _rxCursorSet->getPropertyValue(C2U("Privileges")) >>= nPriv; 379 return ((_rxCursorSet.is() && (nPriv & sdbcx::Privilege::INSERT) != 0)); 380 } 381 /* -----------------------------08.05.2002 08:58------------------------------ 382 383 ---------------------------------------------------------------------------*/ 384 sal_Bool BibFrameController_Impl::SaveModified(const Reference< form::runtime::XFormController>& xController) 385 { 386 if (!xController.is()) 387 return sal_False; 388 sal_Bool bInserted = sal_False; 389 390 Reference< XResultSetUpdate> _xCursor = Reference< XResultSetUpdate>(xController->getModel(), UNO_QUERY); 391 392 if (!_xCursor.is()) 393 return sal_False; 394 395 Reference< beans::XPropertySet> _xSet = Reference< beans::XPropertySet>(_xCursor, UNO_QUERY); 396 if (!_xSet.is()) 397 return sal_False; 398 399 // mu� gespeichert werden ? 400 sal_Bool bIsNew = ::comphelper::getBOOL(_xSet->getPropertyValue(C2U("IsNew"))); 401 sal_Bool bIsModified = ::comphelper::getBOOL(_xSet->getPropertyValue(C2U("IsModified"))); 402 sal_Bool bResult = !bIsModified; 403 if (bIsModified) 404 { 405 try 406 { 407 if (bIsNew) 408 _xCursor->insertRow(); 409 else 410 _xCursor->updateRow(); 411 bResult = sal_True; 412 } 413 catch(Exception&) 414 { 415 DBG_ERROR("SaveModified: Exception occured!"); 416 } 417 418 bInserted = bIsNew && bResult; 419 } 420 return bResult; 421 } 422 423 Window* lcl_GetFocusChild( Window* pParent ) 424 { 425 sal_uInt16 nChildren = pParent->GetChildCount(); 426 for( sal_uInt16 nChild = 0; nChild < nChildren; ++nChild) 427 { 428 Window* pChild = pParent->GetChild( nChild ); 429 if(pChild->HasFocus()) 430 return pChild; 431 Window* pSubChild = lcl_GetFocusChild( pChild ); 432 if(pSubChild) 433 return pSubChild; 434 } 435 return 0; 436 } 437 438 //class XDispatch 439 void BibFrameController_Impl::dispatch(const util::URL& _rURL, const uno::Sequence< beans::PropertyValue >& aArgs) throw (::com::sun::star::uno::RuntimeException) 440 { 441 if ( !bDisposing ) 442 { 443 vos::OGuard aGuard(Application::GetSolarMutex()); 444 Window* pParent = VCLUnoHelper::GetWindow( xWindow ); 445 WaitObject aWaitObject( pParent ); 446 447 String aCommand( _rURL.Path); 448 if(aCommand.EqualsAscii("Bib/Mapping")) 449 { 450 pDatMan->CreateMappingDialog(pParent); 451 } 452 else if(aCommand.EqualsAscii("Bib/source")) 453 { 454 ChangeDataSource(aArgs); 455 } 456 else if(aCommand.EqualsAscii("Bib/sdbsource")) 457 { 458 rtl::OUString aURL = pDatMan->CreateDBChangeDialog(pParent); 459 if(aURL.getLength()) 460 { 461 try 462 { 463 uno::Sequence< beans::PropertyValue > aNewDataSource(2); 464 beans::PropertyValue* pProps = aNewDataSource.getArray(); 465 pProps[0].Value <<= rtl::OUString(); 466 pProps[1].Value <<= aURL; 467 ChangeDataSource(aNewDataSource); 468 } 469 catch(const Exception&) 470 { 471 DBG_ERROR("Exception catched while changing the data source"); 472 } 473 } 474 } 475 else if(aCommand.EqualsAscii("Bib/autoFilter")) 476 { 477 sal_uInt16 nCount = aStatusListeners.Count(); 478 for ( sal_uInt16 n=0; n<nCount; n++ ) 479 { 480 BibStatusDispatch *pObj = aStatusListeners[n]; 481 if ( pObj->aURL.Path == C2U("Bib/removeFilter") ) 482 { 483 FeatureStateEvent aEvent; 484 aEvent.FeatureURL = pObj->aURL; 485 aEvent.IsEnabled = sal_True; 486 aEvent.Requery = sal_False; 487 aEvent.Source = (XDispatch *) this; 488 pObj->xListener->statusChanged( aEvent ); 489 //break; because there are more than one 490 } 491 } 492 493 const beans::PropertyValue* pPropertyValue = aArgs.getConstArray(); 494 uno::Any aValue=pPropertyValue[0].Value; 495 rtl::OUString aQuery; 496 aValue >>= aQuery; 497 498 aValue=pPropertyValue[1].Value; 499 rtl::OUString aQueryField; 500 aValue >>= aQueryField; 501 BibConfig* pConfig = BibModul::GetConfig(); 502 pConfig->setQueryField(aQueryField); 503 pDatMan->startQueryWith(aQuery); 504 } 505 else if(aCommand.EqualsAscii("Bib/standardFilter")) 506 { 507 try 508 { 509 uno::Reference< lang::XMultiServiceFactory > xORB = ::comphelper::getProcessServiceFactory(); 510 511 // build the arguments for the filter dialog to be created 512 Sequence< Any > aDialogCreationArgs( 3 ); 513 Any* pDialogCreationArgs = aDialogCreationArgs.getArray(); 514 // the query composer 515 *pDialogCreationArgs++ <<= beans::PropertyValue( ::rtl::OUString::createFromAscii( "QueryComposer" ), 516 -1, 517 makeAny( pDatMan->getParser() ), 518 beans::PropertyState_DIRECT_VALUE 519 ); 520 521 // the rowset 522 *pDialogCreationArgs++ <<= beans::PropertyValue( ::rtl::OUString::createFromAscii( "RowSet" ), 523 -1, 524 makeAny( pDatMan->getForm() ), 525 beans::PropertyState_DIRECT_VALUE 526 ); 527 // the parent window for the dialog 528 *pDialogCreationArgs++ <<= beans::PropertyValue( ::rtl::OUString::createFromAscii( "ParentWindow" ), 529 -1, 530 makeAny( xWindow ), 531 beans::PropertyState_DIRECT_VALUE 532 ); 533 534 // create the dialog object 535 const ::rtl::OUString sDialogServiceName = ::rtl::OUString::createFromAscii( "com.sun.star.sdb.FilterDialog" ); 536 uno::Reference< uno::XInterface > xDialog = xORB->createInstanceWithArguments( 537 sDialogServiceName, 538 aDialogCreationArgs 539 ); 540 if ( !xDialog.is() ) 541 { 542 ShowServiceNotAvailableError( VCLUnoHelper::GetWindow( xWindow ), sDialogServiceName, sal_True ); 543 } 544 else 545 { 546 // execute it 547 uno::Reference< ui::dialogs::XExecutableDialog > xExec( xDialog, UNO_QUERY ); 548 DBG_ASSERT( xExec.is(), "BibFrameController_Impl::dispatch: missing an interface on the dialog!" ); 549 if ( xExec.is() ) 550 if ( xExec->execute( ) ) 551 { 552 // the dialog has been executed successfully, and the filter on the query composer 553 // has been changed 554 ::rtl::OUString sNewFilter = pDatMan->getParser()->getFilter(); 555 pDatMan->setFilter( sNewFilter ); 556 } 557 } 558 } 559 catch( const uno::Exception& ) 560 { 561 DBG_ERROR( "BibFrameController_Impl::dispatch: caught an exception!" ); 562 } 563 564 sal_uInt16 nCount = aStatusListeners.Count(); 565 for ( sal_uInt16 n=0; n<nCount; n++ ) 566 { 567 BibStatusDispatch *pObj = aStatusListeners[n]; 568 if ( pObj->aURL.Path == C2U("Bib/removeFilter") && pDatMan->getParser().is()) 569 { 570 FeatureStateEvent aEvent; 571 aEvent.FeatureURL = pObj->aURL; 572 aEvent.IsEnabled = 0 != pDatMan->getParser()->getFilter().getLength(); 573 aEvent.Requery = sal_False; 574 aEvent.Source = (XDispatch *) this; 575 pObj->xListener->statusChanged( aEvent ); 576 } 577 } 578 } 579 else if(aCommand.EqualsAscii("Bib/removeFilter")) 580 { 581 RemoveFilter(); 582 } 583 else if(_rURL.Complete.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("slot:5503")) || 584 aCommand.EqualsAscii("CloseDoc")) 585 { 586 Application::PostUserEvent( STATIC_LINK( this, BibFrameController_Impl, 587 DisposeHdl ), 0 ); 588 589 } 590 else if(aCommand.EqualsAscii("Bib/InsertRecord")) 591 { 592 Reference<form::runtime::XFormController > xFormCtrl = pDatMan->GetFormController(); 593 if(SaveModified(xFormCtrl)) 594 { 595 try 596 { 597 Reference< sdbc::XResultSet > xCursor( pDatMan->getForm(), UNO_QUERY ); 598 xCursor->last(); 599 600 Reference< XResultSetUpdate > xUpdateCursor( pDatMan->getForm(), UNO_QUERY ); 601 xUpdateCursor->moveToInsertRow(); 602 } 603 catch(Exception&) 604 { 605 DBG_ERROR("Exception in last() or moveToInsertRow()"); 606 } 607 } 608 } 609 else if(aCommand.EqualsAscii("Bib/DeleteRecord")) 610 { 611 Reference< ::com::sun::star::sdbc::XResultSet > xCursor(pDatMan->getForm(), UNO_QUERY); 612 Reference< XResultSetUpdate > xUpdateCursor(xCursor, UNO_QUERY); 613 Reference< beans::XPropertySet > xSet(pDatMan->getForm(), UNO_QUERY); 614 sal_Bool bIsNew = ::comphelper::getBOOL(xSet->getPropertyValue(C2U("IsNew"))); 615 if(!bIsNew) 616 { 617 sal_uInt32 nCount = 0; 618 xSet->getPropertyValue(C2U("RowCount")) >>= nCount; 619 // naechste position festellen 620 sal_Bool bSuccess = sal_False; 621 sal_Bool bLeft = sal_False; 622 sal_Bool bRight = sal_False; 623 try 624 { 625 bLeft = xCursor->isLast() && nCount > 1; 626 bRight= !xCursor->isLast(); 627 // ask for confirmation 628 Reference< frame::XController > xCtrl = pImp->pController; 629 Reference< form::XConfirmDeleteListener > xConfirm(pDatMan->GetFormController(),UNO_QUERY); 630 if (xConfirm.is()) 631 { 632 sdb::RowChangeEvent aEvent; 633 aEvent.Source = Reference< XInterface > (xCursor, UNO_QUERY); 634 aEvent.Action = sdb::RowChangeAction::DELETE; 635 aEvent.Rows = 1; 636 bSuccess = xConfirm->confirmDelete(aEvent); 637 } 638 639 // das Ding loeschen 640 if (bSuccess) 641 xUpdateCursor->deleteRow(); 642 } 643 catch(Exception&) 644 { 645 bSuccess = sal_False; 646 } 647 if (bSuccess) 648 { 649 if (bLeft || bRight) 650 xCursor->relative(bRight ? 1 : -1); 651 else 652 { 653 sal_Bool bCanInsert = canInsertRecords(xSet); 654 // kann noch ein Datensatz eingefuegt weden 655 try 656 { 657 if (bCanInsert) 658 xUpdateCursor->moveToInsertRow(); 659 else 660 // Datensatz bewegen um Stati neu zu setzen 661 xCursor->first(); 662 } 663 catch(Exception&) 664 { 665 DBG_ERROR("DeleteRecord : exception caught !"); 666 } 667 } 668 } 669 } 670 } 671 else if(aCommand.EqualsAscii("Cut")) 672 { 673 Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) ); 674 if(pChild) 675 { 676 KeyEvent aEvent( 0, KEYFUNC_CUT ); 677 pChild->KeyInput( aEvent ); 678 } 679 } 680 else if(aCommand.EqualsAscii("Copy")) 681 { 682 Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) ); 683 if(pChild) 684 { 685 KeyEvent aEvent( 0, KEYFUNC_COPY ); 686 pChild->KeyInput( aEvent ); 687 } 688 } 689 else if(aCommand.EqualsAscii("Paste")) 690 { 691 Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) ); 692 if(pChild) 693 { 694 KeyEvent aEvent( 0, KEYFUNC_PASTE ); 695 pChild->KeyInput( aEvent ); 696 } 697 } 698 } 699 } 700 IMPL_STATIC_LINK( BibFrameController_Impl, DisposeHdl, void*, EMPTYARG ) 701 { 702 pThis->xFrame->dispose(); 703 return 0; 704 }; 705 706 //----------------------------------------------------------------------------- 707 void BibFrameController_Impl::addStatusListener( 708 const uno::Reference< frame::XStatusListener > & aListener, 709 const util::URL& aURL) 710 throw (::com::sun::star::uno::RuntimeException) 711 { 712 BibConfig* pConfig = BibModul::GetConfig(); 713 // create a new Reference and insert into listener array 714 aStatusListeners.Insert( new BibStatusDispatch( aURL, aListener ), aStatusListeners.Count() ); 715 716 // den ersten Status synchron zusenden 717 FeatureStateEvent aEvent; 718 aEvent.FeatureURL = aURL; 719 aEvent.Requery = sal_False; 720 aEvent.Source = (XDispatch *) this; 721 if ( aURL.Path == C2U("StatusBarVisible") ) 722 { 723 aEvent.IsEnabled = sal_False; 724 aEvent.State <<= sal_Bool( sal_False ); 725 } 726 else if ( aURL.Path == C2U("Bib/hierarchical") ) 727 { 728 aEvent.IsEnabled = sal_True; 729 const char* pHier = bHierarchical? "" : "*" ; 730 aEvent.State <<= rtl::OUString::createFromAscii(pHier); 731 } 732 else if(aURL.Path == C2U("Bib/MenuFilter")) 733 { 734 aEvent.IsEnabled = sal_True; 735 aEvent.FeatureDescriptor=pDatMan->getQueryField(); 736 737 uno::Sequence<rtl::OUString> aStringSeq=pDatMan->getQueryFields(); 738 aEvent.State.setValue(&aStringSeq,::getCppuType((uno::Sequence<rtl::OUString>*)0)); 739 740 } 741 else if ( aURL.Path == C2U("Bib/source")) 742 { 743 aEvent.IsEnabled = sal_True; 744 aEvent.FeatureDescriptor=pDatMan->getActiveDataTable(); 745 746 uno::Sequence<rtl::OUString> aStringSeq=pDatMan->getDataSources(); 747 aEvent.State.setValue(&aStringSeq,::getCppuType((uno::Sequence<rtl::OUString>*)0)); 748 } 749 else if(aURL.Path == C2U("Bib/sdbsource") || 750 aURL.Path == C2U("Bib/Mapping") || 751 aURL.Path == C2U("Bib/autoFilter") || 752 aURL.Path.equalsAscii("Bib/standardFilter")) 753 { 754 aEvent.IsEnabled = sal_True; 755 } 756 else if(aURL.Path == C2U("Bib/query")) 757 { 758 aEvent.IsEnabled = sal_True; 759 aEvent.State <<= pConfig->getQueryText(); 760 } 761 else if (aURL.Path == C2U("Bib/removeFilter") ) 762 { 763 rtl::OUString aFilterStr=pDatMan->getFilter(); 764 aEvent.IsEnabled = (aFilterStr.getLength() > 0); 765 } 766 else if(aURL.Path == C2U("Cut")) 767 { 768 Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) ); 769 Edit* pEdit = dynamic_cast<Edit*>( pChild ); 770 if( pEdit ) 771 aEvent.IsEnabled = !pEdit->IsReadOnly() && pEdit->GetSelection().Len(); 772 } 773 if(aURL.Path == C2U("Copy")) 774 { 775 Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) ); 776 Edit* pEdit = dynamic_cast<Edit*>( pChild ); 777 if( pEdit ) 778 aEvent.IsEnabled = pEdit->GetSelection().Len() > 0; 779 } 780 else if(aURL.Path == C2U("Paste") ) 781 { 782 aEvent.IsEnabled = sal_False; 783 Window* pChild = lcl_GetFocusChild( VCLUnoHelper::GetWindow( xWindow ) ); 784 if(pChild) 785 { 786 uno::Reference< datatransfer::clipboard::XClipboard > xClip = pChild->GetClipboard(); 787 if(xClip.is()) 788 { 789 uno::Reference< datatransfer::XTransferable > xDataObj; 790 const sal_uInt32 nRef = Application::ReleaseSolarMutex(); 791 try 792 { 793 xDataObj = xClip->getContents(); 794 } 795 catch( const uno::Exception& ) 796 { 797 } 798 Application::AcquireSolarMutex( nRef ); 799 800 if ( xDataObj.is() ) 801 { 802 datatransfer::DataFlavor aFlavor; 803 SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor ); 804 try 805 { 806 uno::Any aData = xDataObj->getTransferData( aFlavor ); 807 ::rtl::OUString aText; 808 aData >>= aText; 809 aEvent.IsEnabled = aText.getLength() > 0; 810 } 811 catch( const uno::Exception& ) 812 { 813 } 814 } 815 } 816 uno::Reference< datatransfer::XTransferable > xContents = xClip->getContents( ); 817 } 818 } 819 else if(aURL.Path == C2U("Bib/DeleteRecord")) 820 { 821 Reference< ::com::sun::star::sdbc::XResultSet > xCursor(pDatMan->getForm(), UNO_QUERY); 822 Reference< XResultSetUpdate > xUpdateCursor(xCursor, UNO_QUERY); 823 Reference< beans::XPropertySet > xSet(pDatMan->getForm(), UNO_QUERY); 824 sal_Bool bIsNew = ::comphelper::getBOOL(xSet->getPropertyValue(C2U("IsNew"))); 825 if(!bIsNew) 826 { 827 sal_uInt32 nCount = 0; 828 xSet->getPropertyValue(C2U("RowCount")) >>= nCount; 829 aEvent.IsEnabled = nCount > 0; 830 } 831 } 832 else if (aURL.Path == C2U("Bib/InsertRecord")) 833 { 834 Reference< beans::XPropertySet > xSet(pDatMan->getForm(), UNO_QUERY); 835 aEvent.IsEnabled = canInsertRecords(xSet); 836 } 837 aListener->statusChanged( aEvent ); 838 } 839 //----------------------------------------------------------------------------- 840 void BibFrameController_Impl::removeStatusListener( 841 const uno::Reference< frame::XStatusListener > & aObject, const util::URL& aURL) 842 throw (::com::sun::star::uno::RuntimeException) 843 { 844 // search listener array for given listener 845 // for checking equality always "cast" to XInterface 846 if ( !bDisposing ) 847 { 848 sal_uInt16 nCount = aStatusListeners.Count(); 849 for ( sal_uInt16 n=0; n<nCount; n++ ) 850 { 851 BibStatusDispatch *pObj = aStatusListeners[n]; 852 sal_Bool bFlag=pObj->xListener.is(); 853 if (!bFlag || (pObj->xListener == aObject && 854 ( !aURL.Complete.getLength() || pObj->aURL.Path == aURL.Path ))) 855 { 856 aStatusListeners.DeleteAndDestroy( n ); 857 break; 858 } 859 } 860 } 861 } 862 //----------------------------------------------------------------------------- 863 void BibFrameController_Impl::RemoveFilter() 864 { 865 rtl::OUString aQuery; 866 pDatMan->startQueryWith(aQuery); 867 868 sal_uInt16 nCount = aStatusListeners.Count(); 869 870 sal_Bool bRemoveFilter=sal_False; 871 sal_Bool bQueryText=sal_False; 872 873 for ( sal_uInt16 n=0; n<nCount; n++ ) 874 { 875 BibStatusDispatch *pObj = aStatusListeners[n]; 876 if ( pObj->aURL.Path == C2U("Bib/removeFilter") ) 877 { 878 FeatureStateEvent aEvent; 879 aEvent.FeatureURL = pObj->aURL; 880 aEvent.IsEnabled = sal_False; 881 aEvent.Requery = sal_False; 882 aEvent.Source = (XDispatch *) this; 883 pObj->xListener->statusChanged( aEvent ); 884 bRemoveFilter=sal_True; 885 } 886 else if(pObj->aURL.Path == C2U("Bib/query")) 887 { 888 FeatureStateEvent aEvent; 889 aEvent.FeatureURL = pObj->aURL; 890 aEvent.IsEnabled = sal_True; 891 aEvent.Requery = sal_False; 892 aEvent.Source = (XDispatch *) this; 893 aEvent.State <<= aQuery; 894 pObj->xListener->statusChanged( aEvent ); 895 bQueryText=sal_True; 896 } 897 898 if(bRemoveFilter && bQueryText) 899 break; 900 901 } 902 } 903 //----------------------------------------------------------------------------- 904 void BibFrameController_Impl::ChangeDataSource(const uno::Sequence< beans::PropertyValue >& aArgs) 905 { 906 const beans::PropertyValue* pPropertyValue = aArgs.getConstArray(); 907 uno::Any aValue=pPropertyValue[0].Value; 908 rtl::OUString aDBTableName; 909 aValue >>= aDBTableName; 910 911 912 if(aArgs.getLength() > 1) 913 { 914 uno::Any aDB = pPropertyValue[1].Value; 915 rtl::OUString aURL; 916 aDB >>= aURL; 917 pDatMan->setActiveDataSource(aURL); 918 aDBTableName = pDatMan->getActiveDataTable(); 919 } 920 else 921 { 922 m_xDatMan->unload(); 923 pDatMan->setActiveDataTable(aDBTableName); 924 pDatMan->updateGridModel(); 925 m_xDatMan->load(); 926 } 927 928 929 sal_uInt16 nCount = aStatusListeners.Count(); 930 931 sal_Bool bMenuFilter=sal_False; 932 sal_Bool bQueryText=sal_False; 933 for ( sal_uInt16 n=0; n<nCount; n++ ) 934 { 935 BibStatusDispatch *pObj = aStatusListeners[n]; 936 if(COMPARE_EQUAL == pObj->aURL.Path.compareToAscii("Bib/MenuFilter")) 937 { 938 FeatureStateEvent aEvent; 939 aEvent.FeatureURL = pObj->aURL; 940 aEvent.IsEnabled = sal_True; 941 aEvent.Requery = sal_False; 942 aEvent.Source = (XDispatch *) this; 943 aEvent.FeatureDescriptor=pDatMan->getQueryField(); 944 945 uno::Sequence<rtl::OUString> aStringSeq=pDatMan->getQueryFields(); 946 aEvent.State = makeAny( aStringSeq ); 947 948 pObj->xListener->statusChanged( aEvent ); 949 bMenuFilter=sal_True; 950 } 951 else if(COMPARE_EQUAL == pObj->aURL.Path.compareToAscii("Bib/query")) 952 { 953 FeatureStateEvent aEvent; 954 aEvent.FeatureURL = pObj->aURL; 955 aEvent.IsEnabled = sal_True; 956 aEvent.Requery = sal_False; 957 aEvent.Source = (XDispatch *) this; 958 BibConfig* pConfig = BibModul::GetConfig(); 959 aEvent.State <<= pConfig->getQueryText(); 960 pObj->xListener->statusChanged( aEvent ); 961 bQueryText=sal_True; 962 } 963 964 if (bMenuFilter && bQueryText) 965 break; 966 967 } 968 } 969 970 void BibFrameController_Impl::activate() 971 { 972 } 973 void BibFrameController_Impl::deactivate() 974 { 975 } 976 977 978