Fixes: Allow directories to be entered into the class wizard file names

Task: 237390
Details: Add 'allowDirectories' property to the widgets involved.
This commit is contained in:
Friedemann Kleint
2008-12-05 10:39:08 +01:00
parent 4e76b54dec
commit a48ee6f7a8
8 changed files with 96 additions and 28 deletions

View File

@@ -33,26 +33,65 @@
#include "filenamevalidatinglineedit.h" #include "filenamevalidatinglineedit.h"
#include <QtCore/QRegExp>
#include <QtCore/QDebug>
namespace Core { namespace Core {
namespace Utils { namespace Utils {
FileNameValidatingLineEdit::FileNameValidatingLineEdit(QWidget *parent) :
BaseValidatingLineEdit(parent)
{
}
/* Validate a file base name, check for forbidden characters/strings. */
static const char *notAllowedChars = "/?:&\\*\"|#%<> ";
static const char *notAllowedSubStrings[] = {".."};
// Naming a file like a device name will break on Windows, even if it is // Naming a file like a device name will break on Windows, even if it is
// "com1.txt". Since we are cross-platform, we generally disallow such file // "com1.txt". Since we are cross-platform, we generally disallow such file
// names. // names.
static const char *notAllowedStrings[] = {"CON", "AUX", "PRN", "COM1", "COM2", "LPT1", "LPT2" }; static const QRegExp &windowsDeviceNoSubDirPattern()
{
static const QRegExp rc(QLatin1String("CON|AUX|PRN|COM1|COM2|LPT1|LPT2|NUL"),
Qt::CaseInsensitive);
Q_ASSERT(rc.isValid());
return rc;
}
bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *errorMessage /* = 0*/) static const QRegExp &windowsDeviceSubDirPattern()
{
static const QRegExp rc(QLatin1String(".*[/\\\\]CON|.*[/\\\\]AUX|.*[/\\\\]PRN|.*[/\\\\]COM1|.*[/\\\\]COM2|.*[/\\\\]LPT1|.*[/\\\\]LPT2|.*[/\\\\]NUL"),
Qt::CaseInsensitive);
Q_ASSERT(rc.isValid());
return rc;
}
// ----------- FileNameValidatingLineEdit
FileNameValidatingLineEdit::FileNameValidatingLineEdit(QWidget *parent) :
BaseValidatingLineEdit(parent),
m_allowDirectories(false),
m_unused(0)
{
}
bool FileNameValidatingLineEdit::allowDirectories() const
{
return m_allowDirectories;
}
void FileNameValidatingLineEdit::setAllowDirectories(bool v)
{
m_allowDirectories = v;
}
/* Validate a file base name, check for forbidden characters/strings. */
#ifdef Q_OS_WIN
# define SLASHES "/\\"
#else
# define SLASHES "/"
#endif
static const char *notAllowedCharsSubDir = "?:&*\"|#%<> ";
static const char *notAllowedCharsNoSubDir = "?:&*\"|#%<> "SLASHES;
static const char *notAllowedSubStrings[] = {".."};
bool FileNameValidatingLineEdit::validateFileName(const QString &name,
bool allowDirectories,
QString *errorMessage /* = 0*/)
{ {
if (name.isEmpty()) { if (name.isEmpty()) {
if (errorMessage) if (errorMessage)
@@ -60,6 +99,7 @@ bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *
return false; return false;
} }
// Characters // Characters
const char *notAllowedChars = allowDirectories ? notAllowedCharsSubDir : notAllowedCharsNoSubDir;
for (const char *c = notAllowedChars; *c; c++) for (const char *c = notAllowedChars; *c; c++)
if (name.contains(QLatin1Char(*c))) { if (name.contains(QLatin1Char(*c))) {
if (errorMessage) if (errorMessage)
@@ -76,22 +116,22 @@ bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *
return false; return false;
} }
} }
// Strings // Windows devices
const int notAllowedStringCount = sizeof(notAllowedStrings)/sizeof(const char *); bool matchesWinDevice = windowsDeviceNoSubDirPattern().exactMatch(name);
for (int s = 0; s < notAllowedStringCount; s++) { if (!matchesWinDevice && allowDirectories)
const QLatin1String notAllowedString(notAllowedStrings[s]); matchesWinDevice = windowsDeviceSubDirPattern().exactMatch(name);
if (name == notAllowedString) { if (matchesWinDevice) {
if (errorMessage) if (errorMessage)
*errorMessage = tr("The name must not be '%1'.").arg(QString(notAllowedString)); *errorMessage = tr("The name must not match that of a MS Windows device. (%1).").
arg(windowsDeviceNoSubDirPattern().pattern().replace(QLatin1Char('|'), QLatin1Char(',')));
return false; return false;
} }
}
return true; return true;
} }
bool FileNameValidatingLineEdit::validate(const QString &value, QString *errorMessage) const bool FileNameValidatingLineEdit::validate(const QString &value, QString *errorMessage) const
{ {
return validateFileName(value, errorMessage); return validateFileName(value, m_allowDirectories, errorMessage);
} }
} // namespace Utils } // namespace Utils

