[OpenDocString] kdeconnect-kde (cpp)
kcm.cpp
static QString createId()
{
    return QStringLiteral("kcm") + QString::number(QCoreApplication::applicationPid());
}
Returns a QString object that represents the id of the application.
KdeConnectKcm::KdeConnectKcm(QWidget *parent, const QVariantList &args)
    : KCModule(parent)
    , kcmUi(new Ui::KdeConnectKcmUi())
    , daemon(new DaemonDbusInterface(this))
    , devicesModel(new DevicesModel(this))
    , currentDevice(nullptr)
{
    KAboutData *about = new KAboutData(QStringLiteral("kdeconnect-kcm"),
                                       i18n("KDE Connect Settings"),
                                       QStringLiteral(KDECONNECT_VERSION_STRING),
                                       i18n("KDE Connect Settings module"),
                                       KAboutLicense::KAboutLicense::GPL_V2,
                                       i18n("(C) 2015 Albert Vaca Cintora"),
                                       QString(),
                                       QStringLiteral("https://community.kde.org/KDEConnect"));
    about->addAuthor(i18n("Albert Vaca Cintora"));
    about->setProgramLogo(QIcon(QStringLiteral(":/icons/kdeconnect/kdeconnect.svg")));

    setAboutData(about);

#ifdef Q_OS_WIN
    KColorSchemeManager manager;
    QApplication::setStyle(QStringLiteral("breeze"));
#endif

    kcmUi->setupUi(this);

    sortProxyModel = new DevicesSortProxyModel(devicesModel);

    kcmUi->deviceList->setModel(sortProxyModel);

    kcmUi->deviceInfo->setVisible(false);
    kcmUi->progressBar->setVisible(false);
    kcmUi->messages->setVisible(false);

    // Workaround: If we set this directly (or if we set it in the .ui file), the layout breaks
    kcmUi->noDeviceLinks->setWordWrap(false);
    QTimer::singleShot(0, this, [this] {
        kcmUi->noDeviceLinks->setWordWrap(true);
    });

    setWhenAvailable(
        daemon->announcedName(),
        [this](const QString &announcedName) {
            kcmUi->rename_label->setText(announcedName);
            kcmUi->rename_edit->setText(announcedName);
        },
        this);
    connect(daemon, SIGNAL(announcedNameChanged(QString)), kcmUi->rename_edit, SLOT(setText(QString)));
    connect(daemon, SIGNAL(announcedNameChanged(QString)), kcmUi->rename_label, SLOT(setText(QString)));
    setRenameMode(false);

    setButtons(KCModule::Help | KCModule::NoAdditionalButton);

    connect(devicesModel, &QAbstractItemModel::dataChanged, this, &KdeConnectKcm::resetSelection);
    connect(kcmUi->deviceList->selectionModel(), &QItemSelectionModel::currentChanged, this, &KdeConnectKcm::deviceSelected);
    connect(kcmUi->accept_button, &QAbstractButton::clicked, this, &KdeConnectKcm::acceptPairing);
    connect(kcmUi->reject_button, &QAbstractButton::clicked, this, &KdeConnectKcm::rejectPairing);
    connect(kcmUi->pair_button, &QAbstractButton::clicked, this, &KdeConnectKcm::requestPair);
    connect(kcmUi->unpair_button, &QAbstractButton::clicked, this, &KdeConnectKcm::unpair);
    connect(kcmUi->ping_button, &QAbstractButton::clicked, this, &KdeConnectKcm::sendPing);
    connect(kcmUi->refresh_button, &QAbstractButton::clicked, this, &KdeConnectKcm::refresh);
    connect(kcmUi->rename_edit, &QLineEdit::returnPressed, this, &KdeConnectKcm::renameDone);
    connect(kcmUi->renameDone_button, &QAbstractButton::clicked, this, &KdeConnectKcm::renameDone);
    connect(kcmUi->renameShow_button, &QAbstractButton::clicked, this, &KdeConnectKcm::renameShow);

    daemon->acquireDiscoveryMode(createId());

#if KCMUTILS_VERSION >= QT_VERSION_CHECK(5, 45, 0)

    if (!args.isEmpty() && args.first().type() == QVariant::String) {
        const QString input = args.first().toString();
        const auto colonIdx = input.indexOf(QLatin1Char(':'));
        const QString deviceId = input.left(colonIdx);
        const QString pluginCM = colonIdx < 0 ? QString() : input.mid(colonIdx + 1);

        connect(devicesModel, &DevicesModel::rowsInserted, this, [this, deviceId, pluginCM]() {
            auto row = devicesModel->rowForDevice(deviceId);
            if (row >= 0) {
                const QModelIndex idx = sortProxyModel->mapFromSource(devicesModel->index(row));
                kcmUi->deviceList->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect);
            }
            if (!pluginCM.isEmpty()) {
                kcmUi->pluginSelector->showConfiguration(pluginCM);
            }
            disconnect(devicesModel, &DevicesModel::rowsInserted, this, nullptr);
        });
    }

