diff --git a/images/chip_off.png b/images/chip_off.png new file mode 100644 index 0000000..61c209b Binary files /dev/null and b/images/chip_off.png differ diff --git a/images/chip_on.png b/images/chip_on.png new file mode 100644 index 0000000..ed36ef1 Binary files /dev/null and b/images/chip_on.png differ diff --git a/images/refresh.png b/images/refresh.png new file mode 100644 index 0000000..308b494 Binary files /dev/null and b/images/refresh.png differ diff --git a/src/gstar/Annotation/ScanRegionGraphicsItem.cpp b/src/gstar/Annotation/ScanRegionGraphicsItem.cpp index c36435b..9813d90 100644 --- a/src/gstar/Annotation/ScanRegionGraphicsItem.cpp +++ b/src/gstar/Annotation/ScanRegionGraphicsItem.cpp @@ -15,10 +15,11 @@ using namespace gstar; //--------------------------------------------------------------------------- -ScanRegionGraphicsItem::ScanRegionGraphicsItem(AbstractGraphicsItem* parent) +ScanRegionGraphicsItem::ScanRegionGraphicsItem(std::map * avail_scans, AbstractGraphicsItem* parent) : UProbeRegionGraphicsItem(parent) { - + _avail_scans = avail_scans; + _scan_dialog.setAvailScans(avail_scans); connect(&_scan_dialog, &ScanRegionDialog::ScanUpdated, this, &ScanRegionGraphicsItem::onScanUpdated); prependProperty(new AnnotationProperty("Edit", QIcon(":/images/editing.png"))); @@ -124,7 +125,7 @@ const QString ScanRegionGraphicsItem::displayName() const ScanRegionGraphicsItem* ScanRegionGraphicsItem::cloneRegion() { - ScanRegionGraphicsItem* newRegion = new ScanRegionGraphicsItem(); + ScanRegionGraphicsItem* newRegion = new ScanRegionGraphicsItem(_avail_scans); //newRegion->m_outlineColor = m_outlineColor; newRegion->m_rect = m_rect; @@ -142,10 +143,18 @@ QDialog* ScanRegionGraphicsItem::get_custom_dialog() //--------------------------------------------------------------------------- -void ScanRegionGraphicsItem::onScanUpdated() +void ScanRegionGraphicsItem::onScanUpdated(const BlueskyPlan& plan) { setPropertyValue(DEF_STR_DISPLAY_NAME, _scan_dialog.getScanName()); + BlueskyPlan nplan = plan; + nplan.name = _scan_dialog.getScanName(); + BlueskyParam meta_data; + meta_data.name = "md"; + meta_data.default_val = nplan.name; + meta_data.description = "Link to scan name"; + nplan.parameters["md"] = meta_data; + emit scanUpdated(nplan); } /* diff --git a/src/gstar/Annotation/ScanRegionGraphicsItem.h b/src/gstar/Annotation/ScanRegionGraphicsItem.h index 1242889..6104538 100644 --- a/src/gstar/Annotation/ScanRegionGraphicsItem.h +++ b/src/gstar/Annotation/ScanRegionGraphicsItem.h @@ -24,6 +24,7 @@ #include "gstar/CoordinateModel.h" #include "gstar/Annotation/UProbeRegionGraphicsItem.h" #include "mvc/ScanRegionDialog.h" +#include "mvc/BlueSkyPlan.h" //--------------------------------------------------------------------------- @@ -46,7 +47,7 @@ Q_OBJECT * @param h - height * @param parent - parent Qt widget */ - ScanRegionGraphicsItem(AbstractGraphicsItem* parent = 0); + ScanRegionGraphicsItem(std::map * avail_scans, AbstractGraphicsItem* parent = 0); /** * @brief MarkerGraphicsItem @@ -148,13 +149,18 @@ Q_OBJECT void mouseReleaseEvent(QGraphicsSceneMouseEvent* event); */ +signals: + + void scanUpdated(const BlueskyPlan &plan); + public slots: - void onScanUpdated(); + void onScanUpdated(const BlueskyPlan &plan); private: ScanRegionDialog _scan_dialog; + std::map *_avail_scans; /* void initialScale(); diff --git a/src/mvc/BatchRoiFitWidget.cpp b/src/mvc/BatchRoiFitWidget.cpp index b5d7cca..cd1c35f 100644 --- a/src/mvc/BatchRoiFitWidget.cpp +++ b/src/mvc/BatchRoiFitWidget.cpp @@ -54,8 +54,8 @@ void BatchRoiFitWidget::createLayout() _cb_opt_method = new QComboBox(); _cb_opt_method->addItem(STR_HYBRID_MP_FIT); - _cb_opt_method->addItem(STR_LM_FIT); _cb_opt_method->addItem(STR_MP_FIT); + _cb_opt_method->addItem(STR_LM_FIT); connect(_cb_opt_method, &QComboBox::currentTextChanged, this, &BatchRoiFitWidget::optimizer_changed); _file_list_model = new QStandardItemModel(); diff --git a/src/mvc/BlueskyComm.h b/src/mvc/BlueskyComm.h index 2f7b816..637f69d 100644 --- a/src/mvc/BlueskyComm.h +++ b/src/mvc/BlueskyComm.h @@ -13,6 +13,7 @@ #include #include #include "support/zmq/zmq.hpp" +#include "mvc/BlueskyPlan.h" #include //--------------------------------------------------------------------------- @@ -30,7 +31,7 @@ class BlueskyComm : public QThread BlueskyComm(QString str_ip, QObject* parent = nullptr) : QThread(parent) { - std::string conn_str = "tcp://"+str_ip.toStdString()+":60610"; // or 60615 + std::string conn_str = "tcp://"+str_ip.toStdString()+":60615"; std::string lsn_str = "tcp://"+str_ip.toStdString()+":60625"; _context = new zmq::context_t(1); _zmq_comm_socket = new zmq::socket_t(*_context, ZMQ_REQ); @@ -42,6 +43,8 @@ class BlueskyComm : public QThread } + //--------------------------------------------------------------------------- + /** * Destructor. */ @@ -67,6 +70,453 @@ class BlueskyComm : public QThread _context = nullptr; } + //--------------------------------------------------------------------------- + + QByteArray gen_send_mesg(QString method, std::map *params) + { + QJsonDocument doc; + QJsonObject obj; + obj["method"] = method; + if(params != nullptr) + { + QJsonObject jparams; + for( auto itr : *params ) + { + jparams[itr.first] = itr.second ; + } + obj["params"] = jparams; + } + doc.setObject(obj); + return doc.toJson(); + } + + //--------------------------------------------------------------------------- + + QByteArray gen_send_mesg2(QString method, QJsonObject ¶ms) + { + QJsonDocument doc; + QJsonObject obj; + obj["method"] = method; + obj["params"] = params; + doc.setObject(obj); + return doc.toJson(); + } + + //--------------------------------------------------------------------------- + + QJsonObject plan_to_json_item(const BlueskyPlan& plan) + { + /* + {'name': 'count', + 'args': [['det1', 'det2']], + 'kwargs': {'num': 10, 'delay': 1}, + 'item_type': 'plan', + 'user': 'qserver-cli', + 'user_group': 'primary', + 'item_uid': 'f66d959f-12e2-43a5-a67d-01b3d40b4f43'} + */ + + QJsonObject item; + + item["name"] = plan.type; + item["item_type"] = "plan"; + + QJsonObject kwargs; + for(auto itr: plan.parameters) + { + kwargs[itr.first] = itr.second.default_val; + } + item["kwargs"] = kwargs; + + return item; + } + + //--------------------------------------------------------------------------- + + bool open_env(QString &msg) + { + // + bool ret = false; + + if(_zmq_comm_socket == nullptr) + { + return ret; + } + zmq::message_t message; + QByteArray msg_arr = gen_send_mesg("environment_open", nullptr); + _zmq_comm_socket->send(msg_arr.data(), msg_arr.length()); + + _zmq_comm_socket->recv(&message); + QJsonObject reply = QJsonDocument::fromJson(QString::fromUtf8((char*)message.data(), message.size()).toUtf8()).object(); + if(reply.contains("success")) + { + if(reply["success"].toString() == "true") + { + ret = true; + } + } + if(reply.contains("msg")) + { + msg = reply["msg"].toString(); + } + return ret; + } + + //--------------------------------------------------------------------------- + + bool close_env(QString &msg) + { + // + bool ret = false; + if(_zmq_comm_socket == nullptr) + { + return ret; + } + zmq::message_t message; + QByteArray msg_arr = gen_send_mesg("environment_close", nullptr); + _zmq_comm_socket->send(msg_arr.data(), msg_arr.length()); + + _zmq_comm_socket->recv(&message); + QJsonObject reply = QJsonDocument::fromJson(QString::fromUtf8((char*)message.data(), message.size()).toUtf8()).object(); + if(reply.contains("success")) + { + if(reply["success"].toString() == "true") + { + ret = true; + } + } + if(reply.contains("msg")) + { + msg = reply["msg"].toString(); + } + return ret; + } + + //--------------------------------------------------------------------------- + + bool start_queue(QString &msg) + { + // + bool ret = false; + if(_zmq_comm_socket == nullptr) + { + return ret; + } + zmq::message_t message; + QByteArray msg_arr = gen_send_mesg("queue_start", nullptr); + _zmq_comm_socket->send(msg_arr.data(), msg_arr.length()); + + _zmq_comm_socket->recv(&message); + QJsonObject reply = QJsonDocument::fromJson(QString::fromUtf8((char*)message.data(), message.size()).toUtf8()).object(); + if(reply.contains("success")) + { + if(reply["success"].toString() == "true") + { + ret = true; + } + } + if(reply.contains("msg")) + { + msg = reply["msg"].toString(); + } + return ret; + } + + //--------------------------------------------------------------------------- + + bool stop_queue(QString &msg) + { + // + bool ret = false; + if(_zmq_comm_socket == nullptr) + { + return ret; + } + zmq::message_t message; + QByteArray msg_arr = gen_send_mesg("queue_stop", nullptr); + _zmq_comm_socket->send(msg_arr.data(), msg_arr.length()); + + _zmq_comm_socket->recv(&message); + QJsonObject reply = QJsonDocument::fromJson(QString::fromUtf8((char*)message.data(), message.size()).toUtf8()).object(); + if(reply.contains("success")) + { + if(reply["success"].toString() == "true") + { + ret = true; + } + } + if(reply.contains("msg")) + { + msg = reply["msg"].toString(); + } + return ret; + } + + //--------------------------------------------------------------------------- + + bool queue_plan(QString &msg, const BlueskyPlan& plan) + { + bool ret = false; + if(_zmq_comm_socket == nullptr) + { + return ret; + } + zmq::message_t message; + + QJsonObject params; + params["item"] = plan_to_json_item(plan); + params["user"] = "uProbeX"; + params["user_group"] = "primary"; + QByteArray msg_arr = gen_send_mesg2("queue_item_add", params); + _zmq_comm_socket->send(msg_arr.data(), msg_arr.length()); + + _zmq_comm_socket->recv(&message); + QJsonObject reply = QJsonDocument::fromJson(QString::fromUtf8((char*)message.data(), message.size()).toUtf8()).object(); + if(reply.contains("success")) + { + if(reply["success"].toString() == "true") + { + ret = true; + } + } + if(reply.contains("msg")) + { + msg = reply["msg"].toString(); + } + return ret; + } + + //--------------------------------------------------------------------------- + + bool get_avail_scans(std::map &plans, QString &msg) + { + bool ret = false; + zmq::message_t message; + + //params["user_group"] = "primary"; + //obj["params"] = params; + if(_zmq_comm_socket == nullptr) + { + return ret; + } + std::map params; + params["user_group"] = "primary"; + QByteArray msg_arr = gen_send_mesg("plans_allowed", ¶ms); + _zmq_comm_socket->send(msg_arr.data(), msg_arr.length()); + + _zmq_comm_socket->recv(&message); + QJsonObject reply = QJsonDocument::fromJson(QString::fromUtf8((char*)message.data(), message.size()).toUtf8()).object(); + if(reply.contains("success")) + { + QString strReply = reply["success"].toString(); + if(strReply.length() > 0) + { + if(strReply == "true") + { + ret = true; + } + } + else + { + ret = reply["success"].toBool(); + } + } + if(reply.contains("plans_allowed")) + { + QJsonObject iojb = reply["plans_allowed"].toObject(); + for( auto itr : iojb) + { + QJsonObject pobj = itr.toObject(); + if(pobj.contains("name")) + { + plans[pobj["name"].toString()].name = pobj["name"].toString(); + if(pobj.contains("description")) + { + plans[pobj["name"].toString()].description = pobj["description"].toString(); + } + if(pobj.contains("module")) + { + plans[pobj["name"].toString()].module = pobj["module"].toString(); + } + if(pobj.contains("parameters")) + { + QJsonArray params_obj = pobj["parameters"].toArray(); + for( auto itr2 : params_obj) + { + QJsonObject param = itr2.toObject(); + if(param.contains("name")) + { + plans[pobj["name"].toString()].parameters[param["name"].toString()].name = param["name"].toString(); + if(param.contains("default")) + { + plans[pobj["name"].toString()].parameters[param["name"].toString()].default_val = param["default"].toString(); + } + if(param.contains("description")) + { + plans[pobj["name"].toString()].parameters[param["name"].toString()].description = param["description"].toString(); + } + } + } + } + } + + } + } + if(reply.contains("msg")) + { + msg = reply["msg"].toString(); + } + return ret; + } + + //--------------------------------------------------------------------------- + + bool get_queued_scans(QString &msg, std::vector &queued_plans, BlueskyPlan &running_plan) + { + bool ret = false; + if(_zmq_comm_socket == nullptr) + { + return ret; + } + running_plan.name = ""; + running_plan.uuid = ""; + zmq::message_t message; + QByteArray msg_arr = gen_send_mesg("queue_get", nullptr); + _zmq_comm_socket->send(msg_arr.data(), msg_arr.length()); + + _zmq_comm_socket->recv(&message); + + QJsonObject reply = QJsonDocument::fromJson(QString::fromUtf8((char*)message.data(), message.size()).toUtf8()).object(); + if(reply.contains("success")) + { + QString strReply = reply["success"].toString(); + if(strReply.length() > 0) + { + if(strReply == "true") + { + ret = true; + } + } + else + { + ret = reply["success"].toBool(); + } + } + if(reply.contains("items")) + { + /* + {'name': 'count', + 'args': [['det1', 'det2']], + 'kwargs': {'num': 10, 'delay': 1}, + 'item_type': 'plan', + 'user': 'qserver-cli', + 'user_group': 'primary', + 'item_uid': 'f66d959f-12e2-43a5-a67d-01b3d40b4f43'} + */ + queued_plans.clear(); + QJsonArray items = reply["items"].toArray(); + for( auto itr2 : items) + { + BlueskyPlan plan; + QJsonObject param = itr2.toObject(); + if(param.contains("name")) + { + plan.type = param["name"].toString(); + } + if(param.contains("args")) + { + //plan.args = param["args"].toString(); + } + if(param.contains("kwargs")) + { + QJsonObject kwargs = param["kwargs"].toObject(); + //plan.parameters + for(auto pitr : kwargs.keys()) + { + BlueskyParam bsp; + bsp.name = pitr; + bsp.default_val = kwargs[pitr].toString(); + plan.parameters[pitr] = bsp; + if(pitr == "md") // use meta data to link to scan name + { + plan.name = bsp.default_val; + } + } + } + if(param.contains("user")) + { + plan.user = param["user"].toString(); + } + if(param.contains("item_uid")) + { + plan.uuid = param["item_uid"].toString(); + } + queued_plans.push_back(plan); + } + } + if(reply.contains("running_item")) + { + /* + "name": "count", + "args": [ + [ + "det4", + "det3" + ] + ], + "kwargs": { + "num": 10, + "delay": 1 + }, + "item_type": "plan", + "user": "qserver-cli", + "user_group": "primary", + "item_uid": "dacdd8fc-2903-490d-8027-7510d43fb1e2", + "properties": { + "time_start": 1722889109.0853188 + } + */ + + QJsonObject running_item = reply["running_item"].toObject(); + if(running_item.contains("name")) + { + running_plan.name = running_item["name"].toString(); + } + if(running_item.contains("args")) + { + //running_plan.name = running_item["args"].toString(); + } + if(running_item.contains("kwargs")) + { + QJsonObject kwargs = running_item["kwargs"].toObject(); + for(auto pitr : kwargs.keys()) + { + BlueskyParam bsp; + bsp.name = pitr; + bsp.default_val = kwargs[pitr].toString(); + running_plan.parameters[pitr] = bsp; + } + } + if(running_item.contains("user")) + { + running_plan.user = running_item["user"].toString(); + } + if(running_item.contains("item_uid")) + { + running_plan.uuid = running_item["item_uid"].toString(); + } + } + /* + if(reply.contains("plan_queue_uid")) + { + + } + */ + return ret; + } + + //--------------------------------------------------------------------------- + public slots: void run() override { @@ -80,7 +530,15 @@ public slots: { if(_zmq_lsn_socket->recv(&message)) { - emit newData(QString::fromUtf8((char*)message.data(), message.size())); + QJsonObject rootJson = QJsonDocument::fromJson(QString::fromUtf8((char*)message.data(), message.size()).toUtf8()).object(); + if(rootJson.contains("msg")) + { + emit newData(rootJson["msg"].toString()); + } + else + { + // logI< + diff --git a/src/mvc/BlueskyPlan.h b/src/mvc/BlueskyPlan.h new file mode 100644 index 0000000..ca97ad3 --- /dev/null +++ b/src/mvc/BlueskyPlan.h @@ -0,0 +1,49 @@ +/*----------------------------------------------------------------------------- + * Copyright (c) 2024, UChicago Argonne, LLC + * See LICENSE file. + *---------------------------------------------------------------------------*/ + +#ifndef BLUESKY_PLAN_H +#define BLUESKY_PLAN_H + +//--------------------------------------------------------------------------- + +#include + +//--------------------------------------------------------------------------- +struct BlueskyParam +{ + BlueskyParam() + { + default_val = "0.0"; + } + QString name; + QString description; + QString default_val; +}; + +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- + +struct BlueskyPlan +{ + BlueskyPlan() + { + uuid=""; + user=""; + } + QString name; + QString type; + QString description; + QString module; + std::unordered_map parameters; + QString uuid; + QString user; +}; + + +//--------------------------------------------------------------------------- + +#endif /* */ + +//--------------------------------------------------------------------------- diff --git a/src/mvc/FitElementsTableModel.cpp b/src/mvc/FitElementsTableModel.cpp index 079bb04..38bd35d 100644 --- a/src/mvc/FitElementsTableModel.cpp +++ b/src/mvc/FitElementsTableModel.cpp @@ -5,6 +5,7 @@ #include "FitElementsTableModel.h" #include +#include "preferences/Preferences.h" //--------------------------------------------------------------------------- @@ -22,7 +23,7 @@ FitElementsTableModel::FitElementsTableModel(std::string detector_element, QObje FitElementsTableModel::~FitElementsTableModel() { - _is_log10 = true; + _is_log10 = Preferences::inst()->getValue(STR_PFR_LOG_10).toBool(); for(auto& itr : _nodes) { delete itr.second; @@ -66,28 +67,34 @@ void FitElementsTableModel::setDisplayHeaderMinMax(bool val) void FitElementsTableModel::update_counts_log10(bool is_log10) { - - for (auto& itr : _nodes) + if(_is_log10 != is_log10) { - TreeItem* node = itr.second; _is_log10 = is_log10; - if (is_log10) - { - double val = node->itemData[COUNTS].toDouble(); - node->itemData[COUNTS] = std::log10(val); - m_headers[HEADERS::COUNTS] = tr("Counts (10^Cnts)"); - } - else + for (auto& itr : _nodes) { - double val = node->itemData[COUNTS].toDouble(); - node->itemData[COUNTS] = std::pow(10, val); - m_headers[HEADERS::COUNTS] = tr("Counts"); + TreeItem* node = itr.second; + + if (is_log10) + { + double val = node->itemData[COUNTS].toDouble(); + if (val != 0) + { + node->itemData[COUNTS] = std::log10(val); + } + m_headers[HEADERS::COUNTS] = tr("Counts (10^Cnts)"); + } + else + { + double val = node->itemData[COUNTS].toDouble(); + node->itemData[COUNTS] = std::pow(10, val); + m_headers[HEADERS::COUNTS] = tr("Counts"); + } } + QModelIndex topLeft = index(0, 0); + QModelIndex bottomRight = index(_row_indicies.size() - 1, NUM_PROPS - 1); + emit dataChanged(topLeft, bottomRight); + emit layoutChanged(); } - QModelIndex topLeft = index(0, 0); - QModelIndex bottomRight = index(_row_indicies.size() - 1, NUM_PROPS - 1); - emit dataChanged(topLeft, bottomRight); - emit layoutChanged(); } //--------------------------------------------------------------------------- diff --git a/src/mvc/FitSpectraWidget.cpp b/src/mvc/FitSpectraWidget.cpp index 6b041c8..7565a3d 100644 --- a/src/mvc/FitSpectraWidget.cpp +++ b/src/mvc/FitSpectraWidget.cpp @@ -144,6 +144,7 @@ void FitSpectraWidget::createLayout() _fit_params_table->setItemDelegateForColumn(4, npDelegate); _fit_params_table->setItemDelegateForColumn(5, npDelegate); _fit_params_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + //_fit_params_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); _fit_params_table->setContextMenuPolicy(Qt::CustomContextMenu); connect(_fit_params_table, SIGNAL(customContextMenuRequested(QPoint)), diff --git a/src/mvc/FittingDialog.cpp b/src/mvc/FittingDialog.cpp index 8746dd8..5599683 100644 --- a/src/mvc/FittingDialog.cpp +++ b/src/mvc/FittingDialog.cpp @@ -75,13 +75,13 @@ void FittingDialog::_createLayout() _fit_params_table->setItemDelegateForColumn(3, npDelegate); _fit_params_table->setItemDelegateForColumn(4, npDelegate); _fit_params_table->setItemDelegateForColumn(5, npDelegate); - _fit_params_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + _fit_params_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); _new_fit_params_table = new QTableView(); _new_fit_params_table->setModel(_new_fit_params_table_model); _new_fit_params_table->sortByColumn(0, Qt::AscendingOrder); _new_fit_params_table->setItemDelegateForColumn(2, cbDelegate); - _new_fit_params_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + _new_fit_params_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); connect(_new_fit_params_table->verticalScrollBar(), &QAbstractSlider::valueChanged, _fit_params_table->verticalScrollBar(), &QAbstractSlider::setValue); diff --git a/src/mvc/LiveMapsElementsWidget.cpp b/src/mvc/LiveMapsElementsWidget.cpp index 2d5ed64..0f4a4f9 100644 --- a/src/mvc/LiveMapsElementsWidget.cpp +++ b/src/mvc/LiveMapsElementsWidget.cpp @@ -16,12 +16,14 @@ LiveMapsElementsWidget::LiveMapsElementsWidget(QString ip, QString port, QWidget { _streamWorker = nullptr; + _qserverComm = nullptr; _mapsElementsWidget = nullptr; _last_packet = nullptr; //_currentModel = new MapsH5Model(); _currentModel = nullptr; _num_images = 0; _prev_dataset_name = " "; + _qserver_ip_addr = new QLineEdit("127.0.0.1"); _qline_ip_addr = new QLineEdit(); if(ip.length() > 0) { @@ -83,15 +85,19 @@ void LiveMapsElementsWidget::createLayout() QVBoxLayout* layout = new QVBoxLayout(); QHBoxLayout* hlayout = new QHBoxLayout(); + QHBoxLayout* hlayout2 = new QHBoxLayout(); _btn_update = new QPushButton("Update"); connect(_btn_update, SIGNAL(released()), this, SLOT(updateIp())); - hlayout->addWidget(new QLabel("Computer:")); - hlayout->addWidget(_qline_ip_addr); - hlayout->addWidget(new QLabel("Port:")); - hlayout->addWidget(_qline_port); - hlayout->addWidget(_btn_update); + hlayout->addWidget(new QLabel("QServer Computer:")); + hlayout->addWidget(_qserver_ip_addr); + hlayout2->addWidget(new QLabel("XRF-Maps Computer:")); + hlayout2->addWidget(_qline_ip_addr); + hlayout2->addWidget(new QLabel("Port:")); + hlayout2->addWidget(_qline_port); + hlayout2->addWidget(_btn_update); layout->addLayout(hlayout); + layout->addLayout(hlayout2); // _textEdit = new QTextEdit(this); // _textEdit->resize(1024, 800); @@ -120,8 +126,15 @@ void LiveMapsElementsWidget::createLayout() _vlm_widget = new VLM_Widget(); + _vlm_widget->setAvailScans(&_avail_scans); + connect(_vlm_widget, &VLM_Widget::onScanUpdated, this, &LiveMapsElementsWidget::queueScan); _scan_queue_widget = new ScanQueueWidget(); + connect(_scan_queue_widget, &ScanQueueWidget::queueNeedsToBeUpdated, this, &LiveMapsElementsWidget::getQueuedScans); + connect(_scan_queue_widget, &ScanQueueWidget::onOpenEnv, this, &LiveMapsElementsWidget::callOpenEnv); + connect(_scan_queue_widget, &ScanQueueWidget::onCloseEnv, this, &LiveMapsElementsWidget::callCloseEnv); + connect(_scan_queue_widget, &ScanQueueWidget::onStartQueue, this, &LiveMapsElementsWidget::callStartQueue); + connect(_scan_queue_widget, &ScanQueueWidget::onStopQueue, this, &LiveMapsElementsWidget::callStopQueue); _tab_widget = new QTabWidget(); _tab_widget->addTab(_mapsElementsWidget, "Counts"); @@ -141,6 +154,18 @@ void LiveMapsElementsWidget::createLayout() void LiveMapsElementsWidget::updateIp() { + + if(_qserverComm != nullptr) + { + disconnect(_qserverComm, &BlueskyComm::newData, _scan_queue_widget, &ScanQueueWidget::newDataArrived); + _qserverComm->stop(); + _qserverComm->quit(); + _qserverComm->wait(); + delete _qserverComm; + } + _qserverComm = new BlueskyComm(_qserver_ip_addr->text(), this); + connect(_qserverComm, &BlueskyComm::newData, _scan_queue_widget, &ScanQueueWidget::newDataArrived); + _qserverComm->start(); if(_streamWorker != nullptr) { @@ -156,6 +181,10 @@ void LiveMapsElementsWidget::updateIp() if(_last_packet != nullptr) delete _last_packet; _last_packet = nullptr; + + updateScansAvailable(); + getQueuedScans(); + callOpenEnv(); } //--------------------------------------------------------------------------- @@ -253,3 +282,146 @@ void LiveMapsElementsWidget::image_changed(int start, int end) { _mapsElementsWidget->setModel(_maps_h5_models[start-1]); } + +//--------------------------------------------------------------------------- + +void LiveMapsElementsWidget::updateScansAvailable() +{ + QString msg; + if(_qserverComm == nullptr) + { + updateIp(); + } + if (false == _qserverComm->get_avail_scans(_avail_scans, msg)) + { + _scan_queue_widget->newDataArrived( msg ); + } + +} + +//--------------------------------------------------------------------------- + +void LiveMapsElementsWidget::getQueuedScans() +{ + QString msg; + if(_qserverComm == nullptr) + { + updateIp(); + } + if (false == _qserverComm->get_queued_scans(msg, _queued_scans, _running_scan)) + { + _scan_queue_widget->newDataArrived( msg ); + } + else + { + _scan_queue_widget->updateQueuedItems(_queued_scans, _running_scan); + } +} + +//--------------------------------------------------------------------------- + +void LiveMapsElementsWidget::callOpenEnv() +{ + QString msg; + if(_qserverComm == nullptr) + { + updateIp(); + } + if (false == _qserverComm->open_env(msg)) + { + //_scan_queue_widget->newDataArrived( msg ); + } + else + { + //_scan_queue_widget->updateQueuedItems(_queued_scans, _running_scan); + } + + _scan_queue_widget->newDataArrived( msg ); +} + +//--------------------------------------------------------------------------- + +void LiveMapsElementsWidget::callCloseEnv() +{ + QString msg; + if(_qserverComm == nullptr) + { + updateIp(); + } + if (false == _qserverComm->close_env(msg)) + { + //_scan_queue_widget->newDataArrived( msg ); + } + else + { + //_scan_queue_widget->updateQueuedItems(_queued_scans, _running_scan); + } + + _scan_queue_widget->newDataArrived( msg ); +} + +//--------------------------------------------------------------------------- + +void LiveMapsElementsWidget::callStartQueue() +{ + QString msg; + if(_qserverComm == nullptr) + { + updateIp(); + } + if (false == _qserverComm->start_queue(msg)) + { + //_scan_queue_widget->newDataArrived( msg ); + } + else + { + //_scan_queue_widget->updateQueuedItems(_queued_scans, _running_scan); + } + + _scan_queue_widget->newDataArrived( msg ); +} + +//--------------------------------------------------------------------------- + +void LiveMapsElementsWidget::callStopQueue() +{ + QString msg; + if(_qserverComm == nullptr) + { + updateIp(); + } + if (false == _qserverComm->stop_queue(msg)) + { + //_scan_queue_widget->newDataArrived( msg ); + } + else + { + //_scan_queue_widget->updateQueuedItems(_queued_scans, _running_scan); + } + + _scan_queue_widget->newDataArrived( msg ); +} + +//--------------------------------------------------------------------------- + +void LiveMapsElementsWidget::queueScan(const BlueskyPlan& plan) +{ + QString msg; + if(_qserverComm == nullptr) + { + updateIp(); + } + if (false == _qserverComm->queue_plan(msg, plan)) + { + + } + else + { + + } + + _scan_queue_widget->newDataArrived( msg ); + getQueuedScans(); +} + +//--------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/mvc/LiveMapsElementsWidget.h b/src/mvc/LiveMapsElementsWidget.h index b2b0ba5..804ad3b 100644 --- a/src/mvc/LiveMapsElementsWidget.h +++ b/src/mvc/LiveMapsElementsWidget.h @@ -19,6 +19,7 @@ #include "mvc/MapsElementsWidget.h" #include "mvc/VLM_Widget.h" #include "mvc/ScanQueueWidget.h" +#include "mvc/BlueskyComm.h" //--------------------------------------------------------------------------- @@ -52,6 +53,20 @@ public slots: void image_changed(int start, int end); + void updateScansAvailable(); + + void getQueuedScans(); + + void callOpenEnv(); + + void callCloseEnv(); + + void callStartQueue(); + + void callStopQueue(); + + void queueScan(const BlueskyPlan& plan); + protected: /** @@ -73,6 +88,10 @@ public slots: NetStreamWorker* _streamWorker; + BlueskyComm* _qserverComm; + + QLineEdit *_qserver_ip_addr; + QLineEdit *_qline_ip_addr; QLineEdit *_qline_port; @@ -83,6 +102,12 @@ public slots: MapsH5Model *_currentModel; + std::map _avail_scans; + + std::vector _queued_scans; + + BlueskyPlan _running_scan; + data_struct::Stream_Block* _last_packet; std::string _prev_dataset_name; diff --git a/src/mvc/ScanQueueTableModel.h b/src/mvc/ScanQueueTableModel.h new file mode 100644 index 0000000..0ada60d --- /dev/null +++ b/src/mvc/ScanQueueTableModel.h @@ -0,0 +1,176 @@ +//----------------------------------------------------------------------------- + // Copyright (c) 2024, UChicago Argonne, LLC + // See LICENSE file. + //--------------------------------------------------------------------------- + +#ifndef ScanQueueTableModel_H +#define ScanQueueTableModel_H + +//--------------------------------------------------------------------------- + +#include +#include "mvc/BlueskyPlan.h" + +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- + +class ScanQueueTableModel : public QAbstractTableModel +{ +public: + ScanQueueTableModel(QObject* parent = nullptr) : QAbstractTableModel(parent) + { + _headers[0] = "name"; + _headers[1] = "type"; + _headers[2] = "user"; + _headers[3] = "uuid"; + } + //--------------------------------------------------------------------------- + int rowCount(const QModelIndex& parent = QModelIndex()) const override + { + return _data.size(); + } + + int columnCount(const QModelIndex& parent = QModelIndex()) const override + { + return 4; + } + //--------------------------------------------------------------------------- + void appendRow(const BlueskyPlan& row) + { + int rown = _data.size(); + QModelIndex gIndex = index(rown, 0, QModelIndex()); + beginInsertRows(gIndex, rown, rown); + _data.append(row); + endInsertRows(); + } + + //--------------------------------------------------------------------------- + + void clear() + { + _data.clear(); + } + + //--------------------------------------------------------------------------- + + const BlueskyPlan& item(int row) + { + return _data.at(row); + } + + //--------------------------------------------------------------------------- + + const QString& getNameAtRow(int row) + { + if(_data.size() > row) + { + return _data.at(row).name; + } + return ""; + } + + //--------------------------------------------------------------------------- + + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override + { + if (!index.isValid() || index.row() >= _data.size() || index.column() >= 4) + { + return QVariant(); + } + + const BlueskyPlan& rowData = _data[index.row()]; + + if (role == Qt::DisplayRole) + { + switch(index.column()) + { + case 0: + return rowData.name; + case 1: + return rowData.type; + case 2: + return rowData.user; + case 3: + return rowData.uuid; + }; + } + return QVariant(); + } + //--------------------------------------------------------------------------- + QVariant headerData(int section, Qt::Orientation orientation, int role) const + { + // Check this is DisplayRole + if (role != Qt::DisplayRole) return QVariant(); + + // Horizontal headers + if (orientation == Qt::Horizontal) + { + if(section > 4) + { + return QVariant(); + } + else + { + return _headers[section]; + } + } + + // Return empty data + return QVariant(); + } + + //--------------------------------------------------------------------------- + + Qt::ItemFlags flags(const QModelIndex &index) const + { + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } + + //--------------------------------------------------------------------------- + + void setAllData(std::vector& scans) + { + beginResetModel(); + _data.clear(); + for(auto itr : scans) + { + _data.append(itr); + } + endResetModel(); + } + + //--------------------------------------------------------------------------- + + bool setData(const QModelIndex& index, const QVariant& value, int role) + { + if (role == Qt::EditRole && index.isValid()) + { + if( index.row() < _data.size() && index.column() == 2) + { + _data[index.row()].user = value.toString(); + return true; + } + return false; + } + return false; + + } + //--------------------------------------------------------------------------- + +private: + QList _data; + + QString _headers[4]; +}; + + +//--------------------------------------------------------------------------- + +#endif /* ScanQueueTableModel.h */ + +//--------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/mvc/ScanQueueWidget.cpp b/src/mvc/ScanQueueWidget.cpp index 65a1215..10c6e12 100644 --- a/src/mvc/ScanQueueWidget.cpp +++ b/src/mvc/ScanQueueWidget.cpp @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "core/defines.h" //--------------------------------------------------------------------------- @@ -33,67 +35,107 @@ void ScanQueueWidget::_createLayout() QVBoxLayout* layout = new QVBoxLayout(); + _scan_running_table_model = new ScanQueueTableModel(); + _scan_running_table_view = new QTableView(); + _scan_running_table_view->setFixedHeight(100); + _scan_running_table_view->setModel(_scan_running_table_model); + _scan_running_table_view->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); + // _scan_running_table_view->horizontalHeader()->resizeSections(QHeaderView::Interactive); + + _scan_queue_table_model = new ScanQueueTableModel(); + _scan_queue_table_view = new QTableView(); + _scan_queue_table_view->setModel(_scan_queue_table_model); + _scan_queue_table_view->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); + // _scan_queue_table_view->horizontalHeader()->resizeSections(QHeaderView::Interactive); + + + QSize btn_size(33,33); + + _btn_play = new QPushButton(); + _btn_play->setFixedSize(btn_size); + _btn_play->setIcon(QIcon(":images/start.png")); + _btn_play->setToolTip("Start Queue"); + connect(_btn_play, &QPushButton::pressed, this, &ScanQueueWidget::onStartQueue); + + _btn_stop = new QPushButton(); + _btn_stop->setIcon(QIcon(":images/stop.png")); + _btn_stop->setFixedSize(btn_size); + _btn_stop->setToolTip("Stop Queue"); + connect(_btn_stop, &QPushButton::pressed, this, &ScanQueueWidget::onStopQueue); + + _btn_refresh = new QPushButton(); + _btn_refresh->setIcon(QIcon(":images/refresh.png")); + _btn_refresh->setFixedSize(btn_size); + _btn_refresh->setToolTip("Manual Refresh Queue"); + connect(_btn_refresh, &QPushButton::pressed, this, &ScanQueueWidget::queueNeedsToBeUpdated); + + _btn_open_env = new QPushButton("Open Env"); + _btn_open_env->setToolTip("Open Environment"); + connect(_btn_open_env, &QPushButton::pressed, this, &ScanQueueWidget::onOpenEnv); + + _btn_close_env = new QPushButton("Close Env"); + _btn_close_env->setToolTip("Close Environment"); + connect(_btn_close_env, &QPushButton::pressed, this, &ScanQueueWidget::onCloseEnv); + + QGridLayout *grid = new QGridLayout(); + grid->addWidget(_btn_play, 0,0); + grid->addWidget(_btn_stop,0,1); + grid->addWidget(_btn_refresh,0,2); + grid->addWidget(_btn_open_env,0,3); + grid->addWidget(_btn_close_env,0,4); + grid->addItem(new QSpacerItem(999,10), 0,6); + + layout->addItem(grid); + _te_qs_console = new QTextEdit(this); _te_qs_console->scrollBarWidgets(Qt::AlignRight); - - layout->addWidget(_te_qs_console); - setLayout(layout); -/* - QHBoxLayout* hlayout = new QHBoxLayout(); - _btn_update = new QPushButton("Update"); - connect(_btn_update, SIGNAL(released()), this, SLOT(updateIp())); - - hlayout->addWidget(new QLabel("Computer:")); - hlayout->addWidget(_qline_ip_addr); - hlayout->addWidget(new QLabel("Port:")); - hlayout->addWidget(_qline_port); - hlayout->addWidget(_btn_update); - layout->addLayout(hlayout); - - _mapsElementsWidget = new MapsElementsWidget(1,1,true); - //_mapsElementsWidget->setTabVisible(1, false); - _mapsElementsWidget->setTabVisible(2, false); - _mapsElementsWidget->setTabVisible(3, false); - _mapsElementsWidget->setTabVisible(4, false); - _mapsElementsWidget->setTabVisible(5, false); - //_mapsElementsWidget->setModel(_currentModel, nullptr, nullptr); - // _mapsElementsWidget->appendTab(_textEdit, "Log"); - - connect(_mapsElementsWidget, - SIGNAL(rangeChanged(int, int)), - this, - SLOT(image_changed(int, int))); - - if(_currentModel != nullptr) - { - connect(_currentModel, - SIGNAL(model_data_updated()), - _mapsElementsWidget, - SLOT(model_updated())); - } - - - _vlm_widget = new VLM_Widget(); - - _tab_widget = new QTabWidget(); - - _tab_widget->addTab(_mapsElementsWidget, "Counts"); - _tab_widget->addTab(_vlm_widget, "Scan Area"); - //_tab_widget->addTab(_scan_queue, "Queue"); - - - layout->addWidget(_tab_widget); - - _progressBar = new QProgressBar(this); - layout->addWidget(_progressBar); + + QDockWidget *dock_running = new QDockWidget("Running Scan", this); + dock_running->setWidget(_scan_running_table_view); + layout->addWidget(dock_running); + + QDockWidget *dock_queue = new QDockWidget("Scan Queue", this); + dock_queue->setWidget(_scan_queue_table_view); + layout->addWidget(dock_queue); + + QDockWidget *dock_log = new QDockWidget("QServer Log", this); + dock_log->setWidget(_te_qs_console); + layout->addWidget(dock_log); + setLayout(layout); -*/ + +} + +//--------------------------------------------------------------------------- + +void ScanQueueWidget::updateQueuedItems( std::vector &queued_plans, BlueskyPlan &running_plan) +{ + _scan_queue_table_model->setAllData(queued_plans); + _scan_queue_table_view->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); + std::vector runlist; + if(running_plan.uuid.length() > 0) + { + runlist.push_back(running_plan); + } + _scan_running_table_model->setAllData(runlist); + _scan_running_table_view->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); } //--------------------------------------------------------------------------- void ScanQueueWidget::newDataArrived(const QString& data) { + _te_qs_console->append(data); + if (data.count("Item added: success=True item_type='plan'") > 0 + || data.count("Plan failed:") > 0 + || data.count("The plan was exited") > 0 + || data.count("Removing item from the queue") > 0 + || data.count("Starting the plan") > 0 + || data.count("Queue is empty") > 0) + { + emit queueNeedsToBeUpdated(); + } + // if ERROR:bluesky:Run aborted } -//--------------------------------------------------------------------------- \ No newline at end of file +//--------------------------------------------------------------------------- diff --git a/src/mvc/ScanQueueWidget.h b/src/mvc/ScanQueueWidget.h index e425ca0..eca156c 100644 --- a/src/mvc/ScanQueueWidget.h +++ b/src/mvc/ScanQueueWidget.h @@ -10,6 +10,10 @@ #include #include +#include +#include +#include "mvc/BlueskyPlan.h" +#include "mvc/ScanQueueTableModel.h" //--------------------------------------------------------------------------- @@ -31,8 +35,20 @@ class ScanQueueWidget : public QWidget */ ~ScanQueueWidget(); -public slots: + void updateQueuedItems( std::vector &queued_plans, BlueskyPlan &running_plan); + +signals: + void queueNeedsToBeUpdated(); + + void onOpenEnv(); + + void onCloseEnv(); + + void onStartQueue(); + + void onStopQueue(); +public slots: void newDataArrived(const QString &); protected: @@ -44,11 +60,24 @@ public slots: QTextEdit *_te_qs_console; -// QLineEdit *_qline_ip_addr; + QTableView* _scan_queue_table_view; + + ScanQueueTableModel* _scan_queue_table_model; + + QTableView* _scan_running_table_view; + + ScanQueueTableModel* _scan_running_table_model; + + QPushButton* _btn_play; + + QPushButton* _btn_stop; + + QPushButton* _btn_refresh; -// QLineEdit *_qline_port; + QPushButton* _btn_open_env; -// QPushButton *_btn_update; + QPushButton* _btn_close_env; + }; diff --git a/src/mvc/ScanRegionDialog.cpp b/src/mvc/ScanRegionDialog.cpp index 7a31dbc..9e22d5c 100644 --- a/src/mvc/ScanRegionDialog.cpp +++ b/src/mvc/ScanRegionDialog.cpp @@ -16,7 +16,7 @@ ScanRegionDialog::ScanRegionDialog() : QDialog() { - + _avail_scans = nullptr; _createLayout(); } @@ -36,15 +36,18 @@ void ScanRegionDialog::_createLayout() _scan_name = new QLineEdit(" "); _scan_type = new QComboBox(); + connect(_scan_type, &QComboBox::currentTextChanged, this, &ScanRegionDialog::scanChanged); - _scan_options = new QListWidget(); + _scan_table_model = new ScanTableModel(); + _scan_options = new QTableView(); + _scan_options->setModel(_scan_table_model); _btn_update = new QPushButton("Update"); _btn_update_and_queue = new QPushButton("Update and Queue"); _btn_cancel = new QPushButton("Cancel"); - connect(_btn_update, SIGNAL(pressed()), this, SLOT(onUpdate())); - connect(_btn_update_and_queue, SIGNAL(pressed()), this, SLOT(onUpdateAndQueue())); - connect(_btn_cancel, SIGNAL(pressed()), this, SLOT(close())); + connect(_btn_update, &QPushButton::pressed, this, &ScanRegionDialog::onUpdate); + connect(_btn_update_and_queue, &QPushButton::pressed, this, &ScanRegionDialog::onUpdateAndQueue); + connect(_btn_cancel, &QPushButton::pressed, this, &ScanRegionDialog::close); QVBoxLayout* main_layout = new QVBoxLayout(); @@ -74,6 +77,20 @@ void ScanRegionDialog::_createLayout() //--------------------------------------------------------------------------- +void ScanRegionDialog::setAvailScans(std::map * avail_scans) +{ + _avail_scans = avail_scans; + int i=0; + _scan_type->clear(); + for(auto itr : *avail_scans) + { + _scan_type->insertItem(i, itr.first); + i++; + } +} + +//--------------------------------------------------------------------------- + void ScanRegionDialog::updateProps(QList &anno_list) { for(auto &itr : anno_list) @@ -89,7 +106,7 @@ void ScanRegionDialog::updateProps(QList &anno_list) void ScanRegionDialog::onUpdate() { - emit ScanUpdated(); + //emit ScanUpdated(); close(); } @@ -97,9 +114,25 @@ void ScanRegionDialog::onUpdate() void ScanRegionDialog::onUpdateAndQueue() { - emit ScanUpdated(); + BlueskyPlan plan; + plan.type = _scan_type->currentText(); + _scan_table_model->getCurrentParams(plan); + emit ScanUpdated(plan); close(); } +//--------------------------------------------------------------------------- + +void ScanRegionDialog::scanChanged(const QString &scan_name) +{ + if(_avail_scans != nullptr) + { + if(_avail_scans->count(scan_name) > 0) + { + _scan_table_model->setAllData(_avail_scans->at(scan_name)); + } + } +} + //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- diff --git a/src/mvc/ScanRegionDialog.h b/src/mvc/ScanRegionDialog.h index 01b2a77..84499c1 100644 --- a/src/mvc/ScanRegionDialog.h +++ b/src/mvc/ScanRegionDialog.h @@ -15,8 +15,10 @@ #include #include #include -#include +#include #include "gstar/AnnotationProperty.h" +#include "mvc/BlueskyPlan.h" +#include "mvc/ScanTableModel.h" //--------------------------------------------------------------------------- @@ -41,9 +43,10 @@ class ScanRegionDialog : public QDialog QString getScanName() { return _scan_name->text(); } + void setAvailScans(std::map * avail_scans); signals: - void ScanUpdated(); + void ScanUpdated(const BlueskyPlan& plan); public slots: @@ -51,6 +54,8 @@ public slots: void onUpdateAndQueue(); + void scanChanged(const QString &); + protected: void _createLayout(); @@ -66,7 +71,11 @@ public slots: QPushButton *_btn_cancel; - QListWidget* _scan_options; + QTableView* _scan_options; + + ScanTableModel *_scan_table_model; + + std::map *_avail_scans; }; diff --git a/src/mvc/ScanTableModel.h b/src/mvc/ScanTableModel.h new file mode 100644 index 0000000..c1f5e12 --- /dev/null +++ b/src/mvc/ScanTableModel.h @@ -0,0 +1,189 @@ +//----------------------------------------------------------------------------- + // Copyright (c) 2024, UChicago Argonne, LLC + // See LICENSE file. + //--------------------------------------------------------------------------- + +#ifndef ScanTableModel_H +#define ScanTableModel_H + +//--------------------------------------------------------------------------- + +#include + +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- + +class ScanTableModel : public QAbstractTableModel +{ +public: + ScanTableModel(QObject* parent = nullptr) : QAbstractTableModel(parent) + { + _headers[0] = "Name"; + _headers[1] = "Value"; + _headers[2] = "Desc"; + } + //--------------------------------------------------------------------------- + int rowCount(const QModelIndex& parent = QModelIndex()) const override + { + return _data.size(); + } + + int columnCount(const QModelIndex& parent = QModelIndex()) const override + { + return 3; + } + //--------------------------------------------------------------------------- + void appendRow(const BlueskyParam& row) + { + int rown = _data.size(); + QModelIndex gIndex = index(rown, 0, QModelIndex()); + beginInsertRows(gIndex, rown, rown); + _data.append(row); + endInsertRows(); + } + + //--------------------------------------------------------------------------- + + void clear() + { + _data.clear(); + } + + //--------------------------------------------------------------------------- + + const BlueskyParam& item(int row) + { + return _data.at(row); + } + + //--------------------------------------------------------------------------- + + const QString& getNameAtRow(int row) + { + if(_data.size() > row) + { + return _data.at(row).name; + } + return ""; + } + + //--------------------------------------------------------------------------- + + void getCurrentParams(BlueskyPlan& plan) + { + for(auto itr : _data) + { + plan.parameters[itr.name] = itr; + } + } + + //--------------------------------------------------------------------------- + + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override + { + if (!index.isValid() || index.row() >= _data.size() || index.column() >= 4) + { + return QVariant(); + } + + const BlueskyParam& rowData = _data[index.row()]; + + if (role == Qt::DisplayRole) + { + switch(index.column()) + { + case 0: + return rowData.name; + case 1: + return rowData.default_val; + case 2: + return rowData.description; + }; + } + return QVariant(); + } + //--------------------------------------------------------------------------- + QVariant headerData(int section, Qt::Orientation orientation, int role) const + { + // Check this is DisplayRole + if (role != Qt::DisplayRole) return QVariant(); + + // Horizontal headers + if (orientation == Qt::Horizontal) + { + if(section > 3) + { + return QVariant(); + } + else + { + return _headers[section]; + } + } + + // Return empty data + return QVariant(); + } + + //--------------------------------------------------------------------------- + + Qt::ItemFlags flags(const QModelIndex &index) const + { + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + // Get desired index + int c = index.column(); + if(c == 1) + { + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; + } + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } + + //--------------------------------------------------------------------------- + + void setAllData(BlueskyPlan& scan) + { + beginResetModel(); + _data.clear(); + for(auto itr : scan.parameters) + { + _data.append(itr.second); + } + endResetModel(); + } + + //--------------------------------------------------------------------------- + + bool setData(const QModelIndex& index, const QVariant& value, int role) + { + if (role == Qt::EditRole && index.isValid()) + { + if( index.row() < _data.size() && index.column() == 1) + { + _data[index.row()].default_val = value.toString(); + return true; + } + return false; + } + return false; + + } + //--------------------------------------------------------------------------- + +private: + QList _data; + + QString _headers[3]; +}; + + +//--------------------------------------------------------------------------- + +#endif /* ScanTableModel.h */ + +//--------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/mvc/SpectraWidget.cpp b/src/mvc/SpectraWidget.cpp index 51a63d8..ea336df 100644 --- a/src/mvc/SpectraWidget.cpp +++ b/src/mvc/SpectraWidget.cpp @@ -565,39 +565,41 @@ void SpectraWidget::ShowContextMenu(const QPoint &pos) void SpectraWidget::set_log10(bool val) { - QList series = _chart->series(); - - for(QAbstractSeries* ser : _element_lines) + if(_display_log10 != val) { - series.removeOne(ser); - } + QList series = _chart->series(); - for(QAbstractSeries* ser : series) - { - ser->detachAxis(_currentYAxis); - } - _chart->removeAxis(_currentYAxis); + for(QAbstractSeries* ser : _element_lines) + { + series.removeOne(ser); + } - _display_log10 = val; + for(QAbstractSeries* ser : series) + { + ser->detachAxis(_currentYAxis); + } + _chart->removeAxis(_currentYAxis); - if(_display_log10) //if current one is log10, set to normal - { - _currentYAxis = _axisYLog10; - } - else - { - _currentYAxis = _axisY; - } + _display_log10 = val; - _chart->addAxis(_currentYAxis, Qt::AlignLeft); + if(_display_log10) //if current one is log10, set to normal + { + _currentYAxis = _axisYLog10; + } + else + { + _currentYAxis = _axisY; + } - for(QAbstractSeries* ser : series) - { - ser->attachAxis(_currentYAxis); - } + _chart->addAxis(_currentYAxis, Qt::AlignLeft); - emit(y_axis_changed(_display_log10)); + for(QAbstractSeries* ser : series) + { + ser->attachAxis(_currentYAxis); + } + emit(y_axis_changed(_display_log10)); + } } //--------------------------------------------------------------------------- diff --git a/src/mvc/VLM_Widget.cpp b/src/mvc/VLM_Widget.cpp index 7dfb566..158db6f 100644 --- a/src/mvc/VLM_Widget.cpp +++ b/src/mvc/VLM_Widget.cpp @@ -115,6 +115,7 @@ VLM_Widget::~VLM_Widget() void VLM_Widget::_init() { + _avail_scans = nullptr; m_microProbePvSet = false; // m_pvXHandler = nullptr; // m_pvYHandler = nullptr; @@ -234,11 +235,13 @@ void VLM_Widget::addTopWindowPoints() void VLM_Widget::addMicroProbeRegion() { - ScanRegionGraphicsItem* annotation = new ScanRegionGraphicsItem(); + ScanRegionGraphicsItem* annotation = new ScanRegionGraphicsItem(_avail_scans); ////UProbeRegionGraphicsItem* annotation = new UProbeRegionGraphicsItem(); annotation->setMouseOverPixelCoordModel(m_coordinateModel); annotation->setLightToMicroCoordModel(m_lightToMicroCoordModel); + connect(annotation, &ScanRegionGraphicsItem::scanUpdated, this, &VLM_Widget::onScanUpdated); + insertAndSelectAnnotation(m_mpTreeModel, m_mpAnnoTreeView, m_mpSelectionModel, diff --git a/src/mvc/VLM_Widget.h b/src/mvc/VLM_Widget.h index c76720e..c23e2be 100644 --- a/src/mvc/VLM_Widget.h +++ b/src/mvc/VLM_Widget.h @@ -31,6 +31,7 @@ #include #include #include +#include "mvc/BlueSkyPlan.h" class Solver; @@ -158,6 +159,11 @@ class VLM_Widget */ void addMicroProbeRegion(gstar::UProbeRegionGraphicsItem* annotation); + // TODO: make sure to update all ScansRegionGraphicsItems with new pointer + void setAvailScans(std::map * avail_scans) { _avail_scans = avail_scans;} + + + public slots: /** @@ -395,6 +401,8 @@ protected slots: void onLinkRegionToDataset(QString, QString, QImage); + void onScanUpdated(const BlueskyPlan &plan); + private: /** @@ -659,6 +667,8 @@ protected slots: */ QMap m_actionMap; + std::map *_avail_scans; + }; diff --git a/uProbeX.qrc b/uProbeX.qrc index 7ca2e5a..c5f4244 100644 --- a/uProbeX.qrc +++ b/uProbeX.qrc @@ -32,5 +32,8 @@ images/gear.png images/compose.png images/editing.png + images/refresh.png + images/chip_on.png + images/chip_off.png