forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/3.1'
Conflicts: qbs/imports/QtcTool.qbs src/plugins/git/giteditor.cpp src/plugins/qmldesigner/qmldesignerplugin.cpp Change-Id: Icafd32f713effb1479480a0d1f61a01e429fbec0
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import qbs.base 1.0
|
||||
import qbs 1.0
|
||||
|
||||
import QtcPlugin
|
||||
|
||||
|
||||
@@ -114,10 +114,12 @@ void AndroidAnalyzeSupport::handleRemoteOutput(const QByteArray &output)
|
||||
|
||||
void AndroidAnalyzeSupport::handleRemoteErrorOutput(const QByteArray &output)
|
||||
{
|
||||
const QString msg = QString::fromUtf8(output);
|
||||
if (m_runControl)
|
||||
m_runControl->logApplicationMessage(QString::fromUtf8(output), Utils::StdErrFormatSameLine);
|
||||
m_runControl->logApplicationMessage(msg, Utils::StdErrFormatSameLine);
|
||||
else
|
||||
AndroidRunSupport::handleRemoteErrorOutput(output);
|
||||
m_outputParser.processOutput(msg);
|
||||
}
|
||||
|
||||
void AndroidAnalyzeSupport::remoteIsRunning()
|
||||
|
||||
@@ -574,7 +574,9 @@ QVector<AndroidDeviceInfo> AndroidConfig::androidVirtualDevices() const
|
||||
break;
|
||||
if (line.contains(QLatin1String("Target:")))
|
||||
dev.sdk = line.mid(line.lastIndexOf(QLatin1Char(' '))).remove(QLatin1Char(')')).toInt();
|
||||
if (line.contains(QLatin1String("ABI:")))
|
||||
if (line.contains(QLatin1String("Tag/ABI:")))
|
||||
dev.cpuAbi = QStringList() << line.mid(line.lastIndexOf(QLatin1Char('/')) +1);
|
||||
else if (line.contains(QLatin1String("ABI:")))
|
||||
dev.cpuAbi = QStringList() << line.mid(line.lastIndexOf(QLatin1Char(' '))).trimmed();
|
||||
}
|
||||
// armeabi-v7a devices can also run armeabi code
|
||||
@@ -884,8 +886,9 @@ void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs)
|
||||
m_instance->m_config = devConfigs;
|
||||
|
||||
m_instance->save();
|
||||
m_instance->updateAutomaticKitList();
|
||||
m_instance->updateAndroidDevice();
|
||||
m_instance->updateToolChainList();
|
||||
m_instance->updateAutomaticKitList();
|
||||
emit m_instance->updated();
|
||||
}
|
||||
|
||||
@@ -944,6 +947,32 @@ static bool equalKits(Kit *a, Kit *b)
|
||||
&& QtSupport::QtKitInformation::qtVersion(a) == QtSupport::QtKitInformation::qtVersion(b);
|
||||
}
|
||||
|
||||
void AndroidConfigurations::updateToolChainList()
|
||||
{
|
||||
QList<ToolChain *> existingToolChains = ToolChainManager::toolChains();
|
||||
QList<ToolChain *> toolchains = AndroidToolChainFactory::createToolChainsForNdk(AndroidConfigurations::currentConfig().ndkLocation());
|
||||
foreach (ToolChain *tc, toolchains) {
|
||||
bool found = false;
|
||||
for (int i = 0; i < existingToolChains.count(); ++i) {
|
||||
if (*(existingToolChains.at(i)) == *tc) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
delete tc;
|
||||
else
|
||||
ToolChainManager::registerToolChain(tc);
|
||||
}
|
||||
|
||||
foreach (ToolChain *tc, existingToolChains) {
|
||||
if (tc->type() == QLatin1String(Constants::ANDROID_TOOLCHAIN_TYPE)) {
|
||||
if (!tc->isValid())
|
||||
ToolChainManager::deregisterToolChain(tc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidConfigurations::updateAutomaticKitList()
|
||||
{
|
||||
QList<AndroidToolChain *> toolchains;
|
||||
|
||||
@@ -185,6 +185,7 @@ public:
|
||||
static QString defaultDevice(ProjectExplorer::Project *project, const QString &abi); // serial number or avd name
|
||||
public slots:
|
||||
static void clearDefaultDevices(ProjectExplorer::Project *project);
|
||||
static void updateToolChainList();
|
||||
static void updateAutomaticKitList();
|
||||
|
||||
signals:
|
||||
|
||||
@@ -248,7 +248,7 @@
|
||||
<item>
|
||||
<widget class="QRadioButton" name="ministroOption">
|
||||
<property name="toolTip">
|
||||
<string>Use the external Ministro application to download and maintain Qt libraries.</string>
|
||||
<string>Uses the external Ministro application to download and maintain Qt libraries.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use Ministro service to install Qt</string>
|
||||
@@ -261,7 +261,7 @@
|
||||
<item>
|
||||
<widget class="QRadioButton" name="temporaryQtOption">
|
||||
<property name="toolTip">
|
||||
<string>Push local Qt libraries to device. You must have Qt libraries compiled for that platform.
|
||||
<string>Pushes local Qt libraries to device. You must have Qt libraries compiled for that platform.
|
||||
The APK will not be usable on any other device.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<item>
|
||||
<widget class="QRadioButton" name="ministroOption">
|
||||
<property name="toolTip">
|
||||
<string>Use the external Ministro application to download and maintain Qt libraries.</string>
|
||||
<string>Uses the external Ministro application to download and maintain Qt libraries.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use Ministro service to install Qt</string>
|
||||
@@ -42,7 +42,7 @@
|
||||
<item>
|
||||
<widget class="QRadioButton" name="temporaryQtOption">
|
||||
<property name="toolTip">
|
||||
<string>Push local Qt libraries to device. You must have Qt libraries compiled for that platform.
|
||||
<string>Pushes local Qt libraries to device. You must have Qt libraries compiled for that platform.
|
||||
The APK will not be usable on any other device.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include <QPainter>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QToolTip>
|
||||
|
||||
using namespace Android;
|
||||
using namespace Android::Internal;
|
||||
@@ -386,6 +387,17 @@ AndroidDeviceDialog::AndroidDeviceDialog(int apiLevel, const QString &abi, QWidg
|
||||
|
||||
m_ui->defaultDeviceCheckBox->setText(tr("Always use this device for architecture %1").arg(abi));
|
||||
|
||||
m_ui->noDeviceFoundLabel->setText(tr("<p align=\"center\"><span style=\" font-size:16pt;\">"
|
||||
"No Device Found</span></p>"
|
||||
"<br/>"
|
||||
"<p>Connect an Android device via USB and activate developer mode on it. "
|
||||
"Some devices require the installation of a USB driver.</p>"
|
||||
"<br/>"
|
||||
"<p>The adb tool in the Android SDK lists all connected devices if run via "adb devices".</p>"
|
||||
));
|
||||
connect(m_ui->missingLabel, SIGNAL(linkActivated(QString)),
|
||||
this, SLOT(showHelp()));
|
||||
|
||||
connect(m_ui->refreshDevicesButton, SIGNAL(clicked()),
|
||||
this, SLOT(refreshDeviceList()));
|
||||
|
||||
@@ -445,6 +457,8 @@ void AndroidDeviceDialog::refreshDeviceList()
|
||||
newIndex = m_model->indexFor(devices.first().serialNumber);
|
||||
|
||||
m_ui->deviceView->setCurrentIndex(newIndex);
|
||||
|
||||
m_ui->stackedWidget->setCurrentIndex(devices.isEmpty() ? 1 : 0);
|
||||
}
|
||||
|
||||
void AndroidDeviceDialog::createAvd()
|
||||
@@ -470,3 +484,13 @@ void AndroidDeviceDialog::clickedOnView(const QModelIndex &idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidDeviceDialog::showHelp()
|
||||
{
|
||||
QPoint pos = m_ui->missingLabel->pos();
|
||||
pos = m_ui->missingLabel->parentWidget()->mapToGlobal(pos);
|
||||
QToolTip::showText(pos, tr("<p>Connect an Android device via USB and activate developer mode on it. "
|
||||
"Some devices require the installation of a USB driver.</p>"
|
||||
"<p>The adb tool in the Android SDK lists all connected devices if run via "adb devices".</p>"),
|
||||
this);
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ private slots:
|
||||
void refreshDeviceList();
|
||||
void createAvd();
|
||||
void clickedOnView(const QModelIndex &idx);
|
||||
void showHelp();
|
||||
private:
|
||||
AndroidDeviceModel *m_model;
|
||||
Ui::AndroidDeviceDialog *m_ui;
|
||||
|
||||
@@ -6,36 +6,29 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>618</width>
|
||||
<height>400</height>
|
||||
<width>636</width>
|
||||
<height>438</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Select Android Device</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="refreshDevicesButton">
|
||||
<property name="text">
|
||||
<string>Refresh Device List</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="createAVDButton">
|
||||
<property name="text">
|
||||
<string>Create Android Virtual Device</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="defaultDeviceCheckBox">
|
||||
<property name="text">
|
||||
<string>Always use this device for architecture %1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="createAVDButton">
|
||||
<property name="text">
|
||||
<string>Create Android Virtual Device</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@@ -45,16 +38,64 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QTreeView" name="deviceView">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>600</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="refreshDevicesButton">
|
||||
<property name="text">
|
||||
<string>Refresh Device List</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="devicesPage">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="1" column="0">
|
||||
<widget class="QTreeView" name="deviceView">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>600</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="missingLabel">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><a href="aaa"><span style=" text-decoration: underline; color:#0057ae;">My device is missing</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="noDevicesPage">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="noDeviceFoundLabel">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><br/></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include <coreplugin/documentmanager.h>
|
||||
#include <coreplugin/messagemanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/target.h>
|
||||
@@ -631,7 +632,7 @@ bool AndroidManager::createAndroidTemplatesIfNecessary(ProjectExplorer::Target *
|
||||
}
|
||||
|
||||
if (forceUpdate)
|
||||
QMessageBox::warning(0, tr("Warning"), tr("Android files have been updated automatically."));
|
||||
QMessageBox::warning(Core::ICore::dialogParent(), tr("Warning"), tr("Android files have been updated automatically."));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include <QPushButton>
|
||||
#include <QFileDialog>
|
||||
#include <QTimer>
|
||||
#include <QCheckBox>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Android;
|
||||
@@ -278,16 +279,21 @@ void AndroidManifestEditorWidget::initializePage()
|
||||
{
|
||||
QGridLayout *layout = new QGridLayout(permissionsGroupBox);
|
||||
|
||||
m_defaultPermissonsCheckBox = new QCheckBox(this);
|
||||
m_defaultPermissonsCheckBox->setText(tr("Include default permissions and features for Qt modules."));
|
||||
m_defaultPermissonsCheckBox->setTristate(true);
|
||||
layout->addWidget(m_defaultPermissonsCheckBox, 0, 0);
|
||||
|
||||
m_permissionsModel = new PermissionsModel(this);
|
||||
|
||||
m_permissionsListView = new QListView(permissionsGroupBox);
|
||||
m_permissionsListView->setModel(m_permissionsModel);
|
||||
m_permissionsListView->setMinimumSize(QSize(0, 200));
|
||||
layout->addWidget(m_permissionsListView, 0, 0, 3, 1);
|
||||
layout->addWidget(m_permissionsListView, 1, 0, 3, 1);
|
||||
|
||||
m_removePermissionButton = new QPushButton(permissionsGroupBox);
|
||||
m_removePermissionButton->setText(tr("Remove"));
|
||||
layout->addWidget(m_removePermissionButton, 0, 1);
|
||||
layout->addWidget(m_removePermissionButton, 1, 1);
|
||||
|
||||
m_permissionsComboBox = new QComboBox(permissionsGroupBox);
|
||||
m_permissionsComboBox->insertItems(0, QStringList()
|
||||
@@ -423,14 +429,17 @@ void AndroidManifestEditorWidget::initializePage()
|
||||
<< QLatin1String("android.permission.WRITE_USER_DICTIONARY")
|
||||
);
|
||||
m_permissionsComboBox->setEditable(true);
|
||||
layout->addWidget(m_permissionsComboBox, 4, 0);
|
||||
layout->addWidget(m_permissionsComboBox, 5, 0);
|
||||
|
||||
m_addPermissionButton = new QPushButton(permissionsGroupBox);
|
||||
m_addPermissionButton->setText(tr("Add"));
|
||||
layout->addWidget(m_addPermissionButton, 4, 1);
|
||||
layout->addWidget(m_addPermissionButton, 5, 1);
|
||||
|
||||
permissionsGroupBox->setLayout(layout);
|
||||
|
||||
connect(m_defaultPermissonsCheckBox, SIGNAL(stateChanged(int)),
|
||||
this, SLOT(defaultPermissionCheckBoxClicked()));
|
||||
|
||||
connect(m_addPermissionButton, SIGNAL(clicked()),
|
||||
this, SLOT(addPermission()));
|
||||
connect(m_removePermissionButton, SIGNAL(clicked()),
|
||||
@@ -791,6 +800,29 @@ void AndroidManifestEditorWidget::syncToWidgets(const QDomDocument &doc)
|
||||
m_mIconPath.clear();
|
||||
m_hIconPath.clear();
|
||||
|
||||
disconnect(m_defaultPermissonsCheckBox, SIGNAL(stateChanged(int)),
|
||||
this, SLOT(defaultPermissionCheckBoxClicked()));
|
||||
|
||||
m_defaultPermissonsCheckBox->setChecked(false);
|
||||
QDomNodeList manifestChilds = manifest.childNodes();
|
||||
bool foundPermissionComment = false;
|
||||
bool foundFeatureComment = false;
|
||||
for (int i = 0; i < manifestChilds.size(); ++i) {
|
||||
const QDomNode &child = manifestChilds.at(i);
|
||||
if (child.isComment()) {
|
||||
QDomComment comment = child.toComment();
|
||||
if (comment.data().trimmed() == QLatin1String("%%INSERT_PERMISSIONS"))
|
||||
foundPermissionComment = true;
|
||||
else if (comment.data().trimmed() == QLatin1String("%%INSERT_FEATURES"))
|
||||
foundFeatureComment = true;
|
||||
}
|
||||
}
|
||||
|
||||
m_defaultPermissonsCheckBox->setCheckState(Qt::CheckState(foundFeatureComment + foundPermissionComment));
|
||||
|
||||
connect(m_defaultPermissonsCheckBox, SIGNAL(stateChanged(int)),
|
||||
this, SLOT(defaultPermissionCheckBoxClicked()));
|
||||
|
||||
QStringList permissions;
|
||||
QDomElement permissionElem = manifest.firstChildElement(QLatin1String("uses-permission"));
|
||||
while (!permissionElem.isNull()) {
|
||||
@@ -805,53 +837,6 @@ void AndroidManifestEditorWidget::syncToWidgets(const QDomDocument &doc)
|
||||
m_dirty = false;
|
||||
}
|
||||
|
||||
void setUsesSdk(QDomDocument &doc, QDomElement &manifest, int minimumSdk, int targetSdk)
|
||||
{
|
||||
QDomElement usesSdk = manifest.firstChildElement(QLatin1String("uses-sdk"));
|
||||
if (usesSdk.isNull()) { // doesn't exist yet
|
||||
if (minimumSdk == 0 && targetSdk == 0) {
|
||||
// and doesn't need to exist
|
||||
} else {
|
||||
usesSdk = doc.createElement(QLatin1String("uses-sdk"));
|
||||
if (minimumSdk != 0)
|
||||
usesSdk.setAttribute(QLatin1String("android:minSdkVersion"), minimumSdk);
|
||||
if (targetSdk != 0)
|
||||
usesSdk.setAttribute(QLatin1String("android:targetSdkVersion"), targetSdk);
|
||||
manifest.appendChild(usesSdk);
|
||||
}
|
||||
} else {
|
||||
if (minimumSdk == 0 && targetSdk == 0) {
|
||||
// We might be able to remove the whole element
|
||||
// check if there are other attributes
|
||||
QDomNamedNodeMap usesSdkAttributes = usesSdk.attributes();
|
||||
bool keepNode = false;
|
||||
for (int i = 0; i < usesSdkAttributes.size(); ++i) {
|
||||
if (usesSdkAttributes.item(i).nodeName() != QLatin1String("android:minSdkVersion")
|
||||
&& usesSdkAttributes.item(i).nodeName() != QLatin1String("android:targetSdkVersion")) {
|
||||
keepNode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (keepNode) {
|
||||
usesSdk.removeAttribute(QLatin1String("android:minSdkVersion"));
|
||||
usesSdk.removeAttribute(QLatin1String("android:targetSdkVersion"));
|
||||
} else {
|
||||
manifest.removeChild(usesSdk);
|
||||
}
|
||||
} else {
|
||||
if (minimumSdk == 0)
|
||||
usesSdk.removeAttribute(QLatin1String("android:minSdkVersion"));
|
||||
else
|
||||
usesSdk.setAttribute(QLatin1String("android:minSdkVersion"), minimumSdk);
|
||||
|
||||
if (targetSdk == 0)
|
||||
usesSdk.removeAttribute(QLatin1String("android:targetSdkVersion"));
|
||||
else
|
||||
usesSdk.setAttribute(QLatin1String("android:targetSdkVersion"), targetSdk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int extractVersion(const QString &string)
|
||||
{
|
||||
if (!string.startsWith(QLatin1String("API")))
|
||||
@@ -868,78 +853,360 @@ int extractVersion(const QString &string)
|
||||
|
||||
void AndroidManifestEditorWidget::syncToEditor()
|
||||
{
|
||||
QDomDocument doc;
|
||||
if (!doc.setContent(m_textEditorWidget->toPlainText())) {
|
||||
// This should not happen
|
||||
updateInfoBar();
|
||||
return;
|
||||
QString result;
|
||||
QXmlStreamReader reader(m_textEditorWidget->toPlainText());
|
||||
reader.setNamespaceProcessing(false);
|
||||
QXmlStreamWriter writer(&result);
|
||||
writer.setAutoFormatting(true);
|
||||
writer.setAutoFormattingIndent(4);
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNext();
|
||||
if (reader.hasError()) {
|
||||
// This should not happen
|
||||
updateInfoBar();
|
||||
return;
|
||||
} else {
|
||||
if (reader.name() == QLatin1String("manifest"))
|
||||
parseManifest(reader, writer);
|
||||
else if (reader.isStartElement())
|
||||
parseUnknownElement(reader, writer);
|
||||
else
|
||||
writer.writeCurrentToken(reader);
|
||||
}
|
||||
}
|
||||
|
||||
QDomElement manifest = doc.documentElement();
|
||||
manifest.setAttribute(QLatin1String("package"), m_packageNameLineEdit->text());
|
||||
manifest.setAttribute(QLatin1String("android:versionCode"), m_versionCode->value());
|
||||
manifest.setAttribute(QLatin1String("android:versionName"), m_versionNameLinedit->text());
|
||||
|
||||
if (!m_appNameInStringsXml) {
|
||||
QDomElement application = manifest.firstChildElement(QLatin1String("application"));
|
||||
application.setAttribute(QLatin1String("android:label"), m_appNameLineEdit->text());
|
||||
}
|
||||
|
||||
setUsesSdk(doc, manifest, extractVersion(m_androidMinSdkVersion->currentText()),
|
||||
extractVersion(m_androidTargetSdkVersion->currentText()));
|
||||
|
||||
setAndroidAppLibName(doc, manifest.firstChildElement(QLatin1String("application"))
|
||||
.firstChildElement(QLatin1String("activity")),
|
||||
m_targetLineEdit->currentText());
|
||||
|
||||
// permissions
|
||||
QDomElement permissionElem = manifest.firstChildElement(QLatin1String("uses-permission"));
|
||||
while (!permissionElem.isNull()) {
|
||||
manifest.removeChild(permissionElem);
|
||||
permissionElem = manifest.firstChildElement(QLatin1String("uses-permission"));
|
||||
}
|
||||
|
||||
foreach (const QString &permission, m_permissionsModel->permissions()) {
|
||||
permissionElem = doc.createElement(QLatin1String("uses-permission"));
|
||||
permissionElem.setAttribute(QLatin1String("android:name"), permission);
|
||||
manifest.appendChild(permissionElem);
|
||||
}
|
||||
|
||||
bool ensureIconAttribute = !m_lIconPath.isEmpty()
|
||||
|| !m_mIconPath.isEmpty()
|
||||
|| !m_hIconPath.isEmpty();
|
||||
|
||||
if (ensureIconAttribute) {
|
||||
QDomElement applicationElem = manifest.firstChildElement(QLatin1String("application"));
|
||||
applicationElem.setAttribute(QLatin1String("android:icon"), QLatin1String("@drawable/icon"));
|
||||
}
|
||||
|
||||
|
||||
QString newText = doc.toString(4);
|
||||
if (newText == m_textEditorWidget->toPlainText())
|
||||
if (result == m_textEditorWidget->toPlainText())
|
||||
return;
|
||||
|
||||
m_textEditorWidget->setPlainText(newText);
|
||||
m_textEditorWidget->setPlainText(result);
|
||||
m_textEditorWidget->document()->setModified(true);
|
||||
|
||||
m_dirty = false;
|
||||
}
|
||||
|
||||
bool AndroidManifestEditorWidget::setAndroidAppLibName(QDomDocument document, QDomElement activity, const QString &name)
|
||||
namespace {
|
||||
QXmlStreamAttributes modifyXmlStreamAttributes(const QXmlStreamAttributes &input, const QStringList &keys,
|
||||
const QStringList values, const QStringList &remove = QStringList())
|
||||
{
|
||||
QDomElement metadataElem = activity.firstChildElement(QLatin1String("meta-data"));
|
||||
while (!metadataElem.isNull()) {
|
||||
if (metadataElem.attribute(QLatin1String("android:name")) == QLatin1String("android.app.lib_name")) {
|
||||
metadataElem.setAttribute(QLatin1String("android:value"), name);
|
||||
return true;
|
||||
}
|
||||
metadataElem = metadataElem.nextSiblingElement(QLatin1String("meta-data"));
|
||||
Q_ASSERT(keys.size() == values.size());
|
||||
QXmlStreamAttributes result;
|
||||
result.reserve(input.size());
|
||||
foreach (const QXmlStreamAttribute &attribute, input) {
|
||||
const QString &name = attribute.qualifiedName().toString();
|
||||
if (remove.contains(name))
|
||||
continue;
|
||||
int index = keys.indexOf(name);
|
||||
if (index == -1)
|
||||
result.push_back(attribute);
|
||||
else
|
||||
result.push_back(QXmlStreamAttribute(name,
|
||||
values.at(index)));
|
||||
}
|
||||
|
||||
for (int i = 0; i < keys.size(); ++i) {
|
||||
if (!result.hasAttribute(keys.at(i)))
|
||||
result.push_back(QXmlStreamAttribute(keys.at(i), values.at(i)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} // end namespace
|
||||
|
||||
void AndroidManifestEditorWidget::parseManifest(QXmlStreamReader &reader, QXmlStreamWriter &writer)
|
||||
{
|
||||
Q_ASSERT(reader.isStartElement());
|
||||
writer.writeStartElement(reader.name().toString());
|
||||
|
||||
QXmlStreamAttributes attributes = reader.attributes();
|
||||
QStringList keys = QStringList()
|
||||
<< QLatin1String("package")
|
||||
<< QLatin1String("android:versionCode")
|
||||
<< QLatin1String("android:versionName");
|
||||
QStringList values = QStringList()
|
||||
<< m_packageNameLineEdit->text()
|
||||
<< QString::number(m_versionCode->value())
|
||||
<< m_versionNameLinedit->text();
|
||||
|
||||
QXmlStreamAttributes result = modifyXmlStreamAttributes(attributes, keys, values);
|
||||
writer.writeAttributes(result);
|
||||
|
||||
QSet<QString> permissions = m_permissionsModel->permissions().toSet();
|
||||
|
||||
bool foundUsesSdk = false;
|
||||
bool foundPermissionComment = false;
|
||||
bool foundFeatureComment = false;
|
||||
reader.readNext();
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.name() == QLatin1String("application")) {
|
||||
parseApplication(reader, writer);
|
||||
} else if (reader.name() == QLatin1String("uses-sdk")) {
|
||||
parseUsesSdk(reader, writer);
|
||||
foundUsesSdk = true;
|
||||
} else if (reader.name() == QLatin1String("uses-permission")) {
|
||||
permissions.remove(parseUsesPermission(reader, writer, permissions));
|
||||
} else if (reader.isEndElement()) {
|
||||
if (!foundUsesSdk) {
|
||||
int minimumSdk = extractVersion(m_androidMinSdkVersion->currentText());
|
||||
int targetSdk = extractVersion(m_androidTargetSdkVersion->currentText());
|
||||
if (minimumSdk == 0 && targetSdk == 0) {
|
||||
// and doesn't need to exist
|
||||
} else {
|
||||
writer.writeEmptyElement(QLatin1String("uses-sdk"));
|
||||
if (minimumSdk != 0)
|
||||
writer.writeAttribute(QLatin1String("android:minSdkVersion"),
|
||||
QString::number(minimumSdk));
|
||||
if (targetSdk != 0)
|
||||
writer.writeAttribute(QLatin1String("android:targetSdkVersion"),
|
||||
QString::number(targetSdk));
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundPermissionComment && m_defaultPermissonsCheckBox->checkState() == Qt::Checked)
|
||||
writer.writeComment(QLatin1String(" %%INSERT_PERMISSIONS "));
|
||||
|
||||
if (!foundFeatureComment && m_defaultPermissonsCheckBox->checkState() == Qt::Checked)
|
||||
writer.writeComment(QLatin1String(" %%INSERT_FEATURES "));
|
||||
|
||||
if (!permissions.isEmpty()) {
|
||||
foreach (const QString &permission, permissions) {
|
||||
writer.writeEmptyElement(QLatin1String("uses-permission"));
|
||||
writer.writeAttribute(QLatin1String("android:name"), permission);
|
||||
}
|
||||
}
|
||||
|
||||
writer.writeCurrentToken(reader);
|
||||
return;
|
||||
} else if (reader.isComment()) {
|
||||
QString commentText = parseComment(reader, writer);
|
||||
if (commentText == QLatin1String("%%INSERT_PERMISSIONS"))
|
||||
foundPermissionComment = true;
|
||||
else if (commentText == QLatin1String("%%INSERT_FEATURES"))
|
||||
foundFeatureComment = true;
|
||||
} else if (reader.isStartElement()) {
|
||||
parseUnknownElement(reader, writer);
|
||||
} else {
|
||||
writer.writeCurrentToken(reader);
|
||||
}
|
||||
reader.readNext();
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidManifestEditorWidget::parseApplication(QXmlStreamReader &reader, QXmlStreamWriter &writer)
|
||||
{
|
||||
Q_ASSERT(reader.isStartElement());
|
||||
writer.writeStartElement(reader.name().toString());
|
||||
|
||||
QXmlStreamAttributes attributes = reader.attributes();
|
||||
QStringList keys;
|
||||
QStringList values;
|
||||
if (!m_appNameInStringsXml) {
|
||||
keys << QLatin1String("android:label");
|
||||
values << m_appNameLineEdit->text();
|
||||
}
|
||||
bool ensureIconAttribute = !m_lIconPath.isEmpty()
|
||||
|| !m_mIconPath.isEmpty()
|
||||
|| !m_hIconPath.isEmpty();
|
||||
if (ensureIconAttribute) {
|
||||
keys << QLatin1String("android:icon");
|
||||
values << QLatin1String("@drawable/icon");
|
||||
}
|
||||
|
||||
QXmlStreamAttributes result = modifyXmlStreamAttributes(attributes, keys, values);
|
||||
writer.writeAttributes(result);
|
||||
|
||||
reader.readNext();
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.isEndElement()) {
|
||||
writer.writeCurrentToken(reader);
|
||||
return;
|
||||
} else if (reader.isStartElement()) {
|
||||
if (reader.name() == QLatin1String("activity"))
|
||||
parseActivity(reader, writer);
|
||||
else
|
||||
parseUnknownElement(reader, writer);
|
||||
} else {
|
||||
writer.writeCurrentToken(reader);
|
||||
}
|
||||
|
||||
reader.readNext();
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidManifestEditorWidget::parseActivity(QXmlStreamReader &reader, QXmlStreamWriter &writer)
|
||||
{
|
||||
Q_ASSERT(reader.isStartElement());
|
||||
writer.writeCurrentToken(reader);
|
||||
reader.readNext();
|
||||
|
||||
bool found = false;
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.isEndElement()) {
|
||||
if (!found) {
|
||||
writer.writeEmptyElement(QLatin1String("meta-data"));
|
||||
writer.writeAttribute(QLatin1String("android:name"),
|
||||
QLatin1String("android.app.lib_name"));
|
||||
writer.writeAttribute(QLatin1String("android:value"),
|
||||
m_targetLineEdit->currentText());
|
||||
}
|
||||
writer.writeCurrentToken(reader);
|
||||
return;
|
||||
} else if (reader.isStartElement()) {
|
||||
if (reader.name() == QLatin1String("meta-data"))
|
||||
found = parseMetaData(reader, writer) || found; // ORDER MATTERS
|
||||
else
|
||||
parseUnknownElement(reader, writer);
|
||||
} else {
|
||||
writer.writeCurrentToken(reader);
|
||||
}
|
||||
reader.readNext();
|
||||
}
|
||||
}
|
||||
|
||||
bool AndroidManifestEditorWidget::parseMetaData(QXmlStreamReader &reader, QXmlStreamWriter &writer)
|
||||
{
|
||||
Q_ASSERT(reader.isStartElement());
|
||||
|
||||
bool found = false;
|
||||
QXmlStreamAttributes attributes = reader.attributes();
|
||||
QXmlStreamAttributes result;
|
||||
|
||||
if (attributes.value(QLatin1String("android:name")) == QLatin1String("android.app.lib_name")) {
|
||||
QStringList keys = QStringList() << QLatin1String("android:value");
|
||||
QStringList values = QStringList() << m_targetLineEdit->currentText();
|
||||
result = modifyXmlStreamAttributes(attributes, keys, values);
|
||||
found = true;
|
||||
} else {
|
||||
result = attributes;
|
||||
}
|
||||
|
||||
writer.writeStartElement(QLatin1String("meta-data"));
|
||||
writer.writeAttributes(result);
|
||||
|
||||
reader.readNext();
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.isEndElement()) {
|
||||
writer.writeCurrentToken(reader);
|
||||
return found;
|
||||
} else if (reader.isStartElement()) {
|
||||
parseUnknownElement(reader, writer);
|
||||
} else {
|
||||
writer.writeCurrentToken(reader);
|
||||
}
|
||||
reader.readNext();
|
||||
}
|
||||
return found; // should never be reached
|
||||
}
|
||||
|
||||
void AndroidManifestEditorWidget::parseUsesSdk(QXmlStreamReader &reader, QXmlStreamWriter & writer)
|
||||
{
|
||||
int minimumSdk = extractVersion(m_androidMinSdkVersion->currentText());
|
||||
int targetSdk = extractVersion(m_androidTargetSdkVersion->currentText());
|
||||
|
||||
QStringList keys;
|
||||
QStringList values;
|
||||
QStringList remove;
|
||||
if (minimumSdk == 0) {
|
||||
remove << QLatin1String("android:minSdkVersion");
|
||||
} else {
|
||||
keys << QLatin1String("android:minSdkVersion");
|
||||
values << QString::number(minimumSdk);
|
||||
}
|
||||
if (targetSdk == 0) {
|
||||
remove << QLatin1String("android:targetSdkVersion");
|
||||
} else {
|
||||
keys << QLatin1String("android:targetSdkVersion");
|
||||
values << QString::number(targetSdk);
|
||||
}
|
||||
|
||||
QXmlStreamAttributes result = modifyXmlStreamAttributes(reader.attributes(),
|
||||
keys, values, remove);
|
||||
bool removeUseSdk = result.isEmpty();
|
||||
if (!removeUseSdk) {
|
||||
writer.writeStartElement(reader.name().toString());
|
||||
writer.writeAttributes(result);
|
||||
}
|
||||
|
||||
reader.readNext();
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.isEndElement()) {
|
||||
if (!removeUseSdk)
|
||||
writer.writeCurrentToken(reader);
|
||||
return;
|
||||
} else {
|
||||
if (removeUseSdk) {
|
||||
removeUseSdk = false;
|
||||
writer.writeStartElement(QLatin1String("uses-sdk"));
|
||||
}
|
||||
|
||||
if (reader.isStartElement())
|
||||
parseUnknownElement(reader, writer);
|
||||
else
|
||||
writer.writeCurrentToken(reader);
|
||||
}
|
||||
reader.readNext();
|
||||
}
|
||||
}
|
||||
|
||||
QString AndroidManifestEditorWidget::parseUsesPermission(QXmlStreamReader &reader, QXmlStreamWriter &writer, const QSet<QString> permissions)
|
||||
{
|
||||
Q_ASSERT(reader.isStartElement());
|
||||
|
||||
|
||||
QString permissionName = reader.attributes().value(QLatin1String("android:name")).toString();
|
||||
bool writePermission = permissions.contains(permissionName);
|
||||
if (writePermission)
|
||||
writer.writeCurrentToken(reader);
|
||||
reader.readNext();
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.isEndElement()) {
|
||||
if (writePermission)
|
||||
writer.writeCurrentToken(reader);
|
||||
return permissionName;
|
||||
} else if (reader.isStartElement()) {
|
||||
parseUnknownElement(reader, writer);
|
||||
} else {
|
||||
writer.writeCurrentToken(reader);
|
||||
}
|
||||
reader.readNext();
|
||||
}
|
||||
return permissionName; // should not be reached
|
||||
}
|
||||
|
||||
QString AndroidManifestEditorWidget::parseComment(QXmlStreamReader &reader, QXmlStreamWriter &writer)
|
||||
{
|
||||
QString commentText = reader.text().toString().trimmed();
|
||||
if (commentText == QLatin1String("%%INSERT_PERMISSIONS")
|
||||
|| commentText == QLatin1String("%%INSERT_FEATURES")) {
|
||||
if (m_defaultPermissonsCheckBox->checkState() == Qt::Unchecked)
|
||||
return commentText;
|
||||
|
||||
writer.writeCurrentToken(reader);
|
||||
return commentText;
|
||||
}
|
||||
writer.writeCurrentToken(reader);
|
||||
return QString();
|
||||
}
|
||||
|
||||
void AndroidManifestEditorWidget::parseUnknownElement(QXmlStreamReader &reader, QXmlStreamWriter &writer)
|
||||
{
|
||||
Q_ASSERT(reader.isStartElement());
|
||||
writer.writeCurrentToken(reader);
|
||||
reader.readNext();
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.isEndElement()) {
|
||||
writer.writeCurrentToken(reader);
|
||||
return;
|
||||
} else if (reader.isStartElement()) {
|
||||
parseUnknownElement(reader, writer);
|
||||
} else {
|
||||
writer.writeCurrentToken(reader);
|
||||
}
|
||||
reader.readNext();
|
||||
}
|
||||
QDomElement elem = document.createElement(QLatin1String("meta-data"));
|
||||
elem.setAttribute(QLatin1String("android:name"), QLatin1String("android.app.lib_name"));
|
||||
elem.setAttribute(QLatin1String("android:value"), name);
|
||||
activity.appendChild(elem);
|
||||
return true;
|
||||
}
|
||||
|
||||
QString AndroidManifestEditorWidget::iconPath(const QString &baseDir, IconDPI dpi)
|
||||
@@ -1021,6 +1288,13 @@ void AndroidManifestEditorWidget::setHDPIIcon()
|
||||
setDirty(true);
|
||||
}
|
||||
|
||||
void AndroidManifestEditorWidget::defaultPermissionCheckBoxClicked()
|
||||
{
|
||||
if (m_defaultPermissonsCheckBox->checkState() == Qt::PartiallyChecked)
|
||||
m_defaultPermissonsCheckBox->setChecked(Qt::Checked);
|
||||
setDirty(true);
|
||||
}
|
||||
|
||||
void AndroidManifestEditorWidget::updateAddRemovePermissionButtons()
|
||||
{
|
||||
QStringList permissions = m_permissionsModel->permissions();
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <QTimer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QCheckBox;
|
||||
class QDomDocument;
|
||||
class QDomElement;
|
||||
class QComboBox;
|
||||
@@ -48,6 +49,8 @@ class QLineEdit;
|
||||
class QListView;
|
||||
class QSpinBox;
|
||||
class QToolButton;
|
||||
class QXmlStreamReader;
|
||||
class QXmlStreamWriter;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core { class IEditor; }
|
||||
@@ -120,6 +123,7 @@ private slots:
|
||||
void setLDPIIcon();
|
||||
void setMDPIIcon();
|
||||
void setHDPIIcon();
|
||||
void defaultPermissionCheckBoxClicked();
|
||||
void addPermission();
|
||||
void removePermission();
|
||||
void updateAddRemovePermissionButtons();
|
||||
@@ -137,7 +141,6 @@ private:
|
||||
void syncToEditor();
|
||||
|
||||
bool checkDocument(QDomDocument doc, QString *errorMessage, int *errorLine, int *errorColumn);
|
||||
bool setAndroidAppLibName(QDomDocument document, QDomElement activity, const QString &name);
|
||||
enum IconDPI { LowDPI, MediumDPI, HighDPI };
|
||||
QIcon icon(const QString &baseDir, IconDPI dpi);
|
||||
QString iconPath(const QString &baseDir, IconDPI dpi);
|
||||
@@ -147,6 +150,15 @@ private:
|
||||
void hideInfoBar();
|
||||
Q_SLOT void updateTargetComboBox();
|
||||
|
||||
void parseManifest(QXmlStreamReader &reader, QXmlStreamWriter &writer);
|
||||
void parseApplication(QXmlStreamReader &reader, QXmlStreamWriter &writer);
|
||||
void parseActivity(QXmlStreamReader &reader, QXmlStreamWriter &writer);
|
||||
bool parseMetaData(QXmlStreamReader &reader, QXmlStreamWriter &writer);
|
||||
void parseUsesSdk(QXmlStreamReader &reader, QXmlStreamWriter &writer);
|
||||
QString parseUsesPermission(QXmlStreamReader &reader, QXmlStreamWriter &writer, const QSet<QString> permissions);
|
||||
QString parseComment(QXmlStreamReader &reader, QXmlStreamWriter &writer);
|
||||
void parseUnknownElement(QXmlStreamReader &reader, QXmlStreamWriter &writer);
|
||||
|
||||
bool m_dirty; // indicates that we need to call syncToEditor()
|
||||
bool m_stayClean;
|
||||
bool m_setAppName;
|
||||
@@ -173,6 +185,7 @@ private:
|
||||
QString m_hIconPath;
|
||||
|
||||
// Permissions
|
||||
QCheckBox *m_defaultPermissonsCheckBox;
|
||||
PermissionsModel *m_permissionsModel;
|
||||
QListView *m_permissionsListView;
|
||||
QPushButton *m_addPermissionButton;
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="readInfoPushButton">
|
||||
<property name="toolTip">
|
||||
<string>Automatically check required Qt libraries from compiled application</string>
|
||||
<string>Automatically check required Qt libraries from compiled application.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Read information from application (must be compiled)</string>
|
||||
|
||||
@@ -183,6 +183,7 @@ void AndroidRunner::checkPID()
|
||||
emit remoteProcessStarted(-1, -1);
|
||||
}
|
||||
m_wasStarted = true;
|
||||
logcatReadStandardOutput();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,22 +351,17 @@ void AndroidRunner::stop()
|
||||
m_adbLogcatProcess.waitForFinished();
|
||||
}
|
||||
|
||||
void AndroidRunner::logcatReadStandardError()
|
||||
void AndroidRunner::logcatProcess(const QByteArray &text, QByteArray &buffer, bool onlyError)
|
||||
{
|
||||
emit remoteErrorOutput(m_adbLogcatProcess.readAllStandardError());
|
||||
}
|
||||
|
||||
void AndroidRunner::logcatReadStandardOutput()
|
||||
{
|
||||
QList<QByteArray> lines = m_adbLogcatProcess.readAllStandardOutput().split('\n');
|
||||
QList<QByteArray> lines = text.split('\n');
|
||||
// lines always contains at least one item
|
||||
lines[0].prepend(m_logcat);
|
||||
lines[0].prepend(buffer);
|
||||
if (!lines.last().endsWith('\n')) {
|
||||
// incomplete line
|
||||
m_logcat = lines.last();
|
||||
buffer = lines.last();
|
||||
lines.removeLast();
|
||||
} else {
|
||||
m_logcat.clear();
|
||||
buffer.clear();
|
||||
}
|
||||
|
||||
QByteArray pid(QString::fromLatin1("%1):").arg(m_processPID).toLatin1());
|
||||
@@ -375,7 +371,8 @@ void AndroidRunner::logcatReadStandardOutput()
|
||||
if (line.endsWith('\r'))
|
||||
line.chop(1);
|
||||
line.append('\n');
|
||||
if (line.startsWith("E/")
|
||||
if (onlyError || line.startsWith("F/")
|
||||
|| line.startsWith("E/")
|
||||
|| line.startsWith("D/Qt")
|
||||
|| line.startsWith("W/"))
|
||||
emit remoteErrorOutput(line);
|
||||
@@ -385,6 +382,18 @@ void AndroidRunner::logcatReadStandardOutput()
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidRunner::logcatReadStandardError()
|
||||
{
|
||||
if (m_processPID != -1)
|
||||
logcatProcess(m_adbLogcatProcess.readAllStandardError(), m_stderrBuffer, true);
|
||||
}
|
||||
|
||||
void AndroidRunner::logcatReadStandardOutput()
|
||||
{
|
||||
if (m_processPID != -1)
|
||||
logcatProcess(m_adbLogcatProcess.readAllStandardOutput(), m_stdoutBuffer, false);
|
||||
}
|
||||
|
||||
void AndroidRunner::adbKill(qint64 pid)
|
||||
{
|
||||
{
|
||||
|
||||
@@ -82,6 +82,7 @@ private:
|
||||
void forceStop();
|
||||
QByteArray runPs();
|
||||
void findPs();
|
||||
void logcatProcess(const QByteArray &text, QByteArray &buffer, bool onlyError);
|
||||
|
||||
private:
|
||||
QProcess m_adbLogcatProcess;
|
||||
@@ -89,7 +90,8 @@ private:
|
||||
bool m_wasStarted;
|
||||
int m_tries;
|
||||
|
||||
QByteArray m_logcat;
|
||||
QByteArray m_stdoutBuffer;
|
||||
QByteArray m_stderrBuffer;
|
||||
QString m_intentName;
|
||||
QString m_packageName;
|
||||
QString m_deviceSerialNumber;
|
||||
|
||||
@@ -62,31 +62,6 @@ QWidget *AndroidSettingsPage::widget()
|
||||
void AndroidSettingsPage::apply()
|
||||
{
|
||||
m_widget->saveSettings();
|
||||
|
||||
QList<ToolChain *> existingToolChains = ToolChainManager::toolChains();
|
||||
QList<ToolChain *> toolchains = AndroidToolChainFactory::createToolChainsForNdk(AndroidConfigurations::currentConfig().ndkLocation());
|
||||
foreach (ToolChain *tc, toolchains) {
|
||||
bool found = false;
|
||||
for (int i = 0; i < existingToolChains.count(); ++i) {
|
||||
if (*(existingToolChains.at(i)) == *tc) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
delete tc;
|
||||
else
|
||||
ToolChainManager::registerToolChain(tc);
|
||||
}
|
||||
|
||||
foreach (ToolChain *tc, existingToolChains) {
|
||||
if (tc->type() == QLatin1String(Constants::ANDROID_TOOLCHAIN_TYPE)) {
|
||||
if (!tc->isValid())
|
||||
ToolChainManager::deregisterToolChain(tc);
|
||||
}
|
||||
}
|
||||
|
||||
AndroidConfigurations::updateAutomaticKitList();
|
||||
}
|
||||
|
||||
void AndroidSettingsPage::finish()
|
||||
|
||||
@@ -216,7 +216,7 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
|
||||
m_javaState = NotSet;
|
||||
} else {
|
||||
Utils::FileName bin = m_androidConfig.openJDKLocation();
|
||||
bin.appendPath(QLatin1String("bin"));
|
||||
bin.appendPath(QLatin1String("bin/javac" QTC_HOST_EXE_SUFFIX));
|
||||
if (!m_androidConfig.openJDKLocation().toFileInfo().exists()
|
||||
|| !bin.toFileInfo().exists())
|
||||
m_javaState = Error;
|
||||
|
||||
@@ -95,7 +95,7 @@ void ChooseProFilePage::nodeSelected(int index)
|
||||
// ChooseDirectoryPage
|
||||
//
|
||||
ChooseDirectoryPage::ChooseDirectoryPage(CreateAndroidManifestWizard *wizard)
|
||||
: m_wizard(wizard), m_androidPackageSourceDir(0)
|
||||
: m_wizard(wizard), m_androidPackageSourceDir(0), m_complete(true)
|
||||
{
|
||||
QString androidPackageDir = m_wizard->node()->singleVariableValue(QmakeProjectManager::AndroidPackageSourceDir);
|
||||
|
||||
@@ -104,28 +104,68 @@ ChooseDirectoryPage::ChooseDirectoryPage(CreateAndroidManifestWizard *wizard)
|
||||
label->setWordWrap(true);
|
||||
fl->addRow(label);
|
||||
|
||||
m_sourceDirectoryWarning = new QLabel(this);
|
||||
m_sourceDirectoryWarning->setVisible(false);
|
||||
m_sourceDirectoryWarning->setText(tr("The Android package source directory can not be the same as the project directory."));
|
||||
m_sourceDirectoryWarning->setWordWrap(true);
|
||||
m_warningIcon = new QLabel(this);
|
||||
m_warningIcon->setVisible(false);
|
||||
m_warningIcon->setPixmap(QPixmap(QLatin1String(":/projectexplorer/images/compile_error.png")));
|
||||
m_warningIcon->setWordWrap(true);
|
||||
m_warningIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
|
||||
QHBoxLayout *hbox = new QHBoxLayout;
|
||||
hbox->addWidget(m_warningIcon);
|
||||
hbox->addWidget(m_sourceDirectoryWarning);
|
||||
hbox->setAlignment(m_warningIcon, Qt::AlignTop);
|
||||
|
||||
fl->addRow(hbox);
|
||||
|
||||
m_androidPackageSourceDir = new Utils::PathChooser(this);
|
||||
m_androidPackageSourceDir->setExpectedKind(Utils::PathChooser::Directory);
|
||||
fl->addRow(tr("Android package source directory:"), m_androidPackageSourceDir);
|
||||
|
||||
if (androidPackageDir.isEmpty()) {
|
||||
label->setText(tr("Select the Android package source directory. "
|
||||
label->setText(tr("Select the Android package source directory.\n\n"
|
||||
"The files in the Android package source directory are copied to the build directory's "
|
||||
"Android directory and the default files are overwritten."));
|
||||
|
||||
m_androidPackageSourceDir->setPath(QFileInfo(m_wizard->node()->path()).absolutePath().append(QLatin1String("/android")));
|
||||
connect(m_androidPackageSourceDir, SIGNAL(changed(QString)),
|
||||
this, SLOT(checkPackageSourceDir()));
|
||||
} else {
|
||||
label->setText(tr("The Android manifest file will be created in the ANDROID_PACKAGE_SOURCE_DIR set in the .pro file."));
|
||||
m_androidPackageSourceDir->setPath(androidPackageDir);
|
||||
m_androidPackageSourceDir->setReadOnly(true);
|
||||
}
|
||||
|
||||
|
||||
m_wizard->setDirectory(m_androidPackageSourceDir->path());
|
||||
|
||||
connect(m_androidPackageSourceDir, SIGNAL(pathChanged(QString)),
|
||||
m_wizard, SLOT(setDirectory(QString)));
|
||||
}
|
||||
|
||||
void ChooseDirectoryPage::checkPackageSourceDir()
|
||||
{
|
||||
QString projectDir = QFileInfo(m_wizard->node()->path()).absolutePath();
|
||||
QString newDir = m_androidPackageSourceDir->path();
|
||||
bool isComplete = QFileInfo(projectDir) != QFileInfo(newDir);
|
||||
|
||||
m_sourceDirectoryWarning->setVisible(!isComplete);
|
||||
m_warningIcon->setVisible(!isComplete);
|
||||
|
||||
if (isComplete != m_complete) {
|
||||
m_complete = isComplete;
|
||||
emit completeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool ChooseDirectoryPage::isComplete() const
|
||||
{
|
||||
return m_complete;
|
||||
}
|
||||
|
||||
//
|
||||
// CreateAndroidManifestWizard
|
||||
//
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace ProjectExplorer { class Target; }
|
||||
@@ -70,9 +71,16 @@ class ChooseDirectoryPage : public QWizardPage
|
||||
Q_OBJECT
|
||||
public:
|
||||
ChooseDirectoryPage(CreateAndroidManifestWizard *wizard);
|
||||
protected:
|
||||
bool isComplete() const;
|
||||
private slots:
|
||||
void checkPackageSourceDir();
|
||||
private:
|
||||
CreateAndroidManifestWizard *m_wizard;
|
||||
Utils::PathChooser *m_androidPackageSourceDir;
|
||||
QLabel *m_sourceDirectoryWarning;
|
||||
QLabel *m_warningIcon;
|
||||
bool m_complete;
|
||||
};
|
||||
|
||||
class CreateAndroidManifestWizard : public Utils::Wizard
|
||||
|
||||
Reference in New Issue
Block a user