QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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 const 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
77void QgsSubstitutionListWidget::mButtonAdd_clicked()
78{
79 addSubstitution( QgsStringReplacement( QString(), QString(), false, true ) );
80 mTableSubstitutions->setFocus();
81 mTableSubstitutions->setCurrentCell( mTableSubstitutions->rowCount() - 1, 0 );
82}
83
84void QgsSubstitutionListWidget::mButtonRemove_clicked()
85{
86 const int currentRow = mTableSubstitutions->currentRow();
87 mTableSubstitutions->removeRow( currentRow );
88 tableChanged();
89}
90
91void QgsSubstitutionListWidget::tableChanged()
92{
94}
95
96void QgsSubstitutionListWidget::mButtonExport_clicked()
97{
98 QString fileName = QFileDialog::getSaveFileName( this, tr( "Save Substitutions" ), QDir::homePath(),
99 tr( "XML files (*.xml *.XML)" ) );
100 // return dialog focus on Mac
101 activateWindow();
102 raise();
103 if ( fileName.isEmpty() )
104 {
105 return;
106 }
107
108 // ensure the user never omitted the extension from the file name
109 if ( !fileName.endsWith( QLatin1String( ".xml" ), Qt::CaseInsensitive ) )
110 {
111 fileName += QLatin1String( ".xml" );
112 }
113
114 QDomDocument doc;
115 QDomElement root = doc.createElement( QStringLiteral( "substitutions" ) );
116 root.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0" ) );
118 collection.writeXml( root, doc );
119 doc.appendChild( root );
120
121 QFile file( fileName );
122 if ( !file.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
123 {
124 QMessageBox::warning( nullptr, tr( "Export Substitutions" ),
125 tr( "Cannot write file %1:\n%2" ).arg( fileName, file.errorString() ),
126 QMessageBox::Ok,
127 QMessageBox::Ok );
128 return;
129 }
130
131 QTextStream out( &file );
132 doc.save( out, 4 );
133}
134
135void QgsSubstitutionListWidget::mButtonImport_clicked()
136{
137 const QString fileName = QFileDialog::getOpenFileName( this, tr( "Load Substitutions" ), QDir::homePath(),
138 tr( "XML files (*.xml *.XML)" ) );
139 if ( fileName.isEmpty() )
140 {
141 return;
142 }
143
144 QFile file( fileName );
145 if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
146 {
147 QMessageBox::warning( nullptr, tr( "Import Substitutions" ),
148 tr( "Cannot read file %1:\n%2" ).arg( fileName, file.errorString() ),
149 QMessageBox::Ok,
150 QMessageBox::Ok );
151 return;
152 }
153
154 QDomDocument doc;
155 QString errorStr;
156 int errorLine;
157 int errorColumn;
158
159 if ( !doc.setContent( &file, true, &errorStr, &errorLine, &errorColumn ) )
160 {
161 QMessageBox::warning( nullptr, tr( "Import substitutions" ),
162 tr( "Parse error at line %1, column %2:\n%3" )
163 .arg( errorLine )
164 .arg( errorColumn )
165 .arg( errorStr ),
166 QMessageBox::Ok,
167 QMessageBox::Ok );
168 return;
169 }
170
171 const QDomElement root = doc.documentElement();
172 if ( root.tagName() != QLatin1String( "substitutions" ) )
173 {
174 QMessageBox::warning( nullptr, tr( "Import Substitutions" ),
175 tr( "The selected file is not a substitution list." ),
176 QMessageBox::Ok,
177 QMessageBox::Ok );
178 return;
179 }
180
182 collection.readXml( root );
183 setSubstitutions( collection );
184 tableChanged();
185}
186
187void QgsSubstitutionListWidget::addSubstitution( const QgsStringReplacement &substitution )
188{
189 const int row = mTableSubstitutions->rowCount();
190 mTableSubstitutions->insertRow( row );
191
192 const Qt::ItemFlags itemFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable
193 | Qt::ItemIsEditable;
194
195 QTableWidgetItem *matchItem = new QTableWidgetItem( substitution.match() );
196 matchItem->setFlags( itemFlags );
197 mTableSubstitutions->setItem( row, 0, matchItem );
198 QTableWidgetItem *replaceItem = new QTableWidgetItem( substitution.replacement() );
199 replaceItem->setFlags( itemFlags );
200 mTableSubstitutions->setItem( row, 1, replaceItem );
201
202 QCheckBox *caseSensitiveChk = new QCheckBox( this );
203 caseSensitiveChk->setChecked( substitution.caseSensitive() );
204 mTableSubstitutions->setCellWidget( row, 2, caseSensitiveChk );
205 connect( caseSensitiveChk, &QAbstractButton::toggled, this, &QgsSubstitutionListWidget::tableChanged );
206
207 QCheckBox *wholeWordChk = new QCheckBox( this );
208 wholeWordChk->setChecked( substitution.wholeWordOnly() );
209 mTableSubstitutions->setCellWidget( row, 3, wholeWordChk );
210 connect( wholeWordChk, &QAbstractButton::toggled, this, &QgsSubstitutionListWidget::tableChanged );
211}
212
213
214//
215// QgsSubstitutionListDialog
216//
217
218
220 : QDialog( parent )
221
222{
223 setWindowTitle( tr( "Substitutions" ) );
224 QVBoxLayout *vLayout = new QVBoxLayout();
225 mWidget = new QgsSubstitutionListWidget();
226 vLayout->addWidget( mWidget );
227 QDialogButtonBox *bbox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal );
228 connect( bbox, &QDialogButtonBox::accepted, this, &QDialog::accept );
229 connect( bbox, &QDialogButtonBox::rejected, this, &QDialog::reject );
230 vLayout->addWidget( bbox );
231 setLayout( vLayout );
232}
233
235{
237}
238
240{
241 return mWidget->substitutions();
242}
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:194
Base class for any widget that can be shown as a inline panel.
A collection of string replacements (specified using QgsStringReplacement objects).
void readXml(const QDomElement &elem)
Reads the collection state from an XML element.
void writeXml(QDomElement &elem, QDomDocument &doc) const
Writes the collection state to an XML element.
QList< QgsStringReplacement > replacements() const
Returns the list of string replacements in this collection.
A representation of a single string replacement.
bool wholeWordOnly() const
Returns true if match only applies to whole words, or false if partial word matches are permitted.
QString replacement() const
Returns the string to replace matches with.
bool caseSensitive() const
Returns true if match is case sensitive.
QString match() const
Returns the string matched by this object.
QgsSubstitutionListDialog(QWidget *parent=nullptr)
Constructor for QgsSubstitutionListDialog.
QgsStringReplacementCollection substitutions
void setSubstitutions(const QgsStringReplacementCollection &substitutions)
Sets the list of substitutions to show in the dialog.
A widget which allows users to specify a list of substitutions to apply to a string,...
QgsSubstitutionListWidget(QWidget *parent=nullptr)
Constructor for QgsSubstitutionListWidget.
void setSubstitutions(const QgsStringReplacementCollection &substitutions)
Sets the list of substitutions to show in the widget.
void substitutionsChanged(const QgsStringReplacementCollection &substitutions)
Emitted when the substitution definitions change.
QgsStringReplacementCollection substitutions