/** * @RDE_HEADER@ * * TableView for dynamic topics * * $Id$ * $HeadURL$ * $Author$ */ #include "telegramview.h" #include "telegrammodel.h" #include "detailviewdlg.h" #include "nglsettings.h" #include #include #include #include #include TelegramView::TelegramView(QWidget *parent) : QTableView(parent) , m_proxyModel(new TelegramSortModel(this)) , m_model(new TelegramModel(this)) , m_bConnected(false) , m_logger(DdsView::getLogger("TelegramView")) { init(); } void TelegramView::init() { m_proxyModel->setSourceModel(m_model); setModel(m_proxyModel); sortByColumn(0, Qt::AscendingOrder); setAcceptDrops(true); setDragEnabled(true); setDragDropMode(QAbstractItemView::DragDrop); setDropIndicatorShown(true); setDefaultDropAction(Qt::CopyAction); setSelectionBehavior(SelectRows); setSortingEnabled(true); horizontalHeader()->setStretchLastSection(true); // verticalHeader()->hide(); // show for visual counting for (int i = 0; i < m_model->columnCount(QModelIndex()); ++i) resizeColumnToContents(i); connect(this, &TelegramView::doubleClicked, this, &TelegramView::onTableDoubleClicked); connect(selectionModel(), &QItemSelectionModel::currentChanged, this, &TelegramView::onTableClicked); setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &TelegramView::customContextMenuRequested, this, &TelegramView::onCustomContextMenuRequested); connect(m_model, &TelegramModel::send, this, &TelegramView::send); } TelegramView::~TelegramView() { delete m_model; delete m_proxyModel; } void TelegramView::onCustomContextMenuRequested(const QPoint &p) { QMenu menu(this); QAction *a; a = menu.addAction(tr("Delete"), this, &TelegramView::onDeleteIndex); // Only allow deleting, when at least one row is selected if (selectedIndexes().count() == 0) a->setDisabled(true); menu.addAction(tr("Clear"), m_model, &TelegramModel::onClear); a = menu.addAction(tr("Send"), this, &TelegramView::onSendIndex); // Only allow sending, when only one row is selected: if (selectedIndexes().count() > m_model->columnCount(QModelIndex()) || selectedIndexes().count() == 0 || !m_bConnected) a->setDisabled(true); menu.addSeparator(); a = menu.addAction(tr("Save selected"), this, &TelegramView::onSaveIndex); // Only allow saving, when at least one row is selected if (selectedIndexes().count() == 0) a->setDisabled(true); a = menu.addAction(tr("Save all"), this, &TelegramView::onSaveAllIndexes); // Only allow saving all, when at least one row is available if (m_model->rowCount(QModelIndex()) == 0) a->setDisabled(true); menu.exec(viewport()->mapToGlobal(p)); } void TelegramView::onDeleteIndex() { const auto selIndexes = selectedIndexes(); for (const QModelIndex &mi : selIndexes) { if (mi.column() != 0) continue; QModelIndex sourceMi = m_proxyModel->mapToSource(mi); m_model->deleteRow(sourceMi); } } void TelegramView::onSendIndex() { // Selected Indexes should be only those in exactly one row. // Todo: return after emit to not being able to send millions of samples? const auto selIndexes = selectedIndexes(); for (const QModelIndex &mi : selIndexes) { if (mi.column() != 0) continue; const TelegramModel::TelegramData telegram = m_model->telegramData(m_proxyModel->mapToSource(mi)); emit send(telegram.legatusData, telegram.topicName); } } void TelegramView::onSaveIndex() { QVector vector; const auto selIndexes = selectedIndexes(); for (const QModelIndex &mi : selIndexes) { if (mi.column() != 0) continue; vector.append(m_model->telegramData(m_proxyModel->mapToSource(mi))); } onSaveDynamicDataVector(vector); } void TelegramView::onSaveAllIndexes() { // Iterate over the proxy model to preserve sorting! QVector vector; vector.reserve(m_proxyModel->rowCount()); for (int i = 0; i < m_proxyModel->rowCount(); ++i) { QModelIndex mi = m_proxyModel->index(i, 0); QModelIndex sourceMi = m_proxyModel->mapToSource(mi); vector.append(m_model->telegramData(sourceMi)); } onSaveDynamicDataVector(vector); } void TelegramView::onSaveDynamicDataVector(const QVector &vector) { QString filename = QFileDialog::getSaveFileName(this, tr("Save Sample List"), QString(), tr("Sample List Files (*.spl);;All Files(*)")); QFile f(filename); if (!f.open(QFile::WriteOnly)) return; QDomDocument doc(QLatin1String("Samples")); QDomElement root = doc.createElement(QLatin1String("Samples")); doc.appendChild(root); for (const TelegramModel::TelegramData &telegram : vector) telegram.toXml(doc, root); f.write(doc.toByteArray()); f.close(); } void TelegramView::onTableDoubleClicked(const QModelIndex &mi) { const QSharedPointer data = m_model->dynamicData(m_proxyModel->mapToSource(mi)); const QString topicName = m_model->topicName(m_proxyModel->mapToSource(mi)); DetailViewDlg *dtv = new DetailViewDlg(this); dtv->init(*data.data(), topicName, RwMode::ReadWrite); dtv->setBtnsSendClose(); dtv->show(); dtv->setConnected(m_bConnected); connect(dtv, &DetailViewDlg::send, this, &TelegramView::send); } void TelegramView::onTableClicked(const QModelIndex &mi) { if (selectedIndexes().count() > m_model->columnCount(QModelIndex()) || !mi.isValid()) { emit clearDetailView(); return; } const QSharedPointer data = m_model->dynamicData(m_proxyModel->mapToSource(mi)); emit dataClicked(*data.data(), m_model->topicName(m_proxyModel->mapToSource(mi))); } void TelegramView::onTypeCodeInfosChanged() { m_model->onTypeCodeInfosChanged(); }