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 : #include <svx/dialmgr.hxx>
21 : #include <svx/fmshell.hxx>
22 : #include <svx/fmmodel.hxx>
23 : #include <svx/fmpage.hxx>
24 : #include <svx/fmglob.hxx>
25 : #include "svx/svditer.hxx"
26 : #include <svx/svdogrp.hxx>
27 : #include <svx/svdpagv.hxx>
28 :
29 : #include "fmprop.hrc"
30 :
31 : #include "fmundo.hxx"
32 : #include "fmhelp.hrc"
33 : #include "fmexpl.hrc"
34 : #include "fmexpl.hxx"
35 : #include "svx/fmresids.hrc"
36 : #include "fmshimp.hxx"
37 : #include "fmobj.hxx"
38 : #include <sfx2/objsh.hxx>
39 : #include <tools/diagnose_ex.h>
40 : #include <rtl/logfile.hxx>
41 : #include <com/sun/star/container/XContainer.hpp>
42 :
43 : //............................................................................
44 : namespace svxform
45 : {
46 : //............................................................................
47 :
48 : using namespace ::com::sun::star::uno;
49 : using namespace ::com::sun::star::lang;
50 : using namespace ::com::sun::star::beans;
51 : using namespace ::com::sun::star::form;
52 : using namespace ::com::sun::star::awt;
53 : using namespace ::com::sun::star::container;
54 : using namespace ::com::sun::star::script;
55 : using namespace ::com::sun::star::sdb;
56 :
57 : //========================================================================
58 : // class OFormComponentObserver
59 : //========================================================================
60 : //------------------------------------------------------------------------
61 0 : OFormComponentObserver::OFormComponentObserver(NavigatorTreeModel* _pModel)
62 : :m_pNavModel(_pModel)
63 : ,m_nLocks(0)
64 0 : ,m_bCanUndo(sal_True)
65 : {
66 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::OFormComponentObserver" );
67 0 : }
68 :
69 : // XPropertyChangeListener
70 : //------------------------------------------------------------------------
71 0 : void SAL_CALL OFormComponentObserver::disposing(const EventObject& Source) throw( RuntimeException )
72 : {
73 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::disposing" );
74 0 : Remove( Source.Source );
75 0 : }
76 :
77 : //------------------------------------------------------------------------
78 0 : void SAL_CALL OFormComponentObserver::propertyChange(const PropertyChangeEvent& evt) throw(RuntimeException)
79 : {
80 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::propertyChange" );
81 0 : if( !m_pNavModel ) return;
82 0 : if( evt.PropertyName != FM_PROP_NAME ) return;
83 :
84 0 : Reference< XFormComponent > xFormComponent(evt.Source, UNO_QUERY);
85 0 : Reference< XForm > xForm(evt.Source, UNO_QUERY);
86 :
87 0 : FmEntryData* pEntryData( NULL );
88 0 : if( xForm.is() )
89 0 : pEntryData = m_pNavModel->FindData( xForm, m_pNavModel->GetRootList() );
90 0 : else if( xFormComponent.is() )
91 0 : pEntryData = m_pNavModel->FindData( xFormComponent, m_pNavModel->GetRootList() );
92 :
93 0 : if( pEntryData )
94 : {
95 0 : OUString aNewName = ::comphelper::getString(evt.NewValue);
96 0 : pEntryData->SetText( aNewName );
97 0 : FmNavNameChangedHint aNameChangedHint( pEntryData, aNewName );
98 0 : m_pNavModel->Broadcast( aNameChangedHint );
99 0 : }
100 : }
101 :
102 : // XContainerListener
103 : //------------------------------------------------------------------------------
104 0 : void SAL_CALL OFormComponentObserver::elementInserted(const ContainerEvent& evt) throw(RuntimeException)
105 : {
106 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementInserted" );
107 0 : if (IsLocked() || !m_pNavModel)
108 0 : return;
109 :
110 : // keine Undoaction einfuegen
111 0 : m_bCanUndo = sal_False;
112 :
113 0 : Reference< XInterface > xTemp;
114 0 : evt.Element >>= xTemp;
115 0 : Insert(xTemp, ::comphelper::getINT32(evt.Accessor));
116 :
117 0 : m_bCanUndo = sal_True;
118 : }
119 :
120 : //------------------------------------------------------------------------------
121 0 : void OFormComponentObserver::Insert(const Reference< XInterface > & xIface, sal_Int32 nIndex)
122 : {
123 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::Insert" );
124 0 : Reference< XForm > xForm(xIface, UNO_QUERY);
125 0 : if (xForm.is())
126 : {
127 0 : m_pNavModel->InsertForm(xForm, sal_uInt32(nIndex));
128 0 : Reference< XIndexContainer > xContainer(xForm, UNO_QUERY);
129 0 : Reference< XInterface > xTemp;
130 0 : for (sal_Int32 i = 0; i < xContainer->getCount(); i++)
131 : {
132 0 : xContainer->getByIndex(i) >>= xTemp;
133 0 : Insert(xTemp, i);
134 0 : }
135 : }
136 : else
137 : {
138 0 : Reference< XFormComponent > xFormComp(xIface, UNO_QUERY);
139 0 : if (xFormComp.is())
140 0 : m_pNavModel->InsertFormComponent(xFormComp, sal_uInt32(nIndex));
141 0 : }
142 0 : }
143 :
144 : //------------------------------------------------------------------------------
145 0 : void SAL_CALL OFormComponentObserver::elementReplaced(const ContainerEvent& evt) throw(RuntimeException)
146 : {
147 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementReplaced" );
148 0 : if (IsLocked() || !m_pNavModel)
149 0 : return;
150 :
151 0 : m_bCanUndo = sal_False;
152 :
153 : // EntryData loeschen
154 0 : Reference< XFormComponent > xReplaced;
155 0 : evt.ReplacedElement >>= xReplaced;
156 0 : FmEntryData* pEntryData = m_pNavModel->FindData(xReplaced, m_pNavModel->GetRootList(), sal_True);
157 0 : if (pEntryData)
158 : {
159 0 : if (pEntryData->ISA(FmControlData))
160 : {
161 0 : Reference< XFormComponent > xComp;
162 0 : evt.Element >>= xComp;
163 : DBG_ASSERT(xComp.is(), "OFormComponentObserver::elementReplaced : invalid argument !");
164 : // an einer FmControlData sollte eine XFormComponent haengen
165 0 : m_pNavModel->ReplaceFormComponent(xReplaced, xComp);
166 : }
167 0 : else if (pEntryData->ISA(FmFormData))
168 : {
169 : OSL_FAIL("replacing forms not implemented yet !");
170 : }
171 : }
172 :
173 0 : m_bCanUndo = sal_True;
174 : }
175 :
176 : //------------------------------------------------------------------------------
177 0 : void OFormComponentObserver::Remove( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxElement )
178 : {
179 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::Remove" );
180 0 : if (IsLocked() || !m_pNavModel)
181 0 : return;
182 :
183 0 : m_bCanUndo = sal_False;
184 :
185 : //////////////////////////////////////////////////////////
186 : // EntryData loeschen
187 0 : FmEntryData* pEntryData = m_pNavModel->FindData( _rxElement, m_pNavModel->GetRootList(), sal_True );
188 0 : if (pEntryData)
189 0 : m_pNavModel->Remove(pEntryData);
190 :
191 0 : m_bCanUndo = sal_True;
192 : }
193 :
194 : //------------------------------------------------------------------------------
195 0 : void SAL_CALL OFormComponentObserver::elementRemoved(const ContainerEvent& evt) throw(RuntimeException)
196 : {
197 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementRemoved" );
198 0 : Reference< XInterface > xElement;
199 0 : evt.Element >>= xElement;
200 0 : Remove( xElement );
201 0 : }
202 :
203 : //========================================================================
204 : // class NavigatorTreeModel
205 : //========================================================================
206 :
207 : //------------------------------------------------------------------------
208 0 : NavigatorTreeModel::NavigatorTreeModel( const ImageList& _rNormalImages )
209 : :m_pFormShell(NULL)
210 : ,m_pFormPage(NULL)
211 : ,m_pFormModel(NULL)
212 0 : ,m_aNormalImages( _rNormalImages )
213 : {
214 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::NavigatorTreeModel" );
215 0 : m_pPropChangeList = new OFormComponentObserver(this);
216 0 : m_pPropChangeList->acquire();
217 0 : m_pRootList = new FmEntryDataList();
218 0 : }
219 :
220 : //------------------------------------------------------------------------
221 0 : NavigatorTreeModel::~NavigatorTreeModel()
222 : {
223 : //////////////////////////////////////////////////////////////////////
224 : // Als Listener abmelden
225 0 : if( m_pFormShell)
226 : {
227 0 : FmFormModel* pFormModel = m_pFormShell->GetFormModel();
228 0 : if( pFormModel && IsListening(*pFormModel))
229 0 : EndListening( *pFormModel );
230 :
231 0 : if (IsListening(*m_pFormShell))
232 0 : EndListening(*m_pFormShell);
233 : }
234 :
235 0 : Clear();
236 0 : delete m_pRootList;
237 0 : m_pPropChangeList->ReleaseModel();
238 0 : m_pPropChangeList->release();
239 0 : }
240 :
241 :
242 : //------------------------------------------------------------------------
243 0 : void NavigatorTreeModel::SetModified( sal_Bool bMod )
244 : {
245 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::SetModified" );
246 0 : if( !m_pFormShell ) return;
247 0 : SfxObjectShell* pObjShell = m_pFormShell->GetFormModel()->GetObjectShell();
248 0 : if( !pObjShell ) return;
249 0 : pObjShell->SetModified( bMod );
250 : }
251 :
252 : //------------------------------------------------------------------------
253 0 : void NavigatorTreeModel::Clear()
254 : {
255 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Clear" );
256 0 : Reference< css::form::XForms > xForms( GetForms());
257 0 : if(xForms.is())
258 0 : xForms->removeContainerListener((XContainerListener*)m_pPropChangeList);
259 :
260 : //////////////////////////////////////////////////////////////////////
261 : // RootList loeschen
262 0 : GetRootList()->clear();
263 :
264 : //////////////////////////////////////////////////////////////////////
265 : // UI benachrichtigen
266 0 : FmNavClearedHint aClearedHint;
267 0 : Broadcast( aClearedHint );
268 0 : }
269 :
270 : //------------------------------------------------------------------------
271 0 : Reference< css::form::XForms > NavigatorTreeModel::GetForms() const
272 : {
273 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetForms" );
274 0 : if( !m_pFormShell || !m_pFormShell->GetCurPage())
275 0 : return NULL;
276 : else
277 0 : return m_pFormShell->GetCurPage()->GetForms();
278 : }
279 :
280 : //------------------------------------------------------------------------
281 0 : void NavigatorTreeModel::Insert(FmEntryData* pEntry, sal_uLong nRelPos, sal_Bool bAlterModel)
282 : {
283 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Insert" );
284 0 : if (IsListening(*m_pFormModel))
285 0 : EndListening(*m_pFormModel);
286 :
287 0 : m_pPropChangeList->Lock();
288 0 : FmFormData* pFolder = (FmFormData*) pEntry->GetParent();
289 0 : Reference< XChild > xElement( pEntry->GetChildIFace() );
290 0 : if (bAlterModel)
291 : {
292 0 : XubString aStr;
293 0 : if (pEntry->ISA(FmFormData))
294 0 : aStr = SVX_RESSTR(RID_STR_FORM);
295 : else
296 0 : aStr = SVX_RESSTR(RID_STR_CONTROL);
297 :
298 0 : Reference< XIndexContainer > xContainer;
299 0 : if (pFolder)
300 0 : xContainer = Reference< XIndexContainer > (pFolder->GetFormIface(), UNO_QUERY);
301 : else
302 0 : xContainer = Reference< XIndexContainer > (GetForms(), UNO_QUERY);
303 :
304 0 : bool bUndo = m_pFormModel->IsUndoEnabled();
305 :
306 0 : if( bUndo )
307 : {
308 0 : XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT));
309 0 : aUndoStr.SearchAndReplace(OUString('#'), aStr);
310 0 : m_pFormModel->BegUndo(aUndoStr);
311 : }
312 :
313 0 : if (nRelPos >= (sal_uInt32)xContainer->getCount())
314 0 : nRelPos = (sal_uInt32)xContainer->getCount();
315 :
316 : // UndoAction
317 0 : if ( bUndo && m_pPropChangeList->CanUndo())
318 : {
319 : m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel,
320 : FmUndoContainerAction::Inserted,
321 : xContainer,
322 : xElement,
323 0 : nRelPos));
324 : }
325 :
326 : // das Element muss den Typ haben, den der Container erwartet
327 0 : if (xContainer->getElementType() ==
328 0 : ::getCppuType((const Reference< XForm>*)0))
329 :
330 : {
331 0 : Reference< XForm > xElementAsForm(xElement, UNO_QUERY);
332 0 : xContainer->insertByIndex(nRelPos, makeAny(xElementAsForm));
333 : }
334 0 : else if (xContainer->getElementType() ==
335 0 : ::getCppuType((const Reference< XFormComponent>*)0))
336 :
337 : {
338 0 : Reference< XFormComponent > xElementAsComponent(xElement, UNO_QUERY);
339 0 : xContainer->insertByIndex(nRelPos, makeAny(xElementAsComponent));
340 : }
341 : else
342 : {
343 : OSL_FAIL("NavigatorTreeModel::Insert : the parent container needs an elementtype I don't know !");
344 : }
345 :
346 0 : if( bUndo )
347 0 : m_pFormModel->EndUndo();
348 : }
349 :
350 : //////////////////////////////////////////////////////////////////////
351 : // Als PropertyChangeListener anmelden
352 0 : Reference< XPropertySet > xSet(xElement, UNO_QUERY);
353 0 : if( xSet.is() )
354 0 : xSet->addPropertyChangeListener( FM_PROP_NAME, m_pPropChangeList );
355 :
356 : //////////////////////////////////////////////////////////////////////
357 : // Daten aus Model entfernen
358 0 : if (pEntry->ISA(FmFormData))
359 : {
360 0 : Reference< XContainer > xContainer(xElement, UNO_QUERY);
361 0 : if (xContainer.is())
362 0 : xContainer->addContainerListener((XContainerListener*)m_pPropChangeList);
363 : }
364 :
365 0 : if (pFolder)
366 0 : pFolder->GetChildList()->insert( pEntry, nRelPos );
367 : else
368 0 : GetRootList()->insert( pEntry, nRelPos );
369 :
370 : //////////////////////////////////////////////////////////////////////
371 : // UI benachrichtigen
372 0 : FmNavInsertedHint aInsertedHint( pEntry, nRelPos );
373 0 : Broadcast( aInsertedHint );
374 :
375 0 : m_pPropChangeList->UnLock();
376 0 : if (IsListening(*m_pFormModel))
377 0 : StartListening(*m_pFormModel);
378 0 : }
379 :
380 : //------------------------------------------------------------------------
381 0 : void NavigatorTreeModel::Remove(FmEntryData* pEntry, sal_Bool bAlterModel)
382 : {
383 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Remove" );
384 : //////////////////////////////////////////////////////////////////////
385 : // Form und Parent holen
386 0 : if (!pEntry || !m_pFormModel)
387 0 : return;
388 :
389 0 : if (IsListening(*m_pFormModel))
390 0 : EndListening(*m_pFormModel);
391 :
392 0 : const bool bUndo = m_pFormModel->IsUndoEnabled();
393 :
394 0 : m_pPropChangeList->Lock();
395 0 : FmFormData* pFolder = (FmFormData*) pEntry->GetParent();
396 0 : Reference< XChild > xElement ( pEntry->GetChildIFace() );
397 0 : if (bAlterModel)
398 : {
399 0 : XubString aStr;
400 0 : if (pEntry->ISA(FmFormData))
401 0 : aStr = SVX_RESSTR(RID_STR_FORM);
402 : else
403 0 : aStr = SVX_RESSTR(RID_STR_CONTROL);
404 :
405 0 : if( bUndo )
406 : {
407 0 : XubString aUndoStr(SVX_RESSTR(RID_STR_UNDO_CONTAINER_REMOVE));
408 0 : aUndoStr.SearchAndReplace(OUString('#'), aStr);
409 0 : m_pFormModel->BegUndo(aUndoStr);
410 0 : }
411 : }
412 :
413 : // jetzt die eigentliche Entfernung der Daten aus dem Model
414 0 : if (pEntry->ISA(FmFormData))
415 0 : RemoveForm((FmFormData*)pEntry);
416 : else
417 0 : RemoveFormComponent((FmControlData*)pEntry);
418 :
419 :
420 0 : if (bAlterModel)
421 : {
422 0 : Reference< XIndexContainer > xContainer(xElement->getParent(), UNO_QUERY);
423 : // aus dem Container entfernen
424 0 : sal_Int32 nContainerIndex = getElementPos(xContainer.get(), xElement);
425 : // UndoAction
426 0 : if (nContainerIndex >= 0)
427 : {
428 0 : if ( bUndo && m_pPropChangeList->CanUndo())
429 : {
430 : m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel,
431 : FmUndoContainerAction::Removed,
432 : xContainer,
433 0 : xElement, nContainerIndex ));
434 : }
435 0 : else if( !m_pPropChangeList->CanUndo() )
436 : {
437 0 : FmUndoContainerAction::DisposeElement( xElement );
438 : }
439 :
440 0 : xContainer->removeByIndex(nContainerIndex );
441 : }
442 :
443 0 : if( bUndo )
444 0 : m_pFormModel->EndUndo();
445 : }
446 :
447 : // beim Vater austragen
448 0 : if (pFolder)
449 0 : pFolder->GetChildList()->remove( pEntry );
450 : else
451 : {
452 0 : GetRootList()->remove( pEntry );
453 : //////////////////////////////////////////////////////////////////////
454 : // Wenn keine Form mehr in der Root, an der Shell CurForm zuruecksetzen
455 0 : if ( !GetRootList()->size() )
456 0 : m_pFormShell->GetImpl()->forgetCurrentForm();
457 : }
458 :
459 : //////////////////////////////////////////////////////////////////////
460 : // UI benachrichtigen
461 0 : FmNavRemovedHint aRemovedHint( pEntry );
462 0 : Broadcast( aRemovedHint );
463 :
464 : // Eintrag loeschen
465 0 : delete pEntry;
466 :
467 0 : m_pPropChangeList->UnLock();
468 0 : StartListening(*m_pFormModel);
469 : }
470 :
471 : //------------------------------------------------------------------------
472 0 : void NavigatorTreeModel::RemoveForm(FmFormData* pFormData)
473 : {
474 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveForm" );
475 : //////////////////////////////////////////////////////////////////////
476 : // Form und Parent holen
477 0 : if (!pFormData || !m_pFormModel)
478 0 : return;
479 :
480 0 : FmEntryDataList* pChildList = pFormData->GetChildList();
481 0 : for ( size_t i = pChildList->size(); i > 0; )
482 : {
483 0 : FmEntryData* pEntryData = pChildList->at( --i );
484 :
485 : //////////////////////////////////////////////////////////////////////
486 : // Child ist Form -> rekursiver Aufruf
487 0 : if( pEntryData->ISA(FmFormData) )
488 0 : RemoveForm( (FmFormData*)pEntryData);
489 0 : else if( pEntryData->ISA(FmControlData) )
490 0 : RemoveFormComponent((FmControlData*) pEntryData);
491 : }
492 :
493 : //////////////////////////////////////////////////////////////////////
494 : // Als PropertyChangeListener abmelden
495 0 : Reference< XPropertySet > xSet( pFormData->GetPropertySet() );
496 0 : if ( xSet.is() )
497 0 : xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList );
498 :
499 0 : Reference< XContainer > xContainer( pFormData->GetContainer() );
500 0 : if (xContainer.is())
501 0 : xContainer->removeContainerListener((XContainerListener*)m_pPropChangeList);
502 : }
503 :
504 : //------------------------------------------------------------------------
505 0 : void NavigatorTreeModel::RemoveFormComponent(FmControlData* pControlData)
506 : {
507 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveFormComponent" );
508 : //////////////////////////////////////////////////////////////////////
509 : // Control und Parent holen
510 0 : if (!pControlData)
511 0 : return;
512 :
513 : //////////////////////////////////////////////////////////////////////
514 : // Als PropertyChangeListener abmelden
515 0 : Reference< XPropertySet > xSet( pControlData->GetPropertySet() );
516 0 : if (xSet.is())
517 0 : xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList);
518 : }
519 :
520 : //------------------------------------------------------------------------
521 0 : void NavigatorTreeModel::ClearBranch( FmFormData* pParentData )
522 : {
523 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::ClearBranch" );
524 : //////////////////////////////////////////////////////////////////////
525 : // Alle Eintraege dieses Zweiges loeschen
526 0 : FmEntryDataList* pChildList = pParentData->GetChildList();
527 :
528 0 : for( size_t i = pChildList->size(); i > 0; )
529 : {
530 0 : FmEntryData* pChildData = pChildList->at( --i );
531 0 : if( pChildData->ISA(FmFormData) )
532 0 : ClearBranch( (FmFormData*)pChildData );
533 :
534 0 : pChildList->remove( pChildData );
535 : }
536 0 : }
537 :
538 : //------------------------------------------------------------------------
539 0 : void NavigatorTreeModel::FillBranch( FmFormData* pFormData )
540 : {
541 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FillBranch" );
542 : //////////////////////////////////////////////////////////////
543 : // Forms aus der Root einfuegen
544 0 : if( pFormData == NULL )
545 : {
546 0 : Reference< XIndexContainer > xForms(GetForms(), UNO_QUERY);
547 0 : if (!xForms.is())
548 0 : return;
549 :
550 0 : Reference< XForm > xSubForm;
551 : FmFormData* pSubFormData;
552 0 : for (sal_Int32 i=0; i<xForms->getCount(); ++i)
553 : {
554 : DBG_ASSERT( xForms->getByIndex(i).getValueType() == ::getCppuType((const Reference< XForm>*)NULL),
555 : "NavigatorTreeModel::FillBranch : the root container should supply only elements of type XForm");
556 :
557 0 : xForms->getByIndex(i) >>= xSubForm;
558 0 : pSubFormData = new FmFormData( xSubForm, m_aNormalImages, pFormData );
559 0 : Insert( pSubFormData, LIST_APPEND );
560 :
561 : //////////////////////////////////////////////////////////////
562 : // Neuer Branch, wenn SubForm wiederum Subforms enthaelt
563 0 : FillBranch( pSubFormData );
564 0 : }
565 : }
566 :
567 : //////////////////////////////////////////////////////////////
568 : // Componenten einfuegen
569 : else
570 : {
571 0 : Reference< XIndexContainer > xComponents( GetFormComponents(pFormData));
572 0 : if( !xComponents.is() ) return;
573 :
574 0 : Reference< XInterface > xInterface;
575 0 : Reference< XPropertySet > xSet;
576 : FmControlData* pNewControlData;
577 : FmFormData* pSubFormData;
578 :
579 0 : Reference< XFormComponent > xCurrentComponent;
580 0 : for (sal_Int32 j=0; j<xComponents->getCount(); ++j)
581 : {
582 0 : xComponents->getByIndex(j) >>= xCurrentComponent;
583 0 : Reference< XForm > xSubForm(xCurrentComponent, UNO_QUERY);
584 :
585 0 : if (xSubForm.is())
586 : { // die aktuelle Component ist eine Form
587 0 : pSubFormData = new FmFormData(xSubForm, m_aNormalImages, pFormData);
588 0 : Insert(pSubFormData, LIST_APPEND);
589 :
590 : //////////////////////////////////////////////////////////////
591 : // Neuer Branch, wenn SubForm wiederum Subforms enthaelt
592 0 : FillBranch(pSubFormData);
593 : }
594 : else
595 : {
596 0 : pNewControlData = new FmControlData(xCurrentComponent, m_aNormalImages, pFormData);
597 0 : Insert(pNewControlData, LIST_APPEND);
598 : }
599 0 : }
600 : }
601 : }
602 :
603 : //------------------------------------------------------------------------
604 0 : void NavigatorTreeModel::InsertForm(const Reference< XForm > & xForm, sal_uInt32 nRelPos)
605 : {
606 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertForm" );
607 0 : FmFormData* pFormData = (FmFormData*)FindData( xForm, GetRootList() );
608 0 : if (pFormData)
609 0 : return;
610 :
611 : //////////////////////////////////////////////////////////
612 : // ParentData setzen
613 0 : Reference< XInterface > xIFace( xForm->getParent());
614 0 : Reference< XForm > xParentForm(xIFace, UNO_QUERY);
615 0 : FmFormData* pParentData = NULL;
616 0 : if (xParentForm.is())
617 0 : pParentData = (FmFormData*)FindData( xParentForm, GetRootList() );
618 :
619 0 : pFormData = new FmFormData( xForm, m_aNormalImages, pParentData );
620 0 : Insert( pFormData, nRelPos );
621 : }
622 :
623 : //------------------------------------------------------------------------
624 0 : void NavigatorTreeModel::InsertFormComponent(const Reference< XFormComponent > & xComp, sal_uInt32 nRelPos)
625 : {
626 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertFormComponent" );
627 : //////////////////////////////////////////////////////////
628 : // ParentData setzen
629 0 : Reference< XInterface > xIFace( xComp->getParent());
630 0 : Reference< XForm > xForm(xIFace, UNO_QUERY);
631 0 : if (!xForm.is())
632 0 : return;
633 :
634 0 : FmFormData* pParentData = (FmFormData*)FindData( xForm, GetRootList() );
635 0 : if( !pParentData )
636 : {
637 0 : pParentData = new FmFormData( xForm, m_aNormalImages, NULL );
638 0 : Insert( pParentData, LIST_APPEND );
639 : }
640 :
641 0 : if (!FindData(xComp, pParentData->GetChildList(),sal_False))
642 : {
643 : //////////////////////////////////////////////////////////
644 : // Neue EntryData setzen
645 0 : FmEntryData* pNewEntryData = new FmControlData( xComp, m_aNormalImages, pParentData );
646 :
647 : //////////////////////////////////////////////////////////
648 : // Neue EntryData einfuegen
649 0 : Insert( pNewEntryData, nRelPos );
650 0 : }
651 : }
652 :
653 : //------------------------------------------------------------------------
654 0 : void NavigatorTreeModel::ReplaceFormComponent(
655 : const Reference< XFormComponent > & xOld,
656 : const Reference< XFormComponent > & xNew
657 : )
658 : {
659 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::ReplaceFormComponent" );
660 0 : FmEntryData* pData = FindData(xOld, GetRootList(), sal_True);
661 : DBG_ASSERT(pData && pData->ISA(FmControlData), "NavigatorTreeModel::ReplaceFormComponent : invalid argument !");
662 0 : ((FmControlData*)pData)->ModelReplaced( xNew, m_aNormalImages );
663 :
664 0 : FmNavModelReplacedHint aReplacedHint( pData );
665 0 : Broadcast( aReplacedHint );
666 0 : }
667 :
668 : //------------------------------------------------------------------------
669 0 : FmEntryData* NavigatorTreeModel::FindData(const Reference< XInterface > & xElement, FmEntryDataList* pDataList, sal_Bool bRecurs)
670 : {
671 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FindData" );
672 : // normalize
673 0 : Reference< XInterface > xIFace( xElement, UNO_QUERY );
674 :
675 0 : for ( size_t i = 0; i < pDataList->size(); i++ )
676 : {
677 0 : FmEntryData* pEntryData = pDataList->at( i );
678 0 : if ( pEntryData->GetElement().get() == xIFace.get() )
679 0 : return pEntryData;
680 0 : else if (bRecurs)
681 : {
682 0 : pEntryData = FindData( xElement, pEntryData->GetChildList() );
683 0 : if (pEntryData)
684 0 : return pEntryData;
685 : }
686 : }
687 0 : return NULL;
688 : }
689 :
690 : //------------------------------------------------------------------------
691 0 : FmEntryData* NavigatorTreeModel::FindData( const OUString& rText, FmFormData* pParentData, sal_Bool bRecurs )
692 : {
693 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FindData" );
694 : FmEntryDataList* pDataList;
695 0 : if( !pParentData )
696 0 : pDataList = GetRootList();
697 : else
698 0 : pDataList = pParentData->GetChildList();
699 :
700 0 : OUString aEntryText;
701 : FmEntryData* pEntryData;
702 : FmEntryData* pChildData;
703 :
704 0 : for( size_t i = 0; i < pDataList->size(); i++ )
705 : {
706 0 : pEntryData = pDataList->at( i );
707 0 : aEntryText = pEntryData->GetText();
708 :
709 0 : if (rText == aEntryText)
710 0 : return pEntryData;
711 :
712 0 : if( bRecurs && pEntryData->ISA(FmFormData) )
713 : {
714 0 : pChildData = FindData( rText, (FmFormData*)pEntryData );
715 0 : if( pChildData )
716 0 : return pChildData;
717 : }
718 : }
719 :
720 0 : return NULL;
721 : }
722 :
723 : //------------------------------------------------------------------------
724 0 : void NavigatorTreeModel::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
725 : {
726 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Notify" );
727 0 : if( rHint.ISA(SdrHint) )
728 : {
729 0 : SdrHint* pSdrHint = (SdrHint*)&rHint;
730 0 : switch( pSdrHint->GetKind() )
731 : {
732 : case HINT_OBJINSERTED:
733 0 : InsertSdrObj(pSdrHint->GetObject());
734 0 : break;
735 : case HINT_OBJREMOVED:
736 0 : RemoveSdrObj(pSdrHint->GetObject());
737 0 : break;
738 : default:
739 0 : break;
740 : }
741 : }
742 : // hat sich die shell verabschiedet?
743 0 : else if ( rHint.ISA(SfxSimpleHint) && ((SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING)
744 0 : UpdateContent((FmFormShell*)NULL);
745 :
746 : // hat sich die Markierung der Controls veraendert ?
747 0 : else if (rHint.ISA(FmNavViewMarksChanged))
748 : {
749 0 : FmNavViewMarksChanged* pvmcHint = (FmNavViewMarksChanged*)&rHint;
750 0 : BroadcastMarkedObjects( pvmcHint->GetAffectedView()->GetMarkedObjectList() );
751 : }
752 0 : }
753 :
754 : //------------------------------------------------------------------------
755 0 : void NavigatorTreeModel::InsertSdrObj( const SdrObject* pObj )
756 : {
757 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertSdrObj" );
758 0 : const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
759 0 : if ( pFormObject )
760 : {
761 : try
762 : {
763 0 : Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
764 0 : Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW );
765 :
766 0 : sal_Int32 nPos = getElementPos( xContainer, xFormComponent );
767 0 : InsertFormComponent( xFormComponent, nPos );
768 : }
769 0 : catch( const Exception& )
770 : {
771 : DBG_UNHANDLED_EXCEPTION();
772 : }
773 : }
774 0 : else if ( pObj->IsGroupObject() )
775 : {
776 0 : SdrObjListIter aIter( *pObj->GetSubList() );
777 0 : while ( aIter.IsMore() )
778 0 : InsertSdrObj( aIter.Next() );
779 : }
780 0 : }
781 :
782 : //------------------------------------------------------------------------
783 0 : void NavigatorTreeModel::RemoveSdrObj( const SdrObject* pObj )
784 : {
785 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveSdrObj" );
786 0 : const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
787 0 : if ( pFormObject )
788 : {
789 : try
790 : {
791 0 : Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
792 0 : FmEntryData* pEntryData = FindData( xFormComponent, GetRootList(), sal_True );
793 0 : if ( pEntryData )
794 0 : Remove( pEntryData );
795 : }
796 0 : catch( const Exception& )
797 : {
798 : DBG_UNHANDLED_EXCEPTION();
799 : }
800 : }
801 0 : else if ( pObj->IsGroupObject() )
802 : {
803 0 : SdrObjListIter aIter( *pObj->GetSubList() );
804 0 : while ( aIter.IsMore() )
805 0 : RemoveSdrObj( aIter.Next() );
806 : }
807 0 : }
808 :
809 0 : sal_Bool NavigatorTreeModel::InsertFormComponent(FmNavRequestSelectHint& rHint, SdrObject* pObject)
810 : {
811 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertFormComponent" );
812 0 : if ( pObject->ISA(SdrObjGroup) )
813 : { // rekursiv absteigen
814 0 : const SdrObjList *pChildren = ((SdrObjGroup*)pObject)->GetSubList();
815 0 : for ( sal_uInt16 i=0; i<pChildren->GetObjCount(); ++i )
816 : {
817 0 : SdrObject* pCurrent = pChildren->GetObj(i);
818 0 : if (!InsertFormComponent(rHint, pCurrent))
819 0 : return sal_False;
820 : }
821 : }
822 : else
823 : {
824 0 : FmFormObj* pFormObject = FmFormObj::GetFormObject( pObject );
825 0 : if ( !pFormObject )
826 0 : return sal_False;
827 :
828 : try
829 : {
830 0 : Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
831 0 : FmEntryData* pControlData = FindData( xFormViewControl, GetRootList() );
832 0 : if ( !pControlData )
833 0 : return sal_False;
834 :
835 0 : rHint.AddItem( pControlData );
836 0 : return sal_True;
837 : }
838 0 : catch( const Exception& )
839 : {
840 : DBG_UNHANDLED_EXCEPTION();
841 0 : return sal_False;
842 : }
843 : }
844 :
845 0 : return sal_True;
846 : }
847 :
848 0 : void NavigatorTreeModel::BroadcastMarkedObjects(const SdrMarkList& mlMarked)
849 : {
850 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::BroadcastMarkedObjects" );
851 : // gehen wir durch alle markierten Objekte und suchen wir die raus, mit denen ich was anfangen kann
852 0 : FmNavRequestSelectHint rshRequestSelection;
853 0 : sal_Bool bIsMixedSelection = sal_False;
854 :
855 0 : for (sal_uLong i=0; (i<mlMarked.GetMarkCount()) && !bIsMixedSelection; i++)
856 : {
857 0 : SdrObject* pobjCurrent = mlMarked.GetMark(i)->GetMarkedSdrObj();
858 0 : bIsMixedSelection |= !InsertFormComponent(rshRequestSelection, pobjCurrent);
859 : // bei einem Nicht-Form-Control liefert InsertFormComponent sal_False !
860 : }
861 :
862 0 : rshRequestSelection.SetMixedSelection(bIsMixedSelection);
863 0 : if (bIsMixedSelection)
864 0 : rshRequestSelection.ClearItems();
865 :
866 0 : Broadcast(rshRequestSelection);
867 : // eine leere Liste interpretiert der NavigatorTree so, dass er seine Selektion komplett rausnimmt
868 0 : }
869 :
870 : //------------------------------------------------------------------------
871 0 : void NavigatorTreeModel::UpdateContent( const Reference< css::form::XForms > & xForms )
872 : {
873 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::UpdateContent" );
874 : //////////////////////////////////////////////////////////////////////
875 : // Model von der Root aufwaerts neu fuellen
876 0 : Clear();
877 0 : if (xForms.is())
878 : {
879 0 : xForms->addContainerListener((XContainerListener*)m_pPropChangeList);
880 :
881 0 : FillBranch(NULL);
882 :
883 : // jetzt in meinem Tree genau die das in meiner View markierte Control selektieren
884 : // (bzw alle solchen), falls es eines gibt ...
885 0 : if(!m_pFormShell) return; // keine Shell -> wech
886 :
887 0 : FmFormView* pFormView = m_pFormShell->GetFormView();
888 : DBG_ASSERT(pFormView != NULL, "NavigatorTreeModel::UpdateContent : keine FormView");
889 0 : BroadcastMarkedObjects(pFormView->GetMarkedObjectList());
890 : }
891 : }
892 :
893 : //------------------------------------------------------------------------
894 0 : void NavigatorTreeModel::UpdateContent( FmFormShell* pShell )
895 : {
896 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::UpdateContent" );
897 : //////////////////////////////////////////////////////////////////////
898 : // Wenn Shell sich nicht veraendert hat, nichts machen
899 0 : FmFormPage* pNewPage = pShell ? pShell->GetCurPage() : NULL;
900 0 : if ((pShell == m_pFormShell) && (m_pFormPage == pNewPage))
901 0 : return;
902 :
903 : //////////////////////////////////////////////////////////////////////
904 : // Als Listener abmelden
905 0 : if( m_pFormShell )
906 : {
907 0 : if (m_pFormModel)
908 0 : EndListening( *m_pFormModel );
909 0 : m_pFormModel = NULL;
910 0 : EndListening( *m_pFormShell );
911 0 : Clear();
912 : }
913 :
914 : //////////////////////////////////////////////////////////////////////
915 : // Vollupdate
916 0 : m_pFormShell = pShell;
917 0 : if (m_pFormShell)
918 : {
919 0 : m_pFormPage = pNewPage;
920 0 : UpdateContent(m_pFormPage->GetForms());
921 : } else
922 0 : m_pFormPage = NULL;
923 :
924 : //////////////////////////////////////////////////////////////////////
925 : // Als Listener neu anmelden
926 0 : if( m_pFormShell )
927 : {
928 0 : StartListening( *m_pFormShell );
929 0 : m_pFormModel = m_pFormShell->GetFormModel();
930 0 : if( m_pFormModel )
931 0 : StartListening( *m_pFormModel );
932 : }
933 : }
934 :
935 : //------------------------------------------------------------------------
936 0 : Reference< XIndexContainer > NavigatorTreeModel::GetFormComponents( FmFormData* pFormData )
937 : {
938 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetFormComponents" );
939 : //////////////////////////////////////////////////////////////////////
940 : // Von der Form Components holen
941 0 : if (pFormData)
942 0 : return Reference< XIndexContainer > (pFormData->GetFormIface(), UNO_QUERY);
943 :
944 0 : return Reference< XIndexContainer > ();
945 : }
946 :
947 : //------------------------------------------------------------------------
948 0 : sal_Bool NavigatorTreeModel::Rename( FmEntryData* pEntryData, const OUString& rNewText )
949 : {
950 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Rename" );
951 : //////////////////////////////////////////////////////////////////////
952 : // Wenn Name schon vorhanden, Fehlermeldung
953 0 : pEntryData->SetText( rNewText );
954 :
955 : //////////////////////////////////////////////////////////////////////
956 : // PropertySet besorgen
957 0 : Reference< XFormComponent > xFormComponent;
958 :
959 0 : if( pEntryData->ISA(FmFormData) )
960 : {
961 0 : FmFormData* pFormData = (FmFormData*)pEntryData;
962 0 : Reference< XForm > xForm( pFormData->GetFormIface());
963 0 : xFormComponent = xForm;
964 : }
965 :
966 0 : if( pEntryData->ISA(FmControlData) )
967 : {
968 0 : FmControlData* pControlData = (FmControlData*)pEntryData;
969 0 : xFormComponent = pControlData->GetFormComponent();
970 : }
971 :
972 0 : if( !xFormComponent.is() ) return sal_False;
973 0 : Reference< XPropertySet > xSet(xFormComponent, UNO_QUERY);
974 0 : if( !xSet.is() ) return sal_False;
975 :
976 : //////////////////////////////////////////////////////////////////////
977 : // Namen setzen
978 0 : xSet->setPropertyValue( FM_PROP_NAME, makeAny(rNewText) );
979 :
980 0 : return sal_True;
981 : }
982 :
983 : //------------------------------------------------------------------
984 0 : SdrObject* NavigatorTreeModel::Search(SdrObjListIter& rIter, const Reference< XFormComponent > & xComp)
985 : {
986 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Search" );
987 0 : while (rIter.IsMore())
988 : {
989 0 : SdrObject* pObj = rIter.Next();
990 0 : FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
991 0 : if ( pFormObject )
992 : {
993 0 : Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY );
994 0 : if ( xFormViewControl == xComp )
995 0 : return pObj;
996 : }
997 0 : else if ( pObj->IsGroupObject() )
998 : {
999 0 : SdrObjListIter aIter( *pObj->GetSubList() );
1000 0 : pObj = Search( aIter, xComp );
1001 0 : if ( pObj )
1002 0 : return pObj;
1003 : }
1004 : }
1005 0 : return NULL;
1006 : }
1007 :
1008 : //............................................................................
1009 258 : } // namespace svxform
1010 : //............................................................................
1011 :
1012 :
1013 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|