1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef _FRM_GROUPMANAGER_HXX_
29 #define _FRM_GROUPMANAGER_HXX_
30 
31 #include <com/sun/star/sdbc/XRowSet.hpp>
32 #include <com/sun/star/awt/XControlModel.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/beans/XPropertyChangeListener.hpp>
35 #include <com/sun/star/container/XContainerListener.hpp>
36 #include <com/sun/star/container/XContainer.hpp>
37 #include <comphelper/stl_types.hxx>
38 #include <cppuhelper/implbase2.hxx>
39 #include <comphelper/stl_types.hxx>
40 #include <comphelper/types.hxx>
41 using namespace comphelper;
42 
43 /*========================================================================
44 Funktionsweise GroupManager:
45 
46 Der GroupManager horcht an der starform, ob FormComponents eingefuegt oder entfernt
47 werden. Zusaetzlich horcht er bei den FormComponents an den Properties
48 "Name" und "TabIndex". Mit diesen Infos aktualisiert er seine Gruppen.
49 
50 Der GroupManager verwaltet eine Gruppe, in der alle Controls nach TabIndex
51 geordnet sind, und ein Array von Gruppen, in dem jede FormComponent noch
52 einmal einer Gruppe dem Namen nach zugeordnet wird.
53 Die einzelnen Gruppen werden ueber eine Map aktiviert, wenn sie mehr als
54 ein Element besitzen.
55 
56 Die Gruppen verwalten intern die FormComponents in zwei Arrays. In dem
57 GroupCompArray werden die Components nach TabIndex und Einfuegepostion
58 sortiert. Da auf dieses Array ueber die FormComponent zugegriffen
59 wird, gibt es noch das GroupCompAccessArray, in dem die FormComponents
60 nach ihrer Speicheradresse sortiert sind. Jedes Element des
61 GroupCompAccessArrays ist mit einem Element des GroupCompArrays verpointert.
62 
63 ========================================================================*/
64 
65 //.........................................................................
66 namespace frm
67 {
68 //.........................................................................
69 
70 //========================================================================
71 	template <class ELEMENT, class LESS_COMPARE>
72 	sal_Int32 insert_sorted(::std::vector<ELEMENT>& _rArray, const ELEMENT& _rNewElement, const LESS_COMPARE& _rCompareOp)
73 	{
74 		typename ::std::vector<ELEMENT>::iterator aInsertPos = lower_bound(
75 			_rArray.begin(),
76 			_rArray.end(),
77 			_rNewElement,
78 			_rCompareOp
79 		);
80 		aInsertPos = _rArray.insert(aInsertPos, _rNewElement);
81 		return aInsertPos - _rArray.begin();
82 	}
83 
84 	template <class ELEMENT, class LESS_COMPARE>
85 	sal_Bool seek_entry(const ::std::vector<ELEMENT>& _rArray, const ELEMENT& _rNewElement, sal_Int32& nPos, const LESS_COMPARE& _rCompareOp)
86 	{
87 		typename ::std::vector<ELEMENT>::const_iterator aExistentPos = lower_bound(
88 			_rArray.begin(),
89 			_rArray.end(),
90 			_rNewElement,
91 			_rCompareOp
92 		);
93 		if ((aExistentPos != _rArray.end()) && (*aExistentPos == _rNewElement))
94 		{	// we have a valid "lower or equal" element and it's really "equal"
95 			nPos = aExistentPos - _rArray.begin();
96 			return sal_True;
97 		}
98 		nPos = -1;
99 		return sal_False;
100 	}
101 
102 //========================================================================
103 class OGroupComp
104 {
105 	::rtl::OUString	m_aName;
106 	::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> 	m_xComponent;
107 	::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> 	m_xControlModel;
108 	sal_Int32	m_nPos;
109 	sal_Int16	m_nTabIndex;
110 
111 	friend class OGroupCompLess;
112 
113 public:
114 	OGroupComp(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement, sal_Int32 nInsertPos );
115 	OGroupComp(const OGroupComp& _rSource);
116 	OGroupComp();
117 
118 	sal_Bool operator==( const OGroupComp& rComp ) const;
119 
120 	inline const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& GetComponent() const { return m_xComponent; }
121 	inline const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel>&	GetControlModel() const { return m_xControlModel; }
122 
123 	sal_Int32	GetPos() const { return m_nPos; }
124 	sal_Int16	GetTabIndex() const { return m_nTabIndex; }
125 	::rtl::OUString GetName() const { return m_aName; }
126 };
127 
128 DECLARE_STL_VECTOR(OGroupComp, OGroupCompArr);
129 
130 //========================================================================
131 class OGroupComp;
132 class OGroupCompAcc
133 {
134 	::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> 	m_xComponent;
135 
136 	OGroupComp										m_aGroupComp;
137 
138 	friend class OGroupCompAccLess;
139 
140 public:
141 	OGroupCompAcc(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement, const OGroupComp& _rGroupComp );
142 
143 	sal_Bool operator==( const OGroupCompAcc& rCompAcc ) const;
144 
145 	inline const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>&	GetComponent() const { return m_xComponent; }
146 	const OGroupComp&	GetGroupComponent() const { return m_aGroupComp; }
147 };
148 
149 DECLARE_STL_VECTOR(OGroupCompAcc, OGroupCompAccArr);
150 
151 //========================================================================
152 class OGroup
153 {
154 	OGroupCompArr		m_aCompArray;
155 	OGroupCompAccArr	m_aCompAccArray;
156 
157 	::rtl::OUString m_aGroupName;
158 	sal_uInt16	m_nInsertPos;				// Die Einfugeposition der GroupComps wird von der Gruppe bestimmt.
159 
160 	friend class OGroupLess;
161 
162 public:
163 	OGroup( const ::rtl::OUString& rGroupName );
164 #ifdef DBG_UTIL
165 	OGroup( const OGroup& _rSource );	// just to ensure the DBG_CTOR call
166 #endif
167 	virtual ~OGroup();
168 
169 	sal_Bool operator==( const OGroup& rGroup ) const;
170 
171 	::rtl::OUString GetGroupName() const { return m_aGroupName; }
172 	::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel>  > GetControlModels() const;
173 
174 	void InsertComponent( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
175 	void RemoveComponent( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
176 	sal_uInt16 Count() const { return sal::static_int_cast< sal_uInt16 >(m_aCompArray.size()); }
177 	const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& GetObject( sal_uInt16 nP ) const
178 		{ return m_aCompArray[nP].GetComponent(); }
179 };
180 
181 DECLARE_STL_USTRINGACCESS_MAP(OGroup, OGroupArr);
182 DECLARE_STL_VECTOR(OGroupArr::iterator, OActiveGroups);
183 
184 //========================================================================
185 class OGroupManager	: public ::cppu::WeakImplHelper2< ::com::sun::star::beans::XPropertyChangeListener, ::com::sun::star::container::XContainerListener>
186 {
187 	OGroup*			m_pCompGroup;			// Alle Components nach TabIndizes sortiert
188 	OGroupArr		m_aGroupArr;			// Alle Components nach Gruppen sortiert
189 	OActiveGroups	m_aActiveGroupMap;		// In dieser Map werden die Indizes aller Gruppen gehalten,
190 										// die mehr als 1 Element haben
191 
192 	::com::sun::star::uno::Reference< ::com::sun::star::container::XContainer >
193 					m_xContainer;
194 
195 	// Helper functions
196 	void InsertElement( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
197 	void RemoveElement( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& rxElement );
198 	void removeFromGroupMap(const ::rtl::OUString& _sGroupName,const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _xSet);
199 
200 public:
201 	OGroupManager(const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainer >& _rxContainer);
202 	virtual ~OGroupManager();
203 
204 // ::com::sun::star::lang::XEventListener
205 	virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource) throw(::com::sun::star::uno::RuntimeException);
206 
207 // ::com::sun::star::beans::XPropertyChangeListener
208 	virtual void SAL_CALL propertyChange(const ::com::sun::star::beans::PropertyChangeEvent& evt) throw ( ::com::sun::star::uno::RuntimeException);
209 
210 // ::com::sun::star::container::XContainerListener
211 	virtual void SAL_CALL elementInserted(const ::com::sun::star::container::ContainerEvent& _rEvent) throw ( ::com::sun::star::uno::RuntimeException);
212 	virtual void SAL_CALL elementRemoved(const ::com::sun::star::container::ContainerEvent& _rEvent) throw ( ::com::sun::star::uno::RuntimeException);
213 	virtual void SAL_CALL elementReplaced(const ::com::sun::star::container::ContainerEvent& _rEvent) throw ( ::com::sun::star::uno::RuntimeException);
214 
215 // Other functions
216 	sal_Int32 getGroupCount();
217 	void getGroup(sal_Int32 nGroup, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> >& _rGroup, ::rtl::OUString& Name);
218 	void getGroupByName(const ::rtl::OUString& Name, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> >& _rGroup);
219 	::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel> > getControlModels();
220 };
221 
222 
223 //.........................................................................
224 }	// namespace frm
225 //.........................................................................
226 
227 #endif // _FRM_GROUPMANAGER_HXX_
228 
229