[QGIS Commit] r8493 - in trunk/qgis/src: app ui

svn_qgis at osgeo.org svn_qgis at osgeo.org
Thu May 22 14:52:30 EDT 2008


Author: jef
Date: 2008-05-22 14:52:30 -0400 (Thu, 22 May 2008)
New Revision: 8493

Modified:
   trunk/qgis/src/app/qgssinglesymboldialog.cpp
   trunk/qgis/src/app/qgssinglesymboldialog.h
   trunk/qgis/src/app/qgsuniquevaluedialog.cpp
   trunk/qgis/src/app/qgsuniquevaluedialog.h
   trunk/qgis/src/ui/qgsuniquevaluedialogbase.ui
Log:
enhance unique value dialog:

- allow selection of multiple classes
- new 'add class' button (fixes #1099)
- new 'reset colors' button to reset the color of selected/all classes to white
- new 'randomize colors' button to randomly set colors of selected/all classes
- 'remove classes' removes selected classes
- change common attributes for multiple selected classes at once
- allow renaming of classes
- 'Classify' now adds missing instead of recreating all classes
- used QMap instead for std::map for classes


Modified: trunk/qgis/src/app/qgssinglesymboldialog.cpp
===================================================================
--- trunk/qgis/src/app/qgssinglesymboldialog.cpp	2008-05-22 08:33:53 UTC (rev 8492)
+++ trunk/qgis/src/app/qgssinglesymboldialog.cpp	2008-05-22 18:52:30 UTC (rev 8493)
@@ -42,7 +42,7 @@
 #endif
 }
 
-QgsSingleSymbolDialog::QgsSingleSymbolDialog(QgsVectorLayer * layer): QDialog(), mVectorLayer(layer)
+QgsSingleSymbolDialog::QgsSingleSymbolDialog(QgsVectorLayer * layer, bool disabled): QDialog(), mVectorLayer(layer)
 {
   setupUi(this);
 
@@ -87,34 +87,34 @@
     ++myCounter;
   }
 
-    // Find out the numerical fields of mVectorLayer, and populate the ComboBox
-    QgsVectorDataProvider *provider = mVectorLayer->getDataProvider();
-    if (provider)
+  // Find out the numerical fields of mVectorLayer, and populate the ComboBox
+  QgsVectorDataProvider *provider = mVectorLayer->getDataProvider();
+  if (provider)
+  {
+    const QgsFieldMap & fields = provider->fields();
+    QString str;
+
+    mRotationClassificationComboBox->insertItem(DO_NOT_USE_STR);
+    mScaleClassificationComboBox->insertItem(DO_NOT_USE_STR);
+    mFieldMap.insert(std::make_pair(DO_NOT_USE_STR, -1));
+    for (QgsFieldMap::const_iterator it = fields.begin(); 
+        it != fields.end(); 
+        ++it)
     {
-      const QgsFieldMap & fields = provider->fields();
-      QString str;
-      
-      mRotationClassificationComboBox->insertItem(DO_NOT_USE_STR);
-      mScaleClassificationComboBox->insertItem(DO_NOT_USE_STR);
-      mFieldMap.insert(std::make_pair(DO_NOT_USE_STR, -1));
-      for (QgsFieldMap::const_iterator it = fields.begin(); 
-           it != fields.end(); 
-           ++it)
+      QVariant::Type type = (*it).type();
+      if (type == QVariant::Int || type == QVariant::Double)
       {
-        QVariant::Type type = (*it).type();
-        if (type == QVariant::Int || type == QVariant::Double)
-        {
-          mRotationClassificationComboBox->insertItem(it->name());
-          mScaleClassificationComboBox->insertItem(it->name());
-          mFieldMap.insert(std::make_pair(it->name(), it.key()));
-        }
+        mRotationClassificationComboBox->insertItem(it->name());
+        mScaleClassificationComboBox->insertItem(it->name());
+        mFieldMap.insert(std::make_pair(it->name(), it.key()));
       }
-    } 
-    else
-    {
-      qWarning("Warning, data provider is null in QgsSingleSymbolDialog::QgsSingleSymbolDialog(...)");
-      return;
     }
+  } 
+  else
+  {
+    qWarning("Warning, data provider is null in QgsSingleSymbolDialog::QgsSingleSymbolDialog(...)");
+    return;
+  }
   //
   //set outline / line style
   //
@@ -145,42 +145,39 @@
   cboFillStyle->addItem(QIcon(QgsSymbologyUtils::char2PatternPixmap("NoBrush")),tr("No Brush"),"NoBrush");
   cboFillStyle->addItem(QIcon(QgsSymbologyUtils::char2PatternPixmap("TexturePattern")),tr("Texture"),"TexturePattern");
 
