Wizards: Support using #pragma once instead of include guards

Allow users to choose #pragma once instead of #ifndef include guards in
generated header files.

Fixes: QTCREATORBUG-12166
Change-Id: I3ba41c7570beb9c5958e174b5581fcc25855050f
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Filip Bucek <fbucek@atlas.cz>
This commit is contained in:
Filip Bucek
2019-01-03 10:56:36 +01:00
parent 2781c2a900
commit aaa8beab88
31 changed files with 235 additions and 52 deletions

View File

@@ -1,5 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef @COLLECTION_INCLUDE_GUARD@ #ifndef @COLLECTION_INCLUDE_GUARD@
#define @COLLECTION_INCLUDE_GUARD@ #define @COLLECTION_INCLUDE_GUARD@
@endif
#include <QtDesigner> #include <QtDesigner>
#include <qplugin.h> #include <qplugin.h>
@@ -19,4 +23,6 @@ private:
QList<QDesignerCustomWidgetInterface*> m_widgets; QList<QDesignerCustomWidgetInterface*> m_widgets;
}; };
#endif @if ! '%{Cpp:PragmaOnce}'
#endif // @COLLECTION_INCLUDE_GUARD@
@endif

View File

@@ -1,5 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef @SINGLE_INCLUDE_GUARD@ #ifndef @SINGLE_INCLUDE_GUARD@
#define @SINGLE_INCLUDE_GUARD@ #define @SINGLE_INCLUDE_GUARD@
@endif
#include <QDesignerCustomWidgetInterface> #include <QDesignerCustomWidgetInterface>
@@ -28,4 +32,6 @@ private:
bool m_initialized; bool m_initialized;
}; };
#endif @if ! '%{Cpp:PragmaOnce}'
#endif // @SINGLE_INCLUDE_GUARD@
@endif

View File

@@ -1,5 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef @WIDGET_INCLUDE_GUARD@ #ifndef @WIDGET_INCLUDE_GUARD@
#define @WIDGET_INCLUDE_GUARD@ #define @WIDGET_INCLUDE_GUARD@
@endif
#include <@WIDGET_BASE_CLASS@> #include <@WIDGET_BASE_CLASS@>
@@ -11,4 +15,6 @@ public:
@WIDGET_CLASS@(QWidget *parent = 0); @WIDGET_CLASS@(QWidget *parent = 0);
}; };
#endif @if ! '%{Cpp:PragmaOnce}'
#endif // @WIDGET_INCLUDE_GUARD@
@endif

View File

@@ -1,5 +1,10 @@
%{Cpp:LicenseTemplate}\ %{Cpp:LicenseTemplate}\
@if '%{Cpp:PragmaOnce}'
#pragma once #pragma once
@else
#ifndef %{GUARD}
#define %{GUARD}
@endif
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gmock/gmock-matchers.h> #include <gmock/gmock-matchers.h>
@@ -11,3 +16,7 @@ TEST(%{TestCaseName}, %{TestSetName})
EXPECT_EQ(1, 1); EXPECT_EQ(1, 1);
ASSERT_THAT(0, Eq(0)); ASSERT_THAT(0, Eq(0));
} }
@if ! '%{Cpp:PragmaOnce}'
#endif // %{GUARD}
@endif

View File

