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/runtime/FormController.hpp>
63 : #include <com/sun/star/form/submission/XSubmissionSupplier.hpp>
64 : #include <com/sun/star/awt/XTabControllerModel.hpp>
65 : #include <com/sun/star/awt/XControlContainer.hpp>
66 : #include <com/sun/star/awt/XTabController.hpp>
67 : #include <com/sun/star/container/XIndexAccess.hpp>
68 : #include <com/sun/star/awt/XControl.hpp>
69 : #include <com/sun/star/lang/XUnoTunnel.hpp>
70 : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
71 : #include <com/sun/star/sdbc/XPreparedStatement.hpp>
72 : #include <com/sun/star/sdb/XQueriesSupplier.hpp>
73 : #include <com/sun/star/container/XContainer.hpp>
74 :
75 : #include <comphelper/enumhelper.hxx>
76 : #include <comphelper/extract.hxx>
77 : #include <comphelper/namedvaluecollection.hxx>
78 : #include <comphelper/numbers.hxx>
79 : #include <comphelper/property.hxx>
80 : #include <comphelper/processfactory.hxx>
81 : #include <cppuhelper/exc_hlp.hxx>
82 : #include <unotools/moduleoptions.hxx>
83 : #include <tools/diagnose_ex.h>
84 : #include <vcl/msgbox.hxx>
85 : #include <vcl/stdtext.hxx>
86 : #include <osl/mutex.hxx>
87 :
88 : #include <algorithm>
89 :
90 : using namespace ::comphelper;
91 : using namespace ::svx;
92 : using namespace ::svxform;
93 :
94 : using namespace ::com::sun::star;
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::uno::XComponentContext;
107 : using ::com::sun::star::style::VerticalAlignment_MIDDLE;
108 : using ::com::sun::star::form::FormButtonType_SUBMIT;
109 : using ::com::sun::star::form::binding::XValueBinding;
110 : using ::com::sun::star::form::binding::XBindableValue;
111 : using ::com::sun::star::lang::XComponent;
112 : using ::com::sun::star::container::XIndexAccess;
113 : using ::com::sun::star::form::runtime::FormController;
114 : using ::com::sun::star::form::runtime::XFormController;
115 : using ::com::sun::star::script::XEventAttacherManager;
116 : using ::com::sun::star::awt::XTabControllerModel;
117 : using ::com::sun::star::container::XChild;
118 : using ::com::sun::star::container::XEnumeration;
119 : using ::com::sun::star::task::XInteractionHandler;
120 : using ::com::sun::star::lang::XInitialization;
121 : using ::com::sun::star::awt::XTabController;
122 : using ::com::sun::star::lang::XUnoTunnel;
123 : using ::com::sun::star::awt::XControlContainer;
124 : using ::com::sun::star::awt::XControl;
125 : using ::com::sun::star::form::XFormComponent;
126 : using ::com::sun::star::form::XForm;
127 : using ::com::sun::star::lang::IndexOutOfBoundsException;
128 : using ::com::sun::star::lang::WrappedTargetException;
129 : using ::com::sun::star::container::XContainer;
130 : using ::com::sun::star::container::ContainerEvent;
131 : using ::com::sun::star::lang::EventObject;
132 : using ::com::sun::star::beans::NamedValue;
133 : using ::com::sun::star::sdb::SQLErrorEvent;
134 : using ::com::sun::star::sdbc::XRowSet;
135 : using ::com::sun::star::beans::XPropertySet;
136 : using ::com::sun::star::container::XElementAccess;
137 : using ::com::sun::star::awt::XWindow;
138 : using ::com::sun::star::awt::FocusEvent;
139 : using ::com::sun::star::ui::dialogs::XExecutableDialog;
140 : using ::com::sun::star::sdbc::XDataSource;
141 : using ::com::sun::star::container::XIndexContainer;
142 : using ::com::sun::star::sdbc::XConnection;
143 : using ::com::sun::star::container::XNameAccess;
144 : using ::com::sun::star::sdb::SQLContext;
145 : using ::com::sun::star::sdbc::SQLWarning;
146 : using ::com::sun::star::sdbc::SQLException;
147 : using ::com::sun::star::util::XNumberFormatsSupplier;
148 : using ::com::sun::star::util::XNumberFormats;
149 : using ::com::sun::star::beans::XPropertySetInfo;
150 :
151 : namespace FormComponentType = ::com::sun::star::form::FormComponentType;
152 : namespace CommandType = ::com::sun::star::sdb::CommandType;
153 : namespace DataType = ::com::sun::star::sdbc::DataType;
154 :
155 :
156 640 : class FmXFormView::ObjectRemoveListener : public SfxListener
157 : {
158 : FmXFormView* m_pParent;
159 : public:
160 : ObjectRemoveListener( FmXFormView* pParent );
161 : virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) SAL_OVERRIDE;
162 : };
163 :
164 :
165 :
166 514 : FormViewPageWindowAdapter::FormViewPageWindowAdapter( const css::uno::Reference<css::uno::XComponentContext>& _rContext, const SdrPageWindow& _rWindow, FmXFormView* _pViewImpl )
167 : : m_xControlContainer( _rWindow.GetControlContainer() ),
168 : m_xContext( _rContext ),
169 : m_pViewImpl( _pViewImpl ),
170 514 : m_pWindow( dynamic_cast< vcl::Window* >( &_rWindow.GetPaintWindow().GetOutputDevice() ) )
171 : {
172 :
173 : // create an XFormController for every form
174 514 : FmFormPage* pFormPage = dynamic_cast< FmFormPage* >( _rWindow.GetPageView().GetPage() );
175 : DBG_ASSERT( pFormPage, "FormViewPageWindowAdapter::FormViewPageWindowAdapter: no FmFormPage found!" );
176 514 : if ( pFormPage )
177 : {
178 : try
179 : {
180 514 : Reference< XIndexAccess > xForms( pFormPage->GetForms(), UNO_QUERY_THROW );
181 492 : sal_uInt32 nLength = xForms->getCount();
182 640 : for (sal_uInt32 i = 0; i < nLength; i++)
183 : {
184 148 : Reference< XForm > xForm( xForms->getByIndex(i), UNO_QUERY );
185 148 : if ( xForm.is() )
186 148 : setController( xForm, NULL );
187 640 : }
188 : }
189 22 : catch (const Exception&)
190 : {
191 : DBG_UNHANDLED_EXCEPTION();
192 : }
193 : }
194 514 : }
195 :
196 1028 : FormViewPageWindowAdapter::~FormViewPageWindowAdapter()
197 : {
198 1028 : }
199 :
200 :
201 514 : void FormViewPageWindowAdapter::dispose()
202 : {
203 1986 : for ( ::std::vector< Reference< XFormController > >::const_iterator i = m_aControllerList.begin();
204 1324 : i != m_aControllerList.end();
205 : ++i
206 : )
207 : {
208 : try
209 : {
210 148 : Reference< XFormController > xController( *i, UNO_QUERY_THROW );
211 :
212 : // detaching the events
213 296 : Reference< XChild > xControllerModel( xController->getModel(), UNO_QUERY );
214 148 : if ( xControllerModel.is() )
215 : {
216 148 : Reference< XEventAttacherManager > xEventManager( xControllerModel->getParent(), UNO_QUERY_THROW );
217 296 : Reference< XInterface > xControllerNormalized( xController, UNO_QUERY_THROW );
218 296 : xEventManager->detach( i - m_aControllerList.begin(), xControllerNormalized );
219 : }
220 :
221 : // dispose the formcontroller
222 296 : xController->dispose();
223 : }
224 0 : catch (const Exception&)
225 : {
226 : DBG_UNHANDLED_EXCEPTION();
227 : }
228 : }
229 :
230 514 : m_aControllerList.clear();
231 514 : }
232 :
233 :
234 :
235 0 : sal_Bool SAL_CALL FormViewPageWindowAdapter::hasElements(void) throw( RuntimeException, std::exception )
236 : {
237 0 : return getCount() != 0;
238 : }
239 :
240 :
241 0 : Type SAL_CALL FormViewPageWindowAdapter::getElementType(void) throw( RuntimeException, std::exception )
242 : {
243 0 : return cppu::UnoType<XFormController>::get();
244 : }
245 :
246 : // XEnumerationAccess
247 :
248 0 : Reference< XEnumeration > SAL_CALL FormViewPageWindowAdapter::createEnumeration(void) throw( RuntimeException )
249 : {
250 0 : return new ::comphelper::OEnumerationByIndex(this);
251 : }
252 :
253 : // XIndexAccess
254 :
255 0 : sal_Int32 SAL_CALL FormViewPageWindowAdapter::getCount(void) throw( RuntimeException, std::exception )
256 : {
257 0 : return m_aControllerList.size();
258 : }
259 :
260 :
261 0 : Any SAL_CALL FormViewPageWindowAdapter::getByIndex(sal_Int32 nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
262 : {
263 0 : if (nIndex < 0 ||
264 0 : nIndex >= getCount())
265 0 : throw IndexOutOfBoundsException();
266 :
267 0 : Any aElement;
268 0 : aElement <<= m_aControllerList[nIndex];
269 0 : return aElement;
270 : }
271 :
272 :
273 2 : void SAL_CALL FormViewPageWindowAdapter::makeVisible( const Reference< XControl >& _Control ) throw (RuntimeException, std::exception)
274 : {
275 2 : SolarMutexGuard aSolarGuard;
276 :
277 4 : Reference< XWindow > xWindow( _Control, UNO_QUERY );
278 2 : if ( xWindow.is() && m_pViewImpl->getView() && m_pWindow )
279 : {
280 2 : awt::Rectangle aRect = xWindow->getPosSize();
281 2 : ::Rectangle aNewRect( aRect.X, aRect.Y, aRect.X + aRect.Width, aRect.Y + aRect.Height );
282 2 : aNewRect = m_pWindow->PixelToLogic( aNewRect );
283 2 : m_pViewImpl->getView()->MakeVisible( aNewRect, *m_pWindow );
284 2 : }
285 2 : }
286 :
287 :
288 0 : Reference< XFormController > getControllerSearchChildren( const Reference< XIndexAccess > & xIndex, const Reference< XTabControllerModel > & xModel)
289 : {
290 0 : if (xIndex.is() && xIndex->getCount())
291 : {
292 0 : Reference< XFormController > xController;
293 :
294 0 : for (sal_Int32 n = xIndex->getCount(); n-- && !xController.is(); )
295 : {
296 0 : xIndex->getByIndex(n) >>= xController;
297 0 : if ((XTabControllerModel*)xModel.get() == (XTabControllerModel*)xController->getModel().get())
298 0 : return xController;
299 : else
300 : {
301 0 : xController = getControllerSearchChildren(xController, xModel);
302 0 : if ( xController.is() )
303 0 : return xController;
304 : }
305 0 : }
306 : }
307 0 : return Reference< XFormController > ();
308 : }
309 :
310 : // Search the according controller
311 :
312 56 : Reference< XFormController > FormViewPageWindowAdapter::getController( const Reference< XForm > & xForm ) const
313 : {
314 56 : Reference< XTabControllerModel > xModel(xForm, UNO_QUERY);
315 168 : for (::std::vector< Reference< XFormController > >::const_iterator i = m_aControllerList.begin();
316 112 : i != m_aControllerList.end(); ++i)
317 : {
318 56 : if ((XTabControllerModel*)(*i)->getModel().get() == (XTabControllerModel*)xModel.get())
319 112 : return *i;
320 :
321 : // the current-round controller isn't the right one. perhaps one of its children ?
322 0 : Reference< XFormController > xChildSearch = getControllerSearchChildren(Reference< XIndexAccess > (*i, UNO_QUERY), xModel);
323 0 : if (xChildSearch.is())
324 0 : return xChildSearch;
325 0 : }
326 0 : return Reference< XFormController > ();
327 : }
328 :
329 :
330 148 : void FormViewPageWindowAdapter::setController(const Reference< XForm > & xForm, const Reference< XFormController >& _rxParentController )
331 : {
332 : DBG_ASSERT( xForm.is(), "FormViewPageWindowAdapter::setController: there should be a form!" );
333 148 : Reference< XIndexAccess > xFormCps(xForm, UNO_QUERY);
334 148 : if (!xFormCps.is())
335 148 : return;
336 :
337 296 : Reference< XTabControllerModel > xTabOrder(xForm, UNO_QUERY);
338 :
339 : // create a form controller
340 296 : Reference< XFormController > xController( FormController::create(m_xContext) );
341 :
342 296 : Reference< XInteractionHandler > xHandler;
343 148 : if ( _rxParentController.is() )
344 0 : xHandler = _rxParentController->getInteractionHandler();
345 : else
346 : {
347 : // TODO: should we create a default handler? Not really necessary, since the
348 : // FormController itself has a default fallback
349 : }
350 148 : if ( xHandler.is() )
351 0 : xController->setInteractionHandler( xHandler );
352 :
353 148 : xController->setContext( this );
354 :
355 148 : xController->setModel( xTabOrder );
356 148 : xController->setContainer( m_xControlContainer );
357 148 : xController->activateTabOrder();
358 148 : xController->addActivateListener( m_pViewImpl );
359 :
360 148 : if ( _rxParentController.is() )
361 0 : _rxParentController->addChildController( xController );
362 : else
363 : {
364 148 : m_aControllerList.push_back(xController);
365 :
366 148 : xController->setParent( *this );
367 :
368 : // attaching the events
369 148 : Reference< XEventAttacherManager > xEventManager( xForm->getParent(), UNO_QUERY );
370 148 : xEventManager->attach(m_aControllerList.size() - 1, Reference<XInterface>( xController, UNO_QUERY ), makeAny(xController) );
371 : }
372 :
373 : // jetzt die Subforms durchgehen
374 148 : sal_uInt32 nLength = xFormCps->getCount();
375 296 : Reference< XForm > xSubForm;
376 350 : for (sal_uInt32 i = 0; i < nLength; i++)
377 : {
378 202 : if ( xFormCps->getByIndex(i) >>= xSubForm )
379 0 : setController( xSubForm, xController );
380 148 : }
381 : }
382 :
383 :
384 54 : void FormViewPageWindowAdapter::updateTabOrder( const Reference< XForm >& _rxForm )
385 : {
386 : OSL_PRECOND( _rxForm.is(), "FormViewPageWindowAdapter::updateTabOrder: illegal argument!" );
387 54 : if ( !_rxForm.is() )
388 54 : return;
389 :
390 : try
391 : {
392 54 : Reference< XTabController > xTabCtrl( getController( _rxForm ).get() );
393 54 : if ( xTabCtrl.is() )
394 : { // if there already is a TabController for this form, then delegate the "updateTabOrder" request
395 54 : xTabCtrl->activateTabOrder();
396 : }
397 : else
398 : { // otherwise, create a TabController
399 :
400 : // if it's a sub form, then we must ensure there exist TabControllers
401 : // for all its ancestors, too
402 0 : Reference< XForm > xParentForm( _rxForm->getParent(), UNO_QUERY );
403 : // there is a parent form -> look for the respective controller
404 0 : Reference< XFormController > xParentController;
405 0 : if ( xParentForm.is() )
406 0 : xParentController.set( getController( xParentForm ), UNO_QUERY );
407 :
408 0 : setController( _rxForm, xParentController );
409 54 : }
410 : }
411 0 : catch (const Exception&)
412 : {
413 : DBG_UNHANDLED_EXCEPTION();
414 : }
415 : }
416 :
417 :
418 6460 : FmXFormView::FmXFormView(FmFormView* _pView )
419 : :m_pMarkedGrid(NULL)
420 : ,m_pView(_pView)
421 : ,m_nActivationEvent(0)
422 : ,m_nErrorMessageEvent( 0 )
423 : ,m_nAutoFocusEvent( 0 )
424 : ,m_nControlWizardEvent( 0 )
425 : ,m_pWatchStoredList( NULL )
426 : ,m_bFirstActivation( true )
427 6460 : ,m_isTabOrderUpdateSuspended( false )
428 : {
429 6460 : }
430 :
431 :
432 12916 : void FmXFormView::cancelEvents()
433 : {
434 12916 : if ( m_nActivationEvent )
435 : {
436 220 : Application::RemoveUserEvent( m_nActivationEvent );
437 220 : m_nActivationEvent = 0;
438 : }
439 :
440 12916 : if ( m_nErrorMessageEvent )
441 : {
442 0 : Application::RemoveUserEvent( m_nErrorMessageEvent );
443 0 : m_nErrorMessageEvent = 0;
444 : }
445 :
446 12916 : if ( m_nAutoFocusEvent )
447 : {
448 0 : Application::RemoveUserEvent( m_nAutoFocusEvent );
449 0 : m_nAutoFocusEvent = 0;
450 : }
451 :
452 12916 : if ( m_nControlWizardEvent )
453 : {
454 0 : Application::RemoveUserEvent( m_nControlWizardEvent );
455 0 : m_nControlWizardEvent = 0;
456 : }
457 12916 : }
458 :
459 :
460 6458 : void FmXFormView::notifyViewDying( )
461 : {
462 : DBG_ASSERT( m_pView, "FmXFormView::notifyViewDying: my view already died!" );
463 6458 : m_pView = NULL;
464 6458 : cancelEvents();
465 6458 : }
466 :
467 :
468 19374 : FmXFormView::~FmXFormView()
469 : {
470 : DBG_ASSERT( m_aPageWindowAdapters.empty(), "FmXFormView::~FmXFormView: Window list not empty!" );
471 6458 : if ( !m_aPageWindowAdapters.empty() )
472 : {
473 0 : for ( PageWindowAdapterList::const_iterator loop = m_aPageWindowAdapters.begin();
474 0 : loop != m_aPageWindowAdapters.end();
475 : ++loop
476 : )
477 : {
478 0 : (*loop)->dispose();
479 : }
480 : }
481 :
482 6458 : cancelEvents();
483 :
484 6458 : delete m_pWatchStoredList;
485 6458 : m_pWatchStoredList = NULL;
486 12916 : }
487 :
488 : // EventListener
489 :
490 148 : void SAL_CALL FmXFormView::disposing(const EventObject& Source) throw( RuntimeException, std::exception )
491 : {
492 148 : if ( m_xWindow.is() && Source.Source == m_xWindow )
493 0 : removeGridWindowListening();
494 148 : }
495 :
496 : // XFormControllerListener
497 :
498 2 : void SAL_CALL FmXFormView::formActivated(const EventObject& rEvent) throw( RuntimeException, std::exception )
499 : {
500 2 : if ( m_pView && m_pView->GetFormShell() && m_pView->GetFormShell()->GetImpl() )
501 2 : m_pView->GetFormShell()->GetImpl()->formActivated( rEvent );
502 2 : }
503 :
504 :
505 2 : void SAL_CALL FmXFormView::formDeactivated(const EventObject& rEvent) throw( RuntimeException, std::exception )
506 : {
507 2 : if ( m_pView && m_pView->GetFormShell() && m_pView->GetFormShell()->GetImpl() )
508 2 : m_pView->GetFormShell()->GetImpl()->formDeactivated( rEvent );
509 2 : }
510 :
511 : // XContainerListener
512 :
513 88 : void SAL_CALL FmXFormView::elementInserted(const ContainerEvent& evt) throw( RuntimeException, std::exception )
514 : {
515 : try
516 : {
517 88 : Reference< XControlContainer > xControlContainer( evt.Source, UNO_QUERY_THROW );
518 176 : Reference< XControl > xControl( evt.Element, UNO_QUERY_THROW );
519 176 : Reference< XFormComponent > xControlModel( xControl->getModel(), UNO_QUERY_THROW );
520 176 : Reference< XForm > xForm( xControlModel->getParent(), UNO_QUERY_THROW );
521 :
522 80 : if ( m_isTabOrderUpdateSuspended )
523 : {
524 : // remember the container and the control, so we can update the tab order on resumeTabOrderUpdate
525 80 : m_aNeedTabOrderUpdate[ xControlContainer ].insert( xForm );
526 : }
527 : else
528 : {
529 0 : PFormViewPageWindowAdapter pAdapter = findWindow( xControlContainer );
530 0 : if ( pAdapter.is() )
531 0 : pAdapter->updateTabOrder( xForm );
532 88 : }
533 : }
534 8 : catch (const Exception&)
535 : {
536 : DBG_UNHANDLED_EXCEPTION();
537 : }
538 88 : }
539 :
540 :
541 0 : void SAL_CALL FmXFormView::elementReplaced(const ContainerEvent& evt) throw( RuntimeException, std::exception )
542 : {
543 0 : elementInserted(evt);
544 0 : }
545 :
546 :
547 2 : void SAL_CALL FmXFormView::elementRemoved(const ContainerEvent& /*evt*/) throw( RuntimeException, std::exception )
548 : {
549 2 : }
550 :
551 :
552 1036 : PFormViewPageWindowAdapter FmXFormView::findWindow( const Reference< XControlContainer >& _rxCC ) const
553 : {
554 3192 : for ( PageWindowAdapterList::const_iterator i = m_aPageWindowAdapters.begin();
555 2128 : i != m_aPageWindowAdapters.end();
556 : ++i
557 : )
558 : {
559 550 : if ( _rxCC == (*i)->getControlContainer() )
560 522 : return *i;
561 : }
562 514 : return NULL;
563 : }
564 :
565 :
566 982 : void FmXFormView::addWindow(const SdrPageWindow& rWindow)
567 : {
568 982 : FmFormPage* pFormPage = PTR_CAST( FmFormPage, rWindow.GetPageView().GetPage() );
569 982 : if ( !pFormPage )
570 982 : return;
571 :
572 982 : Reference< XControlContainer > xCC = rWindow.GetControlContainer();
573 2946 : if ( xCC.is()
574 3928 : && ( !findWindow( xCC ).is() )
575 : )
576 : {
577 514 : PFormViewPageWindowAdapter pAdapter = new FormViewPageWindowAdapter( comphelper::getProcessComponentContext(), rWindow, this );
578 514 : m_aPageWindowAdapters.push_back( pAdapter );
579 :
580 : // Am ControlContainer horchen um Aenderungen mitzbekommen
581 1028 : Reference< XContainer > xContainer( xCC, UNO_QUERY );
582 514 : if ( xContainer.is() )
583 1028 : xContainer->addContainerListener( this );
584 982 : }
585 : }
586 :
587 :
588 1806 : void FmXFormView::removeWindow( const Reference< XControlContainer >& _rxCC )
589 : {
590 : // Wird gerufen, wenn
591 : // - in den Design-Modus geschaltet wird
592 : // - ein Window geloescht wird, waehrend man im Design-Modus ist
593 : // - der Control-Container fuer ein Window entfernt wird, waehrend
594 : // der aktive Modus eingeschaltet ist.
595 :
596 5478 : for ( PageWindowAdapterList::iterator i = m_aPageWindowAdapters.begin();
597 3652 : i != m_aPageWindowAdapters.end();
598 : ++i
599 : )
600 : {
601 534 : if ( _rxCC != (*i)->getControlContainer() )
602 20 : continue;
603 :
604 514 : Reference< XContainer > xContainer( _rxCC, UNO_QUERY );
605 514 : if ( xContainer.is() )
606 514 : xContainer->removeContainerListener( this );
607 :
608 514 : (*i)->dispose();
609 514 : m_aPageWindowAdapters.erase( i );
610 514 : break;
611 514 : }
612 1806 : }
613 :
614 :
615 0 : void FmXFormView::displayAsyncErrorMessage( const SQLErrorEvent& _rEvent )
616 : {
617 : DBG_ASSERT( 0 == m_nErrorMessageEvent, "FmXFormView::displayAsyncErrorMessage: not too fast, please!" );
618 : // This should not happen - usually, the PostUserEvent is faster than any possible user
619 : // interaction which could trigger a new error. If it happens, we need a queue for the events.
620 0 : m_aAsyncError = _rEvent;
621 0 : m_nErrorMessageEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnDelayedErrorMessage ) );
622 0 : }
623 :
624 :
625 0 : IMPL_LINK(FmXFormView, OnDelayedErrorMessage, void*, /*EMPTYTAG*/)
626 : {
627 0 : m_nErrorMessageEvent = 0;
628 0 : displayException( m_aAsyncError );
629 0 : return 0L;
630 : }
631 :
632 :
633 318 : void FmXFormView::onFirstViewActivation( const FmFormModel* _pDocModel )
634 : {
635 318 : if ( _pDocModel && _pDocModel->GetAutoControlFocus() )
636 2 : m_nAutoFocusEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnAutoFocus ) );
637 318 : }
638 :
639 :
640 15143 : void FmXFormView::suspendTabOrderUpdate()
641 : {
642 : OSL_ENSURE( !m_isTabOrderUpdateSuspended, "FmXFormView::suspendTabOrderUpdate: nesting not allowed!" );
643 15143 : m_isTabOrderUpdateSuspended = true;
644 15143 : }
645 :
646 :
647 15143 : void FmXFormView::resumeTabOrderUpdate()
648 : {
649 : OSL_ENSURE( m_isTabOrderUpdateSuspended, "FmXFormView::resumeTabOrderUpdate: not suspended!" );
650 15143 : m_isTabOrderUpdateSuspended = false;
651 :
652 : // update the tab orders for all components which were collected since the suspendTabOrderUpdate call.
653 45591 : for ( MapControlContainerToSetOfForms::const_iterator container = m_aNeedTabOrderUpdate.begin();
654 30394 : container != m_aNeedTabOrderUpdate.end();
655 : ++container
656 : )
657 : {
658 54 : PFormViewPageWindowAdapter pAdapter = findWindow( container->first );
659 54 : if ( !pAdapter.is() )
660 0 : continue;
661 :
662 324 : for ( SetOfForms::const_iterator form = container->second.begin();
663 216 : form != container->second.end();
664 : ++form
665 : )
666 : {
667 54 : pAdapter->updateTabOrder( *form );
668 : }
669 54 : }
670 15143 : m_aNeedTabOrderUpdate.clear();
671 15143 : }
672 :
673 :
674 2792 : IMPL_LINK(FmXFormView, OnActivate, void*, /*EMPTYTAG*/)
675 : {
676 1396 : m_nActivationEvent = 0;
677 :
678 1396 : if ( !m_pView )
679 : {
680 : OSL_FAIL( "FmXFormView::OnActivate: well .... seems we have a timing problem (the view already died)!" );
681 0 : return 0;
682 : }
683 :
684 : // setting the controller to activate
685 1396 : if (m_pView->GetFormShell() && m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
686 : {
687 984 : vcl::Window* pWindow = const_cast<vcl::Window*>(static_cast<const vcl::Window*>(m_pView->GetActualOutDev()));
688 984 : PFormViewPageWindowAdapter pAdapter = m_aPageWindowAdapters.empty() ? NULL : m_aPageWindowAdapters[0];
689 3384 : for ( PageWindowAdapterList::const_iterator i = m_aPageWindowAdapters.begin();
690 2256 : i != m_aPageWindowAdapters.end();
691 : ++i
692 : )
693 : {
694 144 : if ( pWindow == (*i)->getWindow() )
695 126 : pAdapter =*i;
696 : }
697 :
698 984 : if ( pAdapter.get() )
699 : {
700 684 : for ( ::std::vector< Reference< XFormController > >::const_iterator i = pAdapter->GetList().begin();
701 456 : i != pAdapter->GetList().end();
702 : ++i
703 : )
704 : {
705 102 : const Reference< XFormController > & xController = *i;
706 102 : if ( !xController.is() )
707 102 : continue;
708 :
709 : // only database forms are to be activated
710 102 : Reference< XRowSet > xForm(xController->getModel(), UNO_QUERY);
711 102 : if ( !xForm.is() || !OStaticDataAccessTools().getRowSetConnection( xForm ).is() )
712 102 : continue;
713 :
714 0 : Reference< XPropertySet > xFormSet( xForm, UNO_QUERY );
715 0 : if ( !xFormSet.is() )
716 : {
717 : SAL_WARN( "svx.form", "FmXFormView::OnActivate: a form which does not have properties?" );
718 0 : continue;
719 : }
720 :
721 0 : const OUString aSource = ::comphelper::getString( xFormSet->getPropertyValue( FM_PROP_COMMAND ) );
722 0 : if ( !aSource.isEmpty() )
723 : {
724 0 : FmXFormShell* pShImpl = m_pView->GetFormShell()->GetImpl();
725 0 : if ( pShImpl )
726 0 : pShImpl->setActiveController( xController );
727 0 : break;
728 : }
729 0 : }
730 984 : }
731 : }
732 1396 : return 0;
733 : }
734 :
735 :
736 6923 : void FmXFormView::Activate(bool bSync)
737 : {
738 6923 : if (m_nActivationEvent)
739 : {
740 312 : Application::RemoveUserEvent(m_nActivationEvent);
741 312 : m_nActivationEvent = 0;
742 : }
743 :
744 6923 : if (bSync)
745 : {
746 116 : LINK(this,FmXFormView,OnActivate).Call(NULL);
747 : }
748 : else
749 6807 : m_nActivationEvent = Application::PostUserEvent(LINK(this,FmXFormView,OnActivate));
750 6923 : }
751 :
752 :
753 6899 : void FmXFormView::Deactivate(bool bDeactivateController)
754 : {
755 6899 : if (m_nActivationEvent)
756 : {
757 4993 : Application::RemoveUserEvent(m_nActivationEvent);
758 4993 : m_nActivationEvent = 0;
759 : }
760 :
761 6899 : FmXFormShell* pShImpl = m_pView->GetFormShell() ? m_pView->GetFormShell()->GetImpl() : NULL;
762 6899 : if (pShImpl && bDeactivateController)
763 184 : pShImpl->setActiveController( NULL );
764 6899 : }
765 :
766 :
767 10996 : FmFormShell* FmXFormView::GetFormShell() const
768 : {
769 10996 : return m_pView ? m_pView->GetFormShell() : NULL;
770 : }
771 :
772 0 : void FmXFormView::AutoFocus( bool _bSync )
773 : {
774 0 : if (m_nAutoFocusEvent)
775 0 : Application::RemoveUserEvent(m_nAutoFocusEvent);
776 :
777 0 : if ( _bSync )
778 0 : OnAutoFocus( NULL );
779 : else
780 0 : m_nAutoFocusEvent = Application::PostUserEvent(LINK(this, FmXFormView, OnAutoFocus));
781 0 : }
782 :
783 :
784 2 : bool FmXFormView::isFocusable( const Reference< XControl >& i_rControl )
785 : {
786 2 : if ( !i_rControl.is() )
787 0 : return false;
788 :
789 : try
790 : {
791 2 : Reference< XPropertySet > xModelProps( i_rControl->getModel(), UNO_QUERY_THROW );
792 :
793 : // only enabled controls are allowed to participate
794 2 : bool bEnabled = false;
795 2 : OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_ENABLED ) >>= bEnabled );
796 2 : if ( !bEnabled )
797 0 : return false;
798 :
799 : // check the class id of the control model
800 2 : sal_Int16 nClassId = FormComponentType::CONTROL;
801 2 : OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
802 :
803 : // controls which are not focussable
804 2 : if ( ( FormComponentType::CONTROL != nClassId )
805 2 : && ( FormComponentType::IMAGEBUTTON != nClassId )
806 2 : && ( FormComponentType::GROUPBOX != nClassId )
807 2 : && ( FormComponentType::FIXEDTEXT != nClassId )
808 2 : && ( FormComponentType::HIDDENCONTROL != nClassId )
809 2 : && ( FormComponentType::IMAGECONTROL != nClassId )
810 2 : && ( FormComponentType::SCROLLBAR != nClassId )
811 2 : && ( FormComponentType::SPINBUTTON!= nClassId )
812 : )
813 : {
814 2 : return true;
815 0 : }
816 : }
817 0 : catch (const Exception&)
818 : {
819 : DBG_UNHANDLED_EXCEPTION();
820 : }
821 0 : return false;
822 : }
823 :
824 :
825 2 : static Reference< XControl > lcl_firstFocussableControl( const Sequence< Reference< XControl > >& _rControls )
826 : {
827 2 : Reference< XControl > xReturn;
828 :
829 : // loop through all the controls
830 2 : const Reference< XControl >* pControls = _rControls.getConstArray();
831 2 : const Reference< XControl >* pControlsEnd = _rControls.getConstArray() + _rControls.getLength();
832 2 : for ( ; pControls != pControlsEnd; ++pControls )
833 : {
834 2 : if ( !pControls->is() )
835 0 : continue;
836 :
837 2 : if ( FmXFormView::isFocusable( *pControls ) )
838 : {
839 2 : xReturn = *pControls;
840 2 : break;
841 : }
842 : }
843 :
844 2 : if ( !xReturn.is() && _rControls.getLength() )
845 0 : xReturn = _rControls[0];
846 :
847 2 : return xReturn;
848 : }
849 :
850 :
851 : namespace
852 : {
853 :
854 0 : void lcl_ensureControlsOfFormExist_nothrow( const SdrPage& _rPage, const SdrView& _rView, const vcl::Window& _rWindow, const Reference< XForm >& _rxForm )
855 : {
856 : try
857 : {
858 0 : Reference< XInterface > xNormalizedForm( _rxForm, UNO_QUERY_THROW );
859 :
860 0 : SdrObjListIter aSdrObjectLoop( _rPage, IM_DEEPNOGROUPS );
861 0 : while ( aSdrObjectLoop.IsMore() )
862 : {
863 0 : FmFormObj* pFormObject = FmFormObj::GetFormObject( aSdrObjectLoop.Next() );
864 0 : if ( !pFormObject )
865 0 : continue;
866 :
867 0 : Reference< XChild > xModel( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
868 0 : Reference< XInterface > xModelParent( xModel->getParent(), UNO_QUERY_THROW );
869 :
870 0 : if ( xNormalizedForm.get() != xModelParent.get() )
871 0 : continue;
872 :
873 0 : pFormObject->GetUnoControl( _rView, _rWindow );
874 0 : }
875 : }
876 0 : catch (const Exception&)
877 : {
878 : DBG_UNHANDLED_EXCEPTION();
879 : }
880 0 : }
881 : }
882 :
883 :
884 0 : Reference< XFormController > FmXFormView::getFormController( const Reference< XForm >& _rxForm, const OutputDevice& _rDevice ) const
885 : {
886 0 : Reference< XFormController > xController;
887 :
888 0 : for ( PageWindowAdapterList::const_iterator pos = m_aPageWindowAdapters.begin();
889 0 : pos != m_aPageWindowAdapters.end();
890 : ++pos
891 : )
892 : {
893 0 : const PFormViewPageWindowAdapter pAdapter( *pos );
894 0 : if ( !pAdapter.get() )
895 : {
896 : SAL_WARN( "svx.form", "FmXFormView::getFormController: invalid page window adapter!" );
897 0 : continue;
898 : }
899 :
900 0 : if ( pAdapter->getWindow() != &_rDevice )
901 : // wrong device
902 0 : continue;
903 :
904 0 : xController = pAdapter->getController( _rxForm );
905 0 : if ( xController.is() )
906 0 : break;
907 0 : }
908 0 : return xController;
909 : }
910 :
911 :
912 4 : IMPL_LINK(FmXFormView, OnAutoFocus, void*, /*EMPTYTAG*/)
913 : {
914 2 : m_nAutoFocusEvent = 0;
915 :
916 : // go to the first form of our page, examine it's TabController, go to it's first (in terms of the tab order)
917 : // control, give it the focus
918 :
919 : do
920 : {
921 :
922 2 : SdrPageView *pPageView = m_pView ? m_pView->GetSdrPageView() : NULL;
923 2 : SdrPage *pSdrPage = pPageView ? pPageView->GetPage() : NULL;
924 : // get the forms collection of the page we belong to
925 2 : FmFormPage* pPage = PTR_CAST( FmFormPage, pSdrPage );
926 2 : Reference< XIndexAccess > xForms( pPage ? Reference< XIndexAccess >( pPage->GetForms(), UNO_QUERY ) : Reference< XIndexAccess >() );
927 :
928 4 : const PFormViewPageWindowAdapter pAdapter = m_aPageWindowAdapters.empty() ? NULL : m_aPageWindowAdapters[0];
929 2 : const vcl::Window* pWindow = pAdapter.get() ? pAdapter->getWindow() : NULL;
930 :
931 2 : ENSURE_OR_RETURN( xForms.is() && pWindow, "FmXFormView::OnAutoFocus: could not collect all essentials!", 0L );
932 :
933 : try
934 : {
935 : // go for the tab controller of the first form
936 2 : if ( !xForms->getCount() )
937 0 : break;
938 2 : Reference< XForm > xForm( xForms->getByIndex( 0 ), UNO_QUERY_THROW );
939 4 : Reference< XTabController > xTabController( pAdapter->getController( xForm ), UNO_QUERY_THROW );
940 :
941 : // go for the first control of the controller
942 4 : Sequence< Reference< XControl > > aControls( xTabController->getControls() );
943 2 : if ( aControls.getLength() == 0 )
944 : {
945 0 : Reference< XElementAccess > xFormElementAccess( xForm, UNO_QUERY_THROW );
946 0 : if (xFormElementAccess->hasElements() && pPage && m_pView)
947 : {
948 : // there are control models in the form, but no controls, yet.
949 : // Well, since some time controls are created on demand only. In particular,
950 : // they're normally created when they're first painted.
951 : // Unfortunately, the FormController does not have any way to
952 : // trigger the creation itself, so we must hack this ...
953 0 : lcl_ensureControlsOfFormExist_nothrow( *pPage, *m_pView, *pWindow, xForm );
954 0 : aControls = xTabController->getControls();
955 : OSL_ENSURE( aControls.getLength(), "FmXFormView::OnAutoFocus: no controls at all!" );
956 0 : }
957 : }
958 :
959 : // set the focus to this first control
960 4 : Reference< XWindow > xControlWindow( lcl_firstFocussableControl( aControls ), UNO_QUERY );
961 2 : if ( !xControlWindow.is() )
962 0 : break;
963 :
964 2 : xControlWindow->setFocus();
965 :
966 : // ensure that the control is visible
967 : // 80210 - 12/07/00 - FS
968 2 : const vcl::Window* pCurrentWindow = m_pView ? dynamic_cast<const vcl::Window*>(m_pView->GetActualOutDev()) : NULL;
969 2 : if ( pCurrentWindow )
970 : {
971 2 : awt::Rectangle aRect = xControlWindow->getPosSize();
972 2 : ::Rectangle aNonUnoRect( aRect.X, aRect.Y, aRect.X + aRect.Width, aRect.Y + aRect.Height );
973 2 : m_pView->MakeVisible( pCurrentWindow->PixelToLogic( aNonUnoRect ), *const_cast< vcl::Window* >( pCurrentWindow ) );
974 2 : }
975 : }
976 0 : catch (const Exception&)
977 : {
978 : DBG_UNHANDLED_EXCEPTION();
979 2 : }
980 :
981 : } // do
982 : while ( false );
983 :
984 2 : return 1L;
985 : }
986 :
987 :
988 0 : void FmXFormView::onCreatedFormObject( FmFormObj& _rFormObject )
989 : {
990 0 : FmFormShell* pShell = m_pView ? m_pView->GetFormShell() : NULL;
991 0 : FmXFormShell* pShellImpl = pShell ? pShell->GetImpl() : NULL;
992 : OSL_ENSURE( pShellImpl, "FmXFormView::onCreatedFormObject: no form shell!" );
993 0 : if ( !pShellImpl )
994 0 : return;
995 :
996 : // it is valid that the form shell's forms collection is not initialized, yet
997 0 : pShellImpl->UpdateForms( true );
998 :
999 0 : m_xLastCreatedControlModel.set( _rFormObject.GetUnoControlModel(), UNO_QUERY );
1000 0 : if ( !m_xLastCreatedControlModel.is() )
1001 0 : return;
1002 :
1003 : // some initial property defaults
1004 0 : FormControlFactory aControlFactory;
1005 0 : aControlFactory.initializeControlModel( pShellImpl->getDocumentType(), _rFormObject );
1006 :
1007 0 : if ( !pShellImpl->GetWizardUsing() )
1008 0 : return;
1009 :
1010 : // #i31958# don't call wizards in XForms mode
1011 0 : if ( pShellImpl->isEnhancedForm() )
1012 0 : return;
1013 :
1014 : // #i46898# no wizards if there is no Base installed - currently, all wizards are
1015 : // database related
1016 0 : if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
1017 0 : return;
1018 :
1019 0 : if ( m_nControlWizardEvent )
1020 0 : Application::RemoveUserEvent( m_nControlWizardEvent );
1021 0 : m_nControlWizardEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnStartControlWizard ) );
1022 : }
1023 :
1024 0 : void FmXFormView::breakCreateFormObject()
1025 : {
1026 0 : if (m_nControlWizardEvent != 0)
1027 : {
1028 0 : Application::RemoveUserEvent(m_nControlWizardEvent);
1029 0 : m_nControlWizardEvent = 0;
1030 : }
1031 0 : m_xLastCreatedControlModel.clear();
1032 0 : }
1033 :
1034 0 : IMPL_LINK( FmXFormView, OnStartControlWizard, void*, /**/ )
1035 : {
1036 0 : m_nControlWizardEvent = 0;
1037 : OSL_PRECOND( m_xLastCreatedControlModel.is(), "FmXFormView::OnStartControlWizard: illegal call!" );
1038 0 : if ( !m_xLastCreatedControlModel.is() )
1039 0 : return 0L;
1040 :
1041 0 : sal_Int16 nClassId = FormComponentType::CONTROL;
1042 : try
1043 : {
1044 0 : OSL_VERIFY( m_xLastCreatedControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
1045 : }
1046 0 : catch (const Exception&)
1047 : {
1048 : DBG_UNHANDLED_EXCEPTION();
1049 : }
1050 :
1051 0 : const sal_Char* pWizardAsciiName = NULL;
1052 0 : switch ( nClassId )
1053 : {
1054 : case FormComponentType::GRIDCONTROL:
1055 0 : pWizardAsciiName = "com.sun.star.sdb.GridControlAutoPilot";
1056 0 : break;
1057 : case FormComponentType::LISTBOX:
1058 : case FormComponentType::COMBOBOX:
1059 0 : pWizardAsciiName = "com.sun.star.sdb.ListComboBoxAutoPilot";
1060 0 : break;
1061 : case FormComponentType::GROUPBOX:
1062 0 : pWizardAsciiName = "com.sun.star.sdb.GroupBoxAutoPilot";
1063 0 : break;
1064 : }
1065 :
1066 0 : if ( pWizardAsciiName )
1067 : {
1068 : // build the argument list
1069 0 : ::comphelper::NamedValueCollection aWizardArgs;
1070 0 : aWizardArgs.put( "ObjectModel", m_xLastCreatedControlModel );
1071 :
1072 : // create the wizard object
1073 0 : Reference< XExecutableDialog > xWizard;
1074 : try
1075 : {
1076 0 : Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
1077 0 : xWizard.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext( OUString::createFromAscii(pWizardAsciiName), aWizardArgs.getWrappedPropertyValues(), xContext ), UNO_QUERY);;
1078 : }
1079 0 : catch (const Exception&)
1080 : {
1081 : DBG_UNHANDLED_EXCEPTION();
1082 : }
1083 :
1084 0 : if ( !xWizard.is() )
1085 : {
1086 0 : ShowServiceNotAvailableError( NULL, OUString::createFromAscii(pWizardAsciiName), 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 OUString& _rDataSourceName = OUString(),
1111 : const OUString& _rCommand = 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 : OUString sCommand, sFieldName;
1135 0 : sal_Int32 nCommandType = CommandType::COMMAND;
1136 0 : SharedConnection xConnection;
1137 :
1138 0 : 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.set(xChild->getParent(), css::uno::UNO_QUERY);
1167 : }
1168 :
1169 : // obtain the data source
1170 0 : if ( !xDataSource.is() )
1171 0 : xDataSource = OStaticDataAccessTools().getDataSource( sDataSource, comphelper::getProcessComponentContext() );
1172 :
1173 : // and the connection, if necessary
1174 0 : if ( !xConnection.is() )
1175 : xConnection.reset( OStaticDataAccessTools().getConnection_withFeedback(
1176 : sDataSource,
1177 : OUString(),
1178 : OUString(),
1179 : comphelper::getProcessComponentContext()
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, false ), UNO_SET_THROW );
1220 0 : Reference< XNumberFormats > xNumberFormats( xSupplier->getNumberFormats(), UNO_SET_THROW );
1221 :
1222 0 : 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 : bool bDateNTimeField = false;
1261 :
1262 0 : bool bIsCurrency = 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 = true;
1299 0 : sLabelPostfix = SVX_RESSTR(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 : SVX_RESSTR(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 : 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(OUString(_rDesc.szServiceName).equals(FM_SUN_COMPONENT_NUMERICFIELD))
1410 0 : nOBJID = OBJ_FM_NUMERICFIELD;
1411 0 : if(OUString(_rDesc.szServiceName).equals(FM_SUN_COMPONENT_CHECKBOX))
1412 0 : nOBJID = OBJ_FM_CHECKBOX;
1413 0 : if(OUString(_rDesc.szServiceName).equals(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( OutputDevice::LogicToLogic( ::Point( controlSize.Width(), 0 ), eSourceMode, eTargetMode ) );
1465 0 : ::Rectangle controlRect( controlPos, OutputDevice::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(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 OUString& _rFieldPostfix,
1495 : SdrUnoObj*& _rpLabel, SdrUnoObj*& _rpControl,
1496 : const Reference< XDataSource >& _rxDataSource, const OUString& _rDataSourceName,
1497 : const OUString& _rCommand, const sal_Int32 _nCommandType )
1498 : {
1499 0 : if ( !createControlLabelPair( _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 hierarchy
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;
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( OutputDevice& _rOutDev, sal_Int32 _nXOffsetMM, sal_Int32 _nYOffsetMM,
1521 : const Reference< XPropertySet >& _rxField,
1522 : const Reference< XNumberFormats >& _rxNumberFormats, sal_uInt16 _nControlObjectID,
1523 : const 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 : 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 = OutputDevice::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 0 : ::std::unique_ptr< SdrUnoObj > pLabel;
1561 0 : Reference< XPropertySet > xLabelModel;
1562 0 : if ( bNeedLabel )
1563 : {
1564 : pLabel.reset( dynamic_cast< SdrUnoObj* >(
1565 0 : SdrObjFactory::MakeNewObject( _nInventor, _nLabelObjectID, _pLabelPage, _pModel ) ) );
1566 : OSL_ENSURE( pLabel.get(), "FmXFormView::createControlLabelPair: could not create the label!" );
1567 0 : if ( !pLabel.get() )
1568 0 : return false;
1569 :
1570 0 : xLabelModel.set( pLabel->GetUnoControlModel(), UNO_QUERY );
1571 0 : if ( xLabelModel.is() )
1572 : {
1573 0 : OUString sLabel;
1574 0 : if ( _rxField.is() && _rxField->getPropertySetInfo()->hasPropertyByName(FM_PROP_LABEL) )
1575 0 : _rxField->getPropertyValue(FM_PROP_LABEL) >>= sLabel;
1576 0 : if ( sLabel.isEmpty() )
1577 0 : sLabel = sFieldName;
1578 :
1579 0 : xLabelModel->setPropertyValue( FM_PROP_LABEL, makeAny( sLabel + _rFieldPostfix ) );
1580 0 : OUString sObjectLabel(SVX_RESSTR(RID_STR_OBJECT_LABEL).replaceAll("#object#", sFieldName));
1581 0 : xLabelModel->setPropertyValue(FM_PROP_NAME, makeAny(sObjectLabel));
1582 : }
1583 :
1584 0 : pLabel->SetLogicRect( ::Rectangle(
1585 0 : OutputDevice::LogicToLogic( ::Point( _nXOffsetMM, _nYOffsetMM ), eSourceMode, eTargetMode ),
1586 : OutputDevice::LogicToLogic( aRealSize, eSourceMode, eTargetMode )
1587 0 : ) );
1588 : }
1589 :
1590 : // the control
1591 : ::std::unique_ptr< SdrUnoObj > pControl( dynamic_cast< SdrUnoObj* >(
1592 0 : SdrObjFactory::MakeNewObject( _nInventor, _nControlObjectID, _pControlPage, _pModel ) ) );
1593 : OSL_ENSURE( pControl.get(), "FmXFormView::createControlLabelPair: could not create the control!" );
1594 0 : if ( !pControl.get() )
1595 0 : return false;
1596 :
1597 0 : Reference< XPropertySet > xControlSet( pControl->GetUnoControlModel(), UNO_QUERY );
1598 0 : if ( !xControlSet.is() )
1599 0 : return false;
1600 :
1601 : // size of the control
1602 0 : ::Size aControlSize( aDefSize );
1603 0 : switch ( nDataType )
1604 : {
1605 : case DataType::BIT:
1606 : case DataType::BOOLEAN:
1607 0 : aControlSize = aDefSize;
1608 0 : break;
1609 : case DataType::LONGVARCHAR:
1610 : case DataType::CLOB:
1611 : case DataType::LONGVARBINARY:
1612 : case DataType::BLOB:
1613 0 : aControlSize = aDefImageSize;
1614 0 : break;
1615 : }
1616 :
1617 0 : if ( OBJ_FM_IMAGECONTROL == _nControlObjectID )
1618 0 : aControlSize = aDefImageSize;
1619 :
1620 0 : aControlSize.Width() = long(Fraction(aControlSize.Width(), 1) * eTargetMode.GetScaleX());
1621 0 : aControlSize.Height() = long(Fraction(aControlSize.Height(), 1) * eTargetMode.GetScaleY());
1622 :
1623 0 : pControl->SetLogicRect( ::Rectangle(
1624 0 : OutputDevice::LogicToLogic( ::Point( aRealSize.Width() + _nXOffsetMM, _nYOffsetMM ), eSourceMode, eTargetMode ),
1625 : OutputDevice::LogicToLogic( aControlSize, eSourceMode, eTargetMode )
1626 0 : ) );
1627 :
1628 : // some initializations
1629 0 : Reference< XPropertySetInfo > xControlPropInfo = xControlSet->getPropertySetInfo();
1630 :
1631 0 : if ( aFieldName.hasValue() )
1632 : {
1633 0 : xControlSet->setPropertyValue( FM_PROP_CONTROLSOURCE, aFieldName );
1634 0 : xControlSet->setPropertyValue( FM_PROP_NAME, aFieldName );
1635 0 : if ( !bNeedLabel )
1636 : {
1637 : // no dedicated label control => use the label property
1638 0 : if ( xControlPropInfo->hasPropertyByName( FM_PROP_LABEL ) )
1639 0 : xControlSet->setPropertyValue( FM_PROP_LABEL, makeAny( sFieldName + _rFieldPostfix ) );
1640 : else
1641 : OSL_FAIL( "FmXFormView::createControlLabelPair: can't set a label for the control!" );
1642 : }
1643 : }
1644 :
1645 0 : if ( (nDataType == DataType::LONGVARCHAR || nDataType == DataType::CLOB) && xControlPropInfo->hasPropertyByName( FM_PROP_MULTILINE ) )
1646 : {
1647 0 : xControlSet->setPropertyValue( FM_PROP_MULTILINE, makeAny( true ) );
1648 : }
1649 :
1650 : // announce the label to the control
1651 0 : if ( xControlPropInfo->hasPropertyByName( FM_PROP_CONTROLLABEL ) && xLabelModel.is() )
1652 : {
1653 : try
1654 : {
1655 0 : xControlSet->setPropertyValue( FM_PROP_CONTROLLABEL, makeAny( xLabelModel ) );
1656 : }
1657 0 : catch (const Exception&)
1658 : {
1659 : DBG_UNHANDLED_EXCEPTION();
1660 : }
1661 : }
1662 :
1663 0 : if ( _rxField.is() )
1664 : {
1665 0 : FormControlFactory aControlFactory;
1666 0 : aControlFactory.initializeFieldDependentProperties( _rxField, xControlSet, _rxNumberFormats );
1667 : }
1668 :
1669 0 : _rpLabel = pLabel.release();
1670 0 : _rpControl = pControl.release();
1671 0 : return true;
1672 : }
1673 :
1674 :
1675 320 : FmXFormView::ObjectRemoveListener::ObjectRemoveListener( FmXFormView* pParent )
1676 320 : :m_pParent( pParent )
1677 : {
1678 320 : }
1679 :
1680 :
1681 594 : void FmXFormView::ObjectRemoveListener::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
1682 : {
1683 594 : const SdrHint* pSdrHint = dynamic_cast<const SdrHint*>(&rHint);
1684 594 : if (pSdrHint && pSdrHint->GetKind() == HINT_OBJREMOVED)
1685 0 : m_pParent->ObjectRemovedInAliveMode(pSdrHint->GetObject());
1686 594 : }
1687 :
1688 :
1689 0 : void FmXFormView::ObjectRemovedInAliveMode( const SdrObject* pObject )
1690 : {
1691 : // wenn das entfernte Objekt in meiner MarkList, die ich mir beim Umschalten in den Alive-Mode gemerkt habe, steht,
1692 : // muss ich es jetzt da rausnehmen, da ich sonst beim Zurueckschalten versuche, die Markierung wieder zu setzen
1693 : // (interesanterweise geht das nur bei gruppierten Objekten schief (beim Zugriff auf deren ObjList GPF), nicht bei einzelnen)
1694 :
1695 0 : const size_t nCount = m_aMark.GetMarkCount();
1696 0 : for (size_t i = 0; i < nCount; ++i)
1697 : {
1698 0 : SdrMark* pMark = m_aMark.GetMark(i);
1699 0 : SdrObject* pCurrent = pMark->GetMarkedSdrObj();
1700 0 : if (pObject == pCurrent)
1701 : {
1702 0 : m_aMark.DeleteMark(i);
1703 0 : return;
1704 : }
1705 : // ich brauche nicht in GroupObjects absteigen : wenn dort unten ein Objekt geloescht wird, dann bleibt der
1706 : // Zeiger auf das GroupObject, den ich habe, trotzdem weiter gueltig bleibt ...
1707 : }
1708 : }
1709 :
1710 :
1711 5178 : void FmXFormView::stopMarkListWatching()
1712 : {
1713 5178 : if ( m_pWatchStoredList )
1714 : {
1715 0 : m_pWatchStoredList->EndListeningAll();
1716 0 : delete m_pWatchStoredList;
1717 0 : m_pWatchStoredList = NULL;
1718 : }
1719 5178 : }
1720 :
1721 :
1722 320 : void FmXFormView::startMarkListWatching()
1723 : {
1724 320 : if ( !m_pWatchStoredList )
1725 : {
1726 320 : FmFormModel* pModel = GetFormShell() ? GetFormShell()->GetFormModel() : NULL;
1727 : DBG_ASSERT( pModel != NULL, "FmXFormView::startMarkListWatching: shell has no model!" );
1728 320 : if (pModel)
1729 : {
1730 320 : m_pWatchStoredList = new ObjectRemoveListener( this );
1731 320 : m_pWatchStoredList->StartListening( *static_cast< SfxBroadcaster* >( pModel ) );
1732 : }
1733 : }
1734 : else
1735 : {
1736 : OSL_FAIL( "FmXFormView::startMarkListWatching: already listening!" );
1737 : }
1738 320 : }
1739 :
1740 :
1741 320 : void FmXFormView::saveMarkList( bool _bSmartUnmark )
1742 : {
1743 320 : if ( m_pView )
1744 : {
1745 320 : m_aMark = m_pView->GetMarkedObjectList();
1746 320 : if ( _bSmartUnmark )
1747 : {
1748 320 : const size_t nCount = m_aMark.GetMarkCount( );
1749 320 : for ( size_t i = 0; i < nCount; ++i )
1750 : {
1751 0 : SdrMark* pMark = m_aMark.GetMark(i);
1752 0 : SdrObject* pObj = pMark->GetMarkedSdrObj();
1753 :
1754 0 : if ( m_pView->IsObjMarked( pObj ) )
1755 : {
1756 0 : if ( pObj->IsGroupObject() )
1757 : {
1758 0 : SdrObjListIter aIter( *pObj->GetSubList() );
1759 0 : bool bMixed = false;
1760 0 : while ( aIter.IsMore() && !bMixed )
1761 0 : bMixed = ( aIter.Next()->GetObjInventor() != FmFormInventor );
1762 :
1763 0 : if ( !bMixed )
1764 : {
1765 : // all objects in the group are form objects
1766 0 : m_pView->MarkObj( pMark->GetMarkedSdrObj(), pMark->GetPageView(), true /* unmark! */ );
1767 0 : }
1768 : }
1769 : else
1770 : {
1771 0 : if ( pObj->GetObjInventor() == FmFormInventor )
1772 : { // this is a form layer object
1773 0 : m_pView->MarkObj( pMark->GetMarkedSdrObj(), pMark->GetPageView(), true /* unmark! */ );
1774 : }
1775 : }
1776 : }
1777 : }
1778 : }
1779 : }
1780 : else
1781 : {
1782 : OSL_FAIL( "FmXFormView::saveMarkList: invalid view!" );
1783 0 : m_aMark = SdrMarkList();
1784 : }
1785 320 : }
1786 :
1787 :
1788 0 : static bool lcl_hasObject( SdrObjListIter& rIter, SdrObject* pObj )
1789 : {
1790 0 : bool bFound = false;
1791 0 : while (rIter.IsMore() && !bFound)
1792 0 : bFound = pObj == rIter.Next();
1793 :
1794 0 : rIter.Reset();
1795 0 : return bFound;
1796 : }
1797 :
1798 :
1799 5178 : void FmXFormView::restoreMarkList( SdrMarkList& _rRestoredMarkList )
1800 : {
1801 5178 : if ( !m_pView )
1802 0 : return;
1803 :
1804 5178 : _rRestoredMarkList.Clear();
1805 :
1806 5178 : const SdrMarkList& rCurrentList = m_pView->GetMarkedObjectList();
1807 5178 : FmFormPage* pPage = GetFormShell() ? GetFormShell()->GetCurPage() : NULL;
1808 5178 : if (pPage)
1809 : {
1810 5178 : if (rCurrentList.GetMarkCount())
1811 : { // there is a current mark ... hmm. Is it a subset of the mark we remembered in saveMarkList?
1812 0 : bool bMisMatch = false;
1813 :
1814 : // loop through all current marks
1815 0 : const size_t nCurrentCount = rCurrentList.GetMarkCount();
1816 0 : for ( size_t i=0; i<nCurrentCount && !bMisMatch; ++i )
1817 : {
1818 0 : const SdrObject* pCurrentMarked = rCurrentList.GetMark( i )->GetMarkedSdrObj();
1819 :
1820 : // loop through all saved marks, check for equality
1821 0 : bool bFound = false;
1822 0 : const size_t nSavedCount = m_aMark.GetMarkCount();
1823 0 : for ( size_t j=0; j<nSavedCount && !bFound; ++j )
1824 : {
1825 0 : if ( m_aMark.GetMark( j )->GetMarkedSdrObj() == pCurrentMarked )
1826 0 : bFound = true;
1827 : }
1828 :
1829 : // did not find a current mark in the saved marks
1830 0 : if ( !bFound )
1831 0 : bMisMatch = true;
1832 : }
1833 :
1834 0 : if ( bMisMatch )
1835 : {
1836 0 : m_aMark.Clear();
1837 0 : _rRestoredMarkList = rCurrentList;
1838 0 : return;
1839 : }
1840 : }
1841 : // wichtig ist das auf die Objecte der markliste nicht zugegriffen wird
1842 : // da diese bereits zerstoert sein koennen
1843 5178 : SdrPageView* pCurPageView = m_pView->GetSdrPageView();
1844 5178 : SdrObjListIter aPageIter( *pPage );
1845 5178 : bool bFound = true;
1846 :
1847 : // gibt es noch alle Objecte
1848 5178 : const size_t nCount = m_aMark.GetMarkCount();
1849 5178 : for (size_t i = 0; i < nCount && bFound; ++i)
1850 : {
1851 0 : SdrMark* pMark = m_aMark.GetMark(i);
1852 0 : SdrObject* pObj = pMark->GetMarkedSdrObj();
1853 0 : if (pObj->IsGroupObject())
1854 : {
1855 0 : SdrObjListIter aIter(*pObj->GetSubList());
1856 0 : while (aIter.IsMore() && bFound)
1857 0 : bFound = lcl_hasObject(aPageIter, aIter.Next());
1858 : }
1859 : else
1860 0 : bFound = lcl_hasObject(aPageIter, pObj);
1861 :
1862 0 : bFound = bFound && pCurPageView == pMark->GetPageView();
1863 : }
1864 :
1865 5178 : if (bFound)
1866 : {
1867 : // Das LastObject auswerten
1868 5178 : if (nCount) // Objecte jetzt Markieren
1869 : {
1870 0 : for (size_t i = 0; i < nCount; ++i)
1871 : {
1872 0 : SdrMark* pMark = m_aMark.GetMark(i);
1873 0 : SdrObject* pObj = pMark->GetMarkedSdrObj();
1874 0 : if ( pObj->GetObjInventor() == FmFormInventor )
1875 0 : if ( !m_pView->IsObjMarked( pObj ) )
1876 0 : m_pView->MarkObj( pObj, pMark->GetPageView() );
1877 : }
1878 :
1879 0 : _rRestoredMarkList = m_aMark;
1880 : }
1881 : }
1882 5178 : m_aMark.Clear();
1883 : }
1884 : }
1885 :
1886 0 : void SAL_CALL FmXFormView::focusGained( const FocusEvent& /*e*/ ) throw (RuntimeException, std::exception)
1887 : {
1888 0 : if ( m_xWindow.is() && m_pView )
1889 : {
1890 0 : m_pView->SetMoveOutside( true, FmFormView::ImplAccess() );
1891 : }
1892 0 : }
1893 :
1894 0 : void SAL_CALL FmXFormView::focusLost( const FocusEvent& /*e*/ ) throw (RuntimeException, std::exception)
1895 : {
1896 : // when switch the focus outside the office the mark didn't change
1897 : // so we can not remove us as focus listener
1898 0 : if ( m_xWindow.is() && m_pView )
1899 : {
1900 0 : m_pView->SetMoveOutside( false, FmFormView::ImplAccess() );
1901 : }
1902 0 : }
1903 :
1904 0 : void FmXFormView::removeGridWindowListening()
1905 : {
1906 0 : if ( m_xWindow.is() )
1907 : {
1908 0 : m_xWindow->removeFocusListener(this);
1909 0 : if ( m_pView )
1910 : {
1911 0 : m_pView->SetMoveOutside( false, FmFormView::ImplAccess() );
1912 : }
1913 0 : m_xWindow = NULL;
1914 : }
1915 0 : }
1916 :
1917 :
1918 0 : DocumentType FmXFormView::impl_getDocumentType() const
1919 : {
1920 0 : if ( GetFormShell() && GetFormShell()->GetImpl() )
1921 0 : return GetFormShell()->GetImpl()->getDocumentType();
1922 0 : return eUnknownDocumentType;
1923 651 : }
1924 :
1925 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|