Mercurial > hg > svcore
diff data/model/ModelDataTableModel.cpp @ 416:a00902d5f0ab
* basics of data editing in data table view
author | Chris Cannam |
---|---|
date | Mon, 09 Jun 2008 16:01:50 +0000 |
parents | 0b274e1aaf10 |
children | 12b7bf0c3915 |
line wrap: on
line diff
--- a/data/model/ModelDataTableModel.cpp Mon Jun 09 16:01:22 2008 +0000 +++ b/data/model/ModelDataTableModel.cpp Mon Jun 09 16:01:50 2008 +0000 @@ -35,10 +35,12 @@ QVariant ModelDataTableModel::data(const QModelIndex &index, int role) const { - if (role != Qt::DisplayRole) { + if (role != Qt::DisplayRole && role != Qt::EditRole) { return QVariant(); } + bool withUnit = (role == Qt::DisplayRole); + if (!index.isValid()) return QVariant(); int row = index.row(), col = index.column(); @@ -46,9 +48,9 @@ if (row < 0 || row >= m_rows.size()) return QVariant(); if (dynamic_cast<const SparseOneDimensionalModel *>(m_model)) { - return dataSparse<SparseOneDimensionalModel::Point>(row, col); + return dataSparse<SparseOneDimensionalModel::Point>(row, col, withUnit); } else if (dynamic_cast<const SparseTimeValueModel *>(m_model)) { - return dataSparse<SparseTimeValueModel::Point>(row, col); + return dataSparse<SparseTimeValueModel::Point>(row, col, withUnit); } return QVariant(); @@ -56,7 +58,7 @@ template <typename PointType> QVariant -ModelDataTableModel::dataSparse(int row, int col) const +ModelDataTableModel::dataSparse(int row, int col, bool withUnit) const { size_t frame = m_rows[row]; @@ -89,10 +91,17 @@ switch (col) { case 0: + { + RealTime rt = RealTime::frame2RealTime(frame, m_model->getSampleRate()); + std::cerr << "Returning time " << rt << std::endl; + return QVariant(rt.toText().c_str()); + } + + case 1: std::cerr << "Returning frame " << frame << std::endl; return QVariant(frame); //!!! RealTime - case 1: + case 2: if (dynamic_cast<const SparseOneDimensionalModel *>(m_model)) { const SparseOneDimensionalModel::Point *cp = reinterpret_cast<const SparseOneDimensionalModel::Point *>(point); @@ -102,10 +111,15 @@ const SparseTimeValueModel::Point *cp = reinterpret_cast<const SparseTimeValueModel::Point *>(point); std::cerr << "Returning value " << cp->value << std::endl; - return cp->value; + if (withUnit) { + return QVariant(QString("%1 %2").arg(cp->value) + .arg(dynamic_cast<const SparseTimeValueModel *>(m_model)->getScaleUnits())); + } else { + return cp->value; + } } else return QVariant(); - case 2: + case 3: if (dynamic_cast<const SparseOneDimensionalModel *>(m_model)) { return QVariant(); } else if (dynamic_cast<const SparseTimeValueModel *>(m_model)) { @@ -120,27 +134,115 @@ bool ModelDataTableModel::setData(const QModelIndex &index, const QVariant &value, int role) { + if (role != Qt::EditRole) { + std::cerr << "setData: ignoring role " << role << std::endl; + return false; + } + + //!!! see comment about disgustuality of this whole process, in + //dataSparse above + + if (!index.isValid()) return false; + + int row = index.row(), col = index.column(); + + if (row < 0 || row >= m_rows.size()) return false; + + if (dynamic_cast<const SparseOneDimensionalModel *>(m_model)) { + return setDataSparse<SparseOneDimensionalModel::Point>(row, col, value); + } else if (dynamic_cast<const SparseTimeValueModel *>(m_model)) { + return setDataSparse<SparseTimeValueModel::Point>(row, col, value); + } + + return false; +} + +template <typename PointType> +bool +ModelDataTableModel::setDataSparse(int row, int col, QVariant value) +{ + size_t frame = m_rows[row]; + + typedef SparseModel<PointType> ModelType; + typedef std::multiset<PointType, typename PointType::OrderComparator> + PointListType; + typedef typename ModelType::EditCommand EditCommandType; + + ModelType *sm = dynamic_cast<const ModelType *>(m_model); + const PointListType &points = sm->getPoints(frame); + + // it is possible to have more than one point at the same frame + + int indexAtFrame = 0; + int ri = row; + while (ri > 0 && m_rows[ri-1] == m_rows[row]) { --ri; ++indexAtFrame; } + + for (typename PointListType::const_iterator i = points.begin(); + i != points.end(); ++i) { + + const PointType *point = &(*i); + if (point->frame < frame) continue; + if (point->frame > frame) return false; + if (indexAtFrame > 0) { --indexAtFrame; continue; } + + switch (col) { + + case 0: + { +/* + RealTime rt = RealTime::frame2RealTime(frame, m_model->getSampleRate()); + std::cerr << "Returning time " << rt << std::endl; + return QVariant(rt.toText().c_str()); +*/ + } + + case 1: + { + EditCommandType *command = + new EditCommandType(sm, tr("Edit point time")); + PointType newPoint(*point); + newPoint.frame = value.toInt(); //!!! check validity + command->deletePoint(*point); + command->addPoint(newPoint); + command = command->finish(); + if (command) emit executeCommand(command); + return true; + } +// std::cerr << "Returning frame " << frame << std::endl; +// return QVariant(frame); //!!! RealTime + + case 2: + break; + + case 3: + break; + } + } + return false; } Qt::ItemFlags ModelDataTableModel::flags(const QModelIndex &index) const { - return Qt::ItemFlags(); + Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsEditable | + Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsSelectable; + return flags; } QVariant ModelDataTableModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { - if (section == 0) return QVariant(tr("Frame")); - else if (section == 1) { + if (section == 0) return QVariant(tr("Time")); + if (section == 1) return QVariant(tr("Frame")); + else if (section == 2) { if (dynamic_cast<const SparseOneDimensionalModel *>(m_model)) { return QVariant(tr("Label")); } else if (dynamic_cast<const SparseTimeValueModel *>(m_model)) { return QVariant(tr("Value")); } - } else if (section == 2) { + } else if (section == 3) { if (dynamic_cast<const SparseTimeValueModel *>(m_model)) { return QVariant(tr("Label")); } @@ -175,12 +277,21 @@ if (!canHandleModelType(m_model)) return 0; if (dynamic_cast<SparseOneDimensionalModel *>(m_model)) { - return 2; + return 3; } else if (dynamic_cast<SparseTimeValueModel *>(m_model)) { - return 3; + return 4; } - return 1; + return 2; +} + +QModelIndex +ModelDataTableModel::getModelIndexForFrame(size_t frame) const +{ + std::vector<size_t>::const_iterator i = + std::lower_bound(m_rows.begin(), m_rows.end(), frame); + size_t dist = std::distance(m_rows.begin(), i); + return createIndex(dist, 0, 0); } void @@ -191,8 +302,13 @@ } void -ModelDataTableModel::modelChanged(size_t, size_t) -{} +ModelDataTableModel::modelChanged(size_t f0, size_t f1) +{ + std::cerr << "ModelDataTableModel::modelChanged(" << f0 << "," << f1 << ")" << std::endl; + //!!! highly inefficient + rebuildRowVector(); + emit layoutChanged(); +} void ModelDataTableModel::rebuildRowVector()