<commit_before>/*
  Q Light Controller Plus
  rdmmanager.cpp

  Copyright (c) <NAME>

  Licensed under the Apache License Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0.txt

  Unless required by applicable law or agreed to in writing software
  distributed under the License is distributed on an "AS IS" BASIS
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#include <QDebug>
#include <QMessageBox>

#include "rdmmanager.h"
#include "outputpatch.h"
#include "qlcioplugin.h"
#include "rdmprotocol.h"
#include "doc.h"

// RDM view column numbers
#define KColumnRDMModel    0
#define KColumnRDMUniverse 1
#define KColumnRDMAddress  2
#define KColumnRDMChannels 3
#define KColumnRDMUID      4

#define MAX_WAIT_COUNT  30

RDMManager::RDMManager(QWidget *parent, Doc *doc)
    : QWidget(parent)
    , m_doc(doc)
{
    setupUi(this);

    m_getInfoButton->setEnabled(false);
    m_readButton->setEnabled(false);

    connect(m_refreshButton, SIGNAL(clicked()), this, SLOT(slotRefresh()));
    connect(m_getInfoButton, SIGNAL(clicked()), this, SLOT(slotGetInfo()));
    connect(m_rdmTree, SIGNAL(itemSelectionChanged()), this, SLOT(slotSelectionChanged()));
    connect(m_readButton, SIGNAL(clicked()), this, SLOT(slotReadPID()));
    connect(m_writeButton, SIGNAL(clicked()), this, SLOT(slotWritePID()));
}

RDMManager::~RDMManager()
{
}

void RDMManager::slotRefresh()
{
    // reset any previously collected information
    m_rdmTree->clear();

    // go through every universe and launch a RDM discovery for each
    // patched plugin which supports the RDM standard
    foreach (Universe *uni, m_doc->inputOutputMap()->universes())
    {
        for (int i = 0; i < uni->outputPatchesCount(); i++)
        {
            OutputPatch *op = uni->outputPatch(i);
            if (op->plugin()->capabilities() & QLCIOPlugin::RDM)
            {
                RDMWorker *wt = new RDMWorker(m_doc);
                connect(wt, SIGNAL(uidFound(QString, UIDInfo)),
                        this, SLOT(updateRDMTreeItem(QString, UIDInfo)));
                connect(wt, SIGNAL(requestPopup(QString, QString)),
                        this, SLOT(slotDisplayPopup(QString, QString)));
                wt->runDiscovery(uni->id(), op->output());
            }
        }
    }
}

bool RDMManager::getPluginInfo(quint32 universe, quint32 line, quint32 &universeID, quint32 &outputLine)
{
    Universe *uni = m_doc->inputOutputMap()->universe(universe);
    if (uni == NULL)
    {
        qDebug() << "ERROR. Universe not found!";
        return false;
    }

    OutputPatch *op = NULL;
    for (int i = 0; i < uni->outputPatchesCount(); i++)
    {
        op = uni->outputPatch(i);
        if (op->output() == line)
            break;
    }
    if (op == NULL)
    {
        qDebug() << "ERROR. Output patch not found!";
        return false;
    }

    universeID = uni->id();
    outputLine = op->output();

    return true;
}

void RDMManager::slotGetInfo()
{
    QTreeWidgetItem *item = m_rdmTree->selectedItems().first();
    QString UID = item->text(KColumnRDMUID);
    UIDInfo info = m_uidMap.value(UID);
    quint32 uniID = 0, outLine = 0;

    if (getPluginInfo(info.universe, info.pluginLine, uniID, outLine) == false)
    {
        qDebug() << "ERROR. Cannot get plugin info";
        return;
    }

    RDMWorker *wt = new RDMWorker(m_doc);
    connect(wt, SIGNAL(fixtureInfoReady(QString&)), this, SIGNAL(fixtureInfoReady(QString&)));
    connect(wt, SIGNAL(requestPopup(QString, QString)), this, SLOT(slotDisplayPopup(QString, QString)));
    wt->getUidInfo(uniID, outLine, UID, info);
}

void RDMManager::slotReadPID()
{
    QTreeWidgetItem *item = m_rdmTree->selectedItems().first();
    QString UID = item->text(KColumnRDMUID);
    UIDInfo info = m_uidMap.value(UID);
    quint32 uniID = 0, outLine = 0;
    QVariantList params;

    if (getPluginInfo(info.universe, info.pluginLine, uniID, outLine) == false)
    {
        qDebug() << "ERROR. Cannot get plugin info";
        return;
    }

    m_pidResult->clear();

    if (m_pidArgsEdit->text().length())
    {
        QStringList argList = m_pidArgsEdit->text().split(",");
        for (int i = 0; i < argList.count(); i++)
            params.append(argList.at(i));
    }

    RDMWorker *wt = new RDMWorker(m_doc);
    connect(wt, SIGNAL(requestPopup(QString, QString)), this, SLOT(slotDisplayPopup(QString, QString)));
    connect(wt, SIGNAL(pidInfoReady(QString)), this, SLOT(slotUpdatePidInfo(QString)));
    wt->handlePID(uniID, outLine, UID, m_pidEdit->text(), params, false);
}

void RDMManager::slotWritePID()
{
    QTreeWidgetItem *item = m_rdmTree->selectedItems().first();
    QString UID = item->text(KColumnRDMUID);
    UIDInfo info = m_uidMap.value(UID);
    quint32 uniID = 0, outLine = 0;
    QVariantList params;

    if (getPluginInfo(info.universe, info.pluginLine, uniID, outLine) == false)
    {
        qDebug() << "ERROR. Cannot get plugin info";
        return;
    }

    m_pidResult->clear();

    if (m_pidArgsEdit->text().length())
    {
        QStringList argList = m_pidArgsEdit->text().split(",");

        for (int i = 0; i < argList.count(); i++)
        {
            switch(m_dataTypeCombo->currentIndex())
            {
                case ByteArg:
                    params.append(uchar(1));
                    params.append(uchar(argList.at(i).toUShort()));
                break;
                case ShortArg:
                    params.append(uchar(2));
                    params.append(argList.at(i).toShort());
                break;
                case LongArg:
                    params.append(uchar(4));
                    params.append(quint32(argList.at(i).toULong()));
                break;
                case ArrayArg:
                {
                    QByteArray ba = QByteArray::fromHex(argList.at(i).toUtf8());
                    params.append(uchar(99)); // special size for array
                    params.append(ba);
                }
                break;
            }
        }
    }

    RDMWorker *wt = new RDMWorker(m_doc);
    connect(wt, SIGNAL(requestPopup(QString, QString)), this, SLOT(slotDisplayPopup(QString, QString)));
    connect(wt, SIGNAL(pidInfoReady(QString)), this, SLOT(slotUpdatePidInfo(QString)));
    wt->handlePID(uniID, outLine, UID, m_pidEdit->text(), params, true);
}

void RDMManager::slotSelectionChanged()
{
    int selectedCount = m_rdmTree->selectedItems().size();

    m_getInfoButton->setEnabled(selectedCount ? true : false);
    m_readButton->setEnabled(selectedCount ? true : false);<commit_msg>ui: allow to enter hex params for a RDM PID<commit_after>/*
  Q Light Controller Plus
  rdmmanager.cpp

  Copyright (c) <NAME>

  Licensed under the Apache License Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0.txt

  Unless required by applicable law or agreed to in writing software
  distributed under the License is distributed on an "AS IS" BASIS
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#include <QDebug>
#include <QMessageBox>

#include "rdmmanager.h"
#include "outputpatch.h"
#include "qlcioplugin.h"
#include "rdmprotocol.h"
#include "doc.h"

// RDM view column numbers
#define KColumnRDMModel    0
#define KColumnRDMUniverse 1
#define KColumnRDMAddress  2
#define KColumnRDMChannels 3
#define KColumnRDMUID      4

#define MAX_WAIT_COUNT  30

RDMManager::RDMManager(QWidget *parent, Doc *doc)
    : QWidget(parent)
    , m_doc(doc)
{
    setupUi(this);

    m_getInfoButton->setEnabled(false);
    m_readButton->setEnabled(false);

    connect(m_refreshButton, SIGNAL(clicked()), this, SLOT(slotRefresh()));
    connect(m_getInfoButton, SIGNAL(clicked()), this, SLOT(slotGetInfo()));
    connect(m_rdmTree, SIGNAL(itemSelectionChanged()), this, SLOT(slotSelectionChanged()));
    connect(m_readButton, SIGNAL(clicked()), this, SLOT(slotReadPID()));
    connect(m_writeButton, SIGNAL(clicked()), this, SLOT(slotWritePID()));
}

RDMManager::~RDMManager()
{
}

void RDMManager::slotRefresh()
{
    // reset any previously collected information
    m_rdmTree->clear();

    // go through every universe and launch a RDM discovery for each
    // patched plugin which supports the RDM standard
    foreach (Universe *uni, m_doc->inputOutputMap()->universes())
    {
        for (int i = 0; i < uni->outputPatchesCount(); i++)
        {
            OutputPatch *op = uni->outputPatch(i);
            if (op->plugin()->capabilities() & QLCIOPlugin::RDM)
            {
                RDMWorker *wt = new RDMWorker(m_doc);
                connect(wt, SIGNAL(uidFound(QString, UIDInfo)),
                        this, SLOT(updateRDMTreeItem(QString, UIDInfo)));
                connect(wt, SIGNAL(requestPopup(QString, QString)),
                        this, SLOT(slotDisplayPopup(QString, QString)));
                wt->runDiscovery(uni->id(), op->output());
            }
        }
    }
}

bool RDMManager::getPluginInfo(quint32 universe, quint32 line, quint32 &universeID, quint32 &outputLine)
{
    Universe *uni = m_doc->inputOutputMap()->universe(universe);
    if (uni == NULL)
    {
        qDebug() << "ERROR. Universe not found!";
        return false;
    }

    OutputPatch *op = NULL;
    for (int i = 0; i < uni->outputPatchesCount(); i++)
    {
        op = uni->outputPatch(i);
        if (op->output() == line)
            break;
    }
    if (op == NULL)
    {
        qDebug() << "ERROR. Output patch not found!";
        return false;
    }

    universeID = uni->id();
    outputLine = op->output();

    return true;
}

void RDMManager::slotGetInfo()
{
    QTreeWidgetItem *item = m_rdmTree->selectedItems().first();
    QString UID = item->text(KColumnRDMUID);
    UIDInfo info = m_uidMap.value(UID);
    quint32 uniID = 0, outLine = 0;

    if (getPluginInfo(info.universe, info.pluginLine, uniID, outLine) == false)
    {
        qDebug() << "ERROR. Cannot get plugin info";
        return;
    }

    RDMWorker *wt = new RDMWorker(m_doc);
    connect(wt, SIGNAL(fixtureInfoReady(QString&)), this, SIGNAL(fixtureInfoReady(QString&)));
    connect(wt, SIGNAL(requestPopup(QString, QString)), this, SLOT(slotDisplayPopup(QString, QString)));
    wt->getUidInfo(uniID, outLine, UID, info);
}

void RDMManager::slotReadPID()
{
    QTreeWidgetItem *item = m_rdmTree->selectedItems().first();
    QString UID = item->text(KColumnRDMUID);
    UIDInfo info = m_uidMap.value(UID);
    quint32 uniID = 0, outLine = 0;
    QVariantList params;

    if (getPluginInfo(info.universe, info.pluginLine, uniID, outLine) == false)
    {
        qDebug() << "ERROR. Cannot get plugin info";
        return;
    }

    m_pidResult->clear();

    if (m_pidArgsEdit->text().length())
    {
        QStringList argList = m_pidArgsEdit->text().split(",");
        for (int i = 0; i < argList.count(); i++)
            params.append(argList.at(i));
    }

    RDMWorker *wt = new RDMWorker(m_doc);
    connect(wt, SIGNAL(requestPopup(QString, QString)), this, SLOT(slotDisplayPopup(QString, QString)));
    connect(wt, SIGNAL(pidInfoReady(QString)), this, SLOT(slotUpdatePidInfo(QString)));
    wt->handlePID(uniID, outLine, UID, m_pidEdit->text(), params, false);
}

void RDMManager::slotWritePID()
{
    QTreeWidgetItem *item = m_rdmTree->selectedItems().first();
    QString UID = item->text(KColumnRDMUID);
    UIDInfo info = m_uidMap.value(UID);
    quint32 uniID = 0, outLine = 0;
    QVariantList params;

    if (getPluginInfo(info.universe, info.pluginLine, uniID, outLine) == false)
    {
        qDebug() << "ERROR. Cannot get plugin info";
        return;
    }

    m_pidResult->clear();

    if (m_pidArgsEdit->text().length())
    {
        QStringList argList = m_pidArgsEdit->text().split(",");
        bool ok;

        for (int i = 0; i < argList.count(); i++)
        {
            QString arg = argList.at(i);

            switch(m_dataTypeCombo->currentIndex())
            {
                case ByteArg:
                    params.append(uchar(1));
                    if (arg.toLower().startsWith("0x"))
                        params.append(uchar(arg.mid(2).toUShort(&ok, 16)));
                    else
                        params.append(uchar(arg.toUShort()));
                break;
                case ShortArg:
                    params.append(uchar(2));
                    if (arg.toLower().startsWith("0x"))
                        params.append(arg.mid(2).toShort(&ok, 16));
                    else
                        params.append(arg.toShort());
                break;
                case LongArg:
                    params.append(uchar(4));
                    if (arg.toLower().startsWith("0x"))
                        params.append(quint32(arg.mid(2).toULong(&ok, 16)));
                    else
                        params.append(quint32(arg.toULong()));
                break;
                case ArrayArg:
                {
                    QByteArray ba = QByteArray::fromHex(argList.at(i).toUtf8());
                    params.append(uchar(99)); // special size for array
                    params.append(ba);
                }
                break;
            }
        }
    }

    RDMWorker *wt = new RDMWorker(m_doc);
    connect(wt, SIGNAL(requestPopup(QString, QString)), this, SLOT(slotDisplayPopup(QString, QString)));
    connect(wt, SIGNAL(pidInfoReady(QString)), this, SLOT(slotUpdatePidInfo(QString)));
    wt->handlePID(uniID, outLine, UID, m_pidEdit->text(), params, true);
}

void RDMManager::slotSelectionChanged()
{
    int selectedCount = m_rdmTree->selectedItems().size();

    m_getInfoButton->setEnabled(selectedCount ? true : false);
    m_readButton->setEnabled(selectedCount ? true : false);
{'fraction_non_alphanumeric': 0.1317845828933474, 'fraction_numerical': 0.007039774727208729, 'mean_word_length': 2.6566280566280565, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1033783', 'n_tokens_mistral': 4571, 'n_tokens_neox': 4379, 'n_words': 1002}