23 #include <QFileDialog> 
   24 #include <QMessageBox> 
   25 #include <QTextStream> 
   29 #include <QRegularExpression> 
   36   tableWidget->insertRow( 0 );
 
   38   tableWidget->horizontalHeader()->setSectionsClickable( 
true );
 
   39   tableWidget->setSortingEnabled( 
true );
 
   41   connect( addNullButton, &QAbstractButton::clicked, 
this, &QgsValueMapConfigDlg::addNullButtonPushed );
 
   42   connect( removeSelectedButton, &QAbstractButton::clicked, 
this, &QgsValueMapConfigDlg::removeSelectedButtonPushed );
 
   43   connect( loadFromLayerButton, &QAbstractButton::clicked, 
this, &QgsValueMapConfigDlg::loadFromLayerButtonPushed );
 
   44   connect( loadFromCSVButton, &QAbstractButton::clicked, 
this, &QgsValueMapConfigDlg::loadFromCSVButtonPushed );
 
   45   connect( tableWidget, &QTableWidget::cellChanged, 
this, &QgsValueMapConfigDlg::vCellChanged );
 
   46   tableWidget->installEventFilter( 
this );
 
   51   QList<QVariant> valueList;
 
   54   for ( 
int i = 0; i < tableWidget->rowCount() - 1; i++ )
 
   56     QTableWidgetItem *ki = tableWidget->item( i, 0 );
 
   57     QTableWidgetItem *vi = tableWidget->item( i, 1 );
 
   62     QString ks = ki->text();
 
   68     if ( !vi || vi->text().isNull() )
 
   70       value.insert( ks, ks );
 
   74       value.insert( vi->text(), ks );
 
   76     valueList.append( value );
 
   80   cfg.insert( QStringLiteral( 
"map" ), valueList );
 
   86   tableWidget->clearContents();
 
   87   for ( 
int i = tableWidget->rowCount() - 1; i > 0; i-- )
 
   89     tableWidget->removeRow( i );
 
   92   QList<QVariant> valueList = 
config.value( QStringLiteral( 
"map" ) ).toList();
 
   94   if ( valueList.count() > 0 )
 
   96     for ( 
int i = 0, row = 0; i < valueList.count(); i++, row++ )
 
   98       setRow( row, valueList[i].toMap().constBegin().value().toString(), valueList[i].toMap().constBegin().key() );
 
  104     const QVariantMap values = 
config.value( QStringLiteral( 
"map" ) ).toMap();
 
  105     for ( QVariantMap::ConstIterator mit = values.constBegin(); mit != values.constEnd(); mit++, row++ )
 
  107       if ( mit.value().isNull() )
 
  108         setRow( row, mit.key(), QString() );
 
  110         setRow( row, mit.value().toString(), mit.key() );
 
  115 void QgsValueMapConfigDlg::vCellChanged( 
int row, 
int column )
 
  118   if ( row == tableWidget->rowCount() - 1 )
 
  120     tableWidget->insertRow( row + 1 );
 
  126 void QgsValueMapConfigDlg::removeSelectedButtonPushed()
 
  128   QList<QTableWidgetItem *> list = tableWidget->selectedItems();
 
  129   QSet<int> rowsToRemove;
 
  132   for ( i = 0; i < list.size(); i++ )
 
  134     if ( list[i]->column() == 0 )
 
  136       const int row = list[i]->row();
 
  137       if ( !rowsToRemove.contains( row ) )
 
  139         rowsToRemove.insert( row );
 
  143   for ( i = 0; i < rowsToRemove.size(); i++ )
 
  145     tableWidget->removeRow( rowsToRemove.values().at( i ) - removed );
 
  153   QList<QPair<QString, QVariant>> orderedMap;
 
  154   const auto end = map.constEnd();
 
  155   for ( 
auto it = map.constBegin(); it != end; ++it )
 
  157     orderedMap.append( qMakePair( it.key(), it.value() ) );
 
  165   tableWidget->clearContents();
 
  166   for ( 
int i = tableWidget->rowCount() - 1; i > 0; i-- )
 
  168     tableWidget->removeRow( i );
 
  178   for ( 
const auto &pair : list )
 
  180     if ( pair.second.isNull() )
 
  181       setRow( row, pair.first, QString() );
 
  183       setRow( row, pair.first, pair.second.toString() );
 
  190   const QList<QVariant> valueList = 
