[QGIS Commit] r11233 - trunk/qgis/src/app/legend

svn_qgis at osgeo.org svn_qgis at osgeo.org
Fri Jul 31 18:37:52 EDT 2009


Author: homann
Date: 2009-07-31 18:37:52 -0400 (Fri, 31 Jul 2009)
New Revision: 11233

Modified:
   trunk/qgis/src/app/legend/qgslegend.cpp
   trunk/qgis/src/app/legend/qgslegend.h
Log:
Change behaviour of legend layer reordering with the mouse. The code needs major cleanup, but the we need to settle on behaviour first.

Modified: trunk/qgis/src/app/legend/qgslegend.cpp
===================================================================
--- trunk/qgis/src/app/legend/qgslegend.cpp	2009-07-31 20:06:50 UTC (rev 11232)
+++ trunk/qgis/src/app/legend/qgslegend.cpp	2009-07-31 22:37:52 UTC (rev 11233)
@@ -75,6 +75,14 @@
   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 );
@@ -91,7 +99,9 @@
 }
 
 QgsLegend::~QgsLegend()
-{}
+{
+  delete mInsertionLine;
+}
 
 void QgsLegend::handleCurrentItemChanged( QTreeWidgetItem* current, QTreeWidgetItem* previous )
 {
@@ -237,86 +247,98 @@
 
     // 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 )
+    if ( item )
     {
-      setCursor( QCursor( Qt::ForbiddenCursor ) );
-    }
-
-    if ( item && ( item != mItemBeingMoved ) )
-    {
+      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() )
+          else if ( action == QgsLegendItem::INSERT )
           {
-            //origin->moveItem(dest);
-            moveItem( origin, dest );
+            QgsDebugMsg( "mouseMoveEvent::INSERT" );
+            mDropAction = INTO_GROUP;
+            showLine( line_y, line_left);
+            setCursor( QCursor( Qt::SizeVerCursor ) );
           }
-          setCursor( QCursor( Qt::SizeVerCursor ) );
-          setCurrentItem( origin );
-        }
-        else if ( action == QgsLegendItem::INSERT )
-        {
-          QgsDebugMsg( "mouseMoveEvent::INSERT" );
-
-          setCursor( QCursor( Qt::PointingHandCursor ) );
-          if ( origin->parent() != dest )
+          else//no action
           {
-            insertItem( origin, dest );
-            setCurrentItem( origin );
+            mDropAction = NO_ACTION;
+            QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );
+            setCursor( QCursor( Qt::ForbiddenCursor ) );
           }
         }
-        else//no action
-        {
-          QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );
-
-          if ( origin->type() == QgsLegendItem::LEGEND_LAYER_FILE && mItemBeingMovedOrigPos != getItemPos( mItemBeingMoved ) )
-          {
-            resetToInitialPosition( mItemBeingMoved );
-          }
-          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 ) );
+    }
   }
 }
 
@@ -332,13 +354,15 @@
     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;
@@ -404,7 +428,40 @@
   }
   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();
@@ -1375,6 +1432,9 @@
 
 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() )
   {
@@ -1921,3 +1981,26 @@
   }
   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;
+}

Modified: trunk/qgis/src/app/legend/qgslegend.h
===================================================================
--- trunk/qgis/src/app/legend/qgslegend.h	2009-07-31 20:06:50 UTC (rev 11232)
+++ trunk/qgis/src/app/legend/qgslegend.h	2009-07-31 22:37:52 UTC (rev 11233)
@@ -300,6 +300,28 @@
     /**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*/
@@ -416,8 +438,9 @@
 
     } mPixmaps;
 
+    //! Widget that holds the indicator line //
+    QWidget *mInsertionLine;
 
-
   signals:
     void zOrderChanged( QgsLegend * lv );
 



More information about the QGIS-commit mailing list