QGIS API Documentation 3.99.0-Master (e9821da5c6b)
Loading...
Searching...
No Matches
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
22#include "qgsgui.h"
23
24#include <QCheckBox>
25#include <QDialogButtonBox>
26#include <QFileDialog>
27#include <QMessageBox>
28#include <QString>
29#include <QTextStream>
30
31#include "moc_qgssubstitutionlistwidget.cpp"
32
33using namespace Qt::StringLiterals;
34
36 : QgsPanelWidget( parent )
37{
38 setupUi( this );
40
41 connect( mButtonAdd, &QToolButton::clicked, this, &QgsSubstitutionListWidget::mButtonAdd_clicked );
42 connect( mButtonRemove, &QToolButton::clicked, this, &QgsSubstitutionListWidget::mButtonRemove_clicked );
43 connect( mButtonExport, &QToolButton::clicked, this, &QgsSubstitutionListWidget::mButtonExport_clicked );
44 connect( mButtonImport, &QToolButton::clicked, this, &QgsSubstitutionListWidget::mButtonImport_clicked );
45 connect( mTableSubstitutions, &QTableWidget::cellChanged, this, &QgsSubstitutionListWidget::tableChanged );
46}
47
49{
50 mTableSubstitutions->blockSignals( true );
51 mTableSubstitutions->clearContents();
52 const auto constReplacements = substitutions.replacements();
53 for ( const QgsStringReplacement &replacement : constReplacements )
54 {
55 addSubstitution( replacement );
56 }
57 mTableSubstitutions->blockSignals( false );
58}
59
61{
62 QList<QgsStringReplacement> result;
63 for ( int i = 0; i < mTableSubstitutions->rowCount(); ++i )
64 {
65 if ( !mTableSubstitutions->item( i, 0 ) )
66 continue;
67
68 if ( mTableSubstitutions->item( i, 0 )->text().isEmpty() )
69 continue;
70
71 QCheckBox *chkCaseSensitive = qobject_cast<QCheckBox *>( mTableSubstitutions->cellWidget( i, 2 ) );
72 QCheckBox *chkWholeWord = qobject_cast<QCheckBox *>( mTableSubstitutions->cellWidget( i, 3 ) );
73
74 const QgsStringReplacement replacement( mTableSubstitutions->item( i, 0 )->text(), mTableSubstitutions->item( i, 1 )->text(), chkCaseSensitive->isChecked(), chkWholeWord->isChecked() );
75 result << replacement;
76 }
77 return QgsStringReplacementCollection( result );
78}
79
80void QgsSubstitutionListWidget::mButtonAdd_clicked()
81{
82 addSubstitution( QgsStringReplacement( QString(), QString(), false, true ) );
83 mTableSubstitutions->setFocus();
84 mTableSubstitutions->setCurrentCell( mTableSubstitutions->rowCount() - 1, 0 );
85}
86
87void QgsSubstitutionListWidget::mButtonRemove_clicked()
88{
89 const int currentRow = mTableSubstitutions->currentRow();
90 mTableSubstitutions->removeRow( currentRow );
91 tableChanged();
92}
93
94void QgsSubstitutionListWidget::tableChanged()
95{
97}
98
99void QgsSubstitutionListWidget::mButtonExport_clicked()
100{
101 QString fileName = QFileDialog::getSaveFileName( this, tr( "Save Substitutions" ), QDir::homePath(), tr( "XML files (*.xml *.XML)" ) );
102 // return dialog focus on Mac
103 activateWindow();
104 raise();
105 if ( fileName.isEmpty() )
106 {
107 return;
108 }
109
110 // ensure the user never omitted the extension from the file name
111 if ( !fileName.endsWith( ".xml"_L1, Qt::CaseInsensitive ) )
112 {
113 fileName += ".xml"_L1;
114 }
115
116 QDomDocument doc;
117 QDomElement root = doc.createElement( u"substitutions"_s );
118 root.setAttribute( u"version"_s, u"1.0"_s );
119 const QgsStringReplacementCollection collection = substitutions();
120 collection.writeXml( root, doc );
121 doc.appendChild( root );
122
123 QFile file( fileName );
124 if ( !file.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
125 {
126 QMessageBox::warning( nullptr, tr( "Export Substitutions" ), tr( "Cannot write file %1:\n%2" ).arg( fileName, file.errorString() ), QMessageBox::Ok, QMessageBox::Ok );
127 return;
128 }
129
130 QTextStream out( &file );
131 doc.save( out, 4 );
132}
133
134void QgsSubstitutionListWidget::mButtonImport_clicked()
135{
136 const QString fileName = QFileDialog::getOpenFileName( this, tr( "Load Substitutions" ), QDir::homePath(), tr( "XML files (*.xml *.XML)" ) );
137 if ( fileName.isEmpty() )
138 {
139 return;
140 }
141
142 QFile file( fileName );
143 if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
144 {
145 QMessageBox::warning( nullptr, tr( "Import Substitutions" ), tr( "Cannot read file %1:\n%2" ).arg( fileName, file.errorString() ), QMessageBox::Ok, QMessageBox::Ok );
146 return;
147 }
148
149 QDomDocument doc;
150 QString errorStr;
151 int errorLine;
152 int errorColumn;
153
154 if ( !doc.setContent( &file, true, &errorStr, &errorLine, &errorColumn ) )
155 {
156 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 );
157 return;
158 }
159
160 const QDomElement root = doc.documentElement();
161 if ( root.tagName() != "substitutions"_L1 )
162 {
163 QMessageBox::warning( nullptr, tr( "Import Substitutions" ), tr( "The selected file is not a substitution list." ), QMessageBox::Ok, QMessageBox::Ok );
164 return;
165 }
166
167 QgsStringReplacementCollection collection;
168 collection.readXml( root );
169 setSubstitutions( collection );
170 tableChanged();
171}
172
173void QgsSubstitutionListWidget::addSubstitution( const QgsStringReplacement &substitution )
174{
175 const int row = mTableSubstitutions->rowCount();
176 mTableSubstitutions->insertRow( row );
177
178 const Qt::ItemFlags itemFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable
179 | Qt::ItemIsEditable;
180
181 QTableWidgetItem *matchItem = new QTableWidgetItem( substitution.match() );
182 matchItem->setFlags( itemFlags );
183 mTableSubstitutions->setItem( row, 0, matchItem );
184 QTableWidgetItem *replaceItem = new QTableWidgetItem( substitution.replacement() );
185 replaceItem->setFlags( itemFlags );
186 mTableSubstitutions->setItem( row, 1, replaceItem );
187
188 QCheckBox *caseSensitiveChk = new QCheckBox( this );
189 caseSensitiveChk->setChecked( substitution.caseSensitive() );
190 mTableSubstitutions->setCellWidget( row, 2, caseSensitiveChk );
191 connect( caseSensitiveChk, &QAbstractButton::toggled, this, &QgsSubstitutionListWidget::tableChanged );
192
193 QCheckBox *wholeWordChk = new QCheckBox( this );
194 wholeWordChk->setChecked( substitution.wholeWordOnly() );
195 mTableSubstitutions->setCellWidget( row, 3, wholeWordChk );
196 connect( wholeWordChk, &QAbstractButton::toggled, this, &QgsSubstitutionListWidget::tableChanged );
197}
198
199
200//
201// QgsSubstitutionListDialog
202//
203
204
206 : QDialog( parent )
207
208{
209 setWindowTitle( tr( "Substitutions" ) );
210 QVBoxLayout *vLayout = new QVBoxLayout();
211 mWidget = new QgsSubstitutionListWidget();
212 vLayout->addWidget( mWidget );
213 QDialogButtonBox *bbox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal );
214 connect( bbox, &QDialogButtonBox::accepted, this, &QDialog::accept );
215 connect( bbox, &QDialogButtonBox::rejected, this, &QDialog::reject );
216 vLayout->addWidget( bbox );
217 setLayout( vLayout );
218}
219
224
226{
227 return mWidget->substitutions();
228}
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:224
QgsPanelWidget(QWidget *parent=nullptr)
Base class for any widget that can be shown as an 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.
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