Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
Executable
+354
@@ -0,0 +1,354 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
*
|
||||
* TableView for dynamic topics
|
||||
*
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "sampleview.h"
|
||||
#include "samplemodel.h"
|
||||
|
||||
#include "topicselector.h"
|
||||
#include "detailviewdlg.h"
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QMenu>
|
||||
#include <QFile>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
SampleView::SampleView(QWidget *parent)
|
||||
: QTableView(parent)
|
||||
, m_proxyModel(new SampleSortModel(this))
|
||||
, m_model(new SampleModel(this))
|
||||
, m_topicSelector(nullptr)
|
||||
, m_playTimer(this)
|
||||
, m_repeat(false)
|
||||
, m_bConnected(false)
|
||||
, m_logger(DdsView::getLogger("SampleView"))
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
void SampleView::init()
|
||||
{
|
||||
m_proxyModel->setSourceModel(m_model);
|
||||
setModel(m_proxyModel);
|
||||
sortByColumn(0, Qt::AscendingOrder);
|
||||
|
||||
setSelectionBehavior(SelectRows);
|
||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
setSortingEnabled(true);
|
||||
horizontalHeader()->setStretchLastSection(true);
|
||||
setAcceptDrops(true);
|
||||
setDragEnabled(true);
|
||||
setDragDropMode(QAbstractItemView::DragDrop);
|
||||
setDropIndicatorShown(true);
|
||||
setDefaultDropAction(Qt::MoveAction);
|
||||
setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
|
||||
// verticalHeader()->hide();
|
||||
|
||||
connect(this, &SampleView::doubleClicked, this, &SampleView::onTableDoubleClicked);
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(this, &SampleView::customContextMenuRequested, this, &SampleView::onCustomContextMenuRequested);
|
||||
|
||||
connect(&m_playTimer, &QTimer::timeout, this, [this]() { onPlayTimerTimeout(); });
|
||||
m_playTimer.setSingleShot(true);
|
||||
// Todo: Model vs. ProxyModel? Column always correct?
|
||||
hideColumn(static_cast<int>(SampleModel::Column::TypeName));
|
||||
}
|
||||
|
||||
SampleView::~SampleView()
|
||||
{
|
||||
delete m_model;
|
||||
delete m_proxyModel;
|
||||
}
|
||||
|
||||
int SampleView::currentRow() const
|
||||
{
|
||||
return m_proxyModel->currentRow();
|
||||
}
|
||||
|
||||
void SampleView::setCurrentRow(int row)
|
||||
{
|
||||
m_proxyModel->setCurrentRow(row);
|
||||
}
|
||||
|
||||
void SampleView::onLoadSampleList()
|
||||
{
|
||||
QString filename = QFileDialog::getOpenFileName(this, tr("Load Sample List"), QString(), tr("Sample List Files (*.spl);;All Files(*)"));
|
||||
|
||||
if (filename.isEmpty())
|
||||
return;
|
||||
|
||||
QFile f(filename);
|
||||
if (!f.open(QFile::ReadOnly))
|
||||
{
|
||||
QMessageBox::warning(this, tr("File not readable"), tr("The selected file is not readable"));
|
||||
return;
|
||||
}
|
||||
QDomDocument doc;
|
||||
if (!doc.setContent(&f))
|
||||
{
|
||||
QMessageBox::warning(this, tr("File not readable"), tr("The selected file is no valid XML"));
|
||||
f.close();
|
||||
return;
|
||||
}
|
||||
f.close();
|
||||
|
||||
m_model->onClear();
|
||||
|
||||
QDomElement de = doc.documentElement();
|
||||
if (de.nodeName() != QLatin1String("Samples"))
|
||||
{
|
||||
QMessageBox::warning(this, tr("File not readable"), tr("The XML file has no valid Root Item."));
|
||||
return;
|
||||
}
|
||||
QDomNodeList dnl = de.childNodes();
|
||||
int errCount = 0;
|
||||
for (int i = 0; i < dnl.size(); ++i)
|
||||
{
|
||||
QDomNode dn = dnl.at(i);
|
||||
if (!dn.isElement())
|
||||
continue;
|
||||
QDomElement innerDe = dn.toElement();
|
||||
if (innerDe.nodeName() != QLatin1String("Sample"))
|
||||
continue;
|
||||
SampleModel::SampleData sample;
|
||||
bool succ = sample.fromXml(innerDe);
|
||||
if (succ)
|
||||
m_model->addRow(sample);
|
||||
else
|
||||
++errCount;
|
||||
}
|
||||
if (errCount > 0)
|
||||
QMessageBox::warning(this,
|
||||
tr("Not all samples could be read"),
|
||||
tr("There were %1 samples that could not be read from file.").arg(errCount));
|
||||
}
|
||||
|
||||
void SampleView::onSaveSampleList()
|
||||
{
|
||||
QString selectedFilter;
|
||||
QString filename = QFileDialog::getSaveFileName(this, tr("Save Sample List"), QString(),
|
||||
tr("Sample List Files (*.spl);;All Files(*)"),
|
||||
&selectedFilter);
|
||||
if (filename.isEmpty())
|
||||
return;
|
||||
|
||||
if (selectedFilter.contains(QLatin1String("spl")) && !filename.endsWith(QLatin1String(".spl")))
|
||||
filename += QLatin1String(".spl");
|
||||
|
||||
QFile f(filename);
|
||||
if (!f.open(QFile::WriteOnly))
|
||||
return;
|
||||
QDomDocument doc(QLatin1String("Samples"));
|
||||
QDomElement root = doc.createElement(QLatin1String("Samples"));
|
||||
doc.appendChild(root);
|
||||
for (int i = 0; i < m_proxyModel->rowCount(); ++i)
|
||||
{
|
||||
QModelIndex mi = m_proxyModel->index(i, 0);
|
||||
QModelIndex sourceMi = m_proxyModel->mapToSource(mi);
|
||||
SampleModel::SampleData sample = m_model->sampleData(sourceMi);
|
||||
sample.toXml(doc, root);
|
||||
}
|
||||
f.write(doc.toByteArray());
|
||||
f.close();
|
||||
}
|
||||
|
||||
void SampleView::onTableDoubleClicked(const QModelIndex &mi)
|
||||
{
|
||||
QModelIndex sourceMi = m_proxyModel->mapToSource(mi);
|
||||
if (mi.column() == SampleModel::Column::Description ||
|
||||
mi.column() == SampleModel::Column::Pause)
|
||||
return;
|
||||
|
||||
const QSharedPointer<dds::core::xtypes::DynamicData> data = m_model->sampleData(sourceMi).legatusData;
|
||||
|
||||
DetailViewDlg *dvd = m_model->sampleData(sourceMi).dialog;
|
||||
if (dvd)
|
||||
{
|
||||
dvd->fill(*data.data());
|
||||
dvd->setWindowTitle(QString::fromLatin1("%1 (%2)").arg(m_model->sampleData(sourceMi).description,
|
||||
m_model->sampleData(sourceMi).topicName));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
dvd = new DetailViewDlg(this);
|
||||
connect(dvd, &DetailViewDlg::dataChanged, this, &SampleView::onUpdateData);
|
||||
connect(dvd, &DetailViewDlg::send, this, &SampleView::send);
|
||||
dvd->init(*data.data(), m_model->sampleData(sourceMi).topicName, RwMode::WriteOnly);
|
||||
dvd->setBtnsSendOkCancel();
|
||||
dvd->setWindowTitle(QString::fromLatin1("%1 (%2)").arg(m_model->sampleData(sourceMi).description,
|
||||
m_model->sampleData(sourceMi).topicName));
|
||||
m_model->setDialog(sourceMi, dvd);
|
||||
}
|
||||
dvd->setConnected(m_bConnected);
|
||||
dvd->show();
|
||||
dvd->adjustSize();
|
||||
}
|
||||
|
||||
void SampleView::onSendSample(const QModelIndex &mi)
|
||||
{
|
||||
const QSharedPointer<dds::core::xtypes::DynamicData> data = m_model->sampleData(m_proxyModel->mapToSource(mi)).legatusData;
|
||||
emit dataClicked(*data.data());
|
||||
}
|
||||
|
||||
void SampleView::onCustomContextMenuRequested(const QPoint &p)
|
||||
{
|
||||
const auto selIndexes = selectionModel()->selectedRows();
|
||||
|
||||
QMenu menu(this);
|
||||
|
||||
menu.addAction(tr("New"), this, &SampleView::onNewTopicRequested);
|
||||
// Only allowg, when a row is selected
|
||||
if (selIndexes.count() == 1)
|
||||
menu.addAction(tr("Delete"), this, &SampleView::onDeleteIndex);
|
||||
if (selIndexes.size() == 1)
|
||||
menu.addAction(tr("Copy"), this, &SampleView::onCopyTelegram);
|
||||
if (!m_copiedSampleData.topicName.isEmpty())
|
||||
menu.addAction(tr("Paste"), this, &SampleView::onPasteTelegram);
|
||||
if (m_model->rowCount() != 0)
|
||||
menu.addAction(tr("Clear"), m_model, &SampleModel::onClear);
|
||||
|
||||
// Only allow, when a row is selected:
|
||||
if (selIndexes.count() != 0 && m_bConnected)
|
||||
menu.addAction(tr("Send"), this, &SampleView::onSendIndex);
|
||||
|
||||
// Only allow, when a row is selected:
|
||||
if (selIndexes.size() == 1)
|
||||
menu.addAction(tr("Set current"), this, &SampleView::onSetCurrent);
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
// Only allow saving all, when at least one row is available
|
||||
if (m_model->rowCount() != 0)
|
||||
menu.addAction(tr("Save all"), this, &SampleView::onSaveSampleList);
|
||||
|
||||
menu.addAction(tr("Load"), this, &SampleView::onLoadSampleList);
|
||||
|
||||
menu.exec(this->viewport()->mapToGlobal(p));
|
||||
}
|
||||
|
||||
void SampleView::onNewTopicRequested()
|
||||
{
|
||||
if (!m_topicSelector)
|
||||
{
|
||||
m_topicSelector = new TopicSelector(TopicSelector::Usage::SampleSkeletons, this);
|
||||
connect(m_topicSelector, &TopicSelector::data, this, &SampleView::onAdd);
|
||||
}
|
||||
m_topicSelector->show();
|
||||
}
|
||||
|
||||
void SampleView::onAdd(const dds::core::xtypes::DynamicData &data, const QString &topicName)
|
||||
{
|
||||
m_model->addRow(data, topicName);
|
||||
for (int i = 0; i < m_model->columnCount(QModelIndex()); ++i)
|
||||
resizeColumnToContents(i);
|
||||
}
|
||||
|
||||
void SampleView::onCopyTelegram()
|
||||
{
|
||||
const auto selIndexes = selectedIndexes();
|
||||
if (selIndexes.isEmpty())
|
||||
return;
|
||||
QModelIndex sourceMi = m_proxyModel->mapToSource(selIndexes.value(0));
|
||||
m_copiedSampleData = m_model->sampleData(sourceMi);
|
||||
}
|
||||
|
||||
void SampleView::onPasteTelegram()
|
||||
{
|
||||
if (m_copiedSampleData.topicName.isEmpty())
|
||||
return;
|
||||
m_model->addRow(m_copiedSampleData);
|
||||
}
|
||||
|
||||
void SampleView::onDeleteIndex()
|
||||
{
|
||||
QModelIndex sourceMi = m_proxyModel->mapToSource(selectedIndexes().value(0));
|
||||
m_model->deleteRow(sourceMi);
|
||||
}
|
||||
|
||||
void SampleView::onSendIndex()
|
||||
{
|
||||
const auto selIndexes = selectedIndexes();
|
||||
if (selIndexes.isEmpty())
|
||||
return;
|
||||
QModelIndex sourceMi = m_proxyModel->mapToSource(selIndexes.value(0));
|
||||
const SampleModel::SampleData sampleData = m_model->sampleData(sourceMi);
|
||||
emit send(sampleData.legatusData, sampleData.topicName);
|
||||
}
|
||||
|
||||
void SampleView::onUpdateData(const QSharedPointer<dds::core::xtypes::DynamicData> &data,
|
||||
const QString &topicName)
|
||||
{
|
||||
DetailViewDlg *dlg = qobject_cast<DetailViewDlg *>(sender());
|
||||
if (!dlg)
|
||||
return;
|
||||
|
||||
QModelIndex index = m_model->indexByDialog(dlg);
|
||||
if (index.isValid())
|
||||
m_model->updateRow(index, data, topicName);
|
||||
|
||||
}
|
||||
|
||||
void SampleView::onSetCurrent()
|
||||
{
|
||||
QModelIndex mi = selectedIndexes().value(0);
|
||||
m_proxyModel->setCurrentRow(mi.row());
|
||||
verticalHeader()->resizeSections(QHeaderView::ResizeToContents);
|
||||
}
|
||||
|
||||
void SampleView::onPlayChecked(bool down)
|
||||
{
|
||||
// Unchecked
|
||||
if (!down)
|
||||
{
|
||||
m_playTimer.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
// If no valid row, start from first row
|
||||
if (currentRow() < 0)
|
||||
setCurrentRow(0);
|
||||
|
||||
onPlayTimerTimeout(false);
|
||||
}
|
||||
|
||||
void SampleView::onPlayTimerTimeout(bool moveOn)
|
||||
{
|
||||
// Move to next row
|
||||
if (moveOn)
|
||||
{
|
||||
setCurrentRow(currentRow() + 1);
|
||||
// If moved beyond end
|
||||
if (currentRow() < 0)
|
||||
{
|
||||
// start over
|
||||
if (m_repeat)
|
||||
setCurrentRow(0);
|
||||
else
|
||||
{
|
||||
// or stop
|
||||
emit playerActive(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const SampleModel::SampleData sampleData = m_model->sampleData(m_proxyModel->mapToSource(m_proxyModel->index(currentRow(), 0)));
|
||||
if (sampleData.legatusData)
|
||||
emit send(sampleData.legatusData, sampleData.topicName);
|
||||
|
||||
int pause = m_model->sampleData(m_proxyModel->index(currentRow(), 0)).pause;
|
||||
|
||||
if (pause > 0)
|
||||
m_playTimer.start(pause);
|
||||
else
|
||||
emit playerActive(false);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user