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