-  if (mVectorLayer)
+  if( mVectorLayer && mVectorLayer->vectorType() != QGis::Point) {
+    mGroupPoint->setVisible(false);
+    mGroupPoint->setEnabled(false);
+  }
+
+  if(disabled)
   {
-    const QgsSingleSymbolRenderer *renderer=dynamic_cast<const QgsSingleSymbolRenderer*>(mVectorLayer->renderer());
+    unset();
+  }
+  else
+  {
+    if(mVectorLayer)
+    {
+      const QgsSingleSymbolRenderer *renderer=dynamic_cast<const QgsSingleSymbolRenderer*>(mVectorLayer->renderer());
 
-    if (renderer)
-    {
-      // Set from the existing renderer
-      set ( renderer->symbols().first() );
+      if (renderer)
+      {
+        // Set from the existing renderer
+        set ( renderer->symbols().first() );
+      }
+      else
+      {
+        // Take values from an example instance
+        QgsSingleSymbolRenderer exampleRenderer = QgsSingleSymbolRenderer( mVectorLayer->vectorType() );
+        set ( exampleRenderer.symbols().first() );
+      }
     }
     else
     {
-      // Take values from an example instance
-      QgsSingleSymbolRenderer exampleRenderer = QgsSingleSymbolRenderer( mVectorLayer->vectorType() );
-      set ( exampleRenderer.symbols().first() );
+      qWarning("Warning, layer is a null pointer in "
+          "QgsSingleSymbolDialog::QgsSingleSymbolDialog(QgsVectorLayer)");
     }
-
-    if (mVectorLayer && mVectorLayer->vectorType() == QGis::Line)
-    {
-      btnFillColor->setEnabled(false);
-      cboFillStyle->setEnabled(false);
-      mGroupPoint->setEnabled(false);
-      mGroupPoint->setVisible(false);
-    }
-
-    if (mVectorLayer && mVectorLayer->vectorType() == QGis::Polygon) 
-    {
-      mGroupPoint->setEnabled(false);
-      mGroupPoint->setVisible(false);
-    }
-
   }
-  else
-  {
-    qWarning("Warning, layer is a null pointer in "
-        "QgsSingleSymbolDialog::QgsSingleSymbolDialog(QgsVectorLayer)");
-  }
 
   //do the signal/slot connections
   connect(btnOutlineColor, SIGNAL(clicked()), this, SLOT(selectOutlineColor()));
@@ -188,12 +185,12 @@
   connect(outlinewidthspinbox, SIGNAL(valueChanged(double)), this, SLOT(resendSettingsChanged()));
   connect(mLabelEdit, SIGNAL(textChanged(const QString&)), this, SLOT(resendSettingsChanged()));
   connect (lstSymbols,SIGNAL(currentItemChanged ( QListWidgetItem * , QListWidgetItem * )),
-        this, SLOT (symbolChanged (QListWidgetItem * , QListWidgetItem * )));
+      this, SLOT (symbolChanged (QListWidgetItem * , QListWidgetItem * )));
   connect(mPointSizeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(resendSettingsChanged()));
   connect(mRotationClassificationComboBox, SIGNAL(currentIndexChanged(const QString &)),
-          this, SLOT(resendSettingsChanged()));
+      this, SLOT(resendSettingsChanged()));
   connect(mScaleClassificationComboBox, SIGNAL(currentIndexChanged(const QString &)),
-          this, SLOT(resendSettingsChanged()));
+      this, SLOT(resendSettingsChanged()));
   connect(cboOutlineStyle, SIGNAL(
         currentIndexChanged ( const QString & )), this, SLOT(resendSettingsChanged()));
   connect(cboFillStyle, SIGNAL(
@@ -202,6 +199,7 @@
   connect(cboFillStyle, SIGNAL(
         currentIndexChanged ( int )), this, SLOT(fillStyleChanged(int)));
   connect(toolSelectTexture, SIGNAL(clicked()), this, SLOT(selectTextureImage()));
+
 }
 
 QgsSingleSymbolDialog::~QgsSingleSymbolDialog()
@@ -251,55 +249,77 @@
 
 void QgsSingleSymbolDialog::apply( QgsSymbol *sy )
 {
-    //query the values of the widgets and set the symbology of the vector layer
+  //query the values of the widgets and set the symbology of the vector layer
+  if( btnFillColor->isEnabled() )
     sy->setFillColor(btnFillColor->color());
+
+  if( outlinewidthspinbox->isEnabled() )
     sy->setLineWidth(outlinewidthspinbox->value());
+
+  if( btnOutlineColor->isEnabled() )
     sy->setColor(btnOutlineColor->color());
 
-    //
-    // Apply point symbol
-    // 
-    if ( lstSymbols->currentItem() )
-    {
-      sy->setNamedPointSymbol( lstSymbols->currentItem()->data(Qt::UserRole).toString() ) ;
-    }
+  //
+  // Apply point symbol
+  // 
+  if ( lstSymbols->isEnabled() && lstSymbols->currentItem() )
+  {
+    sy->setNamedPointSymbol( lstSymbols->currentItem()->data(Qt::UserRole).toString() ) ;
+  }
+
+  if( mPointSizeSpinBox->isEnabled() )
     sy->setPointSize ( mPointSizeSpinBox->value() );
 
+
+  std::map<QString,int>::iterator iter;
+  if( mRotationClassificationComboBox->isEnabled() )
+  {
     sy->setRotationClassificationField(-1);
-    sy->setScaleClassificationField(-1);
 
-    std::map<QString,int>::iterator iter=mFieldMap.find(mRotationClassificationComboBox->currentText());
+    iter=mFieldMap.find(mRotationClassificationComboBox->currentText());
     if(iter!=mFieldMap.end())
     {
       sy->setRotationClassificationField(iter->second);
     }
+  }
 
+  if( mScaleClassificationComboBox->isEnabled() )
+  {
+    sy->setScaleClassificationField(-1);
     iter = mFieldMap.find(mScaleClassificationComboBox->currentText());
     if(iter!=mFieldMap.end())
     {
       sy->setScaleClassificationField(iter->second);
     }
-    
-    //
-    // Apply the line style
-    //
+  }
+
+  //
+  // Apply the line style
+  //
+  if( cboOutlineStyle->isEnabled() )
+  {
     QString myLineStyle = 
       cboOutlineStyle->itemData(cboOutlineStyle->currentIndex(),Qt::UserRole).toString();
-     sy->setLineStyle(QgsSymbologyUtils::qString2PenStyle(myLineStyle));
+    sy->setLineStyle(QgsSymbologyUtils::qString2PenStyle(myLineStyle));
+  }
 
-    //
-    // Apply the pattern
-    //
+  //
+  // Apply the pattern
+  //
 
-    //Store the file path, and set the brush to TexturePattern.  If we have a different button selected,
-    // the below code will override it, but leave the file path alone.
-   
-    sy->setCustomTexture(mTexturePath);
+  //Store the file path, and set the brush to TexturePattern.  If we have a different button selected,
+  // the below code will override it, but leave the file path alone.
 
+  sy->setCustomTexture(mTexturePath);
+
+  if( cboFillStyle->isEnabled() )
+  {
     QString myFillStyle = 
       cboFillStyle->itemData(cboFillStyle->currentIndex(),Qt::UserRole).toString();
     sy->setFillStyle(QgsSymbologyUtils::qString2BrushStyle(myFillStyle));
+  }
 
+  if( mLabelEdit->isEnabled() )
     sy->setLabel(mLabelEdit->text());
 }
 
@@ -315,10 +335,24 @@
   mVectorLayer->setRenderer(renderer);
 }
 
