Merge remote-tracking branch 'origin/3.0'

Conflicts:
	src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp

Change-Id: If62ec06ea069a7eba6735101e5334b0c1f66861f
This commit is contained in:
Eike Ziller
2014-01-20 14:21:46 +01:00
28 changed files with 268 additions and 151 deletions

View File

@@ -92,50 +92,6 @@
./android update sdk ./android update sdk
\endcode \endcode
\section1 Developing with Qt 4
The Necessitas SDK automatically sets the paths to the required software
in \QC, but you need to add the Qt version. \QC can then create the
necessary kits for you.
To configure connections between \QC and Android devices:
\list 1
\li Select \gui Tools > \gui Options > \gui {Build & Run} >
\gui {Qt Versions} > \gui Add to add the path to \c qmake path in
the Qt for Android SDK.
\li Select \gui Tools > \gui Options > \gui Android to check the paths
to the required software.
\image qtcreator-options-android.png "Android options"
\li Select the \gui {Automatically create kits for Android tool chains}
check box to allow \QC to create the kits for you. \QC displays a
warning if it cannot find a suitable Qt version.
\li To create an application, select \gui File >
\gui {New File or Project} > \gui Applications >
\gui {Qt Quick Application} > \gui Choose, and
follow the instructions of the wizard. For more information, see
\l{Creating Qt Quick Projects}.
\li To specify information for the Android manifest file, select
\gui Projects > \gui Run for the \gui Android kit.
\li Select \gui Details to view the
\gui {Package configurations}. For more information about the
options you have, see
\l{Specifying Settings for Qt 4 Packages}.
\li To specify settings for deploying applications to Android, select
\gui Details to view the \gui {Deploy configurations}. For more
information about the options you have, see
\l{Deploying Applications to Android Devices}.
\endlist
\section1 Developing with Qt 5 \section1 Developing with Qt 5
You must download and install the latest Android NDK and SDK, and update the You must download and install the latest Android NDK and SDK, and update the
@@ -181,6 +137,50 @@
\gui {Select Android Devices} dialog. \gui {Select Android Devices} dialog.
\endlist \endlist
\section1 Developing with Qt 4
The Necessitas SDK automatically sets the paths to the required software
in \QC, but you need to add the Qt version. \QC can then create the
necessary kits for you.
To configure connections between \QC and Android devices:
\list 1
\li Select \gui Tools > \gui Options > \gui {Build & Run} >
\gui {Qt Versions} > \gui Add to add the path to \c qmake path in
the Qt for Android SDK.
\li Select \gui Tools > \gui Options > \gui Android to check the paths
to the required software.
\image qtcreator-options-android.png "Android options"
\li Select the \gui {Automatically create kits for Android tool chains}
check box to allow \QC to create the kits for you. \QC displays a
warning if it cannot find a suitable Qt version.
\li To create an application, select \gui File >
\gui {New File or Project} > \gui Applications >
\gui {Qt Quick Application} > \gui Choose, and
follow the instructions of the wizard. For more information, see
\l{Creating Qt Quick Projects}.
\li To specify information for the Android manifest file, select
\gui Projects > \gui Run for the \gui Android kit.
\li Select \gui Details to view the
\gui {Package configurations}. For more information about the
options you have, see
\l{Specifying Settings for Qt 4 Packages}.
\li To specify settings for deploying applications to Android, select
\gui Details to view the \gui {Deploy configurations}. For more
information about the options you have, see
\l{Deploying Applications to Android Devices}.
\endlist
\section1 Selecting Android Devices \section1 Selecting Android Devices
When you deploy an application to an Android device with Android When you deploy an application to an Android device with Android

View File

@@ -39,6 +39,17 @@
\image creator_android_tutorial_ex_app.png \image creator_android_tutorial_ex_app.png
\section1 Setting up the Development Environment
To be able to build and run the application, you must download and install
the latest Android NDK and SDK, and update the SDK to get the API and tools
packages needed for development. In addition, you must install the
Java SE Development Kit (JDK) and Apache Ant. After you have installed all
these tools, you must specify the paths to them in \QC.
For detailed instructions, see \l{Qt for Android} and
\l{Connecting Android Devices}.
\section1 Creating the Project \section1 Creating the Project
\list 1 \list 1

View File

@@ -57,7 +57,8 @@
\li \b {\l{Tutorials}} \li \b {\l{Tutorials}}
Now you are ready to start developing your own applications. Now you are ready to start developing your own applications.
Pick a tutorial to follow in \l{Tutorials} Pick a tutorial to follow in \l{Tutorials}. To start developing
for Android devices, select \l{Creating an Android Application}.
\endtable \endtable
*/ */

View File

