#include #include "ui_mainwindow.h" #include #include #include #include #include #include #include #include #include void infoMessageBox(QString text, QString title = "KYGUI") { QMessageBox box; box.setWindowTitle(title); box.setText(text); box.setButtonText(0, "Close"); box.exec(); } QString getTime() { return QDateTime::currentDateTime().toString("hh:mm:ss"); } /** * @brief MainWindow::MainWindow * @param argc * @param argv * @param parent */ MainWindow::MainWindow(int argc, char** argv, QWidget *parent) : QMainWindow(parent), cli_argc(argc), cli_argv(argv), ui(new Ui::MainWindow), arg_ui(new ArgDialog), q_client(nullptr) { m_process_model = new QStandardItemModel(this); m_event_model = new QStandardItemModel(this); q_client = new Client(this, cli_argc, cli_argv); ui->setupUi(this); this->setWindowTitle("KYGUI"); QPushButton *button = this->findChild("connect"); button->setMaximumSize(700, 900); button->setMinimumSize(700, 900); connect(button, &QPushButton::clicked, this, &MainWindow::connectClient); ui->processList->setModel(m_process_model); ui->eventList->setModel(m_event_model); } /** * @brief MainWindow::~MainWindow */ MainWindow::~MainWindow() { delete q_client; delete ui; } /** * @brief MainWindow::buttonClicked */ void MainWindow::connectClient() { ui->connect->hide(); qDebug() << "Connecting to KServer"; QObject::connect(q_client, &Client::messageReceived, this, &MainWindow::updateMessages); QObject::connect(q_client, &Client::startTimer, this, &MainWindow::startTimer); QProgressBar* progressBar = ui->progressBar; q_client->start(); for (int i = 1; i < 101; i++) { progressBar->setValue(i); } KTextEdit* send_message_box = reinterpret_cast(ui->inputText); send_message_box->show(); QPushButton* send_message_button = this->findChild("sendMessage"); // Handle mouse QObject::connect(send_message_button, &QPushButton::clicked, this, [this, send_message_box]() { QString msg = escapeText(send_message_box->toPlainText()); qDebug() << "Sending message: " << msg; q_client->sendMessage(escapeText(send_message_box->toPlainText())); send_message_box->clear(); }); QObject::connect(ui->appList, static_cast(&QComboBox::currentIndexChanged), this, [this]() { QString app_name = ui->appList->currentText(); // TODO: I know, it's awful. Fix this q_client->setSelectedApp(std::vector{{app_name}}); }); QPushButton* disconnect_button = this->findChild("disconnect"); QObject::connect(disconnect_button, &QPushButton::clicked, this, [this, progressBar]() { q_client->closeConnection(); QApplication::exit(9); }); QObject::connect(ui->execute, &QPushButton::clicked, this, [this]() { q_client->execute(); }); QObject::connect(ui->addArgs, &QPushButton::clicked, this, [this]() { if (ui->appList->count() == 0) { QMessageBox::warning(this, tr("Args"), tr("Please connect to the KServer and retrieve a list of available processes.")); } else { arg_ui->show(); } }); QObject::connect(arg_ui, &ArgDialog::uploadFiles, this, [this](QVector files) { m_timer->stop(); q_client->sendFiles(files); }); QObject::connect(arg_ui, &ArgDialog::taskRequestReady, this, [this](Task task, bool file_pending) { // TODO: Maybe this should be handled by the Client class directly auto mask = q_client->getSelectedApp(); if (mask > -1) { if (q_client->getAppName(mask) == "Instagram") { auto datetime = task.args.at(0); auto current_datetime = QDateTime::currentDateTime().toTime_t(); auto seconds_diff = std::stoi(datetime) - current_datetime; // qDebug() << "Time difference: " << seconds_diff; // if (seconds_diff > 3600) { qDebug() << "Scheduling a task"; task.args.push_back(std::to_string(mask)); q_client->scheduleTask(task.args, file_pending); // } } } }); QObject::connect(ui->tasks, &QPushButton::clicked, this, [this]() { // TODO: Change this to a complete implementation q_client->sendMessage("scheduler"); }); QObject::connect(ui->viewConsole, &QPushButton::clicked, this, [this]() { console_ui.show(); }); // TODO: Handle enter key // QObject::connect(static_cast(ui->inputText), &KTextEdit::textInputEnter, this, &MainWindow::handleInputEnterKey); QObject::connect(static_cast(ui->inputText), &KTextEdit::textInputEnter, this, &MainWindow::handleKey); QObject::connect(ui->processList, &QListView::clicked, this, [this](const QModelIndex &index) { auto process = m_processes.at(index.row()); QString process_info_text = m_processes.at(index.row()).name.toUtf8() + "\n"; process_info_text += "Execution requested at " + process.start.toUtf8() + "\n" + "Is currently in a state of: " + ProcessNames[process.state - 1].toUtf8(); if (process.end.size() > 0 || process.id == "Scheduled task") { process_info_text += "\n\nResult: \n" + process.result; } infoMessageBox(process_info_text, "Process"); }); QObject::connect(ui->eventList, &QListView::clicked, this, [this](const QModelIndex &index) { auto event = m_events.at(index.row()); infoMessageBox(event, "Event"); }); m_timer = new QTimer(this); connect(m_timer, &QTimer::timeout, q_client, &Client::ping); m_timer->start(30000); } void MainWindow::handleKey() { q_client->sendMessage(ui->inputText->toPlainText()); ui->inputText->clear(); } QString MainWindow::parseMessage(const QString& message, StringVec v) { QString simplified_message{}; if (isMessage(message.toUtf8())) { simplified_message += "Message: " + getMessage(message.toUtf8()); } else if (isEvent(message.toUtf8())) { simplified_message += "Event: " + getEvent(message.toUtf8()); } else if (isOperation(message.toUtf8())) { simplified_message += "Operation: "; simplified_message += getOperation(message.toUtf8()).c_str(); } return simplified_message; } QStandardItem* createProcessListItem(Process process) { return new QStandardItem(QString("%0 requested for execution. ID: %1\nStatus: %2\nTime: %3 Done: %4").arg(process.name).arg(process.id).arg(ProcessNames[process.state - 1]).arg(process.start).arg(process.end)); } QStandardItem* createEventListItem(QString event) { return new QStandardItem(event); } /** * @brief MainWindow::updateMessages * @param s */ void MainWindow::updateMessages(int t, const QString& message, StringVec v) { QString timestamp_prefix = QDateTime::currentDateTime().toString("hh:mm:ss") + " - "; if (t == MESSAGE_UPDATE_TYPE) { qDebug() << "Updating message area"; auto simple_message = timestamp_prefix + parseMessage(message, v); ui->messages->append(simple_message); console_ui.updateText(message); } else if (t == COMMANDS_UPDATE_TYPE) { if (message == "New Session") { ui->led->setState(true); } qDebug() << "Updating commands"; QComboBox* app_list = ui->appList; app_list->clear(); for (const auto& s : v) { app_list->addItem(s); } } else if (t == PROCESS_REQUEST_TYPE) { qDebug() << "Updating process list"; m_processes.push_back(Process{ .name=v.at(1), .state=ProcessState::PENDING, .start=getTime(), .id=v.at(2) }); int row = 0; for (const auto& process : m_processes) { m_process_model->setItem(row, createProcessListItem(process)); row++; } } else if (t == EVENT_UPDATE_TYPE) { QString event_message{timestamp_prefix}; if (!v.empty()) { // TODO: extract process result handling from here. This should handle any event if (v.size() == 1) { event_message += message + "\n" + v.at(0); } else { event_message += message; if (message == "Process Result") { event_message += "\n"; auto app_name = q_client->getAppName(std::stoi(v.at(0).toUtf8().constData())); if (v.at(1).length() > 0) { updateProcessResult(v.at(1), v.at(2)); } else { // new process, from scheduled task Process new_process{ .name=app_name, .state=ProcessState::SUCCEEDED, .start=getTime(), .id="Scheduled task" }; if (v.count() > 2 && !v.at(2).isEmpty()) { new_process.result = v.at(2); new_process.end = new_process.start; } m_processes.push_back(new_process); m_process_model->setItem(m_process_model->rowCount(), createProcessListItem(new_process)); } event_message += app_name; event_message += ": "; event_message += v.at(2); } else { event_message += ": "; event_message += v.at(1); } } } else { event_message += message; } m_events.push_back(event_message); m_event_model->setItem(m_event_model->rowCount(), createEventListItem(event_message)); } else { qDebug() << "Unknown update type. Cannot update UI"; } } void MainWindow::startTimer() { if (m_timer != nullptr) { m_timer->start(30000); } } void MainWindow::updateProcessResult(QString id, QString result) { // We need to start matching processes with a unique identifier for (int i = m_processes.size() - 1; i >= 0; i--) { if (m_processes.at(i).id == id) { m_processes.at(i).end = getTime(); m_processes.at(i).state = ProcessState::SUCCEEDED; m_processes.at(i).result = result; m_process_model->setItem(i, 0, createProcessListItem(m_processes.at(i))); return; } } } void MainWindow::keyPressEvent(QKeyEvent *e) { qDebug() << "Key press: " << e->key(); if(e->key()==Qt::Key_0) { qDebug() << "Ok"; } }