-void QgsSingleSymbolDialog::set ( const QgsSymbol *sy ) 
+void QgsSingleSymbolDialog::unset()
 {
+  mLabelEdit->setEnabled(false);
+  lstSymbols->setEnabled(false);
+  mPointSizeSpinBox->setEnabled(false);
+  mRotationClassificationComboBox->setEnabled(false);
+  mScaleClassificationComboBox->setEnabled(false);
+  outlinewidthspinbox->setEnabled(false);
+  btnOutlineColor->setEnabled(false);
+  cboOutlineStyle->setEnabled(false);
+
+  cboFillStyle->setEnabled(false);
+  btnFillColor->setEnabled(false);
+}
+
+void QgsSingleSymbolDialog::set ( const QgsSymbol *sy )
+{
   //set label
-
   mLabelEdit->setText(sy->label());
 
   // Set point symbol
@@ -352,7 +386,6 @@
   mRotationClassificationComboBox->setCurrentText(rotationclassfield);
   mScaleClassificationComboBox->setCurrentText(scaleclassfield);
 
-
   outlinewidthspinbox->setValue(sy->pen().widthF());
 
   //set line width 1 as minimum to avoid confusion between line width 0 and no pen line style
@@ -368,7 +401,7 @@
   //
   // Set the line style combo
   //
-  
+
   QPen myPen = sy->pen();
   QString myLineStyle = QgsSymbologyUtils::penStyle2QString(myPen.style());
   for ( int i = 0; i < cboOutlineStyle->count(); ++i )
@@ -383,7 +416,7 @@
   //
   // Set the brush combo
   //
-  
+
   QBrush myBrush = sy->brush();
   QString myFillStyle =  QgsSymbologyUtils::brushStyle2QString(myBrush.style());
   for ( int i = 0; i < cboFillStyle->count(); ++i )
@@ -394,7 +427,7 @@
       break;
     }
   }
-  
+
   //get and show the file path, even if we aren't using it.
   mTexturePath = sy->customTexture(); 
   //if the file path isn't empty, show the image on the button
@@ -408,8 +441,80 @@
     //show the default question mark
     //texture->setPixmap(QgsSymbologyUtils::char2PatternPixmap("TexturePattern")); 
   }
+
+  mLabelEdit->setEnabled(true);
+  lstSymbols->setEnabled(true);
+  mPointSizeSpinBox->setEnabled(true);
+  mRotationClassificationComboBox->setEnabled(true);
+  mScaleClassificationComboBox->setEnabled(true);
+  outlinewidthspinbox->setEnabled(true);
+  btnOutlineColor->setEnabled(true);
+  cboOutlineStyle->setEnabled(true);
+
+  if (mVectorLayer && mVectorLayer->vectorType() != QGis::Line)
+  {
+    btnFillColor->setEnabled(true);
+    cboFillStyle->setEnabled(true);
+  }
 }
 