@@ -36,6 +36,10 @@
"key": "TestCaseFileWithHeaderSuffix", "key": "TestCaseFileWithHeaderSuffix",
"value": "%{JS: 'tst_%{TestCaseName}.'.toLowerCase() + Util.preferredSuffix('text/x-c++hdr') }" "value": "%{JS: 'tst_%{TestCaseName}.'.toLowerCase() + Util.preferredSuffix('text/x-c++hdr') }"
}, },
{
"key": "GUARD",
"value": "%{JS: '%{TestCaseFileWithHeaderSuffix}'.toUpperCase().replace('.', '_') }"
},
{ {
"key": "TestCaseFileWithCppSuffix", "key": "TestCaseFileWithCppSuffix",
"value": "%{JS: 'tst_%{TestCaseName}.'.toLowerCase() + Util.preferredSuffix('text/x-c++src') }" "value": "%{JS: 'tst_%{TestCaseName}.'.toLowerCase() + Util.preferredSuffix('text/x-c++src') }"

View File

@@ -1,6 +1,10 @@
%{Cpp:LicenseTemplate}\ %{Cpp:LicenseTemplate}\
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %{GUARD} #ifndef %{GUARD}
#define %{GUARD} #define %{GUARD}
@endif
%{JS: QtSupport.qtIncludes([ ( '%{IncludeQObject}' ) ? 'QtCore/%{IncludeQObject}' : '', %{JS: QtSupport.qtIncludes([ ( '%{IncludeQObject}' ) ? 'QtCore/%{IncludeQObject}' : '',
( '%{IncludeQWidget}' ) ? 'QtGui/%{IncludeQWidget}' : '', ( '%{IncludeQWidget}' ) ? 'QtGui/%{IncludeQWidget}' : '',
@@ -53,4 +57,6 @@ private:
@endif @endif
}; };
%{JS: Cpp.closeNamespaces('%{Class}')} %{JS: Cpp.closeNamespaces('%{Class}')}
#endif // %{GUARD}\ @if ! '%{Cpp:PragmaOnce}'
#endif // %{GUARD}
@endif

View File

@@ -1,6 +1,10 @@
%{Cpp:LicenseTemplate}\ %{Cpp:LicenseTemplate}\
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %{GUARD} #ifndef %{GUARD}
#define %{GUARD} #define %{GUARD}
@endif
%{JS: QtSupport.qtIncludes([ 'QtCore/%{Base}' ], [ 'QtCore/%{Base}' ])}\ %{JS: QtSupport.qtIncludes([ 'QtCore/%{Base}' ], [ 'QtCore/%{Base}' ])}\
%{JS: Cpp.openNamespaces('%{Class}')}\ %{JS: Cpp.openNamespaces('%{Class}')}\
@@ -62,4 +66,6 @@ public:
private: private:
}; };
%{JS: Cpp.closeNamespaces('%{Class}')} %{JS: Cpp.closeNamespaces('%{Class}')}
#endif // %{GUARD}\ @if ! '%{Cpp:PragmaOnce}'
#endif // %{GUARD}
@endif

View File

@@ -1,6 +1,10 @@
%{Cpp:LicenseTemplate}\ %{Cpp:LicenseTemplate}\
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %{GUARD} #ifndef %{GUARD}
#define %{GUARD} #define %{GUARD}
@endif
%{JS: QtSupport.qtIncludes([ 'QtCore/%{Base}' ], [ 'QtCore/%{Base}' ])}\ %{JS: QtSupport.qtIncludes([ 'QtCore/%{Base}' ], [ 'QtCore/%{Base}' ])}\
%{JS: Cpp.openNamespaces('%{Class}')}\ %{JS: Cpp.openNamespaces('%{Class}')}\
@@ -47,4 +51,6 @@ public:
private: private:
}; };
%{JS: Cpp.closeNamespaces('%{Class}')} %{JS: Cpp.closeNamespaces('%{Class}')}
#endif // %{GUARD}\ @if ! '%{Cpp:PragmaOnce}'
#endif // %{GUARD}
@endif

View File

@@ -1,6 +1,10 @@
%{Cpp:LicenseTemplate}\ %{Cpp:LicenseTemplate}\
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %{GUARD} #ifndef %{GUARD}
#define %{GUARD} #define %{GUARD}
@endif
%{JS: QtSupport.qtIncludes([ 'QtCore/%{Base}' ], [ 'QtCore/%{Base}' ])}\ %{JS: QtSupport.qtIncludes([ 'QtCore/%{Base}' ], [ 'QtCore/%{Base}' ])}\
%{JS: Cpp.openNamespaces('%{Class}')}\ %{JS: Cpp.openNamespaces('%{Class}')}\
@@ -50,4 +54,6 @@ public:
private: private:
}; };
%{JS: Cpp.closeNamespaces('%{Class}')} %{JS: Cpp.closeNamespaces('%{Class}')}
#endif // %{GUARD}\ @if ! '%{Cpp:PragmaOnce}'
#endif // %{GUARD}
@endif

View File

@@ -1,5 +1,9 @@
%{Cpp:LicenseTemplate}\ %{Cpp:LicenseTemplate}\
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %{JS: Cpp.headerGuard('%{FileName}')} #ifndef %{JS: Cpp.headerGuard('%{FileName}')}
#define %{JS: Cpp.headerGuard('%{FileName}')} #define %{JS: Cpp.headerGuard('%{FileName}')}
#endif // %{JS: Cpp.headerGuard('%{FileName}')} #endif // %{JS: Cpp.headerGuard('%{FileName}')}
@endif

View File

@@ -1,4 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once #pragma once
@else
#ifndef %ProjectName:h%_H
#define %ProjectName:h%_H
@endif
#include "%PluginName:l%_global.%CppHeaderSuffix%" #include "%PluginName:l%_global.%CppHeaderSuffix%"
@@ -26,3 +31,7 @@ private:
} // namespace Internal } // namespace Internal
} // namespace %PluginName% } // namespace %PluginName%
@if ! '%{Cpp:PragmaOnce}'
#endif // %ProjectName:h%_H
@endif

View File

