QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
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 : [email protected]
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 
23 #include "qgslogger.h"
24 #include "qgsnewnamedialog.h"
25 
26 QgsNewNameDialog::QgsNewNameDialog( const QString &source,
27  const QString &initial,
28  const QStringList &extensions,
29  const QStringList &existing,
30  Qt::CaseSensitivity cs,
31  QWidget *parent,
32  Qt::WindowFlags flags )
33  : QgsDialog( parent, flags, QDialogButtonBox::Ok | QDialogButtonBox::Cancel )
34  , mExiting( existing )
35  , mExtensions( extensions )
36  , mCaseSensitivity( cs )
37 {
38  setWindowTitle( tr( "New Name" ) );
39  QgsDialog::layout()->setSizeConstraint( QLayout::SetMinimumSize );
40  layout()->setSizeConstraint( QLayout::SetMinimumSize );
41  layout()->setSpacing( 6 );
42  mOkString = buttonBox()->button( QDialogButtonBox::Ok )->text();
43  QString hintString;
44  const QString nameDesc = mExtensions.isEmpty() ? tr( "name" ) : tr( "base name" );
45  if ( source.isEmpty() )
46  {
47  hintString = tr( "Enter new %1" ).arg( nameDesc );
48  }
49  else
50  {
51  hintString = tr( "Enter new %1 for %2" ).arg( nameDesc, source );
52  }
53  mHintLabel = new QLabel( hintString, this );
54  layout()->addWidget( mHintLabel );
55 
56  mLineEdit = new QLineEdit( initial, this );
57  mLineEdit->setMinimumWidth( mLineEdit->fontMetrics().horizontalAdvance( 'x' ) * 44 );
58 
59  connect( mLineEdit, &QLineEdit::textChanged, this, &QgsNewNameDialog::nameChanged );
60  connect( mLineEdit, &QLineEdit::textChanged, this, &QgsNewNameDialog::newNameChanged );
61  layout()->addWidget( mLineEdit );
62 
63  mNamesLabel = new QLabel( QStringLiteral( " " ), this );
64  mNamesLabel->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
65  if ( !mExtensions.isEmpty() )
66  {
67  mNamesLabel->setWordWrap( true );
68  layout()->addWidget( mNamesLabel );
69  }
70 
71  mErrorLabel = new QLabel( QStringLiteral( " " ), this );
72  mErrorLabel->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
73  mErrorLabel->setWordWrap( true );
74  layout()->addWidget( mErrorLabel );
75 
76  mLineEdit->setFocus();
77  mLineEdit->selectAll();
78 
79  nameChanged();
80 }
81 
82 void QgsNewNameDialog::setHintString( const QString &hintString )
83 {
84  mHintLabel->setText( hintString );
85 }
86 
88 {
89  return mHintLabel->text();
90 }
91 
93 {
94  mOverwriteEnabled = enabled;
95  nameChanged(); //update UI
96 }
97 
99 {
100  mAllowEmptyName = allowed;
101  nameChanged(); //update UI
102 }
103 
104 void QgsNewNameDialog::setConflictingNameWarning( const QString &string )
105 {
106  mConflictingNameWarning = string;
107  nameChanged(); //update UI
108 }
109 
110 void QgsNewNameDialog::setRegularExpression( const QString &expression )
111 {
112  if ( !expression.isEmpty() )
113  {
114  mRegularExpression = QRegularExpression( QRegularExpression::anchoredPattern( expression ) );
115  QRegularExpressionValidator *validator = new QRegularExpressionValidator( mRegularExpression, this );
116  mLineEdit->setValidator( validator );
117  }
118  else
119  {
120  mRegularExpression = QRegularExpression();
121  mLineEdit->setValidator( nullptr );
122  }
123  nameChanged();
124 }
125 
126 QString QgsNewNameDialog::highlightText( const QString &text )
127 {
128  return "<b>" + text + "</b>";
129 }
130 
132 {
133  QString namesString = tr( "Full names" ) + ": ";
134  if ( !mExtensions.isEmpty() )
135  {
136  mNamesLabel->setText( namesString );
137  }
138  mErrorLabel->setText( QStringLiteral( " " ) ); // space to keep vertical space
139  QPushButton *okButton = buttonBox()->button( QDialogButtonBox::Ok );
140  okButton->setText( mOkString );
141  okButton->setEnabled( true );
142 
143  const QString newName = name();
144 
145  if ( newName.length() == 0 || ( !mRegularExpression.pattern().isEmpty() && !mRegularExpression.match( newName ).hasMatch() ) )
146  {
147  //mErrorLabel->setText( highlightText( tr( "Enter new name" ) );
148  okButton->setEnabled( mAllowEmptyName );
149  return;
150  }
151 
152  const QStringList newNames = fullNames( newName, mExtensions );
153  if ( !mExtensions.isEmpty() )
154  {
155  namesString += ' ' + newNames.join( QLatin1String( ", " ) );
156  mNamesLabel->setText( namesString );
157  }
158 
159  const QStringList conflicts = matching( newNames, mExiting, mCaseSensitivity );
160 
161  if ( !conflicts.isEmpty() )
162  {
163  const QString warning = !mConflictingNameWarning.isEmpty() ? mConflictingNameWarning
164  : tr( "%n Name(s) %1 exists", nullptr, conflicts.size() ).arg( conflicts.join( QLatin1String( ", " ) ) );
165  mErrorLabel->setText( highlightText( warning ) );
166  if ( mOverwriteEnabled )
167  {
168  okButton->setText( tr( "Overwrite" ) );
169  }
170  else
171  {
172  okButton->setEnabled( false );
173  }
174  return;
175  }
176 }
177 
178 QString QgsNewNameDialog::name() const
179 {
180  return mLineEdit->text().trimmed();
181 }
182 
183 QStringList QgsNewNameDialog::fullNames( const QString &name, const QStringList &extensions )
184 {
185  QStringList list;
186  const auto constExtensions = extensions;
187  for ( const QString &ext : constExtensions )
188  {
189  list << name + ext;
190 
191  }
192  if ( list.isEmpty() )
193  {
194  list << name;
195  }
196  return list;
197 }
198 
199 QStringList QgsNewNameDialog::matching( const QStringList &newNames, const QStringList &existingNames,
200  Qt::CaseSensitivity cs )
201 {
202  QStringList list;
203 
204  const auto constNewNames = newNames;
205  for ( const QString &newName : constNewNames )
206  {
207  const auto constExistingNames = existingNames;
208  for ( const QString &existingName : constExistingNames )
209  {
210  if ( existingName.compare( newName, cs ) == 0 )
211  {
212  list << existingName;
213  }
214  }
215  }
216  return list;
217 }
218 
219 bool QgsNewNameDialog::exists( const QString &name, const QStringList &extensions,
220  const QStringList &existing, Qt::CaseSensitivity cs )
221 {
222  const QStringList newNames = fullNames( name, extensions );
223  const QStringList conflicts = matching( newNames, existing, cs );
224  return !conflicts.isEmpty();
225 }
A generic dialog with layout and button box.
Definition: qgsdialog.h:34
QVBoxLayout * layout()
Returns the central layout. Widgets added to it must have this dialog as parent.
Definition: qgsdialog.h:46
QDialogButtonBox * buttonBox()
Returns the button box.
Definition: qgsdialog.h:48
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
QLineEdit * mLineEdit
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.
QStringList mExiting
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).