Skip to content

Commit

Permalink
Add actions in the GUI
Browse files Browse the repository at this point in the history
  • Loading branch information
bbodin committed Dec 3, 2024
1 parent f10e7b1 commit d3dcdbf
Show file tree
Hide file tree
Showing 7 changed files with 322 additions and 4 deletions.
12 changes: 12 additions & 0 deletions src/libkiter/commons/KiterRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ class KiterRegistry {
return true;
}

static const std::vector<std::string> get_names() {
tools_map& m = getSingletonMap();
std::vector<std::string> keys;
keys.reserve(m.size()); // Reserve memory to improve performance
std::transform(m.begin(), m.end(), std::back_inserter(keys),
[](const auto& pair) {
return pair.first;
});
return keys;

}

static const T* get(const std::string& name) {
tools_map& map = getSingletonMap();
if (map.find(name) == map.end()) return nullptr;
Expand Down
2 changes: 2 additions & 0 deletions src/qiter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ set(SOURCE_FILES
graphwidget.cpp
qtNode.cpp
qtEdge.cpp
ParameterInputDialog.h
ParameterInputDialog.cpp
)

add_executable(qiter ${SOURCE_FILES})
Expand Down
73 changes: 73 additions & 0 deletions src/qiter/ParameterInputDialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// Created by toky on 3/12/24.
//

#include "ParameterInputDialog.h"
#include <QDialogButtonBox>
#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include "commons/KiterRegistry.h"
#include "generators/generators.h"

ParameterInputDialog::ParameterInputDialog(const QString &generatorName, QWidget *parent)
: QDialog(parent), generatorName(generatorName)
{
setWindowTitle(tr("Parameters for %1").arg(generatorName));
layout = new QVBoxLayout(this);

QLabel *infoLabel = new QLabel(tr("Enter parameters (name and value):"), this);
layout->addWidget(infoLabel);

formLayout = new QFormLayout;

// Add an initial parameter row
QLineEdit *paramNameEdit = new QLineEdit(this);
QLineEdit *paramValueEdit = new QLineEdit(this);
paramNameEdits.append(paramNameEdit);
paramValueEdits.append(paramValueEdit);
formLayout->addRow(paramNameEdit, paramValueEdit);

layout->addLayout(formLayout);

// Add "Add Parameter" button
QPushButton *addParamButton = new QPushButton(tr("Add Parameter"), this);
connect(addParamButton, &QPushButton::clicked, this, &ParameterInputDialog::onAddParameterClicked);
layout->addWidget(addParamButton);

// Add OK and Cancel buttons
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
connect(buttonBox, &QDialogButtonBox::accepted, this, &ParameterInputDialog::accept);
connect(buttonBox, &QDialogButtonBox::rejected, this, &ParameterInputDialog::reject);

layout->addWidget(buttonBox);
}

void ParameterInputDialog::onAddParameterClicked()
{
QLineEdit *paramNameEdit = new QLineEdit(this);
QLineEdit *paramValueEdit = new QLineEdit(this);
paramNameEdits.append(paramNameEdit);
paramValueEdits.append(paramValueEdit);
formLayout->addRow(paramNameEdit, paramValueEdit);
}

void ParameterInputDialog::accept()
{
// Collect parameters
for (int i = 0; i < paramNameEdits.size(); ++i) {
QString paramName = paramNameEdits[i]->text();
QString paramValue = paramValueEdits[i]->text();
if (!paramName.isEmpty()) {
parameters[paramName.toStdString()] = paramValue.toStdString();
}
}

QDialog::accept();
}

parameters_list_t ParameterInputDialog::getParameters() const
{
return parameters;
}
36 changes: 36 additions & 0 deletions src/qiter/ParameterInputDialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// Created by toky on 3/12/24.
//

#ifndef KITER_PARAMETERINPUTDIALOG_H
#define KITER_PARAMETERINPUTDIALOG_H

#include <QDialog>
#include <QMap>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QFormLayout>
#include "printers/printers.h" // For parameters_list_t

class ParameterInputDialog : public QDialog
{
Q_OBJECT

public:
explicit ParameterInputDialog(const QString &generatorName, QWidget *parent = nullptr);
parameters_list_t getParameters() const;

private slots:
void accept() override;
void onAddParameterClicked();

private:
QString generatorName;
parameters_list_t parameters;
QList<QLineEdit*> paramNameEdits;
QList<QLineEdit*> paramValueEdits;
QVBoxLayout *layout;
QFormLayout *formLayout;
};

#endif //KITER_PARAMETERINPUTDIALOG_H
3 changes: 3 additions & 0 deletions src/qiter/graphwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ Q_OBJECT
public:
GraphWidget(QWidget *parent = nullptr);
void setDataflow(models::Dataflow *dataflow);
inline models::Dataflow * getDataflow() {
return this->dataflow;
}
void drawGraph();
void startLayout();

Expand Down
191 changes: 188 additions & 3 deletions src/qiter/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QDebug>
#include <QDebug>
#include "printers/printers.h"

#include "commons/KiterRegistry.h"
#include "generators/generators.h"
#include "ParameterInputDialog.h"

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
Expand All @@ -19,13 +21,70 @@ MainWindow::MainWindow(QWidget *parent)
}

