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 : ::rtl::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< XNameContainer > xForms( GetForms());
257 0 : Reference< XContainer > xContainer(xForms, UNO_QUERY);
258 0 : if (xContainer.is())
259 0 : xContainer->removeContainerListener((XContainerListener*)m_pPropChangeList);
260 :
261 : //////////////////////////////////////////////////////////////////////
262 : // RootList loeschen
263 0 : GetRootList()->clear();
264 :
265 : //////////////////////////////////////////////////////////////////////
266 : // UI benachrichtigen
267 0 : FmNavClearedHint aClearedHint;
268 0 : Broadcast( aClearedHint );
269 0 : }
270 :
271 : //------------------------------------------------------------------------
272 0 : Reference< XNameContainer > NavigatorTreeModel::GetForms() const
273 : {
274 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetForms" );
275 0 : if( !m_pFormShell || !m_pFormShell->GetCurPage())
276 0 : return NULL;
277 : else
278 0 : return m_pFormShell->GetCurPage()->GetForms();
279 : }
280 :
281 : //------------------------------------------------------------------------
282 0 : void NavigatorTreeModel::Insert(FmEntryData* pEntry, sal_uLong nRelPos, sal_Bool bAlterModel)
283 : {
284 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Insert" );
285 0 : if (IsListening(*m_pFormModel))
286 0 : EndListening(*m_pFormModel);
287 :
288 0 : m_pPropChangeList->Lock();
289 0 : FmFormData* pFolder = (FmFormData*) pEntry->GetParent();
290 0 : Reference< XChild > xElement( pEntry->GetChildIFace() );
291 0 : if (bAlterModel)
292 : {
293 0 : XubString aStr;
294 0 : if (pEntry->ISA(FmFormData))
295 0 : aStr = SVX_RESSTR(RID_STR_FORM);
296 : else
297 0 : aStr = SVX_RESSTR(RID_STR_CONTROL);
298 :
299 0 : Reference< XIndexContainer > xContainer;
300 0 : if (pFolder)
301 0 : xContainer = Reference< XIndexContainer > (pFolder->GetFormIface(), UNO_QUERY);
302 : else
303 0 : xContainer = Reference< XIndexContainer > (GetForms(), UNO_QUERY);
304 :
305 0 : bool bUndo = m_pFormModel->IsUndoEnabled();
306 :
307 0 : if( bUndo )
308 : {
309 0 : XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT));
310 0 : aUndoStr.SearchAndReplace(rtl::OUString('#'), aStr);
311 0 : m_pFormModel->BegUndo(aUndoStr);
312 : }
313 :
314 0 : if (nRelPos >= (sal_uInt32)xContainer->getCount())
315 0 : nRelPos = (sal_uInt32)xContainer->getCount();
316 :
317 : // UndoAction
318 0 : if ( bUndo && m_pPropChangeList->CanUndo())
319 : {
320 : m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel,
321 : FmUndoContainerAction::Inserted,
322 : xContainer,
323 : xElement,
324 0 : nRelPos));
325 : }
326 :
327 : // das Element muss den Typ haben, den der Container erwartet
328 0 : if (xContainer->getElementType() ==
329 0 : ::getCppuType((const Reference< XForm>*)0))
330 :
331 : {
332 0 : Reference< XForm > xElementAsForm(xElement, UNO_QUERY);
333 0 : xContainer->insertByIndex(nRelPos, makeAny(xElementAsForm));
334 : }
335 0 : else if (xContainer->getElementType() ==
336 0 : ::getCppuType((const Reference< XFormComponent>*)0))
337 :
338 : {
339 0 : Reference< XFormComponent > xElementAsComponent(xElement, UNO_QUERY);
340 0 : xContainer->insertByIndex(nRelPos, makeAny(xElementAsComponent));
341 : }
342 : else
343 : {
344 : OSL_FAIL("NavigatorTreeModel::Insert : the parent container needs an elementtype I don't know !");
345 : }
346 :
347 0 : if( bUndo )
348 0 : m_pFormModel->EndUndo();
349 : }
350 :
351 : //////////////////////////////////////////////////////////////////////
352 : // Als PropertyChangeListener anmelden
353 0 : Reference< XPropertySet > xSet(xElement, UNO_QUERY);
354 0 : if( xSet.is() )
355 0 : xSet->addPropertyChangeListener( FM_PROP_NAME, m_pPropChangeList );
356 :
357 : //////////////////////////////////////////////////////////////////////
358 : // Daten aus Model entfernen
359 0 : if (pEntry->ISA(FmFormData))
360 : {
361 0 : Reference< XContainer > xContainer(xElement, UNO_QUERY);
362 0 : if (xContainer.is())
363 0 : xContainer->addContainerListener((XContainerListener*)m_pPropChangeList);
364 : }
365 :
366 0 : if (pFolder)
367 0 : pFolder->GetChildList()->insert( pEntry, nRelPos );
368 : else
369 0 : GetRootList()->insert( pEntry, nRelPos );
370 :
371 : //////////////////////////////////////////////////////////////////////
372 : // UI benachrichtigen
373 0 : FmNavInsertedHint aInsertedHint( pEntry, nRelPos );
374 0 : Broadcast( aInsertedHint );
375 :
376 0 : m_pPropChangeList->UnLock();
377 0 : if (IsListening(*m_pFormModel))
378 0 : StartListening(*m_pFormModel);
379 0 : }
380 :
381 : //------------------------------------------------------------------------
382 0 : void NavigatorTreeModel::Remove(FmEntryData* pEntry, sal_Bool bAlterModel)
383 : {
384 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Remove" );
385 : //////////////////////////////////////////////////////////////////////
386 : // Form und Parent holen
387 0 : if (!pEntry || !m_pFormModel)
388 0 : return;
389 :
390 0 : if (IsListening(*m_pFormModel))
391 0 : EndListening(*m_pFormModel);
392 :
393 0 : const bool bUndo = m_pFormModel->IsUndoEnabled();
394 :
395 0 : m_pPropChangeList->Lock();
396 0 : FmFormData* pFolder = (FmFormData*) pEntry->GetParent();
397 0 : Reference< XChild > xElement ( pEntry->GetChildIFace() );
398 0 : if (bAlterModel)
399 : {
400 0 : XubString aStr;
401 0 : if (pEntry->ISA(FmFormData))
402 0 : aStr = SVX_RESSTR(RID_STR_FORM);
403 : else
404 0 : aStr = SVX_RESSTR(RID_STR_CONTROL);
405 :
406 0 : if( bUndo )
407 : {
408 0 : XubString aUndoStr(SVX_RESSTR(RID_STR_UNDO_CONTAINER_REMOVE));
409 0 : aUndoStr.SearchAndReplace(rtl::OUString('#'), aStr);
410 0 : m_pFormModel->BegUndo(aUndoStr);
411 0 : }
412 : }
413 :
414 : // jetzt die eigentliche Entfernung der Daten aus dem Model
415 0 : if (pEntry->ISA(FmFormData))
416 0 : RemoveForm((FmFormData*)pEntry);
417 : else
418 0 : RemoveFormComponent((FmControlData*)pEntry);
419 :
420 :
421 0 : if (bAlterModel)
422 : {
423 0 : Reference< XIndexContainer > xContainer(xElement->getParent(), UNO_QUERY);
424 : // aus dem Container entfernen
425 0 : sal_Int32 nContainerIndex = getElementPos(xContainer.get(), xElement);
426 : // UndoAction
427 0 : if (nContainerIndex >= 0)
428 : {
429 0 : if ( bUndo && m_pPropChangeList->CanUndo())
430 : {
431 : m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel,
432 : FmUndoContainerAction::Removed,
433 : xContainer,
434 0 : xElement, nContainerIndex ));
435 : }
436 0 : else if( !m_pPropChangeList->CanUndo() )
437 : {
438 0 : FmUndoContainerAction::DisposeElement( xElement );
439 : }
440 :
441 0 : xContainer->removeByIndex(nContainerIndex );
442 : }
443 :
444 0 : if( bUndo )
445 0 : m_pFormModel->EndUndo();
446 : }
447 :
448 : // beim Vater austragen
449 0 : if (pFolder)
450 0 : pFolder->GetChildList()->remove( pEntry );
451 : else
452 : {
453 0 : GetRootList()->remove( pEntry );
454 : //////////////////////////////////////////////////////////////////////
455 : // Wenn keine Form mehr in der Root, an der Shell CurForm zuruecksetzen
456 0 : if ( !GetRootList()->size() )
457 0 : m_pFormShell->GetImpl()->forgetCurrentForm();
458 : }
459 :
460 : //////////////////////////////////////////////////////////////////////
461 : // UI benachrichtigen
462 0 : FmNavRemovedHint aRemovedHint( pEntry );
463 0 : Broadcast( aRemovedHint );
464 :
465 : // Eintrag loeschen
466 0 : delete pEntry;
467 :
468 0 : m_pPropChangeList->UnLock();
469 0 : StartListening(*m_pFormModel);
470 : }
471 :
472 : //------------------------------------------------------------------------
473 0 : void NavigatorTreeModel::RemoveForm(FmFormData* pFormData)
474 : {
475 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveForm" );
476 : //////////////////////////////////////////////////////////////////////
477 : // Form und Parent holen
478 0 : if (!pFormData || !m_pFormModel)
479 0 : return;
480 :
481 0 : FmEntryDataList* pChildList = pFormData->GetChildList();
482 0 : for ( size_t i = pChildList->size(); i > 0; )
483 : {
484 0 : FmEntryData* pEntryData = pChildList->at( --i );
485 :
486 : //////////////////////////////////////////////////////////////////////
487 : // Child ist Form -> rekursiver Aufruf
488 0 : if( pEntryData->ISA(FmFormData) )
489 0 : RemoveForm( (FmFormData*)pEntryData);
490 0 : else if( pEntryData->ISA(FmControlData) )
491 0 : RemoveFormComponent((FmControlData*) pEntryData);
492 : }
493 :
494 : //////////////////////////////////////////////////////////////////////
495 : // Als PropertyChangeListener abmelden
496 0 : Reference< XPropertySet > xSet( pFormData->GetPropertySet() );
497 0 : if ( xSet.is() )
498 0 : xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList );
499 :
500 0 : Reference< XContainer > xContainer( pFormData->GetContainer() );
501 0 : if (xContainer.is())
502 0 : xContainer->removeContainerListener((XContainerListener*)m_pPropChangeList);
503 : }
504 :
505 : //------------------------------------------------------------------------
506 0 : void NavigatorTreeModel::RemoveFormComponent(FmControlData* pControlData)
507 : {
508 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveFormComponent" );
509 : //////////////////////////////////////////////////////////////////////
510 : // Control und Parent holen
511 0 : if (!pControlData)
512 0 : return;
513 :
514 : //////////////////////////////////////////////////////////////////////
515 : // Als PropertyChangeListener abmelden
516 0 : Reference< XPropertySet > xSet( pControlData->GetPropertySet() );
517 0 : if (xSet.is())
518 0 : xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList);
519 : }
520 :
521 : //------------------------------------------------------------------------
522 0 : void NavigatorTreeModel::ClearBranch( FmFormData* pParentData )
523 : {
524 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::ClearBranch" );
525 : //////////////////////////////////////////////////////////////////////
526 : // Alle Eintraege dieses Zweiges loeschen
527 0 : FmEntryDataList* pChildList = pParentData->GetChildList();
528 :
529 0 : for( size_t i = pChildList->size(); i > 0; )
530 : {
531 0 : FmEntryData* pChildData = pChildList->at( --i );
532 0 : if( pChildData->ISA(FmFormData) )
533 0 : ClearBranch( (FmFormData*)pChildData );
534 :
535 0 : pChildList->remove( pChildData );
536 : }
537 0 : }
538 :
539 : //------------------------------------------------------------------------
540 0 : void NavigatorTreeModel::FillBranch( FmFormData* pFormData )
541 : {
542 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FillBranch" );
543 : //////////////////////////////////////////////////////////////
544 : // Forms aus der Root einfuegen
545 0 : if( pFormData == NULL )
546 : {
547 0 : Reference< XIndexContainer > xForms(GetForms(), UNO_QUERY);
548 0 : if (!xForms.is())
549 : return;
550 :
551 0 : Reference< XForm > xSubForm;
552 : FmFormData* pSubFormData;
553 0 : for (sal_Int32 i=0; i<xForms->getCount(); ++i)
554 : {
555 : DBG_ASSERT( xForms->getByIndex(i).getValueType() == ::getCppuType((const Reference< XForm>*)NULL),
556 : "NavigatorTreeModel::FillBranch : the root container should supply only elements of type XForm");
557 :
558 0 : xForms->getByIndex(i) >>= xSubForm;
559 0 : pSubFormData = new FmFormData( xSubForm, m_aNormalImages, pFormData );
560 0 : Insert( pSubFormData, LIST_APPEND );
561 :
562 : //////////////////////////////////////////////////////////////
563 : // Neuer Branch, wenn SubForm wiederum Subforms enthaelt
564 0 : FillBranch( pSubFormData );
565 0 : }
566 : }
567 :
568 : //////////////////////////////////////////////////////////////
569 : // Componenten einfuegen
570 : else
571 : {
572 0 : Reference< XIndexContainer > xComponents( GetFormComponents(pFormData));
573 0 : if( !xComponents.is() ) return;
574 :
575 0 : Reference< XInterface > xInterface;
576 0 : Reference< XPropertySet > xSet;
577 : FmControlData* pNewControlData;
578 : FmFormData* pSubFormData;
579 :
580 0 : Reference< XFormComponent > xCurrentComponent;
581 0 : for (sal_Int32 j=0; j<xComponents->getCount(); ++j)
582 : {
583 0 : xComponents->getByIndex(j) >>= xCurrentComponent;
584 0 : Reference< XForm > xSubForm(xCurrentComponent, UNO_QUERY);
585 :
586 0 : if (xSubForm.is())
587 : { // die aktuelle Component ist eine Form
588 0 : pSubFormData = new FmFormData(xSubForm, m_aNormalImages, pFormData);
589 0 : Insert(pSubFormData, LIST_APPEND);
590 :
591 : //////////////////////////////////////////////////////////////
592 : // Neuer Branch, wenn SubForm wiederum Subforms enthaelt
593 0 : FillBranch(pSubFormData);
594 : }
595 : else
596 : {
597 0 : pNewControlData = new FmControlData(xCurrentComponent, m_aNormalImages, pFormData);
598 0 : Insert(pNewControlData, LIST_APPEND);
599 : }
600 0 : }
601 : }
602 : }
603 :
604 : //------------------------------------------------------------------------
605 0 : void NavigatorTreeModel::InsertForm(const Reference< XForm > & xForm, sal_uInt32 nRelPos)
606 : {
607 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertForm" );
608 0 : FmFormData* pFormData = (FmFormData*)FindData( xForm, GetRootList() );
609 0 : if (pFormData)
610 0 : return;
611 :
612 : //////////////////////////////////////////////////////////
613 : // ParentData setzen
614 0 : Reference< XInterface > xIFace( xForm->getParent());
615 0 : Reference< XForm > xParentForm(xIFace, UNO_QUERY);
616 0 : FmFormData* pParentData = NULL;
617 0 : if (xParentForm.is())
618 0 : pParentData = (FmFormData*)FindData( xParentForm, GetRootList() );
619 :
620 0 : pFormData = new FmFormData( xForm, m_aNormalImages, pParentData );
621 0 : Insert( pFormData, nRelPos );
622 : }
623 :
624 : //------------------------------------------------------------------------
625 0 : void NavigatorTreeModel::InsertFormComponent(const Reference< XFormComponent > & xComp, sal_uInt32 nRelPos)
626 : {
627 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertFormComponent" );
628 : //////////////////////////////////////////////////////////
629 : // ParentData setzen
630 0 : Reference< XInterface > xIFace( xComp->getParent());
631 0 : Reference< XForm > xForm(xIFace, UNO_QUERY);
632 0 : if (!xForm.is())
633 0 : return;
634 :
635 0 : FmFormData* pParentData = (FmFormData*)FindData( xForm, GetRootList() );
636 0 : if( !pParentData )
637 : {
638 0 : pParentData = new FmFormData( xForm, m_aNormalImages, NULL );
639 0 : Insert( pParentData, LIST_APPEND );
640 : }
641 :
642 0 : if (!FindData(xComp, pParentData->GetChildList(),sal_False))
643 : {
644 : //////////////////////////////////////////////////////////
645 : // Neue EntryData setzen
646 0 : FmEntryData* pNewEntryData = new FmControlData( xComp, m_aNormalImages, pParentData );
647 :
648 : //////////////////////////////////////////////////////////
649 : // Neue EntryData einfuegen
650 0 : Insert( pNewEntryData, nRelPos );
651 0 : }
652 : }
653 :
654 : //------------------------------------------------------------------------
655 0 : void NavigatorTreeModel::ReplaceFormComponent(
656 : const Reference< XFormComponent > & xOld,
657 : const Reference< XFormComponent > & xNew
658 : )
659 : {
660 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::ReplaceFormComponent" );
661 0 : FmEntryData* pData = FindData(xOld, GetRootList(), sal_True);
662 : DBG_ASSERT(pData && pData->ISA(FmControlData), "NavigatorTreeModel::ReplaceFormComponent : invalid argument !");
663 0 : ((FmControlData*)pData)->ModelReplaced( xNew, m_aNormalImages );
664 :
665 0 : FmNavModelReplacedHint aReplacedHint( pData );
666 0 : Broadcast( aReplacedHint );
667 0 : }
668 :
669 : //------------------------------------------------------------------------
670 0 : FmEntryData* NavigatorTreeModel::FindData(const Reference< XInterface > & xElement, FmEntryDataList* pDataList, sal_Bool bRecurs)
671 : {
672 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FindData" );
673 : // normalize
674 0 : Reference< XInterface > xIFace( xElement, UNO_QUERY );
675 :
676 0 : for ( size_t i = 0; i < pDataList->size(); i++ )
677 : {
678 0 : FmEntryData* pEntryData = pDataList->at( i );
679 0 : if ( pEntryData->GetElement().get() == xIFace.get() )
680 0 : return pEntryData;
681 0 : else if (bRecurs)
682 : {
683 0 : pEntryData = FindData( xElement, pEntryData->GetChildList() );
684 0 : if (pEntryData)
685 0 : return pEntryData;
686 : }
687 : }
688 0 : return NULL;
689 : }
690 :
691 : //------------------------------------------------------------------------
692 0 : FmEntryData* NavigatorTreeModel::FindData( const ::rtl::OUString& rText, FmFormData* pParentData, sal_Bool bRecurs )
693 : {
694 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FindData" );
695 : FmEntryDataList* pDataList;
696 0 : if( !pParentData )
697 0 : pDataList = GetRootList();
698 : else
699 0 : pDataList = pParentData->GetChildList();
700 :
701 0 : ::rtl::OUString aEntryText;
702 : FmEntryData* pEntryData;
703 : FmEntryData* pChildData;
704 :
705 0 : for( size_t i = 0; i < pDataList->size(); i++ )
706 : {
707 0 : pEntryData = pDataList->at( i );
708 0 : aEntryText = pEntryData->GetText();
709 :
710 0 : if (rText == aEntryText)
711 0 : return pEntryData;
712 :
713 0 : if( bRecurs && pEntryData->ISA(FmFormData) )
714 : {
715 0 : pChildData = FindData( rText, (FmFormData*)pEntryData );
716 0 : if( pChildData )
717 0 : return pChildData;
718 : }
719 : }
720 :
721 0 : return NULL;
722 : }
723 :
724 : //------------------------------------------------------------------------
725 0 : void NavigatorTreeModel::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
726 : {
727 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Notify" );
728 0 : if( rHint.ISA(SdrHint) )
729 : {
730 0 : SdrHint* pSdrHint = (SdrHint*)&rHint;
731 0 : switch( pSdrHint->GetKind() )
732 : {
733 : case HINT_OBJINSERTED:
734 0 : InsertSdrObj(pSdrHint->GetObject());
735 0 : break;
736 : case HINT_OBJREMOVED:
737 0 : RemoveSdrObj(pSdrHint->GetObject());
738 0 : break;
739 : default:
740 0 : break;
741 : }
742 : }
743 : // hat sich die shell verabschiedet?
744 0 : else if ( rHint.ISA(SfxSimpleHint) && ((SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING)
745 0 : UpdateContent((FmFormShell*)NULL);
746 :
747 : // hat sich die Markierung der Controls veraendert ?
748 0 : else if (rHint.ISA(FmNavViewMarksChanged))
749 : {
750 0 : FmNavViewMarksChanged* pvmcHint = (FmNavViewMarksChanged*)&rHint;
751 0 : BroadcastMarkedObjects( pvmcHint->GetAffectedView()->GetMarkedObjectList() );
752 : }
753 0 : }
754 :
755 : //------------------------------------------------------------------------
756 0 : void NavigatorTreeModel::InsertSdrObj( const SdrObject* pObj )
757 : {
758 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertSdrObj" );
759 0 : const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
760 0 : if ( pFormObject )
761 : {
762 : try
763 : {
764 0 : Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
765 0 : Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW );
766 :
767 0 : sal_Int32 nPos = getElementPos( xContainer, xFormComponent );
768 0 : InsertFormComponent( xFormComponent, nPos );
769 : }
770 0 : catch( const Exception& )
771 : {
772 : DBG_UNHANDLED_EXCEPTION();
773 : }
774 : }
775 0 : else if ( pObj->IsGroupObject() )
776 : {
777 0 : SdrObjListIter aIter( *pObj->GetSubList() );
778 0 : while ( aIter.IsMore() )
779 0 : InsertSdrObj( aIter.Next() );
780 : }
781 0 : }
782 :
783 : //------------------------------------------------------------------------
784 0 : void NavigatorTreeModel::RemoveSdrObj( const SdrObject* pObj )
785 : {
786 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveSdrObj" );
787 0 : const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
788 0 : if ( pFormObject )
789 : {
790 : try
791 : {
792 0 : Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
793 0 : FmEntryData* pEntryData = FindData( xFormComponent, GetRootList(), sal_True );
794 0 : if ( pEntryData )
795 0 : Remove( pEntryData );
796 : }
797 0 : catch( const Exception& )
798 : {
799 : DBG_UNHANDLED_EXCEPTION();
800 : }
801 : }
802 0 : else if ( pObj->IsGroupObject() )
803 : {
804 0 : SdrObjListIter aIter( *pObj->GetSubList() );
805 0 : while ( aIter.IsMore() )
806 0 : RemoveSdrObj( aIter.Next() );
807 : }
808 0 : }
809 :
810 0 : sal_Bool NavigatorTreeModel::InsertFormComponent(FmNavRequestSelectHint& rHint, SdrObject* pObject)
811 : {
812 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertFormComponent" );
813 0 : if ( pObject->ISA(SdrObjGroup) )
814 : { // rekursiv absteigen
815 0 : const SdrObjList *pChildren = ((SdrObjGroup*)pObject)->GetSubList();
816 0 : for ( sal_uInt16 i=0; i<pChildren->GetObjCount(); ++i )
817 : {
818 0 : SdrObject* pCurrent = pChildren->GetObj(i);
819 0 : if (!InsertFormComponent(rHint, pCurrent))
820 0 : return sal_False;
821 : }
822 : }
823 : else
824 : {
825 0 : FmFormObj* pFormObject = FmFormObj::GetFormObject( pObject );
826 0 : if ( !pFormObject )
827 0 : return sal_False;
828 :
829 : try
830 : {
831 0 : Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
832 0 : FmEntryData* pControlData = FindData( xFormViewControl, GetRootList() );
833 0 : if ( !pControlData )
834 0 : return sal_False;
835 :
836 0 : rHint.AddItem( pControlData );
837 0 : return sal_True;
838 : }
839 0 : catch( const Exception& )
840 : {
841 : DBG_UNHANDLED_EXCEPTION();
842 0 : return sal_False;
843 : }
844 : }
845 :
846 0 : return sal_True;
847 : }
848 :
849 0 : void NavigatorTreeModel::BroadcastMarkedObjects(const SdrMarkList& mlMarked)
850 : {
851 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::BroadcastMarkedObjects" );
852 : // gehen wir durch alle markierten Objekte und suchen wir die raus, mit denen ich was anfangen kann
853 0 : FmNavRequestSelectHint rshRequestSelection;
854 0 : sal_Bool bIsMixedSelection = sal_False;
855 :
856 0 : for (sal_uLong i=0; (i<mlMarked.GetMarkCount()) && !bIsMixedSelection; i++)
857 : {
858 0 : SdrObject* pobjCurrent = mlMarked.GetMark(i)->GetMarkedSdrObj();
859 0 : bIsMixedSelection |= !InsertFormComponent(rshRequestSelection, pobjCurrent);
860 : // bei einem Nicht-Form-Control liefert InsertFormComponent sal_False !
861 : }
862 :
863 0 : rshRequestSelection.SetMixedSelection(bIsMixedSelection);
864 0 : if (bIsMixedSelection)
865 0 : rshRequestSelection.ClearItems();
866 :
867 0 : Broadcast(rshRequestSelection);
868 : // eine leere Liste interpretiert der NavigatorTree so, dass er seine Selektion komplett rausnimmt
869 0 : }
870 :
871 : //------------------------------------------------------------------------
872 0 : void NavigatorTreeModel::UpdateContent( const Reference< XNameContainer > & xForms )
873 : {
874 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::UpdateContent" );
875 : //////////////////////////////////////////////////////////////////////
876 : // Model von der Root aufwaerts neu fuellen
877 0 : Clear();
878 0 : if (xForms.is())
879 : {
880 0 : Reference< XContainer > xFormContainer(xForms, UNO_QUERY);
881 0 : if (xFormContainer.is())
882 0 : xFormContainer->addContainerListener((XContainerListener*)m_pPropChangeList);
883 :
884 0 : FillBranch(NULL);
885 :
886 : // jetzt in meinem Tree genau die das in meiner View markierte Control selektieren
887 : // (bzw alle solchen), falls es eines gibt ...
888 0 : if(!m_pFormShell) return; // keine Shell -> wech
889 :
890 0 : FmFormView* pFormView = m_pFormShell->GetFormView();
891 : DBG_ASSERT(pFormView != NULL, "NavigatorTreeModel::UpdateContent : keine FormView");
892 0 : BroadcastMarkedObjects(pFormView->GetMarkedObjectList());
893 : }
894 : }
895 :
896 : //------------------------------------------------------------------------
897 0 : void NavigatorTreeModel::UpdateContent( FmFormShell* pShell )
898 : {
899 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::UpdateContent" );
900 : //////////////////////////////////////////////////////////////////////
901 : // Wenn Shell sich nicht veraendert hat, nichts machen
902 0 : FmFormPage* pNewPage = pShell ? pShell->GetCurPage() : NULL;
903 0 : if ((pShell == m_pFormShell) && (m_pFormPage == pNewPage))
904 0 : return;
905 :
906 : //////////////////////////////////////////////////////////////////////
907 : // Als Listener abmelden
908 0 : if( m_pFormShell )
909 : {
910 0 : if (m_pFormModel)
911 0 : EndListening( *m_pFormModel );
912 0 : m_pFormModel = NULL;
913 0 : EndListening( *m_pFormShell );
914 0 : Clear();
915 : }
916 :
917 : //////////////////////////////////////////////////////////////////////
918 : // Vollupdate
919 0 : m_pFormShell = pShell;
920 0 : if (m_pFormShell)
921 : {
922 0 : m_pFormPage = pNewPage;
923 0 : UpdateContent(m_pFormPage->GetForms());
924 : } else
925 0 : m_pFormPage = NULL;
926 :
927 : //////////////////////////////////////////////////////////////////////
928 : // Als Listener neu anmelden
929 0 : if( m_pFormShell )
930 : {
931 0 : StartListening( *m_pFormShell );
932 0 : m_pFormModel = m_pFormShell->GetFormModel();
933 0 : if( m_pFormModel )
934 0 : StartListening( *m_pFormModel );
935 : }
936 : }
937 :
938 : //------------------------------------------------------------------------
939 0 : Reference< XIndexContainer > NavigatorTreeModel::GetFormComponents( FmFormData* pFormData )
940 : {
941 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetFormComponents" );
942 : //////////////////////////////////////////////////////////////////////
943 : // Von der Form Components holen
944 0 : if (pFormData)
945 0 : return Reference< XIndexContainer > (pFormData->GetFormIface(), UNO_QUERY);
946 :
947 0 : return Reference< XIndexContainer > ();
948 : }
949 :
950 : //------------------------------------------------------------------------
951 0 : sal_Bool NavigatorTreeModel::Rename( FmEntryData* pEntryData, const ::rtl::OUString& rNewText )
952 : {
953 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Rename" );
954 : //////////////////////////////////////////////////////////////////////
955 : // Wenn Name schon vorhanden, Fehlermeldung
956 0 : pEntryData->SetText( rNewText );
957 :
958 : //////////////////////////////////////////////////////////////////////
959 : // PropertySet besorgen
960 0 : Reference< XFormComponent > xFormComponent;
961 :
962 0 : if( pEntryData->ISA(FmFormData) )
963 : {
964 0 : FmFormData* pFormData = (FmFormData*)pEntryData;
965 0 : Reference< XForm > xForm( pFormData->GetFormIface());
966 0 : xFormComponent = Reference< XFormComponent > (xForm, UNO_QUERY);
967 : }
968 :
969 0 : if( pEntryData->ISA(FmControlData) )
970 : {
971 0 : FmControlData* pControlData = (FmControlData*)pEntryData;
972 0 : xFormComponent = pControlData->GetFormComponent();
973 : }
974 :
975 0 : if( !xFormComponent.is() ) return sal_False;
976 0 : Reference< XPropertySet > xSet(xFormComponent, UNO_QUERY);
977 0 : if( !xSet.is() ) return sal_False;
978 :
979 : //////////////////////////////////////////////////////////////////////
980 : // Namen setzen
981 0 : xSet->setPropertyValue( FM_PROP_NAME, makeAny(rNewText) );
982 :
983 0 : return sal_True;
984 : }
985 :
986 : //------------------------------------------------------------------
987 0 : SdrObject* NavigatorTreeModel::Search(SdrObjListIter& rIter, const Reference< XFormComponent > & xComp)
988 : {
989 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Search" );
990 0 : while (rIter.IsMore())
991 : {
992 0 : SdrObject* pObj = rIter.Next();
993 0 : FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj );
994 0 : if ( pFormObject )
995 : {
996 0 : Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY );
997 0 : if ( xFormViewControl == xComp )
998 0 : return pObj;
999 : }
1000 0 : else if ( pObj->IsGroupObject() )
1001 : {
1002 0 : SdrObjListIter aIter( *pObj->GetSubList() );
1003 0 : pObj = Search( aIter, xComp );
1004 0 : if ( pObj )
1005 0 : return pObj;
1006 : }
1007 : }
1008 0 : return NULL;
1009 : }
1010 :
1011 : //............................................................................
1012 : } // namespace svxform
1013 : //............................................................................
1014 :
1015 :
1016 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|