View File

@@ -43,14 +43,23 @@ class QWORKBENCH_UTILS_EXPORT FileNameValidatingLineEdit : public BaseValidating
{ {
Q_OBJECT Q_OBJECT
Q_DISABLE_COPY(FileNameValidatingLineEdit) Q_DISABLE_COPY(FileNameValidatingLineEdit)
Q_PROPERTY(bool allowDirectories READ allowDirectories WRITE setAllowDirectories)
public: public:
explicit FileNameValidatingLineEdit(QWidget *parent = 0); explicit FileNameValidatingLineEdit(QWidget *parent = 0);
static bool validateFileName(const QString &name, QString *errorMessage /* = 0*/); static bool validateFileName(const QString &name,
bool allowDirectories = false,
QString *errorMessage = 0);
bool allowDirectories() const;
void setAllowDirectories(bool v);
protected: protected:
virtual bool validate(const QString &value, QString *errorMessage) const; virtual bool validate(const QString &value, QString *errorMessage) const;
private:
bool m_allowDirectories;
void *m_unused;
}; };
} // namespace Utils } // namespace Utils

View File

@@ -123,7 +123,7 @@ void FileWizardPage::slotActivated()
bool FileWizardPage::validateBaseName(const QString &name, QString *errorMessage /* = 0*/) bool FileWizardPage::validateBaseName(const QString &name, QString *errorMessage /* = 0*/)
{ {
return FileNameValidatingLineEdit::validateFileName(name, errorMessage); return FileNameValidatingLineEdit::validateFileName(name, false, errorMessage);
} }
} // namespace Utils } // namespace Utils

View File

