QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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 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
132void QgsSubstitutionListWidget::mButtonImport_clicked()
133{
134 const 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 const 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
184void QgsSubstitutionListWidget::addSubstitution( const QgsStringReplacement &substitution )
185{
186 const int row = mTableSubstitutions->rowCount();
187 mTableSubstitutions->insertRow( row );
188
189 const 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{
234}
235
237{
238 return mWidget->substitutions();
239}
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:178
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