diff --git a/src/gui/qgsnewnamedialog.cpp b/src/gui/qgsnewnamedialog.cpp new file mode 100644 index 00000000000..911d097f1ce --- /dev/null +++ b/src/gui/qgsnewnamedialog.cpp @@ -0,0 +1,167 @@ +/*************************************************************************** + qgsnewnamedialog.cpp + ------------------- + begin : May, 2015 + copyright : (C) 2015 Radim Blazek + email : radim.blazek@gmail.com + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include +#include +#include +#include + +#include "qgslogger.h" +#include "qgsnewnamedialog.h" + +QgsNewNameDialog::QgsNewNameDialog(const QString& source, const QString& initial, + const QStringList& extensions, const QStringList& existing, + const QRegExp& regexp, Qt::CaseSensitivity cs, + QWidget *parent, Qt::WindowFlags flags ) + : QgsDialog(parent, flags, QDialogButtonBox::Ok | QDialogButtonBox::Cancel) + , mExiting(existing) + , mExtensions(extensions) + , mCaseSensitivity(cs) + , mNamesLabel(0) +{ + setWindowTitle( tr("New name") ); + QDialog::layout()->setSizeConstraint(QLayout::SetMinimumSize); + layout()->setSizeConstraint(QLayout::SetMinimumSize); + mOkString = buttonBox()->button(QDialogButtonBox::Ok)->text(); + QString hintString; + QString nameDesc = mExtensions.isEmpty() ? tr("name") : tr("base name"); + if ( source.isEmpty() ) + { + hintString = tr("Enter new %1").arg(nameDesc); + } + else + { + hintString = tr("Enter new %1 for %2").arg(nameDesc).arg(source); + } + QLabel* hintLabel = new QLabel( hintString, this ); + layout()->addWidget( hintLabel ); + + mLineEdit = new QLineEdit( initial, this ); + if ( !regexp.isEmpty() ) + { + QRegExpValidator *validator = new QRegExpValidator( regexp, this ); + mLineEdit->setValidator( validator ); + } + connect( mLineEdit, SIGNAL( textChanged( QString ) ), this, SLOT( nameChanged() ) ); + layout()->addWidget( mLineEdit ); + + mNamesLabel = new QLabel( " ", this ); + mNamesLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); + if ( !mExtensions.isEmpty() ) + { + mNamesLabel->setWordWrap(true); + layout()->addWidget( mNamesLabel ); + } + + mErrorLabel = new QLabel( " ", this ); + mErrorLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); + mErrorLabel->setWordWrap(true); + layout()->addWidget( mErrorLabel ); + + nameChanged(); +} + +QString QgsNewNameDialog::highlightText(const QString& text) +{ + return "" + text + ""; +} + +void QgsNewNameDialog::nameChanged() +{ + QgsDebugMsg( "entered" ); + + QString namesString = tr("Full names") + ": "; + if ( !mExtensions.isEmpty() ) + { + mNamesLabel->setText( namesString ); + } + mErrorLabel->setText( " " ); // space to keep vertical space + QPushButton* okButton = buttonBox()->button(QDialogButtonBox::Ok); + okButton->setText( mOkString ); + okButton->setEnabled( true ); + + QString newName = name(); + + if ( newName.length() == 0 ) + { + //mErrorLabel->setText( highlightText( tr( "Enter new name" ) ); + okButton->setEnabled( false ); + return; + } + + QStringList newNames = fullNames(newName, mExtensions); + if ( !mExtensions.isEmpty() ) + { + namesString += " " + newNames.join(", "); + mNamesLabel->setText( namesString ); + } + + QStringList conflicts = matching(newNames, mExiting, mCaseSensitivity ); + + if ( !conflicts.isEmpty() ) + { + mErrorLabel->setText( highlightText( tr( "Name(s) %1 exists", 0, conflicts.size()).arg( conflicts.join(", ") ) ) ); + okButton->setText( tr( "Overwrite" ) ); + return; + } +} + +QString QgsNewNameDialog::name() const +{ + return mLineEdit->text().trimmed(); +} + +QStringList QgsNewNameDialog::fullNames(const QString& name, const QStringList& extensions) +{ + QStringList list; + foreach ( QString ext, extensions) + { + list << name + ext; + + } + if ( list.isEmpty() ) + { + list << name; + } + return list; +} + +QStringList QgsNewNameDialog::matching(const QStringList& newNames, const QStringList& existingNames, + Qt::CaseSensitivity cs) +{ + QStringList list; + + foreach ( QString newName, newNames) + { + foreach ( QString existingName, existingNames) + { + if ( existingName.compare(newName, cs) == 0 ) + { + list << existingName; + } + } + } + return list; +} + +bool QgsNewNameDialog::exists(const QString& name, const QStringList& extensions, + const QStringList& existing, Qt::CaseSensitivity cs) +{ + QStringList newNames = fullNames(name, extensions); + QStringList conflicts = matching(newNames, existing, cs ); + return conflicts.size() > 0; +} diff --git a/src/gui/qgsnewnamedialog.h b/src/gui/qgsnewnamedialog.h new file mode 100644 index 00000000000..8a55cda0ab2 --- /dev/null +++ b/src/gui/qgsnewnamedialog.h @@ -0,0 +1,80 @@ +/*************************************************************************** + qgsnewnamedialog.h + ------------------- + begin : May, 2015 + copyright : (C) 2015 Radim Blazek + email : radim.blazek@gmail.com + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSNEWNAMEDIALOG_H +#define QGSNEWNAMEDIALOG_H + +class QLabel; +class QLineEdit; + +#include "qgsdialog.h" + +/** \ingroup gui + * New name, for example new layer name dialog. If existing names are provided, + * the dialog warns users if an entered name already exists. + * @note added in 2.10 + */ +class GUI_EXPORT QgsNewNameDialog : public QgsDialog +{ + Q_OBJECT + public: + /** New dialog constructor. + * @param source original data source name, e.g. original layer name of the layer to be copied + * @param initial initial name + * @param extensions base name extensions, e.g. raster base name band extensions or vector layer type extensions + * @param existing existing names + * @param regexp regular expression to be used as validator, for example db tables should have "[A-Za-z_][A-Za-z0-9_]+" + * @param cs case sensitivity for new name to existing names comparison + * @param parent + * @param flags + */ + QgsNewNameDialog( const QString& source = QString::null, const QString& initial = QString::null, + const QStringList& extensions = QStringList(), const QStringList& existing = QStringList(), + const QRegExp& regexp = QRegExp(), Qt::CaseSensitivity cs = Qt::CaseSensitive, + QWidget *parent = 0, Qt::WindowFlags flags = QgisGui::ModalDialogFlags ); + + /** Name entered by user. + * @return new name + */ + QString name() const; + + /** Test if name or name with at least one extension exists. + * @param name name or base name + * @param extensions base name extensions + * @param existing existing names + * @return true if name exists + */ + static bool exists(const QString& name, const QStringList& extensions, + const QStringList& existing, Qt::CaseSensitivity cs = Qt::CaseSensitive ); + public slots: + void nameChanged(); + + protected: + QStringList mExiting; + QStringList mExtensions; + Qt::CaseSensitivity mCaseSensitivity; + QLineEdit *mLineEdit; + QLabel *mNamesLabel; // list of names with extensions + QLabel *mErrorLabel; + QString mOkString; + QString highlightText(const QString& text); + static QStringList fullNames(const QString& name, const QStringList& extensions); + // get list of existing names + static QStringList matching(const QStringList& newNames, const QStringList& existingNames, + Qt::CaseSensitivity cs = Qt::CaseSensitive); +}; + +#endif // QGSNEWNAMEDIALOG_H