@@ -346,6 +346,21 @@ void NewClassWidget::setFormExtension(const QString &e)
m_d->m_formExtension = fixSuffix(e); m_d->m_formExtension = fixSuffix(e);
} }
bool NewClassWidget::allowDirectories() const
{
return m_d->m_ui.headerFileLineEdit->allowDirectories();
}
void NewClassWidget::setAllowDirectories(bool v)
{
// We keep all in sync
if (allowDirectories() != v) {
m_d->m_ui.sourceFileLineEdit->setAllowDirectories(v);
m_d->m_ui.headerFileLineEdit->setAllowDirectories(v);
m_d->m_ui.formFileLineEdit->setAllowDirectories(v);
}
}
void NewClassWidget::slotValidChanged() void NewClassWidget::slotValidChanged()
{ {
const bool newValid = isValid(); const bool newValid = isValid();

View File

@@ -73,6 +73,7 @@ class QWORKBENCH_UTILS_EXPORT NewClassWidget : public QWidget
Q_PROPERTY(QString formExtension READ formExtension WRITE setFormExtension DESIGNABLE true) Q_PROPERTY(QString formExtension READ formExtension WRITE setFormExtension DESIGNABLE true)
Q_PROPERTY(bool formInputCheckable READ formInputCheckable WRITE setFormInputCheckable DESIGNABLE true) Q_PROPERTY(bool formInputCheckable READ formInputCheckable WRITE setFormInputCheckable DESIGNABLE true)
Q_PROPERTY(bool formInputChecked READ formInputChecked WRITE setFormInputChecked DESIGNABLE true) Q_PROPERTY(bool formInputChecked READ formInputChecked WRITE setFormInputChecked DESIGNABLE true)
Q_PROPERTY(bool allowDirectories READ allowDirectories WRITE setAllowDirectories)
// Utility "USER" property for wizards containing file names. // Utility "USER" property for wizards containing file names.
Q_PROPERTY(QStringList files READ files DESIGNABLE false USER true) Q_PROPERTY(QStringList files READ files DESIGNABLE false USER true)
public: public:
@@ -97,7 +98,7 @@ public:
QString sourceExtension() const; QString sourceExtension() const;
QString headerExtension() const; QString headerExtension() const;
QString formExtension() const; QString formExtension() const;
bool allowDirectories() const;
bool isValid(QString *error = 0) const; bool isValid(QString *error = 0) const;
@@ -125,6 +126,7 @@ public slots:
void setSourceExtension(const QString &e); void setSourceExtension(const QString &e);
void setHeaderExtension(const QString &e); void setHeaderExtension(const QString &e);
void setFormExtension(const QString &e); void setFormExtension(const QString &e);
void setAllowDirectories(bool v);
/* Suggest a class name from the base class by stripping the leading 'Q' /* Suggest a class name from the base class by stripping the leading 'Q'
* character. This will happen automagically if the base class combo * character. This will happen automagically if the base class combo

View File

@@ -45,7 +45,7 @@ ProjectNameValidatingLineEdit::ProjectNameValidatingLineEdit(QWidget *parent)
bool ProjectNameValidatingLineEdit::validateProjectName(const QString &name, QString *errorMessage /* = 0*/) bool ProjectNameValidatingLineEdit::validateProjectName(const QString &name, QString *errorMessage /* = 0*/)
{ {
// Validation is file name + checking for dots // Validation is file name + checking for dots
if (!FileNameValidatingLineEdit::validateFileName(name, errorMessage)) if (!FileNameValidatingLineEdit::validateFileName(name, false, errorMessage))
return false; return false;
// We don't want dots in the directory name for some legacy Windows // We don't want dots in the directory name for some legacy Windows

View File

@@ -73,6 +73,7 @@ ClassNamePage::ClassNamePage(const QString &sourceSuffix,
m_newClassWidget->setBaseClassEditable(true); m_newClassWidget->setBaseClassEditable(true);
m_newClassWidget->setFormInputVisible(false); m_newClassWidget->setFormInputVisible(false);
m_newClassWidget->setNamespacesEnabled(true); m_newClassWidget->setNamespacesEnabled(true);
m_newClassWidget->setAllowDirectories(true);
connect(m_newClassWidget, SIGNAL(validChanged()), connect(m_newClassWidget, SIGNAL(validChanged()),
this, SLOT(slotValidChanged())); this, SLOT(slotValidChanged()));

View File

@@ -63,6 +63,7 @@ FormClassWizardPage::FormClassWizardPage(QWidget * parent) :
m_ui->newClassWidget->setBaseClassInputVisible(false); m_ui->newClassWidget->setBaseClassInputVisible(false);
m_ui->newClassWidget->setNamespacesEnabled(true); m_ui->newClassWidget->setNamespacesEnabled(true);
m_ui->newClassWidget->setAllowDirectories(true);
connect(m_ui->newClassWidget, SIGNAL(validChanged()), this, SLOT(slotValidChanged())); connect(m_ui->newClassWidget, SIGNAL(validChanged()), this, SLOT(slotValidChanged()));