@@ -1,4 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once #pragma once
@else
#ifndef %ProjectName:h%_GLOBAL_H
#define %ProjectName:h%_GLOBAL_H
@endif
#include <QtGlobal> #include <QtGlobal>
@@ -7,3 +12,7 @@
#else #else
# define %PluginName:u%SHARED_EXPORT Q_DECL_IMPORT # define %PluginName:u%SHARED_EXPORT Q_DECL_IMPORT
#endif #endif
@if ! '%{Cpp:PragmaOnce}'
#endif // %ProjectName:h%_GLOBAL_H
@endif

View File

@@ -1,4 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once #pragma once
@else
#ifndef %ProjectName:h%_CONSTANTS_H
#define %ProjectName:h%_CONSTANTS_H
@endif
namespace %PluginName% { namespace %PluginName% {
namespace Constants { namespace Constants {
@@ -8,3 +13,7 @@ const char MENU_ID[] = "%PluginName%.Menu";
} // namespace %PluginName% } // namespace %PluginName%
} // namespace Constants } // namespace Constants
@if ! '%{Cpp:PragmaOnce}'
#endif // %ProjectName:h%_CONSTANTS_H
@endif

View File

@@ -1,5 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %ObjectName:u%_H #ifndef %ObjectName:u%_H
#define %ObjectName:u%_H #define %ObjectName:u%_H
@endif
#include <QQuickItem> #include <QQuickItem>
@@ -13,4 +17,6 @@ public:
~%ObjectName%(); ~%ObjectName%();
}; };
@if ! '%{Cpp:PragmaOnce}'
#endif // %ObjectName:u%_H #endif // %ObjectName:u%_H
@endif

View File

@@ -1,4 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once #pragma once
@else
#ifndef %ProjectName:h%_PLUGIN_H
#define %ProjectName:h%_PLUGIN_H
@endif
#include <QQmlExtensionPlugin> #include <QQmlExtensionPlugin>
@@ -10,3 +15,7 @@ class %ProjectName:s%Plugin : public QQmlExtensionPlugin
public: public:
void registerTypes(const char *uri) override; void registerTypes(const char *uri) override;
}; };
@if ! '%{Cpp:PragmaOnce}'
#endif // %ProjectName:h%_PLUGIN_H
@endif

View File

@@ -27,6 +27,7 @@
#include "cppfilesettingspage.h" #include "cppfilesettingspage.h"
#include "cppmodelmanager.h" #include "cppmodelmanager.h"
#include "cpptools/cpptoolsplugin.h"
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/macroexpander.h> #include <utils/macroexpander.h>
@@ -68,5 +69,10 @@ QString AbstractEditorSupport::licenseTemplate(const QString &file, const QStrin
return Utils::TemplateEngine::processText(&expander, license, nullptr); return Utils::TemplateEngine::processText(&expander, license, nullptr);
} }
bool AbstractEditorSupport::usePragmaOnce()
{
return Internal::CppToolsPlugin::instance()->usePragmaOnce();
}
} // namespace CppTools } // namespace CppTools

View File

@@ -49,6 +49,7 @@ public:
unsigned revision() const { return m_revision; } unsigned revision() const { return m_revision; }
static QString licenseTemplate(const QString &file = QString(), const QString &className = QString()); static QString licenseTemplate(const QString &file = QString(), const QString &className = QString());
static bool usePragmaOnce();
private: private:
CppModelManager *m_modelmanager; CppModelManager *m_modelmanager;

View File

