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 0 : 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 0 : 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 0 : m_pWindow( dynamic_cast< Window* >( &_rWindow.GetPaintWindow().GetOutputDevice() ) )
171 : {
172 :
173 : // create an XFormController for every form
174 0 : FmFormPage* pFormPage = dynamic_cast< FmFormPage* >( _rWindow.GetPageView().GetPage() );
175 : DBG_ASSERT( pFormPage, "FormViewPageWindowAdapter::FormViewPageWindowAdapter: no FmFormPage found!" );
176 0 : if ( pFormPage )
177 : {
178 : try
179 : {
180 0 : Reference< XIndexAccess > xForms( pFormPage->GetForms(), UNO_QUERY_THROW );
181 0 : sal_uInt32 nLength = xForms->getCount();
182 0 : for (sal_uInt32 i = 0; i < nLength; i++)
183 : {
184 0 : Reference< XForm > xForm( xForms->getByIndex(i), UNO_QUERY );
185 0 : if ( xForm.is() )
186 0 : setController( xForm, NULL );
187 0 : }
188 : }
189 0 : catch (const Exception&)
190 : {
191 : DBG_UNHANDLED_EXCEPTION();
192 : }
193 : }
194 0 : }
195 :
196 0 : FormViewPageWindowAdapter::~FormViewPageWindowAdapter()
197 : {
198 0 : }
199 :
200 :
201 0 : void FormViewPageWindowAdapter::dispose()
202 : {
203 0 : for ( ::std::vector< Reference< XFormController > >::const_iterator i = m_aControllerList.begin();
204 0 : i != m_aControllerList.end();
205 : ++i
206 : )
207 : {
208 : try
209 : {
210 0 : Reference< XFormController > xController( *i, UNO_QUERY_THROW );
211 :
212 : // detaching the events
213 0 : Reference< XChild > xControllerModel( xController->getModel(), UNO_QUERY );
214 0 : if ( xControllerModel.is() )
215 : {
216 0 : Reference< XEventAttacherManager > xEventManager( xControllerModel->getParent(), UNO_QUERY_THROW );
217 0 : Reference< XInterface > xControllerNormalized( xController, UNO_QUERY_THROW );
218 0 : xEventManager->detach( i - m_aControllerList.begin(), xControllerNormalized );
219 : }
220 :
221 : // dispose the formcontroller
222 0 : xController->dispose();
223 : }
224 0 : catch (const Exception&)
225 : {
226 : DBG_UNHANDLED_EXCEPTION();
227 : }
228 : }
229 :
230 0 : m_aControllerList.clear();
231 0 : }
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 ::getCppuType((const Reference< XFormController>*)0);
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 0 : void SAL_CALL FormViewPageWindowAdapter::makeVisible( const Reference< XControl >& _Control ) throw (RuntimeException, std::exception)
274 : {
275 0 : SolarMutexGuard aSolarGuard;
276 :
277 0 : Reference< XWindow > xWindow( _Control, UNO_QUERY );
278 0 : if ( xWindow.is() && m_pViewImpl->getView() && m_pWindow )
279 : {
280 0 : awt::Rectangle aRect = xWindow->getPosSize();
281 0 : ::Rectangle aNewRect( aRect.X, aRect.Y, aRect.X + aRect.Width, aRect.Y + aRect.Height );
282 0 : aNewRect = m_pWindow->PixelToLogic( aNewRect );
283 0 : m_pViewImpl->getView()->MakeVisible( aNewRect, *m_pWindow );
284 0 : }
285 0 : }
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 0 : Reference< XFormController > FormViewPageWindowAdapter::getController( const Reference< XForm > & xForm ) const
313 : {
314 0 : Reference< XTabControllerModel > xModel(xForm, UNO_QUERY);
315 0 : for (::std::vector< Reference< XFormController > >::const_iterator i = m_aControllerList.begin();
316 0 : i != m_aControllerList.end(); ++i)
317 : {
318 0 : if ((XTabControllerModel*)(*i)->getModel().get() == (XTabControllerModel*)xModel.get())
319 0 : 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 0 : 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 0 : Reference< XIndexAccess > xFormCps(xForm, UNO_QUERY);
334 0 : if (!xFormCps.is())
335 0 : return;
336 :
337 0 : Reference< XTabControllerModel > xTabOrder(xForm, UNO_QUERY);
338 :
339 : // create a form controller
340 0 : Reference< XFormController > xController( FormController::create(m_xContext) );
341 :
342 0 : Reference< XInteractionHandler > xHandler;
343 0 : 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 0 : if ( xHandler.is() )
351 0 : xController->setInteractionHandler( xHandler );
352 :
353 0 : xController->setContext( this );
354 :
355 0 : xController->setModel( xTabOrder );
356 0 : xController->setContainer( m_xControlContainer );
357 0 : xController->activateTabOrder();
358 0 : xController->addActivateListener( m_pViewImpl );
359 :
360 0 : if ( _rxParentController.is() )
361 0 : _rxParentController->addChildController( xController );
362 : else
363 : {
364 0 : m_aControllerList.push_back(xController);
365 :
366 0 : xController->setParent( *this );
367 :
368 : // attaching the events
369 0 : Reference< XEventAttacherManager > xEventManager( xForm->getParent(), UNO_QUERY );
370 0 : xEventManager->attach(m_aControllerList.size() - 1, xController, makeAny(xController) );
371 : }
372 :
373 : // jetzt die Subforms durchgehen
374 0 : sal_uInt32 nLength = xFormCps->getCount();
375 0 : Reference< XForm > xSubForm;
376 0 : for (sal_uInt32 i = 0; i < nLength; i++)
377 : {
378 0 : if ( xFormCps->getByIndex(i) >>= xSubForm )
379 0 : setController( xSubForm, xController );
380 0 : }
381 : }
382 :
383 :
384 0 : void FormViewPageWindowAdapter::updateTabOrder( const Reference< XForm >& _rxForm )
385 : {
386 : OSL_PRECOND( _rxForm.is(), "FormViewPageWindowAdapter::updateTabOrder: illegal argument!" );
387 0 : if ( !_rxForm.is() )
388 0 : return;
389 :
390 : try
391 : {
392 0 : Reference< XTabController > xTabCtrl( getController( _rxForm ).get() );
393 0 : if ( xTabCtrl.is() )
394 : { // if there already is a TabController for this form, then delegate the "updateTabOrder" request
395 0 : 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 0 : }
410 : }
411 0 : catch (const Exception&)
412 : {
413 : DBG_UNHANDLED_EXCEPTION();
414 : }
415 : }
416 :
417 :
418 0 : 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 0 : ,m_isTabOrderUpdateSuspended( false )
428 : {
429 0 : }
430 :
431 :
432 0 : void FmXFormView::cancelEvents()
433 : {
434 0 : if ( m_nActivationEvent )
435 : {
436 0 : Application::RemoveUserEvent( m_nActivationEvent );
437 0 : m_nActivationEvent = 0;
438 : }
439 :
440 0 : if ( m_nErrorMessageEvent )
441 : {
442 0 : Application::RemoveUserEvent( m_nErrorMessageEvent );
443 0 : m_nErrorMessageEvent = 0;
444 : }
445 :
446 0 : if ( m_nAutoFocusEvent )
447 : {
448 0 : Application::RemoveUserEvent( m_nAutoFocusEvent );
449 0 : m_nAutoFocusEvent = 0;
450 : }
451 :
452 0 : if ( m_nControlWizardEvent )
453 : {
454 0 : Application::RemoveUserEvent( m_nControlWizardEvent );
455 0 : m_nControlWizardEvent = 0;
456 : }
457 0 : }
458 :
459 :
460 0 : void FmXFormView::notifyViewDying( )
461 : {
462 : DBG_ASSERT( m_pView, "FmXFormView::notifyViewDying: my view already died!" );
463 0 : m_pView = NULL;
464 0 : cancelEvents();
465 0 : }
466 :
467 :
468 0 : FmXFormView::~FmXFormView()
469 : {
470 : DBG_ASSERT( m_aPageWindowAdapters.empty(), "FmXFormView::~FmXFormView: Window list not empty!" );
471 0 : 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 0 : cancelEvents();
483 :
484 0 : delete m_pWatchStoredList;
485 0 : m_pWatchStoredList = NULL;
486 0 : }
487 :
488 : // EventListener
489 :
490 0 : void SAL_CALL FmXFormView::disposing(const EventObject& Source) throw( RuntimeException, std::exception )
491 : {
492 0 : if ( m_xWindow.is() && Source.Source == m_xWindow )
493 0 : removeGridWindowListening();
494 0 : }
495 :
496 : // XFormControllerListener
497 :
498 0 : void SAL_CALL FmXFormView::formActivated(const EventObject& rEvent) throw( RuntimeException, std::exception )
499 : {
500 0 : if ( m_pView && m_pView->GetFormShell() && m_pView->GetFormShell()->GetImpl() )
501 0 : m_pView->GetFormShell()->GetImpl()->formActivated( rEvent );
502 0 : }
503 :
504 :
505 0 : void SAL_CALL FmXFormView::formDeactivated(const EventObject& rEvent) throw( RuntimeException, std::exception )
506 : {
507 0 : if ( m_pView && m_pView->GetFormShell() && m_pView->GetFormShell()->GetImpl() )
508 0 : m_pView->GetFormShell()->GetImpl()->formDeactivated( rEvent );
509 0 : }
510 :
511 : // XContainerListener
512 :
513 0 : void SAL_CALL FmXFormView::elementInserted(const ContainerEvent& evt) throw( RuntimeException, std::exception )
514 : {
515 : try
516 : {
517 0 : Reference< XControlContainer > xControlContainer( evt.Source, UNO_QUERY_THROW );
518 0 : Reference< XControl > xControl( evt.Element, UNO_QUERY_THROW );
519 0 : Reference< XFormComponent > xControlModel( xControl->getModel(), UNO_QUERY_THROW );
520 0 : Reference< XForm > xForm( xControlModel->getParent(), UNO_QUERY_THROW );
521 :
522 0 : if ( m_isTabOrderUpdateSuspended )
523 : {
524 : // remember the container and the control, so we can update the tab order on resumeTabOrderUpdate
525 0 : 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 0 : }
533 : }
534 0 : catch (const Exception&)
535 : {
536 : DBG_UNHANDLED_EXCEPTION();
537 : }
538 0 : }
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 0 : void SAL_CALL FmXFormView::elementRemoved(const ContainerEvent& /*evt*/) throw( RuntimeException, std::exception )
548 : {
549 0 : }
550 :
551 :
552 0 : PFormViewPageWindowAdapter FmXFormView::findWindow( const Reference< XControlContainer >& _rxCC ) const
553 : {
554 0 : for ( PageWindowAdapterList::const_iterator i = m_aPageWindowAdapters.begin();
555 0 : i != m_aPageWindowAdapters.end();
556 : ++i
557 : )
558 : {
559 0 : if ( _rxCC == (*i)->getControlContainer() )
560 0 : return *i;
561 : }
562 0 : return NULL;
563 : }
564 :
565 :
566 0 : void FmXFormView::addWindow(const SdrPageWindow& rWindow)
567 : {
568 0 : FmFormPage* pFormPage = PTR_CAST( FmFormPage, rWindow.GetPageView().GetPage() );
569 0 : if ( !pFormPage )
570 0 : return;
571 :
572 0 : Reference< XControlContainer > xCC = rWindow.GetControlContainer();
573 0 : if ( xCC.is()
574 0 : && ( !findWindow( xCC ).is() )
575 : )
576 : {
577 0 : PFormViewPageWindowAdapter pAdapter = new FormViewPageWindowAdapter( comphelper::getProcessComponentContext(), rWindow, this );
578 0 : m_aPageWindowAdapters.push_back( pAdapter );
579 :
580 : // Am ControlContainer horchen um Aenderungen mitzbekommen
581 0 : Reference< XContainer > xContainer( xCC, UNO_QUERY );
582 0 : if ( xContainer.is() )
583 0 : xContainer->addContainerListener( this );
584 0 : }
585 : }
586 :
587 :
588 0 : 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 0 : for ( PageWindowAdapterList::iterator i = m_aPageWindowAdapters.begin();
597 0 : i != m_aPageWindowAdapters.end();
598 : ++i
599 : )
600 : {
601 0 : if ( _rxCC != (*i)->getControlContainer() )
602 0 : continue;
603 :
604 0 : Reference< XContainer > xContainer( _rxCC, UNO_QUERY );
605 0 : if ( xContainer.is() )
606 0 : xContainer->removeContainerListener( this );
607 :
608 0 : (*i)->dispose();
609 0 : m_aPageWindowAdapters.erase( i );
610 0 : break;
611 0 : }
612 0 : }
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 0 : void FmXFormView::onFirstViewActivation( const FmFormModel* _pDocModel )
634 : {
635 0 : if ( _pDocModel && _pDocModel->GetAutoControlFocus() )
636 0 : m_nAutoFocusEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnAutoFocus ) );
637 0 : }
638 :
639 :
640 0 : void FmXFormView::suspendTabOrderUpdate()
641 : {
642 : OSL_ENSURE( !m_isTabOrderUpdateSuspended, "FmXFormView::suspendTabOrderUpdate: nesting not allowed!" );
643 0 : m_isTabOrderUpdateSuspended = true;
644 0 : }
645 :
646 :
647 0 : void FmXFormView::resumeTabOrderUpdate()
648 : {
649 : OSL_ENSURE( m_isTabOrderUpdateSuspended, "FmXFormView::resumeTabOrderUpdate: not suspended!" );
650 0 : m_isTabOrderUpdateSuspended = false;
651 :
652 : // update the tab orders for all components which were collected since the suspendTabOrderUpdate call.
653 0 : for ( MapControlContainerToSetOfForms::const_iterator container = m_aNeedTabOrderUpdate.begin();
654 0 : container != m_aNeedTabOrderUpdate.end();
655 : ++container
656 : )
657 : {
658 0 : PFormViewPageWindowAdapter pAdapter = findWindow( container->first );
659 0 : if ( !pAdapter.is() )
660 0 : continue;
661 :
662 0 : for ( SetOfForms::const_iterator form = container->second.begin();
663 0 : form != container->second.end();
664 : ++form
665 : )
666 : {
667 0 : pAdapter->updateTabOrder( *form );
668 : }
669 0 : }
670 0 : m_aNeedTabOrderUpdate.clear();
671 0 : }
672 :
673 :
674 0 : IMPL_LINK(FmXFormView, OnActivate, void*, /*EMPTYTAG*/)
675 : {
676 0 : m_nActivationEvent = 0;
677 :
678 0 : 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 0 : if (m_pView->GetFormShell() && m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
686 : {
687 0 : Window* pWindow = const_cast<Window*>(static_cast<const Window*>(m_pView->GetActualOutDev()));
688 0 : PFormViewPageWindowAdapter pAdapter = m_aPageWindowAdapters.empty() ? NULL : m_aPageWindowAdapters[0];
689 0 : for ( PageWindowAdapterList::const_iterator i = m_aPageWindowAdapters.begin();
690 0 : i != m_aPageWindowAdapters.end();
691 : ++i
692 : )
693 : {
694 0 : if ( pWindow == (*i)->getWindow() )
695 0 : pAdapter =*i;
696 : }
697 :
698 0 : if ( pAdapter.get() )
699 : {
700 0 : for ( ::std::vector< Reference< XFormController > >::const_iterator i = pAdapter->GetList().begin();
701 0 : i != pAdapter->GetList().end();
702 : ++i
703 : )
704 : {
705 0 : const Reference< XFormController > & xController = *i;
706 0 : if ( !xController.is() )
707 0 : continue;
708 :
709 : // only database forms are to be activated
710 0 : Reference< XRowSet > xForm(xController->getModel(), UNO_QUERY);
711 0 : if ( !xForm.is() || !OStaticDataAccessTools().getRowSetConnection( xForm ).is() )
712 0 : 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 0 : }
731 : }
732 0 : return 0;
733 : }
734 :
735 :
736 0 : void FmXFormView::Activate(sal_Bool bSync)
737 : {
738 0 : if (m_nActivationEvent)
739 : {
740 0 : Application::RemoveUserEvent(m_nActivationEvent);
741 0 : m_nActivationEvent = 0;
742 : }
743 :
744 0 : if (bSync)
745 : {
746 0 : LINK(this,FmXFormView,OnActivate).Call(NULL);
747 : }
748 : else
749 0 : m_nActivationEvent = Application::PostUserEvent(LINK(this,FmXFormView,OnActivate));
750 0 : }
751 :
752 :
753 0 : void FmXFormView::Deactivate(sal_Bool bDeactivateController)
754 : {
755 0 : if (m_nActivationEvent)
756 : {
757 0 : Application::RemoveUserEvent(m_nActivationEvent);
758 0 : m_nActivationEvent = 0;
759 : }
760 :
761 0 : FmXFormShell* pShImpl = m_pView->GetFormShell() ? m_pView->GetFormShell()->GetImpl() : NULL;
762 0 : if (pShImpl && bDeactivateController)
763 0 : pShImpl->setActiveController( NULL );
764 0 : }
765 :
766 :
767 0 : FmFormShell* FmXFormView::GetFormShell() const
768 : {
769 0 : return m_pView ? m_pView->GetFormShell() : NULL;
770 : }
771 :
772 0 : void FmXFormView::AutoFocus( sal_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 0 : bool FmXFormView::isFocusable( const Reference< XControl >& i_rControl )
785 : {
786 0 : if ( !i_rControl.is() )
787 0 : return false;
788 :
789 : try
790 : {
791 0 : Reference< XPropertySet > xModelProps( i_rControl->getModel(), UNO_QUERY_THROW );
792 :
793 : // only enabled controls are allowed to participate
794 0 : sal_Bool bEnabled = sal_False;
795 0 : OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_ENABLED ) >>= bEnabled );
796 0 : if ( !bEnabled )
797 0 : return false;
798 :
799 : // check the class id of the control model
800 0 : sal_Int16 nClassId = FormComponentType::CONTROL;
801 0 : OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
802 :
803 : // controls which are not focussable
804 0 : if ( ( FormComponentType::CONTROL != nClassId )
805 0 : && ( FormComponentType::IMAGEBUTTON != nClassId )
806 0 : && ( FormComponentType::GROUPBOX != nClassId )
807 0 : && ( FormComponentType::FIXEDTEXT != nClassId )
808 0 : && ( FormComponentType::HIDDENCONTROL != nClassId )
809 0 : && ( FormComponentType::IMAGECONTROL != nClassId )
810 0 : && ( FormComponentType::SCROLLBAR != nClassId )
811 0 : && ( FormComponentType::SPINBUTTON!= nClassId )
812 : )
813 : {
814 0 : return true;
815 0 : }
816 : }
817 0 : catch (const Exception&)
818 : {
819 : DBG_UNHANDLED_EXCEPTION();
820 : }
821 0 : return false;
822 : }
823 :
824 :
825 0 : static Reference< XControl > lcl_firstFocussableControl( const Sequence< Reference< XControl > >& _rControls )
826 : {
827 0 : Reference< XControl > xReturn;
828 :
829 : // loop through all the controls
830 0 : const Reference< XControl >* pControls = _rControls.getConstArray();
831 0 : const Reference< XControl >* pControlsEnd = _rControls.getConstArray() + _rControls.getLength();
832 0 : for ( ; pControls != pControlsEnd; ++pControls )
833 : {
834 0 : if ( !pControls->is() )
835 0 : continue;
836 :
837 0 : if ( FmXFormView::isFocusable( *pControls ) )
838 : {
839 0 : xReturn = *pControls;
840 0 : break;
841 : }
842 : }
843 :
844 0 : if ( !xReturn.is() && _rControls.getLength() )
845 0 : xReturn = _rControls[0];
846 :
847 0 : return xReturn;
848 : }
849 :
850 :
851 : namespace
852 : {
853 :
854 0 : void lcl_ensureControlsOfFormExist_nothrow( const SdrPage& _rPage, const SdrView& _rView, const 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 0 : IMPL_LINK(FmXFormView, OnAutoFocus, void*, /*EMPTYTAG*/)
913 : {
914 0 : 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 0 : SdrPageView *pPageView = m_pView ? m_pView->GetSdrPageView() : NULL;
923 0 : SdrPage *pSdrPage = pPageView ? pPageView->GetPage() : NULL;
924 : // get the forms collection of the page we belong to
925 0 : FmFormPage* pPage = PTR_CAST( FmFormPage, pSdrPage );
926 0 : Reference< XIndexAccess > xForms( pPage ? Reference< XIndexAccess >( pPage->GetForms(), UNO_QUERY ) : Reference< XIndexAccess >() );
927 :
928 0 : const PFormViewPageWindowAdapter pAdapter = m_aPageWindowAdapters.empty() ? NULL : m_aPageWindowAdapters[0];
929 0 : const Window* pWindow = pAdapter.get() ? pAdapter->getWindow() : NULL;
930 :
931 0 : 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 0 : if ( !xForms->getCount() )
937 0 : break;
938 0 : Reference< XForm > xForm( xForms->getByIndex( 0 ), UNO_QUERY_THROW );
939 0 : Reference< XTabController > xTabController( pAdapter->getController( xForm ), UNO_QUERY_THROW );
940 :
941 : // go for the first control of the controller
942 0 : Sequence< Reference< XControl > > aControls( xTabController->getControls() );
943 0 : 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 0 : Reference< XWindow > xControlWindow( lcl_firstFocussableControl( aControls ), UNO_QUERY );
961 0 : if ( !xControlWindow.is() )
962 0 : break;
963 :
964 0 : xControlWindow->setFocus();
965 :
966 : // ensure that the control is visible
967 : // 80210 - 12/07/00 - FS
968 0 : const Window* pCurrentWindow = dynamic_cast< const Window* >( m_pView->GetActualOutDev() );
969 0 : if ( pCurrentWindow )
970 : {
971 0 : awt::Rectangle aRect = xControlWindow->getPosSize();
972 0 : ::Rectangle aNonUnoRect( aRect.X, aRect.Y, aRect.X + aRect.Width, aRect.Y + aRect.Height );
973 0 : m_pView->MakeVisible( pCurrentWindow->PixelToLogic( aNonUnoRect ), *const_cast< Window* >( pCurrentWindow ) );
974 0 : }
975 : }
976 0 : catch (const Exception&)
977 : {
978 : DBG_UNHANDLED_EXCEPTION();
979 0 : }
980 :
981 : } // do
982 : while ( false );
983 :
984 0 : 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( sal_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 :
1025 0 : IMPL_LINK( FmXFormView, OnStartControlWizard, void*, /**/ )
1026 : {
1027 0 : m_nControlWizardEvent = 0;
1028 : OSL_PRECOND( m_xLastCreatedControlModel.is(), "FmXFormView::OnStartControlWizard: illegal call!" );
1029 0 : if ( !m_xLastCreatedControlModel.is() )
1030 0 : return 0L;
1031 :
1032 0 : sal_Int16 nClassId = FormComponentType::CONTROL;
1033 : try
1034 : {
1035 0 : OSL_VERIFY( m_xLastCreatedControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
1036 : }
1037 0 : catch (const Exception&)
1038 : {
1039 : DBG_UNHANDLED_EXCEPTION();
1040 : }
1041 :
1042 0 : const sal_Char* pWizardAsciiName = NULL;
1043 0 : switch ( nClassId )
1044 : {
1045 : case FormComponentType::GRIDCONTROL:
1046 0 : pWizardAsciiName = "com.sun.star.sdb.GridControlAutoPilot";
1047 0 : break;
1048 : case FormComponentType::LISTBOX:
1049 : case FormComponentType::COMBOBOX:
1050 0 : pWizardAsciiName = "com.sun.star.sdb.ListComboBoxAutoPilot";
1051 0 : break;
1052 : case FormComponentType::GROUPBOX:
1053 0 : pWizardAsciiName = "com.sun.star.sdb.GroupBoxAutoPilot";
1054 0 : break;
1055 : }
1056 :
1057 0 : if ( pWizardAsciiName )
1058 : {
1059 : // build the argument list
1060 0 : ::comphelper::NamedValueCollection aWizardArgs;
1061 0 : aWizardArgs.put( "ObjectModel", m_xLastCreatedControlModel );
1062 :
1063 : // create the wizard object
1064 0 : Reference< XExecutableDialog > xWizard;
1065 : try
1066 : {
1067 0 : Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
1068 0 : xWizard.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext( OUString::createFromAscii(pWizardAsciiName), aWizardArgs.getWrappedPropertyValues(), xContext ), UNO_QUERY);;
1069 : }
1070 0 : catch (const Exception&)
1071 : {
1072 : DBG_UNHANDLED_EXCEPTION();
1073 : }
1074 :
1075 0 : if ( !xWizard.is() )
1076 : {
1077 0 : ShowServiceNotAvailableError( NULL, OUString::createFromAscii(pWizardAsciiName), true );
1078 : }
1079 : else
1080 : {
1081 : // execute the wizard
1082 : try
1083 : {
1084 0 : xWizard->execute();
1085 : }
1086 0 : catch (const Exception&)
1087 : {
1088 : DBG_UNHANDLED_EXCEPTION();
1089 : }
1090 0 : }
1091 : }
1092 :
1093 0 : m_xLastCreatedControlModel.clear();
1094 0 : return 1L;
1095 : }
1096 :
1097 :
1098 : namespace
1099 : {
1100 0 : void lcl_insertIntoFormComponentHierarchy_throw( const FmFormView& _rView, const SdrUnoObj& _rSdrObj,
1101 : const Reference< XDataSource >& _rxDataSource = NULL, const OUString& _rDataSourceName = OUString(),
1102 : const OUString& _rCommand = OUString(), const sal_Int32 _nCommandType = -1 )
1103 : {
1104 0 : FmFormPage& rPage = static_cast< FmFormPage& >( *_rView.GetSdrPageView()->GetPage() );
1105 :
1106 0 : Reference< XFormComponent > xFormComponent( _rSdrObj.GetUnoControlModel(), UNO_QUERY_THROW );
1107 : Reference< XForm > xTargetForm(
1108 0 : rPage.GetImpl().findPlaceInFormComponentHierarchy( xFormComponent, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType ),
1109 0 : UNO_SET_THROW );
1110 :
1111 0 : rPage.GetImpl().setUniqueName( xFormComponent, xTargetForm );
1112 :
1113 0 : Reference< XIndexContainer > xFormAsContainer( xTargetForm, UNO_QUERY_THROW );
1114 0 : xFormAsContainer->insertByIndex( xFormAsContainer->getCount(), makeAny( xFormComponent ) );
1115 0 : }
1116 : }
1117 :
1118 :
1119 0 : SdrObject* FmXFormView::implCreateFieldControl( const ::svx::ODataAccessDescriptor& _rColumnDescriptor )
1120 : {
1121 : // not if we're in design mode
1122 0 : if ( !m_pView->IsDesignMode() )
1123 0 : return NULL;
1124 :
1125 0 : OUString sCommand, sFieldName;
1126 0 : sal_Int32 nCommandType = CommandType::COMMAND;
1127 0 : SharedConnection xConnection;
1128 :
1129 0 : OUString sDataSource = _rColumnDescriptor.getDataSource();
1130 0 : _rColumnDescriptor[ daCommand ] >>= sCommand;
1131 0 : _rColumnDescriptor[ daColumnName ] >>= sFieldName;
1132 0 : _rColumnDescriptor[ daCommandType ] >>= nCommandType;
1133 : {
1134 0 : Reference< XConnection > xExternalConnection;
1135 0 : _rColumnDescriptor[ daConnection ] >>= xExternalConnection;
1136 0 : xConnection.reset( xExternalConnection, SharedConnection::NoTakeOwnership );
1137 : }
1138 :
1139 0 : if ( sCommand.isEmpty()
1140 0 : || sFieldName.isEmpty()
1141 0 : || ( sDataSource.isEmpty()
1142 0 : && !xConnection.is()
1143 : )
1144 : )
1145 : {
1146 : OSL_FAIL( "FmXFormView::implCreateFieldControl: nonsense!" );
1147 : }
1148 :
1149 0 : Reference< XDataSource > xDataSource;
1150 0 : SQLErrorEvent aError;
1151 : try
1152 : {
1153 0 : if ( xConnection.is() && !xDataSource.is() && sDataSource.isEmpty() )
1154 : {
1155 0 : Reference< XChild > xChild( xConnection, UNO_QUERY );
1156 0 : if ( xChild.is() )
1157 0 : xDataSource = xDataSource.query( xChild->getParent() );
1158 : }
1159 :
1160 : // obtain the data source
1161 0 : if ( !xDataSource.is() )
1162 0 : xDataSource = OStaticDataAccessTools().getDataSource( sDataSource, comphelper::getProcessComponentContext() );
1163 :
1164 : // and the connection, if necessary
1165 0 : if ( !xConnection.is() )
1166 : xConnection.reset( OStaticDataAccessTools().getConnection_withFeedback(
1167 : sDataSource,
1168 : OUString(),
1169 : OUString(),
1170 : comphelper::getProcessComponentContext()
1171 0 : ) );
1172 : }
1173 0 : catch (const SQLException&)
1174 : {
1175 0 : aError.Reason = ::cppu::getCaughtException();
1176 : }
1177 0 : catch (const Exception& )
1178 : {
1179 : /* will be asserted below */
1180 : }
1181 0 : if (aError.Reason.hasValue())
1182 : {
1183 0 : displayAsyncErrorMessage( aError );
1184 0 : return NULL;
1185 : }
1186 :
1187 : // need a data source and a connection here
1188 0 : if (!xDataSource.is() || !xConnection.is())
1189 : {
1190 : OSL_FAIL("FmXFormView::implCreateFieldControl : could not retrieve the data source or the connection!");
1191 0 : return NULL;
1192 : }
1193 :
1194 0 : OStaticDataAccessTools aDBATools;
1195 0 : Reference< XComponent > xKeepFieldsAlive;
1196 : // go
1197 : try
1198 : {
1199 : // determine the table/query field which we should create a control for
1200 0 : Reference< XPropertySet > xField;
1201 :
1202 : Reference< XNameAccess > xFields = aDBATools.getFieldsByCommandDescriptor(
1203 0 : xConnection, nCommandType, sCommand, xKeepFieldsAlive );
1204 :
1205 0 : if (xFields.is() && xFields->hasByName(sFieldName))
1206 0 : xFields->getByName(sFieldName) >>= xField;
1207 0 : if ( !xField.is() )
1208 0 : return NULL;
1209 :
1210 0 : Reference< XNumberFormatsSupplier > xSupplier( aDBATools.getNumberFormats( xConnection, sal_False ), UNO_SET_THROW );
1211 0 : Reference< XNumberFormats > xNumberFormats( xSupplier->getNumberFormats(), UNO_SET_THROW );
1212 :
1213 0 : OUString sLabelPostfix;
1214 :
1215 :
1216 : // nur fuer Textgroesse
1217 0 : OutputDevice* pOutDev = NULL;
1218 0 : if (m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
1219 0 : pOutDev = const_cast<OutputDevice*>(m_pView->GetActualOutDev());
1220 : else
1221 : {// OutDev suchen
1222 0 : SdrPageView* pPageView = m_pView->GetSdrPageView();
1223 0 : if( pPageView && !pOutDev )
1224 : {
1225 : // const SdrPageViewWinList& rWinList = pPageView->GetWinList();
1226 : // const SdrPageViewWindows& rPageViewWindows = pPageView->GetPageViewWindows();
1227 :
1228 0 : for( sal_uInt32 i = 0L; i < pPageView->PageWindowCount(); i++ )
1229 : {
1230 0 : const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(i);
1231 :
1232 0 : if( rPageWindow.GetPaintWindow().OutputToWindow())
1233 : {
1234 0 : pOutDev = &rPageWindow.GetPaintWindow().GetOutputDevice();
1235 0 : break;
1236 : }
1237 : }
1238 : }
1239 : }
1240 :
1241 0 : if ( !pOutDev )
1242 0 : return NULL;
1243 :
1244 0 : sal_Int32 nDataType = ::comphelper::getINT32(xField->getPropertyValue(FM_PROP_FIELDTYPE));
1245 0 : if ((DataType::BINARY == nDataType) || (DataType::VARBINARY == nDataType))
1246 0 : return NULL;
1247 :
1248 :
1249 : // determine the control type by examining the data type of the bound column
1250 0 : sal_uInt16 nOBJID = 0;
1251 0 : sal_Bool bDateNTimeField = sal_False;
1252 :
1253 0 : sal_Bool bIsCurrency = sal_False;
1254 0 : if (::comphelper::hasProperty(FM_PROP_ISCURRENCY, xField))
1255 0 : bIsCurrency = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_ISCURRENCY));
1256 :
1257 0 : if (bIsCurrency)
1258 0 : nOBJID = OBJ_FM_CURRENCYFIELD;
1259 : else
1260 0 : switch (nDataType)
1261 : {
1262 : case DataType::BLOB:
1263 : case DataType::LONGVARBINARY:
1264 0 : nOBJID = OBJ_FM_IMAGECONTROL;
1265 0 : break;
1266 : case DataType::LONGVARCHAR:
1267 : case DataType::CLOB:
1268 0 : nOBJID = OBJ_FM_EDIT;
1269 0 : break;
1270 : case DataType::BINARY:
1271 : case DataType::VARBINARY:
1272 0 : return NULL;
1273 : case DataType::BIT:
1274 : case DataType::BOOLEAN:
1275 0 : nOBJID = OBJ_FM_CHECKBOX;
1276 0 : break;
1277 : case DataType::TINYINT:
1278 : case DataType::SMALLINT:
1279 : case DataType::INTEGER:
1280 0 : nOBJID = OBJ_FM_NUMERICFIELD;
1281 0 : break;
1282 : case DataType::REAL:
1283 : case DataType::DOUBLE:
1284 : case DataType::NUMERIC:
1285 : case DataType::DECIMAL:
1286 0 : nOBJID = OBJ_FM_FORMATTEDFIELD;
1287 0 : break;
1288 : case DataType::TIMESTAMP:
1289 0 : bDateNTimeField = sal_True;
1290 0 : sLabelPostfix = SVX_RESSTR(RID_STR_POSTFIX_DATE);
1291 : // DON'T break !
1292 : case DataType::DATE:
1293 0 : nOBJID = OBJ_FM_DATEFIELD;
1294 0 : break;
1295 : case DataType::TIME:
1296 0 : nOBJID = OBJ_FM_TIMEFIELD;
1297 0 : break;
1298 : case DataType::CHAR:
1299 : case DataType::VARCHAR:
1300 : default:
1301 0 : nOBJID = OBJ_FM_EDIT;
1302 0 : break;
1303 : }
1304 0 : if (!nOBJID)
1305 0 : return NULL;
1306 :
1307 0 : SdrUnoObj* pLabel( NULL );
1308 0 : SdrUnoObj* pControl( NULL );
1309 0 : if ( !createControlLabelPair( *pOutDev, 0, 0, xField, xNumberFormats, nOBJID, sLabelPostfix,
1310 0 : pLabel, pControl, xDataSource, sDataSource, sCommand, nCommandType )
1311 : )
1312 : {
1313 0 : return NULL;
1314 : }
1315 :
1316 :
1317 : // group objects
1318 0 : bool bCheckbox = ( OBJ_FM_CHECKBOX == nOBJID );
1319 : OSL_ENSURE( !bCheckbox || !pLabel, "FmXFormView::implCreateFieldControl: why was there a label created for a check box?" );
1320 0 : if ( bCheckbox )
1321 0 : return pControl;
1322 :
1323 0 : SdrObjGroup* pGroup = new SdrObjGroup();
1324 0 : SdrObjList* pObjList = pGroup->GetSubList();
1325 0 : pObjList->InsertObject( pLabel );
1326 0 : pObjList->InsertObject( pControl );
1327 :
1328 0 : if ( bDateNTimeField )
1329 : { // so far we created a date field only, but we also need a time field
1330 0 : pLabel = pControl = NULL;
1331 0 : if ( createControlLabelPair( *pOutDev, 0, 1000, xField, xNumberFormats, OBJ_FM_TIMEFIELD,
1332 0 : SVX_RESSTR(RID_STR_POSTFIX_TIME), pLabel, pControl,
1333 0 : xDataSource, sDataSource, sCommand, nCommandType )
1334 : )
1335 : {
1336 0 : pObjList->InsertObject( pLabel );
1337 0 : pObjList->InsertObject( pControl );
1338 : }
1339 : }
1340 :
1341 0 : return pGroup; // und fertig
1342 : }
1343 0 : catch (const Exception&)
1344 : {
1345 : DBG_UNHANDLED_EXCEPTION();
1346 : }
1347 :
1348 :
1349 0 : return NULL;
1350 : }
1351 :
1352 :
1353 0 : SdrObject* FmXFormView::implCreateXFormsControl( const ::svx::OXFormsDescriptor &_rDesc )
1354 : {
1355 : // not if we're in design mode
1356 0 : if ( !m_pView->IsDesignMode() )
1357 0 : return NULL;
1358 :
1359 0 : Reference< XComponent > xKeepFieldsAlive;
1360 :
1361 : // go
1362 : try
1363 : {
1364 : // determine the table/query field which we should create a control for
1365 0 : Reference< XNumberFormats > xNumberFormats;
1366 0 : OUString sLabelPostfix = _rDesc.szName;
1367 :
1368 :
1369 : // nur fuer Textgroesse
1370 0 : OutputDevice* pOutDev = NULL;
1371 0 : if (m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
1372 0 : pOutDev = const_cast<OutputDevice*>(m_pView->GetActualOutDev());
1373 : else
1374 : {// OutDev suchen
1375 0 : SdrPageView* pPageView = m_pView->GetSdrPageView();
1376 0 : if( pPageView && !pOutDev )
1377 : {
1378 : // const SdrPageViewWinList& rWinList = pPageView->GetWinList();
1379 : // const SdrPageViewWindows& rPageViewWindows = pPageView->GetPageViewWindows();
1380 :
1381 0 : for( sal_uInt32 i = 0L; i < pPageView->PageWindowCount(); i++ )
1382 : {
1383 0 : const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(i);
1384 :
1385 0 : if( rPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType() == OUTDEV_WINDOW)
1386 : {
1387 0 : pOutDev = &rPageWindow.GetPaintWindow().GetOutputDevice();
1388 0 : break;
1389 : }
1390 : }
1391 : }
1392 : }
1393 :
1394 0 : if ( !pOutDev )
1395 0 : return NULL;
1396 :
1397 :
1398 : // The service name decides which control should be created
1399 0 : sal_uInt16 nOBJID = OBJ_FM_EDIT;
1400 0 : if(OUString(_rDesc.szServiceName).equals((OUString)FM_SUN_COMPONENT_NUMERICFIELD))
1401 0 : nOBJID = OBJ_FM_NUMERICFIELD;
1402 0 : if(OUString(_rDesc.szServiceName).equals((OUString)FM_SUN_COMPONENT_CHECKBOX))
1403 0 : nOBJID = OBJ_FM_CHECKBOX;
1404 0 : if(OUString(_rDesc.szServiceName).equals((OUString)FM_COMPONENT_COMMANDBUTTON))
1405 0 : nOBJID = OBJ_FM_BUTTON;
1406 :
1407 : typedef ::com::sun::star::form::submission::XSubmission XSubmission_t;
1408 0 : Reference< XSubmission_t > xSubmission(_rDesc.xPropSet, UNO_QUERY);
1409 :
1410 : // xform control or submission button?
1411 0 : if ( !xSubmission.is() )
1412 : {
1413 0 : SdrUnoObj* pLabel( NULL );
1414 0 : SdrUnoObj* pControl( NULL );
1415 0 : if ( !createControlLabelPair( *pOutDev, 0, 0, NULL, xNumberFormats, nOBJID, sLabelPostfix,
1416 0 : pLabel, pControl )
1417 : )
1418 : {
1419 0 : return NULL;
1420 : }
1421 :
1422 :
1423 : // Now build the connection between the control and the data item.
1424 0 : Reference< XValueBinding > xValueBinding(_rDesc.xPropSet,UNO_QUERY);
1425 0 : Reference< XBindableValue > xBindableValue(pControl->GetUnoControlModel(),UNO_QUERY);
1426 :
1427 : DBG_ASSERT( xBindableValue.is(), "FmXFormView::implCreateXFormsControl: control's not bindable!" );
1428 0 : if ( xBindableValue.is() )
1429 0 : xBindableValue->setValueBinding(xValueBinding);
1430 :
1431 0 : bool bCheckbox = ( OBJ_FM_CHECKBOX == nOBJID );
1432 : OSL_ENSURE( !bCheckbox || !pLabel, "FmXFormView::implCreateXFormsControl: why was there a label created for a check box?" );
1433 0 : if ( bCheckbox )
1434 0 : return pControl;
1435 :
1436 :
1437 : // group objects
1438 0 : SdrObjGroup* pGroup = new SdrObjGroup();
1439 0 : SdrObjList* pObjList = pGroup->GetSubList();
1440 0 : pObjList->InsertObject(pLabel);
1441 0 : pObjList->InsertObject(pControl);
1442 :
1443 0 : return pGroup;
1444 : }
1445 : else {
1446 :
1447 : // create a button control
1448 0 : const MapMode eTargetMode( pOutDev->GetMapMode() );
1449 0 : const MapMode eSourceMode(MAP_100TH_MM);
1450 0 : const sal_uInt16 nObjID = OBJ_FM_BUTTON;
1451 0 : ::Size controlSize(4000, 500);
1452 0 : FmFormObj *pControl = static_cast<FmFormObj*>(SdrObjFactory::MakeNewObject( FmFormInventor, nObjID, NULL, NULL ));
1453 0 : controlSize.Width() = Fraction(controlSize.Width(), 1) * eTargetMode.GetScaleX();
1454 0 : controlSize.Height() = Fraction(controlSize.Height(), 1) * eTargetMode.GetScaleY();
1455 0 : ::Point controlPos( pOutDev->LogicToLogic( ::Point( controlSize.Width(), 0 ), eSourceMode, eTargetMode ) );
1456 0 : ::Rectangle controlRect( controlPos, pOutDev->LogicToLogic( controlSize, eSourceMode, eTargetMode ) );
1457 0 : pControl->SetLogicRect(controlRect);
1458 :
1459 : // set the button label
1460 0 : Reference< XPropertySet > xControlSet(pControl->GetUnoControlModel(), UNO_QUERY);
1461 0 : xControlSet->setPropertyValue(FM_PROP_LABEL, makeAny(OUString(_rDesc.szName)));
1462 :
1463 : // connect the submission with the submission supplier (aka the button)
1464 0 : xControlSet->setPropertyValue( FM_PROP_BUTTON_TYPE,
1465 0 : makeAny( FormButtonType_SUBMIT ) );
1466 : typedef ::com::sun::star::form::submission::XSubmissionSupplier XSubmissionSupplier_t;
1467 0 : Reference< XSubmissionSupplier_t > xSubmissionSupplier(pControl->GetUnoControlModel(), UNO_QUERY);
1468 0 : xSubmissionSupplier->setSubmission(xSubmission);
1469 :
1470 0 : return pControl;
1471 0 : }
1472 : }
1473 0 : catch (const Exception&)
1474 : {
1475 : OSL_FAIL("FmXFormView::implCreateXFormsControl: caught an exception while creating the control !");
1476 : }
1477 :
1478 :
1479 0 : return NULL;
1480 : }
1481 :
1482 :
1483 0 : bool FmXFormView::createControlLabelPair( OutputDevice& _rOutDev, sal_Int32 _nXOffsetMM, sal_Int32 _nYOffsetMM,
1484 : const Reference< XPropertySet >& _rxField, const Reference< XNumberFormats >& _rxNumberFormats,
1485 : sal_uInt16 _nControlObjectID, const OUString& _rFieldPostfix,
1486 : SdrUnoObj*& _rpLabel, SdrUnoObj*& _rpControl,
1487 : const Reference< XDataSource >& _rxDataSource, const OUString& _rDataSourceName,
1488 : const OUString& _rCommand, const sal_Int32 _nCommandType )
1489 : {
1490 0 : if ( !createControlLabelPair( _rOutDev, _nXOffsetMM, _nYOffsetMM,
1491 : _rxField, _rxNumberFormats, _nControlObjectID, _rFieldPostfix, FmFormInventor, OBJ_FM_FIXEDTEXT,
1492 0 : NULL, NULL, NULL, _rpLabel, _rpControl )
1493 : )
1494 0 : return false;
1495 :
1496 : // insert the control model(s) into the form component hierachy
1497 0 : if ( _rpLabel )
1498 0 : lcl_insertIntoFormComponentHierarchy_throw( *m_pView, *_rpLabel, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType );
1499 0 : lcl_insertIntoFormComponentHierarchy_throw( *m_pView, *_rpControl, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType );
1500 :
1501 : // some context-dependent initializations
1502 0 : FormControlFactory aControlFactory;
1503 0 : if ( _rpLabel )
1504 0 : aControlFactory.initializeControlModel( impl_getDocumentType(), *_rpLabel );
1505 0 : aControlFactory.initializeControlModel( impl_getDocumentType(), *_rpControl );
1506 :
1507 0 : return true;
1508 : }
1509 :
1510 :
1511 0 : bool FmXFormView::createControlLabelPair( OutputDevice& _rOutDev, sal_Int32 _nXOffsetMM, sal_Int32 _nYOffsetMM,
1512 : const Reference< XPropertySet >& _rxField,
1513 : const Reference< XNumberFormats >& _rxNumberFormats, sal_uInt16 _nControlObjectID,
1514 : const OUString& _rFieldPostfix, sal_uInt32 _nInventor, sal_uInt16 _nLabelObjectID,
1515 : SdrPage* _pLabelPage, SdrPage* _pControlPage, SdrModel* _pModel, SdrUnoObj*& _rpLabel, SdrUnoObj*& _rpControl)
1516 : {
1517 0 : sal_Int32 nDataType = 0;
1518 0 : OUString sFieldName;
1519 0 : Any aFieldName;
1520 0 : if ( _rxField.is() )
1521 : {
1522 0 : nDataType = ::comphelper::getINT32(_rxField->getPropertyValue(FM_PROP_FIELDTYPE));
1523 0 : aFieldName = Any(_rxField->getPropertyValue(FM_PROP_NAME));
1524 0 : aFieldName >>= sFieldName;
1525 : }
1526 :
1527 : // calculate the positions, respecting the settings of the target device
1528 0 : ::Size aTextSize( _rOutDev.GetTextWidth(sFieldName + _rFieldPostfix), _rOutDev.GetTextHeight() );
1529 :
1530 0 : MapMode eTargetMode( _rOutDev.GetMapMode() ),
1531 0 : eSourceMode( MAP_100TH_MM );
1532 :
1533 : // Textbreite ist mindestens 4cm
1534 : // Texthoehe immer halber cm
1535 0 : ::Size aDefTxtSize(4000, 500);
1536 0 : ::Size aDefSize(4000, 500);
1537 0 : ::Size aDefImageSize(4000, 4000);
1538 :
1539 0 : ::Size aRealSize = _rOutDev.LogicToLogic(aTextSize, eTargetMode, eSourceMode);
1540 0 : aRealSize.Width() = std::max(aRealSize.Width(), aDefTxtSize.Width());
1541 0 : aRealSize.Height()= aDefSize.Height();
1542 :
1543 : // adjust to scaling of the target device (#53523#)
1544 0 : aRealSize.Width() = long(Fraction(aRealSize.Width(), 1) * eTargetMode.GetScaleX());
1545 0 : aRealSize.Height() = long(Fraction(aRealSize.Height(), 1) * eTargetMode.GetScaleY());
1546 :
1547 : // for boolean fields, we do not create a label, but just a checkbox
1548 0 : bool bNeedLabel = ( _nControlObjectID != OBJ_FM_CHECKBOX );
1549 :
1550 : // the label
1551 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1552 0 : ::std::auto_ptr< SdrUnoObj > pLabel;
1553 : SAL_WNODEPRECATED_DECLARATIONS_POP
1554 0 : Reference< XPropertySet > xLabelModel;
1555 0 : if ( bNeedLabel )
1556 : {
1557 : pLabel.reset( dynamic_cast< SdrUnoObj* >(
1558 0 : SdrObjFactory::MakeNewObject( _nInventor, _nLabelObjectID, _pLabelPage, _pModel ) ) );
1559 : OSL_ENSURE( pLabel.get(), "FmXFormView::createControlLabelPair: could not create the label!" );
1560 0 : if ( !pLabel.get() )
1561 0 : return false;
1562 :
1563 0 : xLabelModel.set( pLabel->GetUnoControlModel(), UNO_QUERY );
1564 0 : if ( xLabelModel.is() )
1565 : {
1566 0 : OUString sLabel;
1567 0 : if ( _rxField.is() && _rxField->getPropertySetInfo()->hasPropertyByName(FM_PROP_LABEL) )
1568 0 : _rxField->getPropertyValue(FM_PROP_LABEL) >>= sLabel;
1569 0 : if ( sLabel.isEmpty() )
1570 0 : sLabel = sFieldName;
1571 :
1572 0 : xLabelModel->setPropertyValue( FM_PROP_LABEL, makeAny( sLabel + _rFieldPostfix ) );
1573 0 : OUString sObjectLabel(SVX_RESSTR(RID_STR_OBJECT_LABEL).replaceAll("#object#", sFieldName));
1574 0 : xLabelModel->setPropertyValue(FM_PROP_NAME, makeAny(sObjectLabel));
1575 : }
1576 :
1577 0 : pLabel->SetLogicRect( ::Rectangle(
1578 0 : _rOutDev.LogicToLogic( ::Point( _nXOffsetMM, _nYOffsetMM ), eSourceMode, eTargetMode ),
1579 : _rOutDev.LogicToLogic( aRealSize, eSourceMode, eTargetMode )
1580 0 : ) );
1581 : }
1582 :
1583 : // the control
1584 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1585 : ::std::auto_ptr< SdrUnoObj > pControl( dynamic_cast< SdrUnoObj* >(
1586 0 : SdrObjFactory::MakeNewObject( _nInventor, _nControlObjectID, _pControlPage, _pModel ) ) );
1587 : SAL_WNODEPRECATED_DECLARATIONS_POP
1588 : OSL_ENSURE( pControl.get(), "FmXFormView::createControlLabelPair: could not create the control!" );
1589 0 : if ( !pControl.get() )
1590 0 : return false;
1591 :
1592 0 : Reference< XPropertySet > xControlSet( pControl->GetUnoControlModel(), UNO_QUERY );
1593 0 : if ( !xControlSet.is() )
1594 0 : return false;
1595 :
1596 : // size of the control
1597 0 : ::Size aControlSize( aDefSize );
1598 0 : switch ( nDataType )
1599 : {
1600 : case DataType::BIT:
1601 : case DataType::BOOLEAN:
1602 0 : aControlSize = aDefSize;
1603 0 : break;
1604 : case DataType::LONGVARCHAR:
1605 : case DataType::CLOB:
1606 : case DataType::LONGVARBINARY:
1607 : case DataType::BLOB:
1608 0 : aControlSize = aDefImageSize;
1609 0 : break;
1610 : }
1611 :
1612 0 : if ( OBJ_FM_IMAGECONTROL == _nControlObjectID )
1613 0 : aControlSize = aDefImageSize;
1614 :
1615 0 : aControlSize.Width() = long(Fraction(aControlSize.Width(), 1) * eTargetMode.GetScaleX());
1616 0 : aControlSize.Height() = long(Fraction(aControlSize.Height(), 1) * eTargetMode.GetScaleY());
1617 :
1618 0 : pControl->SetLogicRect( ::Rectangle(
1619 0 : _rOutDev.LogicToLogic( ::Point( aRealSize.Width() + _nXOffsetMM, _nYOffsetMM ), eSourceMode, eTargetMode ),
1620 : _rOutDev.LogicToLogic( aControlSize, eSourceMode, eTargetMode )
1621 0 : ) );
1622 :
1623 : // some initializations
1624 0 : Reference< XPropertySetInfo > xControlPropInfo = xControlSet->getPropertySetInfo();
1625 :
1626 0 : if ( aFieldName.hasValue() )
1627 : {
1628 0 : xControlSet->setPropertyValue( FM_PROP_CONTROLSOURCE, aFieldName );
1629 0 : xControlSet->setPropertyValue( FM_PROP_NAME, aFieldName );
1630 0 : if ( !bNeedLabel )
1631 : {
1632 : // no dedicated label control => use the label property
1633 0 : if ( xControlPropInfo->hasPropertyByName( FM_PROP_LABEL ) )
1634 0 : xControlSet->setPropertyValue( FM_PROP_LABEL, makeAny( sFieldName + _rFieldPostfix ) );
1635 : else
1636 : OSL_FAIL( "FmXFormView::createControlLabelPair: can't set a label for the control!" );
1637 : }
1638 : }
1639 :
1640 0 : if ( (nDataType == DataType::LONGVARCHAR || nDataType == DataType::CLOB) && xControlPropInfo->hasPropertyByName( FM_PROP_MULTILINE ) )
1641 : {
1642 0 : xControlSet->setPropertyValue( FM_PROP_MULTILINE, makeAny( sal_Bool( sal_True ) ) );
1643 : }
1644 :
1645 : // announce the label to the control
1646 0 : if ( xControlPropInfo->hasPropertyByName( FM_PROP_CONTROLLABEL ) && xLabelModel.is() )
1647 : {
1648 : try
1649 : {
1650 0 : xControlSet->setPropertyValue( FM_PROP_CONTROLLABEL, makeAny( xLabelModel ) );
1651 : }
1652 0 : catch (const Exception&)
1653 : {
1654 : DBG_UNHANDLED_EXCEPTION();
1655 : }
1656 : }
1657 :
1658 0 : if ( _rxField.is() )
1659 : {
1660 0 : FormControlFactory aControlFactory;
1661 0 : aControlFactory.initializeFieldDependentProperties( _rxField, xControlSet, _rxNumberFormats );
1662 : }
1663 :
1664 0 : _rpLabel = pLabel.release();
1665 0 : _rpControl = pControl.release();
1666 0 : return true;
1667 : }
1668 :
1669 :
1670 0 : FmXFormView::ObjectRemoveListener::ObjectRemoveListener( FmXFormView* pParent )
1671 0 : :m_pParent( pParent )
1672 : {
1673 0 : }
1674 :
1675 :
1676 0 : void FmXFormView::ObjectRemoveListener::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
1677 : {
1678 0 : if (rHint.ISA(SdrHint) && (((SdrHint&)rHint).GetKind() == HINT_OBJREMOVED))
1679 0 : m_pParent->ObjectRemovedInAliveMode(((SdrHint&)rHint).GetObject());
1680 0 : }
1681 :
1682 :
1683 0 : void FmXFormView::ObjectRemovedInAliveMode( const SdrObject* pObject )
1684 : {
1685 : // wenn das entfernte Objekt in meiner MarkList, die ich mir beim Umschalten in den Alive-Mode gemerkt habe, steht,
1686 : // muss ich es jetzt da rausnehmen, da ich sonst beim Zurueckschalten versuche, die Markierung wieder zu setzen
1687 : // (interesanterweise geht das nur bei gruppierten Objekten schief (beim Zugriff auf deren ObjList GPF), nicht bei einzelnen)
1688 :
1689 0 : sal_uIntPtr nCount = m_aMark.GetMarkCount();
1690 0 : for (sal_uIntPtr i = 0; i < nCount; ++i)
1691 : {
1692 0 : SdrMark* pMark = m_aMark.GetMark(i);
1693 0 : SdrObject* pCurrent = pMark->GetMarkedSdrObj();
1694 0 : if (pObject == pCurrent)
1695 : {
1696 0 : m_aMark.DeleteMark(i);
1697 0 : return;
1698 : }
1699 : // ich brauche nicht in GroupObjects absteigen : wenn dort unten ein Objekt geloescht wird, dann bleibt der
1700 : // Zeiger auf das GroupObject, den ich habe, trotzdem weiter gueltig bleibt ...
1701 : }
1702 : }
1703 :
1704 :
1705 0 : void FmXFormView::stopMarkListWatching()
1706 : {
1707 0 : if ( m_pWatchStoredList )
1708 : {
1709 0 : m_pWatchStoredList->EndListeningAll();
1710 0 : delete m_pWatchStoredList;
1711 0 : m_pWatchStoredList = NULL;
1712 : }
1713 0 : }
1714 :
1715 :
1716 0 : void FmXFormView::startMarkListWatching()
1717 : {
1718 0 : if ( !m_pWatchStoredList )
1719 : {
1720 0 : FmFormModel* pModel = GetFormShell() ? GetFormShell()->GetFormModel() : NULL;
1721 : DBG_ASSERT( pModel != NULL, "FmXFormView::startMarkListWatching: shell has no model!" );
1722 0 : if (pModel)
1723 : {
1724 0 : m_pWatchStoredList = new ObjectRemoveListener( this );
1725 0 : m_pWatchStoredList->StartListening( *static_cast< SfxBroadcaster* >( pModel ) );
1726 : }
1727 : }
1728 : else
1729 : {
1730 : OSL_FAIL( "FmXFormView::startMarkListWatching: already listening!" );
1731 : }
1732 0 : }
1733 :
1734 :
1735 0 : void FmXFormView::saveMarkList( sal_Bool _bSmartUnmark )
1736 : {
1737 0 : if ( m_pView )
1738 : {
1739 0 : m_aMark = m_pView->GetMarkedObjectList();
1740 0 : if ( _bSmartUnmark )
1741 : {
1742 0 : sal_uIntPtr nCount = m_aMark.GetMarkCount( );
1743 0 : for ( sal_uIntPtr i = 0; i < nCount; ++i )
1744 : {
1745 0 : SdrMark* pMark = m_aMark.GetMark(i);
1746 0 : SdrObject* pObj = pMark->GetMarkedSdrObj();
1747 :
1748 0 : if ( m_pView->IsObjMarked( pObj ) )
1749 : {
1750 0 : if ( pObj->IsGroupObject() )
1751 : {
1752 0 : SdrObjListIter aIter( *pObj->GetSubList() );
1753 0 : sal_Bool bMixed = sal_False;
1754 0 : while ( aIter.IsMore() && !bMixed )
1755 0 : bMixed = ( aIter.Next()->GetObjInventor() != FmFormInventor );
1756 :
1757 0 : if ( !bMixed )
1758 : {
1759 : // all objects in the group are form objects
1760 0 : m_pView->MarkObj( pMark->GetMarkedSdrObj(), pMark->GetPageView(), true /* unmark! */ );
1761 0 : }
1762 : }
1763 : else
1764 : {
1765 0 : if ( pObj->GetObjInventor() == FmFormInventor )
1766 : { // this is a form layer object
1767 0 : m_pView->MarkObj( pMark->GetMarkedSdrObj(), pMark->GetPageView(), true /* unmark! */ );
1768 : }
1769 : }
1770 : }
1771 : }
1772 : }
1773 : }
1774 : else
1775 : {
1776 : OSL_FAIL( "FmXFormView::saveMarkList: invalid view!" );
1777 0 : m_aMark = SdrMarkList();
1778 : }
1779 0 : }
1780 :
1781 :
1782 0 : static sal_Bool lcl_hasObject( SdrObjListIter& rIter, SdrObject* pObj )
1783 : {
1784 0 : sal_Bool bFound = sal_False;
1785 0 : while (rIter.IsMore() && !bFound)
1786 0 : bFound = pObj == rIter.Next();
1787 :
1788 0 : rIter.Reset();
1789 0 : return bFound;
1790 : }
1791 :
1792 :
1793 0 : void FmXFormView::restoreMarkList( SdrMarkList& _rRestoredMarkList )
1794 : {
1795 0 : if ( !m_pView )
1796 0 : return;
1797 :
1798 0 : _rRestoredMarkList.Clear();
1799 :
1800 0 : const SdrMarkList& rCurrentList = m_pView->GetMarkedObjectList();
1801 0 : FmFormPage* pPage = GetFormShell() ? GetFormShell()->GetCurPage() : NULL;
1802 0 : if (pPage)
1803 : {
1804 0 : if (rCurrentList.GetMarkCount())
1805 : { // there is a current mark ... hmm. Is it a subset of the mark we remembered in saveMarkList?
1806 0 : sal_Bool bMisMatch = sal_False;
1807 :
1808 : // loop through all current marks
1809 0 : sal_uIntPtr nCurrentCount = rCurrentList.GetMarkCount();
1810 0 : for ( sal_uIntPtr i=0; i<nCurrentCount&& !bMisMatch; ++i )
1811 : {
1812 0 : const SdrObject* pCurrentMarked = rCurrentList.GetMark( i )->GetMarkedSdrObj();
1813 :
1814 : // loop through all saved marks, check for equality
1815 0 : sal_Bool bFound = sal_False;
1816 0 : sal_uIntPtr nSavedCount = m_aMark.GetMarkCount();
1817 0 : for ( sal_uIntPtr j=0; j<nSavedCount && !bFound; ++j )
1818 : {
1819 0 : if ( m_aMark.GetMark( j )->GetMarkedSdrObj() == pCurrentMarked )
1820 0 : bFound = sal_True;
1821 : }
1822 :
1823 : // did not find a current mark in the saved marks
1824 0 : if ( !bFound )
1825 0 : bMisMatch = sal_True;
1826 : }
1827 :
1828 0 : if ( bMisMatch )
1829 : {
1830 0 : m_aMark.Clear();
1831 0 : _rRestoredMarkList = rCurrentList;
1832 0 : return;
1833 : }
1834 : }
1835 : // wichtig ist das auf die Objecte der markliste nicht zugegriffen wird
1836 : // da diese bereits zerstoert sein koennen
1837 0 : SdrPageView* pCurPageView = m_pView->GetSdrPageView();
1838 0 : SdrObjListIter aPageIter( *pPage );
1839 0 : sal_Bool bFound = sal_True;
1840 :
1841 : // gibt es noch alle Objecte
1842 0 : sal_uIntPtr nCount = m_aMark.GetMarkCount();
1843 0 : for (sal_uIntPtr i = 0; i < nCount && bFound; i++)
1844 : {
1845 0 : SdrMark* pMark = m_aMark.GetMark(i);
1846 0 : SdrObject* pObj = pMark->GetMarkedSdrObj();
1847 0 : if (pObj->IsGroupObject())
1848 : {
1849 0 : SdrObjListIter aIter(*pObj->GetSubList());
1850 0 : while (aIter.IsMore() && bFound)
1851 0 : bFound = lcl_hasObject(aPageIter, aIter.Next());
1852 : }
1853 : else
1854 0 : bFound = lcl_hasObject(aPageIter, pObj);
1855 :
1856 0 : bFound = bFound && pCurPageView == pMark->GetPageView();
1857 : }
1858 :
1859 0 : if (bFound)
1860 : {
1861 : // Das LastObject auswerten
1862 0 : if (nCount) // Objecte jetzt Markieren
1863 : {
1864 0 : for (sal_uIntPtr i = 0; i < nCount; i++)
1865 : {
1866 0 : SdrMark* pMark = m_aMark.GetMark(i);
1867 0 : SdrObject* pObj = pMark->GetMarkedSdrObj();
1868 0 : if ( pObj->GetObjInventor() == FmFormInventor )
1869 0 : if ( !m_pView->IsObjMarked( pObj ) )
1870 0 : m_pView->MarkObj( pObj, pMark->GetPageView() );
1871 : }
1872 :
1873 0 : _rRestoredMarkList = m_aMark;
1874 : }
1875 : }
1876 0 : m_aMark.Clear();
1877 : }
1878 : }
1879 :
1880 0 : void SAL_CALL FmXFormView::focusGained( const FocusEvent& /*e*/ ) throw (RuntimeException, std::exception)
1881 : {
1882 0 : if ( m_xWindow.is() && m_pView )
1883 : {
1884 0 : m_pView->SetMoveOutside( true, FmFormView::ImplAccess() );
1885 : }
1886 0 : }
1887 :
1888 0 : void SAL_CALL FmXFormView::focusLost( const FocusEvent& /*e*/ ) throw (RuntimeException, std::exception)
1889 : {
1890 : // when switch the focus outside the office the mark didn't change
1891 : // so we can not remove us as focus listener
1892 0 : if ( m_xWindow.is() && m_pView )
1893 : {
1894 0 : m_pView->SetMoveOutside( false, FmFormView::ImplAccess() );
1895 : }
1896 0 : }
1897 :
1898 0 : void FmXFormView::removeGridWindowListening()
1899 : {
1900 0 : if ( m_xWindow.is() )
1901 : {
1902 0 : m_xWindow->removeFocusListener(this);
1903 0 : if ( m_pView )
1904 : {
1905 0 : m_pView->SetMoveOutside( false, FmFormView::ImplAccess() );
1906 : }
1907 0 : m_xWindow = NULL;
1908 : }
1909 0 : }
1910 :
1911 :
1912 0 : DocumentType FmXFormView::impl_getDocumentType() const
1913 : {
1914 0 : if ( GetFormShell() && GetFormShell()->GetImpl() )
1915 0 : return GetFormShell()->GetImpl()->getDocumentType();
1916 0 : return eUnknownDocumentType;
1917 : }
1918 :
1919 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|