connect(ui->actionLoad, &QAction::triggered, this, &MainWindow::loadGraph);

// Create Generate menu dynamically
QMenu *generateMenu = new QMenu(tr("&Generate"), this);
ui->menubar->addMenu(generateMenu);

// Get the list of generators from KiterRegistry
std::vector<std::string> generatorNames = KiterRegistry<generator_t>::get_names();

for (const std::string &generatorName : generatorNames) {
QAction *action = new QAction(QString::fromStdString(generatorName), this);
action->setData(QString::fromStdString(generatorName));
generateMenu->addAction(action);
connect(action, &QAction::triggered, this, &MainWindow::onGenerateActionTriggered);
}

// Create Transformations menu dynamically
QMenu *transformationsMenu = new QMenu(tr("&Transformations"), this);
ui->menubar->addMenu(transformationsMenu);

// Get the list of transformations from KiterRegistry
std::vector<std::string> transformationNames = KiterRegistry<transformation_t>::get_names();

for (const std::string &transformationName : transformationNames) {
QAction *action = new QAction(QString::fromStdString(transformationName), this);
action->setData(QString::fromStdString(transformationName));
transformationsMenu->addAction(action);
connect(action, &QAction::triggered, this, &MainWindow::onTransformationActionTriggered);
}

// Create Buffer Sizing menu dynamically
QMenu *bufferSizingMenu = new QMenu(tr("&Buffer Sizing"), this);
ui->menubar->addMenu(bufferSizingMenu);

// Get the list of buffer sizings from KiterRegistry
std::vector<std::string> bufferSizingNames = KiterRegistry<buffer_sizing_t>::get_names();

for (const std::string &bufferSizingName : bufferSizingNames) {
QAction *action = new QAction(QString::fromStdString(bufferSizingName), this);
action->setData(QString::fromStdString(bufferSizingName));
bufferSizingMenu->addAction(action);
connect(action, &QAction::triggered, this, &MainWindow::onBufferSizingActionTriggered);
}

// Create Printers menu dynamically
QMenu *printersMenu = new QMenu(tr("&Printers"), this);
ui->menubar->addMenu(printersMenu);

// Get the list of printers from KiterRegistry
std::vector<std::string> printerNames = KiterRegistry<printer_t>::get_names();

for (const std::string &printerName : printerNames) {
QAction *action = new QAction(QString::fromStdString(printerName), this);
action->setData(QString::fromStdString(printerName));
printersMenu->addAction(action);
connect(action, &QAction::triggered, this, &MainWindow::onPrinterActionTriggered);
}
}

MainWindow::~MainWindow()
{
delete ui;
}


void MainWindow::loadGraph()
{
qInfo() << "Attempting to open file dialog for XML file selection...";
Expand All @@ -35,7 +94,7 @@ void MainWindow::loadGraph()

if (fileName.isEmpty()) {
qInfo() << "No file selected or dialog canceled.";
return;
return;
}

qInfo() << "Selected file:" << fileName;
Expand All @@ -53,3 +112,129 @@ void MainWindow::loadGraph()

graphWidget->setDataflow(dataflow);
}
void MainWindow::onTransformationActionTriggered()
{
handleAction<transformation_t, void>(
[this](const transformation_t *actionInstance, const parameters_list_t &parameters) {
// Ensure dataflow is loaded
models::Dataflow *dataflow = graphWidget->getDataflow();
if (!dataflow) {
QMessageBox::warning(this, tr("No Dataflow"), tr("Please load or generate a dataflow graph first."));
throw std::runtime_error("No dataflow loaded");
}
// Perform the action
actionInstance->fun(dataflow, parameters);
},
[this]() {
// Post-action processing
graphWidget->update(); // Update the graph display
});
}