@@ -55,6 +55,7 @@ static const char headerSuffixKeyC[] = "HeaderSuffix";
static const char sourceSuffixKeyC[] = "SourceSuffix"; static const char sourceSuffixKeyC[] = "SourceSuffix";
static const char headerSearchPathsKeyC[] = "HeaderSearchPaths"; static const char headerSearchPathsKeyC[] = "HeaderSearchPaths";
static const char sourceSearchPathsKeyC[] = "SourceSearchPaths"; static const char sourceSearchPathsKeyC[] = "SourceSearchPaths";
static const char headerPragmaOnceC[] = "HeaderPragmaOnce";
static const char licenseTemplatePathKeyC[] = "LicenseTemplate"; static const char licenseTemplatePathKeyC[] = "LicenseTemplate";
const char *licenseTemplateTemplate = QT_TRANSLATE_NOOP("CppTools::Internal::CppFileSettingsWidget", const char *licenseTemplateTemplate = QT_TRANSLATE_NOOP("CppTools::Internal::CppFileSettingsWidget",
@@ -68,11 +69,6 @@ const char *licenseTemplateTemplate = QT_TRANSLATE_NOOP("CppTools::Internal::Cpp
namespace CppTools { namespace CppTools {
namespace Internal { namespace Internal {
CppFileSettings::CppFileSettings() :
lowerCaseFiles(false)
{
}
void CppFileSettings::toSettings(QSettings *s) const void CppFileSettings::toSettings(QSettings *s) const
{ {
s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP)); s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
@@ -83,6 +79,7 @@ void CppFileSettings::toSettings(QSettings *s) const
s->setValue(QLatin1String(headerSearchPathsKeyC), headerSearchPaths); s->setValue(QLatin1String(headerSearchPathsKeyC), headerSearchPaths);
s->setValue(QLatin1String(sourceSearchPathsKeyC), sourceSearchPaths); s->setValue(QLatin1String(sourceSearchPathsKeyC), sourceSearchPaths);
s->setValue(QLatin1String(Constants::LOWERCASE_CPPFILES_KEY), lowerCaseFiles); s->setValue(QLatin1String(Constants::LOWERCASE_CPPFILES_KEY), lowerCaseFiles);
s->setValue(QLatin1String(headerPragmaOnceC), headerPragmaOnce);
s->setValue(QLatin1String(licenseTemplatePathKeyC), licenseTemplatePath); s->setValue(QLatin1String(licenseTemplatePathKeyC), licenseTemplatePath);
s->endGroup(); s->endGroup();
} }
@@ -106,6 +103,7 @@ void CppFileSettings::fromSettings(QSettings *s)
.toStringList(); .toStringList();
const bool lowerCaseDefault = Constants::lowerCaseFilesDefault; const bool lowerCaseDefault = Constants::lowerCaseFilesDefault;
lowerCaseFiles = s->value(QLatin1String(Constants::LOWERCASE_CPPFILES_KEY), QVariant(lowerCaseDefault)).toBool(); lowerCaseFiles = s->value(QLatin1String(Constants::LOWERCASE_CPPFILES_KEY), QVariant(lowerCaseDefault)).toBool();
headerPragmaOnce = s->value(headerPragmaOnceC, headerPragmaOnce).toBool();
licenseTemplatePath = s->value(QLatin1String(licenseTemplatePathKeyC), QString()).toString(); licenseTemplatePath = s->value(QLatin1String(licenseTemplatePathKeyC), QString()).toString();
s->endGroup(); s->endGroup();
} }
@@ -127,6 +125,7 @@ bool CppFileSettings::applySuffixesToMimeDB()
bool CppFileSettings::equals(const CppFileSettings &rhs) const bool CppFileSettings::equals(const CppFileSettings &rhs) const
{ {
return lowerCaseFiles == rhs.lowerCaseFiles return lowerCaseFiles == rhs.lowerCaseFiles
&& headerPragmaOnce == rhs.headerPragmaOnce
&& headerPrefixes == rhs.headerPrefixes && headerPrefixes == rhs.headerPrefixes
&& sourcePrefixes == rhs.sourcePrefixes && sourcePrefixes == rhs.sourcePrefixes
&& headerSuffix == rhs.headerSuffix && headerSuffix == rhs.headerSuffix
@@ -303,6 +302,7 @@ CppFileSettings CppFileSettingsWidget::settings() const
{ {
CppFileSettings rc; CppFileSettings rc;
rc.lowerCaseFiles = m_ui->lowerCaseFileNamesCheckBox->isChecked(); rc.lowerCaseFiles = m_ui->lowerCaseFileNamesCheckBox->isChecked();
rc.headerPragmaOnce = m_ui->headerPragmaOnceCheckBox->isChecked();
rc.headerPrefixes = trimmedPaths(m_ui->headerPrefixesEdit->text()); rc.headerPrefixes = trimmedPaths(m_ui->headerPrefixesEdit->text());
rc.sourcePrefixes = trimmedPaths(m_ui->sourcePrefixesEdit->text()); rc.sourcePrefixes = trimmedPaths(m_ui->sourcePrefixesEdit->text());
rc.headerSuffix = m_ui->headerSuffixComboBox->currentText(); rc.headerSuffix = m_ui->headerSuffixComboBox->currentText();
@@ -323,6 +323,7 @@ void CppFileSettingsWidget::setSettings(const CppFileSettings &s)
{ {
const QChar comma = QLatin1Char(','); const QChar comma = QLatin1Char(',');
m_ui->lowerCaseFileNamesCheckBox->setChecked(s.lowerCaseFiles); m_ui->lowerCaseFileNamesCheckBox->setChecked(s.lowerCaseFiles);
m_ui->headerPragmaOnceCheckBox->setChecked(s.headerPragmaOnce);
m_ui->headerPrefixesEdit->setText(s.headerPrefixes.join(comma)); m_ui->headerPrefixesEdit->setText(s.headerPrefixes.join(comma));
m_ui->sourcePrefixesEdit->setText(s.sourcePrefixes.join(comma)); m_ui->sourcePrefixesEdit->setText(s.sourcePrefixes.join(comma));
setComboText(m_ui->headerSuffixComboBox, s.headerSuffix); setComboText(m_ui->headerSuffixComboBox, s.headerSuffix);

View File

@@ -42,16 +42,15 @@ namespace Ui { class CppFileSettingsPage; }
struct CppFileSettings struct CppFileSettings
{ {
CppFileSettings();
QStringList headerPrefixes; QStringList headerPrefixes;
QString headerSuffix; QString headerSuffix;
QStringList headerSearchPaths; QStringList headerSearchPaths;
QStringList sourcePrefixes; QStringList sourcePrefixes;
QString sourceSuffix; QString sourceSuffix;
QStringList sourceSearchPaths; QStringList sourceSearchPaths;
bool lowerCaseFiles;
QString licenseTemplatePath; QString licenseTemplatePath;
bool headerPragmaOnce = false;
bool lowerCaseFiles = false;
void toSettings(QSettings *) const; void toSettings(QSettings *) const;
void fromSettings(QSettings *); void fromSettings(QSettings *);

View File

@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>547</width> <width>547</width>
<height>363</height> <height>406</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
@@ -67,7 +67,7 @@ These paths are used in addition to current directory on Switch Header/Source.</
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="5" column="0">
<widget class="QLabel" name="headerPrefixesLabel"> <widget class="QLabel" name="headerPrefixesLabel">
<property name="text"> <property name="text">
<string>&amp;Prefixes:</string> <string>&amp;Prefixes:</string>
@@ -77,7 +77,7 @@ These paths are used in addition to current directory on Switch Header/Source.</
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="5" column="1">
<widget class="QLineEdit" name="headerPrefixesEdit"> <widget class="QLineEdit" name="headerPrefixesEdit">
<property name="toolTip"> <property name="toolTip">
<string>Comma-separated list of header prefixes. <string>Comma-separated list of header prefixes.
@@ -86,6 +86,26 @@ These prefixes are used in addition to current file name on Switch Header/Source
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="0">
<widget class="QLabel" name="headerPragmaOnceLabel">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Include guards</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="headerPragmaOnceCheckBox">
<property name="toolTip">
<string>Uses #pragma once instead of #ifndef include guards.</string>
</property>
<property name="text">
<string>Use '#pragma once' instead of '#ifndef' guards</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@@ -140,6 +140,11 @@ QString CppToolsPlugin::licenseTemplate()
return m_instance->m_fileSettings->licenseTemplate(); return m_instance->m_fileSettings->licenseTemplate();
} }
bool CppToolsPlugin::usePragmaOnce()
{
return m_instance->m_fileSettings->headerPragmaOnce;
}
const QStringList &CppToolsPlugin::headerSearchPaths() const QStringList &CppToolsPlugin::headerSearchPaths()
{ {
return m_instance->m_fileSettings->headerSearchPaths; return m_instance->m_fileSettings->headerSearchPaths;
@@ -204,6 +209,11 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
tr("The configured path to the license template"), tr("The configured path to the license template"),
[]() { return CppToolsPlugin::licenseTemplatePath().toString(); }); []() { return CppToolsPlugin::licenseTemplatePath().toString(); });
expander->registerVariable(
"Cpp:PragmaOnce",
tr("Insert #pragma once instead of #ifndef include guards into header file"),
[] { return usePragmaOnce() ? QString("true") : QString(); });
return true; return true;
} }

View File

@@ -65,6 +65,7 @@ public:
static void clearHeaderSourceCache(); static void clearHeaderSourceCache();
static Utils::FileName licenseTemplatePath(); static Utils::FileName licenseTemplatePath();
static QString licenseTemplate(); static QString licenseTemplate();
static bool usePragmaOnce();
bool initialize(const QStringList &arguments, QString *errorMessage) final; bool initialize(const QStringList &arguments, QString *errorMessage) final;
void extensionsInitialized() final; void extensionsInitialized() final;

View File

@@ -26,6 +26,7 @@
#include "formclasswizarddialog.h" #include "formclasswizarddialog.h"
#include "formclasswizardpage.h" #include "formclasswizardpage.h"
#include "formclasswizardparameters.h" #include "formclasswizardparameters.h"
#include <cpptools/abstracteditorsupport.h>
#include <designer/formtemplatewizardpage.h> #include <designer/formtemplatewizardpage.h>
#include <qtsupport/codegenerator.h> #include <qtsupport/codegenerator.h>
@@ -88,6 +89,7 @@ FormClassWizardParameters FormClassWizardDialog::parameters() const
m_classPage->getParameters(&rc); m_classPage->getParameters(&rc);
// Name the ui class in the Ui namespace after the class specified // Name the ui class in the Ui namespace after the class specified
rc.uiTemplate = QtSupport::CodeGenerator::changeUiClassName(m_rawFormTemplate, rc.className); rc.uiTemplate = QtSupport::CodeGenerator::changeUiClassName(m_rawFormTemplate, rc.className);
rc.usePragmaOnce = CppTools::AbstractEditorSupport::usePragmaOnce();
return rc; return rc;
} }

View File

@@ -43,6 +43,7 @@ public:
QString sourceFile; QString sourceFile;
QString headerFile; QString headerFile;
QString uiFile; QString uiFile;
bool usePragmaOnce = false;
}; };
} // namespace Designer } // namespace Designer

View File

@@ -104,8 +104,12 @@ bool QtDesignerFormClassCodeGenerator::generateCpp(const FormClassWizardParamete
// 1) Header file // 1) Header file
QTextStream headerStr(header); QTextStream headerStr(header);
headerStr << headerLicense << "#ifndef " << guard headerStr << headerLicense;
<< "\n#define " << guard << '\n' << '\n';
if (parameters.usePragmaOnce)
headerStr << "#pragma once\n\n";
else
headerStr << "#ifndef " << guard << "\n#define " << guard << "\n\n";
// Include 'ui_' // Include 'ui_'
if (generationParameters.embedding != QtSupport::CodeGenSettings::PointerAggregatedUiClass) { if (generationParameters.embedding != QtSupport::CodeGenSettings::PointerAggregatedUiClass) {
@@ -165,7 +169,9 @@ bool QtDesignerFormClassCodeGenerator::generateCpp(const FormClassWizardParamete
} }
headerStr << namespaceIndent << "};\n\n"; headerStr << namespaceIndent << "};\n\n";
Utils::writeClosingNameSpaces(namespaceList, QString(), headerStr); Utils::writeClosingNameSpaces(namespaceList, QString(), headerStr);
headerStr << "#endif // "<< guard << '\n';
if (!parameters.usePragmaOnce)
headerStr << "#endif // " << guard << '\n';
// 2) Source file // 2) Source file
QTextStream sourceStr(source); QTextStream sourceStr(source);

View File

@@ -939,7 +939,17 @@ QString CustomWizardContext::processFile(const FieldReplacementMap &fm, QString
replaceFields(fm, &in); replaceFields(fm, &in);
QString out; QString out;
// Expander needed to handle extra variable "Cpp:PragmaOnce"
QString errorMessage; QString errorMessage;
Utils::MacroExpander *expander = Utils::globalMacroExpander();
in = Utils::TemplateEngine::processText(expander, in, &errorMessage);
if (!errorMessage.isEmpty()) {
qWarning("Error processing custom widget file: %s\nFile:\n%s",
qPrintable(errorMessage), qPrintable(in));
return QString();
}
if (!Utils::TemplateEngine::preprocessText(in, &out, &errorMessage)) { if (!Utils::TemplateEngine::preprocessText(in, &out, &errorMessage)) {
qWarning("Error preprocessing custom widget file: %s\nFile:\n%s", qWarning("Error preprocessing custom widget file: %s\nFile:\n%s",
qPrintable(errorMessage), qPrintable(in)); qPrintable(errorMessage), qPrintable(in));

View File

@@ -30,6 +30,8 @@
#include <cpptools/abstracteditorsupport.h> #include <cpptools/abstracteditorsupport.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/macroexpander.h>
#include <utils/templateengine.h>
#include <QFileInfo> #include <QFileInfo>
#include <QDir> #include <QDir>
@@ -311,7 +313,20 @@ QString PluginGenerator::processTemplate(const QString &tmpl,
if (!reader.fetch(tmpl, errorMessage)) if (!reader.fetch(tmpl, errorMessage))
return QString(); return QString();
QString cont = QString::fromUtf8(reader.data()); QString cont = QString::fromUtf8(reader.data());
// Expander needed to handle extra variable "Cpp:PragmaOnce"
Utils::MacroExpander *expander = Utils::globalMacroExpander();
QString errMsg;
cont = Utils::TemplateEngine::processText(expander, cont, &errMsg);
if (!errMsg.isEmpty()) {
qWarning("Error processing custom plugin file: %s\nFile:\n%s",
qPrintable(errMsg), qPrintable(cont));
errorMessage = &errMsg;
return QString();
}
const QChar atChar = QLatin1Char('@'); const QChar atChar = QLatin1Char('@');
int offset = 0; int offset = 0;
for (;;) { for (;;) {

View File

@@ -105,6 +105,7 @@ static inline bool generateFormClass(const GuiAppParameters &params,
fp.className = params.className; fp.className = params.className;
fp.sourceFile = params.sourceFileName; fp.sourceFile = params.sourceFileName;
fp.headerFile = params.headerFileName; fp.headerFile = params.headerFileName;
fp.usePragmaOnce = CppTools::AbstractEditorSupport::usePragmaOnce();
QString headerContents; QString headerContents;
QString sourceContents; QString sourceContents;
// Invoke code generation service of Qt Designer plugin. // Invoke code generation service of Qt Designer plugin.
@@ -224,7 +225,6 @@ bool GuiAppWizard::parametrizeTemplate(const QString &templatePath, const QStrin
if (!reader.fetch(fileName, QIODevice::Text, errorMessage)) if (!reader.fetch(fileName, QIODevice::Text, errorMessage))
return false; return false;
QString contents = QString::fromUtf8(reader.data()); QString contents = QString::fromUtf8(reader.data());
contents.replace(QLatin1String("%QAPP_INCLUDE%"), QLatin1String("QApplication")); contents.replace(QLatin1String("%QAPP_INCLUDE%"), QLatin1String("QApplication"));
contents.replace(QLatin1String("%INCLUDE%"), params.headerFileName); contents.replace(QLatin1String("%INCLUDE%"), params.headerFileName);
contents.replace(QLatin1String("%CLASS%"), params.className); contents.replace(QLatin1String("%CLASS%"), params.className);
@@ -236,6 +236,11 @@ bool GuiAppWizard::parametrizeTemplate(const QString &templatePath, const QStrin
else else
contents.replace(QLatin1String("%SHOWMETHOD%"), QString::fromLatin1(mainSourceShowC)); contents.replace(QLatin1String("%SHOWMETHOD%"), QString::fromLatin1(mainSourceShowC));
// Replace include guards with pragma once
if (CppTools::AbstractEditorSupport::usePragmaOnce()) {
contents.replace(QLatin1String("#ifndef %PRE_DEF%\n#define %PRE_DEF%"), "#pragma once");
contents.replace(QLatin1String("#endif // %PRE_DEF%\n"), QString());
}
const QChar dot = QLatin1Char('.'); const QChar dot = QLatin1Char('.');

View File

@@ -31,25 +31,6 @@
#include <QTextStream> #include <QTextStream>
#include <QStringList> #include <QStringList>
// Contents of the header defining the shared library export.
#define GUARD_VARIABLE "<GUARD>"
#define EXPORT_MACRO_VARIABLE "<EXPORT_MACRO>"
#define LIBRARY_MACRO_VARIABLE "<LIBRARY_MACRO>"
static const char *globalHeaderContentsC =
"#ifndef " GUARD_VARIABLE "\n"
"#define " GUARD_VARIABLE "\n"
"\n"
"#include <QtCore/qglobal.h>\n"
"\n"
"#if defined(" LIBRARY_MACRO_VARIABLE ")\n"
"# define " EXPORT_MACRO_VARIABLE " Q_DECL_EXPORT\n"
"#else\n"
"# define " EXPORT_MACRO_VARIABLE " Q_DECL_IMPORT\n"
"#endif\n"
"\n"
"#endif // " GUARD_VARIABLE "\n";
namespace QmakeProjectManager { namespace QmakeProjectManager {
namespace Internal { namespace Internal {
@@ -60,6 +41,7 @@ void LibraryParameters::generateCode(QtProjectParameters:: Type t,
const QString &exportMacro, const QString &exportMacro,
const QString &pluginJsonFileName, const QString &pluginJsonFileName,
int indentation, int indentation,
bool usePragmaOnce,
QString *header, QString *header,
QString *source) const QString *source) const
{ {
@@ -76,8 +58,10 @@ void LibraryParameters::generateCode(QtProjectParameters:: Type t,
// 1) Header // 1) Header
const QString guard = Utils::headerGuard(headerFileName, namespaceList); const QString guard = Utils::headerGuard(headerFileName, namespaceList);
headerStr << "#ifndef " << guard if (usePragmaOnce)
<< "\n#define " << guard << '\n' << '\n'; headerStr << "#pragma once\n\n";
else
headerStr << "#ifndef " << guard << "\n#define " << guard << "\n\n";
if (!sharedHeader.isEmpty()) if (!sharedHeader.isEmpty())
Utils::writeIncludeFileDirective(sharedHeader, false, headerStr); Utils::writeIncludeFileDirective(sharedHeader, false, headerStr);
@@ -123,7 +107,9 @@ void LibraryParameters::generateCode(QtProjectParameters:: Type t,
headerStr << namespaceIndent << indent << unqualifiedClassName << "();\n"; headerStr << namespaceIndent << indent << unqualifiedClassName << "();\n";
headerStr << namespaceIndent << "};\n\n"; headerStr << namespaceIndent << "};\n\n";
Utils::writeClosingNameSpaces(namespaceList, indent, headerStr); Utils::writeClosingNameSpaces(namespaceList, indent, headerStr);
headerStr << "#endif // "<< guard << '\n'; if (!usePragmaOnce)
headerStr << "#endif // " << guard << '\n';
/// 2) Source /// 2) Source
QTextStream sourceStr(source); QTextStream sourceStr(source);
@@ -152,12 +138,28 @@ void LibraryParameters::generateCode(QtProjectParameters:: Type t,
QString LibraryParameters::generateSharedHeader(const QString &globalHeaderFileName, QString LibraryParameters::generateSharedHeader(const QString &globalHeaderFileName,
const QString &projectTarget, const QString &projectTarget,
const QString &exportMacro) const QString &exportMacro,
bool usePragmaOnce)
{ {
QString contents = QLatin1String(globalHeaderContentsC); QString contents;
contents.replace(QLatin1String(GUARD_VARIABLE), Utils::headerGuard(globalHeaderFileName)); if (usePragmaOnce) {
contents.replace(QLatin1String(EXPORT_MACRO_VARIABLE), exportMacro); contents += "#pragma once\n";
contents.replace(QLatin1String(LIBRARY_MACRO_VARIABLE), QtProjectParameters::libraryMacro(projectTarget)); } else {
contents += "#ifndef " + Utils::headerGuard(globalHeaderFileName) + "\n";
contents += "#define " + Utils::headerGuard(globalHeaderFileName) + "\n";
}
contents += "\n";
contents += "#include <QtCore/qglobal.h>\n";
contents += "\n";
contents += "#if defined(" + QtProjectParameters::libraryMacro(projectTarget) + ")\n";
contents += "# define " + exportMacro + " Q_DECL_EXPORT\n";
contents += "#else\n";
contents += "# define " + exportMacro + " Q_DECL_IMPORT\n";
contents += "#endif\n";
contents += "\n";
if (!usePragmaOnce)
contents += "#endif // " + Utils::headerGuard(globalHeaderFileName) + '\n';
return contents; return contents;
} }

View File

@@ -44,13 +44,15 @@ struct LibraryParameters {
const QString &exportMacro, const QString &exportMacro,
const QString &pluginJsonFileName, const QString &pluginJsonFileName,
int indentation, int indentation,
bool usePragmaOnce,
QString *header, QString *header,
QString *source) const; QString *source) const;
// Generate the code of the shared header containing the export macro // Generate the code of the shared header containing the export macro
static QString generateSharedHeader(const QString &globalHeaderFileName, static QString generateSharedHeader(const QString &globalHeaderFileName,
const QString &projectTarget, const QString &projectTarget,
const QString &exportMacro); const QString &exportMacro,
bool usePragmaOnce);
QString className; QString className;
QString baseClassName; QString baseClassName;

View File

@@ -80,6 +80,7 @@ Core::GeneratedFiles LibraryWizard::generateFiles(const QWizard *w,
const QtProjectParameters projectParams = dialog->parameters(); const QtProjectParameters projectParams = dialog->parameters();
const QString projectPath = projectParams.projectPath(); const QString projectPath = projectParams.projectPath();
const LibraryParameters params = dialog->libraryParameters(); const LibraryParameters params = dialog->libraryParameters();
const bool usePragmaOnce = CppTools::AbstractEditorSupport::usePragmaOnce();
const QString sharedLibExportMacro = QtProjectParameters::exportMacro(projectParams.fileName); const QString sharedLibExportMacro = QtProjectParameters::exportMacro(projectParams.fileName);
@@ -107,7 +108,7 @@ Core::GeneratedFiles LibraryWizard::generateFiles(const QWizard *w,
Core::GeneratedFile globalHeader(globalHeaderName); Core::GeneratedFile globalHeader(globalHeaderName);
globalHeaderFileName = Utils::FileName::fromString(globalHeader.path()).fileName(); globalHeaderFileName = Utils::FileName::fromString(globalHeader.path()).fileName();
globalHeader.setContents(CppTools::AbstractEditorSupport::licenseTemplate(globalHeaderFileName) globalHeader.setContents(CppTools::AbstractEditorSupport::licenseTemplate(globalHeaderFileName)
+ LibraryParameters::generateSharedHeader(globalHeaderFileName, projectParams.fileName, sharedLibExportMacro)); + LibraryParameters::generateSharedHeader(globalHeaderFileName, projectParams.fileName, sharedLibExportMacro, usePragmaOnce));
rc.push_back(globalHeader); rc.push_back(globalHeader);
} }
@@ -115,7 +116,7 @@ Core::GeneratedFiles LibraryWizard::generateFiles(const QWizard *w,
QString headerContents, sourceContents; QString headerContents, sourceContents;
params.generateCode(projectParams.type, projectParams.fileName, headerFileName, params.generateCode(projectParams.type, projectParams.fileName, headerFileName,
globalHeaderFileName, sharedLibExportMacro, pluginJsonFileName, globalHeaderFileName, sharedLibExportMacro, pluginJsonFileName,
/* indentation*/ 4, &headerContents, &sourceContents); /* indentation*/ 4, usePragmaOnce, &headerContents, &sourceContents);
source.setContents(CppTools::AbstractEditorSupport::licenseTemplate(sourceFileName, params.className) source.setContents(CppTools::AbstractEditorSupport::licenseTemplate(sourceFileName, params.className)
+ sourceContents); + sourceContents);