diff --git a/doc/qtcreator.qdoc b/doc/qtcreator.qdoc index a1f7ab3ed6f5acd617dd177f1ca21ff3923f4e41..4521b7e2fa4317c8eec094fc53e23be12ebfcc7b 100644 --- a/doc/qtcreator.qdoc +++ b/doc/qtcreator.qdoc @@ -814,21 +814,26 @@ a pointer to some private data structure, you will see a list of children, signals and slots. - Similarily, instead of showing a bunch of pointers and ints, - a QHash or QMap will display its contents in an orderly fashion, - a QFileInfo will expose e.g. access data, and the otherwise - "opaque" QVariant gives access to the "real" contents. - - The \gui{Locals and Watchers View} can be used to change the - contents of variables of simple data types like int or float - while the program is stopped. To do so, click into the 'Value' - column, modify the value there, and hit \key{Return}. + Similarly, instead of displaying many pointers and integers, Qt Creator's + debugger will display the contents of a QHash or QMap in an orderly manner. + Also, the debugger will display access data for QFileInfo and provide + access to the "real" contents of QVariant. + + The \gui{Locals and Watchers} view can be used to change the contents of + variables of simple data types such as \c int or \c float when the program + is stopped. To do so, click on the \gui Value column, modify the value + with the inplace editor, and hit \key Enter (or \key Return). - \section2 Modules - The \gui{Modules View} is hidden by default and only useful in + By default, the \gui Modules view is hidden as it is only useful with the + experimental delayed debug information loading feature. You can turn this + feature on by selecting \gui{Fast Debugger Start} + + + + The \gui Modules view is hidden by default and only useful in connection with the experimental feature of delayed debug information loading. This feature is accessible by selecting \gui{Debug} and \gui{Fast Debugger Start}. When using the @@ -849,29 +854,28 @@ commands + \section1 A Walkthrough for the Debugger Frontend - \section1 A short walk through the debugger frontend - - In our \l{Writing a Simple Program with Qt Creator}{TextFinder} - example, we read a text file into a QString and then display it with a - QTextEdit. Suppose, you would like to look at this QString, \c{line}, - and see what data it actually stores. Follow the steps described below - to place a break point and view the QString object's data. + In our \l{Writing a Simple Program with Qt Creator}{TextFinder} example, we + read a text file into a QString and then display it with a QTextEdit. + Suppose, you would like to look at this QString, \c{line}, and see what + data it actually stores. Follow the steps described below to place a + breakpoint and view the QString object's data. \table \row - \i \inlineimage qtcreator-setting-breakpoint1.png + \i \inlineimage qtcreator-setting-breakpoint1.png \i \bold{Setting a Breakpoint} First, we set a breakpoint on the line where we invoke - \l{QTextEdit::}{setPlainText()} by clicking between the line number and - the window border. Then, select \gui{Start Debugging} from the - \gui{Debug} menu or press \key{F5}. + \l{QTextEdit::}{setPlainText()} by clicking between the line number and the + window border. Then, select \gui{Start Debugging} from the \gui{Debug} menu + or press \key{F5}. \endtable Breakpoints are visible in the \gui{Breakpoints} view, shown below, in - \gui{Debug} mode. If you wish to remove a breakpoint, simply right - click on it and select \gui{Delete breakpoint} from the context menu. + \gui{Debug} mode. If you wish to remove a breakpoint, simply right-click on + it and select \gui{Delete breakpoint} from the context menu. \image qtcreator-setting-breakpoint2.png @@ -880,10 +884,10 @@ \image qtcreator-watcher.png - Suppose we modify our \c{on_findButton_clicked()} function to move back - to the start of the document and continue searching once the cursor - hits the end of the document. Adding this functionality can be done - with the code snippet below: + Suppose we modify our \c{on_findButton_clicked()} function to move back to + the start of the document and continue searching once the cursor hits the + end of the document. Adding this functionality can be done with the code + snippet below: \code void TextFinder::on_findButton_clicked() @@ -915,9 +919,9 @@ } \endcode - However, if you compile and run this code, the application will not - work correctly due to a logic error. To locate this logic error, you - can step through the code using the following buttons: + However, if you compile and run this code, the application will not work + correctly due to a logic error. To locate this logic error, you can step + through the code using the following buttons: \image qtcreator-debugging-buttons.png */ @@ -931,20 +935,20 @@ \title Tips and Tricks - \bold{Quick mode switch} + \bold{Quickly Switching between Modes} You can quickly switch between modes by pressing \key{Ctrl+1}, - \key{Ctrl+2}, etc. + \key{Ctrl+2}, and so on. - \bold{Other keyboard shortcuts} + \bold{Keyboard Shortcuts} - There are a lot of other \l{keyboard-shortcuts}{keyboard shortcuts}. + Qt Creator provides a lot of useful keyboard shortcuts. A complete list can + be found \l{Keyboard Shortcuts}{here}. - \bold{Command line} + \bold{Running Qt Creator from the Command Line} - You can start Qt Creator from a command prompt with an already - existing session or \c{.pro} file by giving the name as argument on the - command line. + You can start Qt Creator from a command prompt with an existing session or + \c{.pro} file by giving the name as argument on the command line. \bold{Sidebar} diff --git a/src/libs/utils/filenamevalidatinglineedit.cpp b/src/libs/utils/filenamevalidatinglineedit.cpp index 57a0ed7a5f91577946807db122112559ffe75a0c..5b308f5ce4728eef5823a2c82be842180438e5e3 100644 --- a/src/libs/utils/filenamevalidatinglineedit.cpp +++ b/src/libs/utils/filenamevalidatinglineedit.cpp @@ -33,26 +33,65 @@ #include "filenamevalidatinglineedit.h" +#include <QtCore/QRegExp> +#include <QtCore/QDebug> + namespace Core { namespace Utils { +// 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 +// names. +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; +} + +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) + 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. */ -static const char *notAllowedChars = "/?:&\\*\"|#%<> "; -static const char *notAllowedSubStrings[] = {".."}; +#ifdef Q_OS_WIN +# define SLASHES "/\\" +#else +# define SLASHES "/" +#endif -// 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 -// names. -static const char *notAllowedStrings[] = {"CON", "AUX", "PRN", "COM1", "COM2", "LPT1", "LPT2" }; +static const char *notAllowedCharsSubDir = "?:&*\"|#%<> "; +static const char *notAllowedCharsNoSubDir = "?:&*\"|#%<> "SLASHES; -bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *errorMessage /* = 0*/) +static const char *notAllowedSubStrings[] = {".."}; + +bool FileNameValidatingLineEdit::validateFileName(const QString &name, + bool allowDirectories, + QString *errorMessage /* = 0*/) { if (name.isEmpty()) { if (errorMessage) @@ -60,6 +99,7 @@ bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString * return false; } // Characters + const char *notAllowedChars = allowDirectories ? notAllowedCharsSubDir : notAllowedCharsNoSubDir; for (const char *c = notAllowedChars; *c; c++) if (name.contains(QLatin1Char(*c))) { if (errorMessage) @@ -76,22 +116,22 @@ bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString * return false; } } - // Strings - const int notAllowedStringCount = sizeof(notAllowedStrings)/sizeof(const char *); - for (int s = 0; s < notAllowedStringCount; s++) { - const QLatin1String notAllowedString(notAllowedStrings[s]); - if (name == notAllowedString) { - if (errorMessage) - *errorMessage = tr("The name must not be '%1'.").arg(QString(notAllowedString)); - return false; - } + // Windows devices + bool matchesWinDevice = windowsDeviceNoSubDirPattern().exactMatch(name); + if (!matchesWinDevice && allowDirectories) + matchesWinDevice = windowsDeviceSubDirPattern().exactMatch(name); + if (matchesWinDevice) { + if (errorMessage) + *errorMessage = tr("The name must not match that of a MS Windows device. (%1)."). + arg(windowsDeviceNoSubDirPattern().pattern().replace(QLatin1Char('|'), QLatin1Char(','))); + return false; } return true; } bool FileNameValidatingLineEdit::validate(const QString &value, QString *errorMessage) const { - return validateFileName(value, errorMessage); + return validateFileName(value, m_allowDirectories, errorMessage); } } // namespace Utils diff --git a/src/libs/utils/filenamevalidatinglineedit.h b/src/libs/utils/filenamevalidatinglineedit.h index 5476e3cd5e936ec5c4084fe911526153dc092673..042a48fc5f19f5d1bd5a6df02aed5c29a3b0f2f2 100644 --- a/src/libs/utils/filenamevalidatinglineedit.h +++ b/src/libs/utils/filenamevalidatinglineedit.h @@ -43,14 +43,23 @@ class QWORKBENCH_UTILS_EXPORT FileNameValidatingLineEdit : public BaseValidating { Q_OBJECT Q_DISABLE_COPY(FileNameValidatingLineEdit) - + Q_PROPERTY(bool allowDirectories READ allowDirectories WRITE setAllowDirectories) public: 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: virtual bool validate(const QString &value, QString *errorMessage) const; + +private: + bool m_allowDirectories; + void *m_unused; }; } // namespace Utils diff --git a/src/libs/utils/filewizardpage.cpp b/src/libs/utils/filewizardpage.cpp index 8a12e4c0f3c98a016aa1deedd3093243840b61af..3e85b34d44b729142ff233b5f16f2d37cdc06e23 100644 --- a/src/libs/utils/filewizardpage.cpp +++ b/src/libs/utils/filewizardpage.cpp @@ -123,7 +123,7 @@ void FileWizardPage::slotActivated() bool FileWizardPage::validateBaseName(const QString &name, QString *errorMessage /* = 0*/) { - return FileNameValidatingLineEdit::validateFileName(name, errorMessage); + return FileNameValidatingLineEdit::validateFileName(name, false, errorMessage); } } // namespace Utils diff --git a/src/libs/utils/newclasswidget.cpp b/src/libs/utils/newclasswidget.cpp index df7d81e7b39c9b854fc53cef019de68935d897f0..b34ee40d4fe9469745edd98531560335b682f5ff 100644 --- a/src/libs/utils/newclasswidget.cpp +++ b/src/libs/utils/newclasswidget.cpp @@ -346,6 +346,21 @@ void NewClassWidget::setFormExtension(const QString &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() { const bool newValid = isValid(); diff --git a/src/libs/utils/newclasswidget.h b/src/libs/utils/newclasswidget.h index 04c2aaf58a4f4143ba521955e85e474f87fc943e..40c850d28e94b55809cc91a3d74961a0b8d24bed 100644 --- a/src/libs/utils/newclasswidget.h +++ b/src/libs/utils/newclasswidget.h @@ -73,6 +73,7 @@ class QWORKBENCH_UTILS_EXPORT NewClassWidget : public QWidget Q_PROPERTY(QString formExtension READ formExtension WRITE setFormExtension 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 allowDirectories READ allowDirectories WRITE setAllowDirectories) // Utility "USER" property for wizards containing file names. Q_PROPERTY(QStringList files READ files DESIGNABLE false USER true) public: @@ -97,7 +98,7 @@ public: QString sourceExtension() const; QString headerExtension() const; QString formExtension() const; - + bool allowDirectories() const; bool isValid(QString *error = 0) const; @@ -125,6 +126,7 @@ public slots: void setSourceExtension(const QString &e); void setHeaderExtension(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' * character. This will happen automagically if the base class combo diff --git a/src/libs/utils/projectnamevalidatinglineedit.cpp b/src/libs/utils/projectnamevalidatinglineedit.cpp index df77af8e832a21e41746e99c6199bcaa5a9ca1fb..4160bc18792f8a24714fc35fe431415117f0e90c 100644 --- a/src/libs/utils/projectnamevalidatinglineedit.cpp +++ b/src/libs/utils/projectnamevalidatinglineedit.cpp @@ -45,7 +45,7 @@ ProjectNameValidatingLineEdit::ProjectNameValidatingLineEdit(QWidget *parent) bool ProjectNameValidatingLineEdit::validateProjectName(const QString &name, QString *errorMessage /* = 0*/) { // Validation is file name + checking for dots - if (!FileNameValidatingLineEdit::validateFileName(name, errorMessage)) + if (!FileNameValidatingLineEdit::validateFileName(name, false, errorMessage)) return false; // We don't want dots in the directory name for some legacy Windows diff --git a/src/plugins/cppeditor/cppclasswizard.cpp b/src/plugins/cppeditor/cppclasswizard.cpp index 6730f5b9ed9c388184b1d6040bb55cfe433b0bda..652eec535f18aa4221e7bb1055e780a14a569979 100644 --- a/src/plugins/cppeditor/cppclasswizard.cpp +++ b/src/plugins/cppeditor/cppclasswizard.cpp @@ -73,6 +73,7 @@ ClassNamePage::ClassNamePage(const QString &sourceSuffix, m_newClassWidget->setBaseClassEditable(true); m_newClassWidget->setFormInputVisible(false); m_newClassWidget->setNamespacesEnabled(true); + m_newClassWidget->setAllowDirectories(true); connect(m_newClassWidget, SIGNAL(validChanged()), this, SLOT(slotValidChanged())); diff --git a/src/plugins/cpptools/searchsymbols.cpp b/src/plugins/cpptools/searchsymbols.cpp index c0d29aae18a7fabde085f4a5e129abd1e4fb7539..4b1e48abdf7e55a3d3326d0ed0ca5b59686aadee 100644 --- a/src/plugins/cpptools/searchsymbols.cpp +++ b/src/plugins/cpptools/searchsymbols.cpp @@ -40,13 +40,13 @@ using namespace CPlusPlus; using namespace CppTools::Internal; SearchSymbols::SearchSymbols(): - symbolsToSearchFor(ClassesMethodsFunctionsAndEnums) + symbolsToSearchFor(Classes | Functions | Enums) { } -void SearchSymbols::setSymbolsToSearchFor(SymbolType type) +void SearchSymbols::setSymbolsToSearchFor(SymbolTypes types) { - symbolsToSearchFor = type; + symbolsToSearchFor = types; } QList<ModelItemInfo> SearchSymbols::operator()(Document::Ptr doc, const QString &scope) @@ -69,7 +69,7 @@ QString SearchSymbols::switchScope(const QString &scope) bool SearchSymbols::visit(Enum *symbol) { - if (symbolsToSearchFor != ClassesMethodsFunctionsAndEnums) + if (!(symbolsToSearchFor & Enums)) return false; QString name = symbolName(symbol); @@ -89,7 +89,7 @@ bool SearchSymbols::visit(Enum *symbol) bool SearchSymbols::visit(Function *symbol) { - if (symbolsToSearchFor != ClassesMethodsFunctionsAndEnums) + if (!(symbolsToSearchFor & Functions)) return false; QString name = symbolName(symbol); @@ -131,6 +131,9 @@ bool SearchSymbols::visit(Declaration *symbol) bool SearchSymbols::visit(Class *symbol) { + if (!(symbolsToSearchFor & Classes)) + return false; + QString name = symbolName(symbol); QString previousScope = switchScope(name); QIcon icon = icons.iconForSymbol(symbol); diff --git a/src/plugins/cpptools/searchsymbols.h b/src/plugins/cpptools/searchsymbols.h index d9b678e026fb6778ada898736a45ea3936e571e2..948f9d78e84ea72898f3e1b87f8baf6f26edac88 100644 --- a/src/plugins/cpptools/searchsymbols.h +++ b/src/plugins/cpptools/searchsymbols.h @@ -80,15 +80,16 @@ class SearchSymbols: public std::unary_function<CPlusPlus::Document::Ptr, QList< protected CPlusPlus::SymbolVisitor { public: - // TODO: Probably should use QFlags enum SymbolType { - Classes, - ClassesMethodsFunctionsAndEnums + Classes = 0x1, + Functions = 0x2, + Enums = 0x4 }; + Q_DECLARE_FLAGS(SymbolTypes, SymbolType) SearchSymbols(); - void setSymbolsToSearchFor(SymbolType type); + void setSymbolsToSearchFor(SymbolTypes types); QList<ModelItemInfo> operator()(CPlusPlus::Document::Ptr doc) { return operator()(doc, QString()); } @@ -117,9 +118,11 @@ private: CPlusPlus::Overview overview; CPlusPlus::Icons icons; QList<ModelItemInfo> items; - SymbolType symbolsToSearchFor; + SymbolTypes symbolsToSearchFor; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(SearchSymbols::SymbolTypes) + } // namespace Internal } // namespace CppTools diff --git a/src/plugins/designer/cpp/formclasswizardpage.cpp b/src/plugins/designer/cpp/formclasswizardpage.cpp index d076753374b666ef632c4a97a1f2394857993bae..eac7271b404dd48488d17e9ac56bc4d6b2541703 100644 --- a/src/plugins/designer/cpp/formclasswizardpage.cpp +++ b/src/plugins/designer/cpp/formclasswizardpage.cpp @@ -63,6 +63,7 @@ FormClassWizardPage::FormClassWizardPage(QWidget * parent) : m_ui->newClassWidget->setBaseClassInputVisible(false); m_ui->newClassWidget->setNamespacesEnabled(true); + m_ui->newClassWidget->setAllowDirectories(true); connect(m_ui->newClassWidget, SIGNAL(validChanged()), this, SLOT(slotValidChanged()));