1 //=============================================================================
2 //
3 //   File : KvsObject_treeWidget.cpp
4 //   Creation date : Fri Jan 28 14:21:48 CEST 2005
5 //   by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
6 //
7 //   This file is part of the KVIrc IRC client distribution
8 //   Copyright (C) 2005-2008 Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
9 //
10 //   This program is FREE software. You can redistribute it and/or
11 //   modify it under the terms of the GNU General Public License
12 //   as published by the Free Software Foundation; either version 2
13 //   of the License, or (at your option) any later version.
14 //
15 //   This program 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.
18 //   See the GNU General Public License for more details.
19 //
20 //   You should have received a copy of the GNU General Public License
21 //   along with this program. If not, write to the Free Software Foundation,
22 //   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 //
24 //=============================================================================
25 
26 #include "KvsObject_treeWidget.h"
27 
28 #include "KviError.h"
29 #include "kvi_debug.h"
30 #include "KviLocale.h"
31 #include "KviIconManager.h"
32 #include <QTreeWidget>
33 
34 #include <QEvent>
35 #include <QDragEnterEvent>
36 #include <QDropEvent>
37 #include <QHeaderView>
38 #include <QUrl>
39 #include <QMimeData>
40 
41 /*
42 	@doc: listview
43 	@keyterms:
44 		listview widget class
45 	@title:
46 		listview class
47 	@type:
48 		class
49 	@short:
50 		A listview widget class
51 	@inherits:
52 		[class]widget[/class]
53 	@description:
54 		It can display and control a hierarchy of multi-column items, and provides the ability to add new items at any time.
55 		The items are added by creating children [class]listviewitem[/class] objects: simply allocating them with $new
56 		will add the items to the listview and simply deleting them will remove them.
57 		Allocating a [class]listviewtitem[/class] item2 as a child of item1 will insert it to the same listview creating
58 		a subtree of items spanning from item1. The subtree can be opened or closed by a simple click either
59 		on the parent item or on the little plus sign on the side of it (when [classfnc:listview]$setRootIsDecorated[/classfnc]
60 		is set to $true. The listview can be in Single, Multi, Extended or NoSelection selection mode.[br][br]
61 		In single selection mode there can be only one selected item at a time and the selected item is also
62 		the current item (this mode is the default). In Multi and Extended selection mode there can be multiple selected items
63 		and the current item is one of them. The difference between multi and extended is in the way
64 		that items can be selected by the mouse actions: experiment with the two modes :).
65 		The NoSelection mode has obviously no selection at all.
66 	@functions:
67 		!fn: $addColumn(<text_label:string>,[<width:integer>])
68 		Adds a width pixels wide column with the column header label to the list view.
69 		!fn: $setSorting(<column:integer>,<sort_order:string>)
70 		Sets the list view to be sorted by column in ascending order if sort_order is [i]ascending[/i] or descending order if it is [i]descending[/i].
71 		!fn: $setSortingEnabled(<bEnabled:boolean>)
72 		If <bEnabled> is true, user sorting is enabled for the tree. The default value is false.
73 		In order to avoid performance issues, it is recommended that sorting is enabled after inserting the items into the tree.
74 		!fn: $hideListViewHeader()
75 		Hide the listview column header.
76 		!fn: $showListViewHeader()
77 		Show the listview column header.
78 		!fn: <boolean> $isListViewHeaderVisible()
79 		Returns [b]1[/b] if the listview header is currently visible. Otherwise this function returns [b]0[/b].
80 		!fn: $setAllColumnsShowFocus(<bAllColumnsShowFocus:boolean>)
81 		When the argument is $true, causes the listview to display the focus and selection
82 		by highlighting all the columns of the item. When the argument is $false then
83 		only the first column is selected/highlighted.
84 		!fn: $setSelectionMode(<mode:string>)
85 		Sets the selection mode for this listview. <mode> can be one of [i]Single[/i], [i]NoSelection[/i], [i]Multi[/i] or [i]Extended[/i].
86 		!fn: <listviewitem> $selectedItems()
87 		Returns the currently selected [class]listviewitem[/class] or $null if no items are selected.
88 		This function works only if the list view is in single selection mode.
89 		!fn: <listviewitem:hobject> $itemAt(<x_global_pos:integer>,<y_global_pos:integer>)
90 		Returns the listviewitem object at the x,y globals coordinates or $null if no item at.
91 		!fn: <listviewitem> $currentItem()
92 		Returns the current [class]listviewitem[/class] or $null if no item is current at the moment.
93 		!fn: <listviewitem> $firstChild()
94 		Returns the first child [class]listviewitem[/class] of this listview or $null if there are no items at all.
95 		!fn: <listviewitem> $topLevelItem(<index:int>)
96 		Returns the <index> child [class]listviewitem[/class] of this listview or $null if it does not exist.
97 		!fn: <int> $topLevelItemCount()
98 		Returns the number of top level items of this listview.
99 		!fn: setAcceptDrops(<benabled:boolean>)
100 		If <bEnabled> is true, user can drop files for this listview. The default value is true.
101 		!fn: $clickEvent(<item:object>)
102 		This function is called when the user clicks in the list view.
103 		In its argument the [class]listviewitem[/class] object clicked or 0 if the user didn't click on an item.[br]
104 		The default implementation emits the [classfnc]$clicked[/classfnc]() signal.
105 		!fn: $selectionChangedEvent(<item:object>)
106 		This event handle whenever the set of selected items has changed.
107 		The argument is the newly selected item if the listview is in single selection mode.[br]
108 		When the listview is in multi or extended selection mode then item is always $null.[br]
109 		The default implementation emits the [classfnc]$selectionChanged[/classfnc]() signal.
110 		!fn: $currentChangedEvent(<item:object>)
111 		This event are called whenever the current item has changed.
112 		In its argument is the newly selected item or 0 if the change made no item current.[br]
113 		The default implementation emits the [classfnc]$currentChanged[/classfnc]() signal.
114 		!fn: $itemActivatedEvent(<item:object>)
115 		This signal is emitted when the user activates an item by single- or double-clicking or pressing Enter.[br]
116 		In its argument the current item.[br]
117 		The default implementation emits the [classfnc]$itemActivated[/classfnc]() signal.
118 		!fn: $spacePressedEvent(<item:object>)
119 		This function is called by the framework when the space key is pressed.[br]
120 		In its an argument in the current item.[br]
121 		The default implementation emits the [classfnc]$spacePressed[/classfnc]() signal.
122 		!fn: $onItemEvent(<item:object>)
123 		This event is called by framework when the user moves the mouse cursor onto item.
124 		The default implementation emits the [classfnc]$onItem[/classfnc]() signal.
125 		!fn: $itemExpandedEvent(<item:object>)
126 		This event is called when an item has been expanded, i.e. when the child of an item is shown.
127 		The default implementation emits the [classfnc]$expanded[/classfnc]() signal.
128 		!fn: $itemCollapsedEvent(<item:object>)
129 		This event is called when an item has been collapsed, i.e. when the child of an item is hidden.
130 		The default implementation emits the [classfnc]$collapsed[/classfnc]() signal.
131 		!fn: $itemChangedEvent(<item:object>,<col:integer>,<text:string>)
132 		This event is called when the item has been renamed in text, e.g. by in in-place renaming, in column col.[br]
133 		The default implementation emits the [classfnc]$itemChanged[/classfnc]() signal.
134 	@signals:
135 		!sg: $clicked()
136 		This signal is emitted by the default implementation of [classfnc]$clickEvent[/classfnc]().
137 		!sg: $selectionChanged()
138 		This signal is emitted by the default implementation of [classfnc]$selectionChangedEvent[/classfnc]().
139 		!sg: $currentChanged()
140 		This signal is emitted by the default implementation of [classfnc]$currentChangedEvent[/classfnc]().
141 		!sg: $itemActivated()
142 		This signal is emitted by the default implementation of [classfnc]$itemActivatedEvent[/classfnc]().
143 		!sg: $spacePressed()
144 		This signal is emitted by the default implementation of [classfnc]$spacePressedEvent[/classfnc]().
145 		!sg: $onItem()
146 		This signal is emitted by the default implementation of [classfnc]$onItemEvent[/classfnc]().
147 		!sg: $itemExpanded()
148 		This signal is emitted by the default implementation of [classfnc]$itemExpandedEvent[/classfnc]().
149 		!sg: $itemCollapsed()
150 		This signal is emitted by the default implementation of [classfnc]$itemCollapsedEvent[/classfnc]().
151 		!sg: $itemChanged()
152 		This signal is emitted by the default implementation of [classfnc]$itemChangedEvent[/classfnc]().
153 		!sg: $rightButtonClicked()
154 		This signal is emitted by the default implementation of [classfnc]$rightButtonClickedEvent[/classfnc]().
155 */
156 
157 KVSO_BEGIN_REGISTERCLASS(KvsObject_treeWidget, "listview", "widget")
158 
159 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, setHeaderLabels)
160 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, addColumn)
161 
162 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, setColumnText)
163 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, setColumnCount)
164 
165 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, setSorting)
166 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, setSortingEnabled)
167 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, setRootIsDecorated)
168 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, setAllColumnsShowFocus)
169 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, clear)
170 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, selectedItems)
171 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, currentItem)
172 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, setSelectionMode)
173 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, listViewHeaderIsVisible)
174 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, itemAt)
175 
176 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, hideListViewHeader)
177 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, showListViewHeader)
178 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, firstChild)
179 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, topLevelItem)
180 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, topLevelItemCount)
181 
182 //events
183 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, selectionChangedEvent);
184 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, currentChangedEvent);
185 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, itemActivatedEvent);
186 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, onItemEvent);
187 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, itemClickedEvent);
188 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, itemExpandedEvent);
189 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, itemCollapsedEvent);
190 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, itemChangedEvent);
191 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget, setAcceptDrops);
192 KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KvsObject_treeWidget, "fileDroppedEvent")
193 
KVSO_END_REGISTERCLASS(KvsObject_treeWidget)194 KVSO_END_REGISTERCLASS(KvsObject_treeWidget)
195 
196 KVSO_BEGIN_CONSTRUCTOR(KvsObject_treeWidget, KvsObject_widget)
197 
198 KVSO_END_CONSTRUCTOR(KvsObject_treeWidget)
199 
200 KVSO_BEGIN_DESTRUCTOR(KvsObject_treeWidget)
201 
202 KVSO_END_CONSTRUCTOR(KvsObject_treeWidget)
203 
204 bool KvsObject_treeWidget::init(KviKvsRunTimeContext *, KviKvsVariantList *)
205 {
206 	setObject(new KviKvsTreeWidget(parentScriptWidget(), getName().toUtf8().data(), this), true);
207 	// hack for compatibility with "old" addColumn method;
208 	((QTreeWidget *)widget())->setColumnCount(0);
209 
210 	connect(widget(), SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(slotClicked(QTreeWidgetItem *, int)));
211 	connect(widget(), SIGNAL(itemSelectionChanged()), this, SLOT(slotSelectionChanged()));
212 	connect(widget(), SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(slotCurrentChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
213 	connect(widget(), SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(slotItemActivated(QTreeWidgetItem *, int)));
214 	connect(widget(), SIGNAL(itemEntered(QTreeWidgetItem *, int)), this, SLOT(slotOnItemEntered(QTreeWidgetItem *, int)));
215 	connect(widget(), SIGNAL(itemExpanded(QTreeWidgetItem *)), this, SLOT(slotItemExpanded(QTreeWidgetItem *)));
216 	connect(widget(), SIGNAL(itemCollapsed(QTreeWidgetItem *)), this, SLOT(slotItemCollapsed(QTreeWidgetItem *)));
217 	connect(widget(), SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotItemChanged(QTreeWidgetItem *, int)));
218 	return true;
219 }
220 
KVSO_CLASS_FUNCTION(treeWidget,setHeaderLabels)221 KVSO_CLASS_FUNCTION(treeWidget, setHeaderLabels)
222 {
223 	QStringList columns;
224 	KVSO_PARAMETERS_BEGIN(c)
225 	KVSO_PARAMETER("labels", KVS_PT_STRINGLIST, KVS_PF_OPTIONAL, columns)
226 	KVSO_PARAMETERS_END(c)
227 	if(widget())
228 		((QTreeWidget *)object())->setHeaderLabels(columns);
229 	return true;
230 }
231 
KVSO_CLASS_FUNCTION(treeWidget,setColumnText)232 KVSO_CLASS_FUNCTION(treeWidget, setColumnText)
233 {
234 	if(!widget())
235 		return true;
236 	QString szLabel;
237 	kvs_int_t iCol;
238 	KVSO_PARAMETERS_BEGIN(c)
239 	KVSO_PARAMETER("column", KVS_PT_INT, 0, iCol)
240 	KVSO_PARAMETER("label", KVS_PT_STRING, 0, szLabel)
241 	KVSO_PARAMETERS_END(c)
242 	QTreeWidgetItem * header = ((QTreeWidget *)widget())->headerItem();
243 	header->setText(iCol, szLabel);
244 	return true;
245 }
246 
KVSO_CLASS_FUNCTION(treeWidget,topLevelItem)247 KVSO_CLASS_FUNCTION(treeWidget, topLevelItem)
248 {
249 	if(!widget())
250 		return true;
251 	kvs_int_t iIdx;
252 	KVSO_PARAMETERS_BEGIN(c)
253 	KVSO_PARAMETER("index", KVS_PT_INT, 0, iIdx)
254 	KVSO_PARAMETERS_END(c)
255 	QTreeWidgetItem * pItem = ((QTreeWidget *)widget())->topLevelItem(iIdx);
256 	if(!pItem)
257 		c->returnValue()->setHObject((kvs_hobject_t) nullptr);
258 	else
259 		c->returnValue()->setHObject(KvsObject_treeWidgetItem::itemToHandle(pItem));
260 	return true;
261 }
KVSO_CLASS_FUNCTION(treeWidget,itemAt)262 KVSO_CLASS_FUNCTION(treeWidget, itemAt)
263 {
264 	if(!widget())
265 		return true;
266 	kvs_int_t iXpos, iYpos;
267 	KVSO_PARAMETERS_BEGIN(c)
268 	KVSO_PARAMETER("x_pos", KVS_PT_INT, 0, iXpos)
269 	KVSO_PARAMETER("y_pos", KVS_PT_INT, 0, iYpos)
270 	KVSO_PARAMETERS_END(c)
271 	QPoint pPoint = ((QTreeWidget *)widget())->viewport()->mapFromGlobal(QPoint(iXpos, iYpos));
272 	QTreeWidgetItem * pItem = ((QTreeWidget *)widget())->itemAt(pPoint);
273 	if(!pItem)
274 		c->returnValue()->setHObject((kvs_hobject_t) nullptr);
275 	else
276 		c->returnValue()->setHObject(KvsObject_treeWidgetItem::itemToHandle(pItem));
277 	return true;
278 }
KVSO_CLASS_FUNCTION(treeWidget,topLevelItemCount)279 KVSO_CLASS_FUNCTION(treeWidget, topLevelItemCount)
280 {
281 	if(!widget())
282 		return true;
283 	c->returnValue()->setInteger(((QTreeWidget *)widget())->topLevelItemCount());
284 	return true;
285 }
286 
KVSO_CLASS_FUNCTION(treeWidget,addColumn)287 KVSO_CLASS_FUNCTION(treeWidget, addColumn)
288 {
289 	if(!widget())
290 		return true;
291 	QString szLabel;
292 	kvs_int_t iW;
293 	KVSO_PARAMETERS_BEGIN(c)
294 	KVSO_PARAMETER("label", KVS_PT_STRING, 0, szLabel)
295 	KVSO_PARAMETER("width", KVS_PT_INT, KVS_PF_OPTIONAL, iW)
296 	KVSO_PARAMETERS_END(c)
297 	int col = ((QTreeWidget *)widget())->columnCount();
298 	QTreeWidgetItem * header = ((QTreeWidget *)widget())->headerItem();
299 	header->setText(col, szLabel);
300 	if(iW)
301 		((QTreeWidget *)widget())->setColumnWidth(col, iW);
302 	col++;
303 	((QTreeWidget *)widget())->setColumnCount(col);
304 	//col++;
305 	return true;
306 }
307 
KVSO_CLASS_FUNCTION(treeWidget,setAcceptDrops)308 KVSO_CLASS_FUNCTION(treeWidget, setAcceptDrops)
309 {
310 	bool bEnable;
311 	KVSO_PARAMETERS_BEGIN(c)
312 	KVSO_PARAMETER("bEnable", KVS_PT_BOOLEAN, 0, bEnable)
313 	KVSO_PARAMETERS_END(c)
314 	if(widget())
315 		((QTreeWidget *)object())->setAcceptDrops(bEnable);
316 	return true;
317 }
318 
KVSO_CLASS_FUNCTION(treeWidget,clear)319 KVSO_CLASS_FUNCTION(treeWidget, clear)
320 {
321 	if(widget())
322 		((QTreeWidget *)object())->clear();
323 	return true;
324 }
325 
KVSO_CLASS_FUNCTION(treeWidget,selectedItems)326 KVSO_CLASS_FUNCTION(treeWidget, selectedItems)
327 {
328 	if(widget())
329 	{
330 		QList<QTreeWidgetItem *> list = ((QTreeWidget *)widget())->selectedItems();
331 		KviKvsArray * pArray = new KviKvsArray();
332 		c->returnValue()->setArray(pArray);
333 		for(int i = 0; i < list.count(); i++)
334 			pArray->set(i, new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle((QTreeWidgetItem *)list.at(i))));
335 	}
336 	else
337 		c->returnValue()->setHObject((kvs_hobject_t) nullptr);
338 	return true;
339 }
340 
KVSO_CLASS_FUNCTION(treeWidget,firstChild)341 KVSO_CLASS_FUNCTION(treeWidget, firstChild)
342 {
343 	if(widget())
344 		c->returnValue()->setHObject(KvsObject_treeWidgetItem::itemToHandle((QTreeWidgetItem *)((QTreeWidget *)widget())->topLevelItem(0)));
345 	else
346 		c->returnValue()->setHObject((kvs_hobject_t) nullptr);
347 	return true;
348 }
349 
KVSO_CLASS_FUNCTION(treeWidget,currentItem)350 KVSO_CLASS_FUNCTION(treeWidget, currentItem)
351 {
352 	if(widget())
353 		c->returnValue()->setHObject(KvsObject_treeWidgetItem::itemToHandle((QTreeWidgetItem *)((QTreeWidget *)widget())->currentItem()));
354 	else
355 		c->returnValue()->setHObject((kvs_hobject_t) nullptr);
356 	return true;
357 }
358 
KVSO_CLASS_FUNCTION(treeWidget,setColumnCount)359 KVSO_CLASS_FUNCTION(treeWidget, setColumnCount)
360 {
361 	kvs_uint_t uCol;
362 	KVSO_PARAMETERS_BEGIN(c)
363 	KVSO_PARAMETER("column", KVS_PT_UNSIGNEDINTEGER, 0, uCol)
364 	KVSO_PARAMETERS_END(c)
365 	if(widget())
366 		((QTreeWidget *)widget())->setColumnCount(uCol);
367 	return true;
368 }
369 
KVSO_CLASS_FUNCTION(treeWidget,setSelectionMode)370 KVSO_CLASS_FUNCTION(treeWidget, setSelectionMode)
371 {
372 	QString szMode;
373 	KVSO_PARAMETERS_BEGIN(c)
374 	KVSO_PARAMETER("mode", KVS_PT_NONEMPTYSTRING, 0, szMode)
375 	KVSO_PARAMETERS_END(c)
376 	if(!widget())
377 		return true;
378 	if(KviQString::equalCI(szMode, "NoSelection"))
379 		((QTreeWidget *)widget())->setSelectionMode(QAbstractItemView::NoSelection);
380 	else if(KviQString::equalCI(szMode, "Multi"))
381 		((QTreeWidget *)widget())->setSelectionMode(QTreeWidget::MultiSelection);
382 	else if(KviQString::equalCI(szMode, "Extended"))
383 		((QTreeWidget *)widget())->setSelectionMode(QTreeWidget::ExtendedSelection);
384 	else if(KviQString::equalCI(szMode, "Single"))
385 		((QTreeWidget *)widget())->setSelectionMode(QTreeWidget::SingleSelection);
386 	else
387 		c->warning(__tr2qs_ctx("Invalid selection mode '%Q'", "objects"), &szMode);
388 	return true;
389 }
390 
KVSO_CLASS_FUNCTION(treeWidget,setSorting)391 KVSO_CLASS_FUNCTION(treeWidget, setSorting)
392 {
393 	kvs_int_t iCol;
394 	QString szOrder;
395 	KVSO_PARAMETERS_BEGIN(c)
396 	KVSO_PARAMETER("column", KVS_PT_INT, 0, iCol)
397 	KVSO_PARAMETER("sort_order", KVS_PT_STRING, 0, szOrder)
398 	KVSO_PARAMETERS_END(c)
399 	if(!widget())
400 		return true;
401 	if(KviQString::equalCI(szOrder, "ascending"))
402 		((QTreeWidget *)widget())->sortItems(iCol, Qt::AscendingOrder);
403 	else if(KviQString::equalCI(szOrder, "descending"))
404 		((QTreeWidget *)widget())->sortItems(iCol, Qt::DescendingOrder);
405 	else
406 		c->warning(__tr2qs_ctx("Unknown '%Q' sort order: switching to ascending order", "objects"), &szOrder);
407 	return true;
408 }
KVSO_CLASS_FUNCTION(treeWidget,setSortingEnabled)409 KVSO_CLASS_FUNCTION(treeWidget, setSortingEnabled)
410 {
411 	bool bEnables;
412 	KVSO_PARAMETERS_BEGIN(c)
413 	KVSO_PARAMETER("bEnables", KVS_PT_BOOLEAN, 0, bEnables)
414 	KVSO_PARAMETERS_END(c)
415 	if(!widget())
416 		return true;
417 	((QTreeWidget *)widget())->setSortingEnabled(bEnables);
418 	return true;
419 }
420 
KVSO_CLASS_FUNCTION(treeWidget,setRootIsDecorated)421 KVSO_CLASS_FUNCTION(treeWidget, setRootIsDecorated)
422 {
423 	bool bEnabled;
424 	KVSO_PARAMETERS_BEGIN(c)
425 	KVSO_PARAMETER("bEnabled", KVS_PT_BOOL, 0, bEnabled)
426 	KVSO_PARAMETERS_END(c)
427 	if(widget())
428 		((QTreeWidget *)widget())->setRootIsDecorated(bEnabled);
429 	return true;
430 }
431 
KVSO_CLASS_FUNCTION(treeWidget,setAllColumnsShowFocus)432 KVSO_CLASS_FUNCTION(treeWidget, setAllColumnsShowFocus)
433 {
434 	bool bEnabled;
435 	KVSO_PARAMETERS_BEGIN(c)
436 	KVSO_PARAMETER("bAllColumnsShowFocus", KVS_PT_BOOL, 0, bEnabled)
437 	KVSO_PARAMETERS_END(c)
438 	if(widget())
439 		((QTreeWidget *)widget())->setAllColumnsShowFocus(bEnabled);
440 	return true;
441 }
442 
KVSO_CLASS_FUNCTION(treeWidget,hideListViewHeader)443 KVSO_CLASS_FUNCTION(treeWidget, hideListViewHeader)
444 {
445 	((QTreeWidget *)widget())->header()->hide();
446 	return true;
447 }
448 
KVSO_CLASS_FUNCTION(treeWidget,showListViewHeader)449 KVSO_CLASS_FUNCTION(treeWidget, showListViewHeader)
450 {
451 	((QTreeWidget *)widget())->header()->show();
452 	return true;
453 }
454 
KVSO_CLASS_FUNCTION(treeWidget,listViewHeaderIsVisible)455 KVSO_CLASS_FUNCTION(treeWidget, listViewHeaderIsVisible)
456 {
457 	c->returnValue()->setBoolean(((QTreeWidget *)widget())->header()->isVisible());
458 	return true;
459 }
460 
KVSO_CLASS_FUNCTION(treeWidget,itemClickedEvent)461 KVSO_CLASS_FUNCTION(treeWidget, itemClickedEvent)
462 {
463 	emitSignal("itemClicked", c, c->params());
464 	return true;
465 }
466 
slotClicked(QTreeWidgetItem * i,int col)467 void KvsObject_treeWidget::slotClicked(QTreeWidgetItem * i, int col)
468 {
469 	KviKvsVariant * column = new KviKvsVariant((kvs_int_t)col);
470 
471 	KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(i)), column);
472 	callFunction(this, "itemClickedEvent", nullptr, &params);
473 }
474 
KVSO_CLASS_FUNCTION(treeWidget,selectionChangedEvent)475 KVSO_CLASS_FUNCTION(treeWidget, selectionChangedEvent)
476 {
477 	emitSignal("selectionChanged", c, c->params());
478 	return true;
479 }
480 
slotSelectionChanged()481 void KvsObject_treeWidget::slotSelectionChanged()
482 {
483 	if(((QTreeWidget *)widget())->selectionMode() == QTreeWidget::SingleSelection)
484 	{
485 		QTreeWidgetItem * it = (QTreeWidgetItem *)((QTreeWidget *)widget())->currentItem();
486 		KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(it)));
487 		callFunction(this, "selectionChangedEvent", nullptr, &params);
488 	}
489 	else
490 	{
491 		KviKvsVariantList params(new KviKvsVariant((kvs_hobject_t) nullptr));
492 		callFunction(this, "selectionChangedEvent", nullptr, &params);
493 	}
494 }
495 
KVSO_CLASS_FUNCTION(treeWidget,currentChangedEvent)496 KVSO_CLASS_FUNCTION(treeWidget, currentChangedEvent)
497 {
498 	emitSignal("currentChanged", c, c->params());
499 	return true;
500 }
501 
slotCurrentChanged(QTreeWidgetItem * i,QTreeWidgetItem * prev)502 void KvsObject_treeWidget::slotCurrentChanged(QTreeWidgetItem * i, QTreeWidgetItem * prev)
503 {
504 	KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(i)), new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(prev)));
505 	callFunction(this, "currentChangedEvent", nullptr, &params);
506 }
507 
KVSO_CLASS_FUNCTION(treeWidget,itemActivatedEvent)508 KVSO_CLASS_FUNCTION(treeWidget, itemActivatedEvent)
509 {
510 	emitSignal("itemActivated", c, c->params());
511 	return true;
512 }
513 
slotItemActivated(QTreeWidgetItem * i,int col)514 void KvsObject_treeWidget::slotItemActivated(QTreeWidgetItem * i, int col)
515 {
516 	KviKvsVariant * column = new KviKvsVariant((kvs_int_t)col);
517 	KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(i)), column);
518 	callFunction(this, "itemActivatedEvent", nullptr, &params);
519 }
520 
KVSO_CLASS_FUNCTION(treeWidget,onItemEvent)521 KVSO_CLASS_FUNCTION(treeWidget, onItemEvent)
522 {
523 	emitSignal("onItem", c, c->params());
524 	return true;
525 }
526 
slotOnItemEntered(QTreeWidgetItem * i,int col)527 void KvsObject_treeWidget::slotOnItemEntered(QTreeWidgetItem * i, int col)
528 {
529 	KviKvsVariant * column = new KviKvsVariant((kvs_int_t)col);
530 
531 	KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(i)), column);
532 	callFunction(this, "onItemEvent", nullptr, &params);
533 }
534 
KVSO_CLASS_FUNCTION(treeWidget,itemExpandedEvent)535 KVSO_CLASS_FUNCTION(treeWidget, itemExpandedEvent)
536 {
537 	emitSignal("itemExpanded", c, c->params());
538 	return true;
539 }
540 
slotItemExpanded(QTreeWidgetItem * i)541 void KvsObject_treeWidget::slotItemExpanded(QTreeWidgetItem * i)
542 {
543 	KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(i)));
544 	callFunction(this, "itemExpandedEvent", nullptr, &params);
545 }
546 
KVSO_CLASS_FUNCTION(treeWidget,itemCollapsedEvent)547 KVSO_CLASS_FUNCTION(treeWidget, itemCollapsedEvent)
548 {
549 	emitSignal("itemCollapsed", c, c->params());
550 	return true;
551 }
552 
slotItemCollapsed(QTreeWidgetItem * i)553 void KvsObject_treeWidget::slotItemCollapsed(QTreeWidgetItem * i)
554 {
555 	KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(i)));
556 	callFunction(this, "itemCollapsedEvent", nullptr, &params);
557 }
558 
KVSO_CLASS_FUNCTION(treeWidget,itemChangedEvent)559 KVSO_CLASS_FUNCTION(treeWidget, itemChangedEvent)
560 {
561 	emitSignal("itemChanged", c, c->params());
562 	return true;
563 }
564 
slotItemChanged(QTreeWidgetItem * item,int col)565 void KvsObject_treeWidget::slotItemChanged(QTreeWidgetItem * item, int col)
566 {
567 	KviKvsVariant * column = new KviKvsVariant((kvs_int_t)col);
568 	KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(item)), column);
569 	callFunction(this, "itemChangedEvent", nullptr, &params);
570 }
571 
fileDropped(QString & szFile,QTreeWidgetItem * item)572 void KvsObject_treeWidget::fileDropped(QString & szFile, QTreeWidgetItem * item)
573 {
574 	KviKvsVariant * file = new KviKvsVariant(szFile);
575 	KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(item)), file);
576 	callFunction(this, "fileDroppedEvent", nullptr, &params);
577 }
578 
KviKvsTreeWidget(QWidget * par,const char *,KvsObject_treeWidget * parent)579 KviKvsTreeWidget::KviKvsTreeWidget(QWidget * par, const char *, KvsObject_treeWidget * parent)
580     : QTreeWidget(par)
581 {
582 	m_pParentScript = parent;
583 	setAcceptDrops(true);
584 	setDragEnabled(true);
585 	setDropIndicatorShown(true);
586 	setDragDropMode(QAbstractItemView::DragDrop);
587 	viewport()->setAcceptDrops(true);
588 }
589 
590 KviKvsTreeWidget::~KviKvsTreeWidget()
591     = default;
592 
dragEnterEvent(QDragEnterEvent * e)593 void KviKvsTreeWidget::dragEnterEvent(QDragEnterEvent * e)
594 {
595 	if(!e->mimeData()->hasUrls())
596 	{
597 		e->ignore();
598 		return;
599 	}
600 	e->acceptProposedAction();
601 }
602 
dragMoveEvent(QDragMoveEvent *)603 void KviKvsTreeWidget::dragMoveEvent(QDragMoveEvent *)
604 {
605 	// ?#!
606 }
607 
dropEvent(QDropEvent * e)608 void KviKvsTreeWidget::dropEvent(QDropEvent * e)
609 {
610 	qDebug("Drop event");
611 	QList<QUrl> list;
612 	if(e->mimeData()->hasUrls())
613 	{
614 		list = e->mimeData()->urls();
615 
616 		if(!list.isEmpty())
617 		{
618 			QList<QUrl>::Iterator it = list.begin();
619 			for(; it != list.end(); ++it)
620 			{
621 				QUrl url = *it;
622 				QString path = url.toLocalFile();
623 				qDebug("path %s", path.toUtf8().data());
624 				QTreeWidgetItem * i = itemAt(e->pos());
625 				m_pParentScript->fileDropped(path, i);
626 			}
627 		}
628 	}
629 }
630