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