QGIS API Documentation 3.43.0-Master (3ee7834ace6)
qgsnewnamedialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsnewnamedialog.cpp
3 -------------------
4 begin : May, 2015
5 copyright : (C) 2015 Radim Blazek
6 email : radim.blazek@gmail.com
7 ***************************************************************************/
8/***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17#include <QLabel>
18#include <QLineEdit>
19#include <QPushButton>
20#include <QRegularExpressionValidator>
21#include <QSizePolicy>
22#include <QCompleter>
23
24#include "qgslogger.h"
25#include "qgsnewnamedialog.h"
26#include "moc_qgsnewnamedialog.cpp"
27
28QgsNewNameDialog::QgsNewNameDialog( const QString &source, const QString &initial, const QStringList &extensions, const QStringList &existing, Qt::CaseSensitivity cs, QWidget *parent, Qt::WindowFlags flags )
29 : QgsDialog( parent, flags, QDialogButtonBox::Ok | QDialogButtonBox::Cancel )
30 , mExiting( existing )
31 , mExtensions( extensions )
32 , mCaseSensitivity( cs )
33{
34 setWindowTitle( tr( "New Name" ) );
35 QgsDialog::layout()->setSizeConstraint( QLayout::SetMinimumSize );
36 layout()->setSizeConstraint( QLayout::SetMinimumSize );
37 layout()->setSpacing( 6 );
38 mOkString = buttonBox()->button( QDialogButtonBox::Ok )->text();
39 QString hintString;
40 const QString nameDesc = mExtensions.isEmpty() ? tr( "name" ) : tr( "base name" );
41 if ( source.isEmpty() )
42 {
43 hintString = tr( "Enter new %1" ).arg( nameDesc );
44 }
45 else
46 {
47 hintString = tr( "Enter new %1 for %2" ).arg( nameDesc, source );
48 }
49 mHintLabel = new QLabel( hintString, this );
50 layout()->addWidget( mHintLabel );
51
52 mLineEdit = new QLineEdit( initial, this );
53 mLineEdit->setMinimumWidth( mLineEdit->fontMetrics().horizontalAdvance( 'x' ) * 44 );
54
55 connect( mLineEdit, &QLineEdit::textChanged, this, &QgsNewNameDialog::nameChanged );
56 connect( mLineEdit, &QLineEdit::textChanged, this, &QgsNewNameDialog::newNameChanged );
57 layout()->addWidget( mLineEdit );
58
59 mNamesLabel = new QLabel( QStringLiteral( " " ), this );
60 mNamesLabel->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
61 if ( !mExtensions.isEmpty() )
62 {
63 mNamesLabel->setWordWrap( true );
64 layout()->addWidget( mNamesLabel );
65 }
66
67 mErrorLabel = new QLabel( QStringLiteral( " " ), this );
68 mErrorLabel->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
69 mErrorLabel->setWordWrap( true );
70 layout()->addWidget( mErrorLabel );
71
72 mLineEdit->setFocus();
73 mLineEdit->selectAll();
74
76}
77
78void QgsNewNameDialog::setHintString( const QString &hintString )
79{
80 mHintLabel->setText( hintString );
81}
82
84{
85 return mHintLabel->text();
86}
87
89{
90 mOverwriteEnabled = enabled;
91 nameChanged(); //update UI
92}
93
95{
96 mAllowEmptyName = allowed;
97 nameChanged(); //update UI
98}
99
101{
103 nameChanged(); //update UI
104}
105
106void QgsNewNameDialog::setRegularExpression( const QString &expression )
107{
108 if ( !expression.isEmpty() )
109 {
110 mRegularExpression = QRegularExpression( QRegularExpression::anchoredPattern( expression ) );
111 QRegularExpressionValidator *validator = new QRegularExpressionValidator( mRegularExpression, this );
112 mLineEdit->setValidator( validator );
113 }
114 else
115 {
116 mRegularExpression = QRegularExpression();
117 mLineEdit->setValidator( nullptr );
118 }
119 nameChanged();
120}
121
123{
124 if ( !show )
125 {
126 mLineEdit->setCompleter( nullptr );
127 return;
128 }
129
130 QCompleter *completer = new QCompleter( mExiting, this );
131 completer->setCaseSensitivity( Qt::CaseInsensitive );
132 completer->setCompletionMode( QCompleter::UnfilteredPopupCompletion );
133 mLineEdit->setCompleter( completer );
134}
135
136QString QgsNewNameDialog::highlightText( const QString &text )
137{
138 return "<b>" + text + "</b>";
139}
140
142{
143 QString namesString = tr( "Full names" ) + ": ";
144 if ( !mExtensions.isEmpty() )
145 {
146 mNamesLabel->setText( namesString );
147 }
148 mErrorLabel->setText( QStringLiteral( " " ) ); // space to keep vertical space
149 QPushButton *okButton = buttonBox()->button( QDialogButtonBox::Ok );
150 okButton->setText( mOkString );
151 okButton->setEnabled( true );
152
153 const QString newName = name();
154
155 if ( newName.length() == 0 || ( !mRegularExpression.pattern().isEmpty() && !mRegularExpression.match( newName ).hasMatch() ) )
156 {
157 //mErrorLabel->setText( highlightText( tr( "Enter new name" ) );
158 okButton->setEnabled( mAllowEmptyName );
159 return;
160 }
161
162 const QStringList newNames = fullNames( newName, mExtensions );
163 if ( !mExtensions.isEmpty() )
164 {
165 namesString += ' ' + newNames.join( QLatin1String( ", " ) );
166 mNamesLabel->setText( namesString );
167 }
168
169 const QStringList conflicts = matching( newNames, mExiting, mCaseSensitivity );
170
171 if ( !conflicts.isEmpty() )
172 {
173 const QString warning = !mConflictingNameWarning.isEmpty() ? mConflictingNameWarning
174 : tr( "%n Name(s) %1 exists", nullptr, conflicts.size() ).arg( conflicts.join( QLatin1String( ", " ) ) );
175 mErrorLabel->setText( highlightText( warning ) );
176 if ( mOverwriteEnabled )
177 {
178 okButton->setText( tr( "Overwrite" ) );
179 }
180 else
181 {
182 okButton->setEnabled( false );
183 }
184 return;
185 }
186}
187
189{
190 return mLineEdit->text().trimmed();
191}
192
193QStringList QgsNewNameDialog::fullNames( const QString &name, const QStringList &extensions )
194{
195 QStringList list;
196 const auto constExtensions = extensions;
197 for ( const QString &ext : constExtensions )
198 {
199 list << name + ext;
200 }
201 if ( list.isEmpty() )
202 {
203 list << name;
204 }
205 return list;
206}
207
208QStringList QgsNewNameDialog::matching( const QStringList &newNames, const QStringList &existingNames, Qt::CaseSensitivity cs )
209{
210 QStringList list;
211
212 const auto constNewNames = newNames;
213 for ( const QString &newName : constNewNames )
214 {
215 const auto constExistingNames = existingNames;
216 for ( const QString &existingName : constExistingNames )
217 {
218 if ( existingName.compare( newName, cs ) == 0 )
219 {
220 list << existingName;
221 }
222 }
223 }
224 return list;
225}
226
227bool QgsNewNameDialog::exists( const QString &name, const QStringList &extensions, const QStringList &existing, Qt::CaseSensitivity cs )
228{
229 const QStringList newNames = fullNames( name, extensions );
230 const QStringList conflicts = matching( newNames, existing, cs );
231 return !conflicts.isEmpty();
232}
A generic dialog with layout and button box.
Definition qgsdialog.h:34
QDialogButtonBox * buttonBox()
Returns the button box.
Definition qgsdialog.h:45
QVBoxLayout * layout()
Returns the central layout. Widgets added to it must have this dialog as parent.
Definition qgsdialog.h:43
void setConflictingNameWarning(const QString &string)
Sets the string used for warning users if a conflicting name exists.
static QStringList fullNames(const QString &name, const QStringList &extensions)
static bool exists(const QString &name, const QStringList &extensions, const QStringList &existing, Qt::CaseSensitivity cs=Qt::CaseSensitive)
Test if name or name with at least one extension exists.
QgsNewNameDialog(const QString &source=QString(), const QString &initial=QString(), const QStringList &extensions=QStringList(), const QStringList &existing=QStringList(), Qt::CaseSensitivity cs=Qt::CaseSensitive, QWidget *parent=nullptr, Qt::WindowFlags flags=QgsGuiUtils::ModalDialogFlags)
New dialog constructor.
Qt::CaseSensitivity mCaseSensitivity
void newNameChanged()
Emitted when the name is changed in the dialog.
QRegularExpression mRegularExpression
void setShowExistingNamesCompleter(bool show)
Sets whether a completer for existing names should be used in the line edit.
static QStringList matching(const QStringList &newNames, const QStringList &existingNames, Qt::CaseSensitivity cs=Qt::CaseSensitive)
QStringList mExtensions
void setOverwriteEnabled(bool enabled)
Sets whether users are permitted to overwrite existing names.
QLabel * mNamesLabel
List of names with extensions.
void setRegularExpression(const QString &expression)
Sets a regular expression to use for validating user-entered names in the dialog.
QString highlightText(const QString &text)
QString hintString() const
Returns the hint string for the dialog (the text shown above the name input box).
QString name() const
Name entered by user.
QString mConflictingNameWarning
void setAllowEmptyName(bool allowed)
Sets whether users are permitted to leave the widget empty.
void setHintString(const QString &hintString)
Sets the hint string for the dialog (the text shown above the name input box).