@@ -75,6 +75,14 @@ QgsLegend::QgsLegend( QWidget * parent, const char *name )
75
75
connect ( QgsProject::instance (), SIGNAL ( writeProject ( QDomDocument & ) ),
76
76
this , SLOT ( writeProject ( QDomDocument & ) ) );
77
77
78
+ // Initialise the line indicator widget.
79
+ mInsertionLine = new QWidget (viewport ());
80
+ hideLine ();
81
+ mInsertionLine ->setAutoFillBackground (true );
82
+ QPalette pal = mInsertionLine ->palette ();
83
+ pal.setColor (mInsertionLine ->backgroundRole (), Qt::blue);
84
+ mInsertionLine ->setPalette (pal);
85
+
78
86
setSortingEnabled ( false );
79
87
setDragEnabled ( false );
80
88
setAutoScroll ( true );
@@ -91,7 +99,9 @@ QgsLegend::QgsLegend( QWidget * parent, const char *name )
91
99
}
92
100
93
101
QgsLegend::~QgsLegend ()
94
- {}
102
+ {
103
+ delete mInsertionLine ;
104
+ }
95
105
96
106
void QgsLegend::handleCurrentItemChanged ( QTreeWidgetItem* current, QTreeWidgetItem* previous )
97
107
{
@@ -237,85 +247,97 @@ void QgsLegend::mouseMoveEvent( QMouseEvent * e )
237
247
238
248
// change the cursor appropriate to if drop is allowed
239
249
QTreeWidgetItem* item = itemAt ( p );
250
+
251
+ hideLine ();
252
+
240
253
QgsLegendItem* origin = dynamic_cast <QgsLegendItem*>( mItemBeingMoved );
241
254
QgsLegendItem* dest = dynamic_cast <QgsLegendItem*>( item );
242
255
243
- if ( !item )
244
- {
245
- setCursor ( QCursor ( Qt::ForbiddenCursor ) );
246
- }
247
-
248
- if ( item && ( item != mItemBeingMoved ) )
256
+ if ( item )
249
257
{
258
+ mDropTarget = item;
250
259
QgsLegendItem::DRAG_ACTION action = dest->accept ( origin );
251
- if ( yCoordAboveCenter ( dest, e-> y () ) ) // over center of item
260
+ if ( item != mItemBeingMoved )
252
261
{
253
- if ( action == QgsLegendItem::REORDER )
262
+ if ( yCoordAboveCenter ( dest, e-> y () ) ) // over center of item
254
263
{
255
- if ( origin->nextSibling () != dest )
264
+ int line_y = visualItemRect (item).top () + 1 ;
265
+ int line_left = visualItemRect (item).left ();
266
+
267
+ if ( action == QgsLegendItem::REORDER || action == QgsLegendItem::INSERT )
256
268
{
257
- moveItem ( dest, origin );setCurrentItem ( origin );
269
+ QgsDebugMsg ( " mouseMoveEvent::INSERT or REORDER" );
270
+ mDropAction = BEFORE;
271
+ showLine ( line_y, line_left);
272
+ setCursor ( QCursor ( Qt::SizeVerCursor ) );
258
273
}
259
- setCurrentItem ( origin );
260
- setCursor ( QCursor ( Qt::SizeVerCursor ) );
261
- }
262
- else if ( action == QgsLegendItem::INSERT )
263
- {
264
- setCursor ( QCursor ( Qt::PointingHandCursor ) );
265
- if ( origin->parent () != dest )
274
+ else // no action
266
275
{
267
- insertItem ( origin, dest );
276
+ QgsDebugMsg ( " mouseMoveEvent::NO_ACTION" );
277
+ mDropAction = NO_ACTION;
278
+ setCursor ( QCursor ( Qt::ForbiddenCursor ) );
268
279
}
269
- setCurrentItem ( origin );
270
- setCursor ( QCursor ( Qt::PointingHandCursor ) );
271
280
}
272
- else // no action
281
+ else // below center of item
273
282
{
274
- QgsDebugMsg ( " mouseMoveEvent::NO_ACTION" );
283
+ int line_y = visualItemRect (item).bottom () - 2 ;
284
+ int line_left = visualItemRect (item).left ();
275
285
276
- if ( origin-> type () == QgsLegendItem::LEGEND_LAYER_FILE && mItemBeingMovedOrigPos != getItemPos ( mItemBeingMoved ) )
286
+ if ( action == QgsLegendItem::REORDER )
277
287
{
278
- resetToInitialPosition ( mItemBeingMoved );
288
+ QgsDebugMsg ( " mouseMoveEvent::REORDER bottom half" );
289
+ mDropAction = AFTER;
290
+ showLine ( line_y, line_left);
291
+ setCursor ( QCursor ( Qt::SizeVerCursor ) );
279
292
}
280
- setCursor ( QCursor ( Qt::ForbiddenCursor ) );
281
- }
282
- }
283
- else // below center of item
284
- {
285
-
286
- if ( action == QgsLegendItem::REORDER )
287
- {
288
- QgsDebugMsg ( " mouseMoveEvent::REORDER bottom half" );
289
- if ( mItemBeingMoved != dest->nextSibling () )
290
- {
291
- // origin->moveItem(dest);
292
- moveItem ( origin, dest );
293
- }
294
- setCursor ( QCursor ( Qt::SizeVerCursor ) );
295
- setCurrentItem ( origin );
296
- }
297
- else if ( action == QgsLegendItem::INSERT )
298
- {
299
- QgsDebugMsg ( " mouseMoveEvent::INSERT" );
300
-
301
- setCursor ( QCursor ( Qt::PointingHandCursor ) );
302
- if ( origin->parent () != dest )
293
+ else if ( action == QgsLegendItem::INSERT )
303
294
{
304
- insertItem ( origin, dest );
305
- setCurrentItem ( origin );
295
+ QgsDebugMsg ( " mouseMoveEvent::INSERT" );
296
+ mDropAction = INTO_GROUP;
297
+ showLine ( line_y, line_left);
298
+ setCursor ( QCursor ( Qt::SizeVerCursor ) );
306
299
}
307
- }
308
- else // no action
309
- {
310
- QgsDebugMsg ( " mouseMoveEvent::NO_ACTION" );
311
-
312
- if ( origin->type () == QgsLegendItem::LEGEND_LAYER_FILE && mItemBeingMovedOrigPos != getItemPos ( mItemBeingMoved ) )
300
+ else // no action
313
301
{
314
- resetToInitialPosition ( mItemBeingMoved );
302
+ mDropAction = NO_ACTION;
303
+ QgsDebugMsg ( " mouseMoveEvent::NO_ACTION" );
304
+ setCursor ( QCursor ( Qt::ForbiddenCursor ) );
315
305
}
316
- setCursor ( QCursor ( Qt::ForbiddenCursor ) );
317
306
}
318
307
}
308
+ else
309
+ {
310
+ setCursor ( QCursor ( Qt::ForbiddenCursor ) );
311
+ }
312
+ }
313
+ else if (!item && e->pos ().y () >= 0 && e->pos ().y () < viewport ()->height () && e->pos ().x () >= 0 && e->pos ().x () < viewport ()->width () )
314
+ {
315
+ // Outside the listed items, but check if we are in the empty area
316
+ // of the viewport, so we can drop after the last top level item.
317
+ QgsDebugMsg ( " You are below the table" );
318
+ mDropTarget = topLevelItem ( topLevelItemCount () - 1 );
319
+ dest = dynamic_cast <QgsLegendItem*>( mDropTarget );
320
+ QgsLegendItem::DRAG_ACTION action = dest->accept ( origin );
321
+ if ( action == QgsLegendItem::REORDER || action == QgsLegendItem::INSERT )
322
+ {
323
+ QgsDebugMsg ( " mouseMoveEvent::INSERT or REORDER" );
324
+ mDropAction = AFTER;
325
+ showLine (visualItemRect ( lastVisibleItem () ).bottom () + 1 , 0 );
326
+ setCursor ( QCursor ( Qt::SizeVerCursor ) );
327
+ }
328
+ else // no action
329
+ {
330
+ QgsDebugMsg ( " mouseMoveEvent::NO_ACTION" );
331
+ mDropAction = NO_ACTION;
332
+ setCursor ( QCursor ( Qt::ForbiddenCursor ) );
333
+ }
334
+ }
335
+
336
+ else
337
+ {
338
+ QgsDebugMsg ( " No item here" );
339
+ mDropTarget = NULL ;
340
+ setCursor ( QCursor ( Qt::ForbiddenCursor ) );
319
341
}
320
342
}
321
343
}
@@ -332,13 +354,15 @@ void QgsLegend::mouseReleaseEvent( QMouseEvent * e )
332
354
return ;
333
355
}
334
356
335
- QTreeWidgetItem *destItem = itemAt ( e->pos () );
357
+ hideLine ();
358
+
359
+ QTreeWidgetItem *destItem = mDropTarget ;
336
360
337
361
QgsLegendItem* origin = dynamic_cast <QgsLegendItem*>( mItemBeingMoved );
338
362
QgsLegendItem* dest = dynamic_cast <QgsLegendItem*>( destItem );
339
363
340
364
// no change?
341
- if ( !dest || !origin )
365
+ if ( !dest || !origin || (dest == origin) )
342
366
{
343
367
checkLayerOrderUpdate ();
344
368
return ;
@@ -404,7 +428,40 @@ void QgsLegend::mouseReleaseEvent( QMouseEvent * e )
404
428
}
405
429
else
406
430
{
431
+ // Do the actual move here.
407
432
QgsDebugMsg ( " Other type of drag'n'drop happened!" );
433
+ if ( mDropAction == AFTER) // over center of item
434
+ {
435
+ QgsDebugMsg ( " Drop AFTER" );
436
+ if ( dest->nextSibling () != origin )
437
+ {
438
+ moveItem ( origin, dest );
439
+ setCurrentItem ( origin );
440
+ }
441
+ }
442
+ else if ( mDropAction == BEFORE )// below center of item
443
+ {
444
+ QgsDebugMsg ( " Drop BEFORE" );
445
+ if ( dest->findYoungerSibling () != origin )
446
+ {
447
+ moveItem ( origin, dest ); // Insert after, as above...
448
+ moveItem ( dest, origin ); // ... and then switch places!
449
+ setCurrentItem ( origin );
450
+ }
451
+ }
452
+ else if ( mDropAction == INTO_GROUP )
453
+ {
454
+ QgsDebugMsg ( " Drop INTO_GROUP" );
455
+ if ( origin->parent () != dest )
456
+ {
457
+ insertItem ( origin, dest );
458
+ setCurrentItem ( origin );
459
+ }
460
+ }
461
+ else // no action
462
+ {
463
+ QgsDebugMsg ( " Drop NO_ACTION" );
464
+ }
408
465
}
409
466
410
467
checkLayerOrderUpdate ();
@@ -1375,6 +1432,9 @@ void QgsLegend::insertItem( QTreeWidgetItem* move, QTreeWidgetItem* into )
1375
1432
1376
1433
void QgsLegend::moveItem ( QTreeWidgetItem* move, QTreeWidgetItem* after )
1377
1434
{
1435
+ QgsDebugMsg ( QString ( " Moving layer : %1 (%2)" ).arg ( move->text ( 0 ) ).arg ( move->type () ) );
1436
+ QgsDebugMsg ( QString ( " after layer : %1 (%2)" ).arg ( after->text ( 0 ) ).arg ( after->type () ) );
1437
+
1378
1438
static_cast <QgsLegendItem*>( move )->storeAppearanceSettings ();// store settings in the moved item and its childern
1379
1439
if ( move->parent () )
1380
1440
{
@@ -1921,3 +1981,26 @@ bool QgsLegend::checkLayerOrderUpdate()
1921
1981
}
1922
1982
return false ;
1923
1983
}
1984
+
1985
+ void QgsLegend::hideLine ()
1986
+ {
1987
+ mInsertionLine ->setGeometry (0 , -100 , 1 , 1 );
1988
+ }
1989
+
1990
+ void QgsLegend::showLine (int y, int left)
1991
+ {
1992
+ mInsertionLine ->setGeometry (left, y, viewport ()->width (), 2 );
1993
+ }
1994
+
1995
+ QTreeWidgetItem * QgsLegend::lastVisibleItem ()
1996
+ {
1997
+ QTreeWidgetItem *current;
1998
+ QTreeWidgetItem *next;
1999
+
2000
+ current = topLevelItem ( topLevelItemCount () - 1 );
2001
+ while ( ( next = itemBelow ( current ) ) )
2002
+ {
2003
+ current = next;
2004
+ }
2005
+ return current;
2006
+ }
0 commit comments