Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Change behaviour of legend layer reordering with the mouse. The code …
…needs major cleanup, but the we need to settle on behaviour first.

git-svn-id: http://svn.osgeo.org/qgis/trunk@11233 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
homann committed Jul 31, 2009
1 parent ddba669 commit 97da8f5
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 61 deletions.
203 changes: 143 additions & 60 deletions src/app/legend/qgslegend.cpp
Expand Up @@ -75,6 +75,14 @@ QgsLegend::QgsLegend( QWidget * parent, const char *name )
connect( QgsProject::instance(), SIGNAL( writeProject( QDomDocument & ) ),
this, SLOT( writeProject( QDomDocument & ) ) );

// Initialise the line indicator widget.
mInsertionLine = new QWidget(viewport());
hideLine();
mInsertionLine->setAutoFillBackground(true);
QPalette pal = mInsertionLine->palette();
pal.setColor(mInsertionLine->backgroundRole(), Qt::blue);
mInsertionLine->setPalette(pal);

setSortingEnabled( false );
setDragEnabled( false );
setAutoScroll( true );
Expand All @@ -91,7 +99,9 @@ QgsLegend::QgsLegend( QWidget * parent, const char *name )
}

QgsLegend::~QgsLegend()
{}
{
delete mInsertionLine;
}

void QgsLegend::handleCurrentItemChanged( QTreeWidgetItem* current, QTreeWidgetItem* previous )
{
Expand Down Expand Up @@ -237,85 +247,97 @@ void QgsLegend::mouseMoveEvent( QMouseEvent * e )

// change the cursor appropriate to if drop is allowed
QTreeWidgetItem* item = itemAt( p );

hideLine();

QgsLegendItem* origin = dynamic_cast<QgsLegendItem*>( mItemBeingMoved );
QgsLegendItem* dest = dynamic_cast<QgsLegendItem*>( item );

if ( !item )
{
setCursor( QCursor( Qt::ForbiddenCursor ) );
}

if ( item && ( item != mItemBeingMoved ) )
if ( item )
{
mDropTarget = item;
QgsLegendItem::DRAG_ACTION action = dest->accept( origin );
if ( yCoordAboveCenter( dest, e->y() ) ) //over center of item
if ( item != mItemBeingMoved )
{
if ( action == QgsLegendItem::REORDER )
if ( yCoordAboveCenter( dest, e->y() ) ) //over center of item
{
if ( origin->nextSibling() != dest )
int line_y = visualItemRect(item).top() + 1;
int line_left = visualItemRect(item).left();

if ( action == QgsLegendItem::REORDER || action == QgsLegendItem::INSERT )
{
moveItem( dest, origin );setCurrentItem( origin );
QgsDebugMsg( "mouseMoveEvent::INSERT or REORDER" );
mDropAction = BEFORE;
showLine( line_y, line_left);
setCursor( QCursor( Qt::SizeVerCursor ) );
}
setCurrentItem( origin );
setCursor( QCursor( Qt::SizeVerCursor ) );
}
else if ( action == QgsLegendItem::INSERT )
{
setCursor( QCursor( Qt::PointingHandCursor ) );
if ( origin->parent() != dest )
else //no action
{
insertItem( origin, dest );
QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );
mDropAction = NO_ACTION;
setCursor( QCursor( Qt::ForbiddenCursor ) );
}
setCurrentItem( origin );
setCursor( QCursor( Qt::PointingHandCursor ) );
}
else //no action
else // below center of item
{
QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );
int line_y = visualItemRect(item).bottom() - 2;
int line_left = visualItemRect(item).left();

if ( origin->type() == QgsLegendItem::LEGEND_LAYER_FILE && mItemBeingMovedOrigPos != getItemPos( mItemBeingMoved ) )
if ( action == QgsLegendItem::REORDER )
{
resetToInitialPosition( mItemBeingMoved );
QgsDebugMsg( "mouseMoveEvent::REORDER bottom half" );
mDropAction = AFTER;
showLine( line_y, line_left);
setCursor( QCursor( Qt::SizeVerCursor ) );
}
setCursor( QCursor( Qt::ForbiddenCursor ) );
}
}
else // below center of item
{

if ( action == QgsLegendItem::REORDER )
{
QgsDebugMsg( "mouseMoveEvent::REORDER bottom half" );
if ( mItemBeingMoved != dest->nextSibling() )
{
//origin->moveItem(dest);
moveItem( origin, dest );
}
setCursor( QCursor( Qt::SizeVerCursor ) );
setCurrentItem( origin );
}
else if ( action == QgsLegendItem::INSERT )
{
QgsDebugMsg( "mouseMoveEvent::INSERT" );

setCursor( QCursor( Qt::PointingHandCursor ) );
if ( origin->parent() != dest )
else if ( action == QgsLegendItem::INSERT )
{
insertItem( origin, dest );
setCurrentItem( origin );
QgsDebugMsg( "mouseMoveEvent::INSERT" );
mDropAction = INTO_GROUP;
showLine( line_y, line_left);
setCursor( QCursor( Qt::SizeVerCursor ) );
}
}
else//no action
{
QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );

if ( origin->type() == QgsLegendItem::LEGEND_LAYER_FILE && mItemBeingMovedOrigPos != getItemPos( mItemBeingMoved ) )
else//no action
{
resetToInitialPosition( mItemBeingMoved );
mDropAction = NO_ACTION;
QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );
setCursor( QCursor( Qt::ForbiddenCursor ) );
}
setCursor( QCursor( Qt::ForbiddenCursor ) );
}
}
else
{
setCursor( QCursor( Qt::ForbiddenCursor ) );
}
}
else if (!item && e->pos().y() >= 0 && e->pos().y() < viewport()->height() && e->pos().x() >= 0 && e->pos().x() < viewport()->width() )
{
// Outside the listed items, but check if we are in the empty area
// of the viewport, so we can drop after the last top level item.
QgsDebugMsg( "You are below the table" );
mDropTarget = topLevelItem( topLevelItemCount() - 1 );
dest = dynamic_cast<QgsLegendItem*>( mDropTarget );
QgsLegendItem::DRAG_ACTION action = dest->accept( origin );
if ( action == QgsLegendItem::REORDER || action == QgsLegendItem::INSERT )
{
QgsDebugMsg( "mouseMoveEvent::INSERT or REORDER" );
mDropAction = AFTER;
showLine(visualItemRect( lastVisibleItem() ).bottom() + 1, 0);
setCursor( QCursor( Qt::SizeVerCursor ) );
}
else //no action
{
QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );
mDropAction = NO_ACTION;
setCursor( QCursor( Qt::ForbiddenCursor ) );
}
}

