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