forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/3.0'
Conflicts: src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp Change-Id: If62ec06ea069a7eba6735101e5334b0c1f66861f
This commit is contained in:
@@ -92,50 +92,6 @@
|
||||
./android update sdk
|
||||
\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
|
||||
|
||||
You must download and install the latest Android NDK and SDK, and update the
|
||||
@@ -181,6 +137,50 @@
|
||||
\gui {Select Android Devices} dialog.
|
||||
\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
|
||||
|
||||
When you deploy an application to an Android device with Android
|
||||
|
||||
@@ -39,6 +39,17 @@
|
||||
|
||||
\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
|
||||
|
||||
\list 1
|
||||
|
||||
@@ -57,7 +57,8 @@
|
||||
\li \b {\l{Tutorials}}
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
|
||||
@@ -33,14 +33,21 @@
|
||||
You can test that your \QSDK installation is successful by opening an existing
|
||||
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
|
||||
|
||||
\li In the \gui Welcome mode, select \gui Examples (1).
|
||||
|
||||
\image qtcreator-gs-build-example-open.png "Selecting an example"
|
||||
|
||||
\li Select an example in the list of examples. You can also search for
|
||||
examples (2).
|
||||
\li Select an example in the list of examples.
|
||||
|
||||
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
|
||||
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}
|
||||
{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
|
||||
project is successfully built. The application opens on the device.
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
|
||||
\QC provides a cross-platform, complete integrated development environment
|
||||
(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}.
|
||||
|
||||
\table
|
||||
|
||||
@@ -43,6 +43,8 @@ import HelperWidgets 2.0
|
||||
|
||||
ButtonRow {
|
||||
enabled: anchorBackend.hasParent
|
||||
opacity: enabled ? 1 : 0.5
|
||||
|
||||
id: buttonRow
|
||||
|
||||
ButtonRowButton {
|
||||
|
||||
@@ -31,7 +31,7 @@ import QtQuick 2.1
|
||||
import QtQuick.Controls 1.0 as Controls
|
||||
import QtQuick.Layouts 1.0
|
||||
|
||||
Row {
|
||||
RowLayout {
|
||||
|
||||
id: buttonRow
|
||||
|
||||
@@ -40,6 +40,7 @@ Row {
|
||||
property int initalChecked: 0
|
||||
|
||||
property int checkedIndex: -1
|
||||
spacing: 0
|
||||
|
||||
onCheckedIndexChanged: {
|
||||
__checkButton(checkedIndex)
|
||||
|
||||
@@ -62,12 +62,14 @@ Item {
|
||||
return index() === (parent.children.length - 1);
|
||||
}
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
RoundedPanel {
|
||||
roundLeft: isFirst() && buttonRowButton.roundLeftButton
|
||||
roundRight: isLast()
|
||||
|
||||
anchors.fill: parent
|
||||
visible: checked
|
||||
z: checked ? 1 : 0
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop {color: '#444' ; position: 0}
|
||||
@@ -80,7 +82,8 @@ Item {
|
||||
roundRight: isLast()
|
||||
|
||||
anchors.fill: parent
|
||||
visible: !checked
|
||||
z: !checked ? 1 : 0
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
|
||||
@@ -71,7 +71,6 @@ Section {
|
||||
|
||||
SectionLayout {
|
||||
columns: 2
|
||||
rows: 3
|
||||
Label {
|
||||
text: qsTr("Font")
|
||||
}
|
||||
@@ -104,19 +103,27 @@ Section {
|
||||
sizeWidget.setPointPixelSize();
|
||||
}
|
||||
|
||||
Item {
|
||||
width: sizeSpinBox.width
|
||||
height: sizeSpinBox.height
|
||||
|
||||
SpinBox {
|
||||
id: sizeSpinBox
|
||||
minimumValue: 0
|
||||
visible: !sizeWidget.pixelSize
|
||||
//visible: !sizeWidget.pixelSize
|
||||
z: !sizeWidget.pixelSize ? 1 : 0
|
||||
maximumValue: 400
|
||||
backendValue: pointSize
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
minimumValue: 0
|
||||
visible: sizeWidget.pixelSize
|
||||
//visible: sizeWidget.pixelSize
|
||||
z: sizeWidget.pixelSize ? 1 : 0
|
||||
maximumValue: 400
|
||||
backendValue: pixelSize
|
||||
}
|
||||
}
|
||||
|
||||
Controls.ComboBox {
|
||||
id: sizeType
|
||||
|
||||
@@ -39,11 +39,12 @@ Section {
|
||||
SectionLayout {
|
||||
rows: 4
|
||||
|
||||
OriginControl {
|
||||
backendValue: backendValues.transformOrigin
|
||||
Label {
|
||||
text: qsTr("Origin")
|
||||
}
|
||||
|
||||
SecondColumnLayout {
|
||||
OriginControl {
|
||||
backendValue: backendValues.transformOrigin
|
||||
}
|
||||
|
||||
Label {
|
||||
|
||||
@@ -60,7 +60,8 @@ Section {
|
||||
RowLayout {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
visible: anchorBackend.topAnchored;
|
||||
enabled: anchorBackend.topAnchored;
|
||||
opacity: enabled ? 1 : 0.5
|
||||
|
||||
IconLabel {
|
||||
source: "../HelperWidgets/images/anchor-top.png"
|
||||
@@ -116,7 +117,8 @@ Section {
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: anchorBackend.bottomAnchored;
|
||||
enabled: anchorBackend.bottomAnchored;
|
||||
opacity: enabled ? 1 : 0.5
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
@@ -174,7 +176,8 @@ Section {
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: anchorBackend.leftAnchored;
|
||||
enabled: anchorBackend.leftAnchored;
|
||||
opacity: enabled ? 1 : 0.5
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
@@ -234,7 +237,8 @@ Section {
|
||||
RowLayout {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
visible: anchorBackend.rightAnchored;
|
||||
enabled: anchorBackend.rightAnchored;
|
||||
opacity: enabled ? 1 : 0.5
|
||||
|
||||
IconLabel {
|
||||
source: "../HelperWidgets/images/anchor-right.png"
|
||||
@@ -291,7 +295,8 @@ Section {
|
||||
RowLayout {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
visible: anchorBackend.horizontalCentered;
|
||||
enabled: anchorBackend.horizontalCentered;
|
||||
opacity: enabled ? 1 : 0.5
|
||||
|
||||
IconLabel {
|
||||
source: "../HelperWidgets/images/anchor-horizontal.png"
|
||||
@@ -348,7 +353,8 @@ Section {
|
||||
RowLayout {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
visible: anchorBackend.verticalCentered;
|
||||
enabled: anchorBackend.verticalCentered;
|
||||
opacity: enabled ? 1 : 0.5
|
||||
|
||||
IconLabel {
|
||||
source: "../HelperWidgets/images/anchor-vertical.png"
|
||||
|
||||
@@ -111,10 +111,12 @@ void TypeDescriptionReader::readDocument(UiProgram *ast)
|
||||
version = ComponentVersion(versionString.left(dotIdx).toInt(),
|
||||
versionString.mid(dotIdx + 1).toInt());
|
||||
}
|
||||
if (version > ComponentVersion(1, 1)) {
|
||||
addError(import->versionToken, tr("Expected version 1.1 or lower."));
|
||||
if (version.majorVersion() != 1) {
|
||||
addError(import->versionToken, tr("Major version different from 1 not supported."));
|
||||
return;
|
||||
}
|
||||
if (version.minorVersion() > 1)
|
||||
addWarning(import->versionToken, tr("Reading only version 1.1 parts."));
|
||||
|
||||
if (!ast->members || !ast->members->member || ast->members->next) {
|
||||
addError(SourceLocation(), tr("Expected document to contain a single object definition."));
|
||||
|
||||
@@ -2862,6 +2862,7 @@ QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryUR
|
||||
branches << tr("<Detached HEAD>");
|
||||
QString headSha;
|
||||
// split "82bfad2f51d34e98b18982211c82220b8db049b<tab>refs/heads/master"
|
||||
bool headFound = false;
|
||||
foreach (const QString &line, resp.stdOut.split(QLatin1Char('\n'))) {
|
||||
if (line.endsWith(QLatin1String("\tHEAD"))) {
|
||||
QTC_CHECK(headSha.isNull());
|
||||
@@ -2871,7 +2872,6 @@ QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryUR
|
||||
|
||||
const QString pattern = QLatin1String("\trefs/heads/");
|
||||
const int pos = line.lastIndexOf(pattern);
|
||||
bool headFound = false;
|
||||
if (pos != -1) {
|
||||
const QString branchName = line.mid(pos + pattern.count());
|
||||
if (!headFound && line.startsWith(headSha)) {
|
||||
|
||||
@@ -269,6 +269,12 @@ bool selectionNotEmptyAndHasWidthOrHeightProperty(const SelectionContext &contex
|
||||
&& selectionHasProperty1or2(context, widthProperty, heightProperty);
|
||||
}
|
||||
|
||||
bool singleSelectionItemIsNotAnchoredAndSingleSelectionNotRoot(const SelectionContext &context)
|
||||
{
|
||||
return singleSelectionItemIsNotAnchored(context)
|
||||
&& singleSelectionNotRoot(context);
|
||||
}
|
||||
|
||||
bool selectionNotEmptyAndHasXorYProperty(const SelectionContext &context)
|
||||
{
|
||||
return selectionNotEmpty(context)
|
||||
@@ -335,7 +341,7 @@ void DesignerActionManager::createDefaultDesignerActions()
|
||||
addDesignerAction(new MenuDesignerAction(anchorsCategoryDisplayName, anchorsCategory,
|
||||
priorityAnchorsCategory, &singleSelectionAndInBaseState));
|
||||
addDesignerAction(new ModelNodeAction
|
||||
(anchorsFillDisplayName, anchorsCategory, 200, &anchorsFill, &singleSelectionItemIsNotAnchored));
|
||||
(anchorsFillDisplayName, anchorsCategory, 200, &anchorsFill, &singleSelectionItemIsNotAnchoredAndSingleSelectionNotRoot));
|
||||
addDesignerAction(new ModelNodeAction
|
||||
(anchorsResetDisplayName, anchorsCategory, 180, &anchorsReset, &singleSelectionItemIsAnchored));
|
||||
|
||||
|
||||
@@ -374,6 +374,7 @@ void anchorsFill(const SelectionContext &selectionState)
|
||||
if (!selectionState.view())
|
||||
return;
|
||||
|
||||
try {
|
||||
RewriterTransaction transaction(selectionState.view(), QByteArrayLiteral("DesignerActionManager|anchorsFill"));
|
||||
|
||||
ModelNode modelNode = selectionState.currentSingleSelectedNode();
|
||||
@@ -386,6 +387,11 @@ void anchorsFill(const SelectionContext &selectionState)
|
||||
backupPropertyAndRemove(modelNode, "width");
|
||||
backupPropertyAndRemove(modelNode, "height");
|
||||
}
|
||||
|
||||
transaction.commit();
|
||||
} catch (RewritingException &e) { //better save then sorry
|
||||
QMessageBox::warning(0, "Error", e.description());
|
||||
}
|
||||
}
|
||||
|
||||
void anchorsReset(const SelectionContext &selectionState)
|
||||
|
||||
@@ -171,12 +171,15 @@ void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &
|
||||
// add default qmltypes file if it exists
|
||||
const QLatin1String defaultQmltypesFileName("plugins.qmltypes");
|
||||
const QString defaultQmltypesPath = makeAbsolute(defaultQmltypesFileName, canonicalLibraryPath);
|
||||
if (QFile::exists(defaultQmltypesPath))
|
||||
if (!plugin.typeInfoPaths.contains(defaultQmltypesPath) && QFile::exists(defaultQmltypesPath))
|
||||
plugin.typeInfoPaths += defaultQmltypesPath;
|
||||
|
||||
// add typeinfo files listed in qmldir
|
||||
foreach (const QmlDirParser::TypeInfo &typeInfo, libraryInfo.typeInfos())
|
||||
plugin.typeInfoPaths += makeAbsolute(typeInfo.fileName, canonicalLibraryPath);
|
||||
foreach (const QmlDirParser::TypeInfo &typeInfo, libraryInfo.typeInfos()) {
|
||||
QString pathNow = makeAbsolute(typeInfo.fileName, canonicalLibraryPath);
|
||||
if (!plugin.typeInfoPaths.contains(pathNow) && QFile::exists(pathNow))
|
||||
plugin.typeInfoPaths += pathNow;
|
||||
}
|
||||
|
||||
// watch plugin libraries
|
||||
foreach (const QmlDirParser::Plugin &plugin, snapshot.libraryInfo(canonicalLibraryPath).plugins()) {
|
||||
|
||||
@@ -414,6 +414,7 @@ void ValgrindGlobalSettings::readSettings()
|
||||
|
||||
defaults.insert(QLatin1String(callgrindCostFormatC), CostDelegate::FormatRelative);
|
||||
defaults.insert(QLatin1String(callgrindCycleDetectionC), true);
|
||||
defaults.insert(QLatin1String(callgrindShortenTemplates), true);
|
||||
|
||||
// Read stored values
|
||||
QSettings *settings = Core::ICore::settings();
|
||||
|
||||
@@ -1531,7 +1531,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
||||
if (!args.at(2).toQString(m_tmp1).compare(fL1S("append"), Qt::CaseInsensitive))
|
||||
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: {
|
||||
if (args.count() != 2) {
|
||||
|
||||
@@ -1090,28 +1090,7 @@ bool QMakeEvaluator::prepareProject(const QString &inDir)
|
||||
}
|
||||
no_cache:
|
||||
|
||||
// Look for mkspecs/ in source and build. First to win determines the root.
|
||||
QString sdir = inDir;
|
||||
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 {
|
||||
QString stashfile = dir + QLatin1String("/.qmake.stash");
|
||||
if (dir == (!superdir.isEmpty() ? superdir : m_buildRoot) || m_vfs->exists(stashfile)) {
|
||||
|
||||
@@ -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::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_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_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'}
|
||||
|
||||
@@ -30,12 +30,6 @@
|
||||
import __builtin__
|
||||
import re
|
||||
|
||||
processExited = False
|
||||
|
||||
def __handleProcessExited__(*args):
|
||||
global processExited
|
||||
processExited = True
|
||||
|
||||
def openQmakeProject(projectPath, targets=Targets.desktopTargetClasses(), fromWelcome=False):
|
||||
cleanUpUserFiles(projectPath)
|
||||
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))
|
||||
return checkedTargets
|
||||
|
||||
def waitForProcessStarted():
|
||||
def waitForProcessRunning(running=True):
|
||||
outputButton = waitForObject(":Qt Creator_AppOutput_Core::Internal::OutputPaneToggleButton")
|
||||
if not waitFor("outputButton.checked", 10000):
|
||||
ensureChecked(outputButton)
|
||||
@@ -391,7 +385,7 @@ def waitForProcessStarted():
|
||||
reRunButton = findObject(":Qt Creator.ReRun_QToolButton")
|
||||
waitFor("object.exists(':Qt Creator.Stop_QToolButton')", 20000)
|
||||
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
|
||||
# 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)
|
||||
# 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):
|
||||
global processExited
|
||||
processExited = False
|
||||
overrideInstallLazySignalHandler()
|
||||
installLazySignalHandler("{type='QProcess'}", "finished(int,QProcess::ExitStatus)", "__handleProcessExited__")
|
||||
runButton = waitForObject(":*Qt Creator.Run_Core::Internal::FancyToolButton")
|
||||
clickButton(runButton)
|
||||
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")
|
||||
invokeMenuItem("File", "Exit")
|
||||
return False
|
||||
if not waitForProcessStarted():
|
||||
if not waitForProcessRunning():
|
||||
test.fatal("Couldn't start application - leaving test")
|
||||
invokeMenuItem("File", "Exit")
|
||||
return False
|
||||
@@ -466,7 +456,6 @@ def __closeSubprocessByPushingStop__(sType):
|
||||
test.fatal("Subprocess does not seem to have been started.")
|
||||
|
||||
def __closeSubprocessByHookingInto__(executable, port, function, sType, userDefType):
|
||||
global processExited
|
||||
ensureChecked(":Qt Creator_AppOutput_Core::Internal::OutputPaneToggleButton")
|
||||
output = waitForObject("{type='Core::OutputWindow' visible='1' windowTitle='Application Output Window'}")
|
||||
if port == None:
|
||||
@@ -495,7 +484,7 @@ def __closeSubprocessByHookingInto__(executable, port, function, sType, userDefT
|
||||
switchViewTo(ViewConstants.EDIT)
|
||||
runButton = waitForObject(":*Qt Creator.Run_Core::Internal::FancyToolButton")
|
||||
clickButton(runButton)
|
||||
if not waitForProcessStarted():
|
||||
if not waitForProcessRunning():
|
||||
test.fatal("Something seems to be really wrong.", "Application output:"
|
||||
% str(output.plainText))
|
||||
return False
|
||||
@@ -522,11 +511,10 @@ def __closeSubprocessByHookingInto__(executable, port, function, sType, userDefT
|
||||
"Using fallback of pushing STOP inside Creator.")
|
||||
resetApplicationContextToCreator()
|
||||
__closeSubprocessByPushingStop__(sType)
|
||||
waitFor("processExited==True and 'exited with code' in str(output.plainText)", 10000)
|
||||
if not processExited:
|
||||
resetApplicationContextToCreator()
|
||||
if not waitForProcessRunning(False) and waitFor("'exited with code' in str(output.plainText)", 10000):
|
||||
test.warning("Sub-process seems not to have closed properly.")
|
||||
try:
|
||||
resetApplicationContextToCreator()
|
||||
__closeSubprocessByPushingStop__(sType)
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -299,6 +299,13 @@ def invokeContextMenuOnProject(projectName, menuItem):
|
||||
return
|
||||
openItemContextMenu(waitForObject(":Qt Creator_Utils::NavigationTreeView"),
|
||||
str(projItem.text).replace("_", "\\_").replace(".", "\\."), 5, 5, 0)
|
||||
# Hack for Squish 5.0.1 handling menus of Qt5.2 on Mac (avoids crash) - remove asap
|
||||
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
|
||||
|
||||
@@ -34,7 +34,8 @@ source("../../shared/suites_qtta.py")
|
||||
def main():
|
||||
# expected error texts - for different compilers
|
||||
expectedErrorAlternatives = ["'SyntaxError' was not declared in this scope",
|
||||
"'SyntaxError' : undeclared identifier"]
|
||||
"'SyntaxError' : undeclared identifier",
|
||||
"use of undeclared identifier 'SyntaxError'"]
|
||||
startApplication("qtcreator" + SettingsPath)
|
||||
if not startedWithoutPluginError():
|
||||
return
|
||||
|
||||
@@ -88,8 +88,11 @@ def __handleAppOutputWaitForDebuggerFinish__():
|
||||
ensureChecked(":Qt Creator_AppOutput_Core::Internal::OutputPaneToggleButton")
|
||||
appOutput = waitForObject("{type='Core::OutputWindow' visible='1' "
|
||||
"windowTitle='Application Output Window'}")
|
||||
test.verify(waitFor("str(appOutput.plainText).endswith('Debugging has finished')", 20000),
|
||||
"Verifying whether debugging has finished.")
|
||||
if not test.verify(waitFor("str(appOutput.plainText).endswith('Debugging has finished')", 20000),
|
||||
"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):
|
||||
# for checking if it's a plain C application (as project names are set to match project type)
|
||||
|
||||
@@ -216,6 +216,10 @@ def __getExpectedDebuggers__():
|
||||
result.extend(__getCDB__())
|
||||
debuggers = ["gdb", "lldb"]
|
||||
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
|
||||
|
||||
def __getCDB__():
|
||||
|
||||
@@ -87,9 +87,6 @@ def renameFile(projectDir, proFile, branch, oldname, newname):
|
||||
type(waitForObject(":Qt Creator_Utils::NavigationTreeView::QExpandingLineEdit"), "<Return>")
|
||||
test.verify(waitFor("os.path.exists(newFilePath)", 1000),
|
||||
"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,
|
||||
"Comparing content of file before and after renaming")
|
||||
test.verify(waitFor("newname in safeReadFile(proFile)", 2000),
|
||||
@@ -97,6 +94,9 @@ def renameFile(projectDir, proFile, branch, oldname, newname):
|
||||
if not oldname in newname:
|
||||
test.verify(not oldname in readFile(proFile),
|
||||
"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):
|
||||
text = ""
|
||||
|
||||
@@ -36,7 +36,7 @@ def verifyCloneLog(targetDir, canceled):
|
||||
# Expect fails because of QTCREATORBUG-10531
|
||||
cloneLog = waitForObject(":Git Repository Clone.logPlainTextEdit_QPlainTextEdit")
|
||||
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)),
|
||||
"Searching for target directory in clone log")
|
||||
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)),
|
||||
"Searching for result (%s) in clone log:\n%s"
|
||||
% (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):
|
||||
for file in [".gitignore", "CMakeLists.txt", "jom.pro",
|
||||
@@ -84,9 +86,12 @@ def main():
|
||||
test.compare(cloneDirEdit.text, "p-qt-labs-jom")
|
||||
replaceEditorContent(cloneDirEdit, cloneDir)
|
||||
clickButton(waitForObject(":Next_QPushButton"))
|
||||
cloneLog = findObject(":Git Repository Clone.logPlainTextEdit_QPlainTextEdit")
|
||||
test.compare(waitForObject(":Git Repository Clone.Result._QLabel").text,
|
||||
"Cloning started...")
|
||||
if button == "Cancel immediately":
|
||||
# wait for cloning to have started
|
||||
waitFor('len(str(cloneLog.plainText)) > 20 + len(cloneDir)')
|
||||
clickButton(":Git Repository Clone.Cancel_QPushButton")
|
||||
verifyCloneLog(targetDir, True)
|
||||
clickButton(":Git Repository Clone.Cancel_QPushButton")
|
||||
|
||||
@@ -51,6 +51,66 @@ def verifyItemsInGit(commitMessages):
|
||||
verifyItemOrder(commitMessages, 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():
|
||||
startApplication("qtcreator" + SettingsPath)
|
||||
if not startedWithoutPluginError():
|
||||
@@ -97,6 +157,9 @@ def main():
|
||||
|
||||
invokeMenuItem("Tools", "Git", "Local Repository", "Log")
|
||||
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", "Exit")
|
||||
|
||||
Reference in New Issue
Block a user