#endif
}
This constructor builds a KdeConnectKcm object and its dll-attached components. It takes the args of the constructor and sets up signal/slot connections for controlling the UI, sets up mouse events, sets up mouse button and mouse button clicks, and sets up mouse button bindings, as well as UI settings for the module.
void KdeConnectKcm::renameShow()
{
    setRenameMode(true);
}
This sets the rename mode to show.
void KdeConnectKcm::renameDone()
{
    QString newName = kcmUi->rename_edit->text();
    if (newName.isEmpty()) {
        // Rollback changes
        kcmUi->rename_edit->setText(kcmUi->rename_label->text());
    } else {
        kcmUi->rename_label->setText(newName);
        daemon->setAnnouncedName(newName);
    }
    setRenameMode(false);
}
This sets the rename mode to false and updates the label and the edit text. If the new name is empty, it rolls back the changes.
void KdeConnectKcm::setRenameMode(bool b)
{
    kcmUi->renameDone_button->setVisible(b);
    kcmUi->rename_edit->setVisible(b);
    kcmUi->renameShow_button->setVisible(!b);
    kcmUi->rename_label->setVisible(!b);
}
Sets whether the rename mode is visible. First it sets the done button and the edit button and the label. Then it sets the visible state of the edit button and the label.
KdeConnectKcm::~KdeConnectKcm()
{
    daemon->releaseDiscoveryMode(createId());
    delete kcmUi;
}
This removes the discovery mode object upon destruction.
void KdeConnectKcm::refresh()
{
    daemon->acquireDiscoveryMode(createId());
    daemon->forceOnNetworkChange();
}
This refreshes the discovery mode of the KdeConnectKcm object. It acquires the discovery mode and forces a network change.
void KdeConnectKcm::resetSelection()
{
    if (!currentDevice) {
        return;
    }
    kcmUi->deviceList->selectionModel()->setCurrentIndex(sortProxyModel->mapFromSource(currentIndex), QItemSelectionModel::ClearAndSelect);
}
Resets the selection of the current device to its original state.
void KdeConnectKcm::deviceSelected(const QModelIndex ¤t)
{
    if (currentDevice) {
        disconnect(currentDevice, 0, this, 0);
    }

    if (!current.isValid()) {
        currentDevice = nullptr;
        kcmUi->deviceInfo->setVisible(false);
        return;
    }

    currentIndex = sortProxyModel->mapToSource(current);
    currentDevice = devicesModel->getDevice(currentIndex.row());

    kcmUi->noDevicePlaceholder->setVisible(false);
    bool valid = (currentDevice != nullptr && currentDevice->isValid());
    kcmUi->deviceInfo->setVisible(valid);
    if (!valid) {
        return;
    }

    kcmUi->messages->setVisible(false);
    resetDeviceView();

    connect(currentDevice, SIGNAL(pluginsChanged()), this, SLOT(resetCurrentDevice()));
    connect(currentDevice, SIGNAL(trustedChanged(bool)), this, SLOT(trustedChanged(bool)));
    connect(currentDevice, SIGNAL(pairingError(QString)), this, SLOT(pairingFailed(QString)));
    connect(currentDevice, &DeviceDbusInterface::hasPairingRequestsChangedProxy, this, &KdeConnectKcm::currentDevicePairingChanged);
}
This sets the current device to visible and resets the device view, if it is valid. It sets the currentIndex and currentDevice placeholder to false, and sets the currentDevice to visible and sets the messages visible and active to false. Finally, it connects the signal 'pairingError', and 'hasPairingRequestsChangedProxy', to the device pairingChangedProxy.
void KdeConnectKcm::currentDevicePairingChanged(bool pairing)
{
    if (pairing) {
        setCurrentDeviceTrusted(RequestedByPeer);
    } else {
        setWhenAvailable(
            currentDevice->isTrusted(),
            [this](bool trusted) {
                setCurrentDeviceTrusted(trusted ? Trusted : NotTrusted);
            },
            this);
    }
}
This sets the current device trusted state if pairing is true, otherwise it sets the current device trusted state to trusted. Then it sets the signal to emit this signal to tell that the device is trusted.
void KdeConnectKcm::resetCurrentDevice()
{
    const QStringList supportedPluginNames = currentDevice->supportedPlugins();

    if (m_oldSupportedPluginNames != supportedPluginNames) {
        resetDeviceView();
    }
}
This resets the device view to its original state if the list of supported plugins differs.
void KdeConnectKcm::resetDeviceView()
{
    kcmUi->verificationKey->setText(i18n("Key: %1", QString::fromUtf8(currentDevice->verificationKey())));

    kcmUi->name_label->setText(currentDevice->name());
    setWhenAvailable(
        currentDevice->isTrusted(),
        [this](bool trusted) {
            if (trusted)
                setCurrentDeviceTrusted(Trusted);
            else
                setWhenAvailable(
                    currentDevice->hasPairingRequests(),
                    [this](bool haspr) {
                        setCurrentDeviceTrusted(haspr ? RequestedByPeer : NotTrusted);
                    },
                    this);
        },
        this);

    const QVector pluginInfo = KPluginMetaData::findPlugins(QStringLiteral("kdeconnect/"));
    QVector availablePluginInfo;

    m_oldSupportedPluginNames = currentDevice->supportedPlugins();
    for (auto it = pluginInfo.cbegin(), itEnd = pluginInfo.cend(); it != itEnd; ++it) {
        if (m_oldSupportedPluginNames.contains(it->pluginId())) {
            availablePluginInfo.append(*it);
        }
    }

    KSharedConfigPtr deviceConfig = KSharedConfig::openConfig(currentDevice->pluginsConfigFile());
    kcmUi->pluginSelector->clear();
    kcmUi->pluginSelector->setConfigurationArguments(QStringList(currentDevice->id()));
    kcmUi->pluginSelector->addPlugins(availablePluginInfo, i18n("Available plugins"));
    kcmUi->pluginSelector->setConfig(deviceConfig->group("Plugins"));
    connect(kcmUi->pluginSelector, &KPluginWidget::changed, this, &KdeConnectKcm::pluginsConfigChanged);
}
This resets the device view to its initial state. It first sets the verification key, the device name, and if it is trusted, it sets the current device trusted state, and if it has pairing requests, it requests by peer. Next, it iterates over the available plugins and adds them to the device config. Then, it connects the plugin selector and the configuration arguments to the signal 'changed'.
void KdeConnectKcm::requestPair()
{
    if (!currentDevice) {
        return;
    }

    kcmUi->messages->hide();

    setCurrentDeviceTrusted(Requested);

    currentDevice->requestPair();
}
This requests that the device be trusted. It shows the messages buffer and sets the current device trusted to Requested.
void KdeConnectKcm::unpair()
{
    if (!currentDevice) {
        return;
    }

    setCurrentDeviceTrusted(NotTrusted);
    currentDevice->unpair();
}
This removes the pairing information for the current device. If the current device is not trusted, it is ignored.
void KdeConnectKcm::acceptPairing()
{
    if (!currentDevice) {
        return;
    }

    currentDevice->acceptPairing();
}
This sets the accept pairing flag on the current device. It checks if the current device is available. If it is not the first device it checks if the current device is there. Then it sets the flag on the currentDevice object.
void KdeConnectKcm::rejectPairing()
{
    if (!currentDevice) {
        return;
    }

    currentDevice->rejectPairing();
}
This sets the reject pairing flag on the current device.
void KdeConnectKcm::pairingFailed(const QString &error)
{
    if (sender() != currentDevice)
        return;

    setCurrentDeviceTrusted(NotTrusted);

    kcmUi->messages->setText(i18n("Error trying to pair: %1", error));
    kcmUi->messages->animatedShow();
}
This sets the device to not trusted and shows an error message.
void KdeConnectKcm::trustedChanged(bool trusted)
{
    DeviceDbusInterface *senderDevice = (DeviceDbusInterface *)sender();
    if (senderDevice == currentDevice)
        setCurrentDeviceTrusted(trusted ? Trusted : NotTrusted);
}
Sets the trusted state of the device based on the changes in the trusted state. If the sender device is the current device, the function sets the current device trusted to trusted if the sender device is the same as the current device, otherwise it sets the current device to not trusted.
void KdeConnectKcm::setCurrentDeviceTrusted(KdeConnectKcm::TrustStatus trusted)
{
    kcmUi->accept_button->setVisible(trusted == RequestedByPeer);
    kcmUi->reject_button->setVisible(trusted == RequestedByPeer);
    kcmUi->pair_button->setVisible(trusted == NotTrusted);
    kcmUi->unpair_button->setVisible(trusted == Trusted);
    kcmUi->progressBar->setVisible(trusted == Requested);
    kcmUi->ping_button->setVisible(trusted == Trusted);
    switch (trusted) {
    case Trusted:
        kcmUi->status_label->setText(i18n("(paired)"));
        break;
    case NotTrusted:
        kcmUi->status_label->setText(i18n("(not paired)"));
        break;
    case RequestedByPeer:
        kcmUi->status_label->setText(i18n("(incoming pair request)"));
        break;
    case Requested:
        kcmUi->status_label->setText(i18n("(pairing requested)"));
        break;
    }
}
Sets the visibility of the buttons based on the current trusted state.
void KdeConnectKcm::pluginsConfigChanged()
{
    // Store previous selection
    if (!currentDevice)
        return;

    kcmUi->pluginSelector->save();
    currentDevice->reloadPlugins();
}
This saves the plugins configuration to the plugin selector and reloads the plugins if the device is not active. It makes sure the plugin selector is persisted before calling this function. Then it reloads the plugins after the config has changed.
void KdeConnectKcm::save()
{
    KCModule::save();
}
This saves the state of the KdeConnectKcm object to the persistent storage.
void KdeConnectKcm::sendPing()
{
    if (!currentDevice)
        return;
    currentDevice->pluginCall(QStringLiteral("ping"), QStringLiteral("sendPing"));
}
Sends a ping signal to the current device.
QSize KdeConnectKcm::sizeHint() const
{
    return QSize(890, 550); // Golden ratio :D
}
Returns the size hinted in bytes.
QSize KdeConnectKcm::minimumSizeHint() const
{
    return QSize(500, 300);
}
Returns a minimum size hint that can be used to determine the minimum size for a window.