+void QgsSingleSymbolDialog::updateSet( const QgsSymbol *sy )
+{
+  if( mLabelEdit->isEnabled() && mLabelEdit->text() != sy->label() )
+    mLabelEdit->setEnabled(false);
+
+  if( lstSymbols->isEnabled() && lstSymbols->currentItem()->data( Qt::UserRole ).toString() != sy->pointSymbolName() )
+    lstSymbols->setEnabled(false);
+
+  if( mPointSizeSpinBox->isEnabled() && mPointSizeSpinBox->value()!=sy->pointSize() )
+    mPointSizeSpinBox->setEnabled(false);
+
+  QString rotationclassfield = DO_NOT_USE_STR;
+  QString scaleclassfield = DO_NOT_USE_STR;
+  for(std::map<QString,int>::iterator it=mFieldMap.begin();it!=mFieldMap.end();++it)
+  {
+    if(it->second == sy->rotationClassificationField())
+    {
+      rotationclassfield=it->first;
+      QgsDebugMsg(QString("Found rotation field " + rotationclassfield));
+    }
+    if(it->second == sy->scaleClassificationField())
+    {
+      scaleclassfield=it->first;
+      QgsDebugMsg(QString("Found scale field " + scaleclassfield));
+    }
+  }
+
+  if( mRotationClassificationComboBox->isEnabled() && mRotationClassificationComboBox->currentText()!=rotationclassfield )
+    mRotationClassificationComboBox->setEnabled(false);
+
+  if( mScaleClassificationComboBox->isEnabled() && mScaleClassificationComboBox->currentText()!=scaleclassfield )
+    mScaleClassificationComboBox->setEnabled(false);
+
+  if( outlinewidthspinbox->isEnabled() && outlinewidthspinbox->value() != sy->pen().widthF() )
+    outlinewidthspinbox->setEnabled(false);
+
+  if( btnFillColor->isEnabled() &&  btnFillColor->color() != sy->brush().color() )
+    btnFillColor->setEnabled(false);
+
+  if( btnOutlineColor->isEnabled() &&  btnOutlineColor->color() != sy->pen().color() )
+    btnOutlineColor->setEnabled(false);
+
+  if( cboOutlineStyle->isEnabled() ) {
+    QPen myPen = sy->pen();
+    QString myLineStyle = QgsSymbologyUtils::penStyle2QString(myPen.style());
+    if (cboOutlineStyle->itemData( cboOutlineStyle->currentIndex(), Qt::UserRole ).toString() != myLineStyle)
+      cboOutlineStyle->setEnabled(false);
+  }
+
+  if( cboFillStyle->isEnabled() ) {
+    QBrush myBrush = sy->brush();
+    QString myFillStyle =  QgsSymbologyUtils::brushStyle2QString(myBrush.style());
+    if (cboFillStyle->itemData( cboFillStyle->currentIndex(), Qt::UserRole ).toString() != myFillStyle)
+      cboFillStyle->setEnabled(false);
+  }
+}
+
 void QgsSingleSymbolDialog::setOutlineColor(QColor& c)
 {
     btnOutlineColor->setColor(c);
@@ -525,3 +630,4 @@
   }
 
 }
+

Modified: trunk/qgis/src/app/qgssinglesymboldialog.h
===================================================================
--- trunk/qgis/src/app/qgssinglesymboldialog.h	2008-05-22 08:33:53 UTC (rev 8492)
+++ trunk/qgis/src/app/qgssinglesymboldialog.h	2008-05-22 18:52:30 UTC (rev 8493)
@@ -31,7 +31,7 @@
 {
     Q_OBJECT
 public:
-    QgsSingleSymbolDialog(QgsVectorLayer* layer);
+    QgsSingleSymbolDialog(QgsVectorLayer* layer, bool disabled = false);
     ~QgsSingleSymbolDialog();
     QColor getOutlineColor();
     Qt::PenStyle getOutlineStyle();
@@ -46,7 +46,6 @@
     void setLabel(QString label);
     QString label();
 
-
 protected:
     QgsVectorLayer* mVectorLayer;
     /**Stores the names and numbers of the fields with numeric values*/
@@ -55,7 +54,9 @@
 
 public slots:
     /* arrange the widgets on this dialog to reflect the current state of QgsSymbol */
+    void unset();
     void set(const QgsSymbol *sy);
+    void updateSet(const QgsSymbol *sy);
     /**applies the changes to the vector layer*/
     void apply();
     /**applies the changes to the QgsSymbol */

Modified: trunk/qgis/src/app/qgsuniquevaluedialog.cpp
===================================================================
--- trunk/qgis/src/app/qgsuniquevaluedialog.cpp	2008-05-22 08:33:53 UTC (rev 8492)
+++ trunk/qgis/src/app/qgsuniquevaluedialog.cpp	2008-05-22 18:52:30 UTC (rev 8493)
@@ -26,7 +26,7 @@
 
 #include "qgslogger.h"
 
-QgsUniqueValueDialog::QgsUniqueValueDialog(QgsVectorLayer* vl): QDialog(), mVectorLayer(vl), sydialog(vl)
+QgsUniqueValueDialog::QgsUniqueValueDialog(QgsVectorLayer* vl): QDialog(), mVectorLayer(vl), sydialog(vl, true)
 {
   setupUi(this);
   setOrientation(Qt::Vertical);
@@ -42,13 +42,17 @@
       str = (*it).name();
       mClassificationComboBox->insertItem(str);
     }
-  } 
+  }
   else
   {
     qWarning("Warning, data provider is null in QgsUniqueValueDialog::QgsUniqueValueDialog");
     return;
   }
 
+  mClassListWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
+  mClassListWidget->setEditTriggers(QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::AnyKeyPressed);
+  mClassListWidget->setSortingEnabled(true);
+
   const QgsUniqueValueRenderer* renderer = dynamic_cast < const QgsUniqueValueRenderer * >(mVectorLayer->renderer());
 
   if (renderer)
