/*************************************************************************** qgssubstitutionlistwidget.cpp ----------------------------- begin : August 2016 copyright : (C) 2016 Nyall Dawson email : nyall dot dawson at gmail dot com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "qgssubstitutionlistwidget.h" #include #include #include #include #include QgsSubstitutionListWidget::QgsSubstitutionListWidget( QWidget *parent ) : QgsPanelWidget( parent ) { setupUi( this ); connect( mTableSubstitutions, &QTableWidget::cellChanged, this, &QgsSubstitutionListWidget::tableChanged ); } void QgsSubstitutionListWidget::setSubstitutions( const QgsStringReplacementCollection &substitutions ) { mTableSubstitutions->blockSignals( true ); mTableSubstitutions->clearContents(); Q_FOREACH ( const QgsStringReplacement &replacement, substitutions.replacements() ) { addSubstitution( replacement ); } mTableSubstitutions->blockSignals( false ); } QgsStringReplacementCollection QgsSubstitutionListWidget::substitutions() const { QList< QgsStringReplacement > result; for ( int i = 0; i < mTableSubstitutions->rowCount(); ++i ) { if ( !mTableSubstitutions->item( i, 0 ) ) continue; if ( mTableSubstitutions->item( i, 0 )->text().isEmpty() ) continue; QCheckBox *chkCaseSensitive = qobject_cast( mTableSubstitutions->cellWidget( i, 2 ) ); QCheckBox *chkWholeWord = qobject_cast( mTableSubstitutions->cellWidget( i, 3 ) ); QgsStringReplacement replacement( mTableSubstitutions->item( i, 0 )->text(), mTableSubstitutions->item( i, 1 )->text(), chkCaseSensitive->isChecked(), chkWholeWord->isChecked() ); result << replacement; } return QgsStringReplacementCollection( result ); } void QgsSubstitutionListWidget::on_mButtonAdd_clicked() { addSubstitution( QgsStringReplacement( QString(), QString(), false, true ) ); mTableSubstitutions->setFocus(); mTableSubstitutions->setCurrentCell( mTableSubstitutions->rowCount() - 1, 0 ); } void QgsSubstitutionListWidget::on_mButtonRemove_clicked() { int currentRow = mTableSubstitutions->currentRow(); mTableSubstitutions->removeRow( currentRow ); tableChanged(); } void QgsSubstitutionListWidget::tableChanged() { emit substitutionsChanged( substitutions() ); } void QgsSubstitutionListWidget::on_mButtonExport_clicked() { QString fileName = QFileDialog::getSaveFileName( this, tr( "Save substitutions" ), QDir::homePath(), tr( "XML files (*.xml *.XML)" ) ); if ( fileName.isEmpty() ) { return; } // ensure the user never omitted the extension from the file name if ( !fileName.endsWith( QLatin1String( ".xml" ), Qt::CaseInsensitive ) ) { fileName += QLatin1String( ".xml" ); } QDomDocument doc; QDomElement root = doc.createElement( QStringLiteral( "substitutions" ) ); root.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0" ) ); QgsStringReplacementCollection collection = substitutions(); collection.writeXml( root, doc ); doc.appendChild( root ); QFile file( fileName ); if ( !file.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) ) { QMessageBox::warning( nullptr, tr( "Export substitutions" ), tr( "Cannot write file %1:\n%2." ).arg( fileName, file.errorString() ), QMessageBox::Ok, QMessageBox::Ok ); return; } QTextStream out( &file ); doc.save( out, 4 ); } void QgsSubstitutionListWidget::on_mButtonImport_clicked() { QString fileName = QFileDialog::getOpenFileName( this, tr( "Load substitutions" ), QDir::homePath(), tr( "XML files (*.xml *.XML)" ) ); if ( fileName.isEmpty() ) { return; } QFile file( fileName ); if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) { QMessageBox::warning( nullptr, tr( "Import substitutions" ), tr( "Cannot read file %1:\n%2." ).arg( fileName, file.errorString() ), QMessageBox::Ok, QMessageBox::Ok ); return; } QDomDocument doc; QString errorStr; int errorLine; int errorColumn; if ( !doc.setContent( &file, true, &errorStr, &errorLine, &errorColumn ) ) { QMessageBox::warning( nullptr, tr( "Import substitutions" ), tr( "Parse error at line %1, column %2:\n%3" ) .arg( errorLine ) .arg( errorColumn ) .arg( errorStr ), QMessageBox::Ok, QMessageBox::Ok ); return; } QDomElement root = doc.documentElement(); if ( root.tagName() != QLatin1String( "substitutions" ) ) { QMessageBox::warning( nullptr, tr( "Import substitutions" ), tr( "The selected file is not a substitution list." ), QMessageBox::Ok, QMessageBox::Ok ); return; } QgsStringReplacementCollection collection; collection.readXml( root ); setSubstitutions( collection ); tableChanged(); } void QgsSubstitutionListWidget::addSubstitution( const QgsStringReplacement &substitution ) { int row = mTableSubstitutions->rowCount(); mTableSubstitutions->insertRow( row ); Qt::ItemFlags itemFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; QTableWidgetItem *matchItem = new QTableWidgetItem( substitution.match() ); matchItem->setFlags( itemFlags ); mTableSubstitutions->setItem( row, 0, matchItem ); QTableWidgetItem *replaceItem = new QTableWidgetItem( substitution.replacement() ); replaceItem->setFlags( itemFlags ); mTableSubstitutions->setItem( row, 1, replaceItem ); QCheckBox *caseSensitiveChk = new QCheckBox( this ); caseSensitiveChk->setChecked( substitution.caseSensitive() ); mTableSubstitutions->setCellWidget( row, 2, caseSensitiveChk ); connect( caseSensitiveChk, &QAbstractButton::toggled, this, &QgsSubstitutionListWidget::tableChanged ); QCheckBox *wholeWordChk = new QCheckBox( this ); wholeWordChk->setChecked( substitution.wholeWordOnly() ); mTableSubstitutions->setCellWidget( row, 3, wholeWordChk ); connect( wholeWordChk, &QAbstractButton::toggled, this, &QgsSubstitutionListWidget::tableChanged ); } // // QgsSubstitutionListDialog // QgsSubstitutionListDialog::QgsSubstitutionListDialog( QWidget *parent ) : QDialog( parent ) , mWidget( nullptr ) { setWindowTitle( tr( "Substitutions" ) ); QVBoxLayout *vLayout = new QVBoxLayout(); mWidget = new QgsSubstitutionListWidget(); vLayout->addWidget( mWidget ); QDialogButtonBox *bbox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal ); connect( bbox, &QDialogButtonBox::accepted, this, &QDialog::accept ); connect( bbox, &QDialogButtonBox::rejected, this, &QDialog::reject ); vLayout->addWidget( bbox ); setLayout( vLayout ); } void QgsSubstitutionListDialog::setSubstitutions( const QgsStringReplacementCollection &substitutions ) { mWidget->setSubstitutions( substitutions ); } QgsStringReplacementCollection QgsSubstitutionListDialog::substitutions() const { return mWidget->substitutions(); }