27 #include "ui_telemetryscheduler.h"
28 #include "ui_metadata_dialog.h"
31 #include <QtCore/qglobal.h>
36 #include <QStringList>
37 #include <QMessageBox>
39 #include <QFileDialog>
43 #include <QVBoxLayout>
44 #include <QPushButton>
46 #include <QInputDialog>
61 m_telemetryeditor =
new Ui_TelemetryScheduler();
62 m_telemetryeditor->setupUi(
this);
68 m_telemetryeditor->bnApplySchedule->setVisible(
false);
73 telemetryScheduleView->setObjectName(QString::fromUtf8(
"telemetryScheduleView"));
74 telemetryScheduleView->setAlternatingRowColors(
true);
75 telemetryScheduleView->horizontalHeader()->setCascadingSectionResizes(
false);
76 telemetryScheduleView->horizontalHeader()->setSectionsMovable(
true);
80 int dummyIndex = m_telemetryeditor->gridLayout->indexOf(m_telemetryeditor->tableWidgetDummy);
81 int row, col, rowSpan, colSpan;
82 m_telemetryeditor->gridLayout->getItemPosition(dummyIndex, &row, &col, &rowSpan, &colSpan);
83 m_telemetryeditor->gridLayout->removeWidget(m_telemetryeditor->tableWidgetDummy);
84 m_telemetryeditor->tableWidgetDummy->setVisible(
false);
85 m_telemetryeditor->gridLayout->addWidget(telemetryScheduleView, row, col, rowSpan, colSpan);
86 connect(m_telemetryeditor->hideNotPresent, &QAbstractButton::clicked,
this,
87 &TelemetrySchedulerGadgetWidget::onHideNotPresent);
90 telemetryScheduleView->setItemDelegate(delegate);
93 connect(m_telemetryeditor->bnSaveTelemetryToFile, &QAbstractButton::clicked,
this,
94 &TelemetrySchedulerGadgetWidget::saveTelemetryToFile);
95 connect(m_telemetryeditor->bnLoadTelemetryFromFile, &QAbstractButton::clicked,
this,
96 &TelemetrySchedulerGadgetWidget::loadTelemetryFromFile);
97 connect(m_telemetryeditor->bnApplySchedule, &QAbstractButton::clicked,
this,
98 &TelemetrySchedulerGadgetWidget::applySchedule);
99 connect(m_telemetryeditor->bnSaveSchedule, &QAbstractButton::clicked,
this,
100 &TelemetrySchedulerGadgetWidget::saveSchedule);
101 connect(m_telemetryeditor->bnAddTelemetryColumn, &QAbstractButton::clicked,
this,
102 &TelemetrySchedulerGadgetWidget::addTelemetryColumn);
103 connect(m_telemetryeditor->bnRemoveTelemetryColumn, &QAbstractButton::clicked,
this,
104 &TelemetrySchedulerGadgetWidget::removeTelemetryColumn);
105 connect(schedulerModel, &SchedulerModel::itemChanged,
this,
106 QOverload<QStandardItem *>::of(&TelemetrySchedulerGadgetWidget::dataModel_itemChanged));
107 connect(telemetryScheduleView->horizontalHeader(), &QHeaderView::sectionDoubleClicked,
this,
108 &TelemetrySchedulerGadgetWidget::changeHorizontalHeader);
109 connect(telemetryScheduleView->verticalHeader(), &QHeaderView::sectionDoubleClicked,
this,
110 &TelemetrySchedulerGadgetWidget::changeVerticalHeader);
111 connect(telemetryScheduleView, &QWidget::customContextMenuRequested,
this,
112 &TelemetrySchedulerGadgetWidget::customMenuRequested);
113 telemetryScheduleView->setContextMenuPolicy(Qt::CustomContextMenu);
117 Q_ASSERT(objManager != NULL);
121 foreach (QVector<UAVDataObject *> list, objList) {
122 if (!list.first()->isSettings()) {
123 strList.append(list.first()->getName());
124 connect(qobject_cast<UAVDataObject *>(list.first()),
126 &TelemetrySchedulerGadgetWidget::uavoPresentOnHardwareChanged,
127 Qt::UniqueConnection);
130 strList.sort(Qt::CaseInsensitive);
132 foreach (QString str, strList) {
133 schedulerModel->setVerticalHeaderItem(rowIndex,
new QStandardItem(str));
138 uavoIndex.insert(dobj, rowIndex);
144 0,
new QStandardItem(
"Bandwidth required [bytes/s]"));
148 int width = telemetryScheduleView->verticalHeader()->sizeHint().width();
152 columnHeaders <<
"Default"
159 foreach (QString header, columnHeaders) {
160 schedulerModel->setHorizontalHeaderItem(columnIndex,
new QStandardItem(header));
162 telemetryScheduleView->setColumnWidth(columnIndex, 100);
171 foreach (QString objStr, strList) {
176 QModelIndex index = schedulerModel->index(rowIndex, 0, QModelIndex());
177 schedulerModel->setData(index,
178 QString(
"%1ms").arg(mdataDefault.flightTelemetryUpdatePeriod));
181 defaultMdata.insert(obj->
getName().append(
"Meta"), mdataDefault);
188 &TelemetrySchedulerGadgetWidget::updateCurrentColumn);
191 updateCurrentColumn(mobj);
196 m_telemetryeditor->cmbScheduleList->addItem(
"");
197 m_telemetryeditor->cmbScheduleList->addItems(columnHeaders);
198 onHideNotPresent(
true);
210 void TelemetrySchedulerGadgetWidget::updateCurrentColumn(
UAVObject *obj)
221 for (
int i = 1;
i < schedulerModel->rowCount();
i++) {
224 if (schedulerModel->verticalHeaderItem(
i)->text().append(
"Meta") == mobj->
getName()) {
231 if (rowIndex == -1) {
237 UAVObject::Metadata mdataDefault = defaultMdata.value(mobj->
getName());
238 UAVObject::Metadata mdata = mobj->
getData();
240 if (mdata.flightTelemetryUpdatePeriod != mdataDefault.flightTelemetryUpdatePeriod) {
241 QModelIndex index = schedulerModel->index(rowIndex, 1, QModelIndex());
242 schedulerModel->setData(index, QString(
"%1ms").arg(mdata.flightTelemetryUpdatePeriod));
250 void TelemetrySchedulerGadgetWidget::dataModel_itemChanged(QStandardItem *item)
252 m_telemetryeditor->bnSaveSchedule->setIcon(QIcon());
253 m_telemetryeditor->bnApplySchedule->setIcon(QIcon());
254 int col = item->column();
255 dataModel_itemChanged(col);
262 void TelemetrySchedulerGadgetWidget::dataModel_itemChanged(
int col)
265 double bandwidthRequired_bps = 0;
266 for (
int i = 1;
i < schedulerModel->rowCount();
i++) {
268 QString uavObjectName = schedulerModel->verticalHeaderItem(
i)->text();
271 if (dobj && m_telemetryeditor->hideNotPresent->isChecked()
278 QModelIndex index = schedulerModel->index(
i, col, QModelIndex());
279 double updatePeriod_s;
280 if (schedulerModel->data(index).isValid() && stripMs(schedulerModel->data(index)) >= 0)
281 updatePeriod_s = stripMs(schedulerModel->data(index)) / 1000.0;
284 defaultMdata.value(obj->
getName().append(
"Meta")).flightTelemetryUpdatePeriod
287 double updateFrequency_Hz = updatePeriod_s > 0 ? 1.0 / updatePeriod_s : 0;
290 bandwidthRequired_bps += updateFrequency_Hz * size;
293 QModelIndex index = telemetryScheduleView->
getFrozenModel()->index(0, col, QModelIndex());
295 index, QString(
"%1B/s").arg(lround(bandwidthRequired_bps)));
300 void TelemetrySchedulerGadgetWidget::saveTelemetryToFile()
302 QString
file = filename;
303 QString filter = tr(
"Telemetry Scheduler file (*.xml)");
304 file = QFileDialog::getSaveFileName(
this,
305 tr(
"Save Telemetry Schedule to file .."),
306 QFileInfo(file).absoluteFilePath(), filter, &filter).trimmed();
308 if (file.isEmpty()) {
311 if (!file.endsWith(
".xml", Qt::CaseInsensitive))
319 QDomDocument doc(
"TelemetryScheduler");
320 QDomElement root = doc.createElement(
"telemetry_scheduler");
321 doc.appendChild(root);
324 QDomElement versionInfo = doc.createElement(
"version");
325 root.appendChild(versionInfo);
328 QDomElement settings = doc.createElement(
"settings");
329 QDomElement headings = doc.createElement(
"headings");
332 QStringList tmpStringList = columnHeaders;
333 tmpStringList.pop_front();
334 tmpStringList.pop_front();
337 QDomElement o = doc.createElement(
"headings");
338 o.setAttribute(
"values", tmpStringList.join(
","));
341 root.appendChild(settings);
344 for (
int row = 1; row < schedulerModel->rowCount(); row++) {
345 QString uavObjectName = schedulerModel->verticalHeaderItem(row)->text();
350 QDomElement o = doc.createElement(
"uavobject");
351 o.setAttribute(
"name", obj->
getName());
352 o.setAttribute(
"id", QString(
"0x") + QString().setNum(obj->
getObjID(), 16).toUpper());
355 for (
int col = 0; col < columnHeaders.length(); col++) {
356 QModelIndex index = schedulerModel->index(row, col + 1, QModelIndex());
357 vals << schedulerModel->data(index).toString();
360 QDomElement f = doc.createElement(
"field");
361 f.setAttribute(
"values", vals.join(
","));
365 settings.appendChild(o);
368 QString xml = doc.toString(4);
371 QFile
file(filename);
372 if (file.open(QIODevice::WriteOnly) && (file.write(xml.toLatin1()) != -1)) {
375 QMessageBox::critical(
this, tr(
"UAV Data Export"), tr(
"Unable to save data: ") + filename,
381 msgBox.setText(tr(
"Data saved."));
382 msgBox.setStandardButtons(QMessageBox::Ok);
395 if (m_telemetryeditor->cmbScheduleList->currentText().isEmpty()) {
396 QMessageBox::warning(
this, tr(
"No Schedule selected"),
397 tr(
"Please select a schedule on the dropbox to the left and retry"),
402 for (
int j = 0; j < schedulerModel->columnCount(); j++) {
403 if (schedulerModel->horizontalHeaderItem(j)->text()
404 == m_telemetryeditor->cmbScheduleList->currentText()) {
415 QMap<QString, UAVObject::Metadata> metaDataList;
416 for (
int i = 1;
i < schedulerModel->rowCount();
i++) {
418 QString uavObjectName = schedulerModel->verticalHeaderItem(
i)->text();
426 double updatePeriod_ms;
427 QModelIndex index = schedulerModel->index(
i, col, QModelIndex());
428 if (schedulerModel->data(index).isValid() && stripMs(schedulerModel->data(index)) >= 0) {
429 updatePeriod_ms = stripMs(schedulerModel->data(index));
430 mdata.flightTelemetryUpdatePeriod = updatePeriod_ms;
431 metaDataList.insert(uavObjectName, mdata);
437 if (sender() == m_telemetryeditor->bnApplySchedule) {
439 &TelemetrySchedulerGadgetWidget::onCompletedMetadataWrite);
440 m_telemetryeditor->bnApplySchedule->setIcon(QIcon(
":/uploader/images/system-run.svg"));
443 &TelemetrySchedulerGadgetWidget::onSavedSchedule);
444 m_telemetryeditor->bnSaveSchedule->setIcon(QIcon(
":/uploader/images/system-run.svg"));
446 m_telemetryeditor->bnApplySchedule->setEnabled(
false);
447 m_telemetryeditor->bnSaveSchedule->setEnabled(
false);
455 void TelemetrySchedulerGadgetWidget::saveSchedule()
458 metaObjectsToSave = applySchedule();
461 void TelemetrySchedulerGadgetWidget::onSavedSchedule(
bool value)
464 &TelemetrySchedulerGadgetWidget::onSavedSchedule);
465 if (metaObjectsToSave.isEmpty()) {
466 m_telemetryeditor->bnSaveSchedule->setIcon(QIcon(
":/uploader/images/dialog-apply.svg"));
470 m_telemetryeditor->bnSaveSchedule->setIcon(QIcon(
":/uploader/images/process-stop.svg"));
474 &TelemetrySchedulerGadgetWidget::onCompletedMetadataSave);
475 onCompletedMetadataSave(-1,
true);
481 void TelemetrySchedulerGadgetWidget::onCompletedMetadataWrite(
bool value)
484 m_telemetryeditor->bnApplySchedule->setIcon(QIcon(
":/uploader/images/dialog-apply.svg"));
486 m_telemetryeditor->bnApplySchedule->setIcon(QIcon(
":/uploader/images/process-stop.svg"));
487 m_telemetryeditor->bnApplySchedule->setEnabled(
true);
488 m_telemetryeditor->bnSaveSchedule->setEnabled(
true);
490 &TelemetrySchedulerGadgetWidget::onCompletedMetadataWrite);
493 void TelemetrySchedulerGadgetWidget::onCompletedMetadataSave(
int id,
bool result)
495 static bool success =
true;
504 if (!result && metaObjectsToSave.contains(meta)) {
505 qDebug() << meta->
getName() <<
"save failed";
508 metaObjectsToSave.removeAll(meta);
510 if (metaObjectsToSave.isEmpty()) {
512 m_telemetryeditor->bnSaveSchedule->setIcon(QIcon(
":/uploader/images/dialog-apply.svg"));
514 m_telemetryeditor->bnSaveSchedule->setIcon(QIcon(
":/uploader/images/process-stop.svg"));
515 m_telemetryeditor->bnApplySchedule->setEnabled(
true);
516 m_telemetryeditor->bnSaveSchedule->setEnabled(
true);
518 &TelemetrySchedulerGadgetWidget::onCompletedMetadataSave);
522 void TelemetrySchedulerGadgetWidget::loadTelemetryFromFile()
525 QString file = filename;
526 QString filter = tr(
"Telemetry Scheduler file (*.xml)");
527 file = QFileDialog::getOpenFileName(
this,
528 tr(
"Load Telemetry Schedule from file .."),
529 QFileInfo(file).absoluteFilePath(), filter).trimmed();
530 if (file.isEmpty()) {
536 QMessageBox msgBox(
this);
537 if (!QFileInfo(file).isReadable()) {
538 msgBox.setText(tr(
"Can't read file ") + QFileInfo(file).absoluteFilePath());
542 importTelemetryConfiguration(file);
545 void TelemetrySchedulerGadgetWidget::importTelemetryConfiguration(
const QString &fileName)
548 QFile
file(fileName);
549 QDomDocument doc(
"TelemetryScheduler");
550 file.open(QFile::ReadOnly | QFile::Text);
551 if (!doc.setContent(file.readAll())) {
552 QMessageBox msgBox(
this);
553 msgBox.setText(tr(
"File Parsing Failed."));
554 msgBox.setInformativeText(tr(
"This file is not a correct XML file"));
555 msgBox.setStandardButtons(QMessageBox::Ok);
563 QDomElement root = doc.documentElement();
564 if (root.tagName() ==
"telemetry_scheduler") {
565 root = root.firstChildElement(
"headings");
569 if (root.isNull() || (root.tagName() !=
"headings")) {
570 QMessageBox msgBox(
this);
571 msgBox.setText(tr(
"Wrong file contents"));
572 msgBox.setInformativeText(tr(
"This file does not contain correct telemetry settings"));
573 msgBox.setStandardButtons(QMessageBox::Ok);
578 QDomElement f = root.toElement();
579 QStringList new_columnHeaders = f.attribute(
"values").split(
",");
580 new_columnHeaders.insert(0,
"Default");
581 new_columnHeaders.insert(1,
"Current");
584 schedulerModel->removeColumns(2, columnHeaders.length() - 2, QModelIndex());
585 telemetryScheduleView->
removeColumns(2, columnHeaders.length() - 2, QModelIndex());
588 schedulerModel->setHorizontalHeaderLabels(new_columnHeaders);
593 for (
int columnIndex = 0; columnIndex < new_columnHeaders.length(); columnIndex++) {
595 telemetryScheduleView->setColumnWidth(columnIndex, 100);
601 columnHeaders = new_columnHeaders;
604 m_telemetryeditor->cmbScheduleList->clear();
605 m_telemetryeditor->cmbScheduleList->addItem(
"");
606 m_telemetryeditor->cmbScheduleList->addItems(columnHeaders);
609 root = doc.documentElement();
610 if (root.tagName() ==
"telemetry_scheduler") {
611 root = root.firstChildElement(
"settings");
613 if (root.isNull() || (root.tagName() !=
"settings")) {
614 QMessageBox msgBox(
this);
615 msgBox.setText(tr(
"Wrong file contents"));
616 msgBox.setInformativeText(tr(
"This file does not contain correct telemetry settings"));
617 msgBox.setStandardButtons(QMessageBox::Ok);
622 QDomNode node = root.firstChild();
623 while (!node.isNull()) {
624 QDomElement
e = node.toElement();
625 if (e.tagName() ==
"uavobject") {
627 QString uavObjectName = e.attribute(
"name");
628 uint uavObjectID = e.attribute(
"id").toUInt(NULL, 16);
634 qDebug() <<
"Object unknown:" << uavObjectName << uavObjectID;
637 QDomNode field = node.firstChild();
638 QDomElement f = field.toElement();
639 if (f.tagName() ==
"field") {
641 QStringList valuesList = f.attribute(
"values").split(
",");
645 for (
int i = 1;
i < schedulerModel->rowCount();
i++) {
646 if (schedulerModel->verticalHeaderItem(
i)->text() == uavObjectName) {
653 for (
int j = 0; j < valuesList.length(); j++) {
654 QModelIndex index = schedulerModel->index(row, j + 2, QModelIndex());
655 quint32 val = stripMs(valuesList[j]);
659 schedulerModel->setData(index, QString(
"%1ms").arg(val));
662 field = field.nextSibling();
665 node = node.nextSibling();
667 qDebug() <<
"Import ended";
673 void TelemetrySchedulerGadgetWidget::addTelemetryColumn()
675 int newColumnIndex = schedulerModel->columnCount();
676 QString newColumnString =
"New Column";
677 schedulerModel->setHorizontalHeaderItem(newColumnIndex,
new QStandardItem(newColumnString));
679 telemetryScheduleView->setColumnWidth(newColumnIndex,
682 columnHeaders.append(newColumnString);
683 m_telemetryeditor->cmbScheduleList->clear();
684 m_telemetryeditor->cmbScheduleList->addItem(
"");
685 m_telemetryeditor->cmbScheduleList->addItems(columnHeaders);
691 void TelemetrySchedulerGadgetWidget::removeTelemetryColumn()
693 int oldColumnIndex = schedulerModel->columnCount();
694 schedulerModel->removeColumns(oldColumnIndex - 1, 1);
697 columnHeaders.pop_back();
698 m_telemetryeditor->cmbScheduleList->clear();
699 m_telemetryeditor->cmbScheduleList->addItem(
"");
700 m_telemetryeditor->cmbScheduleList->addItems(columnHeaders);
706 void TelemetrySchedulerGadgetWidget::changeHorizontalHeader(
int headerIndex)
710 QInputDialog::getText(
this, tr(
"Change header name"), tr(
"Input new column name:"),
711 QLineEdit::Normal, columnHeaders.at(headerIndex), &ok);
715 schedulerModel->setHorizontalHeaderItem(headerIndex,
new QStandardItem(headerName));
717 columnHeaders.replace(headerIndex, headerName);
718 m_telemetryeditor->cmbScheduleList->clear();
719 m_telemetryeditor->cmbScheduleList->addItem(
"");
720 m_telemetryeditor->cmbScheduleList->addItems(columnHeaders);
723 void TelemetrySchedulerGadgetWidget::customMenuRequested(QPoint pos)
727 QString text = QInputDialog::getText(this, tr("Mass value filling"), tr("Choose value to use"),
728 QLineEdit::Normal, "", &ok);
733 QMessageBox msgBox(
this);
734 msgBox.setText(
"Value must be numeric");
738 if (!text.isEmpty()) {
739 foreach (QModelIndex index, telemetryScheduleView->selectionModel()->selectedIndexes()) {
740 telemetryScheduleView->model()->setData(index, text);
745 void TelemetrySchedulerGadgetWidget::uavoPresentOnHardwareChanged(
UAVDataObject *obj)
747 if (m_telemetryeditor->hideNotPresent->isChecked())
749 int width = telemetryScheduleView->verticalHeader()->sizeHint().width();
752 for (
int x = 0;
x < schedulerModel->columnCount(); ++
x) {
753 dataModel_itemChanged(
x);
757 void TelemetrySchedulerGadgetWidget::onHideNotPresent(
bool hide)
761 telemetryScheduleView->setRowHidden(uavoIndex.value(obj),
764 int width = telemetryScheduleView->verticalHeader()->sizeHint().width();
768 foreach (
int index, uavoIndex.values()) {
769 telemetryScheduleView->setRowHidden(index,
false);
771 int width = telemetryScheduleView->verticalHeader()->sizeHint().width();
775 for (
int x = 0;
x < schedulerModel->columnCount(); ++
x) {
776 dataModel_itemChanged(
x);
783 void TelemetrySchedulerGadgetWidget::changeVerticalHeader(
int headerIndex)
786 QString uavObjectName = schedulerModel->verticalHeaderItem(headerIndex)->text();
793 metadataDialog.setWindowTitle(QString(uavObj->
getName() +
" settings"));
795 if (metadataDialog.exec() != QDialog::Accepted)
798 UAVObject::Metadata newMetadata;
799 if (metadataDialog.getResetDefaults_flag() ==
false)
800 newMetadata = metadataDialog.getMetadata();
803 newMetadata.flightTelemetryUpdatePeriod = mdata.flightTelemetryUpdatePeriod;
808 if (metadataDialog.getSaveState_flag()) {
822 int TelemetrySchedulerGadgetWidget::stripMs(QVariant rate_ms)
824 return rate_ms.toString().replace(QString(
"ms"), QString(
"")).toUInt();
856 : QItemDelegate(parent)
861 const QModelIndex & )
const
863 QSpinBox *editor =
new QSpinBox(parent);
864 editor->setMinimum(0);
865 editor->setMaximum(65535);
866 editor->setSuffix(QString(
"ms"));
873 int value = index.model()->data(index, Qt::EditRole).toInt();
875 QSpinBox *spinBox =
static_cast<QSpinBox *
>(editor);
877 spinBox->setValue(value);
883 const QModelIndex &index)
const
885 QSpinBox *spinBox =
static_cast<QSpinBox *
>(editor);
886 spinBox->interpretText();
887 int value = spinBox->value();
890 model->setData(index, QString(
"%1ms").arg(value), Qt::EditRole);
894 const QModelIndex & )
const
896 editor->setGeometry(option.rect);
901 void QFrozenTableViewWithCopyPaste::copy()
903 QItemSelectionModel *selection = selectionModel();
904 QModelIndexList indexes = selection->selectedIndexes();
906 if (indexes.size() < 1)
911 std::sort(indexes.begin(), indexes.end());
914 QModelIndex previous = indexes.first();
915 indexes.removeFirst();
916 QString selected_text;
918 foreach (current, indexes) {
919 QVariant
data = model()->data(previous);
920 QString text = data.toString();
922 selected_text.append(text);
925 if (current.row() != previous.row()) {
926 selected_text.append(QLatin1Char(
'\n'));
930 selected_text.append(QLatin1Char(
'\t'));
936 selected_text.append(model()->
data(current).toString());
937 selected_text.append(QLatin1Char(
'\n'));
938 qApp->clipboard()->setText(selected_text);
941 void QFrozenTableViewWithCopyPaste::paste()
943 QItemSelectionModel *selection = selectionModel();
944 QModelIndexList indexes = selection->selectedIndexes();
946 QString selected_text = qApp->clipboard()->text();
947 QStringList cells = selected_text.split(QRegExp(QLatin1String(
"\\n|\\t")));
948 while (!cells.empty() && cells.back().size() == 0) {
951 int rows = selected_text.count(QLatin1Char(
'\n'));
952 int cols = cells.size() / rows;
953 if (cells.size() % rows != 0) {
955 QMessageBox::critical(
this, tr(
"Error"),
956 tr(
"Invalid clipboard data, unable to perform paste operation."));
961 if (indexes.front().row() + rows > model()->rowCount()) {
963 QMessageBox::critical(
this, tr(
"Error"),
964 tr(
"Invalid operation, pasting would exceed the number of rows."));
970 if (indexes.front().column() + cols > model()->columnCount()) {
972 QMessageBox::critical(
this, tr(
"Error"),
973 tr(
"Invalid operation, pasting would exceed the number of columns."));
979 for (
int row = 0; row < rows; ++row) {
980 for (
int col = 0; col < cols; ++col, ++cell) {
981 QModelIndex index = model()->index(indexes.front().row() + row,
982 indexes.front().column() + col, QModelIndex());
983 model()->setData(index, cells[cell]);
988 void QFrozenTableViewWithCopyPaste::deleteCells()
990 QItemSelectionModel *selection = selectionModel();
991 QModelIndexList indices = selection->selectedIndexes();
993 if (indices.size() < 1)
996 foreach (QModelIndex index, indices) {
997 QStandardItemModel *stdModel =
dynamic_cast<QStandardItemModel *
>(model());
998 if (stdModel == NULL) {
1003 stdModel->takeItem(index.row(), index.column());
1012 if (event->matches(QKeySequence::Copy)) {
1014 }
else if (event->matches(QKeySequence::Paste)) {
1016 }
else if (event->matches(QKeySequence::Delete) ||
event->key() == Qt::Key_Backspace) {
1019 QTableView::keyPressEvent(event);
1026 frozenTableView =
new QTableView(
this);
1031 connect(horizontalHeader(), &QHeaderView::sectionResized,
this,
1032 &QFrozenTableViewWithCopyPaste::updateSectionWidth);
1033 connect(verticalHeader(), &QHeaderView::sectionResized,
this,
1034 &QFrozenTableViewWithCopyPaste::updateSectionHeight);
1036 connect(frozenTableView->horizontalScrollBar(), &QAbstractSlider::valueChanged,
1037 horizontalScrollBar(), &QAbstractSlider::setValue);
1038 connect(horizontalScrollBar(), &QAbstractSlider::valueChanged,
1039 frozenTableView->horizontalScrollBar(), &QAbstractSlider::setValue);
1044 delete frozenTableView;
1051 void QFrozenTableViewWithCopyPaste::init()
1053 frozenModel =
new QStandardItemModel(0, 0,
this);
1055 frozenTableView->setModel(frozenModel);
1056 frozenTableView->setFocusPolicy(Qt::NoFocus);
1057 frozenTableView->horizontalHeader()->hide();
1058 frozenTableView->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
1060 viewport()->stackUnder(frozenTableView);
1064 frozenTableView->setStyleSheet(
"QTableView { border: none;"
1066 "background-color: #8EDE21;"
1067 "selection-background-color: #999}");
1068 for (
int row = 1; row < model()->rowCount(); row++)
1069 frozenTableView->setRowHidden(row,
true);
1071 frozenTableView->setRowHeight(rowHeight(0), 0);
1073 frozenTableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1074 this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1075 frozenTableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1076 frozenTableView->show();
1078 updateFrozenTableGeometry(0);
1080 setHorizontalScrollMode(ScrollPerPixel);
1081 setVerticalScrollMode(ScrollPerPixel);
1082 frozenTableView->setHorizontalScrollMode(ScrollPerPixel);
1085 frozenTableView->setEnabled(
false);
1090 void QFrozenTableViewWithCopyPaste::updateSectionWidth(
int logicalIndex,
int,
int newSize)
1092 frozenTableView->setColumnWidth(logicalIndex, newSize);
1093 updateFrozenTableGeometry(0);
1096 void QFrozenTableViewWithCopyPaste::updateSectionHeight(
int logicalIndex,
int,
int newSize)
1098 if (logicalIndex == 0) {
1099 frozenTableView->setRowHeight(0, newSize);
1100 updateFrozenTableGeometry(0);
1111 for (
int x = 0;
x < frozenTableView->model()->columnCount(); ++
x) {
1112 frozenTableView->setColumnWidth(
x, horizontalHeader()->sectionSize(
x));
1114 updateFrozenTableGeometry(value);
1119 QTableView::resizeEvent(event);
1124 if (index.row() != 0) {
1125 QTableView::scrollTo(index, hint);
1129 void QFrozenTableViewWithCopyPaste::updateFrozenTableGeometry(
int verticalHeaderWidth)
1131 if (verticalHeaderWidth == 0)
1132 verticalHeaderWidth = verticalHeader()->width();
1134 for (
int i = 0;
i < this->model()->columnCount(); ++
i) {
1135 col_width += columnWidth(
i);
1137 frozenTableView->setGeometry(frameWidth(), horizontalHeader()->height() + frameWidth(),
1138 verticalHeaderWidth + col_width, rowHeight(0));
1148 frozenModel->setHorizontalHeaderItem(column, item);
1149 updateFrozenTableGeometry(0);
1158 bool ret = frozenModel->removeColumns(column, count, parent);
1159 updateFrozenTableGeometry(0);
virtual Metadata getDefaultMetadata()=0
virtual void setMetadata(const Metadata &mdata)=0
void completedMetadataWrite(bool)
virtual void keyPressEvent(QKeyEvent *event)
TelemetrySchedulerGadgetWidget(QWidget *parent=nullptr)
bool removeColumns(int column, int count, const QModelIndex &parent=QModelIndex())
QFrozenTableViewWithCopyPaste::removeColumns Ensures that the frozen table geometry is updated when c...
Core plugin system that manages the plugins, their life cycle and their registered objects...
virtual void resizeEvent(QResizeEvent *event)
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
QFrozenTableViewWithCopyPaste(QAbstractItemModel *model)
void objectUpdated(UAVObject *obj)
Signal sent whenever any field of the object is updated.
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
QStandardItemModel * getFrozenModel()
virtual Metadata getMetadata()=0
UAVMetaObject * getMetaObject()
bool setAllNonSettingsMetadata(QMap< QString, UAVObject::Metadata >)
UAVObjectUtilManager::setAllNonSettingsMetadata Convenience function for calling setMetadata.
QTableView * getFrozenTableView()
void saveObjectToFlash(UAVObject *obj)
UAVObjectUtilManager::saveObjectToSD Add a new object to save in the queue.
The QFrozenTableViewWithCopyPaste class QTableView with support for a frozen row as well as copy and ...
~QFrozenTableViewWithCopyPaste()
bool getIsPresentOnHardware() const
void fixGeometry(int value)
This class uses a tableview inside a table view to achieve the frozen row effect on the 1st row this ...
void scrollTo(const QModelIndex &index, ScrollHint hint=EnsureVisible)
The SchedulerModel class Subclasses QStandardItemModel in order to reimplement the editable flags...
SpinBoxDelegate(QObject *parent=nullptr)
void setHorizontalHeaderItem(int column, QStandardItem *item)
QFrozenTableViewWithCopyPaste::setHorizontalHeaderItem Ensures that the frozen table geometry is upda...
~TelemetrySchedulerGadgetWidget()
void saveCompleted(int objectID, bool status)
bool useExpertMode() const
UAVObject * getObject(const QString &name, quint32 instId=0)
QVector< QVector< UAVDataObject * > > getDataObjectsVector()
void setEditorData(QWidget *editor, const QModelIndex &index) const
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
void presentOnHardwareChanged(UAVDataObject *)