mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[FEATURE] Allow creation of color ramps in color ramp combo box.
git-svn-id: http://svn.osgeo.org/qgis/trunk@14421 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
8ee79eb4fb
commit
7f32157f8e
@ -2,6 +2,7 @@
|
||||
SET(QGIS_GUI_SRCS
|
||||
|
||||
symbology-ng/qgsbrushstylecombobox.cpp
|
||||
symbology-ng/qgscolorrampcombobox.cpp
|
||||
symbology-ng/qgsdashspacedialog.cpp
|
||||
symbology-ng/qgspenstylecombobox.cpp
|
||||
symbology-ng/qgssymbollayerv2widget.cpp
|
||||
@ -73,6 +74,7 @@ symbology-ng/qgssymbolv2selectordialog.h
|
||||
symbology-ng/qgsvectorgradientcolorrampv2dialog.h
|
||||
symbology-ng/qgsvectorrandomcolorrampv2dialog.h
|
||||
symbology-ng/qgsvectorcolorbrewercolorrampv2dialog.h
|
||||
symbology-ng/qgscolorrampcombobox.h
|
||||
symbology-ng/characterwidget.h
|
||||
symbology-ng/qgspenstylecombobox.h
|
||||
symbology-ng/qgsbrushstylecombobox.h
|
||||
|
@ -24,12 +24,12 @@ QgsRendererV2Widget* QgsCategorizedSymbolRendererV2Widget::create( QgsVectorLaye
|
||||
}
|
||||
|
||||
QgsCategorizedSymbolRendererV2Widget::QgsCategorizedSymbolRendererV2Widget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
|
||||
: QgsRendererV2Widget( layer, style )
|
||||
: QgsRendererV2Widget( layer, style )
|
||||
{
|
||||
|
||||
// try to recognize the previous renderer
|
||||
// (null renderer means "no previous renderer")
|
||||
if ( !renderer || renderer->type() != "categorizedSymbol" )
|
||||
if( !renderer || renderer->type() != "categorizedSymbol" )
|
||||
{
|
||||
// we're not going to use it - so let's delete the renderer
|
||||
delete renderer;
|
||||
@ -48,7 +48,9 @@ QgsCategorizedSymbolRendererV2Widget::QgsCategorizedSymbolRendererV2Widget( QgsV
|
||||
setupUi( this );
|
||||
|
||||
populateColumns();
|
||||
populateColorRamps();
|
||||
|
||||
cboCategorizedColorRamp->populate( mStyle );
|
||||
|
||||
QStandardItemModel* m = new QStandardItemModel( this );
|
||||
QStringList labels;
|
||||
labels << tr( "Symbol" ) << tr( "Value" ) << tr( "Label" );
|
||||
@ -100,7 +102,7 @@ void QgsCategorizedSymbolRendererV2Widget::updateUiFromRenderer()
|
||||
connect( cboCategorizedColumn, SIGNAL( currentIndexChanged( int ) ), this, SLOT( categoryColumnChanged() ) );
|
||||
|
||||
// set source symbol
|
||||
if ( mRenderer->sourceSymbol() )
|
||||
if( mRenderer->sourceSymbol() )
|
||||
{
|
||||
delete mCategorizedSymbol;
|
||||
mCategorizedSymbol = mRenderer->sourceSymbol()->clone();
|
||||
@ -108,15 +110,9 @@ void QgsCategorizedSymbolRendererV2Widget::updateUiFromRenderer()
|
||||
}
|
||||
|
||||
// set source color ramp
|
||||
if ( mRenderer->sourceColorRamp() )
|
||||
if( mRenderer->sourceColorRamp() )
|
||||
{
|
||||
QSize rampIconSize( 50, 16 );
|
||||
QIcon icon = QgsSymbolLayerV2Utils::colorRampPreviewIcon( mRenderer->sourceColorRamp(), rampIconSize );
|
||||
if ( cboCategorizedColorRamp->itemText( 0 ) == "[source]" )
|
||||
cboCategorizedColorRamp->setItemIcon( 0, icon );
|
||||
else
|
||||
cboCategorizedColorRamp->insertItem( 0, icon, "[source]" );
|
||||
cboCategorizedColorRamp->setCurrentIndex( 0 );
|
||||
cboCategorizedColorRamp->setSourceColorRamp( mRenderer->sourceColorRamp() );
|
||||
}
|
||||
|
||||
}
|
||||
@ -129,7 +125,7 @@ QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2Widget::renderer()
|
||||
void QgsCategorizedSymbolRendererV2Widget::changeCategorizedSymbol()
|
||||
{
|
||||
QgsSymbolV2SelectorDialog dlg( mCategorizedSymbol, mStyle, this );
|
||||
if ( !dlg.exec() )
|
||||
if( !dlg.exec() )
|
||||
return;
|
||||
|
||||
updateCategorizedSymbolIcon();
|
||||
@ -154,7 +150,7 @@ void QgsCategorizedSymbolRendererV2Widget::populateCategories()
|
||||
|
||||
// TODO: sort?? utils.sortVariantList(keys);
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
const QgsRendererCategoryV2 &cat = mRenderer->categories()[i];
|
||||
addCategory( cat );
|
||||
@ -170,26 +166,12 @@ void QgsCategorizedSymbolRendererV2Widget::populateColumns()
|
||||
cboCategorizedColumn->clear();
|
||||
const QgsFieldMap& flds = mLayer->pendingFields();
|
||||
QgsFieldMap::ConstIterator it = flds.begin();
|
||||
for ( ; it != flds.end(); ++it )
|
||||
for( ; it != flds.end(); ++it )
|
||||
{
|
||||
cboCategorizedColumn->addItem( it->name() );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsCategorizedSymbolRendererV2Widget::populateColorRamps()
|
||||
{
|
||||
QSize rampIconSize( 50, 16 );
|
||||
cboCategorizedColorRamp->setIconSize( rampIconSize );
|
||||
|
||||
QStringList rampNames = mStyle->colorRampNames();
|
||||
for ( QStringList::iterator it = rampNames.begin(); it != rampNames.end(); ++it )
|
||||
{
|
||||
QgsVectorColorRampV2* ramp = mStyle->colorRamp( *it );
|
||||
QIcon icon = QgsSymbolLayerV2Utils::colorRampPreviewIcon( ramp, rampIconSize );
|
||||
cboCategorizedColorRamp->addItem( icon, *it );
|
||||
delete ramp;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsCategorizedSymbolRendererV2Widget::addCategory( const QgsRendererCategoryV2 &cat )
|
||||
{
|
||||
@ -214,21 +196,21 @@ void QgsCategorizedSymbolRendererV2Widget::categoryColumnChanged()
|
||||
|
||||
void QgsCategorizedSymbolRendererV2Widget::categoriesDoubleClicked( const QModelIndex & idx )
|
||||
{
|
||||
if ( idx.isValid() && idx.column() == 0 )
|
||||
if( idx.isValid() && idx.column() == 0 )
|
||||
changeCategorySymbol();
|
||||
}
|
||||
|
||||
void QgsCategorizedSymbolRendererV2Widget::changeCategorySymbol()
|
||||
{
|
||||
QVariant k = currentCategory();
|
||||
if ( !k.isValid() )
|
||||
if( !k.isValid() )
|
||||
return;
|
||||
|
||||
int catIdx = mRenderer->categoryIndexForValue( k );
|
||||
QgsSymbolV2* newSymbol = mRenderer->categories()[catIdx].symbol()->clone();
|
||||
|
||||
QgsSymbolV2SelectorDialog dlg( newSymbol, mStyle, this );
|
||||
if ( !dlg.exec() )
|
||||
if( !dlg.exec() )
|
||||
{
|
||||
delete newSymbol;
|
||||
return;
|
||||
@ -246,7 +228,7 @@ static void _createCategories( QgsCategoryList& cats, QList<QVariant>& values, Q
|
||||
|
||||
int num = values.count();
|
||||
|
||||
for ( int i = 0; i < num; i++ )
|
||||
for( int i = 0; i < num; i++ )
|
||||
{
|
||||
QVariant value = values[i];
|
||||
double x = i / ( double ) num;
|
||||
@ -269,16 +251,11 @@ void QgsCategorizedSymbolRendererV2Widget::addCategories()
|
||||
//if (!dlg.exec())
|
||||
// return;
|
||||
|
||||
QgsVectorColorRampV2* ramp = NULL;
|
||||
QString rampName = cboCategorizedColorRamp->currentText();
|
||||
if ( rampName == "[source]" )
|
||||
ramp = mRenderer->sourceColorRamp()->clone();
|
||||
else
|
||||
ramp = mStyle->colorRamp( rampName );
|
||||
QgsVectorColorRampV2* ramp = cboCategorizedColorRamp->currentColorRamp();
|
||||
|
||||
if ( ramp == NULL )
|
||||
if( ramp == NULL )
|
||||
{
|
||||
if ( cboCategorizedColorRamp->count() == 0 )
|
||||
if( cboCategorizedColorRamp->count() == 0 )
|
||||
QMessageBox::critical( this, tr( "Error" ), tr( "There are no available color ramps. You can add them in Style Manager." ) );
|
||||
else
|
||||
QMessageBox::critical( this, tr( "Error" ), tr( "The selected color ramp is not available." ) );
|
||||
@ -288,9 +265,9 @@ void QgsCategorizedSymbolRendererV2Widget::addCategories()
|
||||
QgsCategoryList cats;
|
||||
_createCategories( cats, unique_vals, mCategorizedSymbol, ramp );
|
||||
|
||||
if ( !mOldClassificationAttribute.isEmpty() &&
|
||||
attrName != mOldClassificationAttribute &&
|
||||
mRenderer->categories().count() > 0 )
|
||||
if( !mOldClassificationAttribute.isEmpty() &&
|
||||
attrName != mOldClassificationAttribute &&
|
||||
mRenderer->categories().count() > 0 )
|
||||
{
|
||||
int res = QMessageBox::question( this,
|
||||
tr( "Confirm Delete" ),
|
||||
@ -298,24 +275,24 @@ void QgsCategorizedSymbolRendererV2Widget::addCategories()
|
||||
"Should the existing classes be deleted before classification?" )
|
||||
.arg( mOldClassificationAttribute ).arg( attrName ),
|
||||
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel );
|
||||
if ( res == QMessageBox::Cancel )
|
||||
if( res == QMessageBox::Cancel )
|
||||
return;
|
||||
|
||||
bool deleteExisting = ( res == QMessageBox::Yes );
|
||||
if ( !deleteExisting )
|
||||
if( !deleteExisting )
|
||||
{
|
||||
QgsCategoryList prevCats = mRenderer->categories();
|
||||
for ( int i = 0; i < cats.size(); ++i )
|
||||
for( int i = 0; i < cats.size(); ++i )
|
||||
{
|
||||
bool contains = false;
|
||||
QVariant value = cats.at( i ).value();
|
||||
for ( int j = 0; j < prevCats.size() && !contains; ++j )
|
||||
for( int j = 0; j < prevCats.size() && !contains; ++j )
|
||||
{
|
||||
if ( prevCats.at( j ).value() == value )
|
||||
if( prevCats.at( j ).value() == value )
|
||||
contains = true;
|
||||
}
|
||||
|
||||
if ( !contains )
|
||||
if( !contains )
|
||||
prevCats.append( cats.at( i ) );
|
||||
}
|
||||
cats = prevCats;
|
||||
@ -351,7 +328,7 @@ void QgsCategorizedSymbolRendererV2Widget::addCategories()
|
||||
int QgsCategorizedSymbolRendererV2Widget::currentCategoryRow()
|
||||
{
|
||||
QModelIndex idx = viewCategories->selectionModel()->currentIndex();
|
||||
if ( !idx.isValid() )
|
||||
if( !idx.isValid() )
|
||||
return -1;
|
||||
return idx.row();
|
||||
}
|
||||
@ -359,7 +336,7 @@ int QgsCategorizedSymbolRendererV2Widget::currentCategoryRow()
|
||||
QVariant QgsCategorizedSymbolRendererV2Widget::currentCategory()
|
||||
{
|
||||
int row = currentCategoryRow();
|
||||
if ( row == -1 )
|
||||
if( row == -1 )
|
||||
return QVariant();
|
||||
QStandardItemModel* m = qobject_cast<QStandardItemModel*>( viewCategories->model() );
|
||||
return m->item( row, 1 )->data();
|
||||
@ -368,11 +345,11 @@ QVariant QgsCategorizedSymbolRendererV2Widget::currentCategory()
|
||||
void QgsCategorizedSymbolRendererV2Widget::deleteCategory()
|
||||
{
|
||||
QVariant k = currentCategory();
|
||||
if ( !k.isValid() )
|
||||
if( !k.isValid() )
|
||||
return;
|
||||
|
||||
int idx = mRenderer->categoryIndexForValue( k );
|
||||
if ( idx < 0 )
|
||||
if( idx < 0 )
|
||||
return;
|
||||
|
||||
mRenderer->deleteCategory( idx );
|
||||
@ -390,19 +367,19 @@ void QgsCategorizedSymbolRendererV2Widget::changeCurrentValue( QStandardItem * i
|
||||
{
|
||||
int idx = item->row();
|
||||
QString newtext = item->text();
|
||||
if ( item->column() == 1 )
|
||||
if( item->column() == 1 )
|
||||
{
|
||||
QVariant value = newtext;
|
||||
// try to preserve variant type for this value
|
||||
QVariant::Type t = item->data().type();
|
||||
if ( t == QVariant::Int )
|
||||
if( t == QVariant::Int )
|
||||
value = newtext.toInt();
|
||||
else if ( t == QVariant::Double )
|
||||
else if( t == QVariant::Double )
|
||||
value = newtext.toDouble();
|
||||
mRenderer->updateCategoryValue( idx, value );
|
||||
item->setData( value );
|
||||
}
|
||||
else if ( item->column() == 2 )
|
||||
else if( item->column() == 2 )
|
||||
{
|
||||
mRenderer->updateCategoryLabel( idx, newtext );
|
||||
}
|
||||
|
90
src/gui/symbology-ng/qgscolorrampcombobox.cpp
Normal file
90
src/gui/symbology-ng/qgscolorrampcombobox.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#include "qgscolorrampcombobox.h"
|
||||
|
||||
#include "qgssymbollayerv2utils.h"
|
||||
#include "qgsvectorcolorrampv2.h"
|
||||
#include "qgsstylev2.h"
|
||||
#include "qgsstylev2managerdialog.h"
|
||||
|
||||
QSize QgsColorRampComboBox::rampIconSize( 50, 16 );
|
||||
|
||||
QgsColorRampComboBox::QgsColorRampComboBox( QWidget *parent ) :
|
||||
QComboBox( parent ), mStyle( NULL ), mSourceColorRamp( NULL )
|
||||
{
|
||||
}
|
||||
|
||||
QgsColorRampComboBox::~QgsColorRampComboBox()
|
||||
{
|
||||
delete mSourceColorRamp;
|
||||
}
|
||||
|
||||
void QgsColorRampComboBox::populate( QgsStyleV2* style )
|
||||
{
|
||||
if( count() != 0 )
|
||||
return; // already populated!
|
||||
|
||||
mStyle = style;
|
||||
|
||||
setIconSize( rampIconSize );
|
||||
|
||||
QStringList rampNames = mStyle->colorRampNames();
|
||||
for( QStringList::iterator it = rampNames.begin(); it != rampNames.end(); ++it )
|
||||
{
|
||||
QgsVectorColorRampV2* ramp = style->colorRamp( *it );
|
||||
QIcon icon = QgsSymbolLayerV2Utils::colorRampPreviewIcon( ramp, rampIconSize );
|
||||
|
||||
addItem( icon, *it );
|
||||
|
||||
delete ramp;
|
||||
}
|
||||
|
||||
addItem( tr( "New color ramp..." ) );
|
||||
connect( this, SIGNAL( currentIndexChanged( int ) ), SLOT( colorRampChanged( int ) ) );
|
||||
}
|
||||
|
||||
QgsVectorColorRampV2* QgsColorRampComboBox::currentColorRamp()
|
||||
{
|
||||
QString rampName = currentText();
|
||||
if( rampName == "[source]" && mSourceColorRamp )
|
||||
return mSourceColorRamp->clone();
|
||||
else
|
||||
return mStyle->colorRamp( rampName );
|
||||
}
|
||||
|
||||
void QgsColorRampComboBox::setSourceColorRamp( QgsVectorColorRampV2* sourceRamp )
|
||||
{
|
||||
mSourceColorRamp = sourceRamp->clone();
|
||||
|
||||
QIcon icon = QgsSymbolLayerV2Utils::colorRampPreviewIcon( mSourceColorRamp, rampIconSize );
|
||||
if( itemText( 0 ) == "[source]" )
|
||||
setItemIcon( 0, icon );
|
||||
else
|
||||
insertItem( 0, icon, "[source]" );
|
||||
setCurrentIndex( 0 );
|
||||
}
|
||||
|
||||
void QgsColorRampComboBox::colorRampChanged( int index )
|
||||
{
|
||||
if( index != count() - 1 )
|
||||
return;
|
||||
|
||||
// last item: "new color ramp..."
|
||||
QString rampName = QgsStyleV2ManagerDialog::addColorRampStatic( this, mStyle );
|
||||
if( rampName.isEmpty() )
|
||||
return;
|
||||
|
||||
// put newly added ramp into the combo
|
||||
QgsVectorColorRampV2* ramp = mStyle->colorRamp( rampName );
|
||||
QIcon icon = QgsSymbolLayerV2Utils::colorRampPreviewIcon( ramp, rampIconSize );
|
||||
|
||||
blockSignals( true ); // avoid calling this method again!
|
||||
insertItem( index, icon, rampName );
|
||||
blockSignals( false );
|
||||
|
||||
delete ramp;
|
||||
|
||||
// ... and set it as active
|
||||
setCurrentIndex( index );
|
||||
|
||||
// make sure the color ramp is stored
|
||||
mStyle->save();
|
||||
}
|
39
src/gui/symbology-ng/qgscolorrampcombobox.h
Normal file
39
src/gui/symbology-ng/qgscolorrampcombobox.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef QGSCOLORRAMPCOMBOBOX_H
|
||||
#define QGSCOLORRAMPCOMBOBOX_H
|
||||
|
||||
#include <QComboBox>
|
||||
|
||||
class QgsStyleV2;
|
||||
class QgsVectorColorRampV2;
|
||||
|
||||
class QgsColorRampComboBox : public QComboBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QgsColorRampComboBox( QWidget *parent = 0 );
|
||||
|
||||
~QgsColorRampComboBox();
|
||||
|
||||
//! initialize the combo box with color ramps from the style
|
||||
void populate( QgsStyleV2* style );
|
||||
|
||||
//! add/select color ramp which was used previously by the renderer
|
||||
void setSourceColorRamp( QgsVectorColorRampV2* sourceRamp );
|
||||
|
||||
//! return new instance of the current color ramp or NULL if there is no active color ramp
|
||||
QgsVectorColorRampV2* currentColorRamp();
|
||||
|
||||
static QSize rampIconSize;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
void colorRampChanged( int index );
|
||||
|
||||
protected:
|
||||
QgsStyleV2* mStyle;
|
||||
QgsVectorColorRampV2* mSourceColorRamp; // owns the copy
|
||||
};
|
||||
|
||||
#endif // QGSCOLORRAMPCOMBOBOX_H
|
@ -25,12 +25,12 @@ QgsRendererV2Widget* QgsGraduatedSymbolRendererV2Widget::create( QgsVectorLayer*
|
||||
}
|
||||
|
||||
QgsGraduatedSymbolRendererV2Widget::QgsGraduatedSymbolRendererV2Widget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
|
||||
: QgsRendererV2Widget( layer, style )
|
||||
: QgsRendererV2Widget( layer, style )
|
||||
{
|
||||
|
||||
// try to recognize the previous renderer
|
||||
// (null renderer means "no previous renderer")
|
||||
if ( !renderer || renderer->type() != "graduatedSymbol" )
|
||||
if( !renderer || renderer->type() != "graduatedSymbol" )
|
||||
{
|
||||
// we're not going to use it - so let's delete the renderer
|
||||
delete renderer;
|
||||
@ -46,7 +46,9 @@ QgsGraduatedSymbolRendererV2Widget::QgsGraduatedSymbolRendererV2Widget( QgsVecto
|
||||
setupUi( this );
|
||||
|
||||
populateColumns();
|
||||
populateColorRamps();
|
||||
|
||||
cboGraduatedColorRamp->populate( mStyle );
|
||||
|
||||
QStandardItemModel* mg = new QStandardItemModel( this );
|
||||
QStringList labels;
|
||||
labels << tr( "Range" ) << tr( "Label" );
|
||||
@ -96,9 +98,9 @@ void QgsGraduatedSymbolRendererV2Widget::updateUiFromRenderer()
|
||||
populateRanges();
|
||||
|
||||
// update UI from the graduated renderer (update combo boxes, view)
|
||||
if ( mRenderer->mode() < cboGraduatedMode->count() )
|
||||
if( mRenderer->mode() < cboGraduatedMode->count() )
|
||||
cboGraduatedMode->setCurrentIndex( mRenderer->mode() );
|
||||
if ( mRenderer->ranges().count() )
|
||||
if( mRenderer->ranges().count() )
|
||||
spinGraduatedClasses->setValue( mRenderer->ranges().count() );
|
||||
|
||||
// set column
|
||||
@ -109,7 +111,7 @@ void QgsGraduatedSymbolRendererV2Widget::updateUiFromRenderer()
|
||||
connect( cboGraduatedColumn, SIGNAL( currentIndexChanged( int ) ), this, SLOT( graduatedColumnChanged() ) );
|
||||
|
||||
// set source symbol
|
||||
if ( mRenderer->sourceSymbol() )
|
||||
if( mRenderer->sourceSymbol() )
|
||||
{
|
||||
delete mGraduatedSymbol;
|
||||
mGraduatedSymbol = mRenderer->sourceSymbol()->clone();
|
||||
@ -117,15 +119,9 @@ void QgsGraduatedSymbolRendererV2Widget::updateUiFromRenderer()
|
||||
}
|
||||
|
||||
// set source color ramp
|
||||
if ( mRenderer->sourceColorRamp() )
|
||||
if( mRenderer->sourceColorRamp() )
|
||||
{
|
||||
QSize rampIconSize( 50, 16 );
|
||||
QIcon icon = QgsSymbolLayerV2Utils::colorRampPreviewIcon( mRenderer->sourceColorRamp(), rampIconSize );
|
||||
if ( cboGraduatedColorRamp->itemText( 0 ) == "[source]" )
|
||||
cboGraduatedColorRamp->setItemIcon( 0, icon );
|
||||
else
|
||||
cboGraduatedColorRamp->insertItem( 0, icon, "[source]" );
|
||||
cboGraduatedColorRamp->setCurrentIndex( 0 );
|
||||
cboGraduatedColorRamp->setSourceColorRamp( mRenderer->sourceColorRamp() );
|
||||
}
|
||||
|
||||
}
|
||||
@ -137,9 +133,9 @@ void QgsGraduatedSymbolRendererV2Widget::populateColumns()
|
||||
cboGraduatedColumn->clear();
|
||||
const QgsFieldMap& flds = mLayer->pendingFields();
|
||||
QgsFieldMap::ConstIterator it = flds.begin();
|
||||
for ( ; it != flds.end(); ++it )
|
||||
for( ; it != flds.end(); ++it )
|
||||
{
|
||||
if ( it->type() == QVariant::Double || it->type() == QVariant::Int )
|
||||
if( it->type() == QVariant::Double || it->type() == QVariant::Int )
|
||||
cboGraduatedColumn->addItem( it->name() );
|
||||
}
|
||||
}
|
||||
@ -150,39 +146,17 @@ void QgsGraduatedSymbolRendererV2Widget::graduatedColumnChanged()
|
||||
}
|
||||
|
||||
|
||||
void QgsGraduatedSymbolRendererV2Widget::populateColorRamps()
|
||||
{
|
||||
QSize rampIconSize( 50, 16 );
|
||||
cboGraduatedColorRamp->setIconSize( rampIconSize );
|
||||
|
||||
QStringList rampNames = mStyle->colorRampNames();
|
||||
for ( QStringList::iterator it = rampNames.begin(); it != rampNames.end(); ++it )
|
||||
{
|
||||
QgsVectorColorRampV2* ramp = mStyle->colorRamp( *it );
|
||||
QIcon icon = QgsSymbolLayerV2Utils::colorRampPreviewIcon( ramp, rampIconSize );
|
||||
cboGraduatedColorRamp->addItem( icon, *it );
|
||||
delete ramp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void QgsGraduatedSymbolRendererV2Widget::classifyGraduated()
|
||||
{
|
||||
QString attrName = cboGraduatedColumn->currentText();
|
||||
|
||||
int classes = spinGraduatedClasses->value();
|
||||
|
||||
QgsVectorColorRampV2* ramp = NULL;
|
||||
QString rampName = cboGraduatedColorRamp->currentText();
|
||||
if ( rampName == "[source]" )
|
||||
ramp = mRenderer->sourceColorRamp()->clone();
|
||||
else
|
||||
ramp = mStyle->colorRamp( rampName );
|
||||
QgsVectorColorRampV2* ramp = cboGraduatedColorRamp->currentColorRamp();
|
||||
|
||||
if ( ramp == NULL )
|
||||
if( ramp == NULL )
|
||||
{
|
||||
if ( cboGraduatedColorRamp->count() == 0 )
|
||||
if( cboGraduatedColorRamp->count() == 0 )
|
||||
QMessageBox::critical( this, tr( "Error" ), tr( "There are no available color ramps. You can add them in Style Manager." ) );
|
||||
else
|
||||
QMessageBox::critical( this, tr( "Error" ), tr( "The selected color ramp is not available." ) );
|
||||
@ -190,13 +164,13 @@ void QgsGraduatedSymbolRendererV2Widget::classifyGraduated()
|
||||
}
|
||||
|
||||
QgsGraduatedSymbolRendererV2::Mode mode;
|
||||
if ( cboGraduatedMode->currentIndex() == 0 )
|
||||
if( cboGraduatedMode->currentIndex() == 0 )
|
||||
mode = QgsGraduatedSymbolRendererV2::EqualInterval;
|
||||
else if ( cboGraduatedMode->currentIndex() == 2 )
|
||||
else if( cboGraduatedMode->currentIndex() == 2 )
|
||||
mode = QgsGraduatedSymbolRendererV2::Jenks;
|
||||
else if ( cboGraduatedMode->currentIndex() == 3 )
|
||||
else if( cboGraduatedMode->currentIndex() == 3 )
|
||||
mode = QgsGraduatedSymbolRendererV2::StdDev;
|
||||
else if ( cboGraduatedMode->currentIndex() == 4 )
|
||||
else if( cboGraduatedMode->currentIndex() == 4 )
|
||||
mode = QgsGraduatedSymbolRendererV2::Pretty;
|
||||
else // default should be quantile for now
|
||||
mode = QgsGraduatedSymbolRendererV2::Quantile;
|
||||
@ -212,7 +186,7 @@ void QgsGraduatedSymbolRendererV2Widget::classifyGraduated()
|
||||
void QgsGraduatedSymbolRendererV2Widget::changeGraduatedSymbol()
|
||||
{
|
||||
QgsSymbolV2SelectorDialog dlg( mGraduatedSymbol, mStyle, this );
|
||||
if ( !dlg.exec() )
|
||||
if( !dlg.exec() )
|
||||
return;
|
||||
|
||||
updateGraduatedSymbolIcon();
|
||||
@ -240,7 +214,7 @@ void QgsGraduatedSymbolRendererV2Widget::populateRanges()
|
||||
|
||||
int i, count = mRenderer->ranges().count();
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
const QgsRendererRangeV2& range = mRenderer->ranges()[i];
|
||||
QString rangeStr = QString::number( range.lowerValue(), 'f', 4 ) + " - " + QString::number( range.upperValue(), 'f', 4 );
|
||||
@ -268,7 +242,7 @@ void QgsGraduatedSymbolRendererV2Widget::populateRanges()
|
||||
int QgsRendererV2PropertiesDialog::currentRangeRow()
|
||||
{
|
||||
QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
|
||||
if ( !idx.isValid() )
|
||||
if( !idx.isValid() )
|
||||
return -1;
|
||||
return idx.row();
|
||||
}
|
||||
@ -276,15 +250,15 @@ int QgsRendererV2PropertiesDialog::currentRangeRow()
|
||||
|
||||
void QgsGraduatedSymbolRendererV2Widget::rangesDoubleClicked( const QModelIndex & idx )
|
||||
{
|
||||
if ( idx.isValid() && idx.column() == 0 )
|
||||
if( idx.isValid() && idx.column() == 0 )
|
||||
changeRangeSymbol( idx.row() );
|
||||
if ( idx.isValid() && idx.column() == 1 )
|
||||
if( idx.isValid() && idx.column() == 1 )
|
||||
changeRange( idx.row() );
|
||||
}
|
||||
|
||||
void QgsGraduatedSymbolRendererV2Widget::rangesClicked( const QModelIndex & idx )
|
||||
{
|
||||
if ( !idx.isValid() )
|
||||
if( !idx.isValid() )
|
||||
mRowSelected = -1;
|
||||
else
|
||||
mRowSelected = idx.row();
|
||||
@ -295,7 +269,7 @@ void QgsGraduatedSymbolRendererV2Widget::changeRangeSymbol( int rangeIdx )
|
||||
QgsSymbolV2* newSymbol = mRenderer->ranges()[rangeIdx].symbol()->clone();
|
||||
|
||||
QgsSymbolV2SelectorDialog dlg( newSymbol, mStyle, this );
|
||||
if ( !dlg.exec() )
|
||||
if( !dlg.exec() )
|
||||
{
|
||||
delete newSymbol;
|
||||
return;
|
||||
@ -314,7 +288,7 @@ void QgsGraduatedSymbolRendererV2Widget::changeRange( int rangeIdx )
|
||||
dialog.setLowerValue( QString( "%1" ).arg( range.lowerValue() ) );
|
||||
dialog.setUpperValue( QString( "%1" ).arg( range.upperValue() ) );
|
||||
|
||||
if ( dialog.exec() == QDialog::Accepted )
|
||||
if( dialog.exec() == QDialog::Accepted )
|
||||
{
|
||||
double lowerValue = dialog.lowerValue().toDouble();
|
||||
double upperValue = dialog.upperValue().toDouble();
|
||||
@ -341,7 +315,7 @@ void QgsGraduatedSymbolRendererV2Widget::deleteCurrentClass()
|
||||
|
||||
void QgsGraduatedSymbolRendererV2Widget::changeCurrentValue( QStandardItem * item )
|
||||
{
|
||||
if ( item->column() == 2 )
|
||||
if( item->column() == 2 )
|
||||
{
|
||||
QString label = item->text();
|
||||
int idx = item->row();
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
|
||||
QgsStyleV2ManagerDialog::QgsStyleV2ManagerDialog( QgsStyleV2* style, QWidget* parent )
|
||||
: QDialog( parent ), mStyle( style ), mModified( false )
|
||||
: QDialog( parent ), mStyle( style ), mModified( false )
|
||||
{
|
||||
|
||||
setupUi( this );
|
||||
@ -52,7 +52,7 @@ QgsStyleV2ManagerDialog::QgsStyleV2ManagerDialog( QgsStyleV2* style, QWidget* pa
|
||||
|
||||
void QgsStyleV2ManagerDialog::onFinished()
|
||||
{
|
||||
if ( mModified )
|
||||
if( mModified )
|
||||
{
|
||||
mStyle->save();
|
||||
}
|
||||
@ -66,9 +66,9 @@ void QgsStyleV2ManagerDialog::populateTypes()
|
||||
int markerCount = 0, lineCount = 0, fillCount = 0;
|
||||
|
||||
QStringList symbolNames = mStyle->symbolNames();
|
||||
for ( int i = 0; i < symbolNames.count(); ++i )
|
||||
for( int i = 0; i < symbolNames.count(); ++i )
|
||||
{
|
||||
switch ( mStyle->symbolRef( symbolNames[i] )->type() )
|
||||
switch( mStyle->symbolRef( symbolNames[i] )->type() )
|
||||
{
|
||||
case QgsSymbolV2::Marker: markerCount++; break;
|
||||
case QgsSymbolV2::Line: lineCount++; break;
|
||||
@ -94,11 +94,11 @@ void QgsStyleV2ManagerDialog::populateList()
|
||||
// get current symbol type
|
||||
int itemType = currentItemType();
|
||||
|
||||
if ( itemType < 3 )
|
||||
if( itemType < 3 )
|
||||
{
|
||||
populateSymbols( itemType );
|
||||
}
|
||||
else if ( itemType == 3 )
|
||||
else if( itemType == 3 )
|
||||
{
|
||||
populateColorRamps();
|
||||
}
|
||||
@ -115,11 +115,11 @@ void QgsStyleV2ManagerDialog::populateSymbols( int type )
|
||||
|
||||
QStringList symbolNames = mStyle->symbolNames();
|
||||
|
||||
for ( int i = 0; i < symbolNames.count(); ++i )
|
||||
for( int i = 0; i < symbolNames.count(); ++i )
|
||||
{
|
||||
QString name = symbolNames[i];
|
||||
QgsSymbolV2* symbol = mStyle->symbol( name );
|
||||
if ( symbol->type() == type )
|
||||
if( symbol->type() == type )
|
||||
{
|
||||
QStandardItem* item = new QStandardItem( name );
|
||||
QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( symbol, listItems->iconSize() );
|
||||
@ -139,7 +139,7 @@ void QgsStyleV2ManagerDialog::populateColorRamps()
|
||||
|
||||
QStringList colorRamps = mStyle->colorRampNames();
|
||||
|
||||
for ( int i = 0; i < colorRamps.count(); ++i )
|
||||
for( int i = 0; i < colorRamps.count(); ++i )
|
||||
{
|
||||
QString name = colorRamps[i];
|
||||
QgsVectorColorRampV2* ramp = mStyle->colorRamp( name );
|
||||
@ -161,18 +161,18 @@ int QgsStyleV2ManagerDialog::currentItemType()
|
||||
QString QgsStyleV2ManagerDialog::currentItemName()
|
||||
{
|
||||
QModelIndex index = listItems->selectionModel()->currentIndex();
|
||||
if ( !index.isValid() )
|
||||
if( !index.isValid() )
|
||||
return QString();
|
||||
return index.model()->data( index, 0 ).toString();
|
||||
}
|
||||
|
||||
void QgsStyleV2ManagerDialog::addItem()
|
||||
{
|
||||
if ( currentItemType() < 3 )
|
||||
if( currentItemType() < 3 )
|
||||
{
|
||||
addSymbol();
|
||||
}
|
||||
else if ( currentItemType() == 3 )
|
||||
else if( currentItemType() == 3 )
|
||||
{
|
||||
addColorRamp();
|
||||
}
|
||||
@ -189,7 +189,7 @@ bool QgsStyleV2ManagerDialog::addSymbol()
|
||||
{
|
||||
// create new symbol with current type
|
||||
QgsSymbolV2* symbol;
|
||||
switch ( currentItemType() )
|
||||
switch( currentItemType() )
|
||||
{
|
||||
case QgsSymbolV2::Marker: symbol = new QgsMarkerSymbolV2(); break;
|
||||
case QgsSymbolV2::Line: symbol = new QgsLineSymbolV2(); break;
|
||||
@ -199,7 +199,7 @@ bool QgsStyleV2ManagerDialog::addSymbol()
|
||||
|
||||
// get symbol design
|
||||
QgsSymbolV2PropertiesDialog dlg( symbol, this );
|
||||
if ( dlg.exec() == 0 )
|
||||
if( dlg.exec() == 0 )
|
||||
{
|
||||
delete symbol;
|
||||
return false;
|
||||
@ -209,7 +209,7 @@ bool QgsStyleV2ManagerDialog::addSymbol()
|
||||
bool ok;
|
||||
QString name = QInputDialog::getText( this, tr( "Symbol name" ),
|
||||
tr( "Please enter name for new symbol:" ), QLineEdit::Normal, tr( "new symbol" ), &ok );
|
||||
if ( !ok || name.isEmpty() )
|
||||
if( !ok || name.isEmpty() )
|
||||
{
|
||||
delete symbol;
|
||||
return false;
|
||||
@ -221,48 +221,49 @@ bool QgsStyleV2ManagerDialog::addSymbol()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsStyleV2ManagerDialog::addColorRamp()
|
||||
|
||||
QString QgsStyleV2ManagerDialog::addColorRampStatic( QWidget* parent, QgsStyleV2* style )
|
||||
{
|
||||
// let the user choose the color ramp type
|
||||
QStringList rampTypes;
|
||||
rampTypes << tr( "Gradient" ) << tr( "Random" ) << tr( "ColorBrewer" );
|
||||
bool ok;
|
||||
QString rampType = QInputDialog::getItem( this, tr( "Color ramp type" ),
|
||||
QString rampType = QInputDialog::getItem( parent, tr( "Color ramp type" ),
|
||||
tr( "Please select color ramp type:" ), rampTypes, 0, false, &ok );
|
||||
if ( !ok || rampType.isEmpty() )
|
||||
return false;
|
||||
if( !ok || rampType.isEmpty() )
|
||||
return QString();
|
||||
|
||||
QgsVectorColorRampV2 *ramp = NULL;
|
||||
if ( rampType == tr( "Gradient" ) )
|
||||
if( rampType == tr( "Gradient" ) )
|
||||
{
|
||||
QgsVectorGradientColorRampV2* gradRamp = new QgsVectorGradientColorRampV2();
|
||||
QgsVectorGradientColorRampV2Dialog dlg( gradRamp, this );
|
||||
if ( !dlg.exec() )
|
||||
QgsVectorGradientColorRampV2Dialog dlg( gradRamp, parent );
|
||||
if( !dlg.exec() )
|
||||
{
|
||||
delete gradRamp;
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
ramp = gradRamp;
|
||||
}
|
||||
else if ( rampType == tr( "Random" ) )
|
||||
else if( rampType == tr( "Random" ) )
|
||||
{
|
||||
QgsVectorRandomColorRampV2* randRamp = new QgsVectorRandomColorRampV2();
|
||||
QgsVectorRandomColorRampV2Dialog dlg( randRamp, this );
|
||||
if ( !dlg.exec() )
|
||||
QgsVectorRandomColorRampV2Dialog dlg( randRamp, parent );
|
||||
if( !dlg.exec() )
|
||||
{
|
||||
delete randRamp;
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
ramp = randRamp;
|
||||
}
|
||||
else if ( rampType == tr( "ColorBrewer" ) )
|
||||
else if( rampType == tr( "ColorBrewer" ) )
|
||||
{
|
||||
QgsVectorColorBrewerColorRampV2* brewerRamp = new QgsVectorColorBrewerColorRampV2();
|
||||
QgsVectorColorBrewerColorRampV2Dialog dlg( brewerRamp, this );
|
||||
if ( !dlg.exec() )
|
||||
QgsVectorColorBrewerColorRampV2Dialog dlg( brewerRamp, parent );
|
||||
if( !dlg.exec() )
|
||||
{
|
||||
delete brewerRamp;
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
ramp = brewerRamp;
|
||||
}
|
||||
@ -272,29 +273,41 @@ bool QgsStyleV2ManagerDialog::addColorRamp()
|
||||
}
|
||||
|
||||
// get name
|
||||
QString name = QInputDialog::getText( this, tr( "Color ramp name" ),
|
||||
QString name = QInputDialog::getText( parent, tr( "Color ramp name" ),
|
||||
tr( "Please enter name for new color ramp:" ), QLineEdit::Normal, tr( "new color ramp" ), &ok );
|
||||
if ( !ok || name.isEmpty() )
|
||||
if( !ok || name.isEmpty() )
|
||||
{
|
||||
if ( ramp )
|
||||
if( ramp )
|
||||
delete ramp;
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
|
||||
// add new symbol to style and re-populate the list
|
||||
mStyle->addColorRamp( name, ramp );
|
||||
mModified = true;
|
||||
return true;
|
||||
style->addColorRamp( name, ramp );
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
bool QgsStyleV2ManagerDialog::addColorRamp()
|
||||
{
|
||||
QString rampName = addColorRampStatic( this , mStyle );
|
||||
if( !rampName.isEmpty() )
|
||||
{
|
||||
mModified = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void QgsStyleV2ManagerDialog::editItem()
|
||||
{
|
||||
if ( currentItemType() < 3 )
|
||||
if( currentItemType() < 3 )
|
||||
{
|
||||
editSymbol();
|
||||
}
|
||||
else if ( currentItemType() == 3 )
|
||||
else if( currentItemType() == 3 )
|
||||
{
|
||||
editColorRamp();
|
||||
}
|
||||
@ -309,14 +322,14 @@ void QgsStyleV2ManagerDialog::editItem()
|
||||
bool QgsStyleV2ManagerDialog::editSymbol()
|
||||
{
|
||||
QString symbolName = currentItemName();
|
||||
if ( symbolName.isEmpty() )
|
||||
if( symbolName.isEmpty() )
|
||||
return false;
|
||||
|
||||
QgsSymbolV2* symbol = mStyle->symbol( symbolName );
|
||||
|
||||
// let the user edit the symbol and update list when done
|
||||
QgsSymbolV2PropertiesDialog dlg( symbol, this );
|
||||
if ( dlg.exec() == 0 )
|
||||
if( dlg.exec() == 0 )
|
||||
{
|
||||
delete symbol;
|
||||
return false;
|
||||
@ -331,36 +344,36 @@ bool QgsStyleV2ManagerDialog::editSymbol()
|
||||
bool QgsStyleV2ManagerDialog::editColorRamp()
|
||||
{
|
||||
QString name = currentItemName();
|
||||
if ( name.isEmpty() )
|
||||
if( name.isEmpty() )
|
||||
return false;
|
||||
|
||||
QgsVectorColorRampV2* ramp = mStyle->colorRamp( name );
|
||||
|
||||
if ( ramp->type() == "gradient" )
|
||||
if( ramp->type() == "gradient" )
|
||||
{
|
||||
QgsVectorGradientColorRampV2* gradRamp = static_cast<QgsVectorGradientColorRampV2*>( ramp );
|
||||
QgsVectorGradientColorRampV2Dialog dlg( gradRamp, this );
|
||||
if ( !dlg.exec() )
|
||||
if( !dlg.exec() )
|
||||
{
|
||||
delete ramp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( ramp->type() == "random" )
|
||||
else if( ramp->type() == "random" )
|
||||
{
|
||||
QgsVectorRandomColorRampV2* randRamp = static_cast<QgsVectorRandomColorRampV2*>( ramp );
|
||||
QgsVectorRandomColorRampV2Dialog dlg( randRamp, this );
|
||||
if ( !dlg.exec() )
|
||||
if( !dlg.exec() )
|
||||
{
|
||||
delete ramp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( ramp->type() == "colorbrewer" )
|
||||
else if( ramp->type() == "colorbrewer" )
|
||||
{
|
||||
QgsVectorColorBrewerColorRampV2* brewerRamp = static_cast<QgsVectorColorBrewerColorRampV2*>( ramp );
|
||||
QgsVectorColorBrewerColorRampV2Dialog dlg( brewerRamp, this );
|
||||
if ( !dlg.exec() )
|
||||
if( !dlg.exec() )
|
||||
{
|
||||
delete ramp;
|
||||
return false;
|
||||
@ -379,11 +392,11 @@ bool QgsStyleV2ManagerDialog::editColorRamp()
|
||||
|
||||
void QgsStyleV2ManagerDialog::removeItem()
|
||||
{
|
||||
if ( currentItemType() < 3 )
|
||||
if( currentItemType() < 3 )
|
||||
{
|
||||
removeSymbol();
|
||||
}
|
||||
else if ( currentItemType() == 3 )
|
||||
else if( currentItemType() == 3 )
|
||||
{
|
||||
removeColorRamp();
|
||||
}
|
||||
@ -399,7 +412,7 @@ void QgsStyleV2ManagerDialog::removeItem()
|
||||
bool QgsStyleV2ManagerDialog::removeSymbol()
|
||||
{
|
||||
QString symbolName = currentItemName();
|
||||
if ( symbolName.isEmpty() )
|
||||
if( symbolName.isEmpty() )
|
||||
return false;
|
||||
|
||||
// delete from style and update list
|
||||
@ -411,7 +424,7 @@ bool QgsStyleV2ManagerDialog::removeSymbol()
|
||||
bool QgsStyleV2ManagerDialog::removeColorRamp()
|
||||
{
|
||||
QString rampName = currentItemName();
|
||||
if ( rampName.isEmpty() )
|
||||
if( rampName.isEmpty() )
|
||||
return false;
|
||||
|
||||
mStyle->removeColorRamp( rampName );
|
||||
|
@ -16,6 +16,9 @@ class GUI_EXPORT QgsStyleV2ManagerDialog : public QDialog, private Ui::QgsStyleV
|
||||
public:
|
||||
QgsStyleV2ManagerDialog( QgsStyleV2* style, QWidget* parent = NULL );
|
||||
|
||||
//! open add color ramp dialog, return color ramp's name if the ramp has been added
|
||||
static QString addColorRampStatic( QWidget* parent, QgsStyleV2* style );
|
||||
|
||||
public slots:
|
||||
void addItem();
|
||||
void editItem();
|
||||
|
@ -78,7 +78,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cboCategorizedColorRamp">
|
||||
<widget class="QgsColorRampComboBox" name="cboCategorizedColorRamp">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
@ -169,6 +169,13 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsColorRampComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>qgscolorrampcombobox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>cboCategorizedColumn</tabstop>
|
||||
<tabstop>btnChangeCategorizedSymbol</tabstop>
|
||||
|
@ -86,7 +86,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="cboGraduatedColorRamp"/>
|
||||
<widget class="QgsColorRampComboBox" name="cboGraduatedColorRamp"/>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QLabel" name="label_8">
|
||||
@ -199,6 +199,13 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsColorRampComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>qgscolorrampcombobox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>cboGraduatedColumn</tabstop>
|
||||
<tabstop>btnChangeGraduatedSymbol</tabstop>
|
||||
|
Loading…
x
Reference in New Issue
Block a user