else
{
QgsDebugMsg( "No item here" );
mDropTarget = NULL;
setCursor( QCursor( Qt::ForbiddenCursor ) );
}
}
}
Expand All @@ -332,13 +354,15 @@ void QgsLegend::mouseReleaseEvent( QMouseEvent * e )
return;
}

QTreeWidgetItem *destItem = itemAt( e->pos() );
hideLine();

QTreeWidgetItem *destItem = mDropTarget;

QgsLegendItem* origin = dynamic_cast<QgsLegendItem*>( mItemBeingMoved );
QgsLegendItem* dest = dynamic_cast<QgsLegendItem*>( destItem );

// no change?
if ( !dest || !origin )
if ( !dest || !origin || (dest == origin) )
{
checkLayerOrderUpdate();
return;
Expand Down Expand Up @@ -404,7 +428,40 @@ void QgsLegend::mouseReleaseEvent( QMouseEvent * e )
}
else
{
// Do the actual move here.
QgsDebugMsg( "Other type of drag'n'drop happened!" );
if ( mDropAction == AFTER) //over center of item
{
QgsDebugMsg( "Drop AFTER" );
if ( dest->nextSibling() != origin )
{
moveItem( origin, dest );
setCurrentItem( origin );
}
}
else if ( mDropAction == BEFORE )// below center of item
{
QgsDebugMsg( "Drop BEFORE" );
if ( dest->findYoungerSibling() != origin )
{
moveItem( origin, dest ); // Insert after, as above...
moveItem( dest, origin ); // ... and then switch places!
setCurrentItem( origin );
}
}
else if ( mDropAction == INTO_GROUP )
{
QgsDebugMsg( "Drop INTO_GROUP" );
if ( origin->parent() != dest )
{
insertItem( origin, dest );
setCurrentItem( origin );
}
}
else//no action
{
QgsDebugMsg( "Drop NO_ACTION" );
}
}

checkLayerOrderUpdate();
Expand Down Expand Up @@ -1375,6 +1432,9 @@ void QgsLegend::insertItem( QTreeWidgetItem* move, QTreeWidgetItem* into )

void QgsLegend::moveItem( QTreeWidgetItem* move, QTreeWidgetItem* after )
{
QgsDebugMsg( QString( "Moving layer : %1 (%2)" ).arg( move->text( 0 ) ).arg( move->type() ) );
QgsDebugMsg( QString( "after layer : %1 (%2)" ).arg( after->text( 0 ) ).arg( after->type() ) );

static_cast<QgsLegendItem*>( move )->storeAppearanceSettings();//store settings in the moved item and its childern
if ( move->parent() )
{
Expand Down Expand Up @@ -1921,3 +1981,26 @@ bool QgsLegend::checkLayerOrderUpdate()
}
return false;
}

void QgsLegend::hideLine()
{
mInsertionLine->setGeometry(0, -100, 1, 1);
}

void QgsLegend::showLine(int y, int left)
{
mInsertionLine->setGeometry(left, y, viewport()->width(), 2);
}

QTreeWidgetItem * QgsLegend::lastVisibleItem()
{
QTreeWidgetItem *current;
QTreeWidgetItem *next;

current = topLevelItem( topLevelItemCount() - 1 );
while ( ( next = itemBelow( current ) ) )
{
current = next;
}
return current;
}
25 changes: 24 additions & 1 deletion src/app/legend/qgslegend.h
Expand Up @@ -300,6 +300,28 @@ class QgsLegend : public QTreeWidget
/**This function compares the layer order before a drag with the current layer ordering and triggers a canvas repaint if it has changed*/
bool checkLayerOrderUpdate();

/**The target that the mouse is over when dragging */
QTreeWidgetItem *mDropTarget;

enum DROP_ACTION_TYPE
{
BEFORE,
AFTER,
INTO_GROUP,
NO_ACTION
};
/** Set when mouse is moved over different kind of items, depending opn what they accept() */
DROP_ACTION_TYPE mDropAction;

/** Hide the line that indicates insertion position */
void hideLine();

/** Show the line that indicates insertion position */
void showLine(int y, int left);

/** Returns the last visible item in the tree widget */
QTreeWidgetItem *lastVisibleItem();

private slots:

/**Calls 'handleRightClickEvent' on the item*/
Expand Down Expand Up @@ -416,7 +438,8 @@ class QgsLegend : public QTreeWidget

} mPixmaps;


//! Widget that holds the indicator line //
QWidget *mInsertionLine;

signals:
void zOrderChanged( QgsLegend * lv );
Expand Down

0 comments on commit 97da8f5

Please sign in to comment.