Move common logic to basewindow
This commit is contained in:
parent
a761b772c8
commit
4fa0c81ed7
@ -23,19 +23,22 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
#include <QInputDialog>
|
||||||
#include <QSplitter>
|
#include <QSplitter>
|
||||||
#include "designwidget.h"
|
#include "designwidget.h"
|
||||||
#include "fpgaviewwidget.h"
|
#include "fpgaviewwidget.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "pythontab.h"
|
#include "pythontab.h"
|
||||||
|
#include "jsonparse.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
static void initBasenameResource() { Q_INIT_RESOURCE(base); }
|
static void initBasenameResource() { Q_INIT_RESOURCE(base); }
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
BaseMainWindow::BaseMainWindow(std::unique_ptr<Context> context, QWidget *parent)
|
BaseMainWindow::BaseMainWindow(std::unique_ptr<Context> context, QWidget *parent)
|
||||||
: QMainWindow(parent), ctx(std::move(context))
|
: QMainWindow(parent), ctx(std::move(context)), timing_driven(false)
|
||||||
{
|
{
|
||||||
initBasenameResource();
|
initBasenameResource();
|
||||||
qRegisterMetaType<std::string>();
|
qRegisterMetaType<std::string>();
|
||||||
@ -46,7 +49,18 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr<Context> context, QWidget *parent
|
|||||||
setObjectName("BaseMainWindow");
|
setObjectName("BaseMainWindow");
|
||||||
resize(1024, 768);
|
resize(1024, 768);
|
||||||
|
|
||||||
createMenusAndBars();
|
task = new TaskManager();
|
||||||
|
connect(task, SIGNAL(log(std::string)), this, SLOT(writeInfo(std::string)));
|
||||||
|
|
||||||
|
connect(task, SIGNAL(pack_finished(bool)), this, SLOT(pack_finished(bool)));
|
||||||
|
connect(task, SIGNAL(budget_finish(bool)), this, SLOT(budget_finish(bool)));
|
||||||
|
connect(task, SIGNAL(place_finished(bool)), this, SLOT(place_finished(bool)));
|
||||||
|
connect(task, SIGNAL(route_finished(bool)), this, SLOT(route_finished(bool)));
|
||||||
|
|
||||||
|
connect(task, SIGNAL(taskCanceled()), this, SLOT(taskCanceled()));
|
||||||
|
connect(task, SIGNAL(taskStarted()), this, SLOT(taskStarted()));
|
||||||
|
connect(task, SIGNAL(taskPaused()), this, SLOT(taskPaused()));
|
||||||
|
connect(this, SIGNAL(contextChanged(Context *)), task, SIGNAL(contextChanged(Context *)));
|
||||||
|
|
||||||
QWidget *centralWidget = new QWidget(this);
|
QWidget *centralWidget = new QWidget(this);
|
||||||
|
|
||||||
@ -99,9 +113,11 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr<Context> context, QWidget *parent
|
|||||||
|
|
||||||
splitter_v->addWidget(centralTabWidget);
|
splitter_v->addWidget(centralTabWidget);
|
||||||
splitter_v->addWidget(tabWidget);
|
splitter_v->addWidget(tabWidget);
|
||||||
|
|
||||||
|
createMenusAndBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseMainWindow::~BaseMainWindow() {}
|
BaseMainWindow::~BaseMainWindow() { delete task; }
|
||||||
|
|
||||||
void BaseMainWindow::closeTab(int index) { delete centralTabWidget->widget(index); }
|
void BaseMainWindow::closeTab(int index) { delete centralTabWidget->widget(index); }
|
||||||
|
|
||||||
@ -138,10 +154,9 @@ void BaseMainWindow::createMenusAndBars()
|
|||||||
|
|
||||||
menuBar = new QMenuBar();
|
menuBar = new QMenuBar();
|
||||||
menuBar->setGeometry(QRect(0, 0, 1024, 27));
|
menuBar->setGeometry(QRect(0, 0, 1024, 27));
|
||||||
QMenu *menu_File = new QMenu("&File", menuBar);
|
QMenu *menuFile = new QMenu("&File", menuBar);
|
||||||
QMenu *menu_Help = new QMenu("&Help", menuBar);
|
QMenu *menuHelp = new QMenu("&Help", menuBar);
|
||||||
menuBar->addAction(menu_File->menuAction());
|
menuDesign = new QMenu("&Design", menuBar);
|
||||||
menuBar->addAction(menu_Help->menuAction());
|
|
||||||
setMenuBar(menuBar);
|
setMenuBar(menuBar);
|
||||||
|
|
||||||
mainToolBar = new QToolBar();
|
mainToolBar = new QToolBar();
|
||||||
@ -156,20 +171,92 @@ void BaseMainWindow::createMenusAndBars()
|
|||||||
progressBar->setEnabled(false);
|
progressBar->setEnabled(false);
|
||||||
setStatusBar(statusBar);
|
setStatusBar(statusBar);
|
||||||
|
|
||||||
menu_File->addAction(actionNew);
|
menuFile->addAction(actionNew);
|
||||||
menu_File->addAction(actionOpen);
|
menuFile->addAction(actionOpen);
|
||||||
menu_File->addAction(actionSave);
|
menuFile->addAction(actionSave);
|
||||||
menu_File->addSeparator();
|
menuFile->addSeparator();
|
||||||
menu_File->addAction(actionExit);
|
menuFile->addAction(actionExit);
|
||||||
menu_Help->addAction(actionAbout);
|
menuHelp->addAction(actionAbout);
|
||||||
|
|
||||||
mainToolBar->addAction(actionNew);
|
mainToolBar->addAction(actionNew);
|
||||||
mainToolBar->addAction(actionOpen);
|
mainToolBar->addAction(actionOpen);
|
||||||
mainToolBar->addAction(actionSave);
|
mainToolBar->addAction(actionSave);
|
||||||
}
|
|
||||||
|
|
||||||
void BaseMainWindow::createGraphicsBar()
|
menuBar->addAction(menuFile->menuAction());
|
||||||
{
|
menuBar->addAction(menuDesign->menuAction());
|
||||||
|
menuBar->addAction(menuHelp->menuAction());
|
||||||
|
|
||||||
|
actionLoadJSON = new QAction("Open JSON", this);
|
||||||
|
actionLoadJSON->setIcon(QIcon(":/icons/resources/open_json.png"));
|
||||||
|
actionLoadJSON->setStatusTip("Open an existing JSON file");
|
||||||
|
actionLoadJSON->setEnabled(true);
|
||||||
|
connect(actionLoadJSON, SIGNAL(triggered()), this, SLOT(open_json()));
|
||||||
|
|
||||||
|
actionPack = new QAction("Pack", this);
|
||||||
|
actionPack->setIcon(QIcon(":/icons/resources/pack.png"));
|
||||||
|
actionPack->setStatusTip("Pack current design");
|
||||||
|
actionPack->setEnabled(false);
|
||||||
|
connect(actionPack, SIGNAL(triggered()), task, SIGNAL(pack()));
|
||||||
|
|
||||||
|
actionAssignBudget = new QAction("Assign Budget", this);
|
||||||
|
actionAssignBudget->setIcon(QIcon(":/icons/resources/time_add.png"));
|
||||||
|
actionAssignBudget->setStatusTip("Assign time budget for current design");
|
||||||
|
actionAssignBudget->setEnabled(false);
|
||||||
|
connect(actionAssignBudget, SIGNAL(triggered()), this, SLOT(budget()));
|
||||||
|
|
||||||
|
actionPlace = new QAction("Place", this);
|
||||||
|
actionPlace->setIcon(QIcon(":/icons/resources/place.png"));
|
||||||
|
actionPlace->setStatusTip("Place current design");
|
||||||
|
actionPlace->setEnabled(false);
|
||||||
|
connect(actionPlace, SIGNAL(triggered()), this, SLOT(place()));
|
||||||
|
|
||||||
|
actionRoute = new QAction("Route", this);
|
||||||
|
actionRoute->setIcon(QIcon(":/icons/resources/route.png"));
|
||||||
|
actionRoute->setStatusTip("Route current design");
|
||||||
|
actionRoute->setEnabled(false);
|
||||||
|
connect(actionRoute, SIGNAL(triggered()), task, SIGNAL(route()));
|
||||||
|
|
||||||
|
taskFPGABar = new QToolBar();
|
||||||
|
addToolBar(Qt::TopToolBarArea, taskFPGABar);
|
||||||
|
|
||||||
|
taskFPGABar->addAction(actionLoadJSON);
|
||||||
|
taskFPGABar->addAction(actionPack);
|
||||||
|
taskFPGABar->addAction(actionAssignBudget);
|
||||||
|
taskFPGABar->addAction(actionPlace);
|
||||||
|
taskFPGABar->addAction(actionRoute);
|
||||||
|
|
||||||
|
|
||||||
|
menuDesign->addAction(actionLoadJSON);
|
||||||
|
menuDesign->addAction(actionPack);
|
||||||
|
menuDesign->addAction(actionAssignBudget);
|
||||||
|
menuDesign->addAction(actionPlace);
|
||||||
|
menuDesign->addAction(actionRoute);
|
||||||
|
|
||||||
|
actionPlay = new QAction("Play", this);
|
||||||
|
actionPlay->setIcon(QIcon(":/icons/resources/control_play.png"));
|
||||||
|
actionPlay->setStatusTip("Continue running task");
|
||||||
|
actionPlay->setEnabled(false);
|
||||||
|
connect(actionPlay, SIGNAL(triggered()), task, SLOT(continue_thread()));
|
||||||
|
|
||||||
|
actionPause = new QAction("Pause", this);
|
||||||
|
actionPause->setIcon(QIcon(":/icons/resources/control_pause.png"));
|
||||||
|
actionPause->setStatusTip("Pause running task");
|
||||||
|
actionPause->setEnabled(false);
|
||||||
|
connect(actionPause, SIGNAL(triggered()), task, SLOT(pause_thread()));
|
||||||
|
|
||||||
|
actionStop = new QAction("Stop", this);
|
||||||
|
actionStop->setIcon(QIcon(":/icons/resources/control_stop.png"));
|
||||||
|
actionStop->setStatusTip("Stop running task");
|
||||||
|
actionStop->setEnabled(false);
|
||||||
|
connect(actionStop, SIGNAL(triggered()), task, SLOT(terminate_thread()));
|
||||||
|
|
||||||
|
QToolBar *taskToolBar = new QToolBar();
|
||||||
|
addToolBar(Qt::TopToolBarArea, taskToolBar);
|
||||||
|
|
||||||
|
taskToolBar->addAction(actionPlay);
|
||||||
|
taskToolBar->addAction(actionPause);
|
||||||
|
taskToolBar->addAction(actionStop);
|
||||||
|
|
||||||
QAction *actionZoomIn = new QAction("Zoom In", this);
|
QAction *actionZoomIn = new QAction("Zoom In", this);
|
||||||
actionZoomIn->setIcon(QIcon(":/icons/resources/zoom_in.png"));
|
actionZoomIn->setIcon(QIcon(":/icons/resources/zoom_in.png"));
|
||||||
connect(actionZoomIn, SIGNAL(triggered()), fpgaView, SLOT(zoomIn()));
|
connect(actionZoomIn, SIGNAL(triggered()), fpgaView, SLOT(zoomIn()));
|
||||||
@ -194,4 +281,135 @@ void BaseMainWindow::createGraphicsBar()
|
|||||||
graphicsToolBar->addAction(actionZoomOutbound);
|
graphicsToolBar->addAction(actionZoomOutbound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseMainWindow::load_json(std::string filename)
|
||||||
|
{
|
||||||
|
disableActions();
|
||||||
|
currentJson = filename;
|
||||||
|
std::ifstream f(filename);
|
||||||
|
if (parse_json_file(f, filename, ctx.get())) {
|
||||||
|
log("Loading design successful.\n");
|
||||||
|
Q_EMIT updateTreeView();
|
||||||
|
actionPack->setEnabled(true);
|
||||||
|
onJsonLoaded();
|
||||||
|
} else {
|
||||||
|
actionLoadJSON->setEnabled(true);
|
||||||
|
log("Loading design failed.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseMainWindow::open_json()
|
||||||
|
{
|
||||||
|
QString fileName = QFileDialog::getOpenFileName(this, QString("Open JSON"), QString(), QString("*.json"));
|
||||||
|
if (!fileName.isEmpty()) {
|
||||||
|
load_json(fileName.toStdString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseMainWindow::pack_finished(bool status)
|
||||||
|
{
|
||||||
|
disableActions();
|
||||||
|
if (status) {
|
||||||
|
log("Packing design successful.\n");
|
||||||
|
Q_EMIT updateTreeView();
|
||||||
|
actionPlace->setEnabled(true);
|
||||||
|
actionAssignBudget->setEnabled(true);
|
||||||
|
onPackFinished();
|
||||||
|
} else {
|
||||||
|
log("Packing design failed.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseMainWindow::budget_finish(bool status)
|
||||||
|
{
|
||||||
|
disableActions();
|
||||||
|
if (status) {
|
||||||
|
log("Assigning timing budget successful.\n");
|
||||||
|
actionPlace->setEnabled(true);
|
||||||
|
onBudgetFinished();
|
||||||
|
} else {
|
||||||
|
log("Assigning timing budget failed.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseMainWindow::place_finished(bool status)
|
||||||
|
{
|
||||||
|
disableActions();
|
||||||
|
if (status) {
|
||||||
|
log("Placing design successful.\n");
|
||||||
|
Q_EMIT updateTreeView();
|
||||||
|
actionRoute->setEnabled(true);
|
||||||
|
onPlaceFinished();
|
||||||
|
} else {
|
||||||
|
log("Placing design failed.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void BaseMainWindow::route_finished(bool status)
|
||||||
|
{
|
||||||
|
disableActions();
|
||||||
|
if (status) {
|
||||||
|
log("Routing design successful.\n");
|
||||||
|
Q_EMIT updateTreeView();
|
||||||
|
onRouteFinished();
|
||||||
|
} else
|
||||||
|
log("Routing design failed.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseMainWindow::taskCanceled()
|
||||||
|
{
|
||||||
|
log("CANCELED\n");
|
||||||
|
disableActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseMainWindow::taskStarted()
|
||||||
|
{
|
||||||
|
disableActions();
|
||||||
|
actionPause->setEnabled(true);
|
||||||
|
actionStop->setEnabled(true);
|
||||||
|
|
||||||
|
actionNew->setEnabled(false);
|
||||||
|
actionOpen->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseMainWindow::taskPaused()
|
||||||
|
{
|
||||||
|
disableActions();
|
||||||
|
actionPlay->setEnabled(true);
|
||||||
|
actionStop->setEnabled(true);
|
||||||
|
|
||||||
|
actionNew->setEnabled(false);
|
||||||
|
actionOpen->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseMainWindow::budget()
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
double freq = QInputDialog::getDouble(this, "Assign timing budget", "Frequency [MHz]:", 50, 0, 250, 2, &ok);
|
||||||
|
if (ok) {
|
||||||
|
freq *= 1e6;
|
||||||
|
timing_driven = true;
|
||||||
|
Q_EMIT task->budget(freq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseMainWindow::place() { Q_EMIT task->place(timing_driven); }
|
||||||
|
|
||||||
|
void BaseMainWindow::disableActions()
|
||||||
|
{
|
||||||
|
actionLoadJSON->setEnabled(false);
|
||||||
|
actionPack->setEnabled(false);
|
||||||
|
actionAssignBudget->setEnabled(false);
|
||||||
|
actionPlace->setEnabled(false);
|
||||||
|
actionRoute->setEnabled(false);
|
||||||
|
|
||||||
|
actionPlay->setEnabled(false);
|
||||||
|
actionPause->setEnabled(false);
|
||||||
|
actionStop->setEnabled(false);
|
||||||
|
|
||||||
|
actionNew->setEnabled(true);
|
||||||
|
actionOpen->setEnabled(true);
|
||||||
|
actionSave->setEnabled(!currentJson.empty());
|
||||||
|
|
||||||
|
onDisableActions();
|
||||||
|
}
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#define BASEMAINWINDOW_H
|
#define BASEMAINWINDOW_H
|
||||||
|
|
||||||
#include "nextpnr.h"
|
#include "nextpnr.h"
|
||||||
|
#include "worker.h"
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
@ -48,9 +49,16 @@ class BaseMainWindow : public QMainWindow
|
|||||||
virtual ~BaseMainWindow();
|
virtual ~BaseMainWindow();
|
||||||
Context *getContext() { return ctx.get(); }
|
Context *getContext() { return ctx.get(); }
|
||||||
|
|
||||||
|
void load_json(std::string filename);
|
||||||
protected:
|
protected:
|
||||||
void createMenusAndBars();
|
void createMenusAndBars();
|
||||||
void createGraphicsBar();
|
void disableActions();
|
||||||
|
virtual void onDisableActions() {};
|
||||||
|
virtual void onJsonLoaded() {};
|
||||||
|
virtual void onPackFinished() {};
|
||||||
|
virtual void onBudgetFinished() {};
|
||||||
|
virtual void onPlaceFinished() {};
|
||||||
|
virtual void onRouteFinished() {};
|
||||||
|
|
||||||
protected Q_SLOTS:
|
protected Q_SLOTS:
|
||||||
void writeInfo(std::string text);
|
void writeInfo(std::string text);
|
||||||
@ -60,12 +68,26 @@ class BaseMainWindow : public QMainWindow
|
|||||||
virtual void open_proj() = 0;
|
virtual void open_proj() = 0;
|
||||||
virtual bool save_proj() = 0;
|
virtual bool save_proj() = 0;
|
||||||
|
|
||||||
|
void open_json();
|
||||||
|
void budget();
|
||||||
|
void place();
|
||||||
|
|
||||||
|
void pack_finished(bool status);
|
||||||
|
void budget_finish(bool status);
|
||||||
|
void place_finished(bool status);
|
||||||
|
void route_finished(bool status);
|
||||||
|
|
||||||
|
void taskCanceled();
|
||||||
|
void taskStarted();
|
||||||
|
void taskPaused();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void contextChanged(Context *ctx);
|
void contextChanged(Context *ctx);
|
||||||
void updateTreeView();
|
void updateTreeView();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unique_ptr<Context> ctx;
|
std::unique_ptr<Context> ctx;
|
||||||
|
TaskManager *task;
|
||||||
QTabWidget *tabWidget;
|
QTabWidget *tabWidget;
|
||||||
QTabWidget *centralTabWidget;
|
QTabWidget *centralTabWidget;
|
||||||
PythonTab *console;
|
PythonTab *console;
|
||||||
@ -77,9 +99,24 @@ class BaseMainWindow : public QMainWindow
|
|||||||
QAction *actionNew;
|
QAction *actionNew;
|
||||||
QAction *actionOpen;
|
QAction *actionOpen;
|
||||||
QAction *actionSave;
|
QAction *actionSave;
|
||||||
|
|
||||||
|
QAction *actionLoadJSON;
|
||||||
|
QAction *actionPack;
|
||||||
|
QAction *actionAssignBudget;
|
||||||
|
QAction *actionPlace;
|
||||||
|
QAction *actionRoute;
|
||||||
|
QAction *actionPlay;
|
||||||
|
QAction *actionPause;
|
||||||
|
QAction *actionStop;
|
||||||
|
|
||||||
|
QMenu *menuDesign;
|
||||||
|
QToolBar *taskFPGABar;
|
||||||
|
|
||||||
QProgressBar *progressBar;
|
QProgressBar *progressBar;
|
||||||
DesignWidget *designview;
|
DesignWidget *designview;
|
||||||
FPGAViewWidget *fpgaView;
|
FPGAViewWidget *fpgaView;
|
||||||
|
bool timing_driven;
|
||||||
|
std::string currentJson;
|
||||||
};
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -36,13 +36,7 @@ MainWindow::MainWindow(std::unique_ptr<Context> context, QWidget *parent) : Base
|
|||||||
|
|
||||||
MainWindow::~MainWindow() {}
|
MainWindow::~MainWindow() {}
|
||||||
|
|
||||||
void MainWindow::createMenu()
|
void MainWindow::createMenu() {}
|
||||||
{
|
|
||||||
QMenu *menu_Custom = new QMenu("&Generic", menuBar);
|
|
||||||
menuBar->addAction(menu_Custom->menuAction());
|
|
||||||
|
|
||||||
createGraphicsBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::new_proj() {}
|
void MainWindow::new_proj() {}
|
||||||
|
|
||||||
|
@ -36,13 +36,7 @@ MainWindow::MainWindow(std::unique_ptr<Context> context, QWidget *parent) : Base
|
|||||||
|
|
||||||
MainWindow::~MainWindow() {}
|
MainWindow::~MainWindow() {}
|
||||||
|
|
||||||
void MainWindow::createMenu()
|
void MainWindow::createMenu() {}
|
||||||
{
|
|
||||||
QMenu *menu_Custom = new QMenu("&Generic", menuBar);
|
|
||||||
menuBar->addAction(menu_Custom->menuAction());
|
|
||||||
|
|
||||||
createGraphicsBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::new_proj() {}
|
void MainWindow::new_proj() {}
|
||||||
|
|
||||||
|
@ -37,45 +37,24 @@ static void initMainResource() { Q_INIT_RESOURCE(nextpnr); }
|
|||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
MainWindow::MainWindow(std::unique_ptr<Context> context, ArchArgs args, QWidget *parent)
|
MainWindow::MainWindow(std::unique_ptr<Context> context, ArchArgs args, QWidget *parent)
|
||||||
: BaseMainWindow(std::move(context), parent), timing_driven(false), chipArgs(args)
|
: BaseMainWindow(std::move(context), parent), chipArgs(args)
|
||||||
{
|
{
|
||||||
initMainResource();
|
initMainResource();
|
||||||
|
|
||||||
std::string title = "nextpnr-ice40 - [EMPTY]";
|
std::string title = "nextpnr-ice40 - [EMPTY]";
|
||||||
setWindowTitle(title.c_str());
|
setWindowTitle(title.c_str());
|
||||||
|
|
||||||
task = new TaskManager();
|
|
||||||
connect(task, SIGNAL(log(std::string)), this, SLOT(writeInfo(std::string)));
|
|
||||||
|
|
||||||
connect(task, SIGNAL(pack_finished(bool)), this, SLOT(pack_finished(bool)));
|
|
||||||
connect(task, SIGNAL(budget_finish(bool)), this, SLOT(budget_finish(bool)));
|
|
||||||
connect(task, SIGNAL(place_finished(bool)), this, SLOT(place_finished(bool)));
|
|
||||||
connect(task, SIGNAL(route_finished(bool)), this, SLOT(route_finished(bool)));
|
|
||||||
|
|
||||||
connect(task, SIGNAL(taskCanceled()), this, SLOT(taskCanceled()));
|
|
||||||
connect(task, SIGNAL(taskStarted()), this, SLOT(taskStarted()));
|
|
||||||
connect(task, SIGNAL(taskPaused()), this, SLOT(taskPaused()));
|
|
||||||
|
|
||||||
connect(this, SIGNAL(contextChanged(Context *)), this, SLOT(newContext(Context *)));
|
connect(this, SIGNAL(contextChanged(Context *)), this, SLOT(newContext(Context *)));
|
||||||
connect(this, SIGNAL(contextChanged(Context *)), task, SIGNAL(contextChanged(Context *)));
|
|
||||||
|
|
||||||
createMenu();
|
createMenu();
|
||||||
|
|
||||||
Q_EMIT contextChanged(ctx.get());
|
Q_EMIT contextChanged(ctx.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() { delete task; }
|
MainWindow::~MainWindow() {}
|
||||||
|
|
||||||
void MainWindow::createMenu()
|
void MainWindow::createMenu()
|
||||||
{
|
{
|
||||||
QMenu *menu_Design = new QMenu("&Design", menuBar);
|
|
||||||
menuBar->addAction(menu_Design->menuAction());
|
|
||||||
|
|
||||||
actionLoadJSON = new QAction("Open JSON", this);
|
|
||||||
actionLoadJSON->setIcon(QIcon(":/icons/resources/open_json.png"));
|
|
||||||
actionLoadJSON->setStatusTip("Open an existing JSON file");
|
|
||||||
actionLoadJSON->setEnabled(true);
|
|
||||||
connect(actionLoadJSON, SIGNAL(triggered()), this, SLOT(open_json()));
|
|
||||||
|
|
||||||
actionLoadPCF = new QAction("Open PCF", this);
|
actionLoadPCF = new QAction("Open PCF", this);
|
||||||
actionLoadPCF->setIcon(QIcon(":/icons/resources/open_pcf.png"));
|
actionLoadPCF->setIcon(QIcon(":/icons/resources/open_pcf.png"));
|
||||||
@ -83,81 +62,20 @@ void MainWindow::createMenu()
|
|||||||
actionLoadPCF->setEnabled(false);
|
actionLoadPCF->setEnabled(false);
|
||||||
connect(actionLoadPCF, SIGNAL(triggered()), this, SLOT(open_pcf()));
|
connect(actionLoadPCF, SIGNAL(triggered()), this, SLOT(open_pcf()));
|
||||||
|
|
||||||
actionPack = new QAction("Pack", this);
|
|
||||||
actionPack->setIcon(QIcon(":/icons/resources/pack.png"));
|
|
||||||
actionPack->setStatusTip("Pack current design");
|
|
||||||
actionPack->setEnabled(false);
|
|
||||||
connect(actionPack, SIGNAL(triggered()), task, SIGNAL(pack()));
|
|
||||||
|
|
||||||
actionAssignBudget = new QAction("Assign Budget", this);
|
|
||||||
actionAssignBudget->setIcon(QIcon(":/icons/resources/time_add.png"));
|
|
||||||
actionAssignBudget->setStatusTip("Assign time budget for current design");
|
|
||||||
actionAssignBudget->setEnabled(false);
|
|
||||||
connect(actionAssignBudget, SIGNAL(triggered()), this, SLOT(budget()));
|
|
||||||
|
|
||||||
actionPlace = new QAction("Place", this);
|
|
||||||
actionPlace->setIcon(QIcon(":/icons/resources/place.png"));
|
|
||||||
actionPlace->setStatusTip("Place current design");
|
|
||||||
actionPlace->setEnabled(false);
|
|
||||||
connect(actionPlace, SIGNAL(triggered()), this, SLOT(place()));
|
|
||||||
|
|
||||||
actionRoute = new QAction("Route", this);
|
|
||||||
actionRoute->setIcon(QIcon(":/icons/resources/route.png"));
|
|
||||||
actionRoute->setStatusTip("Route current design");
|
|
||||||
actionRoute->setEnabled(false);
|
|
||||||
connect(actionRoute, SIGNAL(triggered()), task, SIGNAL(route()));
|
|
||||||
|
|
||||||
actionSaveAsc = new QAction("Save ASC", this);
|
actionSaveAsc = new QAction("Save ASC", this);
|
||||||
actionSaveAsc->setIcon(QIcon(":/icons/resources/save_asc.png"));
|
actionSaveAsc->setIcon(QIcon(":/icons/resources/save_asc.png"));
|
||||||
actionSaveAsc->setStatusTip("Save ASC file");
|
actionSaveAsc->setStatusTip("Save ASC file");
|
||||||
actionSaveAsc->setEnabled(false);
|
actionSaveAsc->setEnabled(false);
|
||||||
connect(actionSaveAsc, SIGNAL(triggered()), this, SLOT(save_asc()));
|
connect(actionSaveAsc, SIGNAL(triggered()), this, SLOT(save_asc()));
|
||||||
|
|
||||||
QToolBar *taskFPGABar = new QToolBar();
|
taskFPGABar->addSeparator();
|
||||||
addToolBar(Qt::TopToolBarArea, taskFPGABar);
|
|
||||||
|
|
||||||
taskFPGABar->addAction(actionLoadJSON);
|
|
||||||
taskFPGABar->addAction(actionLoadPCF);
|
taskFPGABar->addAction(actionLoadPCF);
|
||||||
taskFPGABar->addAction(actionPack);
|
|
||||||
taskFPGABar->addAction(actionAssignBudget);
|
|
||||||
taskFPGABar->addAction(actionPlace);
|
|
||||||
taskFPGABar->addAction(actionRoute);
|
|
||||||
taskFPGABar->addAction(actionSaveAsc);
|
taskFPGABar->addAction(actionSaveAsc);
|
||||||
|
|
||||||
menu_Design->addAction(actionLoadJSON);
|
menuDesign->addSeparator();
|
||||||
menu_Design->addAction(actionLoadPCF);
|
menuDesign->addAction(actionLoadPCF);
|
||||||
menu_Design->addAction(actionPack);
|
menuDesign->addAction(actionSaveAsc);
|
||||||
menu_Design->addAction(actionAssignBudget);
|
|
||||||
menu_Design->addAction(actionPlace);
|
|
||||||
menu_Design->addAction(actionRoute);
|
|
||||||
menu_Design->addAction(actionSaveAsc);
|
|
||||||
|
|
||||||
actionPlay = new QAction("Play", this);
|
|
||||||
actionPlay->setIcon(QIcon(":/icons/resources/control_play.png"));
|
|
||||||
actionPlay->setStatusTip("Continue running task");
|
|
||||||
actionPlay->setEnabled(false);
|
|
||||||
connect(actionPlay, SIGNAL(triggered()), task, SLOT(continue_thread()));
|
|
||||||
|
|
||||||
actionPause = new QAction("Pause", this);
|
|
||||||
actionPause->setIcon(QIcon(":/icons/resources/control_pause.png"));
|
|
||||||
actionPause->setStatusTip("Pause running task");
|
|
||||||
actionPause->setEnabled(false);
|
|
||||||
connect(actionPause, SIGNAL(triggered()), task, SLOT(pause_thread()));
|
|
||||||
|
|
||||||
actionStop = new QAction("Stop", this);
|
|
||||||
actionStop->setIcon(QIcon(":/icons/resources/control_stop.png"));
|
|
||||||
actionStop->setStatusTip("Stop running task");
|
|
||||||
actionStop->setEnabled(false);
|
|
||||||
connect(actionStop, SIGNAL(triggered()), task, SLOT(terminate_thread()));
|
|
||||||
|
|
||||||
QToolBar *taskToolBar = new QToolBar();
|
|
||||||
addToolBar(Qt::TopToolBarArea, taskToolBar);
|
|
||||||
|
|
||||||
taskToolBar->addAction(actionPlay);
|
|
||||||
taskToolBar->addAction(actionPause);
|
|
||||||
taskToolBar->addAction(actionStop);
|
|
||||||
|
|
||||||
createGraphicsBar();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
@ -235,22 +153,6 @@ void MainWindow::new_proj()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::load_json(std::string filename)
|
|
||||||
{
|
|
||||||
disableActions();
|
|
||||||
currentJson = filename;
|
|
||||||
std::ifstream f(filename);
|
|
||||||
if (parse_json_file(f, filename, ctx.get())) {
|
|
||||||
log("Loading design successful.\n");
|
|
||||||
actionLoadPCF->setEnabled(true);
|
|
||||||
actionPack->setEnabled(true);
|
|
||||||
Q_EMIT updateTreeView();
|
|
||||||
} else {
|
|
||||||
actionLoadJSON->setEnabled(true);
|
|
||||||
log("Loading design failed.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::load_pcf(std::string filename)
|
void MainWindow::load_pcf(std::string filename)
|
||||||
{
|
{
|
||||||
disableActions();
|
disableActions();
|
||||||
@ -351,14 +253,6 @@ void MainWindow::open_proj()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::open_json()
|
|
||||||
{
|
|
||||||
QString fileName = QFileDialog::getOpenFileName(this, QString("Open JSON"), QString(), QString("*.json"));
|
|
||||||
if (!fileName.isEmpty()) {
|
|
||||||
load_json(fileName.toStdString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::open_pcf()
|
void MainWindow::open_pcf()
|
||||||
{
|
{
|
||||||
QString fileName = QFileDialog::getOpenFileName(this, QString("Open PCF"), QString(), QString("*.pcf"));
|
QString fileName = QFileDialog::getOpenFileName(this, QString("Open PCF"), QString(), QString("*.pcf"));
|
||||||
@ -409,108 +303,20 @@ void MainWindow::save_asc()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::disableActions()
|
void MainWindow::onDisableActions()
|
||||||
{
|
{
|
||||||
actionLoadJSON->setEnabled(false);
|
|
||||||
actionLoadPCF->setEnabled(false);
|
actionLoadPCF->setEnabled(false);
|
||||||
actionPack->setEnabled(false);
|
|
||||||
actionAssignBudget->setEnabled(false);
|
|
||||||
actionPlace->setEnabled(false);
|
|
||||||
actionRoute->setEnabled(false);
|
|
||||||
actionSaveAsc->setEnabled(false);
|
actionSaveAsc->setEnabled(false);
|
||||||
|
|
||||||
actionPlay->setEnabled(false);
|
|
||||||
actionPause->setEnabled(false);
|
|
||||||
actionStop->setEnabled(false);
|
|
||||||
|
|
||||||
actionNew->setEnabled(true);
|
|
||||||
actionOpen->setEnabled(true);
|
|
||||||
actionSave->setEnabled(!currentJson.empty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::pack_finished(bool status)
|
void MainWindow::onJsonLoaded()
|
||||||
{
|
{
|
||||||
disableActions();
|
actionLoadPCF->setEnabled(true);
|
||||||
if (status) {
|
|
||||||
log("Packing design successful.\n");
|
|
||||||
Q_EMIT updateTreeView();
|
|
||||||
actionPlace->setEnabled(true);
|
|
||||||
actionAssignBudget->setEnabled(true);
|
|
||||||
} else {
|
|
||||||
log("Packing design failed.\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
void MainWindow::onRouteFinished()
|
||||||
void MainWindow::budget_finish(bool status)
|
|
||||||
{
|
{
|
||||||
disableActions();
|
|
||||||
if (status) {
|
|
||||||
log("Assigning timing budget successful.\n");
|
|
||||||
actionPlace->setEnabled(true);
|
|
||||||
} else {
|
|
||||||
log("Assigning timing budget failed.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::place_finished(bool status)
|
|
||||||
{
|
|
||||||
disableActions();
|
|
||||||
if (status) {
|
|
||||||
log("Placing design successful.\n");
|
|
||||||
Q_EMIT updateTreeView();
|
|
||||||
actionRoute->setEnabled(true);
|
|
||||||
} else {
|
|
||||||
log("Placing design failed.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void MainWindow::route_finished(bool status)
|
|
||||||
{
|
|
||||||
disableActions();
|
|
||||||
if (status) {
|
|
||||||
log("Routing design successful.\n");
|
|
||||||
Q_EMIT updateTreeView();
|
|
||||||
actionSaveAsc->setEnabled(true);
|
actionSaveAsc->setEnabled(true);
|
||||||
} else
|
|
||||||
log("Routing design failed.\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::taskCanceled()
|
|
||||||
{
|
|
||||||
log("CANCELED\n");
|
|
||||||
disableActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::taskStarted()
|
|
||||||
{
|
|
||||||
disableActions();
|
|
||||||
actionPause->setEnabled(true);
|
|
||||||
actionStop->setEnabled(true);
|
|
||||||
|
|
||||||
actionNew->setEnabled(false);
|
|
||||||
actionOpen->setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::taskPaused()
|
|
||||||
{
|
|
||||||
disableActions();
|
|
||||||
actionPlay->setEnabled(true);
|
|
||||||
actionStop->setEnabled(true);
|
|
||||||
|
|
||||||
actionNew->setEnabled(false);
|
|
||||||
actionOpen->setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::budget()
|
|
||||||
{
|
|
||||||
bool ok;
|
|
||||||
double freq = QInputDialog::getDouble(this, "Assign timing budget", "Frequency [MHz]:", 50, 0, 250, 2, &ok);
|
|
||||||
if (ok) {
|
|
||||||
freq *= 1e6;
|
|
||||||
timing_driven = true;
|
|
||||||
Q_EMIT task->budget(freq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::place() { Q_EMIT task->place(timing_driven); }
|
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#define MAINWINDOW_H
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
#include "../basewindow.h"
|
#include "../basewindow.h"
|
||||||
#include "worker.h"
|
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
@ -35,50 +34,29 @@ class MainWindow : public BaseMainWindow
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void createMenu();
|
void createMenu();
|
||||||
void load_json(std::string filename);
|
|
||||||
void load_pcf(std::string filename);
|
void load_pcf(std::string filename);
|
||||||
|
protected:
|
||||||
|
void onDisableActions() override;
|
||||||
|
void onJsonLoaded() override;
|
||||||
|
void onRouteFinished() override;
|
||||||
|
|
||||||
protected Q_SLOTS:
|
protected Q_SLOTS:
|
||||||
virtual void new_proj();
|
virtual void new_proj();
|
||||||
virtual void open_proj();
|
virtual void open_proj();
|
||||||
virtual bool save_proj();
|
virtual bool save_proj();
|
||||||
|
|
||||||
void open_json();
|
|
||||||
void open_pcf();
|
void open_pcf();
|
||||||
void budget();
|
|
||||||
void place();
|
|
||||||
void save_asc();
|
void save_asc();
|
||||||
|
|
||||||
void pack_finished(bool status);
|
|
||||||
void budget_finish(bool status);
|
|
||||||
void place_finished(bool status);
|
|
||||||
void route_finished(bool status);
|
|
||||||
|
|
||||||
void taskCanceled();
|
|
||||||
void taskStarted();
|
|
||||||
void taskPaused();
|
|
||||||
|
|
||||||
void newContext(Context *ctx);
|
void newContext(Context *ctx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void disableActions();
|
|
||||||
|
|
||||||
TaskManager *task;
|
|
||||||
QAction *actionLoadJSON;
|
|
||||||
QAction *actionLoadPCF;
|
QAction *actionLoadPCF;
|
||||||
QAction *actionPack;
|
|
||||||
QAction *actionAssignBudget;
|
|
||||||
QAction *actionPlace;
|
|
||||||
QAction *actionRoute;
|
|
||||||
QAction *actionSaveAsc;
|
QAction *actionSaveAsc;
|
||||||
QAction *actionPlay;
|
|
||||||
QAction *actionPause;
|
|
||||||
QAction *actionStop;
|
|
||||||
|
|
||||||
bool timing_driven;
|
|
||||||
ArchArgs chipArgs;
|
ArchArgs chipArgs;
|
||||||
|
|
||||||
std::string currentProj;
|
std::string currentProj;
|
||||||
std::string currentJson;
|
|
||||||
std::string currentPCF;
|
std::string currentPCF;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user