1 /*!
2 	@file
3 	@author		Albert Semenov
4 	@date		10/2008
5 */
6 #ifndef MIRROR_MULTI_LIST_H_
7 #define MIRROR_MULTI_LIST_H_
8 
9 #include "MyGUI.h"
10 #include "Mirror_List.h"
11 
12 namespace unittest
13 {
14 
15 	class Mirror_MultiList
16 	{
17 
18 	private:
19 
20 		struct ColumnInfo
21 		{
22 			Mirror_List* list;
23 			MyGUI::UString name;
24 			MyGUI::Any data;
25 		};
26 
27 		typedef std::vector<ColumnInfo> VectorColumnInfo;
28 
29 		VectorColumnInfo mVectorColumnInfo;
30 
31 	public:
32 
~Mirror_MultiList()33 		~Mirror_MultiList()
34 		{
35 			removeAllColumns();
36 		}
37 
38 		//------------------------------------------------------------------------------//
39 		// манипуляции айтемами
40 
41 		//! Get number of columns
getColumnCount()42 		size_t getColumnCount() const
43 		{
44 			return mVectorColumnInfo.size();
45 		}
46 
47 		/** Insert new column
48 			@param _column New column will be inserted before _column
49 			@param _name Name of new column
50 			@param _width Width of new column
51 		*/
52 		void insertColumnAt(size_t _column, const MyGUI::UString& _name, int _width, MyGUI::Any _data = MyGUI::Any::Null)
53 		{
54 			MYGUI_ASSERT_RANGE_INSERT(_column, mVectorColumnInfo.size(), "MultiListBox::insertColumnAt");
55 			if (_column == MyGUI::ITEM_NONE) _column = mVectorColumnInfo.size();
56 
57 			ColumnInfo column;
58 
59 			column.list = new Mirror_List();
60 			column.name = _name;
61 			column.data = _data;
62 
63 			// если уже были столбики, то делаем то же колличество полей
64 			if (false == mVectorColumnInfo.empty())
65 			{
66 				size_t count = mVectorColumnInfo.front().list->getItemCount();
67 				for (size_t pos = 0; pos < count; ++pos)
68 					column.list->addItem("");
69 			}
70 
71 			mVectorColumnInfo.insert(mVectorColumnInfo.begin() + _column, column);
72 
73 		}
74 
75 		/** Add new column at last position
76 			@param _width Width of new column
77 			@param _name Name of new column
78 		*/
79 		void addColumn(const MyGUI::UString& _name, int _width = 0, MyGUI::Any _data = MyGUI::Any::Null)
80 		{
81 			insertColumnAt(MyGUI::ITEM_NONE, _name, _width, _data);
82 		}
83 
84 		/** Delete column */
removeColumnAt(size_t _column)85 		void removeColumnAt(size_t _column)
86 		{
87 			MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(), "MultiListBox::removeColumnAt");
88 			delete mVectorColumnInfo[_column].list;
89 			mVectorColumnInfo.erase(mVectorColumnInfo.begin() + _column);
90 		}
91 
92 		/** Delete all columns */
removeAllColumns()93 		void removeAllColumns()
94 		{
95 			while (getColumnCount() > 0) removeColumnAt(0);
96 		}
97 
98 
99 		//------------------------------------------------------------------------------//
100 		// манипуляции отображением
101 
102 		/** Set column name
103 			@param _column Index of column
104 			@param _name New name of column
105 		*/
setColumnNameAt(size_t _column,const MyGUI::UString & _name)106 		void setColumnNameAt(size_t _column, const MyGUI::UString& _name)
107 		{
108 			MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(), "MultiListBox::setColumnNameAt");
109 			mVectorColumnInfo[_column].name = _name;
110 		}
111 
112 		/** Get _column name */
getColumnNameAt(size_t _column)113 		const MyGUI::UString& getColumnNameAt(size_t _column)
114 		{
115 			MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(), "MultiListBox::getColumnNameAt");
116 			return mVectorColumnInfo[_column].name;
117 		}
118 
119 		//------------------------------------------------------------------------------//
120 		// манипуляции данными
121 
122 		//! Replace an item data at a specified position
setColumnDataAt(size_t _index,MyGUI::Any _data)123 		void setColumnDataAt(size_t _index, MyGUI::Any _data)
124 		{
125 			MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.size(), "MultiListBox::setColumnDataAt");
126 			mVectorColumnInfo[_index].data = _data;
127 		}
128 
129 		//! Clear an item data at a specified position
clearColumnDataAt(size_t _index)130 		void clearColumnDataAt(size_t _index)
131 		{
132 			setColumnDataAt(_index, MyGUI::Any::Null);
133 		}
134 
135 		//! Get item data from specified position
136 		template <typename ValueType>
137 		ValueType* getColumnDataAt(size_t _index, bool _throw = true)
138 		{
139 			MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.size(), "MultiListBox::getItemDataAt");
140 			return mVectorColumnInfo[_index].data.castType<ValueType>(_throw);
141 		}
142 
143 		//------------------------------------------------------------------------------//
144 		// Methods for work with lines (RU:методы для работы со строками)
145 		/** @note
146 		All indexes used here is indexes of unsorted Multilist. Even if you sorted
147 			it - all items indexes will be same as before sort.*/
148 
149 		//------------------------------------------------------------------------------//
150 		// манипуляции айтемами
151 
152 		/** Get number of items (lines) */
getItemCount()153 		size_t getItemCount() const
154 		{
155 			if (mVectorColumnInfo.empty()) return 0;
156 			return mVectorColumnInfo.front().list->getItemCount();
157 		}
158 
159 		/** Insert new item before _index line */
160 		void insertItemAt(size_t _index, const MyGUI::UString& _name, MyGUI::Any _data = MyGUI::Any::Null)
161 		{
162 			MYGUI_ASSERT(!mVectorColumnInfo.empty(), "MultiListBox::insertItemAt");
163 			MYGUI_ASSERT_RANGE_INSERT(_index, mVectorColumnInfo.front().list->getItemCount(), "MultiListBox::insertItemAt");
164 			if (MyGUI::ITEM_NONE == _index) _index = mVectorColumnInfo.front().list->getItemCount();
165 
166 			// вставляем во все поля пустые, а потом присваиваем первому
167 			for (VectorColumnInfo::iterator iter = mVectorColumnInfo.begin(); iter != mVectorColumnInfo.end(); ++iter)
168 			{
169 				(*iter).list->insertItemAt(_index, "");
170 			}
171 			mVectorColumnInfo.front().list->setItemNameAt(_index, _name);
172 			mVectorColumnInfo.front().list->setItemDataAt(_index, _data);
173 		}
174 
175 		/** Add new item at the end */
176 		void addItem(const MyGUI::UString& _name, MyGUI::Any _data = MyGUI::Any::Null)
177 		{
178 			insertItemAt(MyGUI::ITEM_NONE, _name, _data);
179 		}
180 
removeItemAt(size_t _index)181 		void removeItemAt(size_t _index)
182 		{
183 			MYGUI_ASSERT(!mVectorColumnInfo.empty(), "MultiListBox::removeItemAt");
184 			MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.begin()->list->getItemCount(), "MultiListBox::removeItemAt");
185 
186 			for (VectorColumnInfo::iterator iter = mVectorColumnInfo.begin(); iter != mVectorColumnInfo.end(); ++iter)
187 			{
188 				(*iter).list->removeItemAt(_index);
189 			}
190 		}
191 
192 		/** Delete all items */
removeAllItems()193 		void removeAllItems()
194 		{
195 			while (getItemCount() > 0) removeItemAt(0);
196 		}
197 
swapItemsAt(size_t _index1,size_t _index2)198 		void swapItemsAt(size_t _index1, size_t _index2)
199 		{
200 			MYGUI_ASSERT(!mVectorColumnInfo.empty(), "MultiListBox::swapItemsAt");
201 			MYGUI_ASSERT_RANGE(_index1, mVectorColumnInfo.begin()->list->getItemCount(), "MultiListBox::swapItemsAt");
202 			MYGUI_ASSERT_RANGE(_index2, mVectorColumnInfo.begin()->list->getItemCount(), "MultiListBox::swapItemsAt");
203 
204 			for (VectorColumnInfo::iterator iter = mVectorColumnInfo.begin(); iter != mVectorColumnInfo.end(); ++iter)
205 			{
206 				(*iter).list->swapItemsAt(_index1, _index2);
207 			}
208 		}
209 
210 
211 		//------------------------------------------------------------------------------//
212 		// манипуляции отображением
213 
214 		/** Set item string */
setItemNameAt(size_t _index,const MyGUI::UString & _name)215 		void setItemNameAt(size_t _index, const MyGUI::UString& _name)
216 		{
217 			setSubItemNameAt(0, _index, _name);
218 		}
219 
getItemNameAt(size_t _index)220 		const MyGUI::UString& getItemNameAt(size_t _index)
221 		{
222 			return getSubItemNameAt(0, _index);
223 		}
224 
225 
226 		//------------------------------------------------------------------------------//
227 		// манипуляции данными
228 
229 		//! Replace an item data at a specified position
setItemDataAt(size_t _index,MyGUI::Any _data)230 		void setItemDataAt(size_t _index, MyGUI::Any _data)
231 		{
232 			setSubItemDataAt(0, _index, _data);
233 		}
234 
235 		//! Clear an item data at a specified position
clearItemDataAt(size_t _index)236 		void clearItemDataAt(size_t _index)
237 		{
238 			setItemDataAt(_index, MyGUI::Any::Null);
239 		}
240 
241 		//! Get item data from specified position
242 		template <typename ValueType>
243 		ValueType* getItemDataAt(size_t _index, bool _throw = true)
244 		{
245 			return getSubItemDataAt<ValueType>(0, _index, _throw);
246 		}
247 
248 
249 		//------------------------------------------------------------------------------//
250 		// Methods for work with sub lines (RU:методы для работы со саб строками)
251 		//------------------------------------------------------------------------------//
252 		// манипуляции данными
253 
254 		/** Set sub item
255 			@param _column Index of column
256 			@param _index Index of line
257 			@param _item New sub item value
258 		*/
setSubItemNameAt(size_t _column,size_t _index,const MyGUI::UString & _name)259 		void setSubItemNameAt(size_t _column, size_t _index, const MyGUI::UString& _name)
260 		{
261 			MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(), "MultiListBox::setSubItemAt");
262 			MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.begin()->list->getItemCount(), "MultiListBox::setSubItemAt");
263 
264 			mVectorColumnInfo[_column].list->setItemNameAt(_index, _name);
265 		}
266 
267 		/** Get sub item name*/
getSubItemNameAt(size_t _column,size_t _index)268 		const MyGUI::UString& getSubItemNameAt(size_t _column, size_t _index)
269 		{
270 			MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(), "MultiListBox::getSubItemNameAt");
271 			MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.begin()->list->getItemCount(), "MultiListBox::getSubItemNameAt");
272 
273 			return mVectorColumnInfo[_column].list->getItemNameAt(_index);
274 		}
275 
276 		/** Search item in specified _column, returns index of the first occurrence in column or ITEM_NONE if item not found */
findSubItemWith(size_t _column,const MyGUI::UString & _item)277 		size_t findSubItemWith(size_t _column, const MyGUI::UString& _item)
278 		{
279 			MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(), "MultiListBox::findSubItemWith");
280 			return mVectorColumnInfo[_column].list->findItemIndexWith(_item);
281 		}
282 
283 		//------------------------------------------------------------------------------//
284 		// манипуляции данными
285 
286 		//! Replace an item data at a specified position
setSubItemDataAt(size_t _column,size_t _index,MyGUI::Any _data)287 		void setSubItemDataAt(size_t _column, size_t _index, MyGUI::Any _data)
288 		{
289 			MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(), "MultiListBox::setSubItemDataAt");
290 			MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.begin()->list->getItemCount(), "MultiListBox::setSubItemDataAt");
291 
292 			mVectorColumnInfo[_column].list->setItemDataAt(_index, _data);
293 		}
294 
295 		//! Clear an item data at a specified position
clearSubItemDataAt(size_t _column,size_t _index)296 		void clearSubItemDataAt(size_t _column, size_t _index)
297 		{
298 			setSubItemDataAt(_column, _index, MyGUI::Any::Null);
299 		}
300 
301 		//! Get item data from specified position
302 		template <typename ValueType>
303 		ValueType* getSubItemDataAt(size_t _column, size_t _index, bool _throw = true)
304 		{
305 			MYGUI_ASSERT_RANGE(_column, mVectorColumnInfo.size(), "MultiListBox::getSubItemDataAt");
306 			MYGUI_ASSERT_RANGE(_index, mVectorColumnInfo.begin()->list->getItemCount(), "MultiListBox::getSubItemDataAt");
307 
308 			return mVectorColumnInfo[_column].list->getItemDataAt<ValueType>(_index, _throw);
309 		}
310 
311 	};
312 
313 }
314 
315 #endif // MIRROR_MULTILIST_H_
316