@@ -33,14 +33,21 @@
You can test that your \QSDK installation is successful by opening an existing You can test that your \QSDK installation is successful by opening an existing
example application project. example application project.
To run an example application on an Android or iOS device, you must set up
the development environment for Android or iOS. For more information, see
\l{Connecting Android Devices} and \l{Connecting iOS Devices}.
\list 1 \list 1
\li In the \gui Welcome mode, select \gui Examples (1). \li In the \gui Welcome mode, select \gui Examples (1).
\image qtcreator-gs-build-example-open.png "Selecting an example" \image qtcreator-gs-build-example-open.png "Selecting an example"
\li Select an example in the list of examples. You can also search for \li Select an example in the list of examples.
examples (2).
You can also search for examples (2). Enter the \gui android or
\gui iOS keyword in the search field to list all the examples tested
for Android or iOS.
\note The project opens in the \gui Edit mode, and the documentation \note The project opens in the \gui Edit mode, and the documentation
for the example hides these instructions. To return to these for the example hides these instructions. To return to these
@@ -67,7 +74,10 @@
If build errors occur, check that a \l{Adding Qt Versions} If build errors occur, check that a \l{Adding Qt Versions}
{Qt version} and \l{Adding Compilers}{compiler} are installed and {Qt version} and \l{Adding Compilers}{compiler} are installed and
configured and that the necessary kits are configured. configured and that the necessary kits are configured. If you are
building for an \l{Connecting Android Devices}{Android device} or
\l{Connecting iOS Devices}{iOS device}, check that the development
environment has been set up correctly.
The \gui Build progress bar on the toolbar turns green when the The \gui Build progress bar on the toolbar turns green when the
project is successfully built. The application opens on the device. project is successfully built. The application opens on the device.

View File

@@ -32,7 +32,9 @@
\QC provides a cross-platform, complete integrated development environment \QC provides a cross-platform, complete integrated development environment
(IDE) for application developers to create applications for multiple desktop (IDE) for application developers to create applications for multiple desktop
and mobile device platforms. It is available for Linux, Mac OS X and Windows and mobile device platforms, such as \l{Connecting Android Devices}{Android}
and \l{Connecting iOS Devices}{iOS}. It is available for Linux, Mac OS X and
Windows
operating systems. For more information, see \l{Supported Platforms}. operating systems. For more information, see \l{Supported Platforms}.
\table \table

View File