void MainWindow::onPrinterActionTriggered()
{
handleAction<printer_t, void>(
[this](const printer_t *actionInstance, const parameters_list_t &parameters) {
models::Dataflow *dataflow = graphWidget->getDataflow();
if (!dataflow) {
QMessageBox::warning(this, tr("No Dataflow"), tr("Please load or generate a dataflow graph first."));
throw std::runtime_error("No dataflow loaded");
}
actionInstance->fun(dataflow, parameters);
},
[]() {
// Post-action processing
qInfo() << "Printer executed successfully.";
});
}


void MainWindow::onBufferSizingActionTriggered()
{
handleAction<buffer_sizing_t, BufferSizingResult>(
[this](const buffer_sizing_t *actionInstance, const parameters_list_t &parameters) -> BufferSizingResult {
models::Dataflow *dataflow = graphWidget->getDataflow();
if (!dataflow) {
QMessageBox::warning(this, tr("No Dataflow"), tr("Please load or generate a dataflow graph first."));
throw std::runtime_error("No dataflow loaded");
}
return actionInstance->fun(dataflow, parameters);
},
[this](const BufferSizingResult &res) {
// Post-action processing
qInfo() << "Total buffer size:" << res.total_size();
QMessageBox::information(this, tr("Buffer Sizing Result"),
tr("Total buffer size: %1").arg(res.total_size()));
});
}



void MainWindow::onGenerateActionTriggered()
{
handleAction<generator_t, models::Dataflow *>(
[](const generator_t *actionInstance, const parameters_list_t &parameters) -> models::Dataflow * {
return actionInstance->fun(parameters);
},
[this](models::Dataflow *newDataflow) {
if (!newDataflow) {
QMessageBox::critical(this, tr("Error"), tr("Failed to generate the graph."));
qWarning() << "Failed to generate the graph.";
return;
}
qInfo() << "Dataflow generated successfully, updating graph widget...";
graphWidget->setDataflow(newDataflow);
});
}

template <typename ActionType, typename ResultType, typename ActionFunction, typename PostAction>
void MainWindow::handleAction(ActionFunction actionFunction, PostAction postAction) {
try {
QAction *actionSender = qobject_cast<QAction *>(sender());
if (!actionSender) {
qWarning() << "Sender is not a QAction!";
return;
}
QString actionName = actionSender->data().toString();
qInfo() << "Action selected:" << actionName;

// Show a dialog to input parameters
ParameterInputDialog dialog(actionName, this);
if (dialog.exec() != QDialog::Accepted) {
qInfo() << "Action dialog canceled.";
return;
}

parameters_list_t parameters = dialog.getParameters();

const ActionType *actionInstance = KiterRegistry<ActionType>::get(actionName.toStdString());
if (!actionInstance) {
QMessageBox::critical(this, tr("Error"), tr("Action not found."));
qWarning() << "Action not found:" << actionName;
return;
}

qInfo() << "Performing action...";

// Run the action on the main thread
if constexpr (std::is_same<ResultType, void>::value) {
// If ResultType is void, call the function without assigning to a variable
actionFunction(actionInstance, parameters);
qInfo() << "Action completed.";
// Process the result using the provided post-action function
postAction();
} else {
// If ResultType is not void, assign the result to a variable
ResultType result = actionFunction(actionInstance, parameters);
qInfo() << "Action completed.";
// Process the result using the provided post-action function
postAction(result);
}


} catch (const std::exception &e) {
QMessageBox::critical(this, tr("Error"), e.what());
qWarning() << "Exception occurred:" << e.what();
}
}
9 changes: 8 additions & 1 deletion src/qiter/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,16 @@ Q_OBJECT

private slots:
void loadGraph();
void onGenerateActionTriggered();
void onTransformationActionTriggered();
void onBufferSizingActionTriggered();
void onPrinterActionTriggered();

private:
Ui::MainWindow *ui;
GraphWidget *graphWidget;
GraphWidget *graphWidget;

template <typename ActionType, typename ResultType, typename ActionFunction, typename PostAction>
void handleAction(ActionFunction actionFunction, PostAction postAction) ;
};
#endif // MAINWINDOW_H

0 comments on commit d3dcdbf

Please sign in to comment.