@@ -65,7 +69,7 @@
 
     const QList<QgsSymbol*> list = renderer->symbols();
     //fill the items of the renderer into mValues
-    for(QList<QgsSymbol*>::const_iterator iter=list.begin();iter!=list.end();++iter)
+    for(QList<QgsSymbol*>::const_iterator iter=list.begin(); iter!=list.end(); ++iter)
     {
       QgsSymbol* symbol=(*iter);
       QString symbolvalue=symbol->lowerValue();
@@ -77,27 +81,37 @@
       sym->setPointSize(symbol->pointSize());
       sym->setScaleClassificationField(symbol->scaleClassificationField());
       sym->setRotationClassificationField(symbol->rotationClassificationField());
-      mValues.insert(std::make_pair(symbolvalue,sym));
-      mClassListWidget->addItem(symbolvalue);
+      mValues.insert(symbolvalue, sym);
+
+      QListWidgetItem *item = new QListWidgetItem(symbolvalue);
+      mClassListWidget->addItem(item);
+      item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsEnabled);
+      item->setData( Qt::UserRole, symbol->lowerValue() );
+      item->setToolTip(symbol->label());
     }
   }
 
+  mDeletePushButton->setEnabled(false);
+
   QObject::connect(mClassifyButton, SIGNAL(clicked()), this, SLOT(changeClassificationAttribute()));
-  QObject::connect(mDeletePushButton, SIGNAL(clicked()), this, SLOT(deleteCurrentClass()));
-  QObject::connect(mClassListWidget, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this, SLOT(changeCurrentValue()));
+  QObject::connect(mAddButton, SIGNAL(clicked()), this, SLOT(addClass()));
+  QObject::connect(mDeletePushButton, SIGNAL(clicked()), this, SLOT(deleteSelectedClasses()));
+  QObject::connect(mRandomizeColors, SIGNAL(clicked()), this, SLOT(randomizeColors()));
+  QObject::connect(mResetColors, SIGNAL(clicked()), this, SLOT(resetColors()));
+  QObject::connect(mClassListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged()));
+  QObject::connect(mClassListWidget, SIGNAL(itemChanged(QListWidgetItem *)), this, SLOT(itemChanged(QListWidgetItem *)));
   QObject::connect(&sydialog, SIGNAL(settingsChanged()), this, SLOT(applySymbologyChanges()));
   mSymbolWidgetStack->addWidget(&sydialog);
   mSymbolWidgetStack->setCurrentWidget(&sydialog);
