1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef INCLUDED_SVX_SOURCE_INC_FMEXPL_HXX
20 #define INCLUDED_SVX_SOURCE_INC_FMEXPL_HXX
22 #include <config_options.h>
23 #include <svl/lstner.hxx>
24 #include <svl/SfxBroadcaster.hxx>
25 #include <vcl/window.hxx>
26 #include <sfx2/childwin.hxx>
27 #include <svl/poolitem.hxx>
28 #include <sfx2/bindings.hxx>
29 #include <sfx2/dockwin.hxx>
30 #include <sfx2/ctrlitem.hxx>
32 #include <com/sun/star/form/XForm.hpp>
33 #include <com/sun/star/form/XFormComponent.hpp>
34 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
35 #include <com/sun/star/container/XContainerListener.hpp>
36 #include <com/sun/star/beans/XPropertyChangeListener.hpp>
37 #include <com/sun/star/container/XIndexContainer.hpp>
39 #include <svx/fmview.hxx>
44 #include <cppuhelper/implbase.hxx>
55 class FmNavInsertedHint final
: public SfxHint
57 FmEntryData
* pEntryData
;
61 FmNavInsertedHint( FmEntryData
* pInsertedEntryData
, sal_uInt32 nRelPos
);
62 virtual ~FmNavInsertedHint() override
;
64 FmEntryData
* GetEntryData() const { return pEntryData
; }
65 sal_uInt32
GetRelPos() const { return nPos
; }
69 class FmNavModelReplacedHint final
: public SfxHint
71 FmEntryData
* pEntryData
; // the data of the entry that has got a new model
74 FmNavModelReplacedHint( FmEntryData
* pAffectedEntryData
);
75 virtual ~FmNavModelReplacedHint() override
;
77 FmEntryData
* GetEntryData() const { return pEntryData
; }
81 class FmNavRemovedHint final
: public SfxHint
83 FmEntryData
* pEntryData
;
86 FmNavRemovedHint( FmEntryData
* pInsertedEntryData
);
87 virtual ~FmNavRemovedHint() override
;
89 FmEntryData
* GetEntryData() const { return pEntryData
; }
93 class FmNavNameChangedHint final
: public SfxHint
95 FmEntryData
* pEntryData
;
99 FmNavNameChangedHint( FmEntryData
* pData
, OUString aNewName
);
100 virtual ~FmNavNameChangedHint() override
;
102 FmEntryData
* GetEntryData() const { return pEntryData
; }
103 const OUString
& GetNewName() const { return aNewName
; }
107 class FmNavClearedHint final
: public SfxHint
111 virtual ~FmNavClearedHint() override
;
115 class FmNavViewMarksChanged final
: public SfxHint
119 FmNavViewMarksChanged(FmFormView
* pWhichView
)
120 : SfxHint(SfxHintId::FmNavViewMarksChanged
) { pView
= pWhichView
; }
122 const FmFormView
* GetAffectedView() const { return pView
; }
126 class FmEntryDataList
;
130 css::uno::Reference
< css::uno::XInterface
> m_xNormalizedIFace
;
131 css::uno::Reference
< css::beans::XPropertySet
> m_xProperties
;
132 css::uno::Reference
< css::container::XChild
> m_xChild
;
135 OUString m_aNormalImage
;
138 std::unique_ptr
<FmEntryDataList
>
140 FmEntryData
* pParent
;
143 void newObject( const css::uno::Reference
< css::uno::XInterface
>& _rxIFace
);
147 FmEntryData( FmEntryData
* pParentData
, const css::uno::Reference
< css::uno::XInterface
>& _rIFace
);
148 virtual ~FmEntryData();
150 void SetText( const OUString
& rText
){ aText
= rText
; }
151 void SetParent( FmEntryData
* pParentData
){ pParent
= pParentData
; }
153 const OUString
& GetNormalImage() const { return m_aNormalImage
; }
155 const OUString
& GetText() const { return aText
; }
156 FmEntryData
* GetParent() const { return pParent
; }
157 FmEntryDataList
* GetChildList() const { return pChildList
.get(); }
159 virtual bool IsEqualWithoutChildren( FmEntryData
* pEntryData
);
161 // note that the interface returned is normalized, i.e. querying the given XInterface of the object
162 // for XInterface must return the interface itself.
163 const css::uno::Reference
< css::uno::XInterface
>& GetElement() const
165 return m_xNormalizedIFace
;
168 const css::uno::Reference
< css::beans::XPropertySet
>& GetPropertySet() const
170 return m_xProperties
;
173 const css::uno::Reference
< css::container::XChild
>& GetChildIFace() const
180 class FmEntryDataList final
183 std::vector
< std::unique_ptr
<FmEntryData
> > maEntryDataList
;
189 FmEntryData
* at( size_t Index
)
190 { return maEntryDataList
.at(Index
).get(); }
192 size_t size() const { return maEntryDataList
.size(); }
193 void removeNoDelete( FmEntryData
* pItem
);
194 void insert( std::unique_ptr
<FmEntryData
> pItem
, size_t Index
);
199 // FmNavRequestSelectHint - someone tells the NavigatorTree to select certain entries
201 typedef std::set
<FmEntryData
*> FmEntryDataArray
;
203 class FmNavRequestSelectHint final
: public SfxHint
205 FmEntryDataArray m_arredToSelect
;
206 bool m_bMixedSelection
;
208 FmNavRequestSelectHint()
209 : SfxHint(SfxHintId::FmNavRequestSelect
),
210 m_bMixedSelection(false)
214 void SetMixedSelection(bool bMixedSelection
) { m_bMixedSelection
= bMixedSelection
; }
215 bool IsMixedSelection() const { return m_bMixedSelection
; }
216 void AddItem(FmEntryData
* pEntry
) { m_arredToSelect
.insert(pEntry
); }
217 void ClearItems() { m_arredToSelect
.clear(); }
218 FmEntryDataArray
& GetItems() { return m_arredToSelect
; }
222 class FmFormData final
: public FmEntryData
224 css::uno::Reference
< css::form::XForm
> m_xForm
;
227 FmFormData(const css::uno::Reference
< css::form::XForm
>& _rxForm
, FmFormData
* _pParent
);
228 virtual ~FmFormData() override
;
230 const css::uno::Reference
< css::form::XForm
>& GetFormIface() const { return m_xForm
; }
232 virtual bool IsEqualWithoutChildren( FmEntryData
* pEntryData
) override
;
236 class FmControlData final
: public FmEntryData
238 css::uno::Reference
< css::form::XFormComponent
> m_xFormComponent
;
240 OUString
GetImage() const;
245 const css::uno::Reference
< css::form::XFormComponent
>& _rxComponent
,
248 virtual ~FmControlData() override
;
250 const css::uno::Reference
< css::form::XFormComponent
>& GetFormComponent() const { return m_xFormComponent
; }
251 virtual bool IsEqualWithoutChildren( FmEntryData
* pEntryData
) override
;
253 void ModelReplaced(const css::uno::Reference
< css::form::XFormComponent
>& _rxNew
);
261 class NavigatorTreeModel
;
263 class OFormComponentObserver final
264 :public ::cppu::WeakImplHelper
< css::beans::XPropertyChangeListener
265 , css::container::XContainerListener
268 ::svxform::NavigatorTreeModel
* m_pNavModel
;
273 OFormComponentObserver( ::svxform::NavigatorTreeModel
* pModel
);
275 // XEventListenerListener
276 virtual void SAL_CALL
disposing(const css::lang::EventObject
& Source
) override
;
278 // css::beans::XPropertyChangeListener
279 virtual void SAL_CALL
propertyChange(const css::beans::PropertyChangeEvent
& evt
) override
;
281 // css::container::XContainerListener
283 virtual void SAL_CALL
elementInserted(const css::container::ContainerEvent
& rEvent
) override
;
284 virtual void SAL_CALL
elementReplaced(const css::container::ContainerEvent
& rEvent
) override
;
285 virtual void SAL_CALL
elementRemoved(const css::container::ContainerEvent
& rEvent
) override
;
287 void Lock() { m_nLocks
++; }
288 void UnLock() { m_nLocks
--; }
289 bool IsLocked() const { return m_nLocks
!= 0; }
290 bool CanUndo() const { return m_bCanUndo
; }
291 void ReleaseModel() { m_pNavModel
= nullptr; }
293 void Insert(const css::uno::Reference
< css::uno::XInterface
>& xIface
, sal_Int32 nIndex
);
294 void Remove( const css::uno::Reference
< css::uno::XInterface
>& _rxElement
);
297 class NavigatorTreeModel final
: public SfxBroadcaster
300 friend class NavigatorTree
;
301 friend class OFormComponentObserver
;
303 std::unique_ptr
<FmEntryDataList
>
305 FmFormShell
* m_pFormShell
;
306 FmFormPage
* m_pFormPage
;
307 FmFormModel
* m_pFormModel
;
308 rtl::Reference
<OFormComponentObserver
> m_pPropChangeList
;
310 void UpdateContent( const css::uno::Reference
< css::form::XForms
>& xForms
);
312 void InsertForm(const css::uno::Reference
< css::form::XForm
>& xForm
, sal_uInt32 nRelPos
);
313 void RemoveForm(FmFormData
const * pFormData
);
315 void InsertFormComponent(const css::uno::Reference
< css::form::XFormComponent
>& xComp
, sal_uInt32 nRelPos
);
316 void RemoveFormComponent(FmControlData
const * pControlData
);
317 void InsertSdrObj(const SdrObject
* pSdrObj
);
318 void RemoveSdrObj(const SdrObject
* pSdrObj
);
320 void ReplaceFormComponent(const css::uno::Reference
< css::form::XFormComponent
>& xOld
, const css::uno::Reference
< css::form::XFormComponent
>& xNew
);
322 void BroadcastMarkedObjects(const SdrMarkList
& mlMarked
);
323 // send a RequestSelectHint with the currently selected objects
324 bool InsertFormComponent(FmNavRequestSelectHint
& rHint
, SdrObject
* pObject
);
325 // is a helper for previous, manages the ... in SdrObjGroups;
326 // returns sal_True if the object is a FormComponent (or recursively consists only of such)
329 NavigatorTreeModel();
330 virtual ~NavigatorTreeModel() override
;
332 void FillBranch( FmFormData
* pParentData
);
333 void UpdateContent( FmFormShell
* pNewShell
);
335 void Insert(FmEntryData
* pEntryData
, sal_uInt32 nRelPos
= SAL_MAX_UINT32
,
336 bool bAlterModel
= false);
337 void Remove(FmEntryData
* pEntryData
, bool bAlterModel
= false);
339 static bool Rename( FmEntryData
* pEntryData
, const OUString
& rNewText
);
344 css::uno::Reference
< css::form::XForms
> GetForms() const;
345 FmFormShell
* GetFormShell() const { return m_pFormShell
; }
346 FmFormPage
* GetFormPage() const { return m_pFormPage
; }
347 FmEntryData
* FindData( const css::uno::Reference
< css::uno::XInterface
>& xElement
, FmEntryDataList
* pDataList
, bool bRecurs
=true );
348 FmEntryData
* FindData( const OUString
& rText
, FmFormData
const * pParentData
, bool bRecurs
);
349 FmEntryDataList
* GetRootList() const { return m_pRootList
.get(); }
350 static css::uno::Reference
< css::container::XIndexContainer
> GetFormComponents( FmFormData
const * pParentFormData
);
352 virtual void Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
) override
;
357 class NavigatorTreeDropTarget final
: public DropTargetHelper
360 NavigatorTree
& m_rTreeView
;
362 virtual sal_Int8
AcceptDrop( const AcceptDropEvent
& rEvt
) override
;
363 virtual sal_Int8
ExecuteDrop( const ExecuteDropEvent
& rEvt
) override
;
366 NavigatorTreeDropTarget(NavigatorTree
& rTreeView
);
369 typedef std::set
<std::unique_ptr
<weld::TreeIter
>> SvLBoxEntrySortedArray
;
371 class NavigatorTree final
: public SfxListener
373 std::unique_ptr
<weld::TreeView
> m_xTreeView
;
374 NavigatorTreeDropTarget m_aDropTargetHelper
;
376 enum SELDATA_ITEMS
{ SDI_DIRTY
, SDI_ALL
, SDI_NORMALIZED
, SDI_NORMALIZED_FORMARK
};
378 Timer m_aSynchronizeTimer
;
379 // the meta-data about my current selection
380 SvLBoxEntrySortedArray m_arrCurrentSelection
;
381 // the entries which, in the view, are currently marked as "cut" (painted semi-transparent)
382 ListBoxEntrySet m_aCutEntries
;
384 ::svxform::OControlExchangeHelper m_aControlExchange
;
386 std::unique_ptr
<NavigatorTreeModel
> m_pNavModel
;
387 std::unique_ptr
<weld::TreeIter
> m_xRootEntry
;
388 std::unique_ptr
<weld::TreeIter
> m_xEditEntry
;
390 ImplSVEvent
* nEditEvent
;
392 SELDATA_ITEMS m_sdiState
;
394 sal_uInt16 m_nSelectLock
;
395 sal_uInt16 m_nFormsSelected
;
396 sal_uInt16 m_nControlsSelected
;
397 sal_uInt16 m_nHiddenControls
; // (the number is included in m_nControlsSelected)
399 bool m_bDragDataDirty
: 1; // ditto
400 bool m_bPrevSelectionMixed
: 1;
401 bool m_bRootSelected
: 1;
402 bool m_bInitialUpdate
: 1; // am I the first time in the UpdateContent?
403 bool m_bKeyboardCut
: 1;
406 FmControlData
* NewControl(const OUString
& rServiceName
, const weld::TreeIter
& rParentEntry
, bool bEditName
);
407 void NewForm(const weld::TreeIter
& rParentEntry
);
408 std::unique_ptr
<weld::TreeIter
> Insert(const FmEntryData
* pEntryData
, int nRelPos
);
409 void Remove( FmEntryData
* pEntryData
);
412 void CollectSelectionData(SELDATA_ITEMS sdiHow
);
413 // Collects the currently selected entries in m_arrCurrentSelection, normalizes the list if requested.
414 // - SDI_NORMALIZED simply means that all entries that already have a selected ancestor are not collected.
415 // - SDI_NORMALIZED_FORMARK means that the procedure is the same as for SDI_NORMALIZED,
416 // but entries whose direct parent is not selected are collected (independent of the
417 // status of further ancestors). The same applies for forms that are selected,
418 // regardless of the status of any ancestors.
419 // For both normalized modes, the m_nFormsSelected, ... contain the correct number,
420 // even if not all of these entries end up in m_arrCurrentSelection.
421 // SDI_DIRTY is of course not allowed as a parameter.
423 // a single interface for all selected entries
424 void ShowSelectionProperties(bool bForce
= false);
425 // delete all selected elements
426 void DeleteSelection();
428 void SynchronizeSelection(FmEntryDataArray
& arredToSelect
);
429 // after calling this method, exactly the entries marked in the array are selected
430 void SynchronizeSelection();
431 // makes the same, takes the MarkList of the View
432 void SynchronizeMarkList();
433 // reverse direction of SynchronizeMarkList: selects in the view all controls corresponding to the current selection
435 void CollectObjects(FmFormData
const * pFormData
, bool bDeep
, ::std::set
< css::uno::Reference
< css::form::XFormComponent
> >& _rObjects
);
437 // in the Select I usually update the Marklist of the corresponding view,
438 // with the following functions I can control the locking of this behavior
439 void LockSelectionHandling() { ++m_nSelectLock
; }
440 void UnlockSelectionHandling() { --m_nSelectLock
; }
441 bool IsSelectionHandlingLocked() const { return m_nSelectLock
>0; }
443 bool IsEditingActive() const { return m_bEditing
; }
445 static bool IsHiddenControl(FmEntryData
const * pEntryData
);
447 DECL_LINK( KeyInputHdl
, const KeyEvent
&, bool );
448 DECL_LINK( PopupMenuHdl
, const CommandEvent
&, bool );
450 DECL_LINK(EditingEntryHdl
, const weld::TreeIter
&, bool);
451 typedef std::pair
<const weld::TreeIter
&, OUString
> IterString
;
452 DECL_LINK(EditedEntryHdl
, const IterString
&, bool);
454 DECL_LINK( OnEdit
, void*, void );
456 DECL_LINK( OnEntrySelDesel
, weld::TreeView
&, void );
457 DECL_LINK( OnSynchronizeTimer
, Timer
*, void );
459 DECL_LINK( OnClipboardAction
, OLocalExchange
&, void );
461 DECL_LINK( DragBeginHdl
, bool&, bool );
464 NavigatorTree(std::unique_ptr
<weld::TreeView
> xTreeView
);
465 virtual ~NavigatorTree() override
;
468 void UpdateContent( FmFormShell
* pFormShell
);
469 void MarkViewObj( FmFormData
const * pFormData
, bool bDeep
);
470 void MarkViewObj( FmControlData
const * pControlData
);
471 void UnmarkAllViewObj();
473 void GrabFocus() { m_xTreeView
->grab_focus(); }
475 bool IsFormEntry(const weld::TreeIter
& rEntry
);
476 bool IsFormComponentEntry(const weld::TreeIter
& rEntry
);
478 OUString
GenerateName(const FmEntryData
& rEntryData
);
480 NavigatorTreeModel
* GetNavModel() const { return m_pNavModel
.get(); }
481 std::unique_ptr
<weld::TreeIter
> FindEntry(FmEntryData
* pEntryData
);
483 virtual void Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
) override
;
485 weld::TreeView
& get_widget() { return *m_xTreeView
; }
487 sal_Int8
AcceptDrop(const AcceptDropEvent
& rEvt
);
488 sal_Int8
ExecuteDrop(const ExecuteDropEvent
& rEvt
);
491 sal_Int8
implAcceptDataTransfer( const DataFlavorExVector
& _rFlavors
, sal_Int8 _nAction
, const weld::TreeIter
* _pTargetEntry
, bool _bDnD
);
493 sal_Int8
implExecuteDataTransfer( const OControlTransferData
& _rData
, sal_Int8 _nAction
, const Point
& _rDropPos
, bool _bDnD
);
494 sal_Int8
implExecuteDataTransfer( const OControlTransferData
& _rData
, sal_Int8 _nAction
, const weld::TreeIter
* _pTargetEntry
, bool _bDnD
);
496 // check if a cut, copy, or drag operation can be started in the current situation
497 bool implAllowExchange( sal_Int8 _nAction
, bool* _pHasNonHidden
= nullptr );
498 // check if a paste with the current clipboard content can be accepted
499 bool implAcceptPaste( );
501 // fills m_aControlExchange in preparation of a DnD or clipboard operation
502 bool implPrepareExchange( sal_Int8 _nAction
);
504 void ModelHasRemoved(const weld::TreeIter
* _pEntry
);
510 bool doingKeyboardCut( ) const { return m_bKeyboardCut
; }
513 class NavigatorFrame final
: public SfxDockingWindow
, public SfxControllerItem
516 std::unique_ptr
<NavigatorTree
> m_xNavigatorTree
;
518 virtual bool Close() override
;
519 virtual void GetFocus() override
;
520 virtual Size
CalcDockingSize( SfxChildAlignment
) override
;
521 virtual SfxChildAlignment
CheckAlignment( SfxChildAlignment
, SfxChildAlignment
) override
;
523 using SfxDockingWindow::StateChanged
;
526 NavigatorFrame( SfxBindings
*pBindings
, SfxChildWindow
*pMgr
,
527 vcl::Window
* pParent
);
528 virtual ~NavigatorFrame() override
;
529 virtual void dispose() override
;
531 void UpdateContent( FmFormShell
* pFormShell
);
532 void StateChangedAtToolBoxControl( sal_uInt16 nSID
, SfxItemState eState
, const SfxPoolItem
* pState
) override
;
533 void FillInfo( SfxChildWinInfo
& rInfo
) const override
;
536 class UNLESS_MERGELIBS(SVXCORE_DLLPUBLIC
) NavigatorFrameManager final
: public SfxChildWindow
539 SVX_DLLPRIVATE
NavigatorFrameManager( vcl::Window
*pParent
, sal_uInt16 nId
, SfxBindings
*pBindings
,
540 SfxChildWinInfo
*pInfo
);
541 SFX_DECL_CHILDWINDOW( NavigatorFrameManager
);
545 #endif // INCLUDED_SVX_SOURCE_INC_FMEXPL_HXX
547 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */