47 |
47 |
|
48 |
48 |
const int AUTOSCROLL_MARGIN = 16;
|
49 |
49 |
|
50 |
|
/**
|
51 |
|
@note
|
52 |
|
|
53 |
|
set mItemBeingMoved pointer to 0 to prevent SuSE 9.0 crash
|
54 |
|
*/
|
55 |
50 |
QgsLegend::QgsLegend( QgsMapCanvas *canvas, QWidget * parent, const char *name )
|
56 |
|
: QTreeWidget( parent ),
|
57 |
|
mMousePressedFlag( false ),
|
58 |
|
mItemBeingMoved( 0 ),
|
59 |
|
mMapCanvas( canvas ),
|
60 |
|
mMinimumIconSize( 20, 20 )
|
|
51 |
: QTreeWidget( parent )
|
|
52 |
, mMousePressedFlag( false )
|
|
53 |
, mMapCanvas( canvas )
|
|
54 |
, mMinimumIconSize( 20, 20 )
|
61 |
55 |
{
|
62 |
56 |
setObjectName( name );
|
63 |
57 |
|
... | ... | |
128 |
122 |
{
|
129 |
123 |
if ( name.isEmpty() )
|
130 |
124 |
name = tr( "group" ); // some default name if none specified
|
131 |
|
QgsLegendGroup* group = new QgsLegendGroup( this, name );
|
|
125 |
|
|
126 |
QgsLegendGroup *parent = dynamic_cast<QgsLegendGroup *>( currentItem() );
|
|
127 |
|
|
128 |
QgsLegendGroup *group;
|
|
129 |
if ( parent )
|
|
130 |
group = new QgsLegendGroup( parent, name );
|
|
131 |
else
|
|
132 |
group = new QgsLegendGroup( this, name );
|
|
133 |
|
132 |
134 |
group->setData( 0, Qt::UserRole, Qt::Checked );
|
133 |
135 |
QModelIndex groupIndex = indexFromItem( group );
|
134 |
136 |
setExpanded( groupIndex, expand );
|
|
137 |
setCurrentItem( group );
|
|
138 |
openEditor();
|
135 |
139 |
return groupIndex.row();
|
136 |
140 |
}
|
137 |
141 |
|
... | ... | |
142 |
146 |
mPixmapHeightValues.clear();
|
143 |
147 |
updateMapCanvasLayerSet();
|
144 |
148 |
setIconSize( mMinimumIconSize );
|
145 |
|
mItemBeingMoved = 0;
|
146 |
149 |
mDropTarget = 0;
|
147 |
150 |
}
|
148 |
151 |
|
... | ... | |
162 |
165 |
QgsLegendItem* litem = dynamic_cast<QgsLegendItem *>( theItem );
|
163 |
166 |
if ( litem && litem->type() == QgsLegendItem::LEGEND_LAYER )
|
164 |
167 |
{
|
165 |
|
theItem->setCheckState( 0, ( select ? Qt::Checked : Qt::Unchecked ) );
|
|
168 |
theItem->setCheckState( 0, select ? Qt::Checked : Qt::Unchecked );
|
166 |
169 |
handleItemChange( theItem, 0 );
|
167 |
170 |
}
|
168 |
171 |
}
|
... | ... | |
212 |
215 |
{
|
213 |
216 |
if ( e->button() == Qt::LeftButton )
|
214 |
217 |
{
|
215 |
|
mLastPressPos = e->pos();
|
216 |
218 |
mMousePressedFlag = true;
|
|
219 |
mDropTarget = itemAt( e->pos() );
|
217 |
220 |
}
|
218 |
221 |
else if ( e->button() == Qt::RightButton )
|
219 |
222 |
{
|
... | ... | |
230 |
233 |
|
231 |
234 |
void QgsLegend::mouseMoveEvent( QMouseEvent * e )
|
232 |
235 |
{
|
233 |
|
if ( mMousePressedFlag )
|
|
236 |
if ( !mMousePressedFlag )
|
234 |
237 |
{
|
235 |
|
//set the flag back such that the else if(mItemBeingMoved)
|
236 |
|
//code part is passed during the next mouse moves
|
237 |
|
mMousePressedFlag = false;
|
|
238 |
QgsDebugMsg( "mouse not pressed" );
|
|
239 |
return;
|
|
240 |
}
|
238 |
241 |
|
239 |
|
// remember item we've pressed as the one being moved
|
240 |
|
// and where it was originally
|
241 |
|
QTreeWidgetItem* item = itemAt( mLastPressPos );
|
242 |
|
if ( item )
|
|
242 |
|
|
243 |
if ( mItemsBeingMoved.isEmpty() && !selectedItems().isEmpty() )
|
|
244 |
{
|
|
245 |
if ( mDropTarget == itemAt( e->pos() ) )
|
|
246 |
return;
|
|
247 |
|
|
248 |
mLayersPriorToMove = layerIDs();
|
|
249 |
QgsDebugMsg( "layers prior to move: " + mLayersPriorToMove.join( ", " ) );
|
|
250 |
|
|
251 |
// record which items were selected and hide them
|
|
252 |
foreach( QTreeWidgetItem *item, selectedItems() )
|
243 |
253 |
{
|
244 |
|
mItemBeingMoved = item;
|
245 |
|
mItemBeingMovedOrigPos = getItemPos( mItemBeingMoved );
|
|
254 |
item->setHidden( true );
|
|
255 |
mItemsBeingMoved << item;
|
|
256 |
}
|
246 |
257 |
|
247 |
|
//store information to insert the item back to the original position
|
248 |
|
storeInitialPosition( mItemBeingMoved );
|
|
258 |
// remove and unhide items, whose parent is already to be moved
|
|
259 |
foreach( QTreeWidgetItem *item, mItemsBeingMoved )
|
|
260 |
{
|
|
261 |
QTreeWidgetItem *parent = item->parent();
|
249 |
262 |
|
250 |
|
setCursor( Qt::SizeVerCursor );
|
|
263 |
bool parentHidden = false;
|
|
264 |
while ( !parentHidden && parent )
|
|
265 |
{
|
|
266 |
parentHidden = parent->isHidden();
|
|
267 |
parent = parent->parent();
|
|
268 |
}
|
|
269 |
|
|
270 |
if ( parentHidden )
|
|
271 |
{
|
|
272 |
mItemsBeingMoved.removeOne( item );
|
|
273 |
item->setHidden( false );
|
|
274 |
}
|
251 |
275 |
}
|
|
276 |
|
|
277 |
setCursor( Qt::SizeVerCursor );
|
252 |
278 |
}
|
253 |
|
else if ( mItemBeingMoved )
|
|
279 |
|
|
280 |
if ( mItemsBeingMoved.isEmpty() )
|
254 |
281 |
{
|
255 |
|
QPoint p( e->pos() );
|
256 |
|
mLastPressPos = p;
|
|
282 |
QgsDebugMsg( "nothing to move" );
|
|
283 |
return;
|
|
284 |
}
|
257 |
285 |
|
258 |
|
// change the cursor appropriate to if drop is allowed
|
259 |
|
QTreeWidgetItem* item = itemAt( p );
|
|
286 |
// change the cursor appropriate to if drop is allowed
|
|
287 |
QTreeWidgetItem* item = itemAt( e->pos() );
|
260 |
288 |
|
261 |
|
hideLine();
|
262 |
|
updateLineWidget();
|
263 |
|
scrollToItem( item );
|
|
289 |
hideLine();
|
|
290 |
updateLineWidget();
|
|
291 |
scrollToItem( item );
|
264 |
292 |
|
265 |
|
QgsLegendItem* origin = dynamic_cast<QgsLegendItem *>( mItemBeingMoved );
|
266 |
|
QgsLegendItem* dest = dynamic_cast<QgsLegendItem *>( item );
|
|
293 |
if ( item )
|
|
294 |
{
|
|
295 |
mDropTarget = item;
|
|
296 |
QgsLegendItem *litem = dynamic_cast<QgsLegendGroup *>( item );
|
|
297 |
QgsLegendGroup *group = dynamic_cast<QgsLegendGroup *>( item );
|
|
298 |
QgsLegendLayer *layer = dynamic_cast<QgsLegendLayer *>( item );
|
267 |
299 |
|
268 |
|
if ( item )
|
|
300 |
|
|
301 |
if ( group )
|
|
302 |
QgsDebugMsg( "group: " + group->text( 0 ) );
|
|
303 |
else if ( layer )
|
|
304 |
QgsDebugMsg( "layer: " + layer->text( 0 ) );
|
|
305 |
else if ( litem )
|
|
306 |
QgsDebugMsg( "litem: " + litem->text( 0 ) );
|
|
307 |
else
|
|
308 |
QgsDebugMsg( "item: " + item->text( 0 ) );
|
|
309 |
|
|
310 |
if ( group || layer )
|
269 |
311 |
{
|
270 |
|
mDropTarget = item;
|
271 |
|
QgsLegendItem::DRAG_ACTION action = dest->accept( origin );
|
272 |
|
if ( item != mItemBeingMoved )
|
|
312 |
if ( yCoordAboveCenter( litem, e->y() ) ) //over center of item
|
273 |
313 |
{
|
274 |
|
if ( yCoordAboveCenter( dest, e->y() ) ) //over center of item
|
|
314 |
int line_y = visualItemRect( item ).top() + 1;
|
|
315 |
int line_left = visualItemRect( item ).left();
|
|
316 |
|
|
317 |
QgsDebugMsg( "insert before layer/group" );
|
|
318 |
showLine( line_y, line_left );
|
|
319 |
setCursor( QCursor( Qt::SizeVerCursor ) );
|
|
320 |
|
|
321 |
mDropAction = BEFORE;
|
|
322 |
}
|
|
323 |
else // below center of item
|
|
324 |
{
|
|
325 |
int line_y = visualItemRect( item ).bottom() - 2;
|
|
326 |
int line_left = visualItemRect( item ).left();
|
|
327 |
|
|
328 |
if ( group )
|
275 |
329 |
{
|
276 |
|
int line_y = visualItemRect( item ).top() + 1;
|
277 |
|
int line_left = visualItemRect( item ).left();
|
|
330 |
QgsDebugMsg( "insert into group" );
|
|
331 |
showLine( line_y, line_left );
|
|
332 |
setCursor( QCursor( Qt::SizeVerCursor ) );
|
278 |
333 |
|
279 |
|
if ( action == QgsLegendItem::REORDER || action == QgsLegendItem::INSERT )
|
280 |
|
{
|
281 |
|
QgsDebugMsg( "mouseMoveEvent::INSERT or REORDER" );
|
282 |
|
mDropAction = BEFORE;
|
283 |
|
showLine( line_y, line_left );
|
284 |
|
setCursor( QCursor( Qt::SizeVerCursor ) );
|
285 |
|
}
|
286 |
|
else //no action
|
287 |
|
{
|
288 |
|
QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );
|
289 |
|
mDropAction = NO_ACTION;
|
290 |
|
setCursor( QCursor( Qt::ForbiddenCursor ) );
|
291 |
|
}
|
|
334 |
mDropAction = INSERT;
|
292 |
335 |
}
|
293 |
|
else // below center of item
|
|
336 |
else
|
294 |
337 |
{
|
295 |
|
int line_y = visualItemRect( item ).bottom() - 2;
|
296 |
|
int line_left = visualItemRect( item ).left();
|
|
338 |
QgsDebugMsg( "insert after layer" );
|
|
339 |
showLine( line_y, line_left );
|
|
340 |
setCursor( QCursor( Qt::SizeVerCursor ) );
|
297 |
341 |
|
298 |
|
if ( action == QgsLegendItem::REORDER )
|
299 |
|
{
|
300 |
|
QgsDebugMsg( "mouseMoveEvent::REORDER bottom half" );
|
301 |
|
mDropAction = AFTER;
|
302 |
|
showLine( line_y, line_left );
|
303 |
|
setCursor( QCursor( Qt::SizeVerCursor ) );
|
304 |
|
}
|
305 |
|
else if ( action == QgsLegendItem::INSERT )
|
306 |
|
{
|
307 |
|
QgsDebugMsg( "mouseMoveEvent::INSERT" );
|
308 |
|
mDropAction = INTO_GROUP;
|
309 |
|
showLine( line_y, line_left );
|
310 |
|
setCursor( QCursor( Qt::SizeVerCursor ) );
|
311 |
|
}
|
312 |
|
else//no action
|
313 |
|
{
|
314 |
|
mDropAction = NO_ACTION;
|
315 |
|
QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );
|
316 |
|
setCursor( QCursor( Qt::ForbiddenCursor ) );
|
317 |
|
}
|
|
342 |
mDropAction = AFTER;
|
318 |
343 |
}
|
319 |
344 |
}
|
320 |
|
else
|
321 |
|
{
|
322 |
|
setCursor( QCursor( Qt::ForbiddenCursor ) );
|
323 |
|
}
|
324 |
345 |
}
|
325 |
|
else if ( !item && e->pos().y() >= 0 && e->pos().y() < viewport()->height() && e->pos().x() >= 0 && e->pos().x() < viewport()->width() )
|
326 |
|
{
|
327 |
|
// Outside the listed items, but check if we are in the empty area
|
328 |
|
// of the viewport, so we can drop after the last top level item.
|
329 |
|
QgsDebugMsg( "You are below the table" );
|
330 |
|
mDropTarget = topLevelItem( topLevelItemCount() - 1 );
|
331 |
|
dest = dynamic_cast<QgsLegendItem *>( mDropTarget );
|
332 |
|
QgsLegendItem::DRAG_ACTION action = dest->accept( origin );
|
333 |
|
if ( action == QgsLegendItem::REORDER || action == QgsLegendItem::INSERT )
|
334 |
|
{
|
335 |
|
QgsDebugMsg( "mouseMoveEvent::INSERT or REORDER" );
|
336 |
|
mDropAction = AFTER;
|
337 |
|
showLine( visualItemRect( lastVisibleItem() ).bottom() + 1, 0 );
|
338 |
|
setCursor( QCursor( Qt::SizeVerCursor ) );
|
339 |
|
}
|
340 |
|
else //no action
|
341 |
|
{
|
342 |
|
QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );
|
343 |
|
mDropAction = NO_ACTION;
|
344 |
|
setCursor( QCursor( Qt::ForbiddenCursor ) );
|
345 |
|
}
|
346 |
|
}
|
347 |
|
|
348 |
346 |
else
|
349 |
347 |
{
|
350 |
|
QgsDebugMsg( "No item here" );
|
351 |
|
mDropTarget = NULL;
|
|
348 |
QgsDebugMsg( "no action" );
|
352 |
349 |
setCursor( QCursor( Qt::ForbiddenCursor ) );
|
353 |
350 |
}
|
354 |
351 |
}
|
|
352 |
else if ( !item
|
|
353 |
&& e->pos().y() >= 0 && e->pos().y() < viewport()->height()
|
|
354 |
&& e->pos().x() >= 0 && e->pos().x() < viewport()->width() )
|
|
355 |
{
|
|
356 |
// Outside the listed items, but check if we are in the empty area
|
|
357 |
// of the viewport, so we can drop after the last top level item.
|
|
358 |
mDropTarget = topLevelItem( topLevelItemCount() - 1 );
|
|
359 |
|
|
360 |
QgsDebugMsg( "insert after last layer/group" );
|
|
361 |
showLine( visualItemRect( lastVisibleItem() ).bottom() + 1, 0 );
|
|
362 |
setCursor( QCursor( Qt::SizeVerCursor ) );
|
|
363 |
|
|
364 |
mDropAction = AFTER;
|
|
365 |
}
|
|
366 |
else
|
|
367 |
{
|
|
368 |
QgsDebugMsg( "No item here" );
|
|
369 |
mDropTarget = NULL;
|
|
370 |
setCursor( QCursor( Qt::ForbiddenCursor ) );
|
|
371 |
}
|
355 |
372 |
}
|
356 |
373 |
|
|
374 |
void QgsLegend::updateGroupCheckStates( QTreeWidgetItem *item )
|
|
375 |
{
|
|
376 |
QgsLegendGroup *lg = dynamic_cast< QgsLegendGroup * >( item );
|
|
377 |
if ( !lg )
|
|
378 |
return;
|
|
379 |
|
|
380 |
for ( int i = 0; i < item->childCount(); i++ )
|
|
381 |
{
|
|
382 |
updateGroupCheckStates( item->child( i ) );
|
|
383 |
}
|
|
384 |
|
|
385 |
lg->updateCheckState();
|
|
386 |
}
|
|
387 |
|
357 |
388 |
void QgsLegend::mouseReleaseEvent( QMouseEvent * e )
|
358 |
389 |
{
|
359 |
390 |
QTreeWidget::mouseReleaseEvent( e );
|
360 |
|
setCursor( QCursor( Qt::ArrowCursor ) );
|
361 |
|
|
362 |
391 |
mMousePressedFlag = false;
|
363 |
392 |
|
364 |
|
// move only if we have a valid item and drop place
|
365 |
|
// otherwise reset the stored values
|
366 |
|
if ( !mItemBeingMoved || !mDropTarget )
|
367 |
|
{
|
368 |
|
mItemBeingMoved = NULL;
|
369 |
|
mDropTarget = NULL;
|
|
393 |
if ( mItemsBeingMoved.isEmpty() )
|
370 |
394 |
return;
|
371 |
|
}
|
372 |
395 |
|
|
396 |
setCursor( QCursor( Qt::ArrowCursor ) );
|
373 |
397 |
hideLine();
|
374 |
398 |
|
375 |
|
QgsLegendItem* origin = dynamic_cast<QgsLegendItem *>( mItemBeingMoved );
|
376 |
|
mItemBeingMoved = NULL;
|
377 |
|
QModelIndex oldIndex = indexFromItem( origin );
|
378 |
|
|
379 |
|
QgsLegendItem* dest = dynamic_cast<QgsLegendItem *>( mDropTarget );
|
380 |
|
mDropTarget = NULL;
|
381 |
|
|
382 |
|
// no change?
|
383 |
|
if ( !dest || !origin || ( dest == origin ) )
|
|
399 |
// unhide
|
|
400 |
foreach( QTreeWidgetItem *item, mItemsBeingMoved )
|
384 |
401 |
{
|
385 |
|
checkLayerOrderUpdate();
|
386 |
|
return;
|
|
402 |
item->setHidden( false );
|
387 |
403 |
}
|
388 |
404 |
|
|
405 |
if ( mDropTarget )
|
389 |
406 |
{
|
390 |
|
// Do the actual move here.
|
391 |
|
QgsDebugMsg( "Drag'n'drop happened!" );
|
392 |
|
if ( mDropAction == AFTER ) //over center of item
|
|
407 |
if ( mDropAction == AFTER )
|
393 |
408 |
{
|
394 |
409 |
QgsDebugMsg( "Drop AFTER" );
|
395 |
|
if ( dest->nextSibling() != origin )
|
|
410 |
foreach( QTreeWidgetItem *item, mItemsBeingMoved )
|
396 |
411 |
{
|
397 |
|
moveItem( origin, dest );
|
398 |
|
setCurrentItem( origin );
|
399 |
|
emit itemMoved( oldIndex, indexFromItem( origin ) );
|
|
412 |
moveItem( item, mDropTarget );
|
|
413 |
mDropTarget = item;
|
400 |
414 |
}
|
401 |
415 |
}
|
402 |
|
else if ( mDropAction == BEFORE )// below center of item
|
|
416 |
else if ( mDropAction == BEFORE )
|
403 |
417 |
{
|
404 |
|
QgsDebugMsg( "Drop BEFORE" );
|
405 |
|
if ( dest->findYoungerSibling() != origin )
|
|
418 |
mDropTarget = previousSibling( mDropTarget );
|
|
419 |
|
|
420 |
foreach( QTreeWidgetItem *item, mItemsBeingMoved )
|
406 |
421 |
{
|
407 |
|
moveItem( origin, dest ); // Insert after, as above...
|
408 |
|
moveItem( dest, origin ); // ... and then switch places!
|
409 |
|
setCurrentItem( origin );
|
410 |
|
emit itemMoved( oldIndex, indexFromItem( origin ) );
|
|
422 |
moveItem( item, mDropTarget );
|
|
423 |
mDropTarget = item;
|
411 |
424 |
}
|
412 |
425 |
}
|
413 |
|
else if ( mDropAction == INTO_GROUP )
|
|
426 |
else
|
414 |
427 |
{
|
415 |
|
QgsDebugMsg( "Drop INTO_GROUP" );
|
416 |
|
if ( origin->parent() != dest )
|
|
428 |
foreach( QTreeWidgetItem *item, mItemsBeingMoved )
|
417 |
429 |
{
|
418 |
|
insertItem( origin, dest );
|
419 |
|
setCurrentItem( origin );
|
420 |
|
emit itemMoved( oldIndex, indexFromItem( origin ) );
|
|
430 |
insertItem( item, mDropTarget );
|
421 |
431 |
}
|
422 |
432 |
}
|
423 |
|
else//no action
|
|
433 |
|
|
434 |
mItemsBeingMoved.clear();
|
|
435 |
|
|
436 |
for ( int i = 0; i < topLevelItemCount(); i++ )
|
424 |
437 |
{
|
425 |
|
QgsDebugMsg( "Drop NO_ACTION" );
|
|
438 |
updateGroupCheckStates( topLevelItem( i ) );
|
426 |
439 |
}
|
427 |
440 |
}
|
|
441 |
else //no action
|
|
442 |
{
|
|
443 |
QgsDebugMsg( "Drop NO_ACTION" );
|
|
444 |
}
|
428 |
445 |
|
429 |
446 |
checkLayerOrderUpdate();
|
430 |
447 |
}
|
... | ... | |
446 |
463 |
QgsLegendItem* li = dynamic_cast<QgsLegendItem *>( item );
|
447 |
464 |
if ( li )
|
448 |
465 |
{
|
449 |
|
|
450 |
466 |
if ( li->type() == QgsLegendItem::LEGEND_LAYER )
|
451 |
467 |
{
|
452 |
468 |
qobject_cast<QgsLegendLayer*>( li )->addToPopupMenu( theMenu );
|
... | ... | |
467 |
483 |
{
|
468 |
484 |
theMenu.addAction( tr( "Re&name" ), this, SLOT( openEditor() ) );
|
469 |
485 |
}
|
470 |
|
|
471 |
486 |
}
|
472 |
487 |
|
473 |
488 |
theMenu.addAction( QgisApp::getThemeIcon( "/folder_new.png" ), tr( "&Add group" ), this, SLOT( addGroup() ) );
|
... | ... | |
565 |
580 |
QgsLegendLayer * ll = findLegendLayer( layer );
|
566 |
581 |
if ( ll )
|
567 |
582 |
{
|
568 |
|
Qt::CheckState cs = visible ? Qt::Checked : Qt::Unchecked;
|
569 |
|
ll->setCheckState( 0, cs );
|
|
583 |
ll->setCheckState( 0, visible ? Qt::Checked : Qt::Unchecked );
|
570 |
584 |
}
|
571 |
585 |
}
|
572 |
586 |
|
... | ... | |
644 |
658 |
}
|
645 |
659 |
}
|
646 |
660 |
|
647 |
|
void QgsLegend::removeGroup( QgsLegendGroup * lg )
|
|
661 |
void QgsLegend::removeGroup( QgsLegendGroup *lg )
|
648 |
662 |
{
|
649 |
663 |
if ( !mMapCanvas || mMapCanvas->isDrawing() )
|
650 |
664 |
{
|
... | ... | |
655 |
669 |
QTreeWidgetItem * child = lg->child( 0 );
|
656 |
670 |
while ( child )
|
657 |
671 |
{
|
658 |
|
QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer *>( child );
|
659 |
|
if ( ll )
|
660 |
|
QgsMapLayerRegistry::instance()->removeMapLayer( ll->layer()->getLayerID() );
|
|
672 |
QgsLegendLayer *cl = dynamic_cast<QgsLegendLayer *>( child );
|
|
673 |
QgsLegendGroup *cg = dynamic_cast<QgsLegendGroup *>( child );
|
|
674 |
|
|
675 |
if ( cl )
|
|
676 |
QgsMapLayerRegistry::instance()->removeMapLayer( cl->layer()->getLayerID() );
|
|
677 |
else if ( cg )
|
|
678 |
removeGroup( cg );
|
|
679 |
|
661 |
680 |
child = lg->child( 0 );
|
662 |
681 |
}
|
|
682 |
|
663 |
683 |
delete lg;
|
664 |
684 |
|
665 |
685 |
adjustIconSize();
|
666 |
686 |
}
|
667 |
687 |
|
668 |
|
void QgsLegend::moveLayer( QgsMapLayer * ml, int groupIndex )
|
|
688 |
void QgsLegend::moveLayer( QgsMapLayer *ml, int groupIndex )
|
669 |
689 |
{
|
670 |
690 |
if ( !ml )
|
671 |
691 |
return;
|
... | ... | |
716 |
736 |
}
|
717 |
737 |
}
|
718 |
738 |
|
719 |
|
bool QgsLegend::writeXML( QDomNode & legendnode, QDomDocument & document )
|
|
739 |
bool QgsLegend::writeXML( QDomNode &legendnode, QDomDocument &document )
|
720 |
740 |
{
|
721 |
|
QDomNode tmplegendnode = legendnode; /*copy of the legendnode*/
|
722 |
|
QDomElement legendgroupnode;
|
723 |
|
QDomElement legendlayernode;
|
724 |
|
QDomElement layerfilegroupnode;
|
725 |
|
QDomElement legendsymbolnode;
|
726 |
|
QDomElement legendpropertynode;
|
727 |
|
QDomElement legendlayerfilenode;
|
728 |
|
Qt::CheckState cstate; //check state for legend layers and legend groups
|
|
741 |
QList<QTreeWidgetItem*> items;
|
|
742 |
for ( int i = 0; i < topLevelItemCount(); i++ )
|
|
743 |
{
|
|
744 |
items << topLevelItem( i );
|
|
745 |
}
|
729 |
746 |
|
730 |
|
for ( QTreeWidgetItem* currentItem = firstItem(); currentItem; currentItem = nextItem( currentItem ) )
|
|
747 |
return writeXML( items, legendnode, document );
|
|
748 |
}
|
|
749 |
|
|
750 |
bool QgsLegend::writeXML( QList<QTreeWidgetItem *> items, QDomNode &node, QDomDocument &document )
|
|
751 |
{
|
|
752 |
foreach( QTreeWidgetItem *currentItem, items )
|
731 |
753 |
{
|
732 |
754 |
QgsLegendItem *item = dynamic_cast<QgsLegendItem *>( currentItem );
|
733 |
755 |
if ( !item )
|
734 |
756 |
continue;
|
735 |
757 |
|
736 |
|
switch ( item->type() )
|
|
758 |
if ( item->type() == QgsLegendItem::LEGEND_GROUP )
|
737 |
759 |
{
|
738 |
|
case QgsLegendItem::LEGEND_GROUP:
|
739 |
|
//make sure the legendnode is 'legend' again after a legend group
|
740 |
|
if ( !( item->parent() ) )
|
|
760 |
QDomElement legendgroupnode = document.createElement( "legendgroup" );
|
|
761 |
legendgroupnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
|
|
762 |
legendgroupnode.setAttribute( "name", item->text( 0 ) );
|
|
763 |
Qt::CheckState cstate = item->checkState( 0 );
|
|
764 |
if ( cstate == Qt::Checked )
|
|
765 |
{
|
|
766 |
legendgroupnode.setAttribute( "checked", "Qt::Checked" );
|
|
767 |
}
|
|
768 |
else if ( cstate == Qt::Unchecked )
|
|
769 |
{
|
|
770 |
legendgroupnode.setAttribute( "checked", "Qt::Unchecked" );
|
|
771 |
}
|
|
772 |
else if ( cstate == Qt::PartiallyChecked )
|
|
773 |
{
|
|
774 |
legendgroupnode.setAttribute( "checked", "Qt::PartiallyChecked" );
|
|
775 |
}
|
|
776 |
|
|
777 |
QList<QTreeWidgetItem *> children;
|
|
778 |
for ( int i = 0; i < currentItem->childCount(); i++ )
|
|
779 |
{
|
|
780 |
children << currentItem->child( i );
|
|
781 |
}
|
|
782 |
|
|
783 |
writeXML( children, legendgroupnode, document );
|
|
784 |
|
|
785 |
node.appendChild( legendgroupnode );
|
|
786 |
}
|
|
787 |
else if ( item->type() == QgsLegendItem::LEGEND_LAYER )
|
|
788 |
{
|
|
789 |
QDomElement legendlayernode = document.createElement( "legendlayer" );
|
|
790 |
legendlayernode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
|
|
791 |
Qt::CheckState cstate = item->checkState( 0 );
|
|
792 |
if ( cstate == Qt::Checked )
|
|
793 |
{
|
|
794 |
legendlayernode.setAttribute( "checked", "Qt::Checked" );
|
|
795 |
}
|
|
796 |
else if ( cstate == Qt::Unchecked )
|
|
797 |
{
|
|
798 |
legendlayernode.setAttribute( "checked", "Qt::Unchecked" );
|
|
799 |
}
|
|
800 |
else if ( cstate == Qt::PartiallyChecked )
|
|
801 |
{
|
|
802 |
legendlayernode.setAttribute( "checked", "Qt::PartiallyChecked" );
|
|
803 |
}
|
|
804 |
legendlayernode.setAttribute( "name", item->text( 0 ) );
|
|
805 |
|
|
806 |
for ( int i = 0; i < item->childCount(); i++ )
|
|
807 |
{
|
|
808 |
QTreeWidgetItem *child = item->child( i );
|
|
809 |
QgsLegendItem *litem = dynamic_cast<QgsLegendItem *>( child );
|
|
810 |
|
|
811 |
if ( !litem )
|
741 |
812 |
{
|
742 |
|
legendnode = tmplegendnode;
|
|
813 |
QgsDebugMsg( "tree widget item not a legend item" );
|
|
814 |
continue;
|
743 |
815 |
}
|
744 |
|
legendgroupnode = document.createElement( "legendgroup" );
|
745 |
|
legendgroupnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
|
746 |
|
legendgroupnode.setAttribute( "name", item->text( 0 ) );
|
747 |
|
cstate = item->checkState( 0 );
|
748 |
|
if ( cstate == Qt::Checked )
|
749 |
|
{
|
750 |
|
legendgroupnode.setAttribute( "checked", "Qt::Checked" );
|
751 |
|
}
|
752 |
|
else if ( cstate == Qt::Unchecked )
|
753 |
|
{
|
754 |
|
legendgroupnode.setAttribute( "checked", "Qt::Unchecked" );
|
755 |
|
}
|
756 |
|
else if ( cstate == Qt::PartiallyChecked )
|
757 |
|
{
|
758 |
|
legendgroupnode.setAttribute( "checked", "Qt::PartiallyChecked" );
|
759 |
|
}
|
760 |
|
legendnode.appendChild( legendgroupnode );
|
761 |
|
tmplegendnode = legendnode;
|
762 |
|
legendnode = legendgroupnode;
|
763 |
|
break;
|
764 |
816 |
|
765 |
|
case QgsLegendItem::LEGEND_LAYER:
|
766 |
|
//make sure the legendnode is 'legend' again after a legend group
|
767 |
|
if ( !( item->parent() ) )
|
|
817 |
if ( litem->type() == QgsLegendItem::LEGEND_PROPERTY_GROUP )
|
768 |
818 |
{
|
769 |
|
legendnode = tmplegendnode;
|
|
819 |
QDomElement legendpropertynode = document.createElement( "propertygroup" );
|
|
820 |
legendpropertynode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
|
|
821 |
legendlayernode.appendChild( legendpropertynode );
|
770 |
822 |
}
|
771 |
|
legendlayernode = document.createElement( "legendlayer" );
|
772 |
|
legendlayernode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
|
773 |
|
cstate = item->checkState( 0 );
|
774 |
|
if ( cstate == Qt::Checked )
|
|
823 |
else if ( litem->type() == QgsLegendItem::LEGEND_SYMBOL_GROUP )
|
775 |
824 |
{
|
776 |
|
legendlayernode.setAttribute( "checked", "Qt::Checked" );
|
|
825 |
QDomElement legendsymbolnode = document.createElement( "symbolgroup" );
|
|
826 |
legendsymbolnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
|
|
827 |
legendlayernode.appendChild( legendsymbolnode );
|
777 |
828 |
}
|
778 |
|
else if ( cstate == Qt::Unchecked )
|
|
829 |
else
|
779 |
830 |
{
|
780 |
|
legendlayernode.setAttribute( "checked", "Qt::Unchecked" );
|
|
831 |
QgsDebugMsg( "unexpected legend item type " + QString::number( litem->type() ) );
|
781 |
832 |
}
|
782 |
|
else if ( cstate == Qt::PartiallyChecked )
|
783 |
|
{
|
784 |
|
legendlayernode.setAttribute( "checked", "Qt::PartiallyChecked" );
|
785 |
|
}
|
786 |
|
legendlayernode.setAttribute( "name", item->text( 0 ) );
|
787 |
|
legendnode.appendChild( legendlayernode );
|
|
833 |
}
|
788 |
834 |
|
789 |
|
// save the information about layer
|
790 |
|
// emulate a legend layer file group and a legend layer file
|
791 |
|
// to keep it compatible with older projects
|
792 |
|
{
|
793 |
|
QgsLegendLayer *ll = dynamic_cast<QgsLegendLayer *>( item );
|
794 |
|
QgsMapLayer* layer = ll->layer();
|
|
835 |
node.appendChild( legendlayernode );
|
795 |
836 |
|
796 |
|
layerfilegroupnode = document.createElement( "filegroup" );
|
797 |
|
layerfilegroupnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
|
798 |
|
layerfilegroupnode.setAttribute( "hidden", isItemHidden( item ) ? "true" : "false" );
|
799 |
|
legendlayernode.appendChild( layerfilegroupnode );
|
|
837 |
// save the information about layer
|
|
838 |
// emulate a legend layer file group and a legend layer file
|
|
839 |
// to keep it compatible with older projects
|
|
840 |
QgsLegendLayer *ll = dynamic_cast<QgsLegendLayer *>( item );
|
|
841 |
QgsMapLayer* layer = ll->layer();
|
800 |
842 |
|
801 |
|
legendlayerfilenode = document.createElement( "legendlayerfile" );
|
|
843 |
QDomElement layerfilegroupnode = document.createElement( "filegroup" );
|
|
844 |
layerfilegroupnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
|
|
845 |
layerfilegroupnode.setAttribute( "hidden", isItemHidden( item ) ? "true" : "false" );
|
|
846 |
legendlayernode.appendChild( layerfilegroupnode );
|
802 |
847 |
|
803 |
|
// layer id
|
804 |
|
legendlayerfilenode.setAttribute( "layerid", layer->getLayerID() );
|
805 |
|
layerfilegroupnode.appendChild( legendlayerfilenode );
|
|
848 |
QDomElement legendlayerfilenode = document.createElement( "legendlayerfile" );
|
806 |
849 |
|
807 |
|
// visible flag
|
808 |
|
legendlayerfilenode.setAttribute( "visible", ll->isVisible() );
|
|
850 |
// layer id
|
|
851 |
legendlayerfilenode.setAttribute( "layerid", layer->getLayerID() );
|
|
852 |
layerfilegroupnode.appendChild( legendlayerfilenode );
|
809 |
853 |
|
810 |
|
// show in overview flag
|
811 |
|
legendlayerfilenode.setAttribute( "isInOverview", ll->isInOverview() );
|
812 |
|
}
|
813 |
|
break;
|
|
854 |
// visible flag
|
|
855 |
legendlayerfilenode.setAttribute( "visible", ll->isVisible() );
|
814 |
856 |
|
815 |
|
case QgsLegendItem::LEGEND_PROPERTY_GROUP:
|
816 |
|
legendpropertynode = document.createElement( "propertygroup" );
|
817 |
|
legendpropertynode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
|
818 |
|
legendlayernode.appendChild( legendpropertynode );
|
819 |
|
break;
|
820 |
|
|
821 |
|
case QgsLegendItem::LEGEND_SYMBOL_GROUP:
|
822 |
|
legendsymbolnode = document.createElement( "symbolgroup" );
|
823 |
|
legendsymbolnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
|
824 |
|
legendlayernode.appendChild( legendsymbolnode );
|
825 |
|
break;
|
826 |
|
|
827 |
|
default: //do nothing for the leaf nodes
|
828 |
|
break;
|
|
857 |
// show in overview flag
|
|
858 |
legendlayerfilenode.setAttribute( "isInOverview", ll->isInOverview() );
|
829 |
859 |
}
|
|
860 |
else
|
|
861 |
{
|
|
862 |
QgsDebugMsg( "unexpected legend item type " + QString::number( item->type() ) );
|
|
863 |
}
|
830 |
864 |
}
|
|
865 |
|
831 |
866 |
return true;
|
832 |
867 |
}
|
833 |
868 |
|
834 |
|
bool QgsLegend::readXML( QDomNode& legendnode )
|
|
869 |
bool QgsLegend::readXML( QgsLegendGroup *parent, const QDomNode &node )
|
835 |
870 |
{
|
836 |
|
QDomElement childelem;
|
837 |
|
QDomNode child;
|
838 |
|
QgsLegendGroup* lastGroup = 0; //pointer to the last inserted group
|
839 |
|
QgsLegendLayer* lastLayer = 0; //pointer to the last inserted legendlayer
|
|
871 |
const QDomNodeList &l = node.childNodes();
|
|
872 |
for ( int i = 0; i < l.count(); i++ )
|
|
873 |
{
|
|
874 |
QDomNode child = l.at( i );
|
|
875 |
QDomElement childelem = child.toElement();
|
|
876 |
QString name = childelem.attribute( "name" );
|
840 |
877 |
|
841 |
|
child = legendnode.firstChild();
|
|
878 |
//test every possibility of element...
|
|
879 |
if ( childelem.tagName() == "legendgroup" )
|
|
880 |
{
|
|
881 |
QgsLegendGroup *theGroup;
|
|
882 |
if ( parent )
|
|
883 |
theGroup = new QgsLegendGroup( parent, name );
|
|
884 |
else
|
|
885 |
theGroup = new QgsLegendGroup( this, name );
|
842 |
886 |
|
843 |
|
// For some unexplained reason, collapsing/expanding the legendLayer items
|
844 |
|
// immediately after they have been created doesn't work (they all end up
|
845 |
|
// expanded). The legendGroups and legendLayerFiles seems ok through. The
|
846 |
|
// workaround is to store the required states of the legendLayers and set
|
847 |
|
// them at the end of this function.
|
848 |
|
QList<QTreeWidgetItem*> collapsed, expanded;
|
|
887 |
//set the checkbox of the legend group to the right state
|
|
888 |
blockSignals( true );
|
|
889 |
QString checked = childelem.attribute( "checked" );
|
|
890 |
if ( checked == "Qt::Checked" )
|
|
891 |
{
|
|
892 |
theGroup->setCheckState( 0, Qt::Checked );
|
|
893 |
theGroup->setData( 0, Qt::UserRole, Qt::Checked );
|
|
894 |
}
|
|
895 |
else if ( checked == "Qt::Unchecked" )
|
|
896 |
{
|
|
897 |
theGroup->setCheckState( 0, Qt::Unchecked );
|
|
898 |
theGroup->setData( 0, Qt::UserRole, Qt::Checked );
|
|
899 |
}
|
|
900 |
else if ( checked == "Qt::PartiallyChecked" )
|
|
901 |
{
|
|
902 |
theGroup->setCheckState( 0, Qt::PartiallyChecked );
|
|
903 |
theGroup->setData( 0, Qt::UserRole, Qt::PartiallyChecked );
|
|
904 |
}
|
|
905 |
blockSignals( false );
|
849 |
906 |
|
850 |
|
if ( !child.isNull() )
|
851 |
|
{
|
852 |
|
clear(); //remove all items first
|
|
907 |
readXML( theGroup, child );
|
853 |
908 |
|
854 |
|
do
|
|
909 |
if ( childelem.attribute( "open" ) == "true" )
|
|
910 |
{
|
|
911 |
expandItem( theGroup );
|
|
912 |
}
|
|
913 |
else
|
|
914 |
{
|
|
915 |
collapseItem( theGroup );
|
|
916 |
}
|
|
917 |
}
|
|
918 |
else if ( childelem.tagName() == "legendlayer" )
|
855 |
919 |
{
|
856 |
|
QDomElement childelem = child.toElement();
|
857 |
|
QString name = childelem.attribute( "name" );
|
|
920 |
bool isOpen;
|
|
921 |
QgsLegendLayer* currentLayer = readLayerFromXML( childelem, isOpen );
|
858 |
922 |
|
859 |
|
//test every possibility of element...
|
860 |
|
if ( childelem.tagName() == "legendgroup" )
|
|
923 |
if ( !currentLayer )
|
|
924 |
return false;
|
|
925 |
|
|
926 |
// add to tree - either as a top-level node or a child of a group
|
|
927 |
if ( parent )
|
861 |
928 |
{
|
862 |
|
QgsLegendGroup* theGroup = new QgsLegendGroup( this, name );
|
863 |
|
childelem.attribute( "open" ) == "true" ? expanded.push_back( theGroup ) : collapsed.push_back( theGroup );
|
864 |
|
//set the checkbox of the legend group to the right state
|
865 |
|
blockSignals( true );
|
866 |
|
QString checked = childelem.attribute( "checked" );
|
867 |
|
if ( checked == "Qt::Checked" )
|
|
929 |
parent->addChild( currentLayer );
|
|
930 |
}
|
|
931 |
else
|
|
932 |
{
|
|
933 |
addTopLevelItem( currentLayer );
|
|
934 |
}
|
|
935 |
|
|
936 |
const QDomNodeList &cnl = child.childNodes();
|
|
937 |
for ( int j = 0; j < cnl.count(); j++ )
|
|
938 |
{
|
|
939 |
const QDomElement &childelem = cnl.at( j ).toElement();
|
|
940 |
|
|
941 |
if ( childelem.tagName() == "legendlayerfile" )
|
868 |
942 |
{
|
869 |
|
theGroup->setCheckState( 0, Qt::Checked );
|
870 |
|
theGroup->setData( 0, Qt::UserRole, Qt::Checked );
|
|
943 |
// do nothing, this has been handled in readLayerFromXML()
|
871 |
944 |
}
|
872 |
|
else if ( checked == "Qt::Unchecked" )
|
|
945 |
else if ( childelem.tagName() == "filegroup" )
|
873 |
946 |
{
|
874 |
|
theGroup->setCheckState( 0, Qt::Unchecked );
|
875 |
|
theGroup->setData( 0, Qt::UserRole, Qt::Checked );
|
|
947 |
// do nothing, this has been handled in readLayerFromXML()
|
876 |
948 |
}
|
877 |
|
else if ( checked == "Qt::PartiallyChecked" )
|
|
949 |
else if ( childelem.tagName() == "propertygroup" )
|
878 |
950 |
{
|
879 |
|
theGroup->setCheckState( 0, Qt::PartiallyChecked );
|
880 |
|
theGroup->setData( 0, Qt::UserRole, Qt::PartiallyChecked );
|
|
951 |
QgsLegendPropertyGroup* thePropertyGroup = new QgsLegendPropertyGroup( currentLayer, "Properties" );
|
|
952 |
setItemExpanded( thePropertyGroup, childelem.attribute( "open" ) == "true" );
|
881 |
953 |
}
|
882 |
|
blockSignals( false );
|
883 |
|
lastGroup = theGroup;
|
884 |
|
}
|
885 |
|
else if ( childelem.tagName() == "legendlayer" )
|
886 |
|
{
|
887 |
|
bool isOpen; // to receive info whether the item is open or closed
|
888 |
|
lastLayer = readLayerFromXML( childelem, isOpen );
|
889 |
|
|
890 |
|
if ( lastLayer )
|
|
954 |
else
|
891 |
955 |
{
|
892 |
|
|
893 |
|
// add to tree - either as a top-level node or a child of a group
|
894 |
|
if ( child.parentNode().toElement().tagName() == "legendgroup" )
|
895 |
|
{
|
896 |
|
lastGroup->addChild( lastLayer );
|
897 |
|
}
|
898 |
|
else
|
899 |
|
{
|
900 |
|
addTopLevelItem( lastLayer );
|
901 |
|
lastGroup = 0;
|
902 |
|
}
|
903 |
|
|
904 |
|
// expanded or collapsed
|
905 |
|
isOpen ? expanded.push_back( lastLayer ) : collapsed.push_back( lastLayer );
|
906 |
|
|
907 |
|
// load symbology
|
908 |
|
refreshLayerSymbology( lastLayer->layer()->getLayerID() );
|
|
956 |
QgsDebugMsg( "unexpected legendlayer child " + childelem.tagName() );
|
909 |
957 |
}
|
910 |
958 |
}
|
911 |
|
else if ( childelem.tagName() == "legendlayerfile" )
|
|
959 |
|
|
960 |
// load symbology
|
|
961 |
refreshLayerSymbology( currentLayer->layer()->getLayerID() );
|
|
962 |
|
|
963 |
if ( isOpen )
|
912 |
964 |
{
|
913 |
|
// do nothing, this has been handled in readLayerFromXML()
|
|
965 |
expandItem( currentLayer );
|
914 |
966 |
}
|
915 |
|
else if ( childelem.tagName() == "filegroup" )
|
|
967 |
else
|
916 |
968 |
{
|
917 |
|
// do nothing, this has been handled in readLayerFromXML()
|
|
969 |
collapseItem( currentLayer );
|
918 |
970 |
}
|
919 |
|
else if ( childelem.tagName() == "propertygroup" )
|
920 |
|
{
|
921 |
|
QgsLegendPropertyGroup* thePropertyGroup = new QgsLegendPropertyGroup( lastLayer, "Properties" );
|
922 |
|
childelem.attribute( "open" ) == "true" ? expandItem( thePropertyGroup ) : collapseItem( thePropertyGroup );
|
923 |
|
}
|
924 |
|
child = nextDomNode( child );
|
925 |
971 |
}
|
926 |
|
while ( !( child.isNull() ) );
|
|
972 |
else
|
|
973 |
{
|
|
974 |
QgsDebugMsg( "unexpected legend child " + childelem.tagName() );
|
|
975 |
}
|
927 |
976 |
}
|
928 |
977 |
|
929 |
|
// Do the tree item expands and collapses.
|
930 |
|
for ( int i = 0; i < expanded.size(); ++i )
|
931 |
|
expandItem( expanded[i] );
|
932 |
|
for ( int i = 0; i < collapsed.size(); ++i )
|
933 |
|
collapseItem( collapsed[i] );
|
934 |
|
|
935 |
978 |
return true;
|
936 |
979 |
}
|
937 |
980 |
|
|
981 |
bool QgsLegend::readXML( QDomNode& legendnode )
|
|
982 |
{
|
|
983 |
clear(); //remove all items first
|
|
984 |
return readXML( 0, legendnode );
|
|
985 |
}
|
938 |
986 |
|
939 |
987 |
QgsLegendLayer* QgsLegend::readLayerFromXML( QDomElement& childelem, bool& isOpen )
|
940 |
988 |
{
|
... | ... | |
982 |
1030 |
}
|
983 |
1031 |
|
984 |
1032 |
|
985 |
|
void QgsLegend::storeInitialPosition( QTreeWidgetItem* li )
|
986 |
|
{
|
987 |
|
if ( li == firstItem() ) //the item is the first item in the list view
|
988 |
|
{
|
989 |
|
mRestoreInformation = FIRST_ITEM;
|
990 |
|
mRestoreItem = 0;
|
991 |
|
}
|
992 |
|
else if ( li->parent() == 0 ) //li is a toplevel item, but not the first one
|
993 |
|
{
|
994 |
|
mRestoreInformation = YOUNGER_SIBLING;
|
995 |
|
mRestoreItem = (( QgsLegendItem* )( li ) )->findYoungerSibling();
|
996 |
|
}
|
997 |
|
else if ( li == li->parent()->child( 0 ) )//li is not a toplevel item, but the first child
|
998 |
|
{
|
999 |
|
mRestoreInformation = FIRST_CHILD;
|
1000 |
|
mRestoreItem = li->parent();
|
1001 |
|
}
|
1002 |
|
else
|
1003 |
|
{
|
1004 |
|
mRestoreInformation = YOUNGER_SIBLING;
|
1005 |
|
mRestoreItem = (( QgsLegendItem* )( li ) )->findYoungerSibling();
|
1006 |
|
}
|
1007 |
|
mLayersPriorToMove = layerIDs();
|
1008 |
|
}
|
1009 |
|
|
1010 |
|
void QgsLegend::resetToInitialPosition( QTreeWidgetItem* li )
|
1011 |
|
{
|
1012 |
|
QgsLegendItem* formerParent = dynamic_cast<QgsLegendItem *>( li->parent() ); //todo: make sure legend layers are updated
|
1013 |
|
if ( mRestoreInformation == FIRST_ITEM )
|
1014 |
|
{
|
1015 |
|
QgsDebugMsg( "FIRST_ITEM" );
|
1016 |
|
|
1017 |
|
removeItem( li );
|
1018 |
|
insertTopLevelItem( 0, li );
|
1019 |
|
}
|
1020 |
|
else if ( mRestoreInformation == FIRST_CHILD )
|
1021 |
|
{
|
1022 |
|
QgsDebugMsg( "FIRST_CHILD" );
|
1023 |
|
|
1024 |
|
removeItem( li );
|
1025 |
|
if ( formerParent )
|
1026 |
|
{
|
1027 |
|
formerParent->release(( QgsLegendItem* )li );
|
1028 |
|
}
|
1029 |
|
mRestoreItem->insertChild( 0, li );
|
1030 |
|
(( QgsLegendItem* )mRestoreItem )->receive(( QgsLegendItem* )li );
|
1031 |
|
}
|
1032 |
|
else if ( mRestoreInformation == YOUNGER_SIBLING )
|
1033 |
|
{
|
1034 |
|
QgsDebugMsg( "YOUNGER_SIBLING" );
|
1035 |
|
|
1036 |
|
if ( formerParent )
|
1037 |
|
{
|
1038 |
|
formerParent->release(( QgsLegendItem* )li );
|
1039 |
|
}
|
1040 |
|
dynamic_cast<QgsLegendItem *>( li )->moveItem( dynamic_cast<QgsLegendItem*>( mRestoreItem ) );
|
1041 |
|
if ( mRestoreItem->parent() )
|
1042 |
|
{
|
1043 |
|
(( QgsLegendItem* )( mRestoreItem->parent() ) )->receive(( QgsLegendItem* )li );
|
1044 |
|
}
|
1045 |
|
}
|
1046 |
|
}
|
1047 |
|
|
1048 |
1033 |
QgsLegendLayer* QgsLegend::findLegendLayer( const QString& layerKey )
|
1049 |
1034 |
{
|
1050 |
1035 |
QgsLegendLayer* theLegendLayer = 0;
|
... | ... | |
1156 |
1141 |
{
|
1157 |
1142 |
QList< GroupLayerInfo > groupLayerList;
|
1158 |
1143 |
|
1159 |
|
int nTopLevelItems = topLevelItemCount();
|
1160 |
|
QTreeWidgetItem* currentTopLevelItem = 0;
|
|
1144 |
QList< QTreeWidgetItem * > items;
|
1161 |
1145 |
|
1162 |
|
for ( int i = 0; i < nTopLevelItems; ++i )
|
|
1146 |
for ( int i = 0; i < topLevelItemCount(); i++ )
|
1163 |
1147 |
{
|
1164 |
|
currentTopLevelItem = topLevelItem( i );
|
1165 |
|
//layer?
|
1166 |
|
QgsLegendLayer* lLayer = dynamic_cast<QgsLegendLayer*>( currentTopLevelItem );
|
|
1148 |
items << topLevelItem( i );
|
|
1149 |
}
|
|
1150 |
|
|
1151 |
while ( !items.isEmpty() )
|
|
1152 |
{
|
|
1153 |
QTreeWidgetItem *currentItem = items.takeFirst();
|
|
1154 |
|
|
1155 |
QgsLegendLayer* lLayer = dynamic_cast<QgsLegendLayer*>( currentItem );
|
1167 |
1156 |
if ( lLayer )
|
1168 |
1157 |
{
|
1169 |
1158 |
if ( lLayer->layer() )
|
... | ... | |
1173 |
1162 |
groupLayerList.push_back( qMakePair( QString(), layerList ) );
|
1174 |
1163 |
}
|
1175 |
1164 |
}
|
1176 |
|
//group?
|
1177 |
|
QgsLegendGroup* lGroup = dynamic_cast<QgsLegendGroup*>( currentTopLevelItem );
|
|
1165 |
|
|
1166 |
QgsLegendGroup* lGroup = dynamic_cast<QgsLegendGroup*>( currentItem );
|
1178 |
1167 |
if ( lGroup )
|
1179 |
1168 |
{
|
1180 |
|
int nLayers = lGroup->childCount();
|
|
1169 |
int nLayers = lGroup->childCount();
|
1181 |
1170 |
QList<QString> layerList;
|
1182 |
1171 |
for ( int i = 0; i < nLayers; ++i )
|
1183 |
1172 |
{
|
1184 |
|
QgsLegendLayer* lLayer = dynamic_cast<QgsLegendLayer*>( lGroup->child( i ) );
|
|
1173 |
QTreeWidgetItem *gItem = lGroup->child( i );
|
|
1174 |
|
|
1175 |
QgsLegendLayer* lLayer = dynamic_cast<QgsLegendLayer*>( gItem );
|
1185 |
1176 |
if ( lLayer )
|
1186 |
1177 |
{
|
1187 |
1178 |
if ( lLayer->layer() )
|
... | ... | |
1189 |
1180 |
layerList.push_back( lLayer->layer()->getLayerID() );
|
1190 |
1181 |
}
|
1191 |
1182 |
}
|
|
1183 |
|
|
1184 |
QgsLegendGroup* lGroup = dynamic_cast<QgsLegendGroup*>( gItem );
|
|
1185 |
if ( lGroup )
|
|
1186 |
{
|
|
1187 |
layerList << lGroup->text( 0 );
|
|
1188 |
items << lGroup;
|
|
1189 |
}
|
1192 |
1190 |
}
|
|
1191 |
|
1193 |
1192 |
groupLayerList.push_back( qMakePair( lGroup->text( 0 ), layerList ) );
|
1194 |
1193 |
}
|
1195 |
1194 |
}
|
... | ... | |
1197 |
1196 |
return groupLayerList;
|
1198 |
1197 |
}
|
1199 |
1198 |
|
1200 |
|
/**Returns the first item in the hierarchy*/
|
1201 |
1199 |
QTreeWidgetItem* QgsLegend::firstItem()
|
1202 |
1200 |
{
|
1203 |
1201 |
return topLevelItem( 0 );
|
... | ... | |
1219 |
1217 |
{
|
1220 |
1218 |
return litem->nextSibling();
|
1221 |
1219 |
}
|
1222 |
|
else if ( !litem->parent() )
|
|
1220 |
else if ( litem->parent() )
|
1223 |
1221 |
{
|
1224 |
|
return 0;
|
|
1222 |
QTreeWidgetItem *parent = litem->parent();
|
|
1223 |
|
|
1224 |
while ( parent )
|
|
1225 |
{
|
|
1226 |
QgsLegendItem *sibling = dynamic_cast<QgsLegendItem *>( parent )->nextSibling();
|
|
1227 |
|
|
1228 |
if ( sibling )
|
|
1229 |
return sibling;
|
|
1230 |
|
|
1231 |
parent = parent->parent();
|
|
1232 |
}
|
1225 |
1233 |
}
|
1226 |
|
//go to other levels to find the next item
|
1227 |
|
else if ( litem->parent() && dynamic_cast<QgsLegendItem *>( litem->parent() )->nextSibling() )
|
1228 |
|
{
|
1229 |
|
return dynamic_cast<QgsLegendItem *>( litem->parent() )->nextSibling();
|
1230 |
|
}
|
1231 |
|
else if ( litem->parent() && litem->parent()->parent() && dynamic_cast<QgsLegendItem*>( litem->parent()->parent() )->nextSibling() )
|
1232 |
|
{
|
1233 |
|
return dynamic_cast<QgsLegendItem *>( litem->parent()->parent() )->nextSibling();
|
1234 |
|
}
|
1235 |
|
else if ( litem->parent() && litem->parent()->parent() && litem->parent()->parent()->parent() &&
|
1236 |
|
dynamic_cast<QgsLegendItem *>( litem->parent()->parent()->parent() )->nextSibling() )//maximum four nesting states in the current legend
|
1237 |
|
{
|
1238 |
|
return dynamic_cast<QgsLegendItem *>( litem->parent()->parent()->parent() )->nextSibling();
|
1239 |
|
}
|
1240 |
|
else
|
1241 |
|
{
|
1242 |
|
return 0;
|
1243 |
|
}
|
|
1234 |
|
|
1235 |
return 0;
|
1244 |
1236 |
}
|
1245 |
1237 |
|
1246 |
1238 |
QTreeWidgetItem* QgsLegend::nextSibling( QTreeWidgetItem* item )
|
... | ... | |
1271 |
1263 |
}
|
1272 |
1264 |
}
|
1273 |
1265 |
|
1274 |
|
QDomNode QgsLegend::nextDomNode( const QDomNode& theNode )
|
1275 |
|
{
|
1276 |
|
if ( !theNode.firstChild().isNull() )
|
1277 |
|
{
|
1278 |
|
return theNode.firstChild();
|
1279 |
|
}
|
1280 |
|
|
1281 |
|
QDomNode currentNode = theNode;
|
1282 |
|
do
|
1283 |
|
{
|
1284 |
|
if ( !currentNode.nextSibling().isNull() )
|
1285 |
|
{
|
1286 |
|
return currentNode.nextSibling();
|
1287 |
|
}
|
1288 |
|
currentNode = currentNode.parentNode();
|
1289 |
|
}
|
1290 |
|
while ( !currentNode.isNull() );
|
1291 |
|
|
1292 |
|
QDomNode nullNode;
|
1293 |
|
return nullNode;
|
1294 |
|
}
|
1295 |
|
|
1296 |
1266 |
void QgsLegend::insertItem( QTreeWidgetItem* move, QTreeWidgetItem* into )
|
1297 |
1267 |
{
|
1298 |
1268 |
QgsLegendItem* movedItem = dynamic_cast<QgsLegendItem *>( move );
|
... | ... | |
1316 |
1286 |
void QgsLegend::moveItem( QTreeWidgetItem* move, QTreeWidgetItem* after )
|
1317 |
1287 |
{
|
1318 |
1288 |
QgsDebugMsg( QString( "Moving layer : %1 (%2)" ).arg( move->text( 0 ) ).arg( move->type() ) );
|
1319 |
|
QgsDebugMsg( QString( "after layer : %1 (%2)" ).arg( after->text( 0 ) ).arg( after->type() ) );
|
|
1289 |
if ( after )
|
|
1290 |
QgsDebugMsg( QString( "after layer : %1 (%2)" ).arg( after->text( 0 ) ).arg( after->type() ) );
|
|
1291 |
else
|
|
1292 |
QgsDebugMsg( "as toplevel item" );
|
1320 |
1293 |
|
1321 |
1294 |
static_cast<QgsLegendItem*>( move )->storeAppearanceSettings();//store settings in the moved item and its childern
|
|
1295 |
|
1322 |
1296 |
if ( move->parent() )
|
1323 |
1297 |
{
|
1324 |
1298 |
move->parent()->takeChild( move->parent()->indexOfChild( move ) );
|
... | ... | |
1327 |
1301 |
{
|
1328 |
1302 |
takeTopLevelItem( indexOfTopLevelItem( move ) );
|
1329 |
1303 |
}
|
1330 |
|
if ( after->parent() )
|
|
1304 |
|
|
1305 |
if ( after )
|
1331 |
1306 |
{
|
1332 |
|
after->parent()->insertChild( after->parent()->indexOfChild( after ) + 1, move );
|
|
1307 |
if ( after->parent() )
|
|
1308 |
{
|
|
1309 |
after->parent()->insertChild( after->parent()->indexOfChild( after ) + 1, move );
|
|
1310 |
}
|
|
1311 |
else //toplevel item
|
|
1312 |
{
|
|
1313 |
insertTopLevelItem( indexOfTopLevelItem( after ) + 1, move );
|
|
1314 |
}
|
1333 |
1315 |
}
|
1334 |
|
else //toplevel item
|
|
1316 |
else
|
1335 |
1317 |
{
|
1336 |
|
insertTopLevelItem( indexOfTopLevelItem( after ) + 1, move );
|
|
1318 |
insertTopLevelItem( 0, move );
|
1337 |
1319 |
}
|
|
1320 |
|
1338 |
1321 |
static_cast<QgsLegendItem*>( move )->restoreAppearanceSettings();//apply the settings again
|
1339 |
1322 |
}
|
1340 |
1323 |
|
... | ... | |
1390 |
1373 |
updateOverview();
|
1391 |
1374 |
}
|
1392 |
1375 |
|
1393 |
|
std::deque<QString> QgsLegend::layerIDs()
|
|
1376 |
QStringList QgsLegend::layerIDs()
|
1394 |
1377 |
{
|
1395 |
|
std::deque<QString> layers;
|
|
1378 |
QStringList layers;
|
|
1379 |
|
1396 |
1380 |
for ( QTreeWidgetItem* theItem = firstItem(); theItem; theItem = nextItem( theItem ) )
|
1397 |
1381 |
{
|
1398 |
1382 |
QgsLegendItem *li = dynamic_cast<QgsLegendItem *>( theItem );
|
... | ... | |
1406 |
1390 |
|
1407 |
1391 |
#ifdef QGISDEBUG
|
1408 |
1392 |
QgsDebugMsg( "QgsLegend::layerIDs()" );
|
1409 |
|
for ( std::deque<QString>::iterator it = layers.begin(); it != layers.end(); ++it )
|
|
1393 |
foreach( QString id, layers )
|
1410 |
1394 |
{
|
1411 |
|
QgsDebugMsg( *it );
|
|
1395 |
QgsDebugMsg( id );
|
1412 |
1396 |
}
|
1413 |
1397 |
#endif
|
1414 |
1398 |
|
... | ... | |
1501 |
1485 |
if ( lg )
|
1502 |
1486 |
{
|
1503 |
1487 |
//set all the child layer files to the new check state
|
1504 |
|
std::list<QgsLegendLayer*> subfiles = lg->legendLayers();
|
1505 |
1488 |
bool renderFlagState = mMapCanvas->renderFlag();
|
1506 |
1489 |
mMapCanvas->setRenderFlag( false );
|
1507 |
|
for ( std::list<QgsLegendLayer*>::iterator iter = subfiles.begin(); iter != subfiles.end(); ++iter )
|
|
1490 |
QList<QTreeWidgetItem *> items;
|
|
1491 |
items << item;
|
|
1492 |
while ( !items.isEmpty() )
|
1508 |
1493 |
{
|
1509 |
|
#ifdef QGISDEBUG
|
1510 |
|
if ( item->checkState( 0 ) == Qt::Checked )
|
|
1494 |
QTreeWidgetItem *litem = items.takeFirst();
|
|
1495 |
|
|
1496 |
QgsLegendLayer *ll = dynamic_cast<QgsLegendLayer *>( litem );
|
|
1497 |
if ( ll )
|
1511 |
1498 |
{
|
1512 |
|
QgsDebugMsg( "item checked" );
|
|
1499 |
blockSignals( true );
|
|
1500 |
ll->setCheckState( 0, item->checkState( 0 ) );
|
|
1501 |
blockSignals( false );
|
|
1502 |
|
|
1503 |
if ( ll->layer() )
|
|
1504 |
{
|
|
1505 |
ll->setVisible( lg->checkState( 0 ) == Qt::Checked );
|
|
1506 |
}
|
1513 |
1507 |
}
|
1514 |
|
else if ( item->checkState( 0 ) == Qt::Unchecked )
|
|
1508 |
|
|
1509 |
QgsLegendGroup *lg = dynamic_cast<QgsLegendGroup *>( litem );
|
|
1510 |
if ( lg )
|
1515 |
1511 |
{
|
1516 |
|
QgsDebugMsg( "item unchecked" );
|
|
1512 |
blockSignals( true );
|
|
1513 |
lg->setCheckState( 0, item->checkState( 0 ) );
|
|
1514 |
blockSignals( false );
|
|
1515 |
|
|
1516 |
for ( int i = 0; i < lg->childCount(); i++ )
|
|
1517 |
items << lg->child( i );
|
1517 |
1518 |
}
|
1518 |
|
else if ( item->checkState( 0 ) == Qt::PartiallyChecked )
|
1519 |
|
{
|
1520 |
|
QgsDebugMsg( "item partially checked" );
|
1521 |
|
}
|
1522 |
|
#endif
|
1523 |
|
blockSignals( true );
|
1524 |
|
( *iter )->setCheckState( 0, item->checkState( 0 ) );
|
1525 |
|
blockSignals( false );
|
1526 |
|
item->setData( 0, Qt::UserRole, item->checkState( 0 ) );
|
1527 |
|
if (( *iter )->layer() )
|
1528 |
|
{
|
1529 |
|
( *iter )->setVisible( item->checkState( 0 ) == Qt::Checked );
|
1530 |
|
}
|
1531 |
1519 |
}
|
1532 |
1520 |
|
1533 |
1521 |
// If it was on, turn it back on, otherwise leave it
|
1534 |
1522 |
// off, as turning it on causes a refresh.
|
1535 |
1523 |
if ( renderFlagState )
|
1536 |
1524 |
mMapCanvas->setRenderFlag( true );
|
|
1525 |
|
1537 |
1526 |
item->setData( 0, Qt::UserRole, item->checkState( 0 ) );
|
1538 |
1527 |
}
|
1539 |
1528 |
|
... | ... | |
1549 |
1538 |
ll->setVisible( item->checkState( 0 ) == Qt::Checked );
|
1550 |
1539 |
}
|
1551 |
1540 |
|
1552 |
|
if ( ll->parent() )
|
|
1541 |
QgsLegendGroup *lg = dynamic_cast<QgsLegendGroup*>( ll->parent() );
|
|
1542 |
while ( lg )
|
1553 |
1543 |
{
|
1554 |
|
static_cast<QgsLegendGroup*>( ll->parent() )->updateCheckState();
|
1555 |
|
ll->parent()->setData( 0, Qt::UserRole, ll->parent()->checkState( 0 ) );
|
|
1544 |
lg->updateCheckState();
|
|
1545 |
lg->setData( 0, Qt::UserRole, lg->checkState( 0 ) );
|
|
1546 |
lg = dynamic_cast<QgsLegendGroup*>( lg->parent() );
|
1556 |
1547 |
}
|
|
1548 |
|
1557 |
1549 |
// If it was on, turn it back on, otherwise leave it
|
1558 |
1550 |
// off, as turning it on causes a refresh.
|
1559 |
1551 |
if ( renderFlagState )
|
... | ... | |
1708 |
1700 |
|
1709 |
1701 |
bool QgsLegend::checkLayerOrderUpdate()
|
1710 |
1702 |
{
|
1711 |
|
std::deque<QString> layersAfterRelease = layerIDs(); //test if canvas redraw is really necessary
|
|
1703 |
QStringList layersAfterRelease = layerIDs(); //test if canvas redraw is really necessary
|
1712 |
1704 |
if ( layersAfterRelease != mLayersPriorToMove )
|
1713 |
1705 |
{
|
1714 |
1706 |
// z-order has changed - update layer set
|
... | ... | |
1761 |
1753 |
QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer *>( item );
|
1762 |
1754 |
if ( ll )
|
1763 |
1755 |
{
|
1764 |
|
ll->setCheckState( 0, ( lst.contains( ll->layer() ) ? Qt::Checked : Qt::Unchecked ) );
|
|
1756 |
ll->setCheckState( 0, lst.contains( ll->layer() ) ? Qt::Checked : Qt::Unchecked );
|
1765 |
1757 |
}
|
1766 |
1758 |
}
|
1767 |
1759 |
}
|