1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svx.hxx" 30 31 #include "fmdocumentclassification.hxx" 32 #include "fmobj.hxx" 33 #include "fmpgeimp.hxx" 34 #include "fmprop.hrc" 35 #include "svx/fmresids.hrc" 36 #include "fmservs.hxx" 37 #include "fmshimp.hxx" 38 #include "svx/fmtools.hxx" 39 #include "fmundo.hxx" 40 #include "fmvwimp.hxx" 41 #include "formcontrolfactory.hxx" 42 #include "svx/sdrpaintwindow.hxx" 43 #include "svx/svditer.hxx" 44 #include "svx/dataaccessdescriptor.hxx" 45 #include "svx/dialmgr.hxx" 46 #include "svx/fmglob.hxx" 47 #include "svx/fmmodel.hxx" 48 #include "svx/fmpage.hxx" 49 #include "svx/fmshell.hxx" 50 #include "svx/fmview.hxx" 51 #include "svx/sdrpagewindow.hxx" 52 #include "svx/svdogrp.hxx" 53 #include "svx/svdpagv.hxx" 54 #include "svx/xmlexchg.hxx" 55 56 /** === begin UNO includes === **/ 57 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> 58 #include <com/sun/star/style/VerticalAlignment.hpp> 59 #include <com/sun/star/lang/XInitialization.hpp> 60 #include <com/sun/star/sdbc/XRowSet.hpp> 61 #include <com/sun/star/form/XLoadable.hpp> 62 #include <com/sun/star/awt/VisualEffect.hpp> 63 #include <com/sun/star/util/XNumberFormatsSupplier.hpp> 64 #include <com/sun/star/util/XNumberFormats.hpp> 65 #include <com/sun/star/sdb/CommandType.hpp> 66 #include <com/sun/star/sdbc/DataType.hpp> 67 #include <com/sun/star/sdbc/ColumnValue.hpp> 68 #include <com/sun/star/form/FormComponentType.hpp> 69 #include <com/sun/star/form/FormButtonType.hpp> 70 #include <com/sun/star/form/XReset.hpp> 71 #include <com/sun/star/form/binding/XBindableValue.hpp> 72 #include <com/sun/star/form/binding/XValueBinding.hpp> 73 #include <com/sun/star/form/submission/XSubmissionSupplier.hpp> 74 #include <com/sun/star/awt/XTabControllerModel.hpp> 75 #include <com/sun/star/awt/XControlContainer.hpp> 76 #include <com/sun/star/awt/XTabController.hpp> 77 #include <com/sun/star/container/XIndexAccess.hpp> 78 #include <com/sun/star/awt/XControl.hpp> 79 #include <com/sun/star/lang/XUnoTunnel.hpp> 80 #include <com/sun/star/sdbcx/XTablesSupplier.hpp> 81 #include <com/sun/star/sdbc/XPreparedStatement.hpp> 82 #include <com/sun/star/sdb/XQueriesSupplier.hpp> 83 #include <com/sun/star/container/XContainer.hpp> 84 /** === end UNO includes === **/ 85 86 #include <comphelper/enumhelper.hxx> 87 #include <comphelper/extract.hxx> 88 #include <comphelper/namedvaluecollection.hxx> 89 #include <comphelper/numbers.hxx> 90 #include <comphelper/property.hxx> 91 #include <cppuhelper/exc_hlp.hxx> 92 #include <unotools/moduleoptions.hxx> 93 #include <tools/diagnose_ex.h> 94 #include <vcl/msgbox.hxx> 95 #include <vcl/stdtext.hxx> 96 #include <vos/mutex.hxx> 97 #include <rtl/logfile.hxx> 98 99 #include <algorithm> 100 101 using namespace ::comphelper; 102 using namespace ::svx; 103 using namespace ::svxform; 104 105 using namespace ::com::sun::star; 106 /** === begin UNO using === **/ 107 using ::com::sun::star::uno::Exception; 108 using ::com::sun::star::uno::RuntimeException; 109 using ::com::sun::star::uno::XInterface; 110 using ::com::sun::star::uno::Sequence; 111 using ::com::sun::star::uno::UNO_QUERY; 112 using ::com::sun::star::uno::UNO_QUERY_THROW; 113 using ::com::sun::star::uno::UNO_SET_THROW; 114 using ::com::sun::star::uno::Type; 115 using ::com::sun::star::uno::Reference; 116 using ::com::sun::star::uno::Any; 117 using ::com::sun::star::uno::makeAny; 118 using ::com::sun::star::style::VerticalAlignment_MIDDLE; 119 using ::com::sun::star::form::FormButtonType_SUBMIT; 120 using ::com::sun::star::form::binding::XValueBinding; 121 using ::com::sun::star::form::binding::XBindableValue; 122 using ::com::sun::star::lang::XComponent; 123 using ::com::sun::star::container::XIndexAccess; 124 using ::com::sun::star::form::XForm; 125 using ::com::sun::star::form::runtime::XFormController; 126 using ::com::sun::star::script::XEventAttacherManager; 127 using ::com::sun::star::awt::XTabControllerModel; 128 using ::com::sun::star::container::XChild; 129 using ::com::sun::star::container::XEnumeration; 130 using ::com::sun::star::task::XInteractionHandler; 131 using ::com::sun::star::lang::XInitialization; 132 using ::com::sun::star::awt::XTabController; 133 using ::com::sun::star::lang::XUnoTunnel; 134 using ::com::sun::star::awt::XControlContainer; 135 using ::com::sun::star::awt::XControl; 136 using ::com::sun::star::form::XFormComponent; 137 using ::com::sun::star::form::XForm; 138 using ::com::sun::star::lang::IndexOutOfBoundsException; 139 using ::com::sun::star::lang::WrappedTargetException; 140 using ::com::sun::star::container::XContainer; 141 using ::com::sun::star::container::ContainerEvent; 142 using ::com::sun::star::lang::EventObject; 143 using ::com::sun::star::beans::NamedValue; 144 using ::com::sun::star::sdb::SQLErrorEvent; 145 using ::com::sun::star::sdbc::XRowSet; 146 using ::com::sun::star::beans::XPropertySet; 147 using ::com::sun::star::container::XElementAccess; 148 using ::com::sun::star::awt::XWindow; 149 using ::com::sun::star::awt::FocusEvent; 150 using ::com::sun::star::ui::dialogs::XExecutableDialog; 151 using ::com::sun::star::sdbc::XDataSource; 152 using ::com::sun::star::container::XIndexContainer; 153 using ::com::sun::star::sdbc::XConnection; 154 using ::com::sun::star::container::XNameAccess; 155 using ::com::sun::star::sdb::SQLContext; 156 using ::com::sun::star::sdbc::SQLWarning; 157 using ::com::sun::star::sdbc::SQLException; 158 using ::com::sun::star::util::XNumberFormatsSupplier; 159 using ::com::sun::star::util::XNumberFormats; 160 using ::com::sun::star::beans::XPropertySetInfo; 161 /** === end UNO using === **/ 162 namespace FormComponentType = ::com::sun::star::form::FormComponentType; 163 namespace CommandType = ::com::sun::star::sdb::CommandType; 164 namespace DataType = ::com::sun::star::sdbc::DataType; 165 166 //------------------------------------------------------------------------------ 167 class FmXFormView::ObjectRemoveListener : public SfxListener 168 { 169 FmXFormView* m_pParent; 170 public: 171 ObjectRemoveListener( FmXFormView* pParent ); 172 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); 173 }; 174 175 //======================================================================== 176 DBG_NAME(FormViewPageWindowAdapter) 177 //------------------------------------------------------------------------ 178 FormViewPageWindowAdapter::FormViewPageWindowAdapter( const ::comphelper::ComponentContext& _rContext, const SdrPageWindow& _rWindow, FmXFormView* _pViewImpl ) 179 : m_xControlContainer( _rWindow.GetControlContainer() ), 180 m_aContext( _rContext ), 181 m_pViewImpl( _pViewImpl ), 182 m_pWindow( dynamic_cast< Window* >( &_rWindow.GetPaintWindow().GetOutputDevice() ) ) 183 { 184 DBG_CTOR(FormViewPageWindowAdapter,NULL); 185 186 // create an XFormController for every form 187 FmFormPage* pFormPage = dynamic_cast< FmFormPage* >( _rWindow.GetPageView().GetPage() ); 188 DBG_ASSERT( pFormPage, "FormViewPageWindowAdapter::FormViewPageWindowAdapter: no FmFormPage found!" ); 189 if ( pFormPage ) 190 { 191 try 192 { 193 Reference< XIndexAccess > xForms( pFormPage->GetForms(), UNO_QUERY_THROW ); 194 sal_uInt32 nLength = xForms->getCount(); 195 for (sal_uInt32 i = 0; i < nLength; i++) 196 { 197 Reference< XForm > xForm( xForms->getByIndex(i), UNO_QUERY ); 198 if ( xForm.is() ) 199 setController( xForm, NULL ); 200 } 201 } 202 catch( const Exception& ) 203 { 204 DBG_UNHANDLED_EXCEPTION(); 205 } 206 } 207 } 208 // ----------------------------------------------------------------------------- 209 FormViewPageWindowAdapter::~FormViewPageWindowAdapter() 210 { 211 DBG_DTOR(FormViewPageWindowAdapter,NULL); 212 } 213 214 //------------------------------------------------------------------ 215 void FormViewPageWindowAdapter::dispose() 216 { 217 for ( ::std::vector< Reference< XFormController > >::const_iterator i = m_aControllerList.begin(); 218 i != m_aControllerList.end(); 219 ++i 220 ) 221 { 222 try 223 { 224 Reference< XFormController > xController( *i, UNO_QUERY_THROW ); 225 226 // detaching the events 227 Reference< XChild > xControllerModel( xController->getModel(), UNO_QUERY ); 228 if ( xControllerModel.is() ) 229 { 230 Reference< XEventAttacherManager > xEventManager( xControllerModel->getParent(), UNO_QUERY_THROW ); 231 Reference< XInterface > xControllerNormalized( xController, UNO_QUERY_THROW ); 232 xEventManager->detach( i - m_aControllerList.begin(), xControllerNormalized ); 233 } 234 235 // dispose the formcontroller 236 Reference< XComponent > xComp( xController, UNO_QUERY_THROW ); 237 xComp->dispose(); 238 } 239 catch( const Exception& ) 240 { 241 DBG_UNHANDLED_EXCEPTION(); 242 } 243 } 244 245 m_aControllerList.clear(); 246 } 247 248 249 //------------------------------------------------------------------------------ 250 sal_Bool SAL_CALL FormViewPageWindowAdapter::hasElements(void) throw( RuntimeException ) 251 { 252 return getCount() != 0; 253 } 254 255 //------------------------------------------------------------------------------ 256 Type SAL_CALL FormViewPageWindowAdapter::getElementType(void) throw( RuntimeException ) 257 { 258 return ::getCppuType((const Reference< XFormController>*)0); 259 } 260 261 // XEnumerationAccess 262 //------------------------------------------------------------------------------ 263 Reference< XEnumeration > SAL_CALL FormViewPageWindowAdapter::createEnumeration(void) throw( RuntimeException ) 264 { 265 return new ::comphelper::OEnumerationByIndex(this); 266 } 267 268 // XIndexAccess 269 //------------------------------------------------------------------------------ 270 sal_Int32 SAL_CALL FormViewPageWindowAdapter::getCount(void) throw( RuntimeException ) 271 { 272 return m_aControllerList.size(); 273 } 274 275 //------------------------------------------------------------------------------ 276 Any SAL_CALL FormViewPageWindowAdapter::getByIndex(sal_Int32 nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 277 { 278 if (nIndex < 0 || 279 nIndex >= getCount()) 280 throw IndexOutOfBoundsException(); 281 282 Any aElement; 283 aElement <<= m_aControllerList[nIndex]; 284 return aElement; 285 } 286 287 //------------------------------------------------------------------------ 288 void SAL_CALL FormViewPageWindowAdapter::makeVisible( const Reference< XControl >& _Control ) throw (RuntimeException) 289 { 290 ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); 291 292 Reference< XWindow > xWindow( _Control, UNO_QUERY ); 293 if ( xWindow.is() && m_pViewImpl->getView() && m_pWindow ) 294 { 295 awt::Rectangle aRect = xWindow->getPosSize(); 296 ::Rectangle aNewRect( aRect.X, aRect.Y, aRect.X + aRect.Width, aRect.Y + aRect.Height ); 297 aNewRect = m_pWindow->PixelToLogic( aNewRect ); 298 m_pViewImpl->getView()->MakeVisible( aNewRect, *m_pWindow ); 299 } 300 } 301 302 //------------------------------------------------------------------------ 303 Reference< XFormController > getControllerSearchChilds( const Reference< XIndexAccess > & xIndex, const Reference< XTabControllerModel > & xModel) 304 { 305 if (xIndex.is() && xIndex->getCount()) 306 { 307 Reference< XFormController > xController; 308 309 for (sal_Int32 n = xIndex->getCount(); n-- && !xController.is(); ) 310 { 311 xIndex->getByIndex(n) >>= xController; 312 if ((XTabControllerModel*)xModel.get() == (XTabControllerModel*)xController->getModel().get()) 313 return xController; 314 else 315 { 316 xController = getControllerSearchChilds(Reference< XIndexAccess > (xController, UNO_QUERY), xModel); 317 if ( xController.is() ) 318 return xController; 319 } 320 } 321 } 322 return Reference< XFormController > (); 323 } 324 325 // Search the according controller 326 //------------------------------------------------------------------------ 327 Reference< XFormController > FormViewPageWindowAdapter::getController( const Reference< XForm > & xForm ) const 328 { 329 Reference< XTabControllerModel > xModel(xForm, UNO_QUERY); 330 for (::std::vector< Reference< XFormController > >::const_iterator i = m_aControllerList.begin(); 331 i != m_aControllerList.end(); i++) 332 { 333 if ((XTabControllerModel*)(*i)->getModel().get() == (XTabControllerModel*)xModel.get()) 334 return *i; 335 336 // the current-round controller isn't the right one. perhaps one of it's children ? 337 Reference< XFormController > xChildSearch = getControllerSearchChilds(Reference< XIndexAccess > (*i, UNO_QUERY), xModel); 338 if (xChildSearch.is()) 339 return xChildSearch; 340 } 341 return Reference< XFormController > (); 342 } 343 344 //------------------------------------------------------------------------ 345 void FormViewPageWindowAdapter::setController(const Reference< XForm > & xForm, const Reference< XFormController >& _rxParentController ) 346 { 347 DBG_ASSERT( xForm.is(), "FormViewPageWindowAdapter::setController: there should be a form!" ); 348 Reference< XIndexAccess > xFormCps(xForm, UNO_QUERY); 349 if (!xFormCps.is()) 350 return; 351 352 Reference< XTabControllerModel > xTabOrder(xForm, UNO_QUERY); 353 354 // create a form controller 355 Reference< XFormController > xController( m_aContext.createComponent( FM_FORM_CONTROLLER ), UNO_QUERY ); 356 if ( !xController.is() ) 357 { 358 ShowServiceNotAvailableError( m_pWindow, FM_FORM_CONTROLLER, sal_True ); 359 return; 360 } 361 362 Reference< XInteractionHandler > xHandler; 363 if ( _rxParentController.is() ) 364 xHandler = _rxParentController->getInteractionHandler(); 365 else 366 { 367 // TODO: should we create a default handler? Not really necessary, since the 368 // FormController itself has a default fallback 369 } 370 if ( xHandler.is() ) 371 xController->setInteractionHandler( xHandler ); 372 373 xController->setContext( this ); 374 375 xController->setModel( xTabOrder ); 376 xController->setContainer( m_xControlContainer ); 377 xController->activateTabOrder(); 378 xController->addActivateListener( m_pViewImpl ); 379 380 if ( _rxParentController.is() ) 381 _rxParentController->addChildController( xController ); 382 else 383 { 384 m_aControllerList.push_back(xController); 385 386 xController->setParent( *this ); 387 388 // attaching the events 389 Reference< XEventAttacherManager > xEventManager( xForm->getParent(), UNO_QUERY ); 390 Reference< XInterface > xIfc(xController, UNO_QUERY); 391 xEventManager->attach(m_aControllerList.size() - 1, xIfc, makeAny(xController) ); 392 } 393 394 // jetzt die Subforms durchgehen 395 sal_uInt32 nLength = xFormCps->getCount(); 396 Reference< XForm > xSubForm; 397 for (sal_uInt32 i = 0; i < nLength; i++) 398 { 399 if ( xFormCps->getByIndex(i) >>= xSubForm ) 400 setController( xSubForm, xController ); 401 } 402 } 403 404 //------------------------------------------------------------------------ 405 void FormViewPageWindowAdapter::updateTabOrder( const Reference< XForm >& _rxForm ) 406 { 407 OSL_PRECOND( _rxForm.is(), "FormViewPageWindowAdapter::updateTabOrder: illegal argument!" ); 408 if ( !_rxForm.is() ) 409 return; 410 411 try 412 { 413 Reference< XTabController > xTabCtrl( getController( _rxForm ).get() ); 414 if ( xTabCtrl.is() ) 415 { // if there already is a TabController for this form, then delegate the "updateTabOrder" request 416 xTabCtrl->activateTabOrder(); 417 } 418 else 419 { // otherwise, create a TabController 420 421 // if it's a sub form, then we must ensure there exist TabControllers 422 // for all its ancestors, too 423 Reference< XForm > xParentForm( _rxForm->getParent(), UNO_QUERY ); 424 // there is a parent form -> look for the respective controller 425 Reference< XFormController > xParentController; 426 if ( xParentForm.is() ) 427 xParentController.set( getController( xParentForm ), UNO_QUERY ); 428 429 setController( _rxForm, xParentController ); 430 } 431 } 432 catch( const Exception& ) 433 { 434 DBG_UNHANDLED_EXCEPTION(); 435 } 436 } 437 438 //------------------------------------------------------------------------ 439 FmXFormView::FmXFormView(const ::comphelper::ComponentContext& _rContext, FmFormView* _pView ) 440 :m_aContext( _rContext ) 441 ,m_pMarkedGrid(NULL) 442 ,m_pView(_pView) 443 ,m_nActivationEvent(0) 444 ,m_nErrorMessageEvent( 0 ) 445 ,m_nAutoFocusEvent( 0 ) 446 ,m_nControlWizardEvent( 0 ) 447 ,m_pWatchStoredList( NULL ) 448 ,m_bFirstActivation( true ) 449 ,m_isTabOrderUpdateSuspended( false ) 450 { 451 } 452 453 //------------------------------------------------------------------------ 454 void FmXFormView::cancelEvents() 455 { 456 if ( m_nActivationEvent ) 457 { 458 Application::RemoveUserEvent( m_nActivationEvent ); 459 m_nActivationEvent = 0; 460 } 461 462 if ( m_nErrorMessageEvent ) 463 { 464 Application::RemoveUserEvent( m_nErrorMessageEvent ); 465 m_nErrorMessageEvent = 0; 466 } 467 468 if ( m_nAutoFocusEvent ) 469 { 470 Application::RemoveUserEvent( m_nAutoFocusEvent ); 471 m_nAutoFocusEvent = 0; 472 } 473 474 if ( m_nControlWizardEvent ) 475 { 476 Application::RemoveUserEvent( m_nControlWizardEvent ); 477 m_nControlWizardEvent = 0; 478 } 479 } 480 481 //------------------------------------------------------------------------ 482 void FmXFormView::notifyViewDying( ) 483 { 484 DBG_ASSERT( m_pView, "FmXFormView::notifyViewDying: my view already died!" ); 485 m_pView = NULL; 486 cancelEvents(); 487 } 488 489 //------------------------------------------------------------------------ 490 FmXFormView::~FmXFormView() 491 { 492 DBG_ASSERT( m_aPageWindowAdapters.empty(), "FmXFormView::~FmXFormView: Window list not empty!" ); 493 if ( !m_aPageWindowAdapters.empty() ) 494 { 495 for ( PageWindowAdapterList::const_iterator loop = m_aPageWindowAdapters.begin(); 496 loop != m_aPageWindowAdapters.end(); 497 ++loop 498 ) 499 { 500 (*loop)->dispose(); 501 } 502 } 503 504 cancelEvents(); 505 506 delete m_pWatchStoredList; 507 m_pWatchStoredList = NULL; 508 } 509 510 // EventListener 511 //------------------------------------------------------------------------------ 512 void SAL_CALL FmXFormView::disposing(const EventObject& Source) throw( RuntimeException ) 513 { 514 if ( m_xWindow.is() && Source.Source == m_xWindow ) 515 removeGridWindowListening(); 516 } 517 518 // XFormControllerListener 519 //------------------------------------------------------------------------------ 520 void SAL_CALL FmXFormView::formActivated(const EventObject& rEvent) throw( RuntimeException ) 521 { 522 if ( m_pView && m_pView->GetFormShell() && m_pView->GetFormShell()->GetImpl() ) 523 m_pView->GetFormShell()->GetImpl()->formActivated( rEvent ); 524 } 525 526 //------------------------------------------------------------------------------ 527 void SAL_CALL FmXFormView::formDeactivated(const EventObject& rEvent) throw( RuntimeException ) 528 { 529 if ( m_pView && m_pView->GetFormShell() && m_pView->GetFormShell()->GetImpl() ) 530 m_pView->GetFormShell()->GetImpl()->formDeactivated( rEvent ); 531 } 532 533 // XContainerListener 534 //------------------------------------------------------------------------------ 535 void SAL_CALL FmXFormView::elementInserted(const ContainerEvent& evt) throw( RuntimeException ) 536 { 537 try 538 { 539 Reference< XControlContainer > xControlContainer( evt.Source, UNO_QUERY_THROW ); 540 Reference< XControl > xControl( evt.Element, UNO_QUERY_THROW ); 541 Reference< XFormComponent > xControlModel( xControl->getModel(), UNO_QUERY_THROW ); 542 Reference< XForm > xForm( xControlModel->getParent(), UNO_QUERY_THROW ); 543 544 if ( m_isTabOrderUpdateSuspended ) 545 { 546 // remember the container and the control, so we can update the tab order on resumeTabOrderUpdate 547 m_aNeedTabOrderUpdate[ xControlContainer ].insert( xForm ); 548 } 549 else 550 { 551 PFormViewPageWindowAdapter pAdapter = findWindow( xControlContainer ); 552 if ( pAdapter.is() ) 553 pAdapter->updateTabOrder( xForm ); 554 } 555 } 556 catch( const Exception& ) 557 { 558 DBG_UNHANDLED_EXCEPTION(); 559 } 560 } 561 562 //------------------------------------------------------------------------------ 563 void SAL_CALL FmXFormView::elementReplaced(const ContainerEvent& evt) throw( RuntimeException ) 564 { 565 elementInserted(evt); 566 } 567 568 //------------------------------------------------------------------------------ 569 void SAL_CALL FmXFormView::elementRemoved(const ContainerEvent& /*evt*/) throw( RuntimeException ) 570 { 571 } 572 573 //------------------------------------------------------------------------------ 574 PFormViewPageWindowAdapter FmXFormView::findWindow( const Reference< XControlContainer >& _rxCC ) const 575 { 576 for ( PageWindowAdapterList::const_iterator i = m_aPageWindowAdapters.begin(); 577 i != m_aPageWindowAdapters.end(); 578 ++i 579 ) 580 { 581 if ( _rxCC == (*i)->getControlContainer() ) 582 return *i; 583 } 584 return NULL; 585 } 586 587 //------------------------------------------------------------------------------ 588 void FmXFormView::addWindow(const SdrPageWindow& rWindow) 589 { 590 FmFormPage* pFormPage = PTR_CAST( FmFormPage, rWindow.GetPageView().GetPage() ); 591 if ( !pFormPage ) 592 return; 593 594 Reference< XControlContainer > xCC = rWindow.GetControlContainer(); 595 if ( xCC.is() 596 && ( !findWindow( xCC ).is() ) 597 ) 598 { 599 PFormViewPageWindowAdapter pAdapter = new FormViewPageWindowAdapter( m_aContext, rWindow, this ); 600 m_aPageWindowAdapters.push_back( pAdapter ); 601 602 // Am ControlContainer horchen um Aenderungen mitzbekommen 603 Reference< XContainer > xContainer( xCC, UNO_QUERY ); 604 if ( xContainer.is() ) 605 xContainer->addContainerListener( this ); 606 } 607 } 608 609 //------------------------------------------------------------------------------ 610 void FmXFormView::removeWindow( const Reference< XControlContainer >& _rxCC ) 611 { 612 // Wird gerufen, wenn 613 // - in den Design-Modus geschaltet wird 614 // - ein Window geloescht wird, waehrend man im Design-Modus ist 615 // - der Control-Container fuer ein Window entfernt wird, waehrend 616 // der aktive Modus eingeschaltet ist. 617 618 for ( PageWindowAdapterList::iterator i = m_aPageWindowAdapters.begin(); 619 i != m_aPageWindowAdapters.end(); 620 ++i 621 ) 622 { 623 if ( _rxCC != (*i)->getControlContainer() ) 624 continue; 625 626 Reference< XContainer > xContainer( _rxCC, UNO_QUERY ); 627 if ( xContainer.is() ) 628 xContainer->removeContainerListener( this ); 629 630 (*i)->dispose(); 631 m_aPageWindowAdapters.erase( i ); 632 break; 633 } 634 } 635 636 //------------------------------------------------------------------------------ 637 void FmXFormView::displayAsyncErrorMessage( const SQLErrorEvent& _rEvent ) 638 { 639 DBG_ASSERT( 0 == m_nErrorMessageEvent, "FmXFormView::displayAsyncErrorMessage: not too fast, please!" ); 640 // This should not happen - usually, the PostUserEvent is faster than any possible user 641 // interaction which could trigger a new error. If it happens, we need a queue for the events. 642 m_aAsyncError = _rEvent; 643 m_nErrorMessageEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnDelayedErrorMessage ) ); 644 } 645 646 //------------------------------------------------------------------------------ 647 IMPL_LINK(FmXFormView, OnDelayedErrorMessage, void*, /*EMPTYTAG*/) 648 { 649 m_nErrorMessageEvent = 0; 650 displayException( m_aAsyncError ); 651 return 0L; 652 } 653 654 //------------------------------------------------------------------------------ 655 void FmXFormView::onFirstViewActivation( const FmFormModel* _pDocModel ) 656 { 657 if ( _pDocModel && _pDocModel->GetAutoControlFocus() ) 658 m_nAutoFocusEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnAutoFocus ) ); 659 } 660 661 //------------------------------------------------------------------------------ 662 void FmXFormView::suspendTabOrderUpdate() 663 { 664 OSL_ENSURE( !m_isTabOrderUpdateSuspended, "FmXFormView::suspendTabOrderUpdate: nesting not allowed!" ); 665 m_isTabOrderUpdateSuspended = true; 666 } 667 668 //------------------------------------------------------------------------------ 669 void FmXFormView::resumeTabOrderUpdate() 670 { 671 OSL_ENSURE( m_isTabOrderUpdateSuspended, "FmXFormView::resumeTabOrderUpdate: not suspended!" ); 672 m_isTabOrderUpdateSuspended = false; 673 674 // update the tab orders for all components which were collected since the suspendTabOrderUpdate call. 675 for ( MapControlContainerToSetOfForms::const_iterator container = m_aNeedTabOrderUpdate.begin(); 676 container != m_aNeedTabOrderUpdate.end(); 677 ++container 678 ) 679 { 680 PFormViewPageWindowAdapter pAdapter = findWindow( container->first ); 681 if ( !pAdapter.is() ) 682 continue; 683 684 for ( SetOfForms::const_iterator form = container->second.begin(); 685 form != container->second.end(); 686 ++form 687 ) 688 { 689 pAdapter->updateTabOrder( *form ); 690 } 691 } 692 m_aNeedTabOrderUpdate.clear(); 693 } 694 695 //------------------------------------------------------------------------------ 696 IMPL_LINK(FmXFormView, OnActivate, void*, /*EMPTYTAG*/) 697 { 698 m_nActivationEvent = 0; 699 700 if ( !m_pView ) 701 { 702 DBG_ERROR( "FmXFormView::OnActivate: well .... seems we have a timing problem (the view already died)!" ); 703 return 0; 704 } 705 706 // setting the controller to activate 707 if (m_pView->GetFormShell() && m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW) 708 { 709 Window* pWindow = const_cast<Window*>(static_cast<const Window*>(m_pView->GetActualOutDev())); 710 PFormViewPageWindowAdapter pAdapter = m_aPageWindowAdapters.empty() ? NULL : m_aPageWindowAdapters[0]; 711 for ( PageWindowAdapterList::const_iterator i = m_aPageWindowAdapters.begin(); 712 i != m_aPageWindowAdapters.end(); 713 ++i 714 ) 715 { 716 if ( pWindow == (*i)->getWindow() ) 717 pAdapter =*i; 718 } 719 720 if ( pAdapter.get() ) 721 { 722 for ( ::std::vector< Reference< XFormController > >::const_iterator i = pAdapter->GetList().begin(); 723 i != pAdapter->GetList().end(); 724 ++i 725 ) 726 { 727 const Reference< XFormController > & xController = *i; 728 if ( !xController.is() ) 729 continue; 730 731 // only database forms are to be activated 732 Reference< XRowSet > xForm(xController->getModel(), UNO_QUERY); 733 if ( !xForm.is() || !OStaticDataAccessTools().getRowSetConnection( xForm ).is() ) 734 continue; 735 736 Reference< XPropertySet > xFormSet( xForm, UNO_QUERY ); 737 ENSURE_OR_CONTINUE( xFormSet.is(), "FmXFormView::OnActivate: a form which does not have properties?" ); 738 739 const ::rtl::OUString aSource = ::comphelper::getString( xFormSet->getPropertyValue( FM_PROP_COMMAND ) ); 740 if ( aSource.getLength() ) 741 { 742 FmXFormShell* pShImpl = m_pView->GetFormShell()->GetImpl(); 743 if ( pShImpl ) 744 pShImpl->setActiveController( xController ); 745 break; 746 } 747 } 748 } 749 } 750 return 0; 751 } 752 753 //------------------------------------------------------------------------------ 754 void FmXFormView::Activate(sal_Bool bSync) 755 { 756 if (m_nActivationEvent) 757 { 758 Application::RemoveUserEvent(m_nActivationEvent); 759 m_nActivationEvent = 0; 760 } 761 762 if (bSync) 763 { 764 LINK(this,FmXFormView,OnActivate).Call(NULL); 765 } 766 else 767 m_nActivationEvent = Application::PostUserEvent(LINK(this,FmXFormView,OnActivate)); 768 } 769 770 //------------------------------------------------------------------------------ 771 void FmXFormView::Deactivate(sal_Bool bDeactivateController) 772 { 773 if (m_nActivationEvent) 774 { 775 Application::RemoveUserEvent(m_nActivationEvent); 776 m_nActivationEvent = 0; 777 } 778 779 FmXFormShell* pShImpl = m_pView->GetFormShell() ? m_pView->GetFormShell()->GetImpl() : NULL; 780 if (pShImpl && bDeactivateController) 781 pShImpl->setActiveController( NULL ); 782 } 783 784 //------------------------------------------------------------------------------ 785 FmFormShell* FmXFormView::GetFormShell() const 786 { 787 return m_pView ? m_pView->GetFormShell() : NULL; 788 } 789 // ----------------------------------------------------------------------------- 790 void FmXFormView::AutoFocus( sal_Bool _bSync ) 791 { 792 if (m_nAutoFocusEvent) 793 Application::RemoveUserEvent(m_nAutoFocusEvent); 794 795 if ( _bSync ) 796 OnAutoFocus( NULL ); 797 else 798 m_nAutoFocusEvent = Application::PostUserEvent(LINK(this, FmXFormView, OnAutoFocus)); 799 } 800 801 // ----------------------------------------------------------------------------- 802 bool FmXFormView::isFocusable( const Reference< XControl >& i_rControl ) 803 { 804 if ( !i_rControl.is() ) 805 return false; 806 807 try 808 { 809 Reference< XPropertySet > xModelProps( i_rControl->getModel(), UNO_QUERY_THROW ); 810 811 // only enabled controls are allowed to participate 812 sal_Bool bEnabled = sal_False; 813 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_ENABLED ) >>= bEnabled ); 814 if ( !bEnabled ) 815 return false; 816 817 // check the class id of the control model 818 sal_Int16 nClassId = FormComponentType::CONTROL; 819 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId ); 820 821 // controls which are not focussable 822 if ( ( FormComponentType::CONTROL != nClassId ) 823 && ( FormComponentType::IMAGEBUTTON != nClassId ) 824 && ( FormComponentType::GROUPBOX != nClassId ) 825 && ( FormComponentType::FIXEDTEXT != nClassId ) 826 && ( FormComponentType::HIDDENCONTROL != nClassId ) 827 && ( FormComponentType::IMAGECONTROL != nClassId ) 828 && ( FormComponentType::SCROLLBAR != nClassId ) 829 && ( FormComponentType::SPINBUTTON!= nClassId ) 830 ) 831 { 832 return true; 833 } 834 } 835 catch( const Exception& e ) 836 { 837 DBG_UNHANDLED_EXCEPTION(); 838 } 839 return false; 840 } 841 842 // ----------------------------------------------------------------------------- 843 static Reference< XControl > lcl_firstFocussableControl( const Sequence< Reference< XControl > >& _rControls ) 844 { 845 Reference< XControl > xReturn; 846 847 // loop through all the controls 848 const Reference< XControl >* pControls = _rControls.getConstArray(); 849 const Reference< XControl >* pControlsEnd = _rControls.getConstArray() + _rControls.getLength(); 850 for ( ; pControls != pControlsEnd; ++pControls ) 851 { 852 if ( !pControls->is() ) 853 continue; 854 855 if ( FmXFormView::isFocusable( *pControls ) ) 856 { 857 xReturn = *pControls; 858 break; 859 } 860 } 861 862 if ( !xReturn.is() && _rControls.getLength() ) 863 xReturn = _rControls[0]; 864 865 return xReturn; 866 } 867 868 // ----------------------------------------------------------------------------- 869 namespace 870 { 871 // ......................................................................... 872 void lcl_ensureControlsOfFormExist_nothrow( const SdrPage& _rPage, const SdrView& _rView, const Window& _rWindow, const Reference< XForm >& _rxForm ) 873 { 874 try 875 { 876 Reference< XInterface > xNormalizedForm( _rxForm, UNO_QUERY_THROW ); 877 878 SdrObjListIter aSdrObjectLoop( _rPage, IM_DEEPNOGROUPS ); 879 while ( aSdrObjectLoop.IsMore() ) 880 { 881 FmFormObj* pFormObject = FmFormObj::GetFormObject( aSdrObjectLoop.Next() ); 882 if ( !pFormObject ) 883 continue; 884 885 Reference< XChild > xModel( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW ); 886 Reference< XInterface > xModelParent( xModel->getParent(), UNO_QUERY_THROW ); 887 888 if ( xNormalizedForm.get() != xModelParent.get() ) 889 continue; 890 891 pFormObject->GetUnoControl( _rView, _rWindow ); 892 } 893 } 894 catch( const Exception& ) 895 { 896 DBG_UNHANDLED_EXCEPTION(); 897 } 898 } 899 } 900 901 // ----------------------------------------------------------------------------- 902 Reference< XFormController > FmXFormView::getFormController( const Reference< XForm >& _rxForm, const OutputDevice& _rDevice ) const 903 { 904 Reference< XFormController > xController; 905 906 for ( PageWindowAdapterList::const_iterator pos = m_aPageWindowAdapters.begin(); 907 pos != m_aPageWindowAdapters.end(); 908 ++pos 909 ) 910 { 911 const PFormViewPageWindowAdapter pAdapter( *pos ); 912 ENSURE_OR_CONTINUE( pAdapter.get(), "FmXFormView::getFormController: invalid page window adapter!" ); 913 if ( pAdapter->getWindow() != &_rDevice ) 914 // wrong device 915 continue; 916 917 xController = pAdapter->getController( _rxForm ); 918 if ( xController.is() ) 919 break; 920 } 921 return xController; 922 } 923 924 // ----------------------------------------------------------------------------- 925 IMPL_LINK(FmXFormView, OnAutoFocus, void*, /*EMPTYTAG*/) 926 { 927 m_nAutoFocusEvent = 0; 928 929 // go to the first form of our page, examine it's TabController, go to it's first (in terms of the tab order) 930 // control, give it the focus 931 932 do 933 { 934 935 // get the forms collection of the page we belong to 936 FmFormPage* pPage = m_pView ? PTR_CAST( FmFormPage, m_pView->GetSdrPageView()->GetPage() ) : NULL; 937 Reference< XIndexAccess > xForms( pPage ? Reference< XIndexAccess >( pPage->GetForms(), UNO_QUERY ) : Reference< XIndexAccess >() ); 938 939 const PFormViewPageWindowAdapter pAdapter = m_aPageWindowAdapters.empty() ? NULL : m_aPageWindowAdapters[0]; 940 const Window* pWindow = pAdapter.get() ? pAdapter->getWindow() : NULL; 941 942 ENSURE_OR_RETURN( xForms.is() && pWindow, "FmXFormView::OnAutoFocus: could not collect all essentials!", 0L ); 943 944 try 945 { 946 // go for the tab controller of the first form 947 if ( !xForms->getCount() ) 948 break; 949 Reference< XForm > xForm( xForms->getByIndex( 0 ), UNO_QUERY_THROW ); 950 Reference< XTabController > xTabController( pAdapter->getController( xForm ), UNO_QUERY_THROW ); 951 952 // go for the first control of the controller 953 Sequence< Reference< XControl > > aControls( xTabController->getControls() ); 954 if ( aControls.getLength() == 0 ) 955 { 956 Reference< XElementAccess > xFormElementAccess( xForm, UNO_QUERY_THROW ); 957 if ( xFormElementAccess->hasElements() ) 958 { 959 // there are control models in the form, but no controls, yet. 960 // Well, since some time controls are created on demand only. In particular, 961 // they're normally created when they're first painted. 962 // Unfortunately, the FormController does not have any way to 963 // trigger the creation itself, so we must hack this ... 964 lcl_ensureControlsOfFormExist_nothrow( *pPage, *m_pView, *pWindow, xForm ); 965 aControls = xTabController->getControls(); 966 OSL_ENSURE( aControls.getLength(), "FmXFormView::OnAutoFocus: no controls at all!" ); 967 } 968 } 969 970 // set the focus to this first control 971 Reference< XWindow > xControlWindow( lcl_firstFocussableControl( aControls ), UNO_QUERY ); 972 if ( !xControlWindow.is() ) 973 break; 974 975 xControlWindow->setFocus(); 976 977 // ensure that the control is visible 978 // 80210 - 12/07/00 - FS 979 const Window* pCurrentWindow = dynamic_cast< const Window* >( m_pView->GetActualOutDev() ); 980 if ( pCurrentWindow ) 981 { 982 awt::Rectangle aRect = xControlWindow->getPosSize(); 983 ::Rectangle aNonUnoRect( aRect.X, aRect.Y, aRect.X + aRect.Width, aRect.Y + aRect.Height ); 984 m_pView->MakeVisible( pCurrentWindow->PixelToLogic( aNonUnoRect ), *const_cast< Window* >( pCurrentWindow ) ); 985 } 986 } 987 catch( const Exception& ) 988 { 989 DBG_UNHANDLED_EXCEPTION(); 990 } 991 992 } // do 993 while ( false ); 994 995 return 1L; 996 } 997 998 // ----------------------------------------------------------------------------- 999 void FmXFormView::onCreatedFormObject( FmFormObj& _rFormObject ) 1000 { 1001 FmFormShell* pShell = m_pView ? m_pView->GetFormShell() : NULL; 1002 FmXFormShell* pShellImpl = pShell ? pShell->GetImpl() : NULL; 1003 OSL_ENSURE( pShellImpl, "FmXFormView::onCreatedFormObject: no form shell!" ); 1004 if ( !pShellImpl ) 1005 return; 1006 1007 // it is valid that the form shell's forms collection is not initialized, yet 1008 pShellImpl->UpdateForms( sal_True ); 1009 1010 m_xLastCreatedControlModel.set( _rFormObject.GetUnoControlModel(), UNO_QUERY ); 1011 if ( !m_xLastCreatedControlModel.is() ) 1012 return; 1013 1014 // some initial property defaults 1015 FormControlFactory aControlFactory( m_aContext ); 1016 aControlFactory.initializeControlModel( pShellImpl->getDocumentType(), _rFormObject ); 1017 1018 if ( !pShellImpl->GetWizardUsing() ) 1019 return; 1020 1021 // #i31958# don't call wizards in XForms mode 1022 if ( pShellImpl->isEnhancedForm() ) 1023 return; 1024 1025 // #i46898# no wizards if there is no Base installed - currently, all wizards are 1026 // database related 1027 if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) ) 1028 return; 1029 1030 if ( m_nControlWizardEvent ) 1031 Application::RemoveUserEvent( m_nControlWizardEvent ); 1032 m_nControlWizardEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnStartControlWizard ) ); 1033 } 1034 1035 // ----------------------------------------------------------------------------- 1036 IMPL_LINK( FmXFormView, OnStartControlWizard, void*, /**/ ) 1037 { 1038 m_nControlWizardEvent = 0; 1039 OSL_PRECOND( m_xLastCreatedControlModel.is(), "FmXFormView::OnStartControlWizard: illegal call!" ); 1040 if ( !m_xLastCreatedControlModel.is() ) 1041 return 0L; 1042 1043 sal_Int16 nClassId = FormComponentType::CONTROL; 1044 try 1045 { 1046 OSL_VERIFY( m_xLastCreatedControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId ); 1047 } 1048 catch( const Exception& ) 1049 { 1050 DBG_UNHANDLED_EXCEPTION(); 1051 } 1052 1053 const sal_Char* pWizardAsciiName = NULL; 1054 switch ( nClassId ) 1055 { 1056 case FormComponentType::GRIDCONTROL: 1057 pWizardAsciiName = "com.sun.star.sdb.GridControlAutoPilot"; 1058 break; 1059 case FormComponentType::LISTBOX: 1060 case FormComponentType::COMBOBOX: 1061 pWizardAsciiName = "com.sun.star.sdb.ListComboBoxAutoPilot"; 1062 break; 1063 case FormComponentType::GROUPBOX: 1064 pWizardAsciiName = "com.sun.star.sdb.GroupBoxAutoPilot"; 1065 break; 1066 } 1067 1068 if ( pWizardAsciiName ) 1069 { 1070 // build the argument list 1071 ::comphelper::NamedValueCollection aWizardArgs; 1072 aWizardArgs.put( "ObjectModel", m_xLastCreatedControlModel ); 1073 1074 // create the wizard object 1075 Reference< XExecutableDialog > xWizard; 1076 try 1077 { 1078 m_aContext.createComponentWithArguments( pWizardAsciiName, aWizardArgs.getWrappedPropertyValues(), xWizard ); 1079 } 1080 catch( const Exception& ) 1081 { 1082 DBG_UNHANDLED_EXCEPTION(); 1083 } 1084 1085 if ( !xWizard.is() ) 1086 { 1087 ShowServiceNotAvailableError( NULL, String::CreateFromAscii( pWizardAsciiName ), sal_True ); 1088 } 1089 else 1090 { 1091 // execute the wizard 1092 try 1093 { 1094 xWizard->execute(); 1095 } 1096 catch( const Exception& ) 1097 { 1098 DBG_UNHANDLED_EXCEPTION(); 1099 } 1100 } 1101 } 1102 1103 m_xLastCreatedControlModel.clear(); 1104 return 1L; 1105 } 1106 1107 // ----------------------------------------------------------------------------- 1108 namespace 1109 { 1110 void lcl_insertIntoFormComponentHierarchy_throw( const FmFormView& _rView, const SdrUnoObj& _rSdrObj, 1111 const Reference< XDataSource >& _rxDataSource = NULL, const ::rtl::OUString& _rDataSourceName = ::rtl::OUString(), 1112 const ::rtl::OUString& _rCommand = ::rtl::OUString(), const sal_Int32 _nCommandType = -1 ) 1113 { 1114 FmFormPage& rPage = static_cast< FmFormPage& >( *_rView.GetSdrPageView()->GetPage() ); 1115 1116 Reference< XFormComponent > xFormComponent( _rSdrObj.GetUnoControlModel(), UNO_QUERY_THROW ); 1117 Reference< XForm > xTargetForm( 1118 rPage.GetImpl().findPlaceInFormComponentHierarchy( xFormComponent, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType ), 1119 UNO_SET_THROW ); 1120 1121 rPage.GetImpl().setUniqueName( xFormComponent, xTargetForm ); 1122 1123 Reference< XIndexContainer > xFormAsContainer( xTargetForm, UNO_QUERY_THROW ); 1124 xFormAsContainer->insertByIndex( xFormAsContainer->getCount(), makeAny( xFormComponent ) ); 1125 } 1126 } 1127 1128 // ----------------------------------------------------------------------------- 1129 SdrObject* FmXFormView::implCreateFieldControl( const ::svx::ODataAccessDescriptor& _rColumnDescriptor ) 1130 { 1131 // not if we're in design mode 1132 if ( !m_pView->IsDesignMode() ) 1133 return NULL; 1134 1135 ::rtl::OUString sCommand, sFieldName; 1136 sal_Int32 nCommandType = CommandType::COMMAND; 1137 SharedConnection xConnection; 1138 1139 ::rtl::OUString sDataSource = _rColumnDescriptor.getDataSource(); 1140 _rColumnDescriptor[ daCommand ] >>= sCommand; 1141 _rColumnDescriptor[ daColumnName ] >>= sFieldName; 1142 _rColumnDescriptor[ daCommandType ] >>= nCommandType; 1143 { 1144 Reference< XConnection > xExternalConnection; 1145 _rColumnDescriptor[ daConnection ] >>= xExternalConnection; 1146 xConnection.reset( xExternalConnection, SharedConnection::NoTakeOwnership ); 1147 } 1148 1149 if ( !sCommand.getLength() 1150 || !sFieldName.getLength() 1151 || ( !sDataSource.getLength() 1152 && !xConnection.is() 1153 ) 1154 ) 1155 { 1156 DBG_ERROR( "FmXFormView::implCreateFieldControl: nonsense!" ); 1157 } 1158 1159 Reference< XDataSource > xDataSource; 1160 SQLErrorEvent aError; 1161 try 1162 { 1163 if ( xConnection.is() && !xDataSource.is() && !sDataSource.getLength() ) 1164 { 1165 Reference< XChild > xChild( xConnection, UNO_QUERY ); 1166 if ( xChild.is() ) 1167 xDataSource = xDataSource.query( xChild->getParent() ); 1168 } 1169 1170 // obtain the data source 1171 if ( !xDataSource.is() ) 1172 xDataSource = OStaticDataAccessTools().getDataSource( sDataSource, m_aContext.getLegacyServiceFactory() ); 1173 1174 // and the connection, if necessary 1175 if ( !xConnection.is() ) 1176 xConnection.reset( OStaticDataAccessTools().getConnection_withFeedback( 1177 sDataSource, 1178 ::rtl::OUString(), 1179 ::rtl::OUString(), 1180 m_aContext.getLegacyServiceFactory() 1181 ) ); 1182 } 1183 catch ( const SQLException& ) 1184 { 1185 aError.Reason = ::cppu::getCaughtException(); 1186 } 1187 catch( const Exception& ) { /* will be asserted below */ } 1188 if (aError.Reason.hasValue()) 1189 { 1190 displayAsyncErrorMessage( aError ); 1191 return NULL; 1192 } 1193 1194 // need a data source and a connection here 1195 if (!xDataSource.is() || !xConnection.is()) 1196 { 1197 DBG_ERROR("FmXFormView::implCreateFieldControl : could not retrieve the data source or the connection!"); 1198 return NULL; 1199 } 1200 1201 OStaticDataAccessTools aDBATools; 1202 Reference< XComponent > xKeepFieldsAlive; 1203 // go 1204 try 1205 { 1206 // determine the table/query field which we should create a control for 1207 Reference< XPropertySet > xField; 1208 1209 Reference< XNameAccess > xFields = aDBATools.getFieldsByCommandDescriptor( 1210 xConnection, nCommandType, sCommand, xKeepFieldsAlive ); 1211 1212 if (xFields.is() && xFields->hasByName(sFieldName)) 1213 xFields->getByName(sFieldName) >>= xField; 1214 if ( !xField.is() ) 1215 return NULL; 1216 1217 Reference< XNumberFormatsSupplier > xSupplier( aDBATools.getNumberFormats( xConnection, sal_False ), UNO_SET_THROW ); 1218 Reference< XNumberFormats > xNumberFormats( xSupplier->getNumberFormats(), UNO_SET_THROW ); 1219 1220 ::rtl::OUString sLabelPostfix; 1221 1222 //////////////////////////////////////////////////////////////// 1223 // nur fuer Textgroesse 1224 OutputDevice* pOutDev = NULL; 1225 if (m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW) 1226 pOutDev = const_cast<OutputDevice*>(m_pView->GetActualOutDev()); 1227 else 1228 {// OutDev suchen 1229 SdrPageView* pPageView = m_pView->GetSdrPageView(); 1230 if( pPageView && !pOutDev ) 1231 { 1232 // const SdrPageViewWinList& rWinList = pPageView->GetWinList(); 1233 // const SdrPageViewWindows& rPageViewWindows = pPageView->GetPageViewWindows(); 1234 1235 for( sal_uInt32 i = 0L; i < pPageView->PageWindowCount(); i++ ) 1236 { 1237 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(i); 1238 1239 if( rPageWindow.GetPaintWindow().OutputToWindow()) 1240 { 1241 pOutDev = &rPageWindow.GetPaintWindow().GetOutputDevice(); 1242 break; 1243 } 1244 } 1245 } 1246 } 1247 1248 if ( !pOutDev ) 1249 return NULL; 1250 1251 sal_Int32 nDataType = ::comphelper::getINT32(xField->getPropertyValue(FM_PROP_FIELDTYPE)); 1252 if ((DataType::BINARY == nDataType) || (DataType::VARBINARY == nDataType)) 1253 return NULL; 1254 1255 ////////////////////////////////////////////////////////////////////// 1256 // determine the control type by examining the data type of the bound column 1257 sal_uInt16 nOBJID = 0; 1258 sal_Bool bDateNTimeField = sal_False; 1259 1260 sal_Bool bIsCurrency = sal_False; 1261 if (::comphelper::hasProperty(FM_PROP_ISCURRENCY, xField)) 1262 bIsCurrency = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_ISCURRENCY)); 1263 1264 if (bIsCurrency) 1265 nOBJID = OBJ_FM_CURRENCYFIELD; 1266 else 1267 switch (nDataType) 1268 { 1269 case DataType::BLOB: 1270 case DataType::LONGVARBINARY: 1271 nOBJID = OBJ_FM_IMAGECONTROL; 1272 break; 1273 case DataType::LONGVARCHAR: 1274 case DataType::CLOB: 1275 nOBJID = OBJ_FM_EDIT; 1276 break; 1277 case DataType::BINARY: 1278 case DataType::VARBINARY: 1279 return NULL; 1280 case DataType::BIT: 1281 case DataType::BOOLEAN: 1282 nOBJID = OBJ_FM_CHECKBOX; 1283 break; 1284 case DataType::TINYINT: 1285 case DataType::SMALLINT: 1286 case DataType::INTEGER: 1287 nOBJID = OBJ_FM_NUMERICFIELD; 1288 break; 1289 case DataType::REAL: 1290 case DataType::DOUBLE: 1291 case DataType::NUMERIC: 1292 case DataType::DECIMAL: 1293 nOBJID = OBJ_FM_FORMATTEDFIELD; 1294 break; 1295 case DataType::TIMESTAMP: 1296 bDateNTimeField = sal_True; 1297 sLabelPostfix = String( SVX_RES( RID_STR_POSTFIX_DATE ) ); 1298 // DON'T break ! 1299 case DataType::DATE: 1300 nOBJID = OBJ_FM_DATEFIELD; 1301 break; 1302 case DataType::TIME: 1303 nOBJID = OBJ_FM_TIMEFIELD; 1304 break; 1305 case DataType::CHAR: 1306 case DataType::VARCHAR: 1307 default: 1308 nOBJID = OBJ_FM_EDIT; 1309 break; 1310 } 1311 if (!nOBJID) 1312 return NULL; 1313 1314 SdrUnoObj* pLabel( NULL ); 1315 SdrUnoObj* pControl( NULL ); 1316 if ( !createControlLabelPair( *pOutDev, 0, 0, xField, xNumberFormats, nOBJID, sLabelPostfix, 1317 pLabel, pControl, xDataSource, sDataSource, sCommand, nCommandType ) 1318 ) 1319 { 1320 return NULL; 1321 } 1322 1323 ////////////////////////////////////////////////////////////////////// 1324 // group objects 1325 bool bCheckbox = ( OBJ_FM_CHECKBOX == nOBJID ); 1326 OSL_ENSURE( !bCheckbox || !pLabel, "FmXFormView::implCreateFieldControl: why was there a label created for a check box?" ); 1327 if ( bCheckbox ) 1328 return pControl; 1329 1330 SdrObjGroup* pGroup = new SdrObjGroup(); 1331 SdrObjList* pObjList = pGroup->GetSubList(); 1332 pObjList->InsertObject( pLabel ); 1333 pObjList->InsertObject( pControl ); 1334 1335 if ( bDateNTimeField ) 1336 { // so far we created a date field only, but we also need a time field 1337 pLabel = pControl = NULL; 1338 if ( createControlLabelPair( *pOutDev, 0, 1000, xField, xNumberFormats, OBJ_FM_TIMEFIELD, 1339 String( SVX_RES( RID_STR_POSTFIX_TIME ) ), pLabel, pControl, 1340 xDataSource, sDataSource, sCommand, nCommandType ) 1341 ) 1342 { 1343 pObjList->InsertObject( pLabel ); 1344 pObjList->InsertObject( pControl ); 1345 } 1346 } 1347 1348 return pGroup; // und fertig 1349 } 1350 catch(const Exception&) 1351 { 1352 DBG_UNHANDLED_EXCEPTION(); 1353 } 1354 1355 1356 return NULL; 1357 } 1358 1359 // ----------------------------------------------------------------------------- 1360 SdrObject* FmXFormView::implCreateXFormsControl( const ::svx::OXFormsDescriptor &_rDesc ) 1361 { 1362 // not if we're in design mode 1363 if ( !m_pView->IsDesignMode() ) 1364 return NULL; 1365 1366 Reference< XComponent > xKeepFieldsAlive; 1367 1368 // go 1369 try 1370 { 1371 // determine the table/query field which we should create a control for 1372 Reference< XNumberFormats > xNumberFormats; 1373 ::rtl::OUString sLabelPostfix = _rDesc.szName; 1374 1375 //////////////////////////////////////////////////////////////// 1376 // nur fuer Textgroesse 1377 OutputDevice* pOutDev = NULL; 1378 if (m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW) 1379 pOutDev = const_cast<OutputDevice*>(m_pView->GetActualOutDev()); 1380 else 1381 {// OutDev suchen 1382 SdrPageView* pPageView = m_pView->GetSdrPageView(); 1383 if( pPageView && !pOutDev ) 1384 { 1385 // const SdrPageViewWinList& rWinList = pPageView->GetWinList(); 1386 // const SdrPageViewWindows& rPageViewWindows = pPageView->GetPageViewWindows(); 1387 1388 for( sal_uInt32 i = 0L; i < pPageView->PageWindowCount(); i++ ) 1389 { 1390 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(i); 1391 1392 if( rPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType() == OUTDEV_WINDOW) 1393 { 1394 pOutDev = &rPageWindow.GetPaintWindow().GetOutputDevice(); 1395 break; 1396 } 1397 } 1398 } 1399 } 1400 1401 if ( !pOutDev ) 1402 return NULL; 1403 1404 ////////////////////////////////////////////////////////////////////// 1405 // The service name decides which control should be created 1406 sal_uInt16 nOBJID = OBJ_FM_EDIT; 1407 if(::rtl::OUString(_rDesc.szServiceName).equals((::rtl::OUString)FM_SUN_COMPONENT_NUMERICFIELD)) 1408 nOBJID = OBJ_FM_NUMERICFIELD; 1409 if(::rtl::OUString(_rDesc.szServiceName).equals((::rtl::OUString)FM_SUN_COMPONENT_CHECKBOX)) 1410 nOBJID = OBJ_FM_CHECKBOX; 1411 if(::rtl::OUString(_rDesc.szServiceName).equals((::rtl::OUString)FM_COMPONENT_COMMANDBUTTON)) 1412 nOBJID = OBJ_FM_BUTTON; 1413 1414 typedef ::com::sun::star::form::submission::XSubmission XSubmission_t; 1415 Reference< XSubmission_t > xSubmission(_rDesc.xPropSet, UNO_QUERY); 1416 1417 // xform control or submission button? 1418 if ( !xSubmission.is() ) 1419 { 1420 SdrUnoObj* pLabel( NULL ); 1421 SdrUnoObj* pControl( NULL ); 1422 if ( !createControlLabelPair( *pOutDev, 0, 0, NULL, xNumberFormats, nOBJID, sLabelPostfix, 1423 pLabel, pControl ) 1424 ) 1425 { 1426 return NULL; 1427 } 1428 1429 ////////////////////////////////////////////////////////////////////// 1430 // Now build the connection between the control and the data item. 1431 Reference< XValueBinding > xValueBinding(_rDesc.xPropSet,UNO_QUERY); 1432 Reference< XBindableValue > xBindableValue(pControl->GetUnoControlModel(),UNO_QUERY); 1433 1434 DBG_ASSERT( xBindableValue.is(), "FmXFormView::implCreateXFormsControl: control's not bindable!" ); 1435 if ( xBindableValue.is() ) 1436 xBindableValue->setValueBinding(xValueBinding); 1437 1438 bool bCheckbox = ( OBJ_FM_CHECKBOX == nOBJID ); 1439 OSL_ENSURE( !bCheckbox || !pLabel, "FmXFormView::implCreateXFormsControl: why was there a label created for a check box?" ); 1440 if ( bCheckbox ) 1441 return pControl; 1442 1443 ////////////////////////////////////////////////////////////////////// 1444 // group objects 1445 SdrObjGroup* pGroup = new SdrObjGroup(); 1446 SdrObjList* pObjList = pGroup->GetSubList(); 1447 pObjList->InsertObject(pLabel); 1448 pObjList->InsertObject(pControl); 1449 1450 return pGroup; 1451 } 1452 else { 1453 1454 // create a button control 1455 const MapMode eTargetMode( pOutDev->GetMapMode() ); 1456 const MapMode eSourceMode(MAP_100TH_MM); 1457 const sal_uInt16 nObjID = OBJ_FM_BUTTON; 1458 ::Size controlSize(4000, 500); 1459 FmFormObj *pControl = static_cast<FmFormObj*>(SdrObjFactory::MakeNewObject( FmFormInventor, nObjID, NULL, NULL )); 1460 controlSize.Width() = Fraction(controlSize.Width(), 1) * eTargetMode.GetScaleX(); 1461 controlSize.Height() = Fraction(controlSize.Height(), 1) * eTargetMode.GetScaleY(); 1462 ::Point controlPos( pOutDev->LogicToLogic( ::Point( controlSize.Width(), 0 ), eSourceMode, eTargetMode ) ); 1463 ::Rectangle controlRect( controlPos, pOutDev->LogicToLogic( controlSize, eSourceMode, eTargetMode ) ); 1464 pControl->SetLogicRect(controlRect); 1465 1466 // set the button label 1467 Reference< XPropertySet > xControlSet(pControl->GetUnoControlModel(), UNO_QUERY); 1468 xControlSet->setPropertyValue(FM_PROP_LABEL, makeAny(::rtl::OUString(_rDesc.szName))); 1469 1470 // connect the submission with the submission supplier (aka the button) 1471 xControlSet->setPropertyValue( FM_PROP_BUTTON_TYPE, 1472 makeAny( FormButtonType_SUBMIT ) ); 1473 typedef ::com::sun::star::form::submission::XSubmissionSupplier XSubmissionSupplier_t; 1474 Reference< XSubmissionSupplier_t > xSubmissionSupplier(pControl->GetUnoControlModel(), UNO_QUERY); 1475 xSubmissionSupplier->setSubmission(xSubmission); 1476 1477 return pControl; 1478 } 1479 } 1480 catch(const Exception&) 1481 { 1482 DBG_ERROR("FmXFormView::implCreateXFormsControl: caught an exception while creating the control !"); 1483 } 1484 1485 1486 return NULL; 1487 } 1488 1489 //------------------------------------------------------------------------ 1490 bool FmXFormView::createControlLabelPair( OutputDevice& _rOutDev, sal_Int32 _nXOffsetMM, sal_Int32 _nYOffsetMM, 1491 const Reference< XPropertySet >& _rxField, const Reference< XNumberFormats >& _rxNumberFormats, 1492 sal_uInt16 _nControlObjectID, const ::rtl::OUString& _rFieldPostfix, 1493 SdrUnoObj*& _rpLabel, SdrUnoObj*& _rpControl, 1494 const Reference< XDataSource >& _rxDataSource, const ::rtl::OUString& _rDataSourceName, 1495 const ::rtl::OUString& _rCommand, const sal_Int32 _nCommandType ) 1496 { 1497 if ( !createControlLabelPair( m_aContext, _rOutDev, _nXOffsetMM, _nYOffsetMM, 1498 _rxField, _rxNumberFormats, _nControlObjectID, _rFieldPostfix, FmFormInventor, OBJ_FM_FIXEDTEXT, 1499 NULL, NULL, NULL, _rpLabel, _rpControl ) 1500 ) 1501 return false; 1502 1503 // insert the control model(s) into the form component hierachy 1504 if ( _rpLabel ) 1505 lcl_insertIntoFormComponentHierarchy_throw( *m_pView, *_rpLabel, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType ); 1506 lcl_insertIntoFormComponentHierarchy_throw( *m_pView, *_rpControl, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType ); 1507 1508 // some context-dependent initializations 1509 FormControlFactory aControlFactory( m_aContext ); 1510 if ( _rpLabel ) 1511 aControlFactory.initializeControlModel( impl_getDocumentType(), *_rpLabel ); 1512 aControlFactory.initializeControlModel( impl_getDocumentType(), *_rpControl ); 1513 1514 return true; 1515 } 1516 1517 //------------------------------------------------------------------------ 1518 bool FmXFormView::createControlLabelPair( const ::comphelper::ComponentContext& _rContext, 1519 OutputDevice& _rOutDev, sal_Int32 _nXOffsetMM, sal_Int32 _nYOffsetMM, const Reference< XPropertySet >& _rxField, 1520 const Reference< XNumberFormats >& _rxNumberFormats, sal_uInt16 _nControlObjectID, 1521 const ::rtl::OUString& _rFieldPostfix, sal_uInt32 _nInventor, sal_uInt16 _nLabelObjectID, 1522 SdrPage* _pLabelPage, SdrPage* _pControlPage, SdrModel* _pModel, SdrUnoObj*& _rpLabel, SdrUnoObj*& _rpControl) 1523 { 1524 sal_Int32 nDataType = 0; 1525 ::rtl::OUString sFieldName; 1526 Any aFieldName; 1527 if ( _rxField.is() ) 1528 { 1529 nDataType = ::comphelper::getINT32(_rxField->getPropertyValue(FM_PROP_FIELDTYPE)); 1530 aFieldName = Any(_rxField->getPropertyValue(FM_PROP_NAME)); 1531 aFieldName >>= sFieldName; 1532 } 1533 1534 // calculate the positions, respecting the settings of the target device 1535 ::Size aTextSize( _rOutDev.GetTextWidth(sFieldName + _rFieldPostfix), _rOutDev.GetTextHeight() ); 1536 1537 MapMode eTargetMode( _rOutDev.GetMapMode() ), 1538 eSourceMode( MAP_100TH_MM ); 1539 1540 // Textbreite ist mindestens 4cm 1541 // Texthoehe immer halber cm 1542 ::Size aDefTxtSize(4000, 500); 1543 ::Size aDefSize(4000, 500); 1544 ::Size aDefImageSize(4000, 4000); 1545 1546 ::Size aRealSize = _rOutDev.LogicToLogic(aTextSize, eTargetMode, eSourceMode); 1547 aRealSize.Width() = std::max(aRealSize.Width(), aDefTxtSize.Width()); 1548 aRealSize.Height()= aDefSize.Height(); 1549 1550 // adjust to scaling of the target device (#53523#) 1551 aRealSize.Width() = long(Fraction(aRealSize.Width(), 1) * eTargetMode.GetScaleX()); 1552 aRealSize.Height() = long(Fraction(aRealSize.Height(), 1) * eTargetMode.GetScaleY()); 1553 1554 // for boolean fields, we do not create a label, but just a checkbox 1555 bool bNeedLabel = ( _nControlObjectID != OBJ_FM_CHECKBOX ); 1556 1557 // the label 1558 ::std::auto_ptr< SdrUnoObj > pLabel; 1559 Reference< XPropertySet > xLabelModel; 1560 if ( bNeedLabel ) 1561 { 1562 pLabel.reset( dynamic_cast< SdrUnoObj* >( 1563 SdrObjFactory::MakeNewObject( _nInventor, _nLabelObjectID, _pLabelPage, _pModel ) ) ); 1564 OSL_ENSURE( pLabel.get(), "FmXFormView::createControlLabelPair: could not create the label!" ); 1565 if ( !pLabel.get() ) 1566 return false; 1567 1568 xLabelModel.set( pLabel->GetUnoControlModel(), UNO_QUERY ); 1569 if ( xLabelModel.is() ) 1570 { 1571 ::rtl::OUString sLabel; 1572 if ( _rxField.is() && _rxField->getPropertySetInfo()->hasPropertyByName(FM_PROP_LABEL) ) 1573 _rxField->getPropertyValue(FM_PROP_LABEL) >>= sLabel; 1574 if ( !sLabel.getLength() ) 1575 sLabel = sFieldName; 1576 1577 xLabelModel->setPropertyValue( FM_PROP_LABEL, makeAny( sLabel + _rFieldPostfix ) ); 1578 String sObjectLabel( SVX_RES( RID_STR_OBJECT_LABEL ) ); 1579 sObjectLabel.SearchAndReplaceAllAscii( "#object#", sFieldName ); 1580 xLabelModel->setPropertyValue( FM_PROP_NAME, makeAny( ::rtl::OUString( sObjectLabel ) ) ); 1581 } 1582 1583 pLabel->SetLogicRect( ::Rectangle( 1584 _rOutDev.LogicToLogic( ::Point( _nXOffsetMM, _nYOffsetMM ), eSourceMode, eTargetMode ), 1585 _rOutDev.LogicToLogic( aRealSize, eSourceMode, eTargetMode ) 1586 ) ); 1587 } 1588 1589 // the control 1590 ::std::auto_ptr< SdrUnoObj > pControl( dynamic_cast< SdrUnoObj* >( 1591 SdrObjFactory::MakeNewObject( _nInventor, _nControlObjectID, _pControlPage, _pModel ) ) ); 1592 OSL_ENSURE( pControl.get(), "FmXFormView::createControlLabelPair: could not create the control!" ); 1593 if ( !pControl.get() ) 1594 return false; 1595 1596 Reference< XPropertySet > xControlSet( pControl->GetUnoControlModel(), UNO_QUERY ); 1597 if ( !xControlSet.is() ) 1598 return false; 1599 1600 // size of the control 1601 ::Size aControlSize( aDefSize ); 1602 switch ( nDataType ) 1603 { 1604 case DataType::BIT: 1605 case DataType::BOOLEAN: 1606 aControlSize = aDefSize; 1607 break; 1608 case DataType::LONGVARCHAR: 1609 case DataType::CLOB: 1610 case DataType::LONGVARBINARY: 1611 case DataType::BLOB: 1612 aControlSize = aDefImageSize; 1613 break; 1614 } 1615 1616 if ( OBJ_FM_IMAGECONTROL == _nControlObjectID ) 1617 aControlSize = aDefImageSize; 1618 1619 aControlSize.Width() = long(Fraction(aControlSize.Width(), 1) * eTargetMode.GetScaleX()); 1620 aControlSize.Height() = long(Fraction(aControlSize.Height(), 1) * eTargetMode.GetScaleY()); 1621 1622 pControl->SetLogicRect( ::Rectangle( 1623 _rOutDev.LogicToLogic( ::Point( aRealSize.Width() + _nXOffsetMM, _nYOffsetMM ), eSourceMode, eTargetMode ), 1624 _rOutDev.LogicToLogic( aControlSize, eSourceMode, eTargetMode ) 1625 ) ); 1626 1627 // some initializations 1628 Reference< XPropertySetInfo > xControlPropInfo = xControlSet->getPropertySetInfo(); 1629 1630 if ( aFieldName.hasValue() ) 1631 { 1632 xControlSet->setPropertyValue( FM_PROP_CONTROLSOURCE, aFieldName ); 1633 xControlSet->setPropertyValue( FM_PROP_NAME, aFieldName ); 1634 if ( !bNeedLabel ) 1635 { 1636 // no dedicated label control => use the label property 1637 if ( xControlPropInfo->hasPropertyByName( FM_PROP_LABEL ) ) 1638 xControlSet->setPropertyValue( FM_PROP_LABEL, makeAny( sFieldName + _rFieldPostfix ) ); 1639 else 1640 OSL_ENSURE( false, "FmXFormView::createControlLabelPair: can't set a label for the control!" ); 1641 } 1642 } 1643 1644 if ( (nDataType == DataType::LONGVARCHAR || nDataType == DataType::CLOB) && xControlPropInfo->hasPropertyByName( FM_PROP_MULTILINE ) ) 1645 { 1646 xControlSet->setPropertyValue( FM_PROP_MULTILINE, makeAny( sal_Bool( sal_True ) ) ); 1647 } 1648 1649 // announce the label to the control 1650 if ( xControlPropInfo->hasPropertyByName( FM_PROP_CONTROLLABEL ) && xLabelModel.is() ) 1651 { 1652 try 1653 { 1654 xControlSet->setPropertyValue( FM_PROP_CONTROLLABEL, makeAny( xLabelModel ) ); 1655 } 1656 catch( const Exception& ) 1657 { 1658 DBG_UNHANDLED_EXCEPTION(); 1659 } 1660 } 1661 1662 if ( _rxField.is() ) 1663 { 1664 FormControlFactory aControlFactory( _rContext ); 1665 aControlFactory.initializeFieldDependentProperties( _rxField, xControlSet, _rxNumberFormats ); 1666 } 1667 1668 _rpLabel = pLabel.release(); 1669 _rpControl = pControl.release(); 1670 return true; 1671 } 1672 1673 //------------------------------------------------------------------------------ 1674 FmXFormView::ObjectRemoveListener::ObjectRemoveListener( FmXFormView* pParent ) 1675 :m_pParent( pParent ) 1676 { 1677 } 1678 1679 //------------------------------------------------------------------------------ 1680 void FmXFormView::ObjectRemoveListener::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) 1681 { 1682 if (rHint.ISA(SdrHint) && (((SdrHint&)rHint).GetKind() == HINT_OBJREMOVED)) 1683 m_pParent->ObjectRemovedInAliveMode(((SdrHint&)rHint).GetObject()); 1684 } 1685 1686 //------------------------------------------------------------------------------ 1687 void FmXFormView::ObjectRemovedInAliveMode( const SdrObject* pObject ) 1688 { 1689 // wenn das entfernte Objekt in meiner MarkList, die ich mir beim Umschalten in den Alive-Mode gemerkt habe, steht, 1690 // muss ich es jetzt da rausnehmen, da ich sonst beim Zurueckschalten versuche, die Markierung wieder zu setzen 1691 // (interesanterweise geht das nur bei gruppierten Objekten schief (beim Zugriff auf deren ObjList GPF), nicht bei einzelnen) 1692 1693 sal_uIntPtr nCount = m_aMark.GetMarkCount(); 1694 for (sal_uIntPtr i = 0; i < nCount; ++i) 1695 { 1696 SdrMark* pMark = m_aMark.GetMark(i); 1697 SdrObject* pCurrent = pMark->GetMarkedSdrObj(); 1698 if (pObject == pCurrent) 1699 { 1700 m_aMark.DeleteMark(i); 1701 return; 1702 } 1703 // ich brauche nicht in GroupObjects absteigen : wenn dort unten ein Objekt geloescht wird, dann bleibt der 1704 // Zeiger auf das GroupObject, den ich habe, trotzdem weiter gueltig bleibt ... 1705 } 1706 } 1707 1708 //------------------------------------------------------------------------------ 1709 void FmXFormView::stopMarkListWatching() 1710 { 1711 if ( m_pWatchStoredList ) 1712 { 1713 m_pWatchStoredList->EndListeningAll(); 1714 delete m_pWatchStoredList; 1715 m_pWatchStoredList = NULL; 1716 } 1717 } 1718 1719 //------------------------------------------------------------------------------ 1720 void FmXFormView::startMarkListWatching() 1721 { 1722 if ( !m_pWatchStoredList ) 1723 { 1724 m_pWatchStoredList = new ObjectRemoveListener( this ); 1725 FmFormModel* pModel = GetFormShell() ? GetFormShell()->GetFormModel() : NULL; 1726 DBG_ASSERT( pModel != NULL, "FmXFormView::startMarkListWatching: shell has no model!" ); 1727 m_pWatchStoredList->StartListening( *static_cast< SfxBroadcaster* >( pModel ) ); 1728 } 1729 else 1730 { 1731 DBG_ERROR( "FmXFormView::startMarkListWatching: already listening!" ); 1732 } 1733 } 1734 1735 //------------------------------------------------------------------------------ 1736 void FmXFormView::saveMarkList( sal_Bool _bSmartUnmark ) 1737 { 1738 if ( m_pView ) 1739 { 1740 m_aMark = m_pView->GetMarkedObjectList(); 1741 if ( _bSmartUnmark ) 1742 { 1743 sal_uIntPtr nCount = m_aMark.GetMarkCount( ); 1744 for ( sal_uIntPtr i = 0; i < nCount; ++i ) 1745 { 1746 SdrMark* pMark = m_aMark.GetMark(i); 1747 SdrObject* pObj = pMark->GetMarkedSdrObj(); 1748 1749 if ( m_pView->IsObjMarked( pObj ) ) 1750 { 1751 if ( pObj->IsGroupObject() ) 1752 { 1753 SdrObjListIter aIter( *pObj->GetSubList() ); 1754 sal_Bool bMixed = sal_False; 1755 while ( aIter.IsMore() && !bMixed ) 1756 bMixed = ( aIter.Next()->GetObjInventor() != FmFormInventor ); 1757 1758 if ( !bMixed ) 1759 { 1760 // all objects in the group are form objects 1761 m_pView->MarkObj( pMark->GetMarkedSdrObj(), pMark->GetPageView(), sal_True /* unmark! */ ); 1762 } 1763 } 1764 else 1765 { 1766 if ( pObj->GetObjInventor() == FmFormInventor ) 1767 { // this is a form layer object 1768 m_pView->MarkObj( pMark->GetMarkedSdrObj(), pMark->GetPageView(), sal_True /* unmark! */ ); 1769 } 1770 } 1771 } 1772 } 1773 } 1774 } 1775 else 1776 { 1777 DBG_ERROR( "FmXFormView::saveMarkList: invalid view!" ); 1778 m_aMark = SdrMarkList(); 1779 } 1780 } 1781 1782 //-------------------------------------------------------------------------- 1783 static sal_Bool lcl_hasObject( SdrObjListIter& rIter, SdrObject* pObj ) 1784 { 1785 sal_Bool bFound = sal_False; 1786 while (rIter.IsMore() && !bFound) 1787 bFound = pObj == rIter.Next(); 1788 1789 rIter.Reset(); 1790 return bFound; 1791 } 1792 1793 //------------------------------------------------------------------------------ 1794 void FmXFormView::restoreMarkList( SdrMarkList& _rRestoredMarkList ) 1795 { 1796 if ( !m_pView ) 1797 return; 1798 1799 _rRestoredMarkList.Clear(); 1800 1801 const SdrMarkList& rCurrentList = m_pView->GetMarkedObjectList(); 1802 FmFormPage* pPage = GetFormShell() ? GetFormShell()->GetCurPage() : NULL; 1803 if (pPage) 1804 { 1805 if (rCurrentList.GetMarkCount()) 1806 { // there is a current mark ... hmm. Is it a subset of the mark we remembered in saveMarkList? 1807 sal_Bool bMisMatch = sal_False; 1808 1809 // loop through all current marks 1810 sal_uIntPtr nCurrentCount = rCurrentList.GetMarkCount(); 1811 for ( sal_uIntPtr i=0; i<nCurrentCount&& !bMisMatch; ++i ) 1812 { 1813 const SdrObject* pCurrentMarked = rCurrentList.GetMark( i )->GetMarkedSdrObj(); 1814 1815 // loop through all saved marks, check for equality 1816 sal_Bool bFound = sal_False; 1817 sal_uIntPtr nSavedCount = m_aMark.GetMarkCount(); 1818 for ( sal_uIntPtr j=0; j<nSavedCount && !bFound; ++j ) 1819 { 1820 if ( m_aMark.GetMark( j )->GetMarkedSdrObj() == pCurrentMarked ) 1821 bFound = sal_True; 1822 } 1823 1824 // did not find a current mark in the saved marks 1825 if ( !bFound ) 1826 bMisMatch = sal_True; 1827 } 1828 1829 if ( bMisMatch ) 1830 { 1831 m_aMark.Clear(); 1832 _rRestoredMarkList = rCurrentList; 1833 return; 1834 } 1835 } 1836 // wichtig ist das auf die Objecte der markliste nicht zugegriffen wird 1837 // da diese bereits zerstoert sein koennen 1838 SdrPageView* pCurPageView = m_pView->GetSdrPageView(); 1839 SdrObjListIter aPageIter( *pPage ); 1840 sal_Bool bFound = sal_True; 1841 1842 // gibt es noch alle Objecte 1843 sal_uIntPtr nCount = m_aMark.GetMarkCount(); 1844 for (sal_uIntPtr i = 0; i < nCount && bFound; i++) 1845 { 1846 SdrMark* pMark = m_aMark.GetMark(i); 1847 SdrObject* pObj = pMark->GetMarkedSdrObj(); 1848 if (pObj->IsGroupObject()) 1849 { 1850 SdrObjListIter aIter(*pObj->GetSubList()); 1851 while (aIter.IsMore() && bFound) 1852 bFound = lcl_hasObject(aPageIter, aIter.Next()); 1853 } 1854 else 1855 bFound = lcl_hasObject(aPageIter, pObj); 1856 1857 bFound = bFound && pCurPageView == pMark->GetPageView(); 1858 } 1859 1860 if (bFound) 1861 { 1862 // Das LastObject auswerten 1863 if (nCount) // Objecte jetzt Markieren 1864 { 1865 for (sal_uIntPtr i = 0; i < nCount; i++) 1866 { 1867 SdrMark* pMark = m_aMark.GetMark(i); 1868 SdrObject* pObj = pMark->GetMarkedSdrObj(); 1869 if ( pObj->GetObjInventor() == FmFormInventor ) 1870 if ( !m_pView->IsObjMarked( pObj ) ) 1871 m_pView->MarkObj( pObj, pMark->GetPageView() ); 1872 } 1873 1874 _rRestoredMarkList = m_aMark; 1875 } 1876 } 1877 m_aMark.Clear(); 1878 } 1879 } 1880 // ----------------------------------------------------------------------------- 1881 void SAL_CALL FmXFormView::focusGained( const FocusEvent& /*e*/ ) throw (RuntimeException) 1882 { 1883 if ( m_xWindow.is() && m_pView ) 1884 { 1885 m_pView->SetMoveOutside( sal_True, FmFormView::ImplAccess() ); 1886 } 1887 } 1888 // ----------------------------------------------------------------------------- 1889 void SAL_CALL FmXFormView::focusLost( const FocusEvent& /*e*/ ) throw (RuntimeException) 1890 { 1891 // when switch the focus outside the office the mark didn't change 1892 // so we can not remove us as focus listener 1893 if ( m_xWindow.is() && m_pView ) 1894 { 1895 m_pView->SetMoveOutside( sal_False, FmFormView::ImplAccess() ); 1896 } 1897 } 1898 // ----------------------------------------------------------------------------- 1899 void FmXFormView::removeGridWindowListening() 1900 { 1901 if ( m_xWindow.is() ) 1902 { 1903 m_xWindow->removeFocusListener(this); 1904 if ( m_pView ) 1905 { 1906 m_pView->SetMoveOutside( sal_False, FmFormView::ImplAccess() ); 1907 } 1908 m_xWindow = NULL; 1909 } 1910 } 1911 1912 // ----------------------------------------------------------------------------- 1913 DocumentType FmXFormView::impl_getDocumentType() const 1914 { 1915 if ( GetFormShell() && GetFormShell()->GetImpl() ) 1916 return GetFormShell()->GetImpl()->getDocumentType(); 1917 return eUnknownDocumentType; 1918 } 1919