35 #include <QMessageBox>
36 #include <QStandardItemModel>
37 #include <QStandardItem>
43 , mMimeFormat(
"application/x-qgscategorizedsymbolrendererv2model" )
51 beginRemoveRows( QModelIndex(), 0, mRenderer->
categories().size() - 1 );
57 beginInsertRows( QModelIndex(), 0, renderer->
categories().size() - 1 );
65 if ( !mRenderer )
return;
67 beginInsertRows( QModelIndex(), idx, idx );
79 int row = index.row();
80 if ( row >= catList.size() )
84 return catList.at( row );
90 if ( !index.isValid() )
92 return Qt::ItemIsDropEnabled;
95 Qt::ItemFlags
flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable;
96 if ( index.column() == 1 || index.column() == 2 )
98 flags |= Qt::ItemIsEditable;
105 return Qt::MoveAction;
110 if ( !index.isValid() || !mRenderer )
115 if ( role == Qt::CheckStateRole && index.column() == 0 )
117 return category.
renderState() ? Qt::Checked : Qt::Unchecked;
119 else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
121 switch ( index.column() )
123 case 1:
return category.
value().toString();
124 case 2:
return category.
label();
125 default:
return QVariant();
128 else if ( role == Qt::DecorationRole && index.column() == 0 && category.
symbol() )
132 else if ( role == Qt::TextAlignmentRole )
134 return ( index.column() == 0 ) ? Qt::AlignHCenter : Qt::AlignLeft;
136 else if ( role == Qt::EditRole )
138 switch ( index.column() )
140 case 1:
return category.
value();
141 case 2:
return category.
label();
142 default:
return QVariant();
151 if ( !index.isValid() )
154 if ( index.column() == 0 && role == Qt::CheckStateRole )
157 emit dataChanged( index, index );
161 if ( role != Qt::EditRole )
164 switch ( index.column() )
170 switch ( mRenderer->
categories().value( index.row() ).value().type() )
175 case QVariant::Double:
176 val = value.toDouble();
179 val = value.toString();
192 emit dataChanged( index, index );
198 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
200 QStringList lst; lst <<
tr(
"Symbol" ) <<
tr(
"Value" ) <<
tr(
"Legend" );
201 return lst.value( section );
208 if ( parent.isValid() || !mRenderer )
223 if ( hasIndex( row, column, parent ) )
225 return createIndex( row, column );
227 return QModelIndex();
233 return QModelIndex();
239 types << mMimeFormat;
245 QMimeData *
mimeData =
new QMimeData();
246 QByteArray encodedData;
248 QDataStream stream( &encodedData, QIODevice::WriteOnly );
251 foreach (
const QModelIndex &
index, indexes )
253 if ( !index.isValid() || index.column() != 0 )
256 stream << index.row();
258 mimeData->setData( mMimeFormat, encodedData );
266 if ( action != Qt::MoveAction )
return true;
268 if ( !data->hasFormat( mMimeFormat ) )
return false;
270 QByteArray encodedData = data->data( mMimeFormat );
271 QDataStream stream( &encodedData, QIODevice::ReadOnly );
274 while ( !stream.atEnd() )
281 int to = parent.row();
284 if ( to == -1 ) to = mRenderer->
categories().size();
285 for (
int i = rows.size() - 1; i >= 0; i-- )
287 QgsDebugMsg( QString(
"move %1 to %2" ).arg( rows[i] ).arg( to ) );
290 if ( rows[i] < t ) t--;
293 for (
int j = 0; j < i; j++ )
295 if ( to < rows[j] && rows[i] > rows[j] ) rows[j] += 1;
298 if ( rows[i] < to ) to--;
300 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->
categories().size(), 0 ) );
307 for (
int i = rows.size() - 1; i >= 0; i-- )
309 beginRemoveRows( QModelIndex(), rows[i], rows[i] );
317 beginRemoveRows( QModelIndex(), 0, mRenderer->
categories().size() - 1 );
333 else if ( column == 2 )
337 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->
categories().size(), 0 ) );
343 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->
categories().size(), 0 ) );
348 : QProxyStyle( style )
353 if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
355 QStyleOption opt( *option );
356 opt.rect.setLeft( 0 );
358 opt.rect.setHeight( 0 );
359 if ( widget ) opt.rect.setRight( widget->width() );
390 mOldClassificationAttribute = attrName;
395 mExpressionWidget->setLayer(
mLayer );
397 cboCategorizedColorRamp->populate(
mStyle );
398 int randomIndex = cboCategorizedColorRamp->findText(
tr(
"Random colors" ) );
399 if ( randomIndex != -1 )
401 cboCategorizedColorRamp->setCurrentIndex( randomIndex );
406 if ( defaultColorRamp !=
"" )
408 int index = cboCategorizedColorRamp->findText( defaultColorRamp, Qt::MatchCaseSensitive );
410 cboCategorizedColorRamp->setCurrentIndex( index );
421 viewCategories->setModel( mModel );
422 viewCategories->resizeColumnToContents( 0 );
423 viewCategories->resizeColumnToContents( 1 );
424 viewCategories->resizeColumnToContents( 2 );
430 connect( mExpressionWidget, SIGNAL( fieldChanged( QString ) ),
this, SLOT(
categoryColumnChanged( QString ) ) );
432 connect( viewCategories, SIGNAL( doubleClicked(
const QModelIndex & ) ),
this, SLOT(
categoriesDoubleClicked(
const QModelIndex & ) ) );
433 connect( viewCategories, SIGNAL( customContextMenuRequested(
const QPoint& ) ),
this, SLOT(
contextMenuViewCategories(
const QPoint& ) ) );
436 connect( btnAddCategories, SIGNAL( clicked() ),
this, SLOT(
addCategories() ) );
437 connect( btnDeleteCategories, SIGNAL( clicked() ),
this, SLOT(
deleteCategories() ) );
438 connect( btnDeleteAllCategories, SIGNAL( clicked() ),
this, SLOT(
deleteAllCategories() ) );
439 connect( btnAddCategory, SIGNAL( clicked() ),
this, SLOT(
addCategory() ) );
440 connect( cbxInvertedColorRamp, SIGNAL( toggled(
bool ) ),
this, SLOT(
applyColorRamp() ) );
441 connect( cboCategorizedColorRamp, SIGNAL( currentIndexChanged(
int ) ),
this, SLOT(
applyColorRamp() ) );
444 QMenu* advMenu =
new QMenu;
453 btnAdvanced->setMenu( advMenu );
474 mExpressionWidget->setField( attrName );
502 if ( selectedCats.size() > 0 )
512 foreach (
const int idx, selectedCats )
526 QItemSelectionModel* m = viewCategories->selectionModel();
527 QModelIndexList i = m->selectedRows();
529 if ( m && i.size() > 0 )
554 btnChangeCategorizedSymbol->setIcon( icon );
568 if ( idx.isValid() && idx.column() == 0 )
580 symbol = symbol->
clone();
602 int num = values.count();
604 bool hasNull =
false;
606 for (
int i = 0; i < num; i++ )
608 QVariant value = values[i];
609 if ( value.toString().isNull() )
631 if ( cboCategorizedColorRamp->count() == 0 )
632 QMessageBox::critical(
this,
tr(
"Error" ),
tr(
"There are no available color ramps. You can add them in Style Manager." ) );
633 else if ( !cboCategorizedColorRamp->createNewColorRampSelected() )
634 QMessageBox::critical(
this,
tr(
"Error" ),
tr(
"The selected color ramp is not available." ) );
642 QString attrName = mExpressionWidget->currentField();
644 QList<QVariant> unique_vals;
654 QVariant value = expression->
evaluate( feature );
655 if ( unique_vals.contains( value ) )
657 unique_vals << value;
666 if ( unique_vals.size() >= 1000 )
668 int res = QMessageBox::warning( 0,
tr(
"High number of classes!" ),
669 tr(
"Classification would yield %1 entries which might not be expected. Continue?" ).arg( unique_vals.size() ),
670 QMessageBox::Ok | QMessageBox::Cancel,
671 QMessageBox::Cancel );
672 if ( res == QMessageBox::Cancel )
679 DlgAddCategories dlg(
mStyle, createDefaultSymbol(), unique_vals,
this );
686 bool deleteExisting =
false;
688 if ( !mOldClassificationAttribute.isEmpty() &&
689 attrName != mOldClassificationAttribute &&
692 int res = QMessageBox::question(
this,
693 tr(
"Confirm Delete" ),
694 tr(
"The classification field was changed from '%1' to '%2'.\n"
695 "Should the existing classes be deleted before classification?" )
696 .arg( mOldClassificationAttribute ).arg( attrName ),
697 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel );
698 if ( res == QMessageBox::Cancel )
703 deleteExisting = ( res == QMessageBox::Yes );
707 bool keepExistingColors =
false;
708 if ( !deleteExisting )
711 keepExistingColors = prevCats.size() > 0;
712 for (
int i = 0; i < cats.size(); ++i )
714 bool contains =
false;
715 QVariant value = cats.at( i ).value();
716 for (
int j = 0; j < prevCats.size() && !contains; ++j )
718 if ( prevCats.at( j ).value() == value )
726 prevCats.append( cats.at( i ) );
731 mOldClassificationAttribute = attrName;
778 QModelIndex idx = viewCategories->selectionModel()->currentIndex();
779 if ( !idx.isValid() )
787 QModelIndexList selectedRows = viewCategories->selectionModel()->selectedRows();
789 foreach ( QModelIndex r, selectedRows )
793 rows.append( r.row() );
837 QItemSelectionModel* m = viewCategories->selectionModel();
838 QModelIndexList selectedIndexes = m->selectedRows( 1 );
840 if ( m && selectedIndexes.size() > 0 )
843 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
844 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
846 int row = ( *indexIt ).row();
850 selectedSymbols.append( s );
861 QItemSelectionModel* m = viewCategories->selectionModel();
862 QModelIndexList selectedIndexes = m->selectedRows( 1 );
864 if ( m && selectedIndexes.size() > 0 )
866 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
867 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
882 viewCategories->selectionModel()->clear();
892 if ( event->key() == Qt::Key_C &&
event->modifiers() == Qt::ControlModifier )
897 else if ( event->key() == Qt::Key_V &&
event->modifiers() == Qt::ControlModifier )
899 QgsCategoryList::const_iterator rIt = mCopyBuffer.constBegin();
900 for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )