1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svx.hxx" 26 27 #include "svx/fmgridif.hxx" 28 #include "fmprop.hrc" 29 #include "fmservs.hxx" 30 #include "svx/fmtools.hxx" 31 #include "fmurl.hxx" 32 #include "formcontrolfactory.hxx" 33 #include "gridcell.hxx" 34 #include "sdbdatacolumn.hxx" 35 #include "svx/fmgridcl.hxx" 36 #include "svx/svxids.hrc" 37 #include <tools/urlobj.hxx> 38 39 /** === begin UNO includes === **/ 40 #include <com/sun/star/awt/PosSize.hpp> 41 #include <com/sun/star/beans/PropertyAttribute.hpp> 42 #include <com/sun/star/form/FormComponentType.hpp> 43 #include <com/sun/star/form/XFormComponent.hpp> 44 #include <com/sun/star/form/XLoadable.hpp> 45 #include <com/sun/star/lang/DisposedException.hpp> 46 #include <com/sun/star/sdbc/ResultSetType.hpp> 47 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp> 48 #include <com/sun/star/util/XURLTransformer.hpp> 49 #include <com/sun/star/view/XSelectionSupplier.hpp> 50 #include <com/sun/star/sdbcx/XRowLocate.hpp> 51 /** === end UNO includes === **/ 52 53 #include <comphelper/container.hxx> 54 #include <comphelper/enumhelper.hxx> 55 #include <comphelper/extract.hxx> 56 #include <comphelper/processfactory.hxx> 57 #include <comphelper/property.hxx> 58 #include <comphelper/sequence.hxx> 59 #include <comphelper/types.hxx> 60 #include <cppuhelper/typeprovider.hxx> 61 #include <toolkit/helper/vclunohelper.hxx> 62 #include <tools/diagnose_ex.h> 63 64 using namespace ::svxform; 65 using namespace ::com::sun::star::container; 66 using namespace ::com::sun::star::sdb; 67 using namespace ::com::sun::star::sdbc; 68 using namespace ::com::sun::star::uno; 69 using namespace ::com::sun::star::view; 70 using namespace ::com::sun::star::beans; 71 using namespace ::com::sun::star::lang; 72 using namespace ::com::sun::star::form; 73 using namespace ::com::sun::star::util; 74 using namespace ::com::sun::star; 75 76 using ::com::sun::star::sdbcx::XColumnsSupplier; 77 using ::com::sun::star::frame::XDispatchProviderInterceptor; 78 using ::com::sun::star::frame::XDispatchProvider; 79 using ::com::sun::star::accessibility::XAccessible; 80 using ::com::sun::star::accessibility::XAccessibleContext; 81 using ::com::sun::star::sdb::XRowSetSupplier; 82 using ::com::sun::star::awt::XVclWindowPeer; 83 84 85 //------------------------------------------------------------------ 86 ::com::sun::star::awt::FontDescriptor ImplCreateFontDescriptor( const Font& rFont ) 87 { 88 ::com::sun::star::awt::FontDescriptor aFD; 89 aFD.Name = rFont.GetName(); 90 aFD.StyleName = rFont.GetStyleName(); 91 aFD.Height = (sal_Int16)rFont.GetSize().Height(); 92 aFD.Width = (sal_Int16)rFont.GetSize().Width(); 93 aFD.Family = (sal_Int16)rFont.GetFamily(); 94 aFD.CharSet = rFont.GetCharSet(); 95 aFD.Pitch = (sal_Int16)rFont.GetPitch(); 96 aFD.CharacterWidth = VCLUnoHelper::ConvertFontWidth( rFont.GetWidthType() ); 97 aFD.Weight= VCLUnoHelper::ConvertFontWeight( rFont.GetWeight() ); 98 aFD.Slant = (::com::sun::star::awt::FontSlant)rFont.GetItalic(); 99 aFD.Underline = (sal_Int16)rFont.GetUnderline(); 100 aFD.Strikeout = (sal_Int16)rFont.GetStrikeout(); 101 aFD.Orientation = rFont.GetOrientation(); 102 aFD.Kerning = rFont.IsKerning(); 103 aFD.WordLineMode = rFont.IsWordLineMode(); 104 aFD.Type = 0; // ??? => Nur an Metric... 105 return aFD; 106 } 107 108 //------------------------------------------------------------------ 109 Font ImplCreateFont( const ::com::sun::star::awt::FontDescriptor& rDescr ) 110 { 111 Font aFont; 112 aFont.SetName( rDescr.Name ); 113 aFont.SetStyleName( rDescr.StyleName ); 114 aFont.SetSize( ::Size( rDescr.Width, rDescr.Height ) ); 115 aFont.SetFamily( (FontFamily)rDescr.Family ); 116 aFont.SetCharSet( (CharSet)rDescr.CharSet ); 117 aFont.SetPitch( (FontPitch)rDescr.Pitch ); 118 aFont.SetWidthType( VCLUnoHelper::ConvertFontWidth( rDescr.CharacterWidth ) ); 119 aFont.SetWeight( VCLUnoHelper::ConvertFontWeight( rDescr.Weight ) ); 120 aFont.SetItalic( (FontItalic)rDescr.Slant ); 121 aFont.SetUnderline( (::FontUnderline)rDescr.Underline ); 122 aFont.SetStrikeout( (::FontStrikeout)rDescr.Strikeout ); 123 aFont.SetOrientation( (sal_Int16)rDescr.Orientation ); 124 aFont.SetKerning( rDescr.Kerning ); 125 aFont.SetWordLineMode( rDescr.WordLineMode ); 126 return aFont; 127 } 128 129 //================================================================== 130 //= FmXModifyMultiplexer 131 //================================================================== 132 //------------------------------------------------------------------ 133 FmXModifyMultiplexer::FmXModifyMultiplexer( ::cppu::OWeakObject& rSource, ::osl::Mutex& _rMutex ) 134 :OWeakSubObject( rSource ) 135 ,OInterfaceContainerHelper( _rMutex ) 136 { 137 } 138 139 //------------------------------------------------------------------ 140 Any SAL_CALL FmXModifyMultiplexer::queryInterface(const Type& _rType) throw (RuntimeException) 141 { 142 Any aReturn; 143 aReturn = ::cppu::queryInterface(_rType, 144 static_cast< ::com::sun::star::util::XModifyListener*>(this), 145 static_cast< XEventListener*>(this) 146 ); 147 148 if (!aReturn.hasValue()) 149 aReturn = OWeakSubObject::queryInterface( _rType ); 150 151 return aReturn; 152 } 153 154 //------------------------------------------------------------------ 155 void FmXModifyMultiplexer::disposing(const EventObject& ) throw( RuntimeException ) 156 { 157 } 158 159 //------------------------------------------------------------------ 160 void FmXModifyMultiplexer::modified(const EventObject& e) throw( RuntimeException ) 161 { 162 EventObject aMulti( e); 163 aMulti.Source = &m_rParent; 164 notifyEach( &XModifyListener::modified, aMulti ); 165 } 166 167 //================================================================== 168 //= FmXUpdateMultiplexer 169 //================================================================== 170 //------------------------------------------------------------------ 171 FmXUpdateMultiplexer::FmXUpdateMultiplexer( ::cppu::OWeakObject& rSource, ::osl::Mutex& _rMutex ) 172 :OWeakSubObject( rSource ) 173 ,OInterfaceContainerHelper( _rMutex ) 174 { 175 } 176 177 //------------------------------------------------------------------ 178 Any SAL_CALL FmXUpdateMultiplexer::queryInterface(const Type& _rType) throw (RuntimeException) 179 { 180 Any aReturn; 181 aReturn = ::cppu::queryInterface(_rType, 182 static_cast< XUpdateListener*>(this), 183 static_cast< XEventListener*>(this) 184 ); 185 186 if (!aReturn.hasValue()) 187 aReturn = OWeakSubObject::queryInterface( _rType ); 188 189 return aReturn; 190 } 191 192 //------------------------------------------------------------------ 193 void FmXUpdateMultiplexer::disposing(const EventObject& ) throw( RuntimeException ) 194 { 195 } 196 197 //------------------------------------------------------------------ 198 sal_Bool FmXUpdateMultiplexer::approveUpdate(const EventObject &e) throw( RuntimeException ) 199 { 200 EventObject aMulti( e ); 201 aMulti.Source = &m_rParent; 202 203 sal_Bool bResult = sal_True; 204 if (getLength()) 205 { 206 ::cppu::OInterfaceIteratorHelper aIter(*this); 207 while ( bResult && aIter.hasMoreElements() ) 208 bResult = static_cast< XUpdateListener* >( aIter.next() )->approveUpdate( aMulti ); 209 } 210 211 return bResult; 212 } 213 214 //------------------------------------------------------------------ 215 void FmXUpdateMultiplexer::updated(const EventObject &e) throw( RuntimeException ) 216 { 217 EventObject aMulti( e ); 218 aMulti.Source = &m_rParent; 219 notifyEach( &XUpdateListener::updated, aMulti ); 220 } 221 222 223 //================================================================== 224 //= FmXSelectionMultiplexer 225 //================================================================== 226 //------------------------------------------------------------------ 227 FmXSelectionMultiplexer::FmXSelectionMultiplexer( ::cppu::OWeakObject& rSource, ::osl::Mutex& _rMutex ) 228 :OWeakSubObject( rSource ) 229 ,OInterfaceContainerHelper( _rMutex ) 230 { 231 } 232 233 //------------------------------------------------------------------ 234 Any SAL_CALL FmXSelectionMultiplexer::queryInterface(const Type& _rType) throw (RuntimeException) 235 { 236 Any aReturn; 237 aReturn = ::cppu::queryInterface(_rType, 238 static_cast< XSelectionChangeListener*>(this), 239 static_cast< XEventListener*>(this) 240 ); 241 242 if (!aReturn.hasValue()) 243 aReturn = OWeakSubObject::queryInterface( _rType ); 244 245 return aReturn; 246 } 247 248 //------------------------------------------------------------------ 249 void FmXSelectionMultiplexer::disposing(const EventObject& ) throw( RuntimeException ) 250 { 251 } 252 253 //------------------------------------------------------------------ 254 void SAL_CALL FmXSelectionMultiplexer::selectionChanged( const EventObject& _rEvent ) throw (RuntimeException) 255 { 256 EventObject aMulti(_rEvent); 257 aMulti.Source = &m_rParent; 258 notifyEach( &XSelectionChangeListener::selectionChanged, aMulti ); 259 } 260 261 //================================================================== 262 //= FmXContainerMultiplexer 263 //================================================================== 264 //------------------------------------------------------------------ 265 FmXContainerMultiplexer::FmXContainerMultiplexer( ::cppu::OWeakObject& rSource, ::osl::Mutex& _rMutex ) 266 :OWeakSubObject( rSource ) 267 ,OInterfaceContainerHelper( _rMutex ) 268 { 269 } 270 271 //------------------------------------------------------------------ 272 Any SAL_CALL FmXContainerMultiplexer::queryInterface(const Type& _rType) throw (RuntimeException) 273 { 274 Any aReturn; 275 aReturn = ::cppu::queryInterface(_rType, 276 static_cast< XContainerListener*>(this), 277 static_cast< XEventListener*>(this) 278 ); 279 280 if (!aReturn.hasValue()) 281 aReturn = OWeakSubObject::queryInterface( _rType ); 282 283 return aReturn; 284 } 285 286 //------------------------------------------------------------------ 287 void FmXContainerMultiplexer::disposing(const EventObject& ) throw( RuntimeException ) 288 { 289 } 290 //------------------------------------------------------------------ 291 void FmXContainerMultiplexer::elementInserted(const ContainerEvent& e) throw( RuntimeException ) 292 { 293 ContainerEvent aMulti( e ); 294 aMulti.Source = &m_rParent; 295 notifyEach( &XContainerListener::elementInserted, aMulti ); 296 } 297 298 //------------------------------------------------------------------ 299 void FmXContainerMultiplexer::elementRemoved(const ContainerEvent& e) throw( RuntimeException ) 300 { 301 ContainerEvent aMulti( e ); 302 aMulti.Source = &m_rParent; 303 notifyEach( &XContainerListener::elementRemoved, aMulti ); 304 } 305 306 307 //------------------------------------------------------------------ 308 void FmXContainerMultiplexer::elementReplaced(const ContainerEvent& e) throw( RuntimeException ) 309 { 310 ContainerEvent aMulti( e ); 311 aMulti.Source = &m_rParent; 312 notifyEach( &XContainerListener::elementReplaced, aMulti ); 313 } 314 315 //================================================================== 316 //= FmXGridControlMultiplexer 317 //================================================================== 318 //------------------------------------------------------------------ 319 FmXGridControlMultiplexer::FmXGridControlMultiplexer( ::cppu::OWeakObject& rSource, ::osl::Mutex& _rMutex ) 320 :OWeakSubObject( rSource ) 321 ,OInterfaceContainerHelper( _rMutex ) 322 { 323 } 324 325 //------------------------------------------------------------------ 326 Any SAL_CALL FmXGridControlMultiplexer::queryInterface(const Type& _rType) throw (RuntimeException) 327 { 328 Any aReturn; 329 aReturn = ::cppu::queryInterface( _rType, 330 static_cast< XGridControlListener*>(this) 331 ); 332 333 if (!aReturn.hasValue()) 334 aReturn = OWeakSubObject::queryInterface( _rType ); 335 336 return aReturn; 337 } 338 339 //------------------------------------------------------------------ 340 void FmXGridControlMultiplexer::disposing( const EventObject& ) throw( RuntimeException ) 341 { 342 } 343 344 //------------------------------------------------------------------ 345 void SAL_CALL FmXGridControlMultiplexer::columnChanged( const EventObject& _event ) throw (RuntimeException) 346 { 347 EventObject aForwardedEvent( _event ); 348 aForwardedEvent.Source = &m_rParent; 349 notifyEach( &XGridControlListener::columnChanged, aForwardedEvent ); 350 } 351 352 //================================================================== 353 //= FmXGridControl 354 //================================================================== 355 356 //------------------------------------------------------------------ 357 Reference< XInterface > SAL_CALL FmXGridControl_NewInstance_Impl(const Reference< XMultiServiceFactory>& _rxFactory) 358 { 359 return *(new FmXGridControl(_rxFactory)); 360 } 361 DBG_NAME(FmXGridControl ) 362 //------------------------------------------------------------------------------ 363 FmXGridControl::FmXGridControl(const Reference< XMultiServiceFactory >& _rxFactory) 364 :UnoControl( _rxFactory) 365 ,m_aModifyListeners(*this, GetMutex()) 366 ,m_aUpdateListeners(*this, GetMutex()) 367 ,m_aContainerListeners(*this, GetMutex()) 368 ,m_aSelectionListeners(*this, GetMutex()) 369 ,m_aGridControlListeners(*this, GetMutex()) 370 ,m_nPeerCreationLevel(0) 371 ,m_bInDraw(sal_False) 372 ,m_xServiceFactory(_rxFactory) 373 { 374 DBG_CTOR(FmXGridControl ,NULL); 375 } 376 377 //------------------------------------------------------------------------------ 378 FmXGridControl::~FmXGridControl() 379 { 380 DBG_DTOR(FmXGridControl ,NULL); 381 } 382 383 //------------------------------------------------------------------ 384 Any SAL_CALL FmXGridControl::queryAggregation(const Type& _rType) throw (RuntimeException) 385 { 386 Any aReturn = FmXGridControl_BASE::queryInterface(_rType); 387 388 if (!aReturn.hasValue()) 389 aReturn = UnoControl::queryAggregation( _rType ); 390 return aReturn; 391 } 392 393 //------------------------------------------------------------------ 394 Sequence< Type> SAL_CALL FmXGridControl::getTypes( ) throw(RuntimeException) 395 { 396 return comphelper::concatSequences(UnoControl::getTypes(),FmXGridControl_BASE::getTypes()); 397 } 398 399 //------------------------------------------------------------------ 400 Sequence<sal_Int8> SAL_CALL FmXGridControl::getImplementationId( ) throw(RuntimeException) 401 { 402 static ::cppu::OImplementationId* pId = 0; 403 if (! pId) 404 { 405 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 406 if (! pId) 407 { 408 static ::cppu::OImplementationId aId; 409 pId = &aId; 410 } 411 } 412 return pId->getImplementationId(); 413 } 414 415 // XServiceInfo 416 //------------------------------------------------------------------------------ 417 sal_Bool SAL_CALL FmXGridControl::supportsService(const ::rtl::OUString& ServiceName) throw() 418 { 419 ::comphelper::StringSequence aSupported = getSupportedServiceNames(); 420 const ::rtl::OUString * pArray = aSupported.getConstArray(); 421 for( sal_Int32 i = 0; i < aSupported.getLength(); i++ ) 422 if( pArray[i] == ServiceName ) 423 return sal_True; 424 return sal_False; 425 } 426 427 //------------------------------------------------------------------------------ 428 ::rtl::OUString SAL_CALL FmXGridControl::getImplementationName() throw() 429 { 430 return ::rtl::OUString::createFromAscii("com.sun.star.form.FmXGridControl"); 431 } 432 433 //------------------------------------------------------------------------------ 434 ::comphelper::StringSequence SAL_CALL FmXGridControl::getSupportedServiceNames() throw() 435 { 436 Sequence< ::rtl::OUString > aServiceNames(2); 437 aServiceNames[0] = FM_SUN_CONTROL_GRIDCONTROL; 438 aServiceNames[1] = ::rtl::OUString::createFromAscii("com.sun.star.awt.UnoControl"); 439 return aServiceNames; 440 } 441 442 //------------------------------------------------------------------------------ 443 void SAL_CALL FmXGridControl::dispose() throw( RuntimeException ) 444 { 445 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 446 447 EventObject aEvt; 448 aEvt.Source = static_cast< ::cppu::OWeakObject* >(this); 449 m_aModifyListeners.disposeAndClear(aEvt); 450 m_aUpdateListeners.disposeAndClear(aEvt); 451 m_aContainerListeners.disposeAndClear(aEvt); 452 453 UnoControl::dispose(); 454 } 455 456 //------------------------------------------------------------------------------ 457 ::rtl::OUString FmXGridControl::GetComponentServiceName() 458 { 459 ::rtl::OUString aName = ::rtl::OUString::createFromAscii("DBGrid"); 460 return aName; 461 } 462 463 //------------------------------------------------------------------------------ 464 sal_Bool SAL_CALL FmXGridControl::setModel(const Reference< ::com::sun::star::awt::XControlModel >& rModel) throw( RuntimeException ) 465 { 466 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 467 468 if (!UnoControl::setModel(rModel)) 469 return sal_False; 470 471 Reference< XGridPeer > xGridPeer(getPeer(), UNO_QUERY); 472 if (xGridPeer.is()) 473 { 474 Reference< XIndexContainer > xCols(mxModel, UNO_QUERY); 475 xGridPeer->setColumns(xCols); 476 } 477 return sal_True; 478 } 479 480 //------------------------------------------------------------------------------ 481 FmXGridPeer* FmXGridControl::imp_CreatePeer(Window* pParent) 482 { 483 FmXGridPeer* pReturn = new FmXGridPeer(m_xServiceFactory); 484 485 // translate properties into WinBits 486 WinBits nStyle = WB_TABSTOP; 487 Reference< XPropertySet > xModelSet(getModel(), UNO_QUERY); 488 if (xModelSet.is()) 489 { 490 try 491 { 492 if (::comphelper::getINT16(xModelSet->getPropertyValue(FM_PROP_BORDER))) 493 nStyle |= WB_BORDER; 494 } 495 catch(const Exception&) 496 { 497 OSL_ASSERT(!"Can not get style"); 498 } 499 } 500 501 pReturn->Create(pParent, nStyle); 502 return pReturn; 503 } 504 505 //------------------------------------------------------------------------------ 506 void SAL_CALL FmXGridControl::createPeer(const Reference< ::com::sun::star::awt::XToolkit >& /*rToolkit*/, const Reference< ::com::sun::star::awt::XWindowPeer >& rParentPeer) throw( RuntimeException ) 507 { 508 if ( !mxModel.is() ) 509 throw DisposedException( ::rtl::OUString(), *this ); 510 511 DBG_ASSERT(/*(0 == m_nPeerCreationLevel) && */!mbCreatingPeer, "FmXGridControl::createPeer : recursion!"); 512 // I think this should never assert, now that we're using the base class' mbCreatingPeer in addition to 513 // our own m_nPeerCreationLevel 514 // But I'm not sure as I don't _fully_ understand the underlying toolkit implementations .... 515 // (if this asserts, we still need m_nPeerCreationLevel. If not, we could omit it ....) 516 // 14.05.2001 - 86836 - frank.schoenheit@germany.sun.com 517 518 // TODO: why the hell this whole class does not use any mutex? 519 520 if (!getPeer().is()) 521 { 522 mbCreatingPeer = sal_True; 523 // mbCreatingPeer is virtually the same as m_nPeerCreationLevel, but it's the base class' method 524 // to prevent recursion. 525 526 Window* pParentWin = NULL; 527 if (rParentPeer.is()) 528 { 529 VCLXWindow* pParent = VCLXWindow::GetImplementation(rParentPeer); 530 if (pParent) 531 pParentWin = pParent->GetWindow(); 532 } 533 534 FmXGridPeer* pPeer = imp_CreatePeer(pParentWin); 535 DBG_ASSERT(pPeer != NULL, "FmXGridControl::createPeer : imp_CreatePeer didn't return a peer !"); 536 setPeer( pPeer ); 537 538 // lesen der properties aus dem model 539 // ++m_nPeerCreationLevel; 540 updateFromModel(); 541 542 // folgendes unschoene Szenario : updateFromModel fuehrt zu einem propertiesChanged am Control, 543 // das stellt fest, dass sich eine 'kritische' Property geaendert hat (zum Beispiel "Border") und 544 // legt daraufhin eine neue Peer an, was wieder hier im createPeer landet, wir legen also eine 545 // zweite FmXGridPeer an und initialisieren die. Dann kommen wir in der ersten Inkarnation aus 546 // dem updsateFromModel raus und arbeiten dort weiter mit dem pPeer, das jetzt eigentlich schon 547 // veraltet ist (da ja in der zweiten Inkarnation eine andere Peer angelegt wurde). 548 // Deswegen also der Aufwand mit dem PeerCreationLevel, das stellt sicher, dass wir die in dem 549 // tiefsten Level angelegte Peer wirklich verwenden, sie aber erst im top-level 550 // initialisieren. 551 // if (--m_nPeerCreationLevel == 0) 552 { 553 DBG_ASSERT(getPeer().is(), "FmXGridControl::createPeer : something went wrong ... no top level peer !"); 554 pPeer = FmXGridPeer::getImplementation(getPeer()); 555 556 setPosSize( maComponentInfos.nX, maComponentInfos.nY, maComponentInfos.nWidth, maComponentInfos.nHeight, ::com::sun::star::awt::PosSize::POSSIZE ); 557 558 Reference< XIndexContainer > xColumns(getModel(), UNO_QUERY); 559 if (xColumns.is()) 560 pPeer->setColumns(xColumns); 561 562 if (maComponentInfos.bVisible) 563 pPeer->setVisible(sal_True); 564 565 if (!maComponentInfos.bEnable) 566 pPeer->setEnable(sal_False); 567 568 if (maWindowListeners.getLength()) 569 pPeer->addWindowListener( &maWindowListeners ); 570 571 if (maFocusListeners.getLength()) 572 pPeer->addFocusListener( &maFocusListeners ); 573 574 if (maKeyListeners.getLength()) 575 pPeer->addKeyListener( &maKeyListeners ); 576 577 if (maMouseListeners.getLength()) 578 pPeer->addMouseListener( &maMouseListeners ); 579 580 if (maMouseMotionListeners.getLength()) 581 pPeer->addMouseMotionListener( &maMouseMotionListeners ); 582 583 if (maPaintListeners.getLength()) 584 pPeer->addPaintListener( &maPaintListeners ); 585 586 if (m_aModifyListeners.getLength()) 587 pPeer->addModifyListener( &m_aModifyListeners ); 588 589 if (m_aUpdateListeners.getLength()) 590 pPeer->addUpdateListener( &m_aUpdateListeners ); 591 592 if (m_aContainerListeners.getLength()) 593 pPeer->addContainerListener( &m_aContainerListeners ); 594 595 // forward the design mode 596 sal_Bool bForceAlivePeer = m_bInDraw && !maComponentInfos.bVisible; 597 // (we force a alive-mode peer if we're in "draw", cause in this case the peer will be used for drawing in 598 // foreign devices. We ensure this with the visibility check as an living peer is assumed to be noncritical 599 // only if invisible) 600 Any aOldCursorBookmark; 601 if (!mbDesignMode || bForceAlivePeer) 602 { 603 Reference< XFormComponent > xComp(getModel(), UNO_QUERY); 604 if (xComp.is()) 605 { 606 Reference< XRowSet > xForm(xComp->getParent(), UNO_QUERY); 607 // is the form alive? 608 // we can see that if the form contains columns 609 Reference< ::com::sun::star::sdbcx::XColumnsSupplier > xColumnsSupplier(xForm, UNO_QUERY); 610 if (xColumnsSupplier.is()) 611 { 612 if (Reference< XIndexAccess > (xColumnsSupplier->getColumns(),UNO_QUERY)->getCount()) 613 { 614 // we get only a new bookmark if the resultset is not forwardonly 615 if (::comphelper::getINT32(Reference< XPropertySet > (xForm, UNO_QUERY)->getPropertyValue(FM_PROP_RESULTSET_TYPE)) != ResultSetType::FORWARD_ONLY) 616 { 617 // as the FmGridControl touches the data source it is connected to we have to remember the current 618 // cursor position (and restore afterwards) 619 // OJ: but only when we stand on a valid row 620 Reference< XResultSet > xResultSet(xForm, UNO_QUERY); 621 if ( !xResultSet->isBeforeFirst() && !xResultSet->isAfterLast() ) 622 { 623 try 624 { 625 aOldCursorBookmark = Reference< ::com::sun::star::sdbcx::XRowLocate > (xForm, UNO_QUERY)->getBookmark(); 626 } 627 catch( const Exception& e ) 628 { 629 DBG_UNHANDLED_EXCEPTION(); 630 (void)e; 631 } 632 } 633 } 634 } 635 } 636 pPeer->setRowSet(xForm); 637 } 638 } 639 pPeer->setDesignMode(mbDesignMode && !bForceAlivePeer); 640 641 try 642 { 643 if (aOldCursorBookmark.hasValue()) 644 { // we have a valid bookmark, so we have to restore the cursor's position 645 Reference< XFormComponent > xComp(getModel(), UNO_QUERY); 646 Reference< ::com::sun::star::sdbcx::XRowLocate > xLocate(xComp->getParent(), UNO_QUERY); 647 xLocate->moveToBookmark(aOldCursorBookmark); 648 } 649 } 650 catch( const Exception& e ) 651 { 652 DBG_UNHANDLED_EXCEPTION(); 653 (void)e; 654 } 655 656 Reference< ::com::sun::star::awt::XView > xPeerView(getPeer(), UNO_QUERY); 657 xPeerView->setZoom( maComponentInfos.nZoomX, maComponentInfos.nZoomY ); 658 xPeerView->setGraphics( mxGraphics ); 659 } 660 mbCreatingPeer = sal_False; 661 } 662 } 663 664 //------------------------------------------------------------------------------ 665 void FmXGridControl::addModifyListener(const Reference< ::com::sun::star::util::XModifyListener >& l) throw( RuntimeException ) 666 { 667 m_aModifyListeners.addInterface( l ); 668 if( getPeer().is() && m_aModifyListeners.getLength() == 1 ) 669 { 670 Reference< ::com::sun::star::util::XModifyBroadcaster > xGrid(getPeer(), UNO_QUERY); 671 xGrid->addModifyListener( &m_aModifyListeners); 672 } 673 } 674 675 //------------------------------------------------------------------------------ 676 sal_Bool SAL_CALL FmXGridControl::select( const Any& _rSelection ) throw (IllegalArgumentException, RuntimeException) 677 { 678 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 679 Reference< XSelectionSupplier > xPeer(getPeer(), UNO_QUERY); 680 return xPeer->select(_rSelection); 681 } 682 683 //------------------------------------------------------------------------------ 684 Any SAL_CALL FmXGridControl::getSelection( ) throw (RuntimeException) 685 { 686 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 687 Reference< XSelectionSupplier > xPeer(getPeer(), UNO_QUERY); 688 return xPeer->getSelection(); 689 } 690 691 //------------------------------------------------------------------------------ 692 void SAL_CALL FmXGridControl::addSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException) 693 { 694 m_aSelectionListeners.addInterface( _rxListener ); 695 if( getPeer().is() && 1 == m_aSelectionListeners.getLength() ) 696 { 697 Reference< XSelectionSupplier > xGrid(getPeer(), UNO_QUERY); 698 xGrid->addSelectionChangeListener( &m_aSelectionListeners); 699 } 700 } 701 702 //------------------------------------------------------------------------------ 703 void SAL_CALL FmXGridControl::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException) 704 { 705 if( getPeer().is() && 1 == m_aSelectionListeners.getLength() ) 706 { 707 Reference< XSelectionSupplier > xGrid(getPeer(), UNO_QUERY); 708 xGrid->removeSelectionChangeListener( &m_aSelectionListeners); 709 } 710 m_aSelectionListeners.removeInterface( _rxListener ); 711 } 712 713 //------------------------------------------------------------------------------ 714 Sequence< sal_Bool > SAL_CALL FmXGridControl::queryFieldDataType( const Type& xType ) throw(RuntimeException) 715 { 716 if (getPeer().is()) 717 { 718 Reference< XGridFieldDataSupplier > xPeerSupplier(getPeer(), UNO_QUERY); 719 if (xPeerSupplier.is()) 720 return xPeerSupplier->queryFieldDataType(xType); 721 } 722 723 return Sequence<sal_Bool>(); 724 } 725 726 //------------------------------------------------------------------------------ 727 Sequence< Any > SAL_CALL FmXGridControl::queryFieldData( sal_Int32 nRow, const Type& xType ) throw(RuntimeException) 728 { 729 if (getPeer().is()) 730 { 731 Reference< XGridFieldDataSupplier > xPeerSupplier(getPeer(), UNO_QUERY); 732 if (xPeerSupplier.is()) 733 return xPeerSupplier->queryFieldData(nRow, xType); 734 } 735 736 return Sequence< Any>(); 737 } 738 739 //------------------------------------------------------------------------------ 740 void SAL_CALL FmXGridControl::removeModifyListener(const Reference< ::com::sun::star::util::XModifyListener >& l) throw( RuntimeException ) 741 { 742 if( getPeer().is() && m_aModifyListeners.getLength() == 1 ) 743 { 744 Reference< ::com::sun::star::util::XModifyBroadcaster > xGrid(getPeer(), UNO_QUERY); 745 xGrid->removeModifyListener( &m_aModifyListeners); 746 } 747 m_aModifyListeners.removeInterface( l ); 748 } 749 750 //------------------------------------------------------------------------------ 751 void SAL_CALL FmXGridControl::draw( sal_Int32 x, sal_Int32 y ) throw( RuntimeException ) 752 { 753 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 754 m_bInDraw = sal_True; 755 UnoControl::draw(x, y); 756 m_bInDraw = sal_False; 757 } 758 759 //------------------------------------------------------------------------------ 760 void SAL_CALL FmXGridControl::setDesignMode(sal_Bool bOn) throw( RuntimeException ) 761 { 762 ::com::sun::star::util::ModeChangeEvent aModeChangeEvent; 763 764 // --- <mutex_lock> --- 765 { 766 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 767 768 Reference< XRowSetSupplier > xGrid(getPeer(), UNO_QUERY); 769 770 if (xGrid.is() && (bOn != mbDesignMode || (!bOn && !xGrid->getRowSet().is()))) 771 { 772 if (bOn) 773 { 774 xGrid->setRowSet(Reference< XRowSet > ()); 775 } 776 else 777 { 778 Reference< XFormComponent > xComp(getModel(), UNO_QUERY); 779 if (xComp.is()) 780 { 781 Reference< XRowSet > xForm(xComp->getParent(), UNO_QUERY); 782 xGrid->setRowSet(xForm); 783 } 784 } 785 786 mbDesignMode = bOn; 787 788 Reference< XVclWindowPeer > xVclWindowPeer( getPeer(), UNO_QUERY ); 789 if (xVclWindowPeer.is()) 790 xVclWindowPeer->setDesignMode(bOn); 791 } 792 mbDesignMode = bOn; 793 794 // dispose our current AccessibleContext, if we have one 795 // (changing the design mode implies having a new implementation for this context, 796 // so the old one must be declared DEFUNC) 797 disposeAccessibleContext(); 798 799 // prepare firing an event 800 aModeChangeEvent.Source = *this; 801 aModeChangeEvent.NewMode = ::rtl::OUString::createFromAscii( mbDesignMode ? "design" : "alive" ); 802 } 803 804 // --- </mutex_lock> --- 805 maModeChangeListeners.notifyEach( &XModeChangeListener::modeChanged, aModeChangeEvent ); 806 } 807 808 // XBoundComponent 809 //------------------------------------------------------------------------------ 810 void SAL_CALL FmXGridControl::addUpdateListener(const Reference< XUpdateListener >& l) throw( RuntimeException ) 811 { 812 m_aUpdateListeners.addInterface( l ); 813 if( getPeer().is() && m_aUpdateListeners.getLength() == 1 ) 814 { 815 Reference< XBoundComponent > xBound(getPeer(), UNO_QUERY); 816 xBound->addUpdateListener( &m_aUpdateListeners); 817 } 818 } 819 820 //------------------------------------------------------------------------------ 821 void SAL_CALL FmXGridControl::removeUpdateListener(const Reference< XUpdateListener >& l) throw( RuntimeException ) 822 { 823 if( getPeer().is() && m_aUpdateListeners.getLength() == 1 ) 824 { 825 Reference< XBoundComponent > xBound(getPeer(), UNO_QUERY); 826 xBound->removeUpdateListener( &m_aUpdateListeners); 827 } 828 m_aUpdateListeners.removeInterface( l ); 829 } 830 831 //------------------------------------------------------------------------------ 832 sal_Bool SAL_CALL FmXGridControl::commit() throw( RuntimeException ) 833 { 834 Reference< XBoundComponent > xBound(getPeer(), UNO_QUERY); 835 if (xBound.is()) 836 return xBound->commit(); 837 else 838 return sal_True; 839 } 840 841 // XContainer 842 //------------------------------------------------------------------------------ 843 void SAL_CALL FmXGridControl::addContainerListener(const Reference< XContainerListener >& l) throw( RuntimeException ) 844 { 845 m_aContainerListeners.addInterface( l ); 846 if( getPeer().is() && m_aContainerListeners.getLength() == 1 ) 847 { 848 Reference< XContainer > xContainer(getPeer(), UNO_QUERY); 849 xContainer->addContainerListener( &m_aContainerListeners); 850 } 851 } 852 853 //------------------------------------------------------------------------------ 854 void SAL_CALL FmXGridControl::removeContainerListener(const Reference< XContainerListener >& l) throw( RuntimeException ) 855 { 856 if( getPeer().is() && m_aContainerListeners.getLength() == 1 ) 857 { 858 Reference< XContainer > xContainer(getPeer(), UNO_QUERY); 859 xContainer->removeContainerListener( &m_aContainerListeners); 860 } 861 m_aContainerListeners.removeInterface( l ); 862 } 863 864 //------------------------------------------------------------------------------ 865 Reference< ::com::sun::star::frame::XDispatch > SAL_CALL FmXGridControl::queryDispatch(const ::com::sun::star::util::URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags) throw( RuntimeException ) 866 { 867 Reference< ::com::sun::star::frame::XDispatchProvider > xPeerProvider(getPeer(), UNO_QUERY); 868 if (xPeerProvider.is()) 869 return xPeerProvider->queryDispatch(aURL, aTargetFrameName, nSearchFlags); 870 else 871 return Reference< ::com::sun::star::frame::XDispatch > (); 872 } 873 874 //------------------------------------------------------------------------------ 875 Sequence< Reference< ::com::sun::star::frame::XDispatch > > SAL_CALL FmXGridControl::queryDispatches(const Sequence< ::com::sun::star::frame::DispatchDescriptor>& aDescripts) throw( RuntimeException ) 876 { 877 Reference< ::com::sun::star::frame::XDispatchProvider > xPeerProvider(getPeer(), UNO_QUERY); 878 if (xPeerProvider.is()) 879 return xPeerProvider->queryDispatches(aDescripts); 880 else 881 return Sequence< Reference< ::com::sun::star::frame::XDispatch > >(); 882 } 883 884 //------------------------------------------------------------------------------ 885 void SAL_CALL FmXGridControl::registerDispatchProviderInterceptor(const Reference< ::com::sun::star::frame::XDispatchProviderInterceptor >& _xInterceptor) throw( RuntimeException ) 886 { 887 Reference< ::com::sun::star::frame::XDispatchProviderInterception > xPeerInterception(getPeer(), UNO_QUERY); 888 if (xPeerInterception.is()) 889 xPeerInterception->registerDispatchProviderInterceptor(_xInterceptor); 890 } 891 892 //------------------------------------------------------------------------------ 893 void SAL_CALL FmXGridControl::releaseDispatchProviderInterceptor(const Reference< ::com::sun::star::frame::XDispatchProviderInterceptor >& _xInterceptor) throw( RuntimeException ) 894 { 895 Reference< ::com::sun::star::frame::XDispatchProviderInterception > xPeerInterception(getPeer(), UNO_QUERY); 896 if (xPeerInterception.is()) 897 xPeerInterception->releaseDispatchProviderInterceptor(_xInterceptor); 898 } 899 900 //------------------------------------------------------------------------------ 901 void SAL_CALL FmXGridControl::addGridControlListener( const Reference< XGridControlListener >& _listener ) throw( RuntimeException ) 902 { 903 ::osl::MutexGuard aGuard( GetMutex() ); 904 905 m_aGridControlListeners.addInterface( _listener ); 906 if ( getPeer().is() && 1 == m_aGridControlListeners.getLength() ) 907 { 908 Reference< XGridControl > xPeerGrid( getPeer(), UNO_QUERY ); 909 if ( xPeerGrid.is() ) 910 xPeerGrid->addGridControlListener( &m_aGridControlListeners ); 911 } 912 } 913 914 //------------------------------------------------------------------------------ 915 void SAL_CALL FmXGridControl::removeGridControlListener( const Reference< XGridControlListener >& _listener ) throw( RuntimeException ) 916 { 917 ::osl::MutexGuard aGuard( GetMutex() ); 918 919 if( getPeer().is() && 1 == m_aGridControlListeners.getLength() ) 920 { 921 Reference< XGridControl > xPeerGrid( getPeer(), UNO_QUERY ); 922 if ( xPeerGrid.is() ) 923 xPeerGrid->removeGridControlListener( &m_aGridControlListeners ); 924 } 925 926 m_aGridControlListeners.removeInterface( _listener ); 927 } 928 929 //------------------------------------------------------------------------------ 930 sal_Int16 SAL_CALL FmXGridControl::getCurrentColumnPosition() throw( RuntimeException ) 931 { 932 Reference< XGridControl > xGrid( getPeer(), UNO_QUERY ); 933 return xGrid.is() ? xGrid->getCurrentColumnPosition() : -1; 934 } 935 936 //------------------------------------------------------------------------------ 937 void SAL_CALL FmXGridControl::setCurrentColumnPosition(sal_Int16 nPos) throw( RuntimeException ) 938 { 939 Reference< XGridControl > xGrid( getPeer(), UNO_QUERY ); 940 if ( xGrid.is() ) 941 { 942 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 943 xGrid->setCurrentColumnPosition( nPos ); 944 } 945 } 946 947 // XElementAccess 948 //------------------------------------------------------------------------------ 949 sal_Bool SAL_CALL FmXGridControl::hasElements() throw( RuntimeException ) 950 { 951 Reference< XElementAccess > xPeer(getPeer(), UNO_QUERY); 952 return xPeer.is() ? xPeer->hasElements() : 0; 953 } 954 955 //------------------------------------------------------------------------------ 956 Type SAL_CALL FmXGridControl::getElementType( ) throw(RuntimeException) 957 { 958 return ::getCppuType((const Reference< ::com::sun::star::awt::XTextComponent >*)NULL); 959 } 960 961 // XEnumerationAccess 962 //------------------------------------------------------------------------------ 963 Reference< XEnumeration > SAL_CALL FmXGridControl::createEnumeration() throw( RuntimeException ) 964 { 965 Reference< XEnumerationAccess > xPeer(getPeer(), UNO_QUERY); 966 if (xPeer.is()) 967 return xPeer->createEnumeration(); 968 else 969 return new ::comphelper::OEnumerationByIndex(this); 970 } 971 972 // XIndexAccess 973 //------------------------------------------------------------------------------ 974 sal_Int32 SAL_CALL FmXGridControl::getCount() throw( RuntimeException ) 975 { 976 Reference< XIndexAccess > xPeer(getPeer(), UNO_QUERY); 977 return xPeer.is() ? xPeer->getCount() : 0; 978 } 979 980 //------------------------------------------------------------------------------ 981 Any SAL_CALL FmXGridControl::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 982 { 983 Reference< XIndexAccess > xPeer(getPeer(), UNO_QUERY); 984 if (!xPeer.is()) 985 throw IndexOutOfBoundsException(); 986 987 return xPeer->getByIndex(_nIndex); 988 } 989 990 // ::com::sun::star::util::XModeSelector 991 //------------------------------------------------------------------------------ 992 void SAL_CALL FmXGridControl::setMode(const ::rtl::OUString& Mode) throw( NoSupportException, RuntimeException ) 993 { 994 Reference< ::com::sun::star::util::XModeSelector > xPeer(getPeer(), UNO_QUERY); 995 if (!xPeer.is()) 996 throw NoSupportException(); 997 998 xPeer->setMode(Mode); 999 } 1000 1001 //------------------------------------------------------------------------------ 1002 ::rtl::OUString SAL_CALL FmXGridControl::getMode() throw( RuntimeException ) 1003 { 1004 Reference< ::com::sun::star::util::XModeSelector > xPeer(getPeer(), UNO_QUERY); 1005 return xPeer.is() ? xPeer->getMode() : ::rtl::OUString(); 1006 } 1007 1008 //------------------------------------------------------------------------------ 1009 ::comphelper::StringSequence SAL_CALL FmXGridControl::getSupportedModes() throw( RuntimeException ) 1010 { 1011 Reference< ::com::sun::star::util::XModeSelector > xPeer(getPeer(), UNO_QUERY); 1012 return xPeer.is() ? xPeer->getSupportedModes() : ::comphelper::StringSequence(); 1013 } 1014 1015 //------------------------------------------------------------------------------ 1016 sal_Bool SAL_CALL FmXGridControl::supportsMode(const ::rtl::OUString& Mode) throw( RuntimeException ) 1017 { 1018 Reference< ::com::sun::star::util::XModeSelector > xPeer(getPeer(), UNO_QUERY); 1019 return xPeer.is() ? xPeer->supportsMode(Mode) : sal_False; 1020 } 1021 1022 //============================================================================== 1023 //= FmXGridPeer 1024 //============================================================================== 1025 // helper class which prevents that in the peer's header the FmGridListener must be known 1026 class FmXGridPeer::GridListenerDelegator : public FmGridListener 1027 { 1028 protected: 1029 FmXGridPeer* m_pPeer; 1030 1031 public: 1032 GridListenerDelegator( FmXGridPeer* _pPeer ); 1033 1034 protected: 1035 virtual void selectionChanged(); 1036 virtual void columnChanged(); 1037 }; 1038 1039 //------------------------------------------------------------------ 1040 FmXGridPeer::GridListenerDelegator::GridListenerDelegator(FmXGridPeer* _pPeer) 1041 :m_pPeer(_pPeer) 1042 { 1043 DBG_ASSERT(m_pPeer, "GridListenerDelegator::GridListenerDelegator"); 1044 } 1045 1046 //------------------------------------------------------------------ 1047 void FmXGridPeer::GridListenerDelegator::selectionChanged() 1048 { 1049 m_pPeer->selectionChanged(); 1050 } 1051 1052 //------------------------------------------------------------------ 1053 void FmXGridPeer::GridListenerDelegator::columnChanged() 1054 { 1055 m_pPeer->columnChanged(); 1056 } 1057 1058 //============================================================================== 1059 //------------------------------------------------------------------ 1060 Reference< XInterface > FmXGridPeer_CreateInstance(const Reference< XMultiServiceFactory>& _rxFactory) 1061 { 1062 FmXGridPeer* pNewObject = new FmXGridPeer(_rxFactory); 1063 pNewObject->Create(NULL, WB_TABSTOP); 1064 return *pNewObject; 1065 } 1066 1067 //------------------------------------------------------------------ 1068 Sequence< Type> SAL_CALL FmXGridPeer::getTypes( ) throw(RuntimeException) 1069 { 1070 return comphelper::concatSequences( VCLXWindow::getTypes(), FmXGridPeer_BASE::getTypes() ); 1071 } 1072 1073 //------------------------------------------------------------------ 1074 Sequence<sal_Int8> SAL_CALL FmXGridPeer::getImplementationId( ) throw(RuntimeException) 1075 { 1076 static ::cppu::OImplementationId* pId = 0; 1077 if (! pId) 1078 { 1079 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 1080 if (! pId) 1081 { 1082 static ::cppu::OImplementationId aId; 1083 pId = &aId; 1084 } 1085 } 1086 return pId->getImplementationId(); 1087 } 1088 1089 //------------------------------------------------------------------ 1090 Any SAL_CALL FmXGridPeer::queryInterface(const Type& _rType) throw (RuntimeException) 1091 { 1092 Any aReturn = FmXGridPeer_BASE::queryInterface(_rType); 1093 1094 if (!aReturn.hasValue()) 1095 aReturn = VCLXWindow::queryInterface( _rType ); 1096 1097 return aReturn; 1098 } 1099 1100 //------------------------------------------------------------------ 1101 void FmXGridPeer::selectionChanged() 1102 { 1103 EventObject aSource; 1104 aSource.Source = static_cast< ::cppu::OWeakObject* >(this); 1105 m_aSelectionListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aSource); 1106 } 1107 1108 //------------------------------------------------------------------ 1109 void FmXGridPeer::columnChanged() 1110 { 1111 EventObject aEvent( *this ); 1112 m_aGridControlListeners.notifyEach( &XGridControlListener::columnChanged, aEvent ); 1113 } 1114 1115 //------------------------------------------------------------------ 1116 namespace fmgridif 1117 { 1118 const ::rtl::OUString getDataModeIdentifier() 1119 { 1120 static ::rtl::OUString s_sDataModeIdentifier = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DataMode" ) ); 1121 return s_sDataModeIdentifier; 1122 } 1123 } 1124 using namespace fmgridif; 1125 1126 //------------------------------------------------------------------ 1127 FmXGridPeer::FmXGridPeer(const Reference< XMultiServiceFactory >& _rxFactory) 1128 :m_aModifyListeners(m_aMutex) 1129 ,m_aUpdateListeners(m_aMutex) 1130 ,m_aContainerListeners(m_aMutex) 1131 ,m_aSelectionListeners(m_aMutex) 1132 ,m_aGridControlListeners(m_aMutex) 1133 ,m_aMode( getDataModeIdentifier() ) 1134 ,m_nCursorListening(0) 1135 ,m_bInterceptingDispatch(sal_False) 1136 ,m_pStateCache(NULL) 1137 ,m_pDispatchers(NULL) 1138 ,m_pGridListener(NULL) 1139 ,m_xServiceFactory(_rxFactory) 1140 { 1141 // nach diesem Constructor muss Create gerufen werden ! 1142 m_pGridListener = new GridListenerDelegator( this ); 1143 } 1144 1145 //------------------------------------------------------------------------------ 1146 FmGridControl* FmXGridPeer::imp_CreateControl(Window* pParent, WinBits nStyle) 1147 { 1148 return new FmGridControl(m_xServiceFactory, pParent, this, nStyle); 1149 } 1150 1151 //------------------------------------------------------------------------------ 1152 void FmXGridPeer::Create(Window* pParent, WinBits nStyle) 1153 { 1154 FmGridControl* pWin = imp_CreateControl(pParent, nStyle); 1155 DBG_ASSERT(pWin != NULL, "FmXGridPeer::Create : imp_CreateControl didn't return a control !"); 1156 1157 pWin->SetStateProvider(LINK(this, FmXGridPeer, OnQueryGridSlotState)); 1158 pWin->SetSlotExecutor(LINK(this, FmXGridPeer, OnExecuteGridSlot)); 1159 1160 // want to hear about row selections 1161 pWin->setGridListener( m_pGridListener ); 1162 1163 // Init mu� immer aufgerufen werden 1164 pWin->Init(); 1165 pWin->SetComponentInterface(this); 1166 1167 getSupportedURLs(); 1168 } 1169 1170 //------------------------------------------------------------------------------ 1171 FmXGridPeer::~FmXGridPeer() 1172 { 1173 setRowSet(Reference< XRowSet > ()); 1174 setColumns(Reference< XIndexContainer > ()); 1175 1176 delete m_pGridListener; 1177 } 1178 1179 //------------------------------------------------------------------------------ 1180 const Sequence< sal_Int8 >& FmXGridPeer::getUnoTunnelImplementationId() throw() 1181 { 1182 static Sequence< sal_Int8 > * pSeq = 0; 1183 if( !pSeq ) 1184 { 1185 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 1186 if( !pSeq ) 1187 { 1188 static Sequence< sal_Int8 > aSeq( 16 ); 1189 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); 1190 pSeq = &aSeq; 1191 } 1192 } 1193 return *pSeq; 1194 } 1195 1196 //------------------------------------------------------------------------------ 1197 FmXGridPeer* FmXGridPeer::getImplementation( const Reference< XInterface >& _rxIFace ) throw() 1198 { 1199 FmXGridPeer* pReturn = NULL; 1200 Reference< XUnoTunnel > xTunnel(_rxIFace, UNO_QUERY); 1201 if (xTunnel.is()) 1202 pReturn = reinterpret_cast<FmXGridPeer*>(xTunnel->getSomething(getUnoTunnelImplementationId())); 1203 1204 return pReturn; 1205 } 1206 1207 //------------------------------------------------------------------------------ 1208 sal_Int64 SAL_CALL FmXGridPeer::getSomething( const Sequence< sal_Int8 >& _rIdentifier ) throw(RuntimeException) 1209 { 1210 sal_Int64 nReturn(0); 1211 1212 if ( (_rIdentifier.getLength() == 16) 1213 && (0 == rtl_compareMemory( getUnoTunnelImplementationId().getConstArray(), _rIdentifier.getConstArray(), 16 )) 1214 ) 1215 { 1216 nReturn = reinterpret_cast<sal_Int64>(this); 1217 } 1218 else 1219 nReturn = VCLXWindow::getSomething(_rIdentifier); 1220 1221 return nReturn; 1222 } 1223 1224 // XEventListener 1225 //------------------------------------------------------------------------------ 1226 void FmXGridPeer::disposing(const EventObject& e) throw( RuntimeException ) 1227 { 1228 using namespace ::com::sun::star::util; 1229 bool bKnownSender = false; 1230 1231 Reference< XIndexContainer > xCols( e.Source, UNO_QUERY ); 1232 if ( xCols.is() ) 1233 { 1234 setColumns(Reference< XIndexContainer > ()); 1235 bKnownSender = true; 1236 } 1237 1238 Reference< XRowSet > xCursor(e.Source, UNO_QUERY); 1239 if (xCursor.is()) 1240 { 1241 setRowSet( m_xCursor ); 1242 m_xCursor = NULL; 1243 bKnownSender = true; 1244 } 1245 1246 1247 if ( !bKnownSender && m_pDispatchers ) 1248 { 1249 const Sequence< URL>& aSupportedURLs = getSupportedURLs(); 1250 const URL* pSupportedURLs = aSupportedURLs.getConstArray(); 1251 for ( sal_uInt16 i=0; i < ( aSupportedURLs.getLength() ) && !bKnownSender; ++i, ++pSupportedURLs ) 1252 { 1253 if ( m_pDispatchers[i] == e.Source ) 1254 { 1255 m_pDispatchers[i]->removeStatusListener( static_cast< ::com::sun::star::frame::XStatusListener* >( this ), *pSupportedURLs ); 1256 m_pDispatchers[i] = NULL; 1257 m_pStateCache[i] = 0; 1258 bKnownSender = true; 1259 } 1260 } 1261 } 1262 1263 if ( !bKnownSender ) 1264 VCLXWindow::disposing(e); 1265 } 1266 1267 //------------------------------------------------------------------------------ 1268 void FmXGridPeer::addModifyListener(const Reference< ::com::sun::star::util::XModifyListener >& l) throw( RuntimeException ) 1269 { 1270 m_aModifyListeners.addInterface( l ); 1271 } 1272 1273 //------------------------------------------------------------------------------ 1274 void FmXGridPeer::removeModifyListener(const Reference< ::com::sun::star::util::XModifyListener >& l) throw( RuntimeException ) 1275 { 1276 m_aModifyListeners.removeInterface( l ); 1277 } 1278 1279 //------------------------------------------------------------------------------ 1280 #define LAST_KNOWN_TYPE FormComponentType::PATTERNFIELD 1281 Sequence< sal_Bool > SAL_CALL FmXGridPeer::queryFieldDataType( const Type& xType ) throw(RuntimeException) 1282 { 1283 // eine 'Konvertierungstabelle' 1284 static sal_Bool bCanConvert[LAST_KNOWN_TYPE][4] = 1285 { 1286 { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::CONTROL 1287 { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::COMMANDBUTTON 1288 { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::RADIOBUTTON 1289 { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::IMAGEBUTTON 1290 { sal_False, sal_False, sal_False, sal_True }, // FormComponentType::CHECKBOX 1291 { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::LISTBOX 1292 { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::COMBOBOX 1293 { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::GROUPBOX 1294 { sal_True , sal_False, sal_False, sal_False }, // FormComponentType::TEXTFIELD 1295 { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::FIXEDTEXT 1296 { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::GRIDCONTROL 1297 { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::FILECONTROL 1298 { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::HIDDENCONTROL 1299 { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::IMAGECONTROL 1300 { sal_True , sal_True , sal_True , sal_False }, // FormComponentType::DATEFIELD 1301 { sal_True , sal_True , sal_False, sal_False }, // FormComponentType::TIMEFIELD 1302 { sal_True , sal_True , sal_False, sal_False }, // FormComponentType::NUMERICFIELD 1303 { sal_True , sal_True , sal_False, sal_False }, // FormComponentType::CURRENCYFIELD 1304 { sal_True , sal_False, sal_False, sal_False } // FormComponentType::PATTERNFIELD 1305 }; 1306 1307 1308 sal_Int16 nMapColumn = -1; 1309 switch (xType.getTypeClass()) 1310 { 1311 case TypeClass_STRING : nMapColumn = 0; break; 1312 case TypeClass_FLOAT: 1313 case TypeClass_DOUBLE : nMapColumn = 1; break; 1314 case TypeClass_SHORT: 1315 case TypeClass_LONG: 1316 case TypeClass_UNSIGNED_LONG: 1317 case TypeClass_UNSIGNED_SHORT : nMapColumn = 2; break; 1318 case TypeClass_BOOLEAN : nMapColumn = 3; break; 1319 default: 1320 break; 1321 } 1322 1323 Reference< XIndexContainer > xColumns = getColumns(); 1324 1325 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 1326 sal_Int32 nColumns = pGrid->GetViewColCount(); 1327 1328 DbGridColumns aColumns = pGrid->GetColumns(); 1329 1330 Sequence<sal_Bool> aReturnSequence(nColumns); 1331 sal_Bool* pReturnArray = aReturnSequence.getArray(); 1332 1333 sal_Bool bRequestedAsAny = (xType.getTypeClass() == TypeClass_ANY); 1334 1335 DbGridColumn* pCol; 1336 Reference< ::com::sun::star::sdb::XColumn > xFieldContent; 1337 Reference< XPropertySet > xCurrentColumn; 1338 for (sal_Int32 i=0; i<nColumns; ++i) 1339 { 1340 if (bRequestedAsAny) 1341 { 1342 pReturnArray[i] = sal_True; 1343 continue; 1344 } 1345 1346 pReturnArray[i] = sal_False; 1347 1348 sal_uInt16 nModelPos = pGrid->GetModelColumnPos(pGrid->GetColumnIdFromViewPos((sal_uInt16)i)); 1349 DBG_ASSERT(nModelPos != (sal_uInt16)-1, "FmXGridPeer::queryFieldDataType : no model pos !"); 1350 1351 pCol = aColumns.GetObject(nModelPos); 1352 const DbGridRowRef xRow = pGrid->GetSeekRow(); 1353 xFieldContent = (xRow.Is() && xRow->HasField(pCol->GetFieldPos())) ? xRow->GetField(pCol->GetFieldPos()).getColumn() : Reference< ::com::sun::star::sdb::XColumn > (); 1354 if (!xFieldContent.is()) 1355 // can't supply anything without a field content 1356 // FS - 07.12.99 - 54391 1357 continue; 1358 1359 xColumns->getByIndex(nModelPos) >>= xCurrentColumn; 1360 if (!::comphelper::hasProperty(FM_PROP_CLASSID, xCurrentColumn)) 1361 continue; 1362 1363 sal_Int16 nClassId = sal_Int16(); 1364 xCurrentColumn->getPropertyValue(FM_PROP_CLASSID) >>= nClassId; 1365 if (nClassId>LAST_KNOWN_TYPE) 1366 continue; 1367 DBG_ASSERT(nClassId>0, "FmXGridPeer::queryFieldDataType : somebody changed the definition of the FormComponentType enum !"); 1368 1369 if (nMapColumn != -1) 1370 pReturnArray[i] = bCanConvert[nClassId-1][nMapColumn]; 1371 } 1372 1373 return aReturnSequence; 1374 } 1375 1376 //------------------------------------------------------------------------------ 1377 Sequence< Any > SAL_CALL FmXGridPeer::queryFieldData( sal_Int32 nRow, const Type& xType ) throw(RuntimeException) 1378 { 1379 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 1380 DBG_ASSERT(pGrid && pGrid->IsOpen(), "FmXGridPeer::queryFieldData : have no valid grid window !"); 1381 if (!pGrid || !pGrid->IsOpen()) 1382 return Sequence< Any>(); 1383 1384 // das Control zur angegebenen Row fahren 1385 if (!pGrid->SeekRow(nRow)) 1386 { 1387 throw IllegalArgumentException(); 1388 } 1389 1390 // don't use GetCurrentRow as this isn't affected by the above SeekRow 1391 // FS - 30.09.99 - 68644 1392 DbGridRowRef xPaintRow = pGrid->GetPaintRow(); 1393 ENSURE_OR_THROW( xPaintRow.Is(), "invalid paint row" ); 1394 1395 // die Columns des Controls brauche ich fuer GetFieldText 1396 DbGridColumns aColumns = pGrid->GetColumns(); 1397 1398 // und durch alle Spalten durch 1399 sal_Int32 nColumnCount = pGrid->GetViewColCount(); 1400 1401 Sequence< Any> aReturnSequence(nColumnCount); 1402 Any* pReturnArray = aReturnSequence.getArray(); 1403 1404 sal_Bool bRequestedAsAny = (xType.getTypeClass() == TypeClass_ANY); 1405 Reference< ::com::sun::star::sdb::XColumn > xFieldContent; 1406 DbGridColumn* pCol; 1407 for (sal_Int32 i=0; i < nColumnCount; ++i) 1408 { 1409 sal_uInt16 nModelPos = pGrid->GetModelColumnPos(pGrid->GetColumnIdFromViewPos((sal_uInt16)i)); 1410 DBG_ASSERT(nModelPos != (sal_uInt16)-1, "FmXGridPeer::queryFieldData : invalid model pos !"); 1411 1412 // don't use GetCurrentFieldValue to determine the field content as this isn't affected by the above SeekRow 1413 // FS - 30.09.99 - 68644 1414 pCol = aColumns.GetObject(nModelPos); 1415 xFieldContent = xPaintRow->HasField( pCol->GetFieldPos() ) 1416 ? xPaintRow->GetField( pCol->GetFieldPos() ).getColumn() 1417 : Reference< XColumn > (); 1418 1419 if ( !xFieldContent.is() ) 1420 continue; 1421 1422 if (bRequestedAsAny) 1423 { 1424 Reference< XPropertySet > xFieldSet(xFieldContent, UNO_QUERY); 1425 pReturnArray[i] = xFieldSet->getPropertyValue(FM_PROP_VALUE); 1426 } 1427 else 1428 { 1429 switch (xType.getTypeClass()) 1430 { 1431 // Strings werden direkt ueber das GetFieldText abgehandelt 1432 case TypeClass_STRING : 1433 { 1434 String sText = aColumns.GetObject(nModelPos)->GetCellText( xPaintRow, pGrid->getNumberFormatter() ); 1435 pReturnArray[i] <<= ::rtl::OUString(sText); 1436 } 1437 break; 1438 // alles andere wird an der DatabaseVariant erfragt 1439 case TypeClass_FLOAT : pReturnArray[i] <<= xFieldContent->getFloat(); break; 1440 case TypeClass_DOUBLE : pReturnArray[i] <<= xFieldContent->getDouble(); break; 1441 case TypeClass_SHORT : pReturnArray[i] <<= (sal_Int16)xFieldContent->getShort(); break; 1442 case TypeClass_LONG : pReturnArray[i] <<= (sal_Int32)xFieldContent->getLong(); break; 1443 case TypeClass_UNSIGNED_SHORT : pReturnArray[i] <<= (sal_uInt16)xFieldContent->getShort(); break; 1444 case TypeClass_UNSIGNED_LONG : pReturnArray[i] <<= (sal_uInt32)xFieldContent->getLong(); break; 1445 case TypeClass_BOOLEAN : ::comphelper::setBOOL(pReturnArray[i],xFieldContent->getBoolean()); break; 1446 default: 1447 { 1448 throw IllegalArgumentException(); 1449 } 1450 } 1451 } 1452 } 1453 return aReturnSequence; 1454 } 1455 1456 //------------------------------------------------------------------------------ 1457 void FmXGridPeer::CellModified() 1458 { 1459 EventObject aEvt; 1460 aEvt.Source = static_cast< ::cppu::OWeakObject* >(this); 1461 m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvt ); 1462 } 1463 1464 // XPropertyChangeListener 1465 //------------------------------------------------------------------------------ 1466 void FmXGridPeer::propertyChange(const PropertyChangeEvent& evt) throw( RuntimeException ) 1467 { 1468 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1469 // want to do a lot of VCL stuff here ... 1470 // this should not be (deadlock) critical, as by definition, every component should release 1471 // any own mutexes before notifying 1472 1473 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 1474 if (!pGrid) 1475 return; 1476 1477 // DatenbankEvent 1478 Reference< XRowSet > xCursor(evt.Source, UNO_QUERY); 1479 if (evt.PropertyName == FM_PROP_VALUE || m_xCursor == evt.Source) 1480 pGrid->propertyChange(evt); 1481 else if (pGrid && m_xColumns.is() && m_xColumns->hasElements()) 1482 { 1483 // zunaechst raussuchen welche Column sich geaendert hat 1484 ::comphelper::InterfaceRef xCurrent; 1485 sal_Int32 i; 1486 1487 for ( i = 0; i < m_xColumns->getCount(); i++) 1488 { 1489 ::cppu::extractInterface(xCurrent, m_xColumns->getByIndex(i)); 1490 if (evt.Source == xCurrent) 1491 break; 1492 } 1493 1494 if (i >= m_xColumns->getCount()) 1495 // this is valid because we are listening at the cursor, too (RecordCount, -status, edit mode) 1496 return; 1497 1498 sal_uInt16 nId = pGrid->GetColumnIdFromModelPos((sal_uInt16)i); 1499 sal_Bool bInvalidateColumn = sal_False; 1500 1501 if (evt.PropertyName == FM_PROP_LABEL) 1502 { 1503 String aName = ::comphelper::getString(evt.NewValue); 1504 if (aName != pGrid->GetColumnTitle(nId)) 1505 pGrid->SetColumnTitle(nId, aName); 1506 } 1507 else if (evt.PropertyName == FM_PROP_WIDTH) 1508 { 1509 sal_Int32 nWidth = 0; 1510 if (evt.NewValue.getValueType().getTypeClass() == TypeClass_VOID) 1511 nWidth = pGrid->GetDefaultColumnWidth(pGrid->GetColumnTitle(nId)); 1512 // GetDefaultColumnWidth already considerd the zoom factor 1513 else 1514 { 1515 sal_Int32 nTest = 0; 1516 if (evt.NewValue >>= nTest) 1517 { 1518 nWidth = pGrid->LogicToPixel(Point(nTest,0),MAP_10TH_MM).X(); 1519 // take the zoom factor into account 1520 nWidth = pGrid->CalcZoom(nWidth); 1521 } 1522 } 1523 if (nWidth != (sal_Int32(pGrid->GetColumnWidth(nId)))) 1524 { 1525 if (pGrid->IsEditing()) 1526 { 1527 pGrid->DeactivateCell(); 1528 pGrid->ActivateCell(); 1529 } 1530 pGrid->SetColumnWidth(nId, nWidth); 1531 } 1532 } 1533 else if (evt.PropertyName == FM_PROP_HIDDEN) 1534 { 1535 DBG_ASSERT(evt.NewValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, 1536 "FmXGridPeer::propertyChange : the property 'hidden' should be of type boolean !"); 1537 if (::comphelper::getBOOL(evt.NewValue)) 1538 pGrid->HideColumn(nId); 1539 else 1540 pGrid->ShowColumn(nId); 1541 } 1542 else if (evt.PropertyName == FM_PROP_ALIGN) 1543 { 1544 // it design mode it doesn't matter 1545 if (!isDesignMode()) 1546 { 1547 DbGridColumn* pCol = pGrid->GetColumns().GetObject(i); 1548 1549 pCol->SetAlignmentFromModel(-1); 1550 bInvalidateColumn = sal_True; 1551 } 1552 } 1553 else if (evt.PropertyName == FM_PROP_FORMATKEY) 1554 { 1555 if (!isDesignMode()) 1556 bInvalidateColumn = sal_True; 1557 } 1558 1559 // need to invalidate the affected column ? 1560 if (bInvalidateColumn) 1561 { 1562 sal_Bool bWasEditing = pGrid->IsEditing(); 1563 if (bWasEditing) 1564 pGrid->DeactivateCell(); 1565 1566 ::Rectangle aColRect = pGrid->GetFieldRect(nId); 1567 aColRect.Top() = 0; 1568 aColRect.Bottom() = pGrid->GetSizePixel().Height(); 1569 pGrid->Invalidate(aColRect); 1570 1571 if (bWasEditing) 1572 pGrid->ActivateCell(); 1573 } 1574 } 1575 } 1576 1577 // XBoundComponent 1578 //------------------------------------------------------------------------------ 1579 void FmXGridPeer::addUpdateListener(const Reference< XUpdateListener >& l) throw( RuntimeException ) 1580 { 1581 m_aUpdateListeners.addInterface(l); 1582 } 1583 1584 //------------------------------------------------------------------------------ 1585 void FmXGridPeer::removeUpdateListener(const Reference< XUpdateListener >& l) throw( RuntimeException ) 1586 { 1587 m_aUpdateListeners.removeInterface(l); 1588 } 1589 1590 //------------------------------------------------------------------------------ 1591 sal_Bool FmXGridPeer::commit() throw( RuntimeException ) 1592 { 1593 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 1594 if (!m_xCursor.is() || !pGrid) 1595 return sal_True; 1596 1597 EventObject aEvt(static_cast< ::cppu::OWeakObject* >(this)); 1598 ::cppu::OInterfaceIteratorHelper aIter(m_aUpdateListeners); 1599 sal_Bool bCancel = sal_False; 1600 while (aIter.hasMoreElements() && !bCancel) 1601 if ( !static_cast< XUpdateListener* >( aIter.next() )->approveUpdate( aEvt ) ) 1602 bCancel = sal_True; 1603 1604 if (!bCancel) 1605 bCancel = !pGrid->commit(); 1606 1607 if (!bCancel) 1608 m_aUpdateListeners.notifyEach( &XUpdateListener::updated, aEvt ); 1609 return !bCancel; 1610 } 1611 1612 1613 //------------------------------------------------------------------------------ 1614 void FmXGridPeer::cursorMoved(const EventObject& _rEvent) throw( RuntimeException ) 1615 { 1616 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 1617 // we are not interested in move to insert row only in the resetted event 1618 // which is fired after positioning an the insert row 1619 if (pGrid && pGrid->IsOpen() && !::comphelper::getBOOL(Reference< XPropertySet > (_rEvent.Source, UNO_QUERY)->getPropertyValue(FM_PROP_ISNEW))) 1620 pGrid->positioned(_rEvent); 1621 } 1622 1623 //------------------------------------------------------------------------------ 1624 void FmXGridPeer::rowChanged(const EventObject& _rEvent) throw( RuntimeException ) 1625 { 1626 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 1627 if (pGrid && pGrid->IsOpen()) 1628 { 1629 if (m_xCursor->rowUpdated() && !pGrid->IsCurrentAppending()) 1630 pGrid->RowModified(pGrid->GetCurrentPos()); 1631 else if (m_xCursor->rowInserted()) 1632 pGrid->inserted(_rEvent); 1633 } 1634 } 1635 1636 //------------------------------------------------------------------------------ 1637 void FmXGridPeer::rowSetChanged(const EventObject& /*event*/) throw( RuntimeException ) 1638 { 1639 // not interested in ... 1640 // (our parent is a form which means we get a loaded or reloaded after this rowSetChanged) 1641 } 1642 1643 // XLoadListener 1644 //------------------------------------------------------------------------------ 1645 void FmXGridPeer::loaded(const EventObject& /*rEvent*/) throw( RuntimeException ) 1646 { 1647 updateGrid(m_xCursor); 1648 } 1649 1650 //------------------------------------------------------------------------------ 1651 void FmXGridPeer::unloaded(const EventObject& /*rEvent*/) throw( RuntimeException ) 1652 { 1653 updateGrid( Reference< XRowSet > (NULL) ); 1654 } 1655 1656 //------------------------------------------------------------------------------ 1657 void FmXGridPeer::reloading(const EventObject& /*aEvent*/) throw( RuntimeException ) 1658 { 1659 // empty the grid 1660 updateGrid( Reference< XRowSet > (NULL) ); 1661 } 1662 1663 //------------------------------------------------------------------------------ 1664 void FmXGridPeer::unloading(const EventObject& /*aEvent*/) throw( RuntimeException ) 1665 { 1666 // empty the grid 1667 updateGrid( Reference< XRowSet > (NULL) ); 1668 } 1669 1670 //------------------------------------------------------------------------------ 1671 void FmXGridPeer::reloaded(const EventObject& /*aEvent*/) throw( RuntimeException ) 1672 { 1673 updateGrid(m_xCursor); 1674 } 1675 1676 // XGridPeer 1677 //------------------------------------------------------------------------------ 1678 Reference< XIndexContainer > FmXGridPeer::getColumns() throw( RuntimeException ) 1679 { 1680 return m_xColumns; 1681 } 1682 1683 //------------------------------------------------------------------------------ 1684 void FmXGridPeer::addColumnListeners(const Reference< XPropertySet >& xCol) 1685 { 1686 static const ::rtl::OUString aPropsListenedTo[] = 1687 { 1688 FM_PROP_LABEL, FM_PROP_WIDTH, FM_PROP_HIDDEN, FM_PROP_ALIGN, FM_PROP_FORMATKEY 1689 }; 1690 1691 // as not all properties have to be supported by all columns we have to check this 1692 // before adding a listener 1693 Reference< XPropertySetInfo > xInfo = xCol->getPropertySetInfo(); 1694 Property aPropDesc; 1695 const ::rtl::OUString* pProps = aPropsListenedTo; 1696 const ::rtl::OUString* pPropsEnd = pProps + sizeof( aPropsListenedTo ) / sizeof( aPropsListenedTo[ 0 ] ); 1697 for (; pProps != pPropsEnd; ++pProps) 1698 { 1699 if ( xInfo->hasPropertyByName( *pProps ) ) 1700 { 1701 aPropDesc = xInfo->getPropertyByName( *pProps ); 1702 if ( 0 != ( aPropDesc.Attributes & PropertyAttribute::BOUND ) ) 1703 xCol->addPropertyChangeListener( *pProps, this ); 1704 } 1705 } 1706 } 1707 1708 //------------------------------------------------------------------------------ 1709 void FmXGridPeer::removeColumnListeners(const Reference< XPropertySet >& xCol) 1710 { 1711 // the same props as in addColumnListeners ... linux has problems with global static UStrings, so 1712 // we have to do it this way .... 1713 static ::rtl::OUString aPropsListenedTo[] = 1714 { 1715 FM_PROP_LABEL, FM_PROP_WIDTH, FM_PROP_HIDDEN, FM_PROP_ALIGN, FM_PROP_FORMATKEY 1716 }; 1717 1718 Reference< XPropertySetInfo > xInfo = xCol->getPropertySetInfo(); 1719 for (sal_uInt16 i=0; i<sizeof(aPropsListenedTo)/sizeof(aPropsListenedTo[0]); ++i) 1720 if (xInfo->hasPropertyByName(aPropsListenedTo[i])) 1721 xCol->removePropertyChangeListener(aPropsListenedTo[i], this); 1722 } 1723 1724 //------------------------------------------------------------------------------ 1725 void FmXGridPeer::setColumns(const Reference< XIndexContainer >& Columns) throw( RuntimeException ) 1726 { 1727 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1728 1729 FmGridControl* pGrid = static_cast< FmGridControl* >( GetWindow() ); 1730 1731 if (m_xColumns.is()) 1732 { 1733 Reference< XPropertySet > xCol; 1734 for (sal_Int32 i = 0; i < m_xColumns->getCount(); i++) 1735 { 1736 ::cppu::extractInterface(xCol, m_xColumns->getByIndex(i)); 1737 removeColumnListeners(xCol); 1738 } 1739 Reference< XContainer > xContainer(m_xColumns, UNO_QUERY); 1740 xContainer->removeContainerListener(this); 1741 1742 Reference< XSelectionSupplier > xSelSupplier(m_xColumns, UNO_QUERY); 1743 xSelSupplier->removeSelectionChangeListener(this); 1744 1745 Reference< XReset > xColumnReset(m_xColumns, UNO_QUERY); 1746 if (xColumnReset.is()) 1747 xColumnReset->removeResetListener((XResetListener*)this); 1748 } 1749 if (Columns.is()) 1750 { 1751 Reference< XContainer > xContainer(Columns, UNO_QUERY); 1752 xContainer->addContainerListener(this); 1753 1754 Reference< XSelectionSupplier > xSelSupplier(Columns, UNO_QUERY); 1755 xSelSupplier->addSelectionChangeListener(this); 1756 1757 Reference< XPropertySet > xCol; 1758 for (sal_Int32 i = 0; i < Columns->getCount(); i++) 1759 { 1760 ::cppu::extractInterface(xCol, Columns->getByIndex(i)); 1761 addColumnListeners(xCol); 1762 } 1763 1764 Reference< XReset > xColumnReset(Columns, UNO_QUERY); 1765 if (xColumnReset.is()) 1766 xColumnReset->addResetListener((XResetListener*)this); 1767 } 1768 m_xColumns = Columns; 1769 if (pGrid) 1770 { 1771 pGrid->InitColumnsByModels(m_xColumns); 1772 1773 if (m_xColumns.is()) 1774 { 1775 EventObject aEvt(m_xColumns); 1776 selectionChanged(aEvt); 1777 } 1778 } 1779 } 1780 1781 //------------------------------------------------------------------------------ 1782 void FmXGridPeer::setDesignMode(sal_Bool bOn) throw( RuntimeException ) 1783 { 1784 if (bOn != isDesignMode()) 1785 { 1786 Window* pWin = GetWindow(); 1787 if (pWin) 1788 ((FmGridControl*) pWin)->SetDesignMode(bOn); 1789 } 1790 1791 if (bOn) 1792 DisConnectFromDispatcher(); 1793 else 1794 UpdateDispatches(); // will connect if not already connected and just update else 1795 } 1796 1797 //------------------------------------------------------------------------------ 1798 sal_Bool FmXGridPeer::isDesignMode() throw( RuntimeException ) 1799 { 1800 Window* pWin = GetWindow(); 1801 if (pWin) 1802 return ((FmGridControl*) pWin)->IsDesignMode(); 1803 else 1804 return sal_False; 1805 } 1806 1807 //------------------------------------------------------------------------------ 1808 void FmXGridPeer::elementInserted(const ContainerEvent& evt) throw( RuntimeException ) 1809 { 1810 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1811 1812 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 1813 // Handle Column beruecksichtigen 1814 if (!pGrid || !m_xColumns.is() || pGrid->IsInColumnMove() || m_xColumns->getCount() == ((sal_Int32)pGrid->GetModelColCount())) 1815 return; 1816 1817 Reference< XPropertySet > xSet; 1818 ::cppu::extractInterface(xSet, evt.Element); 1819 addColumnListeners(xSet); 1820 1821 Reference< XPropertySet > xNewColumn(xSet); 1822 String aName = ::comphelper::getString(xNewColumn->getPropertyValue(FM_PROP_LABEL)); 1823 Any aWidth = xNewColumn->getPropertyValue(FM_PROP_WIDTH); 1824 sal_Int32 nWidth = 0; 1825 if (aWidth >>= nWidth) 1826 nWidth = pGrid->LogicToPixel(Point(nWidth,0),MAP_10TH_MM).X(); 1827 1828 pGrid->AppendColumn(aName, (sal_uInt16)nWidth, (sal_Int16)::comphelper::getINT32(evt.Accessor)); 1829 1830 // jetzt die Spalte setzen 1831 DbGridColumn* pCol = pGrid->GetColumns().GetObject(::comphelper::getINT32(evt.Accessor)); 1832 pCol->setModel(xNewColumn); 1833 1834 Any aHidden = xNewColumn->getPropertyValue(FM_PROP_HIDDEN); 1835 if (::comphelper::getBOOL(aHidden)) 1836 pGrid->HideColumn(pCol->GetId()); 1837 1838 FormControlFactory( m_xServiceFactory ).initializeTextFieldLineEnds( xNewColumn ); 1839 } 1840 1841 //------------------------------------------------------------------------------ 1842 void FmXGridPeer::elementReplaced(const ContainerEvent& evt) throw( RuntimeException ) 1843 { 1844 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1845 1846 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 1847 1848 // Handle Column beruecksichtigen 1849 if (!pGrid || !m_xColumns.is() || pGrid->IsInColumnMove()) 1850 return; 1851 1852 Reference< XPropertySet > xNewColumn; 1853 Reference< XPropertySet > xOldColumn; 1854 ::cppu::extractInterface(xNewColumn, evt.Element); 1855 ::cppu::extractInterface(xOldColumn, evt.ReplacedElement); 1856 1857 sal_Bool bWasEditing = pGrid->IsEditing(); 1858 if (bWasEditing) 1859 pGrid->DeactivateCell(); 1860 1861 pGrid->RemoveColumn(pGrid->GetColumnIdFromModelPos((sal_uInt16)::comphelper::getINT32(evt.Accessor))); 1862 1863 removeColumnListeners(xOldColumn); 1864 addColumnListeners(xNewColumn); 1865 1866 String aName = ::comphelper::getString(xNewColumn->getPropertyValue(FM_PROP_LABEL)); 1867 Any aWidth = xNewColumn->getPropertyValue(FM_PROP_WIDTH); 1868 sal_Int32 nWidth = 0; 1869 if (aWidth >>= nWidth) 1870 nWidth = pGrid->LogicToPixel(Point(nWidth,0),MAP_10TH_MM).X(); 1871 sal_uInt16 nNewId = pGrid->AppendColumn(aName, (sal_uInt16)nWidth, (sal_Int16)::comphelper::getINT32(evt.Accessor)); 1872 sal_uInt16 nNewPos = pGrid->GetModelColumnPos(nNewId); 1873 1874 // set the model of the new column 1875 DbGridColumn* pCol = pGrid->GetColumns().GetObject(nNewPos); 1876 1877 // for initializong this grid column, we need the fields of the grid's data source 1878 Reference< XColumnsSupplier > xSuppColumns; 1879 CursorWrapper* pGridDataSource = pGrid->getDataSource(); 1880 if ( pGridDataSource ) 1881 xSuppColumns = xSuppColumns.query( (Reference< XInterface >)( *pGridDataSource ) ); 1882 Reference< XNameAccess > xColumnsByName; 1883 if ( xSuppColumns.is() ) 1884 xColumnsByName = xSuppColumns->getColumns(); 1885 Reference< XIndexAccess > xColumnsByIndex( xColumnsByName, UNO_QUERY ); 1886 1887 if ( xColumnsByIndex.is() ) 1888 pGrid->InitColumnByField( pCol, xNewColumn, xColumnsByName, xColumnsByIndex ); 1889 else 1890 // the simple version, applies when the grid is not yet connected to a data source 1891 pCol->setModel(xNewColumn); 1892 1893 if (bWasEditing) 1894 pGrid->ActivateCell(); 1895 } 1896 1897 //------------------------------------------------------------------------------ 1898 void FmXGridPeer::elementRemoved(const ContainerEvent& evt) throw( RuntimeException ) 1899 { 1900 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1901 1902 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 1903 1904 // Handle Column beruecksichtigen 1905 if (!pGrid || !m_xColumns.is() || pGrid->IsInColumnMove() || m_xColumns->getCount() == ((sal_Int32)pGrid->GetModelColCount())) 1906 return; 1907 1908 pGrid->RemoveColumn(pGrid->GetColumnIdFromModelPos((sal_uInt16)::comphelper::getINT32(evt.Accessor))); 1909 1910 Reference< XPropertySet > xOldColumn; 1911 ::cppu::extractInterface(xOldColumn, evt.Element); 1912 removeColumnListeners(xOldColumn); 1913 } 1914 1915 //------------------------------------------------------------------------------ 1916 void FmXGridPeer::setProperty( const ::rtl::OUString& PropertyName, const Any& Value) throw( RuntimeException ) 1917 { 1918 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1919 1920 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 1921 1922 sal_Bool bVoid = !Value.hasValue(); 1923 1924 if ( 0 == PropertyName.compareTo( FM_PROP_TEXTLINECOLOR ) ) 1925 { 1926 ::Color aTextLineColor( bVoid ? COL_TRANSPARENT : ::comphelper::getINT32( Value ) ); 1927 if (bVoid) 1928 { 1929 pGrid->SetTextLineColor(); 1930 pGrid->GetDataWindow().SetTextLineColor(); 1931 } 1932 else 1933 { 1934 pGrid->SetTextLineColor(aTextLineColor); 1935 pGrid->GetDataWindow().SetTextLineColor(aTextLineColor); 1936 } 1937 1938 // need to forward this to the columns 1939 DbGridColumns& rColumns = const_cast<DbGridColumns&>(pGrid->GetColumns()); 1940 DbGridColumn* pLoop = rColumns.First(); 1941 while (pLoop) 1942 { 1943 FmXGridCell* pXCell = pLoop->GetCell(); 1944 if (pXCell) 1945 { 1946 if (bVoid) 1947 pXCell->SetTextLineColor(); 1948 else 1949 pXCell->SetTextLineColor(aTextLineColor); 1950 } 1951 1952 pLoop = rColumns.Next(); 1953 } 1954 1955 if (isDesignMode()) 1956 pGrid->Invalidate(); 1957 } 1958 else if ( 0 == PropertyName.compareTo( FM_PROP_FONTEMPHASISMARK ) ) 1959 { 1960 Font aGridFont = pGrid->GetControlFont(); 1961 sal_Int16 nValue = ::comphelper::getINT16(Value); 1962 aGridFont.SetEmphasisMark( nValue ); 1963 pGrid->SetControlFont( aGridFont ); 1964 } 1965 else if ( 0 == PropertyName.compareTo( FM_PROP_FONTRELIEF ) ) 1966 { 1967 Font aGridFont = pGrid->GetControlFont(); 1968 sal_Int16 nValue = ::comphelper::getINT16(Value); 1969 aGridFont.SetRelief( (FontRelief)nValue ); 1970 pGrid->SetControlFont( aGridFont ); 1971 } 1972 else if ( 0 == PropertyName.compareTo( FM_PROP_HELPURL ) ) 1973 { 1974 ::rtl::OUString sHelpURL; 1975 OSL_VERIFY( Value >>= sHelpURL ); 1976 INetURLObject aHID( sHelpURL ); 1977 if ( aHID.GetProtocol() == INET_PROT_HID ) 1978 sHelpURL = aHID.GetURLPath(); 1979 pGrid->SetHelpId( rtl::OUStringToOString( sHelpURL, RTL_TEXTENCODING_UTF8 ) ); 1980 } 1981 else if ( 0 == PropertyName.compareTo( FM_PROP_DISPLAYSYNCHRON ) ) 1982 { 1983 pGrid->setDisplaySynchron(::comphelper::getBOOL(Value)); 1984 } 1985 else if ( 0 == PropertyName.compareTo( FM_PROP_CURSORCOLOR ) ) 1986 { 1987 if (bVoid) 1988 pGrid->SetCursorColor(COL_TRANSPARENT); 1989 else 1990 pGrid->SetCursorColor( ::Color(::comphelper::getINT32(Value))); 1991 if (isDesignMode()) 1992 pGrid->Invalidate(); 1993 } 1994 else if ( 0 == PropertyName.compareTo( FM_PROP_ALWAYSSHOWCURSOR ) ) 1995 { 1996 pGrid->EnablePermanentCursor(::comphelper::getBOOL(Value)); 1997 if (isDesignMode()) 1998 pGrid->Invalidate(); 1999 } 2000 else if ( 0 == PropertyName.compareTo( FM_PROP_FONT ) ) 2001 { 2002 if ( bVoid ) 2003 pGrid->SetControlFont( Font() ); 2004 else 2005 { 2006 ::com::sun::star::awt::FontDescriptor aFont; 2007 if (Value >>= aFont) 2008 { 2009 Font aNewVclFont; 2010 if (::comphelper::operator!=(aFont, ::comphelper::getDefaultFont())) // ist das der Default 2011 aNewVclFont = ImplCreateFont( aFont ); 2012 2013 // need to add relief and emphasis (they're stored in a VCL-Font, but not in a FontDescriptor 2014 Font aOldVclFont = pGrid->GetControlFont(); 2015 aNewVclFont.SetRelief( aOldVclFont.GetRelief() ); 2016 aNewVclFont.SetEmphasisMark( aOldVclFont.GetEmphasisMark() ); 2017 2018 // now set it ... 2019 pGrid->SetControlFont( aNewVclFont ); 2020 2021 // if our row-height property is void (which means "calculate it font-dependent") we have 2022 // to adjust the control's row height 2023 Reference< XPropertySet > xModelSet(getColumns(), UNO_QUERY); 2024 if (xModelSet.is() && ::comphelper::hasProperty(FM_PROP_ROWHEIGHT, xModelSet)) 2025 { 2026 Any aHeight = xModelSet->getPropertyValue(FM_PROP_ROWHEIGHT); 2027 if (!aHeight.hasValue()) 2028 pGrid->SetDataRowHeight(0); 2029 } 2030 2031 } 2032 } 2033 } 2034 else if ( 0 == PropertyName.compareTo( FM_PROP_BACKGROUNDCOLOR ) ) 2035 { 2036 if ( bVoid ) 2037 { 2038 pGrid->SetControlBackground(); 2039 } 2040 else 2041 { 2042 ::Color aColor( ::comphelper::getINT32(Value) ); 2043 pGrid->SetBackground( aColor ); 2044 pGrid->SetControlBackground( aColor ); 2045 } 2046 } 2047 else if ( 0 == PropertyName.compareTo( FM_PROP_TEXTCOLOR ) ) 2048 { 2049 if ( bVoid ) 2050 { 2051 pGrid->SetControlForeground(); 2052 } 2053 else 2054 { 2055 ::Color aColor( ::comphelper::getINT32(Value) ); 2056 pGrid->SetTextColor( aColor ); 2057 pGrid->SetControlForeground( aColor ); 2058 } 2059 } 2060 else if ( 0 == PropertyName.compareTo( FM_PROP_ROWHEIGHT ) ) 2061 { 2062 sal_Int32 nLogHeight(0); 2063 if (Value >>= nLogHeight) 2064 { 2065 sal_Int32 nHeight = pGrid->LogicToPixel(Point(0,nLogHeight),MAP_10TH_MM).Y(); 2066 // take the zoom factor into account 2067 nHeight = pGrid->CalcZoom(nHeight); 2068 pGrid->SetDataRowHeight(nHeight); 2069 } 2070 else if (bVoid) 2071 pGrid->SetDataRowHeight(0); 2072 } 2073 else if ( 0 == PropertyName.compareTo( FM_PROP_HASNAVIGATION ) ) 2074 { 2075 sal_Bool bValue( sal_True ); 2076 OSL_VERIFY( Value >>= bValue ); 2077 pGrid->EnableNavigationBar( bValue ); 2078 } 2079 else if ( 0 == PropertyName.compareTo( FM_PROP_RECORDMARKER ) ) 2080 { 2081 sal_Bool bValue( sal_True ); 2082 OSL_VERIFY( Value >>= bValue ); 2083 pGrid->EnableHandle( bValue ); 2084 } 2085 else if ( 0 == PropertyName.compareTo( FM_PROP_ENABLED ) ) 2086 { 2087 sal_Bool bValue( sal_True ); 2088 OSL_VERIFY( Value >>= bValue ); 2089 pGrid->EnableHandle( bValue ); 2090 2091 // Im DesignModus nur das Datenfenster disablen 2092 // Sonst kann das Control nicht mehr konfiguriert werden 2093 if (isDesignMode()) 2094 pGrid->GetDataWindow().Enable( bValue ); 2095 else 2096 pGrid->Enable( bValue ); 2097 } 2098 else 2099 VCLXWindow::setProperty( PropertyName, Value ); 2100 } 2101 2102 //------------------------------------------------------------------------------ 2103 Reference< XAccessibleContext > FmXGridPeer::CreateAccessibleContext() 2104 { 2105 Reference< XAccessibleContext > xContext; 2106 2107 // use the AccessibleContext provided by the VCL window 2108 Window* pGrid = GetWindow(); 2109 if ( pGrid ) 2110 { 2111 Reference< XAccessible > xAcc( pGrid->GetAccessible( sal_True ) ); 2112 if ( xAcc.is() ) 2113 xContext = xAcc->getAccessibleContext(); 2114 // TODO: this has a slight conceptual problem: 2115 // 2116 // We know that the XAccessible and XAccessibleContext implementation of the browse 2117 // box is the same (the class implements both interfaces), which, speaking strictly, 2118 // is bad here (means when a browse box acts as UnoControl): We (the FmXGridPeer) are 2119 // the XAccessible here, and the browse box should be able to provide us an XAccessibleContext, 2120 // but it should _not_ be the XAccessible itself. 2121 // However, as long as no client implementation uses dirty hacks such as querying an 2122 // XAccessibleContext for XAccessible, this should not be a problem. 2123 } 2124 2125 if ( !xContext.is() ) 2126 xContext = VCLXWindow::CreateAccessibleContext( ); 2127 2128 return xContext; 2129 } 2130 2131 //------------------------------------------------------------------------------ 2132 Any FmXGridPeer::getProperty( const ::rtl::OUString& _rPropertyName ) throw( RuntimeException ) 2133 { 2134 Any aProp; 2135 if (GetWindow()) 2136 { 2137 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 2138 Window* pDataWindow = &pGrid->GetDataWindow(); 2139 2140 if ( 0 == _rPropertyName.compareTo( FM_PROP_NAME ) ) 2141 { 2142 Font aFont = pDataWindow->GetControlFont(); 2143 aProp <<= ImplCreateFontDescriptor( aFont ); 2144 } 2145 else if ( 0 == _rPropertyName.compareTo( FM_PROP_TEXTCOLOR ) ) 2146 { 2147 aProp <<= (sal_Int32)pDataWindow->GetControlForeground().GetColor(); 2148 } 2149 else if ( 0 == _rPropertyName.compareTo( FM_PROP_BACKGROUNDCOLOR ) ) 2150 { 2151 aProp <<= (sal_Int32)pDataWindow->GetControlBackground().GetColor(); 2152 } 2153 else if ( 0 == _rPropertyName.compareTo( FM_PROP_ROWHEIGHT ) ) 2154 { 2155 sal_Int32 nPixelHeight = pGrid->GetDataRowHeight(); 2156 // take the zoom factor into account 2157 nPixelHeight = pGrid->CalcReverseZoom(nPixelHeight); 2158 aProp <<= (sal_Int32)pGrid->PixelToLogic(Point(0,nPixelHeight),MAP_10TH_MM).Y(); 2159 } 2160 else if ( 0 == _rPropertyName.compareTo( FM_PROP_HASNAVIGATION ) ) 2161 { 2162 sal_Bool bHasNavBar = pGrid->HasNavigationBar(); 2163 aProp <<= (sal_Bool)bHasNavBar; 2164 } 2165 else if ( 0 == _rPropertyName.compareTo( FM_PROP_RECORDMARKER ) ) 2166 { 2167 sal_Bool bHasHandle = pGrid->HasHandle(); 2168 aProp <<= (sal_Bool)bHasHandle; 2169 } 2170 else if ( 0 == _rPropertyName.compareTo( FM_PROP_ENABLED ) ) 2171 { 2172 aProp <<= (sal_Bool)pDataWindow->IsEnabled(); 2173 } 2174 else 2175 aProp = VCLXWindow::getProperty( _rPropertyName ); 2176 } 2177 return aProp; 2178 } 2179 2180 //------------------------------------------------------------------------------ 2181 void FmXGridPeer::dispose() throw( RuntimeException ) 2182 { 2183 EventObject aEvt; 2184 aEvt.Source = static_cast< ::cppu::OWeakObject* >(this); 2185 m_aModifyListeners.disposeAndClear(aEvt); 2186 m_aUpdateListeners.disposeAndClear(aEvt); 2187 m_aContainerListeners.disposeAndClear(aEvt); 2188 VCLXWindow::dispose(); 2189 2190 // release all interceptors 2191 // discovered during #100312# - 2002-10-23 - fs@openoffice.org 2192 Reference< XDispatchProviderInterceptor > xInterceptor( m_xFirstDispatchInterceptor ); 2193 m_xFirstDispatchInterceptor.clear(); 2194 while ( xInterceptor.is() ) 2195 { 2196 // tell the interceptor it has a new (means no) predecessor 2197 xInterceptor->setMasterDispatchProvider( NULL ); 2198 2199 // ask for it's successor 2200 Reference< XDispatchProvider > xSlave = xInterceptor->getSlaveDispatchProvider(); 2201 // and give it the new (means no) successoert 2202 xInterceptor->setSlaveDispatchProvider( NULL ); 2203 2204 // start over with the next chain element 2205 xInterceptor = xInterceptor.query( xSlave ); 2206 } 2207 2208 DisConnectFromDispatcher(); 2209 setRowSet(Reference< XRowSet > ()); 2210 } 2211 2212 // XContainer 2213 //------------------------------------------------------------------------------ 2214 void FmXGridPeer::addContainerListener(const Reference< XContainerListener >& l) throw( RuntimeException ) 2215 { 2216 m_aContainerListeners.addInterface( l ); 2217 } 2218 //------------------------------------------------------------------------------ 2219 void FmXGridPeer::removeContainerListener(const Reference< XContainerListener >& l) throw( RuntimeException ) 2220 { 2221 m_aContainerListeners.removeInterface( l ); 2222 } 2223 2224 // ::com::sun::star::data::XDatabaseCursorSupplier 2225 //------------------------------------------------------------------------------ 2226 void FmXGridPeer::startCursorListening() 2227 { 2228 if (!m_nCursorListening) 2229 { 2230 Reference< XRowSet > xRowSet(m_xCursor, UNO_QUERY); 2231 if (xRowSet.is()) 2232 xRowSet->addRowSetListener(this); 2233 2234 Reference< XReset > xReset(m_xCursor, UNO_QUERY); 2235 if (xReset.is()) 2236 xReset->addResetListener(this); 2237 2238 // alle Listener anmelden 2239 Reference< XPropertySet > xSet(m_xCursor, UNO_QUERY); 2240 if (xSet.is()) 2241 { 2242 xSet->addPropertyChangeListener(FM_PROP_ISMODIFIED, this); 2243 xSet->addPropertyChangeListener(FM_PROP_ROWCOUNT, this); 2244 } 2245 } 2246 m_nCursorListening++; 2247 } 2248 2249 //------------------------------------------------------------------------------ 2250 void FmXGridPeer::stopCursorListening() 2251 { 2252 if (!--m_nCursorListening) 2253 { 2254 Reference< XRowSet > xRowSet(m_xCursor, UNO_QUERY); 2255 if (xRowSet.is()) 2256 xRowSet->removeRowSetListener(this); 2257 2258 Reference< XReset > xReset(m_xCursor, UNO_QUERY); 2259 if (xReset.is()) 2260 xReset->removeResetListener(this); 2261 2262 Reference< XPropertySet > xSet(m_xCursor, UNO_QUERY); 2263 if (xSet.is()) 2264 { 2265 xSet->removePropertyChangeListener(FM_PROP_ISMODIFIED, this); 2266 xSet->removePropertyChangeListener(FM_PROP_ROWCOUNT, this); 2267 } 2268 } 2269 } 2270 2271 //------------------------------------------------------------------------------ 2272 void FmXGridPeer::updateGrid(const Reference< XRowSet >& _rxCursor) 2273 { 2274 FmGridControl* pGrid = (FmGridControl*)GetWindow(); 2275 if (pGrid) 2276 pGrid->setDataSource(_rxCursor); 2277 } 2278 2279 //------------------------------------------------------------------------------ 2280 Reference< XRowSet > FmXGridPeer::getRowSet() throw( RuntimeException ) 2281 { 2282 return m_xCursor; 2283 } 2284 2285 //------------------------------------------------------------------------------ 2286 void FmXGridPeer::setRowSet(const Reference< XRowSet >& _rDatabaseCursor) throw( RuntimeException ) 2287 { 2288 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 2289 if (!pGrid || !m_xColumns.is() || !m_xColumns->getCount()) 2290 return; 2291 // alle Listener abmelden 2292 if (m_xCursor.is()) 2293 { 2294 Reference< XLoadable > xLoadable(m_xCursor, UNO_QUERY); 2295 // only if the form is loaded we set the rowset 2296 if (xLoadable.is()) 2297 { 2298 stopCursorListening(); 2299 xLoadable->removeLoadListener(this); 2300 } 2301 } 2302 2303 m_xCursor = _rDatabaseCursor; 2304 2305 if (pGrid) 2306 { 2307 Reference< XLoadable > xLoadable(m_xCursor, UNO_QUERY); 2308 // only if the form is loaded we set the rowset 2309 if (xLoadable.is() && xLoadable->isLoaded()) 2310 pGrid->setDataSource(m_xCursor); 2311 else 2312 pGrid->setDataSource(Reference< XRowSet > ()); 2313 2314 if (xLoadable.is()) 2315 { 2316 startCursorListening(); 2317 xLoadable->addLoadListener(this); 2318 } 2319 } 2320 } 2321 2322 //------------------------------------------------------------------------------ 2323 void SAL_CALL FmXGridPeer::addGridControlListener( const Reference< XGridControlListener >& _listener ) throw( RuntimeException ) 2324 { 2325 m_aGridControlListeners.addInterface( _listener ); 2326 } 2327 2328 //------------------------------------------------------------------------------ 2329 void SAL_CALL FmXGridPeer::removeGridControlListener( const Reference< XGridControlListener >& _listener ) throw( RuntimeException ) 2330 { 2331 m_aGridControlListeners.removeInterface( _listener ); 2332 } 2333 2334 //------------------------------------------------------------------------------ 2335 sal_Int16 FmXGridPeer::getCurrentColumnPosition() throw( RuntimeException ) 2336 { 2337 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 2338 return pGrid ? pGrid->GetViewColumnPos(pGrid->GetCurColumnId()) : -1; 2339 } 2340 2341 //------------------------------------------------------------------------------ 2342 void FmXGridPeer::setCurrentColumnPosition(sal_Int16 nPos) throw( RuntimeException ) 2343 { 2344 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 2345 if (pGrid) 2346 pGrid->GoToColumnId(pGrid->GetColumnIdFromViewPos(nPos)); 2347 } 2348 2349 //------------------------------------------------------------------------------ 2350 void FmXGridPeer::selectionChanged(const EventObject& evt) throw( RuntimeException ) 2351 { 2352 ::vos::OGuard aGuard(Application::GetSolarMutex()); 2353 2354 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 2355 if (pGrid) 2356 { 2357 Reference< ::com::sun::star::view::XSelectionSupplier > xSelSupplier(evt.Source, UNO_QUERY); 2358 Any aSelection = xSelSupplier->getSelection(); 2359 DBG_ASSERT(aSelection.getValueType().getTypeClass() == TypeClass_INTERFACE, "FmXGridPeer::selectionChanged : invalid selection !"); 2360 Reference< XPropertySet > xSelection; 2361 aSelection >>= xSelection; 2362 if (xSelection.is()) 2363 { 2364 Reference< XPropertySet > xCol; 2365 sal_Int32 i = 0; 2366 sal_Int32 nColCount = m_xColumns->getCount(); 2367 2368 for (; i < nColCount; ++i) 2369 { 2370 m_xColumns->getByIndex(i) >>= xCol; 2371 if ( xCol == xSelection ) 2372 { 2373 pGrid->markColumn(pGrid->GetColumnIdFromModelPos((sal_uInt16)i)); 2374 break; 2375 } 2376 } 2377 // fuer das VCL-Control muessen die Columns 1-basiert sein 2378 // die Selektion an das VCL-Control weiterreichen, wenn noetig 2379 if ( i != pGrid->GetSelectedColumn() ) 2380 { // (wenn das nicht greift, wurde das selectionChanged implizit von dem Control selber ausgeloest 2381 if ( i < nColCount ) 2382 { 2383 pGrid->SelectColumnPos(pGrid->GetViewColumnPos(pGrid->GetColumnIdFromModelPos( (sal_uInt16)i )) + 1, sal_True); 2384 // SelectColumnPos hat wieder zu einem impliziten ActivateCell gefuehrt 2385 if (pGrid->IsEditing()) 2386 pGrid->DeactivateCell(); 2387 } 2388 else 2389 pGrid->SetNoSelection(); 2390 } 2391 } 2392 else 2393 pGrid->markColumn(USHRT_MAX); 2394 } 2395 } 2396 2397 // XElementAccess 2398 //------------------------------------------------------------------------------ 2399 sal_Bool FmXGridPeer::hasElements() throw( RuntimeException ) 2400 { 2401 return getCount() != 0; 2402 } 2403 2404 //------------------------------------------------------------------------------ 2405 Type SAL_CALL FmXGridPeer::getElementType( ) throw(RuntimeException) 2406 { 2407 return ::getCppuType((Reference< ::com::sun::star::awt::XControl> *)NULL); 2408 } 2409 2410 // XEnumerationAccess 2411 //------------------------------------------------------------------------------ 2412 Reference< XEnumeration > FmXGridPeer::createEnumeration() throw( RuntimeException ) 2413 { 2414 return new ::comphelper::OEnumerationByIndex(this); 2415 } 2416 2417 // XIndexAccess 2418 //------------------------------------------------------------------------------ 2419 sal_Int32 FmXGridPeer::getCount() throw( RuntimeException ) 2420 { 2421 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 2422 if (pGrid) 2423 return pGrid->GetViewColCount(); 2424 else 2425 return 0; 2426 } 2427 2428 //------------------------------------------------------------------------------ 2429 Any FmXGridPeer::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 2430 { 2431 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 2432 if (_nIndex < 0 || 2433 _nIndex >= getCount() || !pGrid) 2434 throw IndexOutOfBoundsException(); 2435 2436 Any aElement; 2437 // get the columnid 2438 sal_uInt16 nId = pGrid->GetColumnIdFromViewPos((sal_uInt16)_nIndex); 2439 // get the list position 2440 sal_uInt16 nPos = pGrid->GetModelColumnPos(nId); 2441 2442 DbGridColumn* pCol = pGrid->GetColumns().GetObject(nPos); 2443 // DBG_ASSERT(pCol && pCol->GetCell(), "FmXGridPeer::getByIndex(): Invalid cell"); 2444 Reference< ::com::sun::star::awt::XControl > xControl(pCol->GetCell()); 2445 aElement <<= xControl; 2446 2447 return aElement; 2448 } 2449 2450 // ::com::sun::star::util::XModeSelector 2451 //------------------------------------------------------------------------------ 2452 void FmXGridPeer::setMode(const ::rtl::OUString& Mode) throw( NoSupportException, RuntimeException ) 2453 { 2454 if (!supportsMode(Mode)) 2455 throw NoSupportException(); 2456 2457 if (Mode == m_aMode) 2458 return; 2459 2460 m_aMode = Mode; 2461 2462 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 2463 if ( Mode == ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterMode" ) ) ) 2464 pGrid->SetFilterMode(sal_True); 2465 else 2466 { 2467 pGrid->SetFilterMode(sal_False); 2468 pGrid->setDataSource(m_xCursor); 2469 } 2470 } 2471 2472 //------------------------------------------------------------------------------ 2473 ::rtl::OUString FmXGridPeer::getMode() throw( RuntimeException ) 2474 { 2475 return m_aMode; 2476 } 2477 2478 //------------------------------------------------------------------------------ 2479 ::comphelper::StringSequence FmXGridPeer::getSupportedModes() throw( RuntimeException ) 2480 { 2481 static ::comphelper::StringSequence aModes; 2482 if (!aModes.getLength()) 2483 { 2484 aModes.realloc(2); 2485 ::rtl::OUString* pModes = aModes.getArray(); 2486 pModes[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DataMode" ) ); 2487 pModes[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterMode" ) ); 2488 } 2489 return aModes; 2490 } 2491 2492 //------------------------------------------------------------------------------ 2493 sal_Bool FmXGridPeer::supportsMode(const ::rtl::OUString& Mode) throw( RuntimeException ) 2494 { 2495 ::comphelper::StringSequence aModes(getSupportedModes()); 2496 const ::rtl::OUString* pModes = aModes.getConstArray(); 2497 for (sal_Int32 i = aModes.getLength(); i > 0; ) 2498 { 2499 if (pModes[--i] == Mode) 2500 return sal_True; 2501 } 2502 return sal_False; 2503 } 2504 2505 //------------------------------------------------------------------------------ 2506 void FmXGridPeer::columnVisible(DbGridColumn* pColumn) 2507 { 2508 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 2509 2510 sal_Int32 _nIndex = pGrid->GetModelColumnPos(pColumn->GetId()); 2511 Reference< ::com::sun::star::awt::XControl > xControl(pColumn->GetCell()); 2512 ContainerEvent aEvt; 2513 aEvt.Source = (XContainer*)this; 2514 aEvt.Accessor <<= _nIndex; 2515 aEvt.Element <<= xControl; 2516 2517 m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvt ); 2518 } 2519 2520 //------------------------------------------------------------------------------ 2521 void FmXGridPeer::columnHidden(DbGridColumn* pColumn) 2522 { 2523 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 2524 2525 sal_Int32 _nIndex = pGrid->GetModelColumnPos(pColumn->GetId()); 2526 Reference< ::com::sun::star::awt::XControl > xControl(pColumn->GetCell()); 2527 ContainerEvent aEvt; 2528 aEvt.Source = (XContainer*)this; 2529 aEvt.Accessor <<= _nIndex; 2530 aEvt.Element <<= xControl; 2531 2532 m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvt ); 2533 } 2534 2535 //------------------------------------------------------------------------------ 2536 void FmXGridPeer::draw( sal_Int32 x, sal_Int32 y ) throw( RuntimeException ) 2537 { 2538 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 2539 sal_Int32 nOldFlags = pGrid->GetBrowserFlags(); 2540 pGrid->SetBrowserFlags(nOldFlags | EBBF_NOROWPICTURE); 2541 2542 VCLXWindow::draw(x, y); 2543 2544 pGrid->SetBrowserFlags(nOldFlags); 2545 } 2546 2547 //------------------------------------------------------------------------------ 2548 Reference< ::com::sun::star::frame::XDispatch > FmXGridPeer::queryDispatch(const ::com::sun::star::util::URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags) throw( RuntimeException ) 2549 { 2550 Reference< ::com::sun::star::frame::XDispatch > xResult; 2551 2552 // first ask our interceptor chain 2553 if (m_xFirstDispatchInterceptor.is() && !m_bInterceptingDispatch) 2554 { 2555 m_bInterceptingDispatch = sal_True; 2556 // safety against recursion : as we are master of the first chain element and slave of the last one we would 2557 // have an infinite loop without this if no dispatcher can fullfill the rewuest) 2558 xResult = m_xFirstDispatchInterceptor->queryDispatch(aURL, aTargetFrameName, nSearchFlags); 2559 m_bInterceptingDispatch = sal_False; 2560 } 2561 2562 // then ask ourself : we don't have any dispatches 2563 return xResult; 2564 } 2565 2566 //------------------------------------------------------------------------------ 2567 Sequence< Reference< ::com::sun::star::frame::XDispatch > > FmXGridPeer::queryDispatches(const Sequence< ::com::sun::star::frame::DispatchDescriptor>& aDescripts) throw( RuntimeException ) 2568 { 2569 if (m_xFirstDispatchInterceptor.is()) 2570 return m_xFirstDispatchInterceptor->queryDispatches(aDescripts); 2571 2572 // then ask ourself : we don't have any dispatches 2573 return Sequence< Reference< ::com::sun::star::frame::XDispatch > >(); 2574 } 2575 2576 //------------------------------------------------------------------------------ 2577 void FmXGridPeer::registerDispatchProviderInterceptor(const Reference< ::com::sun::star::frame::XDispatchProviderInterceptor >& _xInterceptor) throw( RuntimeException ) 2578 { 2579 if (_xInterceptor.is()) 2580 { 2581 if (m_xFirstDispatchInterceptor.is()) 2582 { 2583 Reference< ::com::sun::star::frame::XDispatchProvider > xFirstProvider(m_xFirstDispatchInterceptor, UNO_QUERY); 2584 // there is already an interceptor; the new one will become its master 2585 _xInterceptor->setSlaveDispatchProvider(xFirstProvider); 2586 m_xFirstDispatchInterceptor->setMasterDispatchProvider(xFirstProvider); 2587 } 2588 else 2589 { 2590 // it is the first interceptor; set ourself as slave 2591 _xInterceptor->setSlaveDispatchProvider((::com::sun::star::frame::XDispatchProvider*)this); 2592 } 2593 2594 // we are the master of the chain's first interceptor 2595 m_xFirstDispatchInterceptor = _xInterceptor; 2596 m_xFirstDispatchInterceptor->setMasterDispatchProvider((::com::sun::star::frame::XDispatchProvider*)this); 2597 2598 // we have a new interceptor and we're alive ? 2599 if (!isDesignMode()) 2600 // -> check for new dispatchers 2601 UpdateDispatches(); 2602 } 2603 } 2604 2605 //------------------------------------------------------------------------------ 2606 void FmXGridPeer::releaseDispatchProviderInterceptor(const Reference< ::com::sun::star::frame::XDispatchProviderInterceptor >& _xInterceptor) throw( RuntimeException ) 2607 { 2608 if (!_xInterceptor.is()) 2609 return; 2610 2611 Reference< ::com::sun::star::frame::XDispatchProviderInterceptor > xChainWalk(m_xFirstDispatchInterceptor); 2612 2613 if (m_xFirstDispatchInterceptor == _xInterceptor) 2614 { // our chain will have a new first element 2615 Reference< ::com::sun::star::frame::XDispatchProviderInterceptor > xSlave(m_xFirstDispatchInterceptor->getSlaveDispatchProvider(), UNO_QUERY); 2616 m_xFirstDispatchInterceptor = xSlave; 2617 } 2618 // do this before removing the interceptor from the chain as we won't know it's slave afterwards) 2619 2620 while (xChainWalk.is()) 2621 { 2622 // walk along the chain of interceptors and look for the interceptor that has to be removed 2623 Reference< ::com::sun::star::frame::XDispatchProviderInterceptor > xSlave(xChainWalk->getSlaveDispatchProvider(), UNO_QUERY); 2624 2625 if (xChainWalk == _xInterceptor) 2626 { 2627 // old master may be an interceptor too 2628 Reference< ::com::sun::star::frame::XDispatchProviderInterceptor > xMaster(xChainWalk->getMasterDispatchProvider(), UNO_QUERY); 2629 2630 // unchain the interceptor that has to be removed 2631 xChainWalk->setSlaveDispatchProvider(Reference< ::com::sun::star::frame::XDispatchProvider > ()); 2632 xChainWalk->setMasterDispatchProvider(Reference< ::com::sun::star::frame::XDispatchProvider > ()); 2633 2634 // reconnect the chain 2635 if (xMaster.is()) 2636 { 2637 if (xSlave.is()) 2638 xMaster->setSlaveDispatchProvider(Reference< ::com::sun::star::frame::XDispatchProvider >::query(xSlave)); 2639 else 2640 // it's the first interceptor of the chain, set ourself as slave 2641 xMaster->setSlaveDispatchProvider((::com::sun::star::frame::XDispatchProvider*)this); 2642 } 2643 else 2644 { 2645 // the chain's first element was removed, set ourself as new master of the second one 2646 if (xSlave.is()) 2647 xSlave->setMasterDispatchProvider((::com::sun::star::frame::XDispatchProvider*)this); 2648 } 2649 } 2650 2651 xChainWalk = xSlave; 2652 } 2653 // our interceptor chain has changed and we're alive ? 2654 if (!isDesignMode()) 2655 // -> check the dispatchers 2656 UpdateDispatches(); 2657 } 2658 2659 //------------------------------------------------------------------------------ 2660 void FmXGridPeer::statusChanged(const ::com::sun::star::frame::FeatureStateEvent& Event) throw( RuntimeException ) 2661 { 2662 DBG_ASSERT(m_pStateCache, "FmXGridPeer::statusChanged : invalid call !"); 2663 DBG_ASSERT(m_pDispatchers, "FmXGridPeer::statusChanged : invalid call !"); 2664 2665 Sequence< ::com::sun::star::util::URL>& aUrls = getSupportedURLs(); 2666 const ::com::sun::star::util::URL* pUrls = aUrls.getConstArray(); 2667 2668 Sequence<sal_uInt16> aSlots = getSupportedGridSlots(); 2669 const sal_uInt16* pSlots = aSlots.getConstArray(); 2670 2671 sal_uInt16 i; 2672 for (i=0; i<aUrls.getLength(); ++i, ++pUrls, ++pSlots) 2673 { 2674 if (pUrls->Main == Event.FeatureURL.Main) 2675 { 2676 DBG_ASSERT(m_pDispatchers[i] == Event.Source, "FmXGridPeer::statusChanged : the event source is a little bit suspect !"); 2677 m_pStateCache[i] = Event.IsEnabled; 2678 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 2679 if (*pSlots != SID_FM_RECORD_UNDO) 2680 pGrid->GetNavigationBar().InvalidateState(*pSlots); 2681 break; 2682 } 2683 } 2684 DBG_ASSERT(i<aUrls.getLength(), "FmXGridPeer::statusChanged : got a call for an unknown url !"); 2685 } 2686 2687 //------------------------------------------------------------------------------ 2688 sal_Bool FmXGridPeer::approveReset(const EventObject& /*rEvent*/) throw( RuntimeException ) 2689 { 2690 return sal_True; 2691 } 2692 2693 //------------------------------------------------------------------------------ 2694 sal_Bool SAL_CALL FmXGridPeer::select( const Any& _rSelection ) throw (IllegalArgumentException, RuntimeException) 2695 { 2696 Sequence< Any > aBookmarks; 2697 if ( !( _rSelection >>= aBookmarks ) ) 2698 throw IllegalArgumentException(); 2699 2700 FmGridControl* pVclControl = static_cast<FmGridControl*>(GetWindow()); 2701 return pVclControl->selectBookmarks(aBookmarks); 2702 2703 // TODO: 2704 // speaking strictly, we would have to adjust our model, as our ColumnSelection may have changed. 2705 // Our model is a XSelectionSupplier, too, it handles the selection of single columns. 2706 // This is somewhat strange, as selection should be a view (not a model) aspect. 2707 // So for a clean solution, we should handle column selection ourself, and the model shouldn't 2708 // deal with selection at all. 2709 } 2710 2711 //------------------------------------------------------------------------------ 2712 Any SAL_CALL FmXGridPeer::getSelection( ) throw (RuntimeException) 2713 { 2714 FmGridControl* pVclControl = static_cast<FmGridControl*>(GetWindow()); 2715 Sequence< Any > aSelectionBookmarks = pVclControl->getSelectionBookmarks(); 2716 return makeAny(aSelectionBookmarks); 2717 } 2718 2719 //------------------------------------------------------------------------------ 2720 void SAL_CALL FmXGridPeer::addSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException) 2721 { 2722 m_aSelectionListeners.addInterface( _rxListener ); 2723 } 2724 2725 //------------------------------------------------------------------------------ 2726 void SAL_CALL FmXGridPeer::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException) 2727 { 2728 m_aSelectionListeners.removeInterface( _rxListener ); 2729 } 2730 2731 //------------------------------------------------------------------------------ 2732 void FmXGridPeer::resetted(const EventObject& rEvent) throw( RuntimeException ) 2733 { 2734 if (m_xColumns == rEvent.Source) 2735 { // my model was reset -> refresh the grid content 2736 FmGridControl* pGrid = (FmGridControl*)GetWindow(); 2737 if (!pGrid) 2738 return; 2739 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2740 pGrid->resetCurrentRow(); 2741 } 2742 // if the cursor fired a reset event we seem to be on the insert row 2743 else if (m_xCursor == rEvent.Source) 2744 { 2745 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2746 FmGridControl* pGrid = (FmGridControl*) GetWindow(); 2747 if (pGrid && pGrid->IsOpen()) 2748 pGrid->positioned(rEvent); 2749 } 2750 } 2751 2752 //------------------------------------------------------------------------------ 2753 Sequence<sal_uInt16>& FmXGridPeer::getSupportedGridSlots() 2754 { 2755 static Sequence<sal_uInt16> aSupported; 2756 if (aSupported.getLength() == 0) 2757 { 2758 sal_uInt16 nSupported[] = { 2759 DbGridControl::NavigationBar::RECORD_FIRST, 2760 DbGridControl::NavigationBar::RECORD_PREV, 2761 DbGridControl::NavigationBar::RECORD_NEXT, 2762 DbGridControl::NavigationBar::RECORD_LAST, 2763 DbGridControl::NavigationBar::RECORD_NEW, 2764 SID_FM_RECORD_UNDO 2765 }; 2766 aSupported.realloc(sizeof(nSupported)/sizeof(nSupported[0])); 2767 sal_uInt16* pSupported = aSupported.getArray(); 2768 for (sal_uInt16 i=0; i<aSupported.getLength(); ++i, ++pSupported) 2769 *pSupported = nSupported[i]; 2770 } 2771 return aSupported; 2772 } 2773 2774 //------------------------------------------------------------------------------ 2775 Sequence< ::com::sun::star::util::URL>& FmXGridPeer::getSupportedURLs() 2776 { 2777 static Sequence< ::com::sun::star::util::URL> aSupported; 2778 if (aSupported.getLength() == 0) 2779 { 2780 static ::rtl::OUString sSupported[] = { 2781 FMURL_RECORD_MOVEFIRST, 2782 FMURL_RECORD_MOVEPREV, 2783 FMURL_RECORD_MOVENEXT, 2784 FMURL_RECORD_MOVELAST, 2785 FMURL_RECORD_MOVETONEW, 2786 FMURL_RECORD_UNDO 2787 }; 2788 aSupported.realloc(sizeof(sSupported)/sizeof(sSupported[0])); 2789 ::com::sun::star::util::URL* pSupported = aSupported.getArray(); 2790 sal_uInt16 i; 2791 2792 for ( i = 0; i < aSupported.getLength(); ++i, ++pSupported) 2793 pSupported->Complete = sSupported[i]; 2794 2795 // let an ::com::sun::star::util::URL-transformer normalize the URLs 2796 Reference< ::com::sun::star::util::XURLTransformer > xTransformer( 2797 ::comphelper::getProcessServiceFactory()->createInstance( 2798 ::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer")), 2799 UNO_QUERY); 2800 pSupported = aSupported.getArray(); 2801 if (xTransformer.is()) 2802 { 2803 for (i=0; i<aSupported.getLength(); ++i) 2804 xTransformer->parseStrict(pSupported[i]); 2805 } 2806 } 2807 2808 return aSupported; 2809 } 2810 2811 //------------------------------------------------------------------------------ 2812 void FmXGridPeer::UpdateDispatches() 2813 { 2814 if (!m_pStateCache) 2815 { // we don't have any dispatchers yet -> do the initial connect 2816 ConnectToDispatcher(); 2817 return; 2818 } 2819 2820 sal_uInt16 nDispatchersGot = 0; 2821 const Sequence< ::com::sun::star::util::URL>& aSupportedURLs = getSupportedURLs(); 2822 const ::com::sun::star::util::URL* pSupportedURLs = aSupportedURLs.getConstArray(); 2823 Reference< ::com::sun::star::frame::XDispatch > xNewDispatch; 2824 for (sal_uInt16 i=0; i<aSupportedURLs.getLength(); ++i, ++pSupportedURLs) 2825 { 2826 xNewDispatch = queryDispatch(*pSupportedURLs, rtl::OUString(), 0); 2827 if (xNewDispatch != m_pDispatchers[i]) 2828 { 2829 if (m_pDispatchers[i].is()) 2830 m_pDispatchers[i]->removeStatusListener((::com::sun::star::frame::XStatusListener*)this, *pSupportedURLs); 2831 m_pDispatchers[i] = xNewDispatch; 2832 if (m_pDispatchers[i].is()) 2833 m_pDispatchers[i]->addStatusListener((::com::sun::star::frame::XStatusListener*)this, *pSupportedURLs); 2834 } 2835 if (m_pDispatchers[i].is()) 2836 ++nDispatchersGot; 2837 } 2838 2839 if (!nDispatchersGot) 2840 { 2841 delete[] m_pStateCache; 2842 delete[] m_pDispatchers; 2843 m_pStateCache = NULL; 2844 m_pDispatchers = NULL; 2845 } 2846 } 2847 2848 //------------------------------------------------------------------------------ 2849 void FmXGridPeer::ConnectToDispatcher() 2850 { 2851 DBG_ASSERT((m_pStateCache != NULL) == (m_pDispatchers != NULL), "FmXGridPeer::ConnectToDispatcher : inconsistent !"); 2852 if (m_pStateCache) 2853 { // already connected -> just do an update 2854 UpdateDispatches(); 2855 return; 2856 } 2857 2858 const Sequence< ::com::sun::star::util::URL>& aSupportedURLs = getSupportedURLs(); 2859 2860 // _before_ adding the status listeners (as the add should result in a statusChanged-call) ! 2861 m_pStateCache = new sal_Bool[aSupportedURLs.getLength()]; 2862 m_pDispatchers = new Reference< ::com::sun::star::frame::XDispatch > [aSupportedURLs.getLength()]; 2863 2864 sal_uInt16 nDispatchersGot = 0; 2865 const ::com::sun::star::util::URL* pSupportedURLs = aSupportedURLs.getConstArray(); 2866 for (sal_uInt16 i=0; i<aSupportedURLs.getLength(); ++i, ++pSupportedURLs) 2867 { 2868 m_pStateCache[i] = 0; 2869 m_pDispatchers[i] = queryDispatch(*pSupportedURLs, rtl::OUString(), 0); 2870 if (m_pDispatchers[i].is()) 2871 { 2872 m_pDispatchers[i]->addStatusListener((::com::sun::star::frame::XStatusListener*)this, *pSupportedURLs); 2873 ++nDispatchersGot; 2874 } 2875 } 2876 2877 if (!nDispatchersGot) 2878 { 2879 delete[] m_pStateCache; 2880 delete[] m_pDispatchers; 2881 m_pStateCache = NULL; 2882 m_pDispatchers = NULL; 2883 } 2884 } 2885 2886 //------------------------------------------------------------------------------ 2887 void FmXGridPeer::DisConnectFromDispatcher() 2888 { 2889 if (!m_pStateCache || !m_pDispatchers) 2890 return; 2891 // we're not connected 2892 2893 const Sequence< ::com::sun::star::util::URL>& aSupportedURLs = getSupportedURLs(); 2894 const ::com::sun::star::util::URL* pSupportedURLs = aSupportedURLs.getConstArray(); 2895 for (sal_uInt16 i=0; i<aSupportedURLs.getLength(); ++i, ++pSupportedURLs) 2896 { 2897 if (m_pDispatchers[i].is()) 2898 m_pDispatchers[i]->removeStatusListener((::com::sun::star::frame::XStatusListener*)this, *pSupportedURLs); 2899 } 2900 2901 delete[] m_pStateCache; 2902 delete[] m_pDispatchers; 2903 m_pStateCache = NULL; 2904 m_pDispatchers = NULL; 2905 } 2906 2907 //------------------------------------------------------------------------------ 2908 IMPL_LINK(FmXGridPeer, OnQueryGridSlotState, void*, pSlot) 2909 { 2910 if (!m_pStateCache) 2911 return -1; // unspecified 2912 2913 sal_uInt16 nSlot = (sal_uInt16)(sal_uIntPtr)pSlot; 2914 2915 // search the given slot with our supported sequence 2916 Sequence<sal_uInt16>& aSupported = getSupportedGridSlots(); 2917 const sal_uInt16* pSlots = aSupported.getConstArray(); 2918 for (sal_uInt16 i=0; i<aSupported.getLength(); ++i) 2919 { 2920 if (pSlots[i] == nSlot) 2921 { 2922 if (!m_pDispatchers[i].is()) 2923 return -1; // nothing known about this slot 2924 else 2925 return m_pStateCache[i]; 2926 } 2927 } 2928 2929 return -1; 2930 } 2931 2932 //------------------------------------------------------------------------------ 2933 IMPL_LINK(FmXGridPeer, OnExecuteGridSlot, void*, pSlot) 2934 { 2935 if (!m_pDispatchers) 2936 return 0; // not handled 2937 2938 Sequence< ::com::sun::star::util::URL>& aUrls = getSupportedURLs(); 2939 const ::com::sun::star::util::URL* pUrls = aUrls.getConstArray(); 2940 2941 Sequence<sal_uInt16> aSlots = getSupportedGridSlots(); 2942 const sal_uInt16* pSlots = aSlots.getConstArray(); 2943 2944 DBG_ASSERT(aSlots.getLength() == aUrls.getLength(), "FmXGridPeer::OnExecuteGridSlot : inconstent data returned by getSupportedURLs/getSupportedGridSlots !"); 2945 2946 sal_uInt16 nSlot = (sal_uInt16)(sal_uIntPtr)pSlot; 2947 for (sal_uInt16 i=0; i<aSlots.getLength(); ++i, ++pUrls, ++pSlots) 2948 { 2949 if (*pSlots == nSlot) 2950 { 2951 if (m_pDispatchers[i].is()) 2952 { 2953 // commit any changes done so far, if it's not the undoRecord URL 2954 if ( 0 == pUrls->Complete.compareTo( FMURL_RECORD_UNDO ) || commit() ) 2955 m_pDispatchers[i]->dispatch(*pUrls, Sequence< PropertyValue>()); 2956 2957 return 1; // handled 2958 } 2959 } 2960 } 2961 2962 return 0; // not handled 2963 } 2964 2965