From 7f7cb6601e52650714358e84c077bf394d295809 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 2 Aug 2018 17:48:02 +0200 Subject: Move generic resources to top level --- gui/base.qrc | 8 ++++++++ gui/ice40/nextpnr.qrc | 8 -------- gui/ice40/resources/control_pause.png | Bin 721 -> 0 bytes gui/ice40/resources/control_play.png | Bin 717 -> 0 bytes gui/ice40/resources/control_stop.png | Bin 695 -> 0 bytes gui/ice40/resources/open_json.png | Bin 2093 -> 0 bytes gui/ice40/resources/pack.png | Bin 853 -> 0 bytes gui/ice40/resources/place.png | Bin 825 -> 0 bytes gui/ice40/resources/route.png | Bin 683 -> 0 bytes gui/ice40/resources/time_add.png | Bin 827 -> 0 bytes gui/resources/control_pause.png | Bin 0 -> 721 bytes gui/resources/control_play.png | Bin 0 -> 717 bytes gui/resources/control_stop.png | Bin 0 -> 695 bytes gui/resources/open_json.png | Bin 0 -> 2093 bytes gui/resources/pack.png | Bin 0 -> 853 bytes gui/resources/place.png | Bin 0 -> 825 bytes gui/resources/route.png | Bin 0 -> 683 bytes gui/resources/time_add.png | Bin 0 -> 827 bytes 18 files changed, 8 insertions(+), 8 deletions(-) delete mode 100644 gui/ice40/resources/control_pause.png delete mode 100644 gui/ice40/resources/control_play.png delete mode 100644 gui/ice40/resources/control_stop.png delete mode 100644 gui/ice40/resources/open_json.png delete mode 100644 gui/ice40/resources/pack.png delete mode 100644 gui/ice40/resources/place.png delete mode 100644 gui/ice40/resources/route.png delete mode 100644 gui/ice40/resources/time_add.png create mode 100644 gui/resources/control_pause.png create mode 100644 gui/resources/control_play.png create mode 100644 gui/resources/control_stop.png create mode 100644 gui/resources/open_json.png create mode 100644 gui/resources/pack.png create mode 100644 gui/resources/place.png create mode 100644 gui/resources/route.png create mode 100644 gui/resources/time_add.png diff --git a/gui/base.qrc b/gui/base.qrc index 7b3fa55c..8f58f585 100644 --- a/gui/base.qrc +++ b/gui/base.qrc @@ -14,5 +14,13 @@ resources/zoom_out.png resources/shape_handles.png resources/shape_square.png + resources/control_play.png + resources/control_pause.png + resources/control_stop.png + resources/pack.png + resources/place.png + resources/route.png + resources/time_add.png + resources/open_json.png diff --git a/gui/ice40/nextpnr.qrc b/gui/ice40/nextpnr.qrc index 3c86057d..8eca1e09 100644 --- a/gui/ice40/nextpnr.qrc +++ b/gui/ice40/nextpnr.qrc @@ -1,14 +1,6 @@ - resources/control_play.png - resources/control_pause.png - resources/control_stop.png - resources/pack.png - resources/place.png - resources/route.png - resources/time_add.png resources/open_pcf.png resources/save_asc.png - resources/open_json.png diff --git a/gui/ice40/resources/control_pause.png b/gui/ice40/resources/control_pause.png deleted file mode 100644 index ec61099b..00000000 Binary files a/gui/ice40/resources/control_pause.png and /dev/null differ diff --git a/gui/ice40/resources/control_play.png b/gui/ice40/resources/control_play.png deleted file mode 100644 index f8c8ec68..00000000 Binary files a/gui/ice40/resources/control_play.png and /dev/null differ diff --git a/gui/ice40/resources/control_stop.png b/gui/ice40/resources/control_stop.png deleted file mode 100644 index e6f75d23..00000000 Binary files a/gui/ice40/resources/control_stop.png and /dev/null differ diff --git a/gui/ice40/resources/open_json.png b/gui/ice40/resources/open_json.png deleted file mode 100644 index 90c07267..00000000 Binary files a/gui/ice40/resources/open_json.png and /dev/null differ diff --git a/gui/ice40/resources/pack.png b/gui/ice40/resources/pack.png deleted file mode 100644 index da3c2a2d..00000000 Binary files a/gui/ice40/resources/pack.png and /dev/null differ diff --git a/gui/ice40/resources/place.png b/gui/ice40/resources/place.png deleted file mode 100644 index 0905f933..00000000 Binary files a/gui/ice40/resources/place.png and /dev/null differ diff --git a/gui/ice40/resources/route.png b/gui/ice40/resources/route.png deleted file mode 100644 index 258c16c6..00000000 Binary files a/gui/ice40/resources/route.png and /dev/null differ diff --git a/gui/ice40/resources/time_add.png b/gui/ice40/resources/time_add.png deleted file mode 100644 index dcc45cb2..00000000 Binary files a/gui/ice40/resources/time_add.png and /dev/null differ diff --git a/gui/resources/control_pause.png b/gui/resources/control_pause.png new file mode 100644 index 00000000..ec61099b Binary files /dev/null and b/gui/resources/control_pause.png differ diff --git a/gui/resources/control_play.png b/gui/resources/control_play.png new file mode 100644 index 00000000..f8c8ec68 Binary files /dev/null and b/gui/resources/control_play.png differ diff --git a/gui/resources/control_stop.png b/gui/resources/control_stop.png new file mode 100644 index 00000000..e6f75d23 Binary files /dev/null and b/gui/resources/control_stop.png differ diff --git a/gui/resources/open_json.png b/gui/resources/open_json.png new file mode 100644 index 00000000..90c07267 Binary files /dev/null and b/gui/resources/open_json.png differ diff --git a/gui/resources/pack.png b/gui/resources/pack.png new file mode 100644 index 00000000..da3c2a2d Binary files /dev/null and b/gui/resources/pack.png differ diff --git a/gui/resources/place.png b/gui/resources/place.png new file mode 100644 index 00000000..0905f933 Binary files /dev/null and b/gui/resources/place.png differ diff --git a/gui/resources/route.png b/gui/resources/route.png new file mode 100644 index 00000000..258c16c6 Binary files /dev/null and b/gui/resources/route.png differ diff --git a/gui/resources/time_add.png b/gui/resources/time_add.png new file mode 100644 index 00000000..dcc45cb2 Binary files /dev/null and b/gui/resources/time_add.png differ -- cgit v1.2.3 From a761b772c8294858590c4abced272d04bd58aad3 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 2 Aug 2018 18:10:01 +0200 Subject: Make worker generic --- gui/ice40/mainwindow.cc | 73 ++++++---------- gui/ice40/mainwindow.h | 5 +- gui/ice40/worker.cc | 221 ------------------------------------------------ gui/ice40/worker.h | 110 ------------------------ gui/worker.cc | 175 ++++++++++++++++++++++++++++++++++++++ gui/worker.h | 98 +++++++++++++++++++++ ice40/main.cc | 6 +- 7 files changed, 304 insertions(+), 384 deletions(-) delete mode 100644 gui/ice40/worker.cc delete mode 100644 gui/ice40/worker.h create mode 100644 gui/worker.cc create mode 100644 gui/worker.h diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc index f06971b6..bc790296 100644 --- a/gui/ice40/mainwindow.cc +++ b/gui/ice40/mainwindow.cc @@ -47,9 +47,6 @@ MainWindow::MainWindow(std::unique_ptr context, ArchArgs args, QWidget task = new TaskManager(); connect(task, SIGNAL(log(std::string)), this, SLOT(writeInfo(std::string))); - connect(task, SIGNAL(loadfile_finished(bool)), this, SLOT(loadfile_finished(bool))); - connect(task, SIGNAL(loadpcf_finished(bool)), this, SLOT(loadpcf_finished(bool))); - connect(task, SIGNAL(saveasc_finished(bool)), this, SLOT(saveasc_finished(bool))); 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))); @@ -238,19 +235,34 @@ void MainWindow::new_proj() } } -void MainWindow::load_json(std::string filename, std::string pcf) +void MainWindow::load_json(std::string filename) { disableActions(); currentJson = filename; - currentPCF = pcf; - Q_EMIT task->loadfile(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) { disableActions(); currentPCF = filename; - Q_EMIT task->loadpcf(filename); + std::ifstream f(filename); + if (apply_pcf(ctx.get(), f)) { + log("Loading PCF successful.\n"); + actionPack->setEnabled(true); + } else { + actionLoadPCF->setEnabled(true); + log("Loading PCF failed.\n"); + } } void MainWindow::newContext(Context *ctx) @@ -331,7 +343,9 @@ void MainWindow::open_proj() } log_info("Loading json: %s...\n", json.c_str()); - load_json(json, pcf); + load_json(json); + if (!pcf.empty()) + load_pcf(json); } catch (log_execution_error_exception) { } } @@ -341,7 +355,7 @@ void MainWindow::open_json() { QString fileName = QFileDialog::getOpenFileName(this, QString("Open JSON"), QString(), QString("*.json")); if (!fileName.isEmpty()) { - load_json(fileName.toStdString(), ""); + load_json(fileName.toStdString()); } } @@ -389,7 +403,9 @@ void MainWindow::save_asc() if (!fileName.isEmpty()) { std::string fn = fileName.toStdString(); disableActions(); - Q_EMIT task->saveasc(fn); + std::ofstream f(fn); + write_asc(ctx.get(), f); + log("Saving ASC successful.\n"); } } @@ -412,43 +428,6 @@ void MainWindow::disableActions() actionSave->setEnabled(!currentJson.empty()); } -void MainWindow::loadfile_finished(bool status) -{ - disableActions(); - if (status) { - log("Loading design successful.\n"); - actionLoadPCF->setEnabled(true); - actionPack->setEnabled(true); - if (!currentPCF.empty()) - load_pcf(currentPCF); - Q_EMIT updateTreeView(); - } else { - log("Loading design failed.\n"); - currentPCF = ""; - } -} - -void MainWindow::loadpcf_finished(bool status) -{ - disableActions(); - if (status) { - log("Loading PCF successful.\n"); - actionPack->setEnabled(true); - } else { - log("Loading PCF failed.\n"); - } -} - -void MainWindow::saveasc_finished(bool status) -{ - disableActions(); - if (status) { - log("Saving ASC successful.\n"); - } else { - log("Saving ASC failed.\n"); - } -} - void MainWindow::pack_finished(bool status) { disableActions(); diff --git a/gui/ice40/mainwindow.h b/gui/ice40/mainwindow.h index 4600d1da..b71af162 100644 --- a/gui/ice40/mainwindow.h +++ b/gui/ice40/mainwindow.h @@ -35,7 +35,7 @@ class MainWindow : public BaseMainWindow public: void createMenu(); - void load_json(std::string filename, std::string pcf); + void load_json(std::string filename); void load_pcf(std::string filename); protected Q_SLOTS: virtual void new_proj(); @@ -48,9 +48,6 @@ class MainWindow : public BaseMainWindow void place(); void save_asc(); - void loadfile_finished(bool status); - void loadpcf_finished(bool status); - void saveasc_finished(bool status); void pack_finished(bool status); void budget_finish(bool status); void place_finished(bool status); diff --git a/gui/ice40/worker.cc b/gui/ice40/worker.cc deleted file mode 100644 index 09093ec8..00000000 --- a/gui/ice40/worker.cc +++ /dev/null @@ -1,221 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Miodrag Milanovic - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "worker.h" -#include -#include "bitstream.h" -#include "design_utils.h" -#include "jsonparse.h" -#include "log.h" -#include "pcf.h" -#include "timing.h" - -NEXTPNR_NAMESPACE_BEGIN - -struct WorkerInterruptionRequested -{ -}; - -Worker::Worker(TaskManager *parent) : ctx(nullptr) -{ - log_write_function = [this, parent](std::string text) { - Q_EMIT log(text); - if (parent->shouldTerminate()) { - parent->clearTerminate(); - throw WorkerInterruptionRequested(); - } - if (parent->isPaused()) { - Q_EMIT taskPaused(); - } - while (parent->isPaused()) { - if (parent->shouldTerminate()) { - parent->clearTerminate(); - throw WorkerInterruptionRequested(); - } - QThread::sleep(1); - } - }; -} - -void Worker::newContext(Context *ctx_) { ctx = ctx_; } - -void Worker::loadfile(const std::string &filename) -{ - Q_EMIT taskStarted(); - std::string fn = filename; - std::ifstream f(fn); - try { - Q_EMIT loadfile_finished(parse_json_file(f, fn, ctx)); - } catch (WorkerInterruptionRequested) { - Q_EMIT taskCanceled(); - } -} - -void Worker::loadpcf(const std::string &filename) -{ - Q_EMIT taskStarted(); - std::string fn = filename; - std::ifstream f(fn); - try { - Q_EMIT loadpcf_finished(apply_pcf(ctx, f)); - } catch (WorkerInterruptionRequested) { - Q_EMIT taskCanceled(); - } -} - -void Worker::saveasc(const std::string &filename) -{ - Q_EMIT taskStarted(); - std::string fn = filename; - std::ofstream f(fn); - try { - write_asc(ctx, f); - Q_EMIT saveasc_finished(true); - } catch (WorkerInterruptionRequested) { - Q_EMIT taskCanceled(); - } -} - -void Worker::pack() -{ - Q_EMIT taskStarted(); - try { - bool res = ctx->pack(); - print_utilisation(ctx); - Q_EMIT pack_finished(res); - } catch (WorkerInterruptionRequested) { - Q_EMIT taskCanceled(); - } -} - -void Worker::budget(double freq) -{ - Q_EMIT taskStarted(); - try { - ctx->target_freq = freq; - assign_budget(ctx); - Q_EMIT budget_finish(true); - } catch (WorkerInterruptionRequested) { - Q_EMIT taskCanceled(); - } -} - -void Worker::place(bool timing_driven) -{ - Q_EMIT taskStarted(); - try { - ctx->timing_driven = timing_driven; - Q_EMIT place_finished(ctx->place()); - } catch (WorkerInterruptionRequested) { - Q_EMIT taskCanceled(); - } -} - -void Worker::route() -{ - Q_EMIT taskStarted(); - try { - Q_EMIT route_finished(ctx->route()); - } catch (WorkerInterruptionRequested) { - Q_EMIT taskCanceled(); - } -} - -TaskManager::TaskManager() : toTerminate(false), toPause(false) -{ - Worker *worker = new Worker(this); - worker->moveToThread(&workerThread); - - connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); - - connect(this, &TaskManager::loadfile, worker, &Worker::loadfile); - connect(this, &TaskManager::loadpcf, worker, &Worker::loadpcf); - connect(this, &TaskManager::saveasc, worker, &Worker::saveasc); - connect(this, &TaskManager::pack, worker, &Worker::pack); - connect(this, &TaskManager::budget, worker, &Worker::budget); - connect(this, &TaskManager::place, worker, &Worker::place); - connect(this, &TaskManager::route, worker, &Worker::route); - - connect(this, &TaskManager::contextChanged, worker, &Worker::newContext); - - connect(worker, &Worker::log, this, &TaskManager::info); - connect(worker, &Worker::loadfile_finished, this, &TaskManager::loadfile_finished); - connect(worker, &Worker::loadpcf_finished, this, &TaskManager::loadpcf_finished); - connect(worker, &Worker::saveasc_finished, this, &TaskManager::saveasc_finished); - connect(worker, &Worker::pack_finished, this, &TaskManager::pack_finished); - connect(worker, &Worker::budget_finish, this, &TaskManager::budget_finish); - connect(worker, &Worker::place_finished, this, &TaskManager::place_finished); - connect(worker, &Worker::route_finished, this, &TaskManager::route_finished); - - connect(worker, &Worker::taskCanceled, this, &TaskManager::taskCanceled); - connect(worker, &Worker::taskStarted, this, &TaskManager::taskStarted); - connect(worker, &Worker::taskPaused, this, &TaskManager::taskPaused); - - workerThread.start(); -} - -TaskManager::~TaskManager() -{ - if (workerThread.isRunning()) - terminate_thread(); - workerThread.quit(); - workerThread.wait(); -} - -void TaskManager::info(const std::string &result) { Q_EMIT log(result); } - -void TaskManager::terminate_thread() -{ - QMutexLocker locker(&mutex); - toPause = false; - toTerminate = true; -} - -bool TaskManager::shouldTerminate() -{ - QMutexLocker locker(&mutex); - return toTerminate; -} - -void TaskManager::clearTerminate() -{ - QMutexLocker locker(&mutex); - toTerminate = false; -} - -void TaskManager::pause_thread() -{ - QMutexLocker locker(&mutex); - toPause = true; -} - -void TaskManager::continue_thread() -{ - QMutexLocker locker(&mutex); - toPause = false; - Q_EMIT taskStarted(); -} - -bool TaskManager::isPaused() -{ - QMutexLocker locker(&mutex); - return toPause; -} - -NEXTPNR_NAMESPACE_END diff --git a/gui/ice40/worker.h b/gui/ice40/worker.h deleted file mode 100644 index f4369535..00000000 --- a/gui/ice40/worker.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Miodrag Milanovic - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#ifndef WORKER_H -#define WORKER_H - -#include -#include -#include "nextpnr.h" - -NEXTPNR_NAMESPACE_BEGIN - -class TaskManager; - -class Worker : public QObject -{ - Q_OBJECT - public: - explicit Worker(TaskManager *parent); - public Q_SLOTS: - void newContext(Context *); - void loadfile(const std::string &); - void loadpcf(const std::string &); - void saveasc(const std::string &); - void pack(); - void budget(double freq); - void place(bool timing_driven); - void route(); - Q_SIGNALS: - void log(const std::string &text); - void loadfile_finished(bool status); - void loadpcf_finished(bool status); - void saveasc_finished(bool status); - 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(); - - private: - Context *ctx; -}; - -class TaskManager : public QObject -{ - Q_OBJECT - QThread workerThread; - - public: - explicit TaskManager(); - ~TaskManager(); - bool shouldTerminate(); - void clearTerminate(); - bool isPaused(); - public Q_SLOTS: - void info(const std::string &text); - void terminate_thread(); - void pause_thread(); - void continue_thread(); - Q_SIGNALS: - void contextChanged(Context *ctx); - void terminate(); - void loadfile(const std::string &); - void loadpcf(const std::string &); - void saveasc(const std::string &); - void pack(); - void budget(double freq); - void place(bool timing_driven); - void route(); - - // redirected signals - void log(const std::string &text); - void loadfile_finished(bool status); - void loadpcf_finished(bool status); - void saveasc_finished(bool status); - 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(); - - private: - QMutex mutex; - bool toTerminate; - bool toPause; -}; - -NEXTPNR_NAMESPACE_END - -#endif // WORKER_H diff --git a/gui/worker.cc b/gui/worker.cc new file mode 100644 index 00000000..b009ecd3 --- /dev/null +++ b/gui/worker.cc @@ -0,0 +1,175 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Miodrag Milanovic + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "worker.h" +#include +#include "design_utils.h" +#include "log.h" +#include "timing.h" + +NEXTPNR_NAMESPACE_BEGIN + +struct WorkerInterruptionRequested +{ +}; + +Worker::Worker(TaskManager *parent) : ctx(nullptr) +{ + log_write_function = [this, parent](std::string text) { + Q_EMIT log(text); + if (parent->shouldTerminate()) { + parent->clearTerminate(); + throw WorkerInterruptionRequested(); + } + if (parent->isPaused()) { + Q_EMIT taskPaused(); + } + while (parent->isPaused()) { + if (parent->shouldTerminate()) { + parent->clearTerminate(); + throw WorkerInterruptionRequested(); + } + QThread::sleep(1); + } + }; +} + +void Worker::newContext(Context *ctx_) { ctx = ctx_; } + +void Worker::pack() +{ + Q_EMIT taskStarted(); + try { + bool res = ctx->pack(); + print_utilisation(ctx); + Q_EMIT pack_finished(res); + } catch (WorkerInterruptionRequested) { + Q_EMIT taskCanceled(); + } +} + +void Worker::budget(double freq) +{ + Q_EMIT taskStarted(); + try { + ctx->target_freq = freq; + assign_budget(ctx); + Q_EMIT budget_finish(true); + } catch (WorkerInterruptionRequested) { + Q_EMIT taskCanceled(); + } +} + +void Worker::place(bool timing_driven) +{ + Q_EMIT taskStarted(); + try { + ctx->timing_driven = timing_driven; + Q_EMIT place_finished(ctx->place()); + } catch (WorkerInterruptionRequested) { + Q_EMIT taskCanceled(); + } +} + +void Worker::route() +{ + Q_EMIT taskStarted(); + try { + Q_EMIT route_finished(ctx->route()); + } catch (WorkerInterruptionRequested) { + Q_EMIT taskCanceled(); + } +} + +TaskManager::TaskManager() : toTerminate(false), toPause(false) +{ + Worker *worker = new Worker(this); + worker->moveToThread(&workerThread); + + connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); + + connect(this, &TaskManager::pack, worker, &Worker::pack); + connect(this, &TaskManager::budget, worker, &Worker::budget); + connect(this, &TaskManager::place, worker, &Worker::place); + connect(this, &TaskManager::route, worker, &Worker::route); + + connect(this, &TaskManager::contextChanged, worker, &Worker::newContext); + + connect(worker, &Worker::log, this, &TaskManager::info); + connect(worker, &Worker::pack_finished, this, &TaskManager::pack_finished); + connect(worker, &Worker::budget_finish, this, &TaskManager::budget_finish); + connect(worker, &Worker::place_finished, this, &TaskManager::place_finished); + connect(worker, &Worker::route_finished, this, &TaskManager::route_finished); + + connect(worker, &Worker::taskCanceled, this, &TaskManager::taskCanceled); + connect(worker, &Worker::taskStarted, this, &TaskManager::taskStarted); + connect(worker, &Worker::taskPaused, this, &TaskManager::taskPaused); + + workerThread.start(); +} + +TaskManager::~TaskManager() +{ + if (workerThread.isRunning()) + terminate_thread(); + workerThread.quit(); + workerThread.wait(); +} + +void TaskManager::info(const std::string &result) { Q_EMIT log(result); } + +void TaskManager::terminate_thread() +{ + QMutexLocker locker(&mutex); + toPause = false; + toTerminate = true; +} + +bool TaskManager::shouldTerminate() +{ + QMutexLocker locker(&mutex); + return toTerminate; +} + +void TaskManager::clearTerminate() +{ + QMutexLocker locker(&mutex); + toTerminate = false; +} + +void TaskManager::pause_thread() +{ + QMutexLocker locker(&mutex); + toPause = true; +} + +void TaskManager::continue_thread() +{ + QMutexLocker locker(&mutex); + toPause = false; + Q_EMIT taskStarted(); +} + +bool TaskManager::isPaused() +{ + QMutexLocker locker(&mutex); + return toPause; +} + +NEXTPNR_NAMESPACE_END diff --git a/gui/worker.h b/gui/worker.h new file mode 100644 index 00000000..12a11977 --- /dev/null +++ b/gui/worker.h @@ -0,0 +1,98 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Miodrag Milanovic + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef WORKER_H +#define WORKER_H + +#include +#include +#include "nextpnr.h" + +NEXTPNR_NAMESPACE_BEGIN + +class TaskManager; + +class Worker : public QObject +{ + Q_OBJECT + public: + explicit Worker(TaskManager *parent); + public Q_SLOTS: + void newContext(Context *); + void pack(); + void budget(double freq); + void place(bool timing_driven); + void route(); + Q_SIGNALS: + void log(const std::string &text); + 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(); + + private: + Context *ctx; +}; + +class TaskManager : public QObject +{ + Q_OBJECT + QThread workerThread; + + public: + explicit TaskManager(); + ~TaskManager(); + bool shouldTerminate(); + void clearTerminate(); + bool isPaused(); + public Q_SLOTS: + void info(const std::string &text); + void terminate_thread(); + void pause_thread(); + void continue_thread(); + Q_SIGNALS: + void contextChanged(Context *ctx); + void terminate(); + void pack(); + void budget(double freq); + void place(bool timing_driven); + void route(); + + // redirected signals + void log(const std::string &text); + 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(); + + private: + QMutex mutex; + bool toTerminate; + bool toPause; +}; + +NEXTPNR_NAMESPACE_END + +#endif // WORKER_H diff --git a/ice40/main.cc b/ice40/main.cc index 358b46ba..4a2e9532 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -406,9 +406,11 @@ int main(int argc, char *argv[]) if (vm.count("json")) { std::string filename = vm["json"].as(); std::string pcf = ""; - if (vm.count("pcf")) + w.load_json(filename); + if (vm.count("pcf")) { pcf = vm["pcf"].as(); - w.load_json(filename, pcf); + w.load_pcf(pcf); + } } w.show(); -- cgit v1.2.3 From 4fa0c81ed7ea8a8ad1c636b3d9f45deb8c73a2c4 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 2 Aug 2018 18:50:08 +0200 Subject: Move common logic to basewindow --- gui/basewindow.cc | 250 +++++++++++++++++++++++++++++++++++++++++++--- gui/basewindow.h | 39 +++++++- gui/ecp5/mainwindow.cc | 8 +- gui/generic/mainwindow.cc | 8 +- gui/ice40/mainwindow.cc | 220 +++------------------------------------- gui/ice40/mainwindow.h | 32 +----- 6 files changed, 292 insertions(+), 265 deletions(-) diff --git a/gui/basewindow.cc b/gui/basewindow.cc index 685a205f..27d0b528 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -23,19 +23,22 @@ #include #include #include +#include #include #include "designwidget.h" #include "fpgaviewwidget.h" #include "log.h" #include "mainwindow.h" #include "pythontab.h" +#include "jsonparse.h" +#include static void initBasenameResource() { Q_INIT_RESOURCE(base); } NEXTPNR_NAMESPACE_BEGIN BaseMainWindow::BaseMainWindow(std::unique_ptr context, QWidget *parent) - : QMainWindow(parent), ctx(std::move(context)) + : QMainWindow(parent), ctx(std::move(context)), timing_driven(false) { initBasenameResource(); qRegisterMetaType(); @@ -46,7 +49,18 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr context, QWidget *parent setObjectName("BaseMainWindow"); 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); @@ -99,9 +113,11 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr context, QWidget *parent splitter_v->addWidget(centralTabWidget); splitter_v->addWidget(tabWidget); + + createMenusAndBars(); } -BaseMainWindow::~BaseMainWindow() {} +BaseMainWindow::~BaseMainWindow() { delete task; } void BaseMainWindow::closeTab(int index) { delete centralTabWidget->widget(index); } @@ -138,10 +154,9 @@ void BaseMainWindow::createMenusAndBars() menuBar = new QMenuBar(); menuBar->setGeometry(QRect(0, 0, 1024, 27)); - QMenu *menu_File = new QMenu("&File", menuBar); - QMenu *menu_Help = new QMenu("&Help", menuBar); - menuBar->addAction(menu_File->menuAction()); - menuBar->addAction(menu_Help->menuAction()); + QMenu *menuFile = new QMenu("&File", menuBar); + QMenu *menuHelp = new QMenu("&Help", menuBar); + menuDesign = new QMenu("&Design", menuBar); setMenuBar(menuBar); mainToolBar = new QToolBar(); @@ -156,20 +171,92 @@ void BaseMainWindow::createMenusAndBars() progressBar->setEnabled(false); setStatusBar(statusBar); - menu_File->addAction(actionNew); - menu_File->addAction(actionOpen); - menu_File->addAction(actionSave); - menu_File->addSeparator(); - menu_File->addAction(actionExit); - menu_Help->addAction(actionAbout); + menuFile->addAction(actionNew); + menuFile->addAction(actionOpen); + menuFile->addAction(actionSave); + menuFile->addSeparator(); + menuFile->addAction(actionExit); + menuHelp->addAction(actionAbout); mainToolBar->addAction(actionNew); mainToolBar->addAction(actionOpen); 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); actionZoomIn->setIcon(QIcon(":/icons/resources/zoom_in.png")); connect(actionZoomIn, SIGNAL(triggered()), fpgaView, SLOT(zoomIn())); @@ -194,4 +281,135 @@ void BaseMainWindow::createGraphicsBar() 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 diff --git a/gui/basewindow.h b/gui/basewindow.h index a25a2854..536ce786 100644 --- a/gui/basewindow.h +++ b/gui/basewindow.h @@ -21,6 +21,7 @@ #define BASEMAINWINDOW_H #include "nextpnr.h" +#include "worker.h" #include #include @@ -48,9 +49,16 @@ class BaseMainWindow : public QMainWindow virtual ~BaseMainWindow(); Context *getContext() { return ctx.get(); } + void load_json(std::string filename); protected: 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: void writeInfo(std::string text); @@ -60,12 +68,26 @@ class BaseMainWindow : public QMainWindow virtual void open_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: void contextChanged(Context *ctx); void updateTreeView(); protected: std::unique_ptr ctx; + TaskManager *task; QTabWidget *tabWidget; QTabWidget *centralTabWidget; PythonTab *console; @@ -77,9 +99,24 @@ class BaseMainWindow : public QMainWindow QAction *actionNew; QAction *actionOpen; QAction *actionSave; + + QAction *actionLoadJSON; + QAction *actionPack; + QAction *actionAssignBudget; + QAction *actionPlace; + QAction *actionRoute; + QAction *actionPlay; + QAction *actionPause; + QAction *actionStop; + + QMenu *menuDesign; + QToolBar *taskFPGABar; + QProgressBar *progressBar; DesignWidget *designview; FPGAViewWidget *fpgaView; + bool timing_driven; + std::string currentJson; }; NEXTPNR_NAMESPACE_END diff --git a/gui/ecp5/mainwindow.cc b/gui/ecp5/mainwindow.cc index 4b1c7e3b..935daefd 100644 --- a/gui/ecp5/mainwindow.cc +++ b/gui/ecp5/mainwindow.cc @@ -36,13 +36,7 @@ MainWindow::MainWindow(std::unique_ptr context, QWidget *parent) : Base MainWindow::~MainWindow() {} -void MainWindow::createMenu() -{ - QMenu *menu_Custom = new QMenu("&Generic", menuBar); - menuBar->addAction(menu_Custom->menuAction()); - - createGraphicsBar(); -} +void MainWindow::createMenu() {} void MainWindow::new_proj() {} diff --git a/gui/generic/mainwindow.cc b/gui/generic/mainwindow.cc index 1efc73bb..70ee600d 100644 --- a/gui/generic/mainwindow.cc +++ b/gui/generic/mainwindow.cc @@ -36,13 +36,7 @@ MainWindow::MainWindow(std::unique_ptr context, QWidget *parent) : Base MainWindow::~MainWindow() {} -void MainWindow::createMenu() -{ - QMenu *menu_Custom = new QMenu("&Generic", menuBar); - menuBar->addAction(menu_Custom->menuAction()); - - createGraphicsBar(); -} +void MainWindow::createMenu() {} void MainWindow::new_proj() {} diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc index bc790296..8f880191 100644 --- a/gui/ice40/mainwindow.cc +++ b/gui/ice40/mainwindow.cc @@ -37,127 +37,45 @@ static void initMainResource() { Q_INIT_RESOURCE(nextpnr); } NEXTPNR_NAMESPACE_BEGIN MainWindow::MainWindow(std::unique_ptr context, ArchArgs args, QWidget *parent) - : BaseMainWindow(std::move(context), parent), timing_driven(false), chipArgs(args) + : BaseMainWindow(std::move(context), parent), chipArgs(args) { initMainResource(); std::string title = "nextpnr-ice40 - [EMPTY]"; 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 *)), task, SIGNAL(contextChanged(Context *))); createMenu(); Q_EMIT contextChanged(ctx.get()); } -MainWindow::~MainWindow() { delete task; } +MainWindow::~MainWindow() {} 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->setIcon(QIcon(":/icons/resources/open_pcf.png")); actionLoadPCF->setStatusTip("Open PCF file"); actionLoadPCF->setEnabled(false); 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->setIcon(QIcon(":/icons/resources/save_asc.png")); actionSaveAsc->setStatusTip("Save ASC file"); actionSaveAsc->setEnabled(false); connect(actionSaveAsc, SIGNAL(triggered()), this, SLOT(save_asc())); - QToolBar *taskFPGABar = new QToolBar(); - addToolBar(Qt::TopToolBarArea, taskFPGABar); - - taskFPGABar->addAction(actionLoadJSON); + taskFPGABar->addSeparator(); taskFPGABar->addAction(actionLoadPCF); - taskFPGABar->addAction(actionPack); - taskFPGABar->addAction(actionAssignBudget); - taskFPGABar->addAction(actionPlace); - taskFPGABar->addAction(actionRoute); taskFPGABar->addAction(actionSaveAsc); + + menuDesign->addSeparator(); + menuDesign->addAction(actionLoadPCF); + menuDesign->addAction(actionSaveAsc); - menu_Design->addAction(actionLoadJSON); - menu_Design->addAction(actionLoadPCF); - menu_Design->addAction(actionPack); - 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) @@ -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) { 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() { 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); - actionPack->setEnabled(false); - actionAssignBudget->setEnabled(false); - actionPlace->setEnabled(false); - actionRoute->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(); - if (status) { - log("Packing design successful.\n"); - Q_EMIT updateTreeView(); - actionPlace->setEnabled(true); - actionAssignBudget->setEnabled(true); - } else { - log("Packing design failed.\n"); - } + actionLoadPCF->setEnabled(true); } - -void MainWindow::budget_finish(bool status) +void MainWindow::onRouteFinished() { - 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); - } 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); - } + actionSaveAsc->setEnabled(true); } -void MainWindow::place() { Q_EMIT task->place(timing_driven); } NEXTPNR_NAMESPACE_END diff --git a/gui/ice40/mainwindow.h b/gui/ice40/mainwindow.h index b71af162..e2e9a2e3 100644 --- a/gui/ice40/mainwindow.h +++ b/gui/ice40/mainwindow.h @@ -21,7 +21,6 @@ #define MAINWINDOW_H #include "../basewindow.h" -#include "worker.h" NEXTPNR_NAMESPACE_BEGIN @@ -35,50 +34,29 @@ class MainWindow : public BaseMainWindow public: void createMenu(); - void load_json(std::string filename); void load_pcf(std::string filename); + protected: + void onDisableActions() override; + void onJsonLoaded() override; + void onRouteFinished() override; + protected Q_SLOTS: virtual void new_proj(); virtual void open_proj(); virtual bool save_proj(); - void open_json(); void open_pcf(); - void budget(); - void place(); 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); private: - void disableActions(); - - TaskManager *task; - QAction *actionLoadJSON; QAction *actionLoadPCF; - QAction *actionPack; - QAction *actionAssignBudget; - QAction *actionPlace; - QAction *actionRoute; QAction *actionSaveAsc; - QAction *actionPlay; - QAction *actionPause; - QAction *actionStop; - bool timing_driven; ArchArgs chipArgs; std::string currentProj; - std::string currentJson; std::string currentPCF; }; -- cgit v1.2.3 From 44147dc7049457183abdcea8537c390300f3281b Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 2 Aug 2018 19:21:25 +0200 Subject: Document and cleanup --- gui/basewindow.cc | 189 ++++++++++++++++++++++++++---------------------- gui/basewindow.h | 23 +++--- gui/designwidget.h | 1 - gui/ice40/mainwindow.cc | 12 +-- 4 files changed, 120 insertions(+), 105 deletions(-) diff --git a/gui/basewindow.cc b/gui/basewindow.cc index 27d0b528..84d86483 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -50,20 +50,9 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr context, QWidget *parent resize(1024, 768); 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 *))); + // Create and deploy widgets on main screen QWidget *centralWidget = new QWidget(this); - QGridLayout *gridLayout = new QGridLayout(centralWidget); gridLayout->setSpacing(6); gridLayout->setContentsMargins(11, 11, 11, 11); @@ -84,35 +73,51 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr context, QWidget *parent console = new PythonTab(); tabWidget->addTab(console, "Console"); - connect(this, SIGNAL(contextChanged(Context *)), console, SLOT(newContext(Context *))); centralTabWidget = new QTabWidget(); centralTabWidget->setTabsClosable(true); - connect(centralTabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); fpgaView = new FPGAViewWidget(); centralTabWidget->addTab(fpgaView, "Device"); centralTabWidget->tabBar()->setTabButton(0, QTabBar::RightSide, 0); centralTabWidget->tabBar()->setTabButton(0, QTabBar::LeftSide, 0); + splitter_v->addWidget(centralTabWidget); + splitter_v->addWidget(tabWidget); + + // Connect Worker + 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())); + + // Events for context change + connect(this, SIGNAL(contextChanged(Context *)), task, SIGNAL(contextChanged(Context *))); + connect(this, SIGNAL(contextChanged(Context *)), console, SLOT(newContext(Context *))); connect(this, SIGNAL(contextChanged(Context *)), fpgaView, SLOT(newContext(Context *))); + connect(this, SIGNAL(contextChanged(Context *)), designview, SLOT(newContext(Context *))); + + // Catch close tab events + connect(centralTabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); + + // Propagate events from design view to device view connect(designview, SIGNAL(selected(std::vector, bool)), fpgaView, SLOT(onSelectedArchItem(std::vector, bool))); - connect(fpgaView, SIGNAL(clickedBel(BelId, bool)), designview, SLOT(onClickedBel(BelId, bool))); - connect(fpgaView, SIGNAL(clickedWire(WireId, bool)), designview, SLOT(onClickedWire(WireId, bool))); - connect(fpgaView, SIGNAL(clickedPip(PipId, bool)), designview, SLOT(onClickedPip(PipId, bool))); connect(designview, SIGNAL(zoomSelected()), fpgaView, SLOT(zoomSelected())); - connect(designview, SIGNAL(highlight(std::vector, int)), fpgaView, SLOT(onHighlightGroupChanged(std::vector, int))); - connect(this, SIGNAL(contextChanged(Context *)), designview, SLOT(newContext(Context *))); - connect(this, SIGNAL(updateTreeView()), designview, SLOT(updateTree())); - - connect(designview, SIGNAL(info(std::string)), this, SLOT(writeInfo(std::string))); + // Click event on device view + connect(fpgaView, SIGNAL(clickedBel(BelId, bool)), designview, SLOT(onClickedBel(BelId, bool))); + connect(fpgaView, SIGNAL(clickedWire(WireId, bool)), designview, SLOT(onClickedWire(WireId, bool))); + connect(fpgaView, SIGNAL(clickedPip(PipId, bool)), designview, SLOT(onClickedPip(PipId, bool))); - splitter_v->addWidget(centralTabWidget); - splitter_v->addWidget(tabWidget); + // Update tree event + connect(this, SIGNAL(updateTreeView()), designview, SLOT(updateTree())); createMenusAndBars(); } @@ -125,6 +130,7 @@ void BaseMainWindow::writeInfo(std::string text) { console->info(text); } void BaseMainWindow::createMenusAndBars() { + // File menu / project toolbar actions actionNew = new QAction("New", this); actionNew->setIcon(QIcon(":/icons/resources/new.png")); actionNew->setShortcuts(QKeySequence::New); @@ -150,42 +156,10 @@ void BaseMainWindow::createMenusAndBars() actionExit->setStatusTip("Exit the application"); connect(actionExit, SIGNAL(triggered()), this, SLOT(close())); + // Help menu actions QAction *actionAbout = new QAction("About", this); - menuBar = new QMenuBar(); - menuBar->setGeometry(QRect(0, 0, 1024, 27)); - QMenu *menuFile = new QMenu("&File", menuBar); - QMenu *menuHelp = new QMenu("&Help", menuBar); - menuDesign = new QMenu("&Design", menuBar); - setMenuBar(menuBar); - - mainToolBar = new QToolBar(); - addToolBar(Qt::TopToolBarArea, mainToolBar); - - statusBar = new QStatusBar(); - progressBar = new QProgressBar(statusBar); - progressBar->setAlignment(Qt::AlignRight); - progressBar->setMaximumSize(180, 19); - statusBar->addPermanentWidget(progressBar); - progressBar->setValue(0); - progressBar->setEnabled(false); - setStatusBar(statusBar); - - menuFile->addAction(actionNew); - menuFile->addAction(actionOpen); - menuFile->addAction(actionSave); - menuFile->addSeparator(); - menuFile->addAction(actionExit); - menuHelp->addAction(actionAbout); - - mainToolBar->addAction(actionNew); - mainToolBar->addAction(actionOpen); - mainToolBar->addAction(actionSave); - - menuBar->addAction(menuFile->menuAction()); - menuBar->addAction(menuDesign->menuAction()); - menuBar->addAction(menuHelp->menuAction()); - + // Design menu options actionLoadJSON = new QAction("Open JSON", this); actionLoadJSON->setIcon(QIcon(":/icons/resources/open_json.png")); actionLoadJSON->setStatusTip("Open an existing JSON file"); @@ -216,22 +190,7 @@ void BaseMainWindow::createMenusAndBars() 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); - + // Worker control toolbar actions actionPlay = new QAction("Play", this); actionPlay->setIcon(QIcon(":/icons/resources/control_play.png")); actionPlay->setStatusTip("Continue running task"); @@ -250,13 +209,7 @@ void BaseMainWindow::createMenusAndBars() 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); - + // Device view control toolbar actions QAction *actionZoomIn = new QAction("Zoom In", this); actionZoomIn->setIcon(QIcon(":/icons/resources/zoom_in.png")); connect(actionZoomIn, SIGNAL(triggered()), fpgaView, SLOT(zoomIn())); @@ -273,12 +226,74 @@ void BaseMainWindow::createMenusAndBars() actionZoomOutbound->setIcon(QIcon(":/icons/resources/shape_square.png")); connect(actionZoomOutbound, SIGNAL(triggered()), fpgaView, SLOT(zoomOutbound())); - graphicsToolBar = new QToolBar(); - addToolBar(Qt::TopToolBarArea, graphicsToolBar); - graphicsToolBar->addAction(actionZoomIn); - graphicsToolBar->addAction(actionZoomOut); - graphicsToolBar->addAction(actionZoomSelected); - graphicsToolBar->addAction(actionZoomOutbound); + // Add main menu + menuBar = new QMenuBar(); + menuBar->setGeometry(QRect(0, 0, 1024, 27)); + setMenuBar(menuBar); + QMenu *menuFile = new QMenu("&File", menuBar); + QMenu *menuHelp = new QMenu("&Help", menuBar); + menuDesign = new QMenu("&Design", menuBar); + menuBar->addAction(menuFile->menuAction()); + menuBar->addAction(menuDesign->menuAction()); + menuBar->addAction(menuHelp->menuAction()); + + // Add File menu actions + menuFile->addAction(actionNew); + menuFile->addAction(actionOpen); + menuFile->addAction(actionSave); + menuFile->addSeparator(); + menuFile->addAction(actionExit); + + // Add Design menu actions + menuDesign->addAction(actionLoadJSON); + menuDesign->addAction(actionPack); + menuDesign->addAction(actionAssignBudget); + menuDesign->addAction(actionPlace); + menuDesign->addAction(actionRoute); + + // Add Help menu actions + menuHelp->addAction(actionAbout); + + // Project toolbar + QToolBar *projectToolBar = new QToolBar(); + addToolBar(Qt::TopToolBarArea, projectToolBar); + projectToolBar->addAction(actionNew); + projectToolBar->addAction(actionOpen); + projectToolBar->addAction(actionSave); + + // Main action bar + mainActionBar = new QToolBar(); + addToolBar(Qt::TopToolBarArea, mainActionBar); + mainActionBar->addAction(actionLoadJSON); + mainActionBar->addAction(actionPack); + mainActionBar->addAction(actionAssignBudget); + mainActionBar->addAction(actionPlace); + mainActionBar->addAction(actionRoute); + + // Add worker control toolbar + QToolBar *workerControlToolBar = new QToolBar(); + addToolBar(Qt::TopToolBarArea, workerControlToolBar); + workerControlToolBar->addAction(actionPlay); + workerControlToolBar->addAction(actionPause); + workerControlToolBar->addAction(actionStop); + + // Add device view control toolbar + QToolBar *deviceViewToolBar = new QToolBar(); + addToolBar(Qt::TopToolBarArea, deviceViewToolBar); + deviceViewToolBar->addAction(actionZoomIn); + deviceViewToolBar->addAction(actionZoomOut); + deviceViewToolBar->addAction(actionZoomSelected); + deviceViewToolBar->addAction(actionZoomOutbound); + + // Add status bar with progress bar + statusBar = new QStatusBar(); + progressBar = new QProgressBar(statusBar); + progressBar->setAlignment(Qt::AlignRight); + progressBar->setMaximumSize(180, 19); + statusBar->addPermanentWidget(progressBar); + progressBar->setValue(0); + progressBar->setEnabled(false); + setStatusBar(statusBar); } void BaseMainWindow::load_json(std::string filename) diff --git a/gui/basewindow.h b/gui/basewindow.h index 536ce786..9cea6637 100644 --- a/gui/basewindow.h +++ b/gui/basewindow.h @@ -86,16 +86,26 @@ class BaseMainWindow : public QMainWindow void updateTreeView(); protected: + // state variables std::unique_ptr ctx; TaskManager *task; + bool timing_driven; + std::string currentJson; + + // main widgets QTabWidget *tabWidget; QTabWidget *centralTabWidget; PythonTab *console; + DesignWidget *designview; + FPGAViewWidget *fpgaView; + // Menus, bars and actions QMenuBar *menuBar; - QToolBar *mainToolBar; - QToolBar *graphicsToolBar; + QMenu *menuDesign; QStatusBar *statusBar; + QToolBar *mainActionBar; + QProgressBar *progressBar; + QAction *actionNew; QAction *actionOpen; QAction *actionSave; @@ -108,15 +118,6 @@ class BaseMainWindow : public QMainWindow QAction *actionPlay; QAction *actionPause; QAction *actionStop; - - QMenu *menuDesign; - QToolBar *taskFPGABar; - - QProgressBar *progressBar; - DesignWidget *designview; - FPGAViewWidget *fpgaView; - bool timing_driven; - std::string currentJson; }; NEXTPNR_NAMESPACE_END diff --git a/gui/designwidget.h b/gui/designwidget.h index 628586f4..c78d7232 100644 --- a/gui/designwidget.h +++ b/gui/designwidget.h @@ -53,7 +53,6 @@ class DesignWidget : public QWidget std::vector getDecals(ElementType type, IdString value); void updateHighlightGroup(QList item, int group); Q_SIGNALS: - void info(std::string text); void selected(std::vector decal, bool keep); void highlight(std::vector decal, int group); void zoomSelected(); diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc index 8f880191..10817e07 100644 --- a/gui/ice40/mainwindow.cc +++ b/gui/ice40/mainwindow.cc @@ -54,8 +54,8 @@ MainWindow::MainWindow(std::unique_ptr context, ArchArgs args, QWidget MainWindow::~MainWindow() {} void MainWindow::createMenu() -{ - +{ + // Add arch specific actions actionLoadPCF = new QAction("Open PCF", this); actionLoadPCF->setIcon(QIcon(":/icons/resources/open_pcf.png")); actionLoadPCF->setStatusTip("Open PCF file"); @@ -68,14 +68,14 @@ void MainWindow::createMenu() actionSaveAsc->setEnabled(false); connect(actionSaveAsc, SIGNAL(triggered()), this, SLOT(save_asc())); - taskFPGABar->addSeparator(); - taskFPGABar->addAction(actionLoadPCF); - taskFPGABar->addAction(actionSaveAsc); + // Add actions in menus + mainActionBar->addSeparator(); + mainActionBar->addAction(actionLoadPCF); + mainActionBar->addAction(actionSaveAsc); menuDesign->addSeparator(); menuDesign->addAction(actionLoadPCF); menuDesign->addAction(actionSaveAsc); - } #if defined(_MSC_VER) -- cgit v1.2.3 From e40b61e87e38fd64812991cf413675c52cbd29c8 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 2 Aug 2018 19:24:05 +0200 Subject: Add names to toolbars --- gui/basewindow.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gui/basewindow.cc b/gui/basewindow.cc index 84d86483..b7efe69e 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -255,14 +255,14 @@ void BaseMainWindow::createMenusAndBars() menuHelp->addAction(actionAbout); // Project toolbar - QToolBar *projectToolBar = new QToolBar(); + QToolBar *projectToolBar = new QToolBar("Project"); addToolBar(Qt::TopToolBarArea, projectToolBar); projectToolBar->addAction(actionNew); projectToolBar->addAction(actionOpen); projectToolBar->addAction(actionSave); // Main action bar - mainActionBar = new QToolBar(); + mainActionBar = new QToolBar("Main"); addToolBar(Qt::TopToolBarArea, mainActionBar); mainActionBar->addAction(actionLoadJSON); mainActionBar->addAction(actionPack); @@ -271,14 +271,14 @@ void BaseMainWindow::createMenusAndBars() mainActionBar->addAction(actionRoute); // Add worker control toolbar - QToolBar *workerControlToolBar = new QToolBar(); + QToolBar *workerControlToolBar = new QToolBar("Worker"); addToolBar(Qt::TopToolBarArea, workerControlToolBar); workerControlToolBar->addAction(actionPlay); workerControlToolBar->addAction(actionPause); workerControlToolBar->addAction(actionStop); // Add device view control toolbar - QToolBar *deviceViewToolBar = new QToolBar(); + QToolBar *deviceViewToolBar = new QToolBar("Device"); addToolBar(Qt::TopToolBarArea, deviceViewToolBar); deviceViewToolBar->addAction(actionZoomIn); deviceViewToolBar->addAction(actionZoomOut); -- cgit v1.2.3 From 23a7d96f4cbe43f5dba752d7c7bbd88ec2fa6bfd Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 2 Aug 2018 19:25:20 +0200 Subject: clangformat --- gui/basewindow.cc | 10 +++++----- gui/basewindow.h | 15 ++++++++------- gui/designwidget.cc | 6 +++--- gui/ice40/mainwindow.cc | 19 ++++++------------- gui/ice40/mainwindow.h | 1 + 5 files changed, 23 insertions(+), 28 deletions(-) diff --git a/gui/basewindow.cc b/gui/basewindow.cc index b7efe69e..c2937a67 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -25,13 +25,13 @@ #include #include #include +#include #include "designwidget.h" #include "fpgaviewwidget.h" +#include "jsonparse.h" #include "log.h" #include "mainwindow.h" #include "pythontab.h" -#include "jsonparse.h" -#include static void initBasenameResource() { Q_INIT_RESOURCE(base); } @@ -85,7 +85,7 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr context, QWidget *parent splitter_v->addWidget(centralTabWidget); splitter_v->addWidget(tabWidget); - // Connect Worker + // Connect Worker 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))); @@ -95,7 +95,7 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr context, QWidget *parent connect(task, SIGNAL(taskStarted()), this, SLOT(taskStarted())); connect(task, SIGNAL(taskPaused()), this, SLOT(taskPaused())); - // Events for context change + // Events for context change connect(this, SIGNAL(contextChanged(Context *)), task, SIGNAL(contextChanged(Context *))); connect(this, SIGNAL(contextChanged(Context *)), console, SLOT(newContext(Context *))); connect(this, SIGNAL(contextChanged(Context *)), fpgaView, SLOT(newContext(Context *))); @@ -104,7 +104,7 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr context, QWidget *parent // Catch close tab events connect(centralTabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); - // Propagate events from design view to device view + // Propagate events from design view to device view connect(designview, SIGNAL(selected(std::vector, bool)), fpgaView, SLOT(onSelectedArchItem(std::vector, bool))); connect(designview, SIGNAL(zoomSelected()), fpgaView, SLOT(zoomSelected())); diff --git a/gui/basewindow.h b/gui/basewindow.h index 9cea6637..5cec24c5 100644 --- a/gui/basewindow.h +++ b/gui/basewindow.h @@ -50,15 +50,16 @@ class BaseMainWindow : public QMainWindow Context *getContext() { return ctx.get(); } void load_json(std::string filename); + protected: void createMenusAndBars(); void disableActions(); - virtual void onDisableActions() {}; - virtual void onJsonLoaded() {}; - virtual void onPackFinished() {}; - virtual void onBudgetFinished() {}; - virtual void onPlaceFinished() {}; - virtual void onRouteFinished() {}; + virtual void onDisableActions(){}; + virtual void onJsonLoaded(){}; + virtual void onPackFinished(){}; + virtual void onBudgetFinished(){}; + virtual void onPlaceFinished(){}; + virtual void onRouteFinished(){}; protected Q_SLOTS: void writeInfo(std::string text); @@ -105,7 +106,7 @@ class BaseMainWindow : public QMainWindow QStatusBar *statusBar; QToolBar *mainActionBar; QProgressBar *progressBar; - + QAction *actionNew; QAction *actionOpen; QAction *actionSave; diff --git a/gui/designwidget.cc b/gui/designwidget.cc index 276b8b20..07bad774 100644 --- a/gui/designwidget.cc +++ b/gui/designwidget.cc @@ -317,7 +317,7 @@ QtProperty *DesignWidget::addSubGroup(QtProperty *topItem, const QString &name) void DesignWidget::onClickedBel(BelId bel, bool keep) { - boost::optional item; + boost::optional item; { std::lock_guard lock_ui(ctx->ui_mutex); std::lock_guard lock(ctx->mutex); @@ -334,7 +334,7 @@ void DesignWidget::onClickedBel(BelId bel, bool keep) void DesignWidget::onClickedWire(WireId wire, bool keep) { - boost::optional item; + boost::optional item; { std::lock_guard lock_ui(ctx->ui_mutex); std::lock_guard lock(ctx->mutex); @@ -351,7 +351,7 @@ void DesignWidget::onClickedWire(WireId wire, bool keep) void DesignWidget::onClickedPip(PipId pip, bool keep) { - boost::optional item; + boost::optional item; { std::lock_guard lock_ui(ctx->ui_mutex); std::lock_guard lock(ctx->mutex); diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc index 10817e07..ed017ee8 100644 --- a/gui/ice40/mainwindow.cc +++ b/gui/ice40/mainwindow.cc @@ -54,8 +54,8 @@ MainWindow::MainWindow(std::unique_ptr context, ArchArgs args, QWidget MainWindow::~MainWindow() {} void MainWindow::createMenu() -{ - // Add arch specific actions +{ + // Add arch specific actions actionLoadPCF = new QAction("Open PCF", this); actionLoadPCF->setIcon(QIcon(":/icons/resources/open_pcf.png")); actionLoadPCF->setStatusTip("Open PCF file"); @@ -72,7 +72,7 @@ void MainWindow::createMenu() mainActionBar->addSeparator(); mainActionBar->addAction(actionLoadPCF); mainActionBar->addAction(actionSaveAsc); - + menuDesign->addSeparator(); menuDesign->addAction(actionLoadPCF); menuDesign->addAction(actionSaveAsc); @@ -157,7 +157,7 @@ void MainWindow::load_pcf(std::string filename) { disableActions(); currentPCF = filename; - std::ifstream f(filename); + std::ifstream f(filename); if (apply_pcf(ctx.get(), f)) { log("Loading PCF successful.\n"); actionPack->setEnabled(true); @@ -309,14 +309,7 @@ void MainWindow::onDisableActions() actionSaveAsc->setEnabled(false); } -void MainWindow::onJsonLoaded() -{ - actionLoadPCF->setEnabled(true); -} -void MainWindow::onRouteFinished() -{ - actionSaveAsc->setEnabled(true); -} - +void MainWindow::onJsonLoaded() { actionLoadPCF->setEnabled(true); } +void MainWindow::onRouteFinished() { actionSaveAsc->setEnabled(true); } NEXTPNR_NAMESPACE_END diff --git a/gui/ice40/mainwindow.h b/gui/ice40/mainwindow.h index e2e9a2e3..230ccc4e 100644 --- a/gui/ice40/mainwindow.h +++ b/gui/ice40/mainwindow.h @@ -35,6 +35,7 @@ class MainWindow : public BaseMainWindow public: void createMenu(); void load_pcf(std::string filename); + protected: void onDisableActions() override; void onJsonLoaded() override; -- cgit v1.2.3 From 8abf38f37ff57f2b176d584e096d79894e6e6b88 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 3 Aug 2018 10:53:38 +0200 Subject: Moved to new signal slot syntax --- gui/basewindow.cc | 74 ++++++++++++++++++++++++------------------------- gui/designwidget.cc | 5 ++-- gui/ice40/mainwindow.cc | 6 ++-- gui/line_editor.cc | 6 ++-- gui/pythontab.cc | 6 ++-- 5 files changed, 47 insertions(+), 50 deletions(-) diff --git a/gui/basewindow.cc b/gui/basewindow.cc index c2937a67..37141fd6 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -86,38 +86,36 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr context, QWidget *parent splitter_v->addWidget(tabWidget); // Connect Worker - 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(task, &TaskManager::log, this, &BaseMainWindow::writeInfo); + connect(task, &TaskManager::pack_finished, this, &BaseMainWindow::pack_finished); + connect(task, &TaskManager::budget_finish, this, &BaseMainWindow::budget_finish); + connect(task, &TaskManager::place_finished, this, &BaseMainWindow::place_finished); + connect(task, &TaskManager::route_finished, this, &BaseMainWindow::route_finished); + connect(task, &TaskManager::taskCanceled, this, &BaseMainWindow::taskCanceled); + connect(task, &TaskManager::taskStarted, this, &BaseMainWindow::taskStarted); + connect(task, &TaskManager::taskPaused, this, &BaseMainWindow::taskPaused); // Events for context change - connect(this, SIGNAL(contextChanged(Context *)), task, SIGNAL(contextChanged(Context *))); - connect(this, SIGNAL(contextChanged(Context *)), console, SLOT(newContext(Context *))); - connect(this, SIGNAL(contextChanged(Context *)), fpgaView, SLOT(newContext(Context *))); - connect(this, SIGNAL(contextChanged(Context *)), designview, SLOT(newContext(Context *))); + connect(this, &BaseMainWindow::contextChanged, task, &TaskManager::contextChanged); + connect(this, &BaseMainWindow::contextChanged, console, &PythonTab::newContext); + connect(this, &BaseMainWindow::contextChanged, fpgaView, &FPGAViewWidget::newContext); + connect(this, &BaseMainWindow::contextChanged, designview, &DesignWidget::newContext); // Catch close tab events - connect(centralTabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); + connect(centralTabWidget, &QTabWidget::tabCloseRequested, this, &BaseMainWindow::closeTab); // Propagate events from design view to device view - connect(designview, SIGNAL(selected(std::vector, bool)), fpgaView, - SLOT(onSelectedArchItem(std::vector, bool))); - connect(designview, SIGNAL(zoomSelected()), fpgaView, SLOT(zoomSelected())); - connect(designview, SIGNAL(highlight(std::vector, int)), fpgaView, - SLOT(onHighlightGroupChanged(std::vector, int))); + connect(designview, &DesignWidget::selected, fpgaView, &FPGAViewWidget::onSelectedArchItem); + connect(designview, &DesignWidget::zoomSelected, fpgaView, &FPGAViewWidget::zoomSelected); + connect(designview, &DesignWidget::highlight, fpgaView, &FPGAViewWidget::onHighlightGroupChanged); // Click event on device view - connect(fpgaView, SIGNAL(clickedBel(BelId, bool)), designview, SLOT(onClickedBel(BelId, bool))); - connect(fpgaView, SIGNAL(clickedWire(WireId, bool)), designview, SLOT(onClickedWire(WireId, bool))); - connect(fpgaView, SIGNAL(clickedPip(PipId, bool)), designview, SLOT(onClickedPip(PipId, bool))); + connect(fpgaView, &FPGAViewWidget::clickedBel, designview, &DesignWidget::onClickedBel); + connect(fpgaView, &FPGAViewWidget::clickedWire, designview, &DesignWidget::onClickedWire); + connect(fpgaView, &FPGAViewWidget::clickedPip, designview, &DesignWidget::onClickedPip); // Update tree event - connect(this, SIGNAL(updateTreeView()), designview, SLOT(updateTree())); + connect(this, &BaseMainWindow::updateTreeView, designview, &DesignWidget::updateTree); createMenusAndBars(); } @@ -135,26 +133,26 @@ void BaseMainWindow::createMenusAndBars() actionNew->setIcon(QIcon(":/icons/resources/new.png")); actionNew->setShortcuts(QKeySequence::New); actionNew->setStatusTip("New project file"); - connect(actionNew, SIGNAL(triggered()), this, SLOT(new_proj())); + connect(actionNew, &QAction::triggered, this, &BaseMainWindow::new_proj); actionOpen = new QAction("Open", this); actionOpen->setIcon(QIcon(":/icons/resources/open.png")); actionOpen->setShortcuts(QKeySequence::Open); actionOpen->setStatusTip("Open an existing project file"); - connect(actionOpen, SIGNAL(triggered()), this, SLOT(open_proj())); + connect(actionOpen, &QAction::triggered, this, &BaseMainWindow::open_proj); actionSave = new QAction("Save", this); actionSave->setIcon(QIcon(":/icons/resources/save.png")); actionSave->setShortcuts(QKeySequence::Save); actionSave->setStatusTip("Save existing project to disk"); actionSave->setEnabled(false); - connect(actionSave, SIGNAL(triggered()), this, SLOT(save_proj())); + connect(actionSave, &QAction::triggered, this, &BaseMainWindow::save_proj); QAction *actionExit = new QAction("Exit", this); actionExit->setIcon(QIcon(":/icons/resources/exit.png")); actionExit->setShortcuts(QKeySequence::Quit); actionExit->setStatusTip("Exit the application"); - connect(actionExit, SIGNAL(triggered()), this, SLOT(close())); + connect(actionExit, &QAction::triggered, this, &BaseMainWindow::close); // Help menu actions QAction *actionAbout = new QAction("About", this); @@ -164,67 +162,67 @@ void BaseMainWindow::createMenusAndBars() 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())); + connect(actionLoadJSON, &QAction::triggered, this, &BaseMainWindow::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())); + connect(actionPack, &QAction::triggered, task, &TaskManager::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())); + connect(actionAssignBudget, &QAction::triggered, this, &BaseMainWindow::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())); + connect(actionPlace, &QAction::triggered, this, &BaseMainWindow::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())); + connect(actionRoute, &QAction::triggered, task, &TaskManager::route); // Worker control toolbar actions 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())); + connect(actionPlay, &QAction::triggered, task, &TaskManager::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())); + connect(actionPause, &QAction::triggered, task, &TaskManager::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())); + connect(actionStop, &QAction::triggered, task, &TaskManager::terminate_thread); // Device view control toolbar actions QAction *actionZoomIn = new QAction("Zoom In", this); actionZoomIn->setIcon(QIcon(":/icons/resources/zoom_in.png")); - connect(actionZoomIn, SIGNAL(triggered()), fpgaView, SLOT(zoomIn())); + connect(actionZoomIn, &QAction::triggered, fpgaView, &FPGAViewWidget::zoomIn); QAction *actionZoomOut = new QAction("Zoom Out", this); actionZoomOut->setIcon(QIcon(":/icons/resources/zoom_out.png")); - connect(actionZoomOut, SIGNAL(triggered()), fpgaView, SLOT(zoomOut())); + connect(actionZoomOut, &QAction::triggered, fpgaView, &FPGAViewWidget::zoomOut); QAction *actionZoomSelected = new QAction("Zoom Selected", this); actionZoomSelected->setIcon(QIcon(":/icons/resources/shape_handles.png")); - connect(actionZoomSelected, SIGNAL(triggered()), fpgaView, SLOT(zoomSelected())); + connect(actionZoomSelected, &QAction::triggered, fpgaView, &FPGAViewWidget::zoomSelected); QAction *actionZoomOutbound = new QAction("Zoom Outbound", this); actionZoomOutbound->setIcon(QIcon(":/icons/resources/shape_square.png")); - connect(actionZoomOutbound, SIGNAL(triggered()), fpgaView, SLOT(zoomOutbound())); + connect(actionZoomOutbound, &QAction::triggered, fpgaView, &FPGAViewWidget::zoomOutbound); // Add main menu menuBar = new QMenuBar(); diff --git a/gui/designwidget.cc b/gui/designwidget.cc index 07bad774..5a448235 100644 --- a/gui/designwidget.cc +++ b/gui/designwidget.cc @@ -55,7 +55,7 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel searchEdit->setClearButtonEnabled(true); searchEdit->addAction(QIcon(":/icons/resources/zoom.png"), QLineEdit::LeadingPosition); searchEdit->setPlaceholderText("Search..."); - connect(searchEdit, SIGNAL(returnPressed()), this, SLOT(onSearchInserted())); + connect(searchEdit, &QLineEdit::returnPressed, this, &DesignWidget::onSearchInserted); actionFirst = new QAction("", this); actionFirst->setIcon(QIcon(":/icons/resources/resultset_first.png")); @@ -162,8 +162,7 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel connect(treeView, &QTreeView::customContextMenuRequested, this, &DesignWidget::prepareMenuTree); connect(treeView, &QTreeView::doubleClicked, this, &DesignWidget::onDoubleClicked); selectionModel = treeView->selectionModel(); - connect(selectionModel, SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), - SLOT(onSelectionChanged(const QItemSelection &, const QItemSelection &))); + connect(selectionModel, &QItemSelectionModel::selectionChanged, this, &DesignWidget::onSelectionChanged); history_index = -1; history_ignore = false; diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc index ed017ee8..2fa2e561 100644 --- a/gui/ice40/mainwindow.cc +++ b/gui/ice40/mainwindow.cc @@ -44,7 +44,7 @@ MainWindow::MainWindow(std::unique_ptr context, ArchArgs args, QWidget std::string title = "nextpnr-ice40 - [EMPTY]"; setWindowTitle(title.c_str()); - connect(this, SIGNAL(contextChanged(Context *)), this, SLOT(newContext(Context *))); + connect(this, &BaseMainWindow::contextChanged, this, &MainWindow::newContext); createMenu(); @@ -60,13 +60,13 @@ void MainWindow::createMenu() actionLoadPCF->setIcon(QIcon(":/icons/resources/open_pcf.png")); actionLoadPCF->setStatusTip("Open PCF file"); actionLoadPCF->setEnabled(false); - connect(actionLoadPCF, SIGNAL(triggered()), this, SLOT(open_pcf())); + connect(actionLoadPCF, &QAction::triggered, this, &MainWindow::open_pcf); actionSaveAsc = new QAction("Save ASC", this); actionSaveAsc->setIcon(QIcon(":/icons/resources/save_asc.png")); actionSaveAsc->setStatusTip("Save ASC file"); actionSaveAsc->setEnabled(false); - connect(actionSaveAsc, SIGNAL(triggered()), this, SLOT(save_asc())); + connect(actionSaveAsc, &QAction::triggered, this, &MainWindow::save_asc); // Add actions in menus mainActionBar->addSeparator(); diff --git a/gui/line_editor.cc b/gui/line_editor.cc index 23415092..b25f4031 100644 --- a/gui/line_editor.cc +++ b/gui/line_editor.cc @@ -32,13 +32,13 @@ LineEditor::LineEditor(ParseHelper *helper, QWidget *parent) : QLineEdit(parent) setContextMenuPolicy(Qt::CustomContextMenu); QAction *clearAction = new QAction("Clear &history", this); clearAction->setStatusTip("Clears line edit history"); - connect(clearAction, SIGNAL(triggered()), this, SLOT(clearHistory())); + connect(clearAction, &QAction::triggered, this, &LineEditor::clearHistory); contextMenu = createStandardContextMenu(); contextMenu->addSeparator(); contextMenu->addAction(clearAction); - connect(this, SIGNAL(returnPressed()), SLOT(textInserted())); - connect(this, SIGNAL(customContextMenuRequested(const QPoint)), this, SLOT(showContextMenu(const QPoint))); + connect(this, &LineEditor::returnPressed, this, &LineEditor::textInserted); + connect(this, &LineEditor::customContextMenuRequested, this, &LineEditor::showContextMenu); } void LineEditor::keyPressEvent(QKeyEvent *ev) diff --git a/gui/pythontab.cc b/gui/pythontab.cc index e761128d..80d731e9 100644 --- a/gui/pythontab.cc +++ b/gui/pythontab.cc @@ -42,18 +42,18 @@ PythonTab::PythonTab(QWidget *parent) : QWidget(parent), initialized(false) console->setContextMenuPolicy(Qt::CustomContextMenu); QAction *clearAction = new QAction("Clear &buffer", this); clearAction->setStatusTip("Clears display buffer"); - connect(clearAction, SIGNAL(triggered()), this, SLOT(clearBuffer())); + connect(clearAction, &QAction::triggered, this, &PythonTab::clearBuffer); contextMenu = console->createStandardContextMenu(); contextMenu->addSeparator(); contextMenu->addAction(clearAction); - connect(console, SIGNAL(customContextMenuRequested(const QPoint)), this, SLOT(showContextMenu(const QPoint))); + connect(console, &PythonConsole::customContextMenuRequested, this, &PythonTab::showContextMenu); lineEdit = new LineEditor(&parseHelper); lineEdit->setMinimumHeight(30); lineEdit->setMaximumHeight(30); lineEdit->setFont(f); lineEdit->setPlaceholderText(PythonTab::PROMPT); - connect(lineEdit, SIGNAL(textLineInserted(QString)), this, SLOT(editLineReturnPressed(QString))); + connect(lineEdit, &LineEditor::textLineInserted, this, &PythonTab::editLineReturnPressed); QGridLayout *mainLayout = new QGridLayout(); mainLayout->addWidget(console, 0, 0); -- cgit v1.2.3 From 90623b80e8c37e71e095cc377ce9e8c032af679b Mon Sep 17 00:00:00 2001 From: David Shah Date: Fri, 3 Aug 2018 12:00:07 +0200 Subject: ecp5: Refresh Bels when they are modified Signed-off-by: David Shah --- ecp5/arch.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ecp5/arch.h b/ecp5/arch.h index d450321d..cd103b12 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -454,6 +454,7 @@ struct Arch : BaseCtx bel_to_cell[bel] = cell; cells[cell]->bel = bel; cells[cell]->belStrength = strength; + refreshUiBel(bel); } void unbindBel(BelId bel) @@ -463,6 +464,7 @@ struct Arch : BaseCtx cells[bel_to_cell[bel]]->bel = BelId(); cells[bel_to_cell[bel]]->belStrength = STRENGTH_NONE; bel_to_cell[bel] = IdString(); + refreshUiBel(bel); } Loc getBelLocation(BelId bel) const -- cgit v1.2.3