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