QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgssubstitutionlistwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssubstitutionlistwidget.cpp
3  -----------------------------
4  begin : August 2016
5  copyright : (C) 2016 Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7 
8 
9  ***************************************************************************/
10 
11 /***************************************************************************
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * *
18  ***************************************************************************/
19 
21 #include "qgsgui.h"
22 
23 #include <QDialogButtonBox>
24 #include <QCheckBox>
25 #include <QFileDialog>
26 #include <QMessageBox>
27 #include <QTextStream>
28 
30  : QgsPanelWidget( parent )
31 {
32  setupUi( this );
34 
35  connect( mButtonAdd, &QToolButton::clicked, this, &QgsSubstitutionListWidget::mButtonAdd_clicked );
36  connect( mButtonRemove, &QToolButton::clicked, this, &QgsSubstitutionListWidget::mButtonRemove_clicked );
37  connect( mButtonExport, &QToolButton::clicked, this, &QgsSubstitutionListWidget::mButtonExport_clicked );
38  connect( mButtonImport, &QToolButton::clicked, this, &QgsSubstitutionListWidget::mButtonImport_clicked );
39  connect( mTableSubstitutions, &QTableWidget::cellChanged, this, &QgsSubstitutionListWidget::tableChanged );
40 }
41 
43 {
44  mTableSubstitutions->blockSignals( true );
45  mTableSubstitutions->clearContents();
46  const auto constReplacements = substitutions.replacements();
47  for ( const QgsStringReplacement &replacement : constReplacements )
48  {
49  addSubstitution( replacement );
50  }
51  mTableSubstitutions->blockSignals( false );
52 }
53 
55 {
56  QList< QgsStringReplacement > result;
57  for ( int i = 0; i < mTableSubstitutions->rowCount(); ++i )
58  {
59  if ( !mTableSubstitutions->item( i, 0 ) )
60  continue;
61 
62  if ( mTableSubstitutions->item( i, 0 )->text().isEmpty() )
63  continue;
64 
65  QCheckBox *chkCaseSensitive = qobject_cast<QCheckBox *>( mTableSubstitutions->cellWidget( i, 2 ) );
66  QCheckBox *chkWholeWord = qobject_cast<QCheckBox *>( mTableSubstitutions->cellWidget( i, 3 ) );
67 
68  QgsStringReplacement replacement( mTableSubstitutions->item( i, 0 )->text(),
69  mTableSubstitutions->item( i, 1 )->text(),
70  chkCaseSensitive->isChecked(),
71  chkWholeWord->isChecked() );
72  result << replacement;
73  }
74  return QgsStringReplacementCollection( result );
75 }
76 
77 void QgsSubstitutionListWidget::mButtonAdd_clicked()
78 {
79  addSubstitution( QgsStringReplacement( QString(), QString(), false, true ) );
80  mTableSubstitutions->setFocus();
81  mTableSubstitutions->setCurrentCell( mTableSubstitutions->rowCount() - 1, 0 );
82 }
83 
84 void QgsSubstitutionListWidget::mButtonRemove_clicked()
85 {
86  int currentRow = mTableSubstitutions->currentRow();
87  mTableSubstitutions->removeRow( currentRow );
88  tableChanged();
89 }
90 
91 void QgsSubstitutionListWidget::tableChanged()
92 {
94 }
95 
96 void QgsSubstitutionListWidget::mButtonExport_clicked()
97 {
98  QString fileName = QFileDialog::getSaveFileName( this, tr( "Save Substitutions" ), QDir::homePath(),
99  tr( "XML files (*.xml *.XML)" ) );
100  if ( fileName.isEmpty() )
101  {
102  return;
103  }
104 
105  // ensure the user never omitted the extension from the file name
106  if ( !fileName.endsWith( QLatin1String( ".xml" ), Qt::CaseInsensitive ) )
107  {
108  fileName += QLatin1String( ".xml" );
109  }
110 
111  QDomDocument doc;
112  QDomElement root = doc.createElement( QStringLiteral( "substitutions" ) );
113  root.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0" ) );
115  collection.writeXml( root, doc );
116  doc.appendChild( root );
117 
118  QFile file( fileName );
119  if ( !file.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
120  {
121  QMessageBox::warning( nullptr, tr( "Export Substitutions" ),
122  tr( "Cannot write file %1:\n%2" ).arg( fileName, file.errorString() ),
123  QMessageBox::Ok,
124  QMessageBox::Ok );
125  return;
126  }
127 
128  QTextStream out( &file );
129  doc.save( out, 4 );
130 }
131 
132 void QgsSubstitutionListWidget::mButtonImport_clicked()
133 {
134  QString fileName = QFileDialog::getOpenFileName( this, tr( "Load Substitutions" ), QDir::homePath(),
135  tr( "XML files (*.xml *.XML)" ) );
136  if ( fileName.isEmpty() )
137  {
138  return;
139  }
140 
141  QFile file( fileName );
142  if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
143  {
144  QMessageBox::warning( nullptr, tr( "Import Substitutions" ),
145  tr( "Cannot read file %1:\n%2" ).arg( fileName, file.errorString() ),
146  QMessageBox::Ok,
147  QMessageBox::Ok );
148  return;
149  }
150 
151  QDomDocument doc;
152  QString errorStr;
153  int errorLine;
154  int errorColumn;
155 
156  if ( !doc.setContent( &file, true, &errorStr, &errorLine, &errorColumn ) )
157  {
158  QMessageBox::warning( nullptr, tr( "Import substitutions" ),
159  tr( "Parse error at line %1, column %2:\n%3" )
160  .arg( errorLine )
161  .arg( errorColumn )
162  .arg( errorStr ),
163  QMessageBox::Ok,
164  QMessageBox::Ok );
165  return;
166  }
167 
168  QDomElement root = doc.documentElement();
169  if ( root.tagName() != QLatin1String( "substitutions" ) )
170  {
171  QMessageBox::warning( nullptr, tr( "Import Substitutions" ),
172  tr( "The selected file is not a substitution list." ),
173  QMessageBox::Ok,
174  QMessageBox::Ok );
175  return;
176  }
177 
179  collection.readXml( root );
180  setSubstitutions( collection );
181  tableChanged();
182 }
183 
184 void QgsSubstitutionListWidget::addSubstitution( const QgsStringReplacement &substitution )
185 {
186  int row = mTableSubstitutions->rowCount();
187  mTableSubstitutions->insertRow( row );
188 
189  Qt::ItemFlags itemFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable
190  | Qt::ItemIsEditable;
191 
192  QTableWidgetItem *matchItem = new QTableWidgetItem( substitution.match() );
193  matchItem->setFlags( itemFlags );
194  mTableSubstitutions->setItem( row, 0, matchItem );
195  QTableWidgetItem *replaceItem = new QTableWidgetItem( substitution.replacement() );
196  replaceItem->setFlags( itemFlags );
197  mTableSubstitutions->setItem( row, 1, replaceItem );
198 
199  QCheckBox *caseSensitiveChk = new QCheckBox( this );
200  caseSensitiveChk->setChecked( substitution.caseSensitive() );
201  mTableSubstitutions->setCellWidget( row, 2, caseSensitiveChk );
202  connect( caseSensitiveChk, &QAbstractButton::toggled, this, &QgsSubstitutionListWidget::tableChanged );
203 
204  QCheckBox *wholeWordChk = new QCheckBox( this );
205  wholeWordChk->setChecked( substitution.wholeWordOnly() );
206  mTableSubstitutions->setCellWidget( row, 3, wholeWordChk );
207  connect( wholeWordChk, &QAbstractButton::toggled, this, &QgsSubstitutionListWidget::tableChanged );
208 }
209 
210 
211 //
212 // QgsSubstitutionListDialog
213 //
214 
215 
217  : QDialog( parent )
218 
219 {
220  setWindowTitle( tr( "Substitutions" ) );
221  QVBoxLayout *vLayout = new QVBoxLayout();
222  mWidget = new QgsSubstitutionListWidget();
223  vLayout->addWidget( mWidget );
224  QDialogButtonBox *bbox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal );
225  connect( bbox, &QDialogButtonBox::accepted, this, &QDialog::accept );
226  connect( bbox, &QDialogButtonBox::rejected, this, &QDialog::reject );
227  vLayout->addWidget( bbox );
228  setLayout( vLayout );
229 }
230 
232 {
233  mWidget->setSubstitutions( substitutions );
234 }
235 
237 {
238  return mWidget->substitutions();
239 }
QgsStringReplacementCollection::readXml
void readXml(const QDomElement &elem)
Reads the collection state from an XML element.
Definition: qgsstringutils.cpp:746
QgsSubstitutionListDialog::setSubstitutions
void setSubstitutions(const QgsStringReplacementCollection &substitutions)
Sets the list of substitutions to show in the dialog.
Definition: qgssubstitutionlistwidget.cpp:231
qgsgui.h
QgsSubstitutionListWidget::substitutionsChanged
void substitutionsChanged(const QgsStringReplacementCollection &substitutions)
Emitted when the substitution definitions change.
QgsStringReplacement::wholeWordOnly
bool wholeWordOnly() const
Returns true if match only applies to whole words, or false if partial word matches are permitted.
Definition: qgsstringutils.h:65
QgsSubstitutionListWidget
A widget which allows users to specify a list of substitutions to apply to a string,...
Definition: qgssubstitutionlistwidget.h:37
QgsStringReplacementCollection::replacements
QList< QgsStringReplacement > replacements() const
Returns the list of string replacements in this collection.
Definition: qgsstringutils.h:132
QgsSubstitutionListDialog::substitutions
QgsStringReplacementCollection substitutions
Definition: qgssubstitutionlistwidget.h:92
QgsSubstitutionListWidget::QgsSubstitutionListWidget
QgsSubstitutionListWidget(QWidget *parent=nullptr)
Constructor for QgsSubstitutionListWidget.
Definition: qgssubstitutionlistwidget.cpp:29
QgsStringReplacement::caseSensitive
bool caseSensitive() const
Returns true if match is case sensitive.
Definition: qgsstringutils.h:62
QgsGui::enableAutoGeometryRestore
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition: qgsgui.cpp:139
QgsPanelWidget
Base class for any widget that can be shown as a inline panel.
Definition: qgspanelwidget.h:30
QgsStringReplacement
A representation of a single string replacement.
Definition: qgsstringutils.h:39
QgsStringReplacementCollection
A collection of string replacements (specified using QgsStringReplacement objects).
Definition: qgsstringutils.h:116
QgsStringReplacement::replacement
QString replacement() const
Returns the string to replace matches with.
Definition: qgsstringutils.h:59
QgsStringReplacement::match
QString match() const
Returns the string matched by this object.
Definition: qgsstringutils.h:56
QgsSubstitutionListWidget::setSubstitutions
void setSubstitutions(const QgsStringReplacementCollection &substitutions)
Sets the list of substitutions to show in the widget.
Definition: qgssubstitutionlistwidget.cpp:42
qgssubstitutionlistwidget.h
QgsStringReplacementCollection::writeXml
void writeXml(QDomElement &elem, QDomDocument &doc) const
Writes the collection state to an XML element.
Definition: qgsstringutils.cpp:730
QgsSubstitutionListWidget::substitutions
QgsStringReplacementCollection substitutions
Definition: qgssubstitutionlistwidget.h:39
QgsSubstitutionListDialog::QgsSubstitutionListDialog
QgsSubstitutionListDialog(QWidget *parent=nullptr)
Constructor for QgsSubstitutionListDialog.
Definition: qgssubstitutionlistwidget.cpp:216