// ************************************************************************** // // (C) Copyright 2009 Swiss SIMTEC AG // // ************************************************************************** // // $HeadURL$ // $LastChangedBy$ // $LastChangedDate$ // $LastChangedRevision$ // // ************************************************************************** // manual class headers #include "LogViewTableWidget.hpp" #include "LogViewField.hpp" #include #include #include "LogViewXdrStandardType.hpp" #include "LogViewTelegram.hpp" #include "LogViewEnumEdit.hpp" namespace N_LogView { // --------------------------------------------------------------- LogViewTableWidget::LogViewTableWidget(LogViewField* a_field, QWidget* a_parent, const bool a_readonly) : QTableWidget(0, 2, a_parent) , LogViewWidget(a_field, this, a_parent, a_readonly) , m_IsFloat(false) , m_IsEnum(false) { switch (m_Field->xdrElement()->getKind()) { case LogViewXdrElement::e_KindEnum: m_IsEnum = true; break; default: m_IsFloat = LogViewXdrStandardType::e_Float == static_cast(m_Field->xdrElement())->getValueKind(); } if (!m_IsFloat) setColumnCount(3); if (m_IsEnum) setColumnCount(1); setHorizontalHeaderItem(0, new QTableWidgetItem(m_IsEnum ? tr("Enum") : tr("Dez"))); if (!m_IsEnum) { setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Hex"))); if (!m_IsFloat) { setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Bin"))); } } setAlternatingRowColors(true); // make pretty // horizontalHeader()->setResizeMode(2, QHeaderView::Stretch); updateToolTip(); // for debugging only // INFO_LOG(m_logger) << "type=" << static_cast(a_field->getXdrElement())->getValueKind(); // INFO_LOG(m_logger) << "name=" << static_cast(a_field->getXdrElement())->getName().toStdString(); // a_field->getXdrElement()->dump(); // fill in the values // fixme: implementiere den Fall isHasContent() false int nbrOfRows = a_field->valueListSize(); setRowCount(nbrOfRows); for (int i = 0; i < nbrOfRows; i++) changeRow(i, a_field->value(i)); makePretty(); // connect signals connect(this, &LogViewTableWidget::itemChanged, this, &LogViewTableWidget::checkAndOvertakeContent); } // --------------------------------------------------------------- void LogViewTableWidget::changeSize(const int a_newSize) { setRowCount(a_newSize); disconnect(this, &LogViewTableWidget::itemChanged, this, &LogViewTableWidget::checkAndOvertakeContent); // check and set the new fields for (int i = 0; i < a_newSize; i++) changeRow(i, QLatin1String("0")); connect(this, &LogViewTableWidget::itemChanged, this, &LogViewTableWidget::checkAndOvertakeContent); makePretty(); m_Valid = true; } // --------------------------------------------------------------- void LogViewTableWidget::changeRow(const int a_rowIndex, const QString& a_value) { // INFO_LOG(m_logger) << "a_rowIndex=" << a_rowIndex << " a_value=" << a_value.toStdString(); if (m_IsEnum) { // enum QWidget* enumItem = cellWidget(a_rowIndex, 0); if (!enumItem) setCellWidget(a_rowIndex, 0, new LogViewEnumEdit(m_Field, this, m_Readonly, a_rowIndex)); } else { QFont font; font.setStyleHint(QFont::TypeWriter); font.setFamily(QString()); // decimal QTableWidgetItem* decItem = item(a_rowIndex, 0); if (!decItem) { decItem = new QTableWidgetItem(); //decItem->setData(Qt::DisplayRole, 0); decItem->setText(a_value); decItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); if (!m_Readonly) { decItem->setFlags(decItem->flags() | Qt::ItemIsEditable); } decItem->setFont(font); decItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); setItem(a_rowIndex, 0, decItem); } // hexadecimal QTableWidgetItem* hexItem = item(a_rowIndex, 1); if (!hexItem) { hexItem = new QTableWidgetItem(); hexItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); hexItem->setFont(font); hexItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); setItem(a_rowIndex, 1, hexItem); } // binary if (!m_IsFloat) { QTableWidgetItem* binItem = item(a_rowIndex, 2); if (!binItem) { binItem = new QTableWidgetItem(); binItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); binItem->setFont(font); binItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); setItem(a_rowIndex, 2, binItem); } } // set the values checkAndOvertakeContent(decItem); makePretty(); } } // --------------------------------------------------------------- void LogViewTableWidget::checkAndOvertakeContent(QTableWidgetItem* a_changedItem) { if (a_changedItem->column() != 0) return; int row = a_changedItem->row(); QString text = a_changedItem->text(); bool ok; int64_t intValue = 0; double floatValue = 0.0; // get the calculated and checked value if (m_IsFloat) floatValue = getFloat(text, (uint64_t&)intValue, ok, true); else intValue = getInteger(text, ok); // handle errors if (!ok) { setFocus(); // selectAll(); setCurrentCell(row, 0); // todo: funktioniert nicht return; } // set the decimal value QTableWidgetItem* decField = item(row, 0); if (decField) decField->setText(QString::number(m_IsFloat ? floatValue : intValue)); // set the hex value QTableWidgetItem* hexField = item(row, 1); if (hexField) hexField->setText(toHex(intValue)); // set the binary value if (!m_IsFloat) { QTableWidgetItem* binField = item(row, 2); if (binField) binField->setText(toBin(intValue)); } } // --------------------------------------------------------------- void LogViewTableWidget::makePretty() { //horizontalHeader()->setResizeMode(2, QHeaderView::Stretch); resizeColumnsToContents(); resizeRowsToContents(); // set the height of table-widget //// QWidget* cellWdg = tableWidget->cellWidget(0, 0); // int showRows = 7; // if (m_Field->getValueListSize() < (showRows-1)) // { // showRows = m_Field->getValueListSize()+1; // setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // } // else // { // setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); // } // setFixedHeight(showRows*tableWidget->rowHeight(0)); } // --------------------------------------------------------------- // Writes the content into telegram. // Returns true if successful. // --------------------------------------------------------------- bool LogViewTableWidget::saveContent(LogViewTelegram* a_telegram) { if (!isValid()) return false; if (a_telegram->isJsonTelegram()) { if (m_Field->kind() == LogViewField::e_FieldKindPodArray) { QJsonArray arr; for (int i = 0; i < rowCount(); ++i) arr += item(i, 0)->text().toInt(); a_telegram->setJsonValue(m_Field->jsonPath(), arr); } else { QString value; value.reserve(rowCount() * 2); for (int i = 0; i < rowCount(); ++i) { int val = item(i, 0)->text().toInt(); value += QStringLiteral("%1").arg(val, 2, 16, QLatin1Char('0')); } a_telegram->setJsonValue(m_Field->jsonPath(), value); } return true; } uint16_t arraySize; if (m_Field->isDynamicArray()) { arraySize = rowCount(); a_telegram->setUIntX(LogViewTelegram::SIZE_CENTRAL_DYN_ARRAY_SIZE, arraySize); // fixme: bei vielen Telegrammen muss Länge auf die Länge des Textes gesetzt werden. Dies kann nicht automatisch gemacht werden. Aber vielleicht kann man schauen, ob vor dem dyn. Array ein Feld Länge vorkommt, oder hartcodieren, oder konfigurierbaren } else { // todo: teste mit opaque[] arraySize = m_Field->maxArraySize(); } // copy the data INFO_LOG(m_logger) << "arraySize=" << arraySize; for (int i = 0; i < arraySize; i++) { if (m_IsEnum) { LogViewEnumEdit *enumEdit = dynamic_cast(cellWidget(i,0)); enumEdit->saveContent(a_telegram); } else { uint16_t size = getSize(); QString text = item(i, 0)->text(); if (!m_IsFloat) { a_telegram->setUIntX(size, text.toULong()); } else { const LogViewXdrStandardType *stdType = static_cast(m_Field->xdrElement()); LogViewXdrStandardType::E_ByteOrder byteOrder = stdType->getByteOrder(); uint64_t hex; getFloat(text, hex, m_Valid); a_telegram->setUIntX(size, hex, byteOrder); } } } return true; } } // namespace N_LogView