Commit e426d08e authored by Oswald Buddenhagen's avatar Oswald Buddenhagen

Merge remote-tracking branch 'origin/4.0'

Conflicts:
	qtcreator.pri
	qtcreator.qbs
	src/plugins/debugger/debuggerruncontrol.cpp

Change-Id: I81b43480a1369e3d7be60ae26e812dda6b962b0b
parents 26e51ff6 ea1f5d2b
doc/images/qtcreator-kits.png

17.6 KB | W: | H:

doc/images/qtcreator-kits.png

22.3 KB | W: | H:

doc/images/qtcreator-kits.png
doc/images/qtcreator-kits.png
doc/images/qtcreator-kits.png
doc/images/qtcreator-kits.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -109,8 +109,6 @@
items with names consisting of plain characters, numbers,
underscores, and hyphens.
\li Creating new CMake projects with \QC is not supported.
\li If error messages displayed in the \uicontrol {Compile Output} pane contain
paths where slashes are missing (for example, C:QtSDK),
check your PATH variable. For more information, see
......
......@@ -43,67 +43,104 @@
native build configurations and workspaces that you can use in the compiler
environment of your choice.
Since \QC 1.1, CMake configuration files are supported. Since \QC 1.3, the
Microsoft tool chain is supported if the CMake version is at least 2.8.
\QC automatically detects the CMake executable specified in the \c PATH.
You can add paths to other CMake executables and use them in different
build and run \l{glossary-buildandrun-kit}{kits}.
\section1 Adding CMake Tools
To specify paths to CMake executables, select \uicontrol Tools >
\uicontrol Options > \uicontrol {Build & Run} > \uicontrol CMake >
\uicontrol Add.
\QC supports CMake version 2.9, or later.
\image qtcreator-cmakeexecutable.png
To specify paths to CMake executables and to add them to kits:
\section1 Opening CMake Projects
\list 1
\note Before you open a CMake project, you must modify the \c {PATH}
environment variable to include the bin folders of \c mingw and Qt.
\li Select \uicontrol Tools > \uicontrol Options >
\uicontrol {Build & Run} > \uicontrol CMake > \uicontrol Add.
For instance, if Qt 5.5 is installed in \c {C:\Qt}, you would use the
following command to set the environment variables in the command line
prompt:
\code
set PATH=C:\Qt\Tools\mingw<VERSION>\bin;C:\Qt\5.5\<TARGET>\bin;
\endcode
Then start \QC by typing:
\code
C:\Qt\Tools\QtCreator\qtcreator.exe
\endcode
\image qtcreator-cmakeexecutable.png
\li In the \uicontrol Name field, specify a name for the tool.
\li In the \uicontrol Path field, specify the path to the CMake
executable.
\li Select \uicontrol Apply to save your changes.
\li Select the \uicontrol Kits tab to add the CMake tool to a build and
run kit. The kit also specifies the CMake Generator that is used for
producing project files for \QC and the configuration variables that
are used:
To open a CMake project:
\image qtcreator-kits.png
For more information, see \l {Adding Kits}.
\endlist
\section1 Creating CMake Projects
To create a CMake project:
\list 1
\li Select \uicontrol File > \uicontrol {Open File or Project}.
\li Select \uicontrol File > \uicontrol {New File or Project} >
\uicontrol {Non-Qt Project} > \uicontrol {Plain C Application} or
\uicontrol {Plain C++ Application} > \uicontrol Choose.
\li Select the \c {CMakeLists.txt} file from your CMake project.
\li In the \uicontrol Name field, enter a name for the project.
\li In the \uicontrol {Create in} field, enter the path for the project
files, and then select \uicontrol Next (or \uicontrol Continue on
OS X).
\li In the \uicontrol {Build system} field, select \uicontrol CMake, and
then select \uicontrol Next.
\li Select CMake kits for the platforms that you want to build the
application for, and then select \uicontrol Next.
\li Review the project settings, and click \uicontrol{Finish} (or
\uicontrol Done on OS X).
\li Select \uicontrol {Run CMake} to generate a .cbp file.
\image qtcreator-cmake-run-cmake.png
Some projects require command line arguments to the initial CMake
call. CMake will remember the arguments during subsequent calls.
\endlist
A wizard guides you through the rest of the process.
\QC generates a \c {main.cpp} and \c {CMakeLists.txt} file that you can
modify in the \uicontrol Edit mode.
\note If the CMake project does not have an in-place build, \QC
lets you specify the directory in which the project is built
(\l{glossary-shadow-build}{shadow build}).
\section1 Opening CMake Projects
\image qtcreator-cmake-import-wizard1.png
To open an existing CMake project:
The screenshot below shows how you can specify command line arguments to
CMake for your project.
\list 1
\image qtcreator-cmake-import-wizard2.png
\li Select \uicontrol File > \uicontrol {Open File or Project}.
\li Select the \c {CMakeLists.txt} file from your CMake project.
Normally, there is no need to pass any command line arguments for projects
that are already built, as CMake caches that information.
\li Select a kit that is configured to use CMake for building the
project.
\li In \uicontrol Projects, right-click the project name to open the
context menu, and then select \uicontrol {Run CMake} to have the
project contents listed in the view.
\endlist
\section1 Editing CMake Configuration Files
You can open CMake configuration files in \QC for editing. The following
features are supported:
To open a CMakeLists.txt file for editing, right-click it in the
\uicontrol Projects view and select \uicontrol {Open with} >
\uicontrol {CMake Editor}.
The following features are supported:
\list
......@@ -119,31 +156,55 @@
\section1 Building CMake Projects
\QC builds CMake projects by running \c make, \c mingw32-make,
\c nmake, or \c ninja depending on your platform. The build errors and
warnings are parsed and displayed in the \uicontrol Issues output pane.
To build CMake projects, select \uicontrol {Build Project} or press
\key Ctrl+B (or \key Cmd+B on OS X).
\QC builds CMake projects by running \c make, \c mingw32-make, \c nmake, or
\c ninja depending on the selected kit.
By default, \QC uses the \uicontrol All \l{glossary-build-config}
By default, \QC uses the \uicontrol Default \l{glossary-build-config}
{build configuration}. You can select another build configuration in
\uicontrol Projects > \uicontrol {Edit build configuration}. In addition to
\uicontrol Projects > \uicontrol {Build Settings} >
\uicontrol {Edit build configuration}. In addition to
debug and release build configurations, you can create a release build that
contains debug information or a release build with the smallest possible
size.
\image qtcreator-cmake-build-settings.png
You can change the build directory after the initial import.
In the \uicontrol {Build directory} field, you can specify the directory in
which the project is built (\l{glossary-shadow-build}{shadow build}).
To view all settings, select the \uicontrol Advanced check box.
To modify the value of a build setting, select it, and then select
\uicontrol Edit. The new value is displayed in italics until you save the
changes by selecting \uicontrol {Apply Configuration Changes}. Any
configuration change might trigger a follow-up configuration change, so keep
saving until no more values are displayed in italics.
The build and run kit that you select determines which CMake tool is used
for building. For more information, see \l {Adding Kits}.
You can add arguments and targets for the build command in
\uicontrol {Build Steps}.
\image qtcreator-cmake-build-steps.png
You can add arguments and targets for the clean command in
\uicontrol {Clean Steps}.
\image qtcreator-cmake-clean-steps.png
The build errors and warnings are parsed and displayed in the
\uicontrol Issues output pane.
\section1 Running CMake Projects
\QC automatically adds \uicontrol {Run Configurations} for all targets
specified in the CMake project file.
For more information about known issues for the current version, see
\l{Known Issues}.
\image qtcreator-cmake-run-settings.png
To run CMake projects, select \uicontrol Run or press \key Ctrl+R (or
\key Cmd+R on OS X).
\section1 Deploying CMake Projects to Embedded Linux Devices
......
......@@ -126,6 +126,16 @@
CMake tools to the list. For more information, see
\l{Adding CMake Tools}.
\li In the \uicontrol {CMake Generator} field, select the CMake
Generator to use for producing project files. Only the generators
with names beginning with the string \uicontrol CodeBlocks produce
all the necessary data for the \QC code model. \QC displays a
warning if you select a generator that is not supported.
\li In the \uicontrol {CMake configuration} field, select
\uicontrol Change to edit the variables of the CMake configuration
for the kit.
\endlist
*/
......@@ -426,7 +426,7 @@ def qdump__QFile(d, value):
if d.isWindowsTarget():
offset = 164 if is32bit else 248
else:
offset = 156 if is32bit else 248
offset = 164 if is32bit else 248
elif qtVersion >= 0x050400:
if d.isWindowsTarget():
offset = 188 if is32bit else 272
......
......@@ -2277,6 +2277,14 @@ ImportInfo ImportInfo::implicitDirectoryImport(const QString &directory)
return info;
}
ImportInfo ImportInfo::qrcDirectoryImport(const QString &directory)
{
ImportInfo info;
info.m_type = ImportType::QrcDirectory;
info.m_path = directory;
return info;
}
bool ImportInfo::isValid() const
{
return m_type != ImportType::Invalid;
......
......@@ -1001,6 +1001,7 @@ public:
const QString &as, AST::UiImport *ast = 0);
static ImportInfo invalidImport(AST::UiImport *ast = 0);
static ImportInfo implicitDirectoryImport(const QString &directory);
static ImportInfo qrcDirectoryImport(const QString &directory);
bool isValid() const;
ImportType::Enum type() const;
......
......@@ -575,16 +575,23 @@ void LinkPrivate::loadQmldirComponents(ObjectValue *import, ComponentVersion ver
void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, Document::Ptr doc)
{
ImportInfo implcitDirectoryImportInfo = ImportInfo::implicitDirectoryImport(doc->path());
Import directoryImport = importCache.value(ImportCacheKey(implcitDirectoryImportInfo));
if (!directoryImport.object) {
directoryImport = importFileOrDirectory(doc, implcitDirectoryImportInfo);
auto processImport = [this, imports, doc](const ImportInfo &importInfo){
Import directoryImport = importCache.value(ImportCacheKey(importInfo));
if (!directoryImport.object) {
directoryImport = importFileOrDirectory(doc, importInfo);
if (directoryImport.object)
importCache.insert(ImportCacheKey(importInfo), directoryImport);
}
if (directoryImport.object)
importCache.insert(ImportCacheKey(implcitDirectoryImportInfo), directoryImport);
imports->append(directoryImport);
};
processImport(ImportInfo::implicitDirectoryImport(doc->path()));
foreach (const QString &path,
ModelManagerInterface::instance()->qrcPathsForFile(doc->fileName())) {
processImport(ImportInfo::qrcDirectoryImport(
QrcParser::qrcDirectoryPathForQrcFilePath(path)));
}
if (directoryImport.object)
imports->append(directoryImport);
}
void LinkPrivate::loadImplicitDefaultImports(Imports *imports)
......
......@@ -427,18 +427,21 @@ bool pInfoLessThanImports(const ModelManagerInterface::ProjectInfo &p1, const Mo
}
QStringList ModelManagerInterface::filesAtQrcPath(const QString &path, const QLocale *locale,
ProjectExplorer::Project *project,
QrcResourceSelector resources)
void ModelManagerInterface::iterateQrcFiles(ProjectExplorer::Project *project,
QrcResourceSelector resources,
std::function<void(QrcParser::ConstPtr)> callback)
{
QString normPath = QrcParser::normalizedQrcFilePath(path);
QList<ProjectInfo> pInfos;
if (project)
if (project) {
pInfos.append(projectInfo(project));
else
} else {
pInfos = projectInfos();
if (resources == ActiveQrcResources) // make the result predictable
qSort(pInfos.begin(), pInfos.end(), &pInfoLessThanActive);
else
qSort(pInfos.begin(), pInfos.end(), &pInfoLessThanAll);
}
QStringList res;
QSet<QString> pathsChecked;
foreach (const ModelManagerInterface::ProjectInfo &pInfo, pInfos) {
QStringList qrcFilePaths;
......@@ -453,10 +456,31 @@ QStringList ModelManagerInterface::filesAtQrcPath(const QString &path, const QLo
QrcParser::ConstPtr qrcFile = m_qrcCache.parsedPath(qrcFilePath);
if (qrcFile.isNull())
continue;
qrcFile->collectFilesAtPath(normPath, &res, locale);
callback(qrcFile);
}
}
res.sort(); // make the result predictable
}
QStringList ModelManagerInterface::qrcPathsForFile(const QString &file, const QLocale *locale,
ProjectExplorer::Project *project,
QrcResourceSelector resources)
{
QStringList res;
iterateQrcFiles(project, resources, [&](QrcParser::ConstPtr qrcFile) {
qrcFile->collectResourceFilesForSourceFile(file, &res, locale);
});
return res;
}
QStringList ModelManagerInterface::filesAtQrcPath(const QString &path, const QLocale *locale,
ProjectExplorer::Project *project,
QrcResourceSelector resources)
{
QString normPath = QrcParser::normalizedQrcFilePath(path);
QStringList res;
iterateQrcFiles(project, resources, [&](QrcParser::ConstPtr qrcFile) {
qrcFile->collectFilesAtPath(normPath, &res, locale);
});
return res;
}
......@@ -467,35 +491,10 @@ QMap<QString, QStringList> ModelManagerInterface::filesInQrcPath(const QString &
QrcResourceSelector resources)
{
QString normPath = QrcParser::normalizedQrcDirectoryPath(path);
QList<ProjectInfo> pInfos;
if (project) {
pInfos.append(projectInfo(project));
} else {
pInfos = projectInfos();
if (resources == ActiveQrcResources) // make the result predictable
qSort(pInfos.begin(), pInfos.end(), &pInfoLessThanActive);
else
qSort(pInfos.begin(), pInfos.end(), &pInfoLessThanAll);
}
QMap<QString, QStringList> res;
QSet<QString> pathsChecked;
foreach (const ModelManagerInterface::ProjectInfo &pInfo, pInfos) {
QStringList qrcFilePaths;
if (resources == ActiveQrcResources)
qrcFilePaths = pInfo.activeResourceFiles;
else
qrcFilePaths = pInfo.allResourceFiles;
foreach (const QString &qrcFilePath, qrcFilePaths) {
if (pathsChecked.contains(qrcFilePath))
continue;
pathsChecked.insert(qrcFilePath);
QrcParser::ConstPtr qrcFile = m_qrcCache.parsedPath(qrcFilePath);
if (qrcFile.isNull())
continue;
qrcFile->collectFilesInPath(normPath, &res, addDirs, locale);
}
}
iterateQrcFiles(project, resources, [&](QrcParser::ConstPtr qrcFile) {
qrcFile->collectFilesInPath(normPath, &res, addDirs, locale);
});
return res;
}
......
......@@ -152,6 +152,9 @@ public:
bool emitDocumentOnDiskChanged);
void fileChangedOnDisk(const QString &path);
void removeFiles(const QStringList &files);
QStringList qrcPathsForFile(const QString &file, const QLocale *locale = 0,
ProjectExplorer::Project *project = 0,
QrcResourceSelector resources = AllQrcResources);
QStringList filesAtQrcPath(const QString &path, const QLocale *locale = 0,
ProjectExplorer::Project *project = 0,
QrcResourceSelector resources = AllQrcResources);
......@@ -249,6 +252,9 @@ protected:
private:
void cleanupFutures();
void iterateQrcFiles(ProjectExplorer::Project *project,
QrcResourceSelector resources,
std::function<void(QrcParser::ConstPtr)> callback);
mutable QMutex m_mutex;
QmlJS::Snapshot m_validSnapshot;
......
......@@ -74,6 +74,9 @@ public:
bool hasDirAtPath(const QString &path, const QLocale *locale = 0) const;
void collectFilesInPath(const QString &path, QMap<QString,QStringList> *res, bool addDirs = false,
const QLocale *locale = 0) const;
void collectResourceFilesForSourceFile(const QString &sourceFile, QStringList *res,
const QLocale *locale = 0) const;
QStringList errorMessages() const;
QStringList languages() const;
private:
......@@ -81,6 +84,7 @@ private:
QStringList allUiLanguages(const QLocale *locale) const;
SMap m_resources;
SMap m_files;
QStringList m_languages;
QStringList m_errorMessages;
};
......@@ -130,6 +134,11 @@ QString QrcParser::normalizedQrcDirectoryPath(const QString &path) {
return normPath;
}
QString QrcParser::qrcDirectoryPathForQrcFilePath(const QString &file)
{
return file.left(file.lastIndexOf(QLatin1Char('/')));
}
QrcParser::QrcParser()
{
d = new Internal::QrcParserPrivate(this);
......@@ -181,6 +190,12 @@ void QrcParser::collectFilesInPath(const QString &path, QMap<QString,QStringList
d->collectFilesInPath(path, res, addDirs, locale);
}
void QrcParser::collectResourceFilesForSourceFile(const QString &sourceFile, QStringList *res,
const QLocale *locale) const
{
d->collectResourceFilesForSourceFile(sourceFile, res, locale);
}
/*! \brief returns the errors found while parsing
*/
QStringList QrcParser::errorMessages() const
......@@ -297,13 +312,12 @@ bool QrcParserPrivate::parseFile(const QString &path)
accessPath = language + prefix + alias;
else
accessPath = language + prefix + fileName;
if (m_resources.contains(accessPath)) {
QStringList &val = m_resources[accessPath];
if (!val.contains(filePath))
val.append(filePath);
} else {
m_resources.insert(accessPath, QStringList(filePath));
}
QStringList &resources = m_resources[accessPath];
if (!resources.contains(filePath))
resources.append(filePath);
QStringList &files = m_files[filePath];
if (!files.contains(accessPath))
files.append(accessPath);
}
}
return true;
......@@ -388,6 +402,24 @@ void QrcParserPrivate::collectFilesInPath(const QString &path, QMap<QString,QStr
}
}
void QrcParserPrivate::collectResourceFilesForSourceFile(const QString &sourceFile,
QStringList *results,
const QLocale *locale) const
{
QTC_CHECK(sourceFile.startsWith(QLatin1Char('/')));
QTC_CHECK(!sourceFile.endsWith(QLatin1Char('/')));
QStringList langs = allUiLanguages(locale);
SMap::const_iterator file = m_files.find(sourceFile);
if (file == m_files.end())
return;
foreach (const QString &resource, file.value()) {
foreach (const QString &language, langs) {
if (resource.startsWith(language) && !results->contains(resource))
results->append(resource);
}
}
}
QStringList QrcParserPrivate::errorMessages() const
{
return m_errorMessages;
......
......@@ -52,6 +52,9 @@ public:
bool hasDirAtPath(const QString &path, const QLocale *locale = 0) const;
void collectFilesInPath(const QString &path, QMap<QString,QStringList> *res, bool addDirs = false,
const QLocale *locale = 0) const;
void collectResourceFilesForSourceFile(const QString &sourceFile, QStringList *results,
const QLocale *locale = 0) const;
QStringList errorMessages() const;
QStringList languages() const;
bool isValid() const;
......@@ -59,6 +62,7 @@ public:
static Ptr parseQrcFile(const QString &path);
static QString normalizedQrcFilePath(const QString &path);
static QString normalizedQrcDirectoryPath(const QString &path);
static QString qrcDirectoryPathForQrcFilePath(const QString &file);
private:
QrcParser();
QrcParser(const QrcParser &);
......
......@@ -275,7 +275,7 @@ extern "C" HRESULT CALLBACK pid(CIDebugClient *client, PCSTR args)
int token;
commandTokens<StringList>(args, &token);
dprintf("Qt Creator CDB extension version 3.6 %d bit.\n",
dprintf("Qt Creator CDB extension version 4.0 %d bit.\n",
sizeof(void *) * 8);
if (const ULONG pid = currentProcessId(client))
ExtensionContext::instance().report('R', token, 0, "pid", "%u", pid);
......
......@@ -38,6 +38,9 @@
namespace Utils {
static const qreal PunchEdgeWidth = 0.5;
static const qreal PunchEdgeIntensity = 0.6;
static QPixmap maskToColorAndAlpha(const QPixmap &mask, const QColor &color)
{
QImage result(mask.toImage().convertToFormat(QImage::Format_ARGB32));
......@@ -95,9 +98,9 @@ static QPixmap combinedMask(const MasksAndColors &masks, Icon::IconStyleOptions
for (;maskImage != masks.constEnd(); ++maskImage) {
if (style & Icon::PunchEdges) {
p.save();
p.setOpacity(0.4);
p.setOpacity(PunchEdgeIntensity);
p.setCompositionMode(QPainter::CompositionMode_Lighten);
smearPixmap(&p, maskToColorAndAlpha((*maskImage).first, Qt::white), 0.5);
smearPixmap(&p, maskToColorAndAlpha((*maskImage).first, Qt::white), PunchEdgeWidth);
p.restore();
}
p.drawPixmap(0, 0, (*maskImage).first);
......@@ -118,9 +121,9 @@ static QPixmap masksToIcon(const MasksAndColors &masks, const QPixmap &combinedM
if (style & Icon::PunchEdges && maskImage != masks.constBegin()) {
// Punch a transparent outline around an overlay.
p.save();
p.setOpacity(0.4);
p.setOpacity(PunchEdgeIntensity);
p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
smearPixmap(&p, maskToColorAndAlpha((*maskImage).first, Qt::white), 0.5);
smearPixmap(&p, maskToColorAndAlpha((*maskImage).first, Qt::white), PunchEdgeWidth);
p.restore();
}
p.drawPixmap(0, 0, maskToColorAndAlpha((*maskImage).first, (*maskImage).second));
......
......@@ -46,13 +46,13 @@ inline void deallocate(char *memory)
#ifdef WIN32
_aligned_free(memory);
#else
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic ignored "-Wfree-nonheap-object"
#endif
std::free(memory);
#pragma GCC diagnostic pop
#endif
#endif
}
inline char *reallocate(char *oldMemory, std::size_t newSize)
......
......@@ -286,20 +286,14 @@ void StyleHelper::drawArrow(QStyle::PrimitiveElement element, QPainter *painter,
return;
const qreal devicePixelRatio = painter->device()->devicePixelRatio();
const bool enabled = option->state & QStyle::State_Enabled;
QRect r = option->rect;
int size = qMin(r.height(), r.width());
QPixmap pixmap;
QString pixmapName;
pixmapName.sprintf("arrow-%s-%d-%d-%d-%lld-%f",
"$qt_ia",
uint(option->state), element,
size, option->palette.cacheKey(),
devicePixelRatio);
pixmapName.sprintf("StyleHelper::drawArrow-%d-%d-%d-%f",
element, size, enabled, devicePixelRatio);
if (!QPixmapCache::find(pixmapName, pixmap)) {
const QCommonStyle* const style = qobject_cast<QCommonStyle*>(QApplication::style());
if (!style)
return;
QImage image(size * devicePixelRatio, size * devicePixelRatio, QImage::Format_ARGB32_Premultiplied);
image.fill(Qt::transparent);
QPainter painter(&image);
......@@ -307,20 +301,22 @@ void StyleHelper::drawArrow(QStyle::PrimitiveElement element, QPainter *painter,
QStyleOption tweakedOption(*option);
tweakedOption.state = QStyle::State_Enabled;
if (!(option