# HG changeset patch # User Chris Cannam # Date 1213261380 0 # Node ID 4caa28a0a8a233658dbc11f9c11ef3db64c69bd8 # Parent 397fe91dc8e0186e926e1e01ba943edc3b34aaa5 * sorting arbitrary columns in data editor diff -r 397fe91dc8e0 -r 4caa28a0a8a2 data/model/ModelDataTableModel.cpp --- a/data/model/ModelDataTableModel.cpp Wed Jun 11 17:00:04 2008 +0000 +++ b/data/model/ModelDataTableModel.cpp Thu Jun 12 09:03:00 2008 +0000 @@ -18,6 +18,7 @@ #include "TabularModel.h" #include "Model.h" +#include #include #include @@ -122,9 +123,11 @@ { std::cerr << "ModelDataTableModel::sort(" << column << ", " << sortOrder << ")" << std::endl; + if (m_sortColumn != column) { + m_sort.clear(); + } m_sortColumn = column; m_sortOrdering = sortOrder; - m_sort.clear(); emit layoutChanged(); } @@ -157,8 +160,15 @@ if (m_sort.empty()) { resort(); } - if (row < 0 || row >= m_sort.size()) return 0; - return m_sort[row]; + int result = 0; + if (row >= 0 && row < m_sort.size()) { + result = m_sort[row]; + } + if (m_sortOrdering == Qt::DescendingOrder) { + result = rowCount() - result - 1; + } + + return result; } int @@ -171,17 +181,91 @@ return rowCount() - row - 1; } } -//!!! need the reverse of this + if (m_sort.empty()) { resort(); } - if (row < 0 || row >= m_sort.size()) return 0; - return m_sort[row]; + + int result = 0; + if (row >= 0 && row < m_sort.size()) { + if (m_sortOrdering == Qt::AscendingOrder) { + result = m_rsort[row]; + } else { + result = m_rsort[rowCount() - row - 1]; + } + } + + return result; } void ModelDataTableModel::resort() { - + bool numeric = (m_model->getSortType(m_sortColumn) == + TabularModel::SortNumeric); + + m_sort.clear(); + m_rsort.clear(); + + if (numeric) resortNumeric(); + else resortAlphabetical(); + + std::map tmp; + + // rsort maps from sorted row number to original row number + + for (int i = 0; i < m_rsort.size(); ++i) { + tmp[m_rsort[i]] = i; + } + + // tmp now maps from original row number to sorted row number + + for (std::map::const_iterator i = tmp.begin(); i != tmp.end(); ++i) { + m_sort.push_back(i->second); + } + + // and sort now maps from original row number to sorted row number } +void +ModelDataTableModel::resortNumeric() +{ + typedef std::multimap MapType; + + MapType rowMap; + int rows = m_model->getRowCount(); + + for (int i = 0; i < rows; ++i) { + QVariant value = + m_model->getData(i, m_sortColumn, TabularModel::SortRole); + rowMap.insert(MapType::value_type(value.toDouble(), i)); + } + + for (MapType::iterator i = rowMap.begin(); i != rowMap.end(); ++i) { + m_rsort.push_back(i->second); + } + + // rsort now maps from sorted row number to original row number +} + +void +ModelDataTableModel::resortAlphabetical() +{ + typedef std::multimap MapType; + + MapType rowMap; + int rows = m_model->getRowCount(); + + for (int i = 0; i < rows; ++i) { + QVariant value = + m_model->getData(i, m_sortColumn, TabularModel::SortRole); + rowMap.insert(MapType::value_type(value.toString(), i)); + } + + for (MapType::iterator i = rowMap.begin(); i != rowMap.end(); ++i) { + m_rsort.push_back(i->second); + } + + // rsort now maps from sorted row number to original row number +} + diff -r 397fe91dc8e0 -r 4caa28a0a8a2 data/model/ModelDataTableModel.h --- a/data/model/ModelDataTableModel.h Wed Jun 11 17:00:04 2008 +0000 +++ b/data/model/ModelDataTableModel.h Thu Jun 12 09:03:00 2008 +0000 @@ -67,9 +67,12 @@ Qt::SortOrder m_sortOrdering; typedef std::vector RowList; RowList m_sort; + RowList m_rsort; int getSorted(int row); int getUnsorted(int row); void resort(); + void resortNumeric(); + void resortAlphabetical(); }; #endif diff -r 397fe91dc8e0 -r 4caa28a0a8a2 data/model/SparseModel.h --- a/data/model/SparseModel.h Wed Jun 11 17:00:04 2008 +0000 +++ b/data/model/SparseModel.h Thu Jun 12 09:03:00 2008 +0000 @@ -293,6 +293,7 @@ return QVariant(); } virtual bool isColumnTimeValue(int column) const { return true; } + virtual SortType getSortType(int column) const { return SortNumeric; } protected: size_t m_sampleRate; diff -r 397fe91dc8e0 -r 4caa28a0a8a2 data/model/SparseOneDimensionalModel.h --- a/data/model/SparseOneDimensionalModel.h Wed Jun 11 17:00:04 2008 +0000 +++ b/data/model/SparseOneDimensionalModel.h Thu Jun 12 09:03:00 2008 +0000 @@ -130,17 +130,20 @@ virtual QVariant getData(int row, int column, int role) const { - if (role != Qt::EditRole && role != Qt::DisplayRole) return QVariant(); + if (role != Qt::EditRole && + role != Qt::DisplayRole && + role != SortRole) return QVariant(); PointListIterator i = getPointListIteratorForRow(row); if (i == m_points.end()) return QVariant(); switch (column) { case 0: { + if (role == SortRole) return int(i->frame); RealTime rt = RealTime::frame2RealTime(i->frame, getSampleRate()); return QVariant(rt.toText().c_str()); } - case 1: return QVariant(int(i->frame)); - case 2: return QVariant(i->label); + case 1: return int(i->frame); + case 2: return i->label; default: return QVariant(); } } @@ -149,6 +152,12 @@ { return (column < 2); } + + virtual SortType getSortType(int column) const + { + if (column == 2) return SortAlphabetical; + return SortNumeric; + } }; #endif diff -r 397fe91dc8e0 -r 4caa28a0a8a2 data/model/SparseTimeValueModel.h --- a/data/model/SparseTimeValueModel.h Wed Jun 11 17:00:04 2008 +0000 +++ b/data/model/SparseTimeValueModel.h Thu Jun 12 09:03:00 2008 +0000 @@ -120,18 +120,21 @@ virtual QVariant getData(int row, int column, int role) const { - if (role != Qt::EditRole && role != Qt::DisplayRole) return QVariant(); + if (role != Qt::EditRole && + role != Qt::DisplayRole && + role != SortRole) return QVariant(); PointListIterator i = getPointListIteratorForRow(row); if (i == m_points.end()) return QVariant(); switch (column) { case 0: { + if (role == SortRole) return int(i->frame); RealTime rt = RealTime::frame2RealTime(i->frame, getSampleRate()); return rt.toText().c_str(); } case 1: return int(i->frame); case 2: - if (role == Qt::EditRole) return i->value; + if (role == Qt::EditRole || role == SortRole) return i->value; else return QString("%1 %2").arg(i->value).arg(getScaleUnits()); case 3: return i->label; default: return QVariant(); @@ -170,6 +173,12 @@ { return (column < 2); } + + virtual SortType getSortType(int column) const + { + if (column == 3) return SortAlphabetical; + return SortNumeric; + } }; diff -r 397fe91dc8e0 -r 4caa28a0a8a2 data/model/TabularModel.h --- a/data/model/TabularModel.h Wed Jun 11 17:00:04 2008 +0000 +++ b/data/model/TabularModel.h Thu Jun 12 09:03:00 2008 +0000 @@ -38,13 +38,17 @@ virtual int getColumnCount() const = 0; virtual QString getHeading(int column) const = 0; + + enum { SortRole = Qt::UserRole }; + enum SortType { SortNumeric, SortAlphabetical }; + virtual QVariant getData(int row, int column, int role) const = 0; + virtual bool isColumnTimeValue(int col) const = 0; + virtual SortType getSortType(int col) const = 0; virtual long getFrameForRow(int row) const = 0; virtual int getRowForFrame(long frame) const = 0; - virtual bool isColumnTimeValue(int col) const = 0; - virtual bool isEditable() const { return false; } virtual Command *getSetDataCommand(int row, int column, const QVariant &, int role) const { return 0; } };