@@ -43,6 +43,8 @@ import HelperWidgets 2.0
ButtonRow { ButtonRow {
enabled: anchorBackend.hasParent enabled: anchorBackend.hasParent
opacity: enabled ? 1 : 0.5
id: buttonRow id: buttonRow
ButtonRowButton { ButtonRowButton {

View File

@@ -31,7 +31,7 @@ import QtQuick 2.1
import QtQuick.Controls 1.0 as Controls import QtQuick.Controls 1.0 as Controls
import QtQuick.Layouts 1.0 import QtQuick.Layouts 1.0
Row { RowLayout {
id: buttonRow id: buttonRow
@@ -40,6 +40,7 @@ Row {
property int initalChecked: 0 property int initalChecked: 0
property int checkedIndex: -1 property int checkedIndex: -1
spacing: 0
onCheckedIndexChanged: { onCheckedIndexChanged: {
__checkButton(checkedIndex) __checkButton(checkedIndex)

View File

@@ -62,25 +62,28 @@ Item {
return index() === (parent.children.length - 1); return index() === (parent.children.length - 1);
} }
RoundedPanel { Item {
roundLeft: isFirst() && buttonRowButton.roundLeftButton
roundRight: isLast()
anchors.fill: parent anchors.fill: parent
visible: checked RoundedPanel {
roundLeft: isFirst() && buttonRowButton.roundLeftButton
roundRight: isLast()
gradient: Gradient { anchors.fill: parent
GradientStop {color: '#444' ; position: 0} z: checked ? 1 : 0
GradientStop {color: '#333' ; position: 1}
gradient: Gradient {
GradientStop {color: '#444' ; position: 0}
GradientStop {color: '#333' ; position: 1}
}
} }
}
RoundedPanel { RoundedPanel {
roundLeft: isFirst() roundLeft: isFirst()
roundRight: isLast() roundRight: isLast()
anchors.fill: parent anchors.fill: parent
visible: !checked z: !checked ? 1 : 0
}
} }
Image { Image {

View File

@@ -71,7 +71,6 @@ Section {
SectionLayout { SectionLayout {
columns: 2 columns: 2
rows: 3
Label { Label {
text: qsTr("Font") text: qsTr("Font")
} }
@@ -104,18 +103,26 @@ Section {
sizeWidget.setPointPixelSize(); sizeWidget.setPointPixelSize();
} }
SpinBox { Item {
minimumValue: 0 width: sizeSpinBox.width
visible: !sizeWidget.pixelSize height: sizeSpinBox.height
maximumValue: 400
backendValue: pointSize
}
SpinBox { SpinBox {
minimumValue: 0 id: sizeSpinBox
visible: sizeWidget.pixelSize minimumValue: 0
maximumValue: 400 //visible: !sizeWidget.pixelSize
backendValue: pixelSize z: !sizeWidget.pixelSize ? 1 : 0
maximumValue: 400
backendValue: pointSize
}
SpinBox {
minimumValue: 0
//visible: sizeWidget.pixelSize
z: sizeWidget.pixelSize ? 1 : 0
maximumValue: 400
backendValue: pixelSize
}
} }
Controls.ComboBox { Controls.ComboBox {

View File

@@ -39,11 +39,12 @@ Section {
SectionLayout { SectionLayout {
rows: 4 rows: 4
OriginControl { Label {
backendValue: backendValues.transformOrigin text: qsTr("Origin")
} }
SecondColumnLayout { OriginControl {
backendValue: backendValues.transformOrigin
} }
Label { Label {

View File

@@ -60,7 +60,8 @@ Section {
RowLayout { RowLayout {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
visible: anchorBackend.topAnchored; enabled: anchorBackend.topAnchored;
opacity: enabled ? 1 : 0.5
IconLabel { IconLabel {
source: "../HelperWidgets/images/anchor-top.png" source: "../HelperWidgets/images/anchor-top.png"
@@ -116,7 +117,8 @@ Section {
} }
RowLayout { RowLayout {
visible: anchorBackend.bottomAnchored; enabled: anchorBackend.bottomAnchored;
opacity: enabled ? 1 : 0.5
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@@ -174,7 +176,8 @@ Section {
} }
RowLayout { RowLayout {
visible: anchorBackend.leftAnchored; enabled: anchorBackend.leftAnchored;
opacity: enabled ? 1 : 0.5
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@@ -234,7 +237,8 @@ Section {
RowLayout { RowLayout {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
visible: anchorBackend.rightAnchored; enabled: anchorBackend.rightAnchored;
opacity: enabled ? 1 : 0.5
IconLabel { IconLabel {
source: "../HelperWidgets/images/anchor-right.png" source: "../HelperWidgets/images/anchor-right.png"
@@ -291,7 +295,8 @@ Section {
RowLayout { RowLayout {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
visible: anchorBackend.horizontalCentered; enabled: anchorBackend.horizontalCentered;
opacity: enabled ? 1 : 0.5
IconLabel { IconLabel {
source: "../HelperWidgets/images/anchor-horizontal.png" source: "../HelperWidgets/images/anchor-horizontal.png"
@@ -348,7 +353,8 @@ Section {
RowLayout { RowLayout {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
visible: anchorBackend.verticalCentered; enabled: anchorBackend.verticalCentered;
opacity: enabled ? 1 : 0.5
IconLabel { IconLabel {
source: "../HelperWidgets/images/anchor-vertical.png" source: "../HelperWidgets/images/anchor-vertical.png"

View File

@@ -111,10 +111,12 @@ void TypeDescriptionReader::readDocument(UiProgram *ast)
version = ComponentVersion(versionString.left(dotIdx).toInt(), version = ComponentVersion(versionString.left(dotIdx).toInt(),
versionString.mid(dotIdx + 1).toInt()); versionString.mid(dotIdx + 1).toInt());
} }
if (version > ComponentVersion(1, 1)) { if (version.majorVersion() != 1) {
addError(import->versionToken, tr("Expected version 1.1 or lower.")); addError(import->versionToken, tr("Major version different from 1 not supported."));
return; return;
} }
if (version.minorVersion() > 1)
addWarning(import->versionToken, tr("Reading only version 1.1 parts."));
if (!ast->members || !ast->members->member || ast->members->next) { if (!ast->members || !ast->members->member || ast->members->next) {
addError(SourceLocation(), tr("Expected document to contain a single object definition.")); addError(SourceLocation(), tr("Expected document to contain a single object definition."));

View File

@@ -2862,6 +2862,7 @@ QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryUR
branches << tr("<Detached HEAD>"); branches << tr("<Detached HEAD>");
QString headSha; QString headSha;
// split "82bfad2f51d34e98b18982211c82220b8db049b<tab>refs/heads/master" // split "82bfad2f51d34e98b18982211c82220b8db049b<tab>refs/heads/master"
bool headFound = false;
foreach (const QString &line, resp.stdOut.split(QLatin1Char('\n'))) { foreach (const QString &line, resp.stdOut.split(QLatin1Char('\n'))) {
if (line.endsWith(QLatin1String("\tHEAD"))) { if (line.endsWith(QLatin1String("\tHEAD"))) {
QTC_CHECK(headSha.isNull()); QTC_CHECK(headSha.isNull());
@@ -2871,7 +2872,6 @@ QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryUR
const QString pattern = QLatin1String("\trefs/heads/"); const QString pattern = QLatin1String("\trefs/heads/");
const int pos = line.lastIndexOf(pattern); const int pos = line.lastIndexOf(pattern);
bool headFound = false;
if (pos != -1) { if (pos != -1) {
const QString branchName = line.mid(pos + pattern.count()); const QString branchName = line.mid(pos + pattern.count());
if (!headFound && line.startsWith(headSha)) { if (!headFound && line.startsWith(headSha)) {

View File

@@ -269,6 +269,12 @@ bool selectionNotEmptyAndHasWidthOrHeightProperty(const SelectionContext &contex
&& selectionHasProperty1or2(context, widthProperty, heightProperty); && selectionHasProperty1or2(context, widthProperty, heightProperty);
} }
bool singleSelectionItemIsNotAnchoredAndSingleSelectionNotRoot(const SelectionContext &context)
{
return singleSelectionItemIsNotAnchored(context)
&& singleSelectionNotRoot(context);
}
bool selectionNotEmptyAndHasXorYProperty(const SelectionContext &context) bool selectionNotEmptyAndHasXorYProperty(const SelectionContext &context)
{ {
return selectionNotEmpty(context) return selectionNotEmpty(context)
@@ -335,7 +341,7 @@ void DesignerActionManager::createDefaultDesignerActions()
addDesignerAction(new MenuDesignerAction(anchorsCategoryDisplayName, anchorsCategory, addDesignerAction(new MenuDesignerAction(anchorsCategoryDisplayName, anchorsCategory,
priorityAnchorsCategory, &singleSelectionAndInBaseState)); priorityAnchorsCategory, &singleSelectionAndInBaseState));
addDesignerAction(new ModelNodeAction addDesignerAction(new ModelNodeAction
(anchorsFillDisplayName, anchorsCategory, 200, &anchorsFill, &singleSelectionItemIsNotAnchored)); (anchorsFillDisplayName, anchorsCategory, 200, &anchorsFill, &singleSelectionItemIsNotAnchoredAndSingleSelectionNotRoot));
addDesignerAction(new ModelNodeAction addDesignerAction(new ModelNodeAction
(anchorsResetDisplayName, anchorsCategory, 180, &anchorsReset, &singleSelectionItemIsAnchored)); (anchorsResetDisplayName, anchorsCategory, 180, &anchorsReset, &singleSelectionItemIsAnchored));

View File

@@ -374,17 +374,23 @@ void anchorsFill(const SelectionContext &selectionState)
if (!selectionState.view()) if (!selectionState.view())
return; return;
RewriterTransaction transaction(selectionState.view(), QByteArrayLiteral("DesignerActionManager|anchorsFill")); try {
RewriterTransaction transaction(selectionState.view(), QByteArrayLiteral("DesignerActionManager|anchorsFill"));
ModelNode modelNode = selectionState.currentSingleSelectedNode(); ModelNode modelNode = selectionState.currentSingleSelectedNode();
QmlItemNode node = modelNode; QmlItemNode node = modelNode;
if (node.isValid()) { if (node.isValid()) {
node.anchors().fill(); node.anchors().fill();
backupPropertyAndRemove(modelNode, "x"); backupPropertyAndRemove(modelNode, "x");
backupPropertyAndRemove(modelNode, "y"); backupPropertyAndRemove(modelNode, "y");
backupPropertyAndRemove(modelNode, "width"); backupPropertyAndRemove(modelNode, "width");
backupPropertyAndRemove(modelNode, "height"); backupPropertyAndRemove(modelNode, "height");
}
transaction.commit();
} catch (RewritingException &e) { //better save then sorry
QMessageBox::warning(0, "Error", e.description());
} }
} }

View File

@@ -171,12 +171,15 @@ void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &
// add default qmltypes file if it exists // add default qmltypes file if it exists
const QLatin1String defaultQmltypesFileName("plugins.qmltypes"); const QLatin1String defaultQmltypesFileName("plugins.qmltypes");
const QString defaultQmltypesPath = makeAbsolute(defaultQmltypesFileName, canonicalLibraryPath); const QString defaultQmltypesPath = makeAbsolute(defaultQmltypesFileName, canonicalLibraryPath);
if (QFile::exists(defaultQmltypesPath)) if (!plugin.typeInfoPaths.contains(defaultQmltypesPath) && QFile::exists(defaultQmltypesPath))
plugin.typeInfoPaths += defaultQmltypesPath; plugin.typeInfoPaths += defaultQmltypesPath;
// add typeinfo files listed in qmldir // add typeinfo files listed in qmldir
foreach (const QmlDirParser::TypeInfo &typeInfo, libraryInfo.typeInfos()) foreach (const QmlDirParser::TypeInfo &typeInfo, libraryInfo.typeInfos()) {
plugin.typeInfoPaths += makeAbsolute(typeInfo.fileName, canonicalLibraryPath); QString pathNow = makeAbsolute(typeInfo.fileName, canonicalLibraryPath);
if (!plugin.typeInfoPaths.contains(pathNow) && QFile::exists(pathNow))
plugin.typeInfoPaths += pathNow;
}
// watch plugin libraries // watch plugin libraries
foreach (const QmlDirParser::Plugin &plugin, snapshot.libraryInfo(canonicalLibraryPath).plugins()) { foreach (const QmlDirParser::Plugin &plugin, snapshot.libraryInfo(canonicalLibraryPath).plugins()) {

View File

@@ -414,6 +414,7 @@ void ValgrindGlobalSettings::readSettings()
defaults.insert(QLatin1String(callgrindCostFormatC), CostDelegate::FormatRelative); defaults.insert(QLatin1String(callgrindCostFormatC), CostDelegate::FormatRelative);
defaults.insert(QLatin1String(callgrindCycleDetectionC), true); defaults.insert(QLatin1String(callgrindCycleDetectionC), true);
defaults.insert(QLatin1String(callgrindShortenTemplates), true);
// Read stored values // Read stored values
QSettings *settings = Core::ICore::settings(); QSettings *settings = Core::ICore::settings();

View File

@@ -1531,7 +1531,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
if (!args.at(2).toQString(m_tmp1).compare(fL1S("append"), Qt::CaseInsensitive)) if (!args.at(2).toQString(m_tmp1).compare(fL1S("append"), Qt::CaseInsensitive))
mode = QIODevice::Append; mode = QIODevice::Append;
} }
return writeFile(QString(), resolvePath(args.at(0).toQString(m_tmp1)), mode, contents); QString path = resolvePath(args.at(0).toQString(m_tmp1));
path.detach(); // make sure to not leak m_tmp1 into the map of written files.
return writeFile(QString(), path, mode, contents);
} }
case T_TOUCH: { case T_TOUCH: {
if (args.count() != 2) { if (args.count() != 2) {

View File

@@ -1090,28 +1090,7 @@ bool QMakeEvaluator::prepareProject(const QString &inDir)
} }
no_cache: no_cache:
// Look for mkspecs/ in source and build. First to win determines the root.
QString sdir = inDir;
QString dir = m_outputDir; QString dir = m_outputDir;
while (dir != m_buildRoot) {
if ((dir != sdir && QFileInfo(sdir, QLatin1String("mkspecs")).isDir())
|| QFileInfo(dir, QLatin1String("mkspecs")).isDir()) {
if (dir != sdir)
m_sourceRoot = sdir;
m_buildRoot = dir;
break;
}
if (dir == superdir)
break;
QFileInfo qsdfi(sdir);
QFileInfo qdfi(dir);
if (qsdfi.isRoot() || qdfi.isRoot())
break;
sdir = qsdfi.path();
dir = qdfi.path();
}
dir = m_outputDir;
forever { forever {
QString stashfile = dir + QLatin1String("/.qmake.stash"); QString stashfile = dir + QLatin1String("/.qmake.stash");
if (dir == (!superdir.isEmpty() ? superdir : m_buildRoot) || m_vfs->exists(stashfile)) { if (dir == (!superdir.isEmpty() ? superdir : m_buildRoot) || m_vfs->exists(stashfile)) {

View File

@@ -150,6 +150,9 @@
:Qt Creator_Core::Internal::ProgressBar {type='Core::Internal::ProgressBar' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_Core::Internal::ProgressBar {type='Core::Internal::ProgressBar' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_Core::OutputWindow {type='Core::OutputWindow' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_Core::OutputWindow {type='Core::OutputWindow' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_CppEditor::Internal::CPPEditorWidget {type='CppEditor::Internal::CPPEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_CppEditor::Internal::CPPEditorWidget {type='CppEditor::Internal::CPPEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_DiffEditor::DiffViewEditorWidget {type='DiffEditor::DiffViewEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_DiffEditor::DiffViewEditorWidget2 {occurrence='2' type='DiffEditor::DiffViewEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_DiffEditor::Internal::DiffShowEditorWidget {type='DiffEditor::Internal::DiffShowEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_FilenameQComboBox {type='QComboBox' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_FilenameQComboBox {type='QComboBox' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_Find::Internal::SearchResultTreeView {type='Find::Internal::SearchResultTreeView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_Find::Internal::SearchResultTreeView {type='Find::Internal::SearchResultTreeView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_Git::Internal::GitEditor {type='Git::Internal::GitEditor' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_Git::Internal::GitEditor {type='Git::Internal::GitEditor' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}

View File

@@ -30,12 +30,6 @@
import __builtin__ import __builtin__
import re import re
processExited = False
def __handleProcessExited__(*args):
global processExited
processExited = True
def openQmakeProject(projectPath, targets=Targets.desktopTargetClasses(), fromWelcome=False): def openQmakeProject(projectPath, targets=Targets.desktopTargetClasses(), fromWelcome=False):
cleanUpUserFiles(projectPath) cleanUpUserFiles(projectPath)
if fromWelcome: if fromWelcome:
@@ -383,7 +377,7 @@ def __chooseTargets__(targets=Targets.DESKTOP_474_GCC, availableTargets=None):
test.warning("Target '%s' is not set up correctly." % Targets.getStringForTarget(current)) test.warning("Target '%s' is not set up correctly." % Targets.getStringForTarget(current))
return checkedTargets return checkedTargets
def waitForProcessStarted(): def waitForProcessRunning(running=True):
outputButton = waitForObject(":Qt Creator_AppOutput_Core::Internal::OutputPaneToggleButton") outputButton = waitForObject(":Qt Creator_AppOutput_Core::Internal::OutputPaneToggleButton")
if not waitFor("outputButton.checked", 10000): if not waitFor("outputButton.checked", 10000):
ensureChecked(outputButton) ensureChecked(outputButton)
@@ -391,7 +385,7 @@ def waitForProcessStarted():
reRunButton = findObject(":Qt Creator.ReRun_QToolButton") reRunButton = findObject(":Qt Creator.ReRun_QToolButton")
waitFor("object.exists(':Qt Creator.Stop_QToolButton')", 20000) waitFor("object.exists(':Qt Creator.Stop_QToolButton')", 20000)
stopButton = findObject(":Qt Creator.Stop_QToolButton") stopButton = findObject(":Qt Creator.Stop_QToolButton")
return waitFor("not reRunButton.enabled and stopButton.enabled", 10000) return waitFor("(reRunButton.enabled != running) and (stopButton.enabled == running)", 10000)
# run and close an application # run and close an application
# withHookInto - if set to True the function tries to attach to the sub-process instead of simply pressing Stop inside Creator # withHookInto - if set to True the function tries to attach to the sub-process instead of simply pressing Stop inside Creator
@@ -404,10 +398,6 @@ def waitForProcessStarted():
# by yourself (or use the function parameter) # by yourself (or use the function parameter)
# ATTENTION! Make sure this function won't fail and the sub-process will end when the function returns # ATTENTION! Make sure this function won't fail and the sub-process will end when the function returns
def runAndCloseApp(withHookInto=False, executable=None, port=None, function=None, sType=None, userDefinedType=None): def runAndCloseApp(withHookInto=False, executable=None, port=None, function=None, sType=None, userDefinedType=None):
global processExited
processExited = False
overrideInstallLazySignalHandler()
installLazySignalHandler("{type='QProcess'}", "finished(int,QProcess::ExitStatus)", "__handleProcessExited__")
runButton = waitForObject(":*Qt Creator.Run_Core::Internal::FancyToolButton") runButton = waitForObject(":*Qt Creator.Run_Core::Internal::FancyToolButton")
clickButton(runButton) clickButton(runButton)
if sType != SubprocessType.QT_QUICK_UI: if sType != SubprocessType.QT_QUICK_UI:
@@ -418,7 +408,7 @@ def runAndCloseApp(withHookInto=False, executable=None, port=None, function=None
test.fatal("Build inside run wasn't successful - leaving test") test.fatal("Build inside run wasn't successful - leaving test")
invokeMenuItem("File", "Exit") invokeMenuItem("File", "Exit")
return False return False
if not waitForProcessStarted(): if not waitForProcessRunning():
test.fatal("Couldn't start application - leaving test") test.fatal("Couldn't start application - leaving test")
invokeMenuItem("File", "Exit") invokeMenuItem("File", "Exit")
return False return False
@@ -466,7 +456,6 @@ def __closeSubprocessByPushingStop__(sType):
test.fatal("Subprocess does not seem to have been started.") test.fatal("Subprocess does not seem to have been started.")
def __closeSubprocessByHookingInto__(executable, port, function, sType, userDefType): def __closeSubprocessByHookingInto__(executable, port, function, sType, userDefType):
global processExited
ensureChecked(":Qt Creator_AppOutput_Core::Internal::OutputPaneToggleButton") ensureChecked(":Qt Creator_AppOutput_Core::Internal::OutputPaneToggleButton")
output = waitForObject("{type='Core::OutputWindow' visible='1' windowTitle='Application Output Window'}") output = waitForObject("{type='Core::OutputWindow' visible='1' windowTitle='Application Output Window'}")
if port == None: if port == None:
@@ -495,7 +484,7 @@ def __closeSubprocessByHookingInto__(executable, port, function, sType, userDefT
switchViewTo(ViewConstants.EDIT) switchViewTo(ViewConstants.EDIT)
runButton = waitForObject(":*Qt Creator.Run_Core::Internal::FancyToolButton") runButton = waitForObject(":*Qt Creator.Run_Core::Internal::FancyToolButton")
clickButton(runButton) clickButton(runButton)
if not waitForProcessStarted(): if not waitForProcessRunning():
test.fatal("Something seems to be really wrong.", "Application output:" test.fatal("Something seems to be really wrong.", "Application output:"
% str(output.plainText)) % str(output.plainText))
return False return False
@@ -522,11 +511,10 @@ def __closeSubprocessByHookingInto__(executable, port, function, sType, userDefT
"Using fallback of pushing STOP inside Creator.") "Using fallback of pushing STOP inside Creator.")
resetApplicationContextToCreator() resetApplicationContextToCreator()
__closeSubprocessByPushingStop__(sType) __closeSubprocessByPushingStop__(sType)
waitFor("processExited==True and 'exited with code' in str(output.plainText)", 10000) resetApplicationContextToCreator()
if not processExited: if not waitForProcessRunning(False) and waitFor("'exited with code' in str(output.plainText)", 10000):
test.warning("Sub-process seems not to have closed properly.") test.warning("Sub-process seems not to have closed properly.")
try: try:
resetApplicationContextToCreator()
__closeSubprocessByPushingStop__(sType) __closeSubprocessByPushingStop__(sType)
except: except:
pass pass

View File

@@ -299,6 +299,13 @@ def invokeContextMenuOnProject(projectName, menuItem):
return return
openItemContextMenu(waitForObject(":Qt Creator_Utils::NavigationTreeView"), openItemContextMenu(waitForObject(":Qt Creator_Utils::NavigationTreeView"),
str(projItem.text).replace("_", "\\_").replace(".", "\\."), 5, 5, 0) str(projItem.text).replace("_", "\\_").replace(".", "\\."), 5, 5, 0)
activateItem(waitForObjectItem("{name='Project.Menu.Project' type='QMenu' visible='1' " # Hack for Squish 5.0.1 handling menus of Qt5.2 on Mac (avoids crash) - remove asap
"window=':Qt Creator_Core::Internal::MainWindow'}", menuItem)) if platform.system() == 'Darwin':
for obj in object.topLevelObjects():
if (className(obj) == "QMenu" and obj.visible):
activateItem(waitForObjectItem(obj, menuItem))
break
else:
activateItem(waitForObjectItem("{name='Project.Menu.Project' type='QMenu' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}", menuItem))
return projItem return projItem

View File

@@ -34,7 +34,8 @@ source("../../shared/suites_qtta.py")
def main(): def main():
# expected error texts - for different compilers # expected error texts - for different compilers
expectedErrorAlternatives = ["'SyntaxError' was not declared in this scope", expectedErrorAlternatives = ["'SyntaxError' was not declared in this scope",
"'SyntaxError' : undeclared identifier"] "'SyntaxError' : undeclared identifier",
"use of undeclared identifier 'SyntaxError'"]
startApplication("qtcreator" + SettingsPath) startApplication("qtcreator" + SettingsPath)
if not startedWithoutPluginError(): if not startedWithoutPluginError():
return return

View File

@@ -88,8 +88,11 @@ def __handleAppOutputWaitForDebuggerFinish__():
ensureChecked(":Qt Creator_AppOutput_Core::Internal::OutputPaneToggleButton") ensureChecked(":Qt Creator_AppOutput_Core::Internal::OutputPaneToggleButton")
appOutput = waitForObject("{type='Core::OutputWindow' visible='1' " appOutput = waitForObject("{type='Core::OutputWindow' visible='1' "
"windowTitle='Application Output Window'}") "windowTitle='Application Output Window'}")
test.verify(waitFor("str(appOutput.plainText).endswith('Debugging has finished')", 20000), if not test.verify(waitFor("str(appOutput.plainText).endswith('Debugging has finished')", 20000),
"Verifying whether debugging has finished.") "Verifying whether debugging has finished."):
test.log("Aborting debugging to let test continue.")
invokeMenuItem("Debug", "Abort Debugging")
waitFor("str(appOutput.plainText).endswith('Debugging has finished')", 5000)
def performDebugging(workingDir, projectName, checkedTargets): def performDebugging(workingDir, projectName, checkedTargets):
# for checking if it's a plain C application (as project names are set to match project type) # for checking if it's a plain C application (as project names are set to match project type)

View File

@@ -216,6 +216,10 @@ def __getExpectedDebuggers__():
result.extend(__getCDB__()) result.extend(__getCDB__())
debuggers = ["gdb", "lldb"] debuggers = ["gdb", "lldb"]
result.extend(filter(None, map(which, debuggers))) result.extend(filter(None, map(which, debuggers)))
if platform.system() == 'Darwin':
xcodeLLDB = "/Applications/Xcode.app/Contents/Developer/usr/bin/lldb"
if os.path.exists(xcodeLLDB):
result.append(xcodeLLDB)
return result return result
def __getCDB__(): def __getCDB__():

View File

@@ -87,9 +87,6 @@ def renameFile(projectDir, proFile, branch, oldname, newname):
type(waitForObject(":Qt Creator_Utils::NavigationTreeView::QExpandingLineEdit"), "<Return>") type(waitForObject(":Qt Creator_Utils::NavigationTreeView::QExpandingLineEdit"), "<Return>")
test.verify(waitFor("os.path.exists(newFilePath)", 1000), test.verify(waitFor("os.path.exists(newFilePath)", 1000),
"Verify that file with new name exists: %s" % newFilePath) "Verify that file with new name exists: %s" % newFilePath)
if not (oldname.lower() == newname.lower() and platform.system() in ('Windows', 'Microsoft')):
test.verify(not os.path.exists(oldFilePath),
"Verify that file with old name does not exist: %s" % oldFilePath)
test.compare(readFile(newFilePath), oldFileText, test.compare(readFile(newFilePath), oldFileText,
"Comparing content of file before and after renaming") "Comparing content of file before and after renaming")
test.verify(waitFor("newname in safeReadFile(proFile)", 2000), test.verify(waitFor("newname in safeReadFile(proFile)", 2000),
@@ -97,6 +94,9 @@ def renameFile(projectDir, proFile, branch, oldname, newname):
if not oldname in newname: if not oldname in newname:
test.verify(not oldname in readFile(proFile), test.verify(not oldname in readFile(proFile),
"Verify that old filename '%s' was removed from pro-file." % oldname) "Verify that old filename '%s' was removed from pro-file." % oldname)
if not (oldname.lower() == newname.lower() and platform.system() in ('Windows', 'Microsoft')):
test.verify(not oldname in os.listdir(projectDir),
"Verify that file with old name does not exist: %s" % oldFilePath)
def safeReadFile(filename): def safeReadFile(filename):
text = "" text = ""

View File

@@ -36,7 +36,7 @@ def verifyCloneLog(targetDir, canceled):
# Expect fails because of QTCREATORBUG-10531 # Expect fails because of QTCREATORBUG-10531
cloneLog = waitForObject(":Git Repository Clone.logPlainTextEdit_QPlainTextEdit") cloneLog = waitForObject(":Git Repository Clone.logPlainTextEdit_QPlainTextEdit")
finish = findObject(":Git Repository Clone.Finish_QPushButton") finish = findObject(":Git Repository Clone.Finish_QPushButton")
waitFor("finish.enabled", 30000) waitFor("canceled or finish.enabled", 30000)
test.xverify(("Executing in " + targetDir + ":" in str(cloneLog.plainText)), test.xverify(("Executing in " + targetDir + ":" in str(cloneLog.plainText)),
"Searching for target directory in clone log") "Searching for target directory in clone log")
test.xverify((" ".join(["clone", cloneUrl, cloneDir]) in str(cloneLog.plainText)), test.xverify((" ".join(["clone", cloneUrl, cloneDir]) in str(cloneLog.plainText)),
@@ -58,7 +58,9 @@ def verifyCloneLog(targetDir, canceled):
test.xverify((result in str(cloneLog.plainText)), test.xverify((result in str(cloneLog.plainText)),
"Searching for result (%s) in clone log:\n%s" "Searching for result (%s) in clone log:\n%s"
% (result, str(cloneLog.plainText).replace(unicode("\x1b"), ""))) % (result, str(cloneLog.plainText).replace(unicode("\x1b"), "")))
test.compare(waitForObject(":Git Repository Clone.Result._QLabel").text, summary) resultLabel = findObject(":Git Repository Clone.Result._QLabel")
test.verify(waitFor('str(resultLabel.text) == summary', 3000),
"Verifying expected result (%s)" % summary)
def verifyFiles(targetDir): def verifyFiles(targetDir):
for file in [".gitignore", "CMakeLists.txt", "jom.pro", for file in [".gitignore", "CMakeLists.txt", "jom.pro",
@@ -84,9 +86,12 @@ def main():
test.compare(cloneDirEdit.text, "p-qt-labs-jom") test.compare(cloneDirEdit.text, "p-qt-labs-jom")
replaceEditorContent(cloneDirEdit, cloneDir) replaceEditorContent(cloneDirEdit, cloneDir)
clickButton(waitForObject(":Next_QPushButton")) clickButton(waitForObject(":Next_QPushButton"))
cloneLog = findObject(":Git Repository Clone.logPlainTextEdit_QPlainTextEdit")
test.compare(waitForObject(":Git Repository Clone.Result._QLabel").text, test.compare(waitForObject(":Git Repository Clone.Result._QLabel").text,
"Cloning started...") "Cloning started...")
if button == "Cancel immediately": if button == "Cancel immediately":
# wait for cloning to have started
waitFor('len(str(cloneLog.plainText)) > 20 + len(cloneDir)')
clickButton(":Git Repository Clone.Cancel_QPushButton") clickButton(":Git Repository Clone.Cancel_QPushButton")
verifyCloneLog(targetDir, True) verifyCloneLog(targetDir, True)
clickButton(":Git Repository Clone.Cancel_QPushButton") clickButton(":Git Repository Clone.Cancel_QPushButton")

View File

@@ -51,6 +51,66 @@ def verifyItemsInGit(commitMessages):
verifyItemOrder(commitMessages, plainText) verifyItemOrder(commitMessages, plainText)
return plainText return plainText
def verifyClickCommit():
gitEditor = waitForObject(":Qt Creator_Git::Internal::GitEditor")
fileName = waitForObject(":Qt Creator_FilenameQComboBox")
test.verify(waitFor('str(fileName.currentText).startswith("Git Log")', 1000),
"Verifying Qt Creator still displays git log inside editor.")
content = str(gitEditor.plainText)
noOfCommits = content.count("commit")
commit = None
# find second commit
try:
line = filter(lambda line: line.startswith("commit"), content.splitlines())[-2]
commit = line.split(" ", 1)[1]
except:
test.fail("Could not find the second commit - leaving test")
return
placeCursorToLine(gitEditor, line)
for i in range(5):
type(gitEditor, "<Left>")
# get the current cursor rectangle which should be positioned on the commit ID
rect = gitEditor.cursorRect()
# click on the commit ID
mouseClick(gitEditor, rect.x, rect.y + rect.height / 2, 0, Qt.LeftButton)
expected = 'Git Show "%s"' % commit
test.verify(waitFor('str(fileName.currentText) == expected', 5000),
"Verifying editor switches to Git Show.")
diffShow = waitForObject(":Qt Creator_DiffEditor::Internal::DiffShowEditorWidget")
waitFor('len(str(diffShow.plainText)) != 0', 5000)
show = str(diffShow.plainText)
expected = [{"commit %s" % commit:False},
{"Author: (\w|\s)+ <(\w|[-.])+@(\w|[-.])+>": True},
{"Date:\s+\w{3} \w{3} \d{1,2} \d{2}:\d{2}:\d{2} \d{4}.*":True},
{"Branches: master":False}]
for line, exp in zip(show.splitlines(), expected):
expLine = exp.keys()[0]
isRegex = exp.values()[0]
if isRegex:
test.verify(re.match(expLine, line), "Verifying commit header line '%s'" % line)
else:
test.compare(line, expLine, "Verifying commit header line.")
changed = waitForObject(":Qt Creator_DiffEditor::DiffViewEditorWidget")
original = waitForObject(":Qt Creator_DiffEditor::DiffViewEditorWidget2")
waitFor('str(changed.plainText) != "Waiting for data..." '
'and str(original.plainText) != "Waiting for data..."', 5000)
# content of diff editors is merge of modified files
diffOriginal = str(original.plainText)
diffChanged = str(changed.plainText)
# diffChanged must completely contain the pointless_header.h
pointlessHeader = readFile(os.path.join(srcPath, projectName, "pointless_header.h"))
test.verify(pointlessHeader in diffChanged,
"Verifying whether diff editor contains pointless_header.h file.")
test.verify(pointlessHeader not in diffOriginal,
"Verifying whether original does not contain pointless_header.h file.")
test.verify("HEADERS += mainwindow.h \\\n pointless_header.h\n" in diffChanged,
"Verifying whether diff editor has pointless_header.h listed in pro file.")
test.verify("HEADERS += mainwindow.h\n\n" in diffOriginal
and "pointless_header.h" not in diffOriginal,
"Verifying whether original has no additional header in pro file.")
test.verify(original.readOnly and changed.readOnly and diffShow.readOnly,
"Verifying all diff editor widgets are readonly.")
def main(): def main():
startApplication("qtcreator" + SettingsPath) startApplication("qtcreator" + SettingsPath)
if not startedWithoutPluginError(): if not startedWithoutPluginError():
@@ -97,6 +157,9 @@ def main():
invokeMenuItem("Tools", "Git", "Local Repository", "Log") invokeMenuItem("Tools", "Git", "Local Repository", "Log")
verifyItemsInGit(commitMessages) verifyItemsInGit(commitMessages)
# verifyClickCommit() must be called after the local git has been created and the files
# have been pushed to the repository
verifyClickCommit()
invokeMenuItem("File", "Close All Projects and Editors") invokeMenuItem("File", "Close All Projects and Editors")
invokeMenuItem("File", "Exit") invokeMenuItem("File", "Exit")