config.value( QStringLiteral( 
"map" ) ).toList();
 
  192   if ( !valueList.empty() )
 
  194     for ( 
const QVariant &value : valueList )
 
  196       const QVariantMap valueMap = value.toMap();
 
  201       comboBox->addItem( valueMap.constBegin().key(), valueMap.constBegin().value() );
 
  206     const QVariantMap map = 
config.value( QStringLiteral( 
"map" ) ).toMap();
 
  207     for ( 
auto it = map.constBegin(); it != map.constEnd(); ++it )
 
  212       comboBox->addItem( it.key(), it.value() );
 
  220   if ( event->type() == QEvent::KeyPress )
 
  222     QKeyEvent *keyEvent = 
static_cast<QKeyEvent *
>( event );
 
  223     if ( keyEvent->matches( QKeySequence::Copy ) )
 
  225       copySelectionToClipboard();
 
  233 void QgsValueMapConfigDlg::setRow( 
int row, 
const QString &value, 
const QString &description )
 
  236   QTableWidgetItem *valueCell = 
nullptr;
 
  237   QTableWidgetItem *descriptionCell = 
new QTableWidgetItem( description );
 
  238   tableWidget->insertRow( row );
 
  242     cellFont.setItalic( 
true );
 
  244     valueCell->setFont( cellFont );
 
  245     valueCell->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
 
  246     descriptionCell->setFont( cellFont );
 
  250     valueCell = 
new QTableWidgetItem( value );
 
  252   tableWidget->setItem( row, 0, valueCell );
 
  253   tableWidget->setItem( row, 1, descriptionCell );
 
  256 void QgsValueMapConfigDlg::copySelectionToClipboard()
 
  258   QAbstractItemModel *model = tableWidget->model();
 
  259   QItemSelectionModel *selection = tableWidget->selectionModel();
 
  260   const QModelIndexList indexes = selection->selectedIndexes();
 
  262   QString clipboardText;
 
  263   QModelIndex previous = indexes.first();
 
  264   std::unique_ptr<QMimeData> mimeData = std::make_unique<QMimeData>();
 
  265   for ( 
const QModelIndex ¤t : indexes )
 
  267     const QString text = model->data( current ).toString();
 
  268     if ( current.row() != previous.row() )
 
  270       clipboardText.append( 
'\n' );
 
  272     else if ( current.column() != previous.column() )
 
  274       clipboardText.append( 
'\t' );
 
  276     clipboardText.append( text );
 
  279   mimeData->setData( QStringLiteral( 
"text/plain" ), clipboardText.toUtf8() );
 
  280   QApplication::clipboard()->setMimeData( mimeData.release() );
 
  283 void QgsValueMapConfigDlg::addNullButtonPushed()
 
  288 void QgsValueMapConfigDlg::loadFromLayerButtonPushed()
 
  291   if ( !layerDialog.exec() )
 
  294   updateMap( layerDialog.valueMap(), layerDialog.insertNull() );
 
  297 void QgsValueMapConfigDlg::loadFromCSVButtonPushed()
 
  301   const QString fileName = QFileDialog::getOpenFileName( 
nullptr, tr( 
"Load Value Map from File" ), QDir::homePath() );
 
  302   if ( fileName.isNull() )
 
  311   if ( !f.open( QIODevice::ReadOnly ) )
 
  313     QMessageBox::information( 
nullptr,
 
  314                               tr( 
"Load Value Map from File" ),
 
  315                               tr( 
"Could not open file %1\nError was: %2" ).arg( filePath, f.errorString() ),
 
  316                               QMessageBox::Cancel );
 
  321   s.setAutoDetectUnicode( 
true );
 
  323   const thread_local QRegularExpression re( 
"(?:^\"|[;,]\")(\"\"|[\\w\\W]*?)(?=\"[;,]|\"$)|(?:^(?!\")|[;,](?!\"))([^;,]*?)(?=$|[;,])|(\\r\\n|\\n)" );
 
  324   QList<QPair<QString, QVariant>> map;
 
  327     const QString l = s.readLine().trimmed();
 
  328     QRegularExpressionMatchIterator matches = re.globalMatch( l );
 
  330     while ( matches.hasNext() && ceils.size() < 2 )
 
  332       const QRegularExpressionMatch match = matches.next();
 
  333       ceils << match.capturedTexts().last().trimmed().replace( QLatin1String( 
"\"\"" ), QLatin1String( 
"\"" ) );
 
  336     if ( ceils.size() != 2 )
 
  339     QString key = ceils[0];
 
  340     QString val = ceils[1];
 
  343     map.append( qMakePair( key, val ) );