aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/android/androidservicewidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/android/androidservicewidget.cpp')
-rw-r--r--src/plugins/android/androidservicewidget.cpp410
1 files changed, 410 insertions, 0 deletions
diff --git a/src/plugins/android/androidservicewidget.cpp b/src/plugins/android/androidservicewidget.cpp
new file mode 100644
index 0000000000..465d2e2600
--- /dev/null
+++ b/src/plugins/android/androidservicewidget.cpp
@@ -0,0 +1,410 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "androidservicewidget.h"
+#include "androidservicewidget_p.h"
+
+#include <utils/utilsicons.h>
+
+#include <QAbstractTableModel>
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <QHeaderView>
+#include <QPushButton>
+#include <QTableView>
+
+namespace Android {
+namespace Internal {
+
+bool AndroidServiceData::isValid() const
+{
+ return !m_className.isEmpty()
+ && (!m_isRunInExternalProcess || !m_externalProcessName.isEmpty())
+ && (!m_isRunInExternalLibrary || !m_externalLibName.isEmpty())
+ && (m_isRunInExternalLibrary || !m_serviceArguments.isEmpty());
+}
+
+void AndroidServiceData::setClassName(const QString &className)
+{
+ m_className = className;
+}
+
+QString AndroidServiceData::className() const
+{
+ return m_className;
+}
+
+void AndroidServiceData::setRunInExternalProcess(bool isRunInExternalProcess)
+{
+ m_isRunInExternalProcess = isRunInExternalProcess;
+ if (!m_isRunInExternalProcess) {
+ m_isRunInExternalLibrary = false;
+ m_externalProcessName.clear();
+ m_externalLibName.clear();
+ }
+}
+
+bool AndroidServiceData::isRunInExternalProcess() const
+{
+ return m_isRunInExternalProcess;
+}
+
+void AndroidServiceData::setExternalProcessName(const QString &externalProcessName)
+{
+ if (m_isRunInExternalProcess)
+ m_externalProcessName = externalProcessName;
+}
+
+QString AndroidServiceData::externalProcessName() const
+{
+ return m_externalProcessName;
+}
+
+void AndroidServiceData::setRunInExternalLibrary(bool isRunInExternalLibrary)
+{
+ if (m_isRunInExternalProcess)
+ m_isRunInExternalLibrary = isRunInExternalLibrary;
+ if (!m_isRunInExternalLibrary)
+ m_externalLibName.clear();
+ else
+ m_serviceArguments.clear();
+}
+
+bool AndroidServiceData::isRunInExternalLibrary() const
+{
+ return m_isRunInExternalLibrary;
+}
+
+void AndroidServiceData::setExternalLibraryName(const QString &externalLibraryName)
+{
+ if (m_isRunInExternalLibrary)
+ m_externalLibName = externalLibraryName;
+}
+
+QString AndroidServiceData::externalLibraryName() const
+{
+ return m_externalLibName;
+}
+
+void AndroidServiceData::setServiceArguments(const QString &serviceArguments)
+{
+ if (!m_isRunInExternalLibrary)
+ m_serviceArguments = serviceArguments;
+}
+
+QString AndroidServiceData::serviceArguments() const
+{
+ return m_serviceArguments;
+}
+
+void AndroidServiceData::setNewService(bool isNewService)
+{
+ m_isNewService = isNewService;
+}
+
+bool AndroidServiceData::isNewService() const
+{
+ return m_isNewService;
+}
+
+void AndroidServiceWidget::AndroidServiceModel::setServices(const QList<AndroidServiceData> &androidServices)
+{
+ beginResetModel();
+ m_services = androidServices;
+ endResetModel();
+}
+
+const QList<AndroidServiceData> &AndroidServiceWidget::AndroidServiceModel::services()
+{
+ return m_services;
+}
+
+void AndroidServiceWidget::AndroidServiceModel::addService()
+{
+ int rowIndex = m_services.size();
+ beginInsertRows(QModelIndex(), rowIndex, rowIndex);
+ AndroidServiceData service;
+ service.setNewService(true);
+ m_services.push_back(service);
+ endInsertRows();
+ invalidDataChanged();
+}
+
+void AndroidServiceWidget::AndroidServiceModel::removeService(int row)
+{
+ beginRemoveRows(QModelIndex(), row, row);
+ m_services.removeAt(row);
+ endRemoveRows();
+}
+
+void AndroidServiceWidget::AndroidServiceModel::servicesSaved()
+{
+ for (auto && x : m_services)
+ x.setNewService(false);
+}
+
+int AndroidServiceWidget::AndroidServiceModel::rowCount(const QModelIndex &/*parent*/) const
+{
+ return m_services.count();
+}
+
+int AndroidServiceWidget::AndroidServiceModel::columnCount(const QModelIndex &/*parent*/) const
+{
+ return 6;
+}
+
+Qt::ItemFlags AndroidServiceWidget::AndroidServiceModel::flags(const QModelIndex &index) const
+{
+ if (index.column() == 0)
+ return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
+ else if (index.column() == 1)
+ return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable;
+ else if (index.column() == 2 && index.row() <= m_services.count()) {
+ if (m_services[index.row()].isRunInExternalProcess())
+ return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
+ return Qt::ItemIsSelectable;
+ } else if (index.column() == 3 && index.row() <= m_services.count()) {
+ if (m_services[index.row()].isRunInExternalProcess())
+ return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable;
+ return Qt::ItemIsUserCheckable | Qt::ItemIsSelectable;
+ } else if (index.column() == 4 && index.row() <= m_services.count()) {
+ if (m_services[index.row()].isRunInExternalLibrary())
+ return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
+ return Qt::ItemIsSelectable;
+ } else if (index.column() == 5 && index.row() <= m_services.count()) {
+ if (!m_services[index.row()].isRunInExternalLibrary())
+ return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
+ return Qt::ItemIsSelectable;
+ }
+ return Qt::ItemIsSelectable;
+}
+
+QVariant AndroidServiceWidget::AndroidServiceModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (role == Qt::ToolTipRole && orientation == Qt::Horizontal) {
+ if (section == 0)
+ return tr("The name of the class implementing the service");
+ else if (section == 1)
+ return tr("Checked if the service is run in an external process");
+ else if (section == 2)
+ return tr("The name of the external process.\n"
+ "Prefix with : if the process is private, use a lowercase name if the process is global.");
+ else if (section == 3)
+ return tr("Checked if the service is in a separate dynamic library");
+ else if (section == 4)
+ return tr("The name of the separate dynamic library");
+ else if (section == 5)
+ return tr("The arguments for telling the app to run the service instead of the main activity");
+ } else if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
+ if (section == 0)
+ return tr("Service class name");
+ else if (section == 1)
+ return tr("Run in external process");
+ else if (section == 2)
+ return tr("Process name");
+ else if (section == 3)
+ return tr("Run in external library");
+ else if (section == 4)
+ return tr("Library name");
+ else if (section == 5)
+ return tr("Service arguments");
+ }
+ return {};
+}
+
+QVariant AndroidServiceWidget::AndroidServiceModel::data(const QModelIndex &index, int role) const
+{
+ if (!(index.row() >= 0 && index.row() < m_services.count()))
+ return {};
+ if (role == Qt::CheckStateRole) {
+ if (index.column() == 3)
+ return m_services[index.row()].isRunInExternalLibrary() ? Qt::Checked : Qt::Unchecked;
+ else if (index.column() == 1 && index.row() <= m_services.count())
+ return m_services[index.row()].isRunInExternalProcess() ? Qt::Checked : Qt::Unchecked;
+ return QVariant();
+ } else if (role == Qt::DisplayRole) {
+ if (index.column() == 0)
+ return m_services[index.row()].className();
+ else if (index.column() == 1)
+ return tr("Run in external process");
+ else if (index.column() == 2)
+ return m_services[index.row()].externalProcessName();
+ else if (index.column() == 3)
+ return tr("Run in external library");
+ else if (index.column() == 4)
+ return m_services[index.row()].externalLibraryName();
+ else if (index.column() == 5)
+ return m_services[index.row()].serviceArguments();
+ } else if (role == Qt::ToolTipRole) {
+ if (index.column() == 0 && m_services[index.row()].className().isEmpty())
+ return tr("The class name must be set");
+ else if (index.column() == 2 && m_services[index.row()].isRunInExternalProcess())
+ return tr("The process name must be set for a service run in an external process");
+ else if (index.column() == 4 && m_services[index.row()].isRunInExternalLibrary())
+ return tr("The library name must be set for a service run in an external library");
+ else if (index.column() == 5 && !m_services[index.row()].isRunInExternalLibrary())
+ return tr("The service arguments must be set for a service not run in an external library");
+ } else if (role == Qt::EditRole) {
+ if (index.column() == 0)
+ return m_services[index.row()].className();
+ else if (index.column() == 2)
+ return m_services[index.row()].externalProcessName();
+ else if (index.column() == 4)
+ return m_services[index.row()].externalLibraryName();
+ else if (index.column() == 5)
+ return m_services[index.row()].serviceArguments();
+ } else if (role == Qt::DecorationRole) {
+ if (index.column() == 0) {
+ if (m_services[index.row()].className().isEmpty())
+ return Utils::Icons::WARNING.icon();
+ } else if (index.column() == 2) {
+ if (m_services[index.row()].isRunInExternalProcess()
+ && m_services[index.row()].externalProcessName().isEmpty())
+ return Utils::Icons::WARNING.icon();
+ } else if (index.column() == 4) {
+ if (m_services[index.row()].isRunInExternalLibrary()
+ && m_services[index.row()].externalLibraryName().isEmpty())
+ return Utils::Icons::WARNING.icon();
+ } else if (index.column() == 5) {
+ if (!m_services[index.row()].isRunInExternalLibrary()
+ && m_services[index.row()].serviceArguments().isEmpty())
+ return Utils::Icons::WARNING.icon();
+ }
+ }
+ return {};
+}
+
+bool AndroidServiceWidget::AndroidServiceModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (!(index.row() >= 0 && index.row() < m_services.count()))
+ return {};
+ if (role == Qt::CheckStateRole) {
+ if (index.column() == 1)
+ m_services[index.row()].setRunInExternalProcess((value == Qt::Checked) ? true : false);
+ else if (index.column() == 3)
+ m_services[index.row()].setRunInExternalLibrary((value == Qt::Checked) ? true : false);
+ dataChanged(createIndex(index.row(), 0), createIndex(index.row(), 5));
+ if (m_services[index.row()].isValid())
+ validDataChanged();
+ else
+ invalidDataChanged();
+ } else if (role == Qt::EditRole) {
+ if (index.column() == 0) {
+ QString className = value.toString();
+ if (!className.isEmpty() && className[0] != QChar('.'))
+ className.push_front(QChar('.'));
+ m_services[index.row()].setClassName(className);
+ m_services[index.row()].setNewService(true);
+ } else if (index.column() == 2) {
+ m_services[index.row()].setExternalProcessName(value.toString());
+ } else if (index.column() == 4) {
+ m_services[index.row()].setExternalLibraryName(value.toString());
+ } else if (index.column() == 5) {
+ m_services[index.row()].setServiceArguments(value.toString());
+ }
+ dataChanged(index, index);
+ if (m_services[index.row()].isValid())
+ validDataChanged();
+ else
+ invalidDataChanged();
+ }
+ return true;
+}
+
+AndroidServiceWidget::AndroidServiceWidget(QWidget *parent) : QWidget(parent),
+ m_model(new AndroidServiceModel), m_tableView(new QTableView(this))
+{
+ m_tableView->setModel(m_model.data());
+ m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
+ QSizePolicy sizePolicy;
+ sizePolicy.setHorizontalPolicy(QSizePolicy::Expanding);
+ m_tableView->setSizePolicy(sizePolicy);
+ m_tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+ auto layout = new QHBoxLayout(this);
+ layout->addWidget(m_tableView, 1);
+ auto buttonLayout = new QGridLayout();
+ auto addButton = new QPushButton(this);
+ addButton->setText(tr("Add"));
+ buttonLayout->addWidget(addButton, 0, 0);
+ m_removeButton = new QPushButton(this);
+ m_removeButton->setText(tr("Remove"));
+ m_removeButton->setEnabled(false);
+ buttonLayout->addWidget(m_removeButton, 1, 0);
+ layout->addLayout(buttonLayout);
+ layout->setAlignment(buttonLayout, Qt::AlignTop);
+ connect(addButton, &QAbstractButton::clicked,
+ this, &AndroidServiceWidget::addService);
+ connect(m_removeButton, &QAbstractButton::clicked,
+ this, &AndroidServiceWidget::removeService);
+ connect(m_tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
+ [this](const QItemSelection &selected, const QItemSelection &/*deselected*/) {
+ if (!selected.isEmpty())
+ m_removeButton->setEnabled(true);
+ });
+ connect(m_model.data(), &AndroidServiceWidget::AndroidServiceModel::validDataChanged,
+ [this] {servicesModified();});
+ connect(m_model.data(), &AndroidServiceWidget::AndroidServiceModel::invalidDataChanged,
+ [this] {servicesInvalid();});
+}
+
+AndroidServiceWidget::~AndroidServiceWidget()
+{
+
+}
+
+void AndroidServiceWidget::setServices(const QList<AndroidServiceData> &androidServices)
+{
+ m_removeButton->setEnabled(false);
+ m_model->setServices(androidServices);
+}
+
+const QList<AndroidServiceData> &AndroidServiceWidget::services()
+{
+ return m_model->services();
+}
+
+void AndroidServiceWidget::servicesSaved()
+{
+ m_model->servicesSaved();
+}
+
+void AndroidServiceWidget::addService()
+{
+ m_model->addService();
+}
+
+void AndroidServiceWidget::removeService()
+{
+ auto selections = m_tableView->selectionModel()->selectedRows();
+ for (const auto &x : selections) {
+ m_model->removeService(x.row());
+ m_removeButton->setEnabled(false);
+ servicesModified();
+ break;
+ }
+}
+
+} // namespace Internal
+} // namespace Android