-
-  mClassListWidget->setCurrentItem(0);
 }
 
 QgsUniqueValueDialog::~QgsUniqueValueDialog()
 {
-  std::map<QString, QgsSymbol *>::iterator myValueIterator = mValues.begin();
+  QgsDebugMsg("called.");
+  QMap<QString, QgsSymbol *>::iterator myValueIterator = mValues.begin();
   while ( myValueIterator != mValues.end() )
   {
-    delete myValueIterator->second;
+    delete myValueIterator.value();
 
     mValues.erase( myValueIterator );
 
@@ -109,12 +123,13 @@
 
 void QgsUniqueValueDialog::apply()
 {
+  QgsDebugMsg("called.");
   QgsUniqueValueRenderer *renderer = new QgsUniqueValueRenderer(mVectorLayer->vectorType());
 
   //go through mValues and add the entries to the renderer
-  for(std::map<QString,QgsSymbol*>::iterator it=mValues.begin();it!=mValues.end();++it)
+  for(QMap<QString,QgsSymbol*>::iterator it=mValues.begin();it!=mValues.end();++it)
   {
-    QgsSymbol* symbol=it->second;
+    QgsSymbol* symbol=it.value();
     QgsSymbol* newsymbol=new QgsSymbol(mVectorLayer->vectorType(), symbol->lowerValue(), symbol->upperValue(), symbol->label());
     newsymbol->setPen(symbol->pen());
     newsymbol->setCustomTexture(symbol->customTexture());
@@ -123,7 +138,7 @@
     newsymbol->setPointSize(symbol->pointSize());
     newsymbol->setScaleClassificationField(symbol->scaleClassificationField());
     newsymbol->setRotationClassificationField(symbol->rotationClassificationField());
-    renderer->insertValue(it->first,newsymbol);
+    renderer->insertValue(it.key(), newsymbol);
   }
   renderer->updateSymbolAttributes();
 
@@ -142,144 +157,271 @@
   delete renderer; //something went wrong
 }
 
-void QgsUniqueValueDialog::changeClassificationAttribute()
+
+QColor QgsUniqueValueDialog::randomColor()
 {
-  QString attributeName = mClassificationComboBox->currentText();
+  QColor thecolor;
 
-  //delete old entries
-  for(std::map<QString,QgsSymbol*>::iterator it=mValues.begin();it!=mValues.end();++it)
+  //insert a random color
+  int red = 1 + (int) (255.0 * rand() / (RAND_MAX + 1.0));
+  int green = 1 + (int) (255.0 * rand() / (RAND_MAX + 1.0));
+  int blue = 1 + (int) (255.0 * rand() / (RAND_MAX + 1.0));
+  thecolor.setRgb(red, green, blue);
+
+  return thecolor;
+}
+
+void QgsUniqueValueDialog::setSymbolColor(QgsSymbol *symbol, QColor thecolor)
+{
+  QPen pen;
+  QBrush brush;
+  if(mVectorLayer->vectorType() == QGis::Line)
+  {
+    pen.setColor(thecolor);
+    pen.setStyle(Qt::SolidLine);
+    pen.setWidthF(0.4);
+  }
+  else
+  {
+    brush.setColor(thecolor);
+    brush.setStyle(Qt::SolidPattern);
+    pen.setColor(Qt::black);
+    pen.setStyle(Qt::SolidLine);
+    pen.setWidthF(0.4);
+  }
+  symbol->setPen(pen);
+  symbol->setBrush(brush);
+}
+
+void QgsUniqueValueDialog::addClass(QString value)
+{
+  QgsDebugMsg("called.");
+  if( value.isNull() || mValues.contains(value) )
+  {
+    int i;
+    for(i=0; mValues.contains(value+QString::number(i)); i++)
+      ;
+    value += QString::number(i);
+  }
+
+  QgsSymbol *symbol=new QgsSymbol(mVectorLayer->vectorType(), value);
+  mValues.insert(value, symbol);
+
+  QListWidgetItem *item = new QListWidgetItem(value);
+  item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsEnabled);
+  item->setData( Qt::UserRole, value );
+  item->setToolTip(symbol->label());
+  mClassListWidget->addItem(item);
+
+  setSymbolColor(symbol, randomColor() );
+}
+
+void QgsUniqueValueDialog::randomizeColors()
+{
+  QList<QListWidgetItem *> selection = mClassListWidget->selectedItems();
+  if(selection.size()>0) {
+    for(int i=0; i<selection.size(); i++)
     {
-      delete it->second;
+      QListWidgetItem *item=selection[i];
+      if(!item)
+        continue;
+
+      if( !mValues.contains( item->text() ) )
+        continue;
+
+      setSymbolColor( mValues[ item->text() ], randomColor() );
     }
-  mValues.clear();
-  
-  QgsVectorDataProvider *provider = dynamic_cast<QgsVectorDataProvider *>(mVectorLayer->getDataProvider());
-  if (provider)
+  }
+  else
+  {
+    for(QMap<QString, QgsSymbol *>::iterator it = mValues.begin(); it!=mValues.end(); it++)
     {
-      QString value;
-      QgsAttributeList attlist;
-     
-      QgsSymbol* symbol;
-      int nr = provider->indexFromFieldName(attributeName);
-      if(nr == -1)
-	{
-	  return;
-	}
-      attlist.append(nr);	
-      
-      provider->select(attlist, QgsRect(), false);
-      QgsFeature feat;
-      
-      //go through all the features and insert their value into the map and into mClassListWidget
-      mClassListWidget->clear();
-      while(provider->getNextFeature(feat))
-	{
-	  const QgsAttributeMap& attrs = feat.attributeMap();
-	  value = attrs[nr].toString();
-	  
-	  if(mValues.find(value)==mValues.end())
-	    {
-	      symbol=new QgsSymbol(mVectorLayer->vectorType(), value);
-	      mValues.insert(std::make_pair(value,symbol));
-	    }
-	}
-      
-      //set symbology for all QgsSiSyDialogs
-      QColor thecolor;
-      
-      for(std::map<QString,QgsSymbol*>::iterator it=mValues.begin();it!=mValues.end();++it)
-	{
-	  //insert a random color
-	  int red = 1 + (int) (255.0 * rand() / (RAND_MAX + 1.0));
-	  int green = 1 + (int) (255.0 * rand() / (RAND_MAX + 1.0));
-	  int blue = 1 + (int) (255.0 * rand() / (RAND_MAX + 1.0));
-	  thecolor.setRgb(red, green, blue);
-	  mClassListWidget->addItem(it->first);
-	  QgsSymbol* sym=it->second;
-	  QPen pen;
-	  QBrush brush;
-	  if(mVectorLayer->vectorType() == QGis::Line)
-	    {
-	      pen.setColor(thecolor);
-	      pen.setStyle(Qt::SolidLine);
-	      pen.setWidthF(0.4);
-	    }
-	  else
-	    {
-	      brush.setColor(thecolor);
-	      brush.setStyle(Qt::SolidPattern);
-	      pen.setColor(Qt::black);
-	      pen.setStyle(Qt::SolidLine);
-	      pen.setWidthF(0.4);
-	    }
-	  sym->setPen(pen);
-	  sym->setBrush(brush);
-	}
+      setSymbolColor( it.value(), randomColor() );
     }
-  mClassListWidget->setCurrentRow(0);
+  }
+
+  selectionChanged();
 }
 
-void QgsUniqueValueDialog::changeCurrentValue()
+void QgsUniqueValueDialog::resetColors()
 {
-  sydialog.blockSignals(true);//block signal to prevent sydialog from changing the current QgsRenderItem
-  QListWidgetItem* item=mClassListWidget->currentItem();
-  if(item)
+  QColor white;
+  white.setRgb(255.0, 255.0, 255.0);
+
+  QList<QListWidgetItem *> selection = mClassListWidget->selectedItems();
+  if(selection.size()>0) {
+    for(int i=0; i<selection.size(); i++)
+    {
+      QListWidgetItem *item=selection[i];
+      if(!item)
+        continue;
+
+      if( !mValues.contains( item->text() ) )
+        continue;
+
+      setSymbolColor( mValues[ item->text() ], white);
+    }
+  }
+  else
   {
-    QString value=item->text();
-    std::map<QString,QgsSymbol*>::iterator it=mValues.find(value);
-    if(it!=mValues.end())
+    for(QMap<QString, QgsSymbol *>::iterator it = mValues.begin(); it!=mValues.end(); it++)
     {
-      sydialog.set( it->second);
-      sydialog.setLabel(it->second->label());
+      setSymbolColor( it.value(), white);
     }
-    else
+  }
+
+  selectionChanged();
+}
+
+
+void QgsUniqueValueDialog::changeClassificationAttribute()
+{
+  QgsDebugMsg("called.");
+  QString attributeName = mClassificationComboBox->currentText();
+
+  QgsVectorDataProvider *provider = dynamic_cast<QgsVectorDataProvider *>(mVectorLayer->getDataProvider());
+  if (provider)
+  {
+    QString value;
+    QgsAttributeList attlist;
+
+    int nr = provider->indexFromFieldName(attributeName);
+    if(nr == -1)
     {
-      //no entry found
+      return;
     }
+    attlist.append(nr);
+
+    provider->select(attlist, QgsRect(), false);
+    QgsFeature feat;
+
+    //go through all the features and insert their value into the map and into mClassListWidget
+    while(provider->getNextFeature(feat)) 
+    {
+      const QgsAttributeMap& attrs = feat.attributeMap();
+      value = attrs[nr].toString();
+
+      if( mValues.contains(value) )
+        continue;
+
+      addClass(value);
+    }
   }
-  sydialog.blockSignals(false);
+  mClassListWidget->setCurrentRow(0);
 }
 
-void QgsUniqueValueDialog::deleteCurrentClass()
+void QgsUniqueValueDialog::itemChanged( QListWidgetItem *item )
 {
-  QListWidgetItem* currentItem = mClassListWidget->currentItem();
-  if(!currentItem)
+  QString oldValue = item->data( Qt::UserRole ).toString();
+  QString newValue = item->text();
+
+  if(oldValue==newValue)
+    return;
+  
+  if( !mValues.contains(newValue) )
   {
-    return;
+    QgsSymbol *sy = mValues[oldValue];
+    mValues.erase(oldValue);
+    mValues.insert(newValue, sy);
+    sy->setLowerValue(newValue);
+    item->setData( Qt::UserRole, newValue );
   }
+  else
+    item->setText(oldValue);
+}
 
-  QString classValue = currentItem->text();
-  int currentIndex = mClassListWidget->currentRow();
-  mValues.erase(classValue);
-  delete (mClassListWidget->takeItem(currentIndex));
-  qWarning("numRows: ");
-  qWarning(QString::number(mClassListWidget->count()).toUtf8());
 
-  if(mClassListWidget->count() < (currentIndex + 1))
+void QgsUniqueValueDialog::selectionChanged()
+{
+  QgsDebugMsg("called.");
+  sydialog.blockSignals(true);//block signal to prevent sydialog from changing the current QgsRenderItem
+  QList<QListWidgetItem *> selection = mClassListWidget->selectedItems();
+
+  if(selection.size()==0)
   {
-    qWarning("selecting numRows - 1");
-    mClassListWidget->setCurrentRow(mClassListWidget->count() - 1);
+    mDeletePushButton->setEnabled(false);
+    sydialog.unset();
   }
   else
   {
-    qWarning("selecting currentIndex");
-    mClassListWidget->setCurrentRow(currentIndex);
+    mDeletePushButton->setEnabled(true);
+
+    if(selection.size()==1)
+    {
+      QListWidgetItem *item=selection[0];
+      if(!item)
+        return;
+
+      if( !mValues.contains( item->text() ) )
+        return;
+
+      QgsSymbol *symbol = mValues[ item->text() ];
+      sydialog.set( symbol );
+      sydialog.setLabel( symbol->label() );
+    }
+    else if(selection.size()>1)
+    {
+      if( !mValues.contains( selection[0]->text() ) )
+        return;
+
+      sydialog.set( mValues[ selection[0]->text() ] );
+
+      for(int i=1; i<selection.size(); i++)
+      {
+        if( !mValues.contains( selection[i]->text() ) )
+          continue;
+
+        sydialog.updateSet( mValues[ selection[i]->text() ] );
+      }
+    }
   }
+  sydialog.blockSignals(false);
 }
 
-void QgsUniqueValueDialog::applySymbologyChanges()
+void QgsUniqueValueDialog::deleteSelectedClasses()
 {
-  QListWidgetItem* item=mClassListWidget->currentItem();
-  if(!item)
+  QgsDebugMsg("called.");
+  QList<QListWidgetItem *> selection = mClassListWidget->selectedItems();
+  for(int i=0; i<selection.size(); i++) 
   {
-    return;
+    QListWidgetItem* currentItem = selection[i];
+    if(!currentItem)
+      continue;
+ 
+    mValues.erase( currentItem->text() );
+
+    mClassListWidget->removeItemWidget(currentItem);
+    delete currentItem;
   }
-  QString value=item->text();
-  std::map<QString,QgsSymbol*>::iterator it=mValues.find(value);
-  if(it!=mValues.end())
+
+  QgsDebugMsg( QString("numRows: %1").arg( mClassListWidget->count()) );
+}
+
+void QgsUniqueValueDialog::applySymbologyChanges()
+{
+  QgsDebugMsg("called.");
+  QList<QListWidgetItem *> selection = mClassListWidget->selectedItems();
+  for(int i=0; i<selection.size(); i++)
   {
-    it->second->setLabel(sydialog.label());
-    it->second->setLowerValue(value);
-    sydialog.apply( it->second );
+    QListWidgetItem* item=selection[i];
+    if(!item)
+    {
+      QgsDebugMsg( QString("selected item %1 not found").arg(i) );
+      continue;
+    }
+
+    QString value=item->text();
+    if( !mValues.contains( value ) ) {
+      QgsDebugMsg( QString("value %1 not found").arg(value) );
+      continue;
+    }
+
+    QgsSymbol *symbol = mValues[ value ];
+    symbol->setLabel(sydialog.label());
+    symbol->setLowerValue(value);
+    sydialog.apply(symbol);
+
+    item->setToolTip(sydialog.label());
+    item->setData( Qt::UserRole, value);
   }
 }

Modified: trunk/qgis/src/app/qgsuniquevaluedialog.h
===================================================================
--- trunk/qgis/src/app/qgsuniquevaluedialog.h	2008-05-22 08:33:53 UTC (rev 8492)
+++ trunk/qgis/src/app/qgsuniquevaluedialog.h	2008-05-22 18:52:30 UTC (rev 8493)
@@ -34,26 +34,33 @@
     ~QgsUniqueValueDialog();
 
  public slots:
-     void apply();
+    void apply();
+    void itemChanged(QListWidgetItem *item);
+    void randomizeColors();
+    void resetColors();
 
  protected:
     /**Pointer to the associated vector layer*/
     QgsVectorLayer* mVectorLayer;
     /**Set to store the already entered values*/
-    std::map<QString,QgsSymbol*> mValues;
+    QMap<QString,QgsSymbol*> mValues;
     QgsSingleSymbolDialog sydialog;
-    /**Value for which symbology settings are displayed*/
-    QString currentValue;
 
  protected slots:
     /**Set new attribut for classification*/
     void changeClassificationAttribute();
-    /**Changes the display of the single symbol dialog*/
-    void changeCurrentValue();
-    /**Removes a class from the classification*/
-    void deleteCurrentClass();
+    /**update single symbol dialog after selection changed*/
+    void selectionChanged();
+    /**add a new classes to the classification*/
+    void addClass(QString value = QString::null);
+    /**Removes the selected classes from the classification*/
+    void deleteSelectedClasses();
     /**Writes changes in the single symbol dialog to the corresponding QgsSymbol*/
     void applySymbologyChanges();
+
+private:
+    QColor randomColor();
+    void setSymbolColor(QgsSymbol *symbol, QColor thecolor);
 };
 
 #endif

Modified: trunk/qgis/src/ui/qgsuniquevaluedialogbase.ui
===================================================================
--- trunk/qgis/src/ui/qgsuniquevaluedialogbase.ui	2008-05-22 08:33:53 UTC (rev 8492)
+++ trunk/qgis/src/ui/qgsuniquevaluedialogbase.ui	2008-05-22 18:52:30 UTC (rev 8493)
@@ -5,7 +5,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>505</width>
+    <width>500</width>
     <height>408</height>
    </rect>
   </property>
@@ -69,25 +69,25 @@
      </property>
     </widget>
    </item>
-   <item row="1" column="0" >
-    <spacer>
-     <property name="orientation" >
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="sizeType" >
-      <enum>QSizePolicy::Minimum</enum>
-     </property>
-     <property name="sizeHint" >
-      <size>
-       <width>111</width>
-       <height>20</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-   <item row="1" column="1" >
+   <item row="1" column="0" colspan="2" >
     <layout class="QHBoxLayout" >
      <item>
+      <spacer>
+       <property name="orientation" >
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType" >
+        <enum>QSizePolicy::Minimum</enum>
+       </property>
+       <property name="sizeHint" stdset="0" >
+        <size>
+         <width>111</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
       <widget class="QPushButton" name="mClassifyButton" >
        <property name="text" >
         <string>Classify</string>
@@ -95,12 +95,33 @@
       </widget>
      </item>
      <item>
+      <widget class="QPushButton" name="mAddButton" >
+       <property name="text" >
+        <string>Add class</string>
+       </property>
+      </widget>
+     </item>
+     <item>
       <widget class="QPushButton" name="mDeletePushButton" >
        <property name="text" >
-        <string>Delete class</string>
+        <string>Delete classes</string>
        </property>
       </widget>
      </item>
+     <item>
+      <widget class="QPushButton" name="mRandomizeColors" >
+       <property name="text" >
+        <string>Randomize Colors</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="mResetColors" >
+       <property name="text" >
+        <string>Reset Colors</string>
+       </property>
+      </widget>
+     </item>
     </layout>
    </item>
    <item row="2" column="0" >



More information about the QGIS-commit mailing list