annotate data/model/ModelDataTableModel.cpp @ 426:2386582f67cd

* build fix
author Chris Cannam
date Mon, 16 Jun 2008 07:55:35 +0000
parents f5e8f12d2e58
children 72ec275e458b
rev   line source
Chris@413 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@413 2
Chris@413 3 /*
Chris@413 4 Sonic Visualiser
Chris@413 5 An audio file viewer and annotation editor.
Chris@413 6 Centre for Digital Music, Queen Mary, University of London.
Chris@413 7 This file copyright 2008 QMUL.
Chris@413 8
Chris@413 9 This program is free software; you can redistribute it and/or
Chris@413 10 modify it under the terms of the GNU General Public License as
Chris@413 11 published by the Free Software Foundation; either version 2 of the
Chris@413 12 License, or (at your option) any later version. See the file
Chris@413 13 COPYING included with this distribution for more information.
Chris@413 14 */
Chris@413 15
Chris@413 16 #include "ModelDataTableModel.h"
Chris@413 17
Chris@420 18 #include "TabularModel.h"
Chris@420 19 #include "Model.h"
Chris@413 20
Chris@422 21 #include <map>
Chris@417 22 #include <algorithm>
Chris@420 23 #include <iostream>
Chris@417 24
Chris@420 25 ModelDataTableModel::ModelDataTableModel(TabularModel *m) :
Chris@421 26 m_model(m),
Chris@421 27 m_sortColumn(0),
Chris@421 28 m_sortOrdering(Qt::AscendingOrder)
Chris@413 29 {
Chris@420 30 Model *baseModel = dynamic_cast<Model *>(m);
Chris@420 31
Chris@420 32 connect(baseModel, SIGNAL(modelChanged()), this, SLOT(modelChanged()));
Chris@420 33 connect(baseModel, SIGNAL(modelChanged(size_t, size_t)),
Chris@413 34 this, SLOT(modelChanged(size_t, size_t)));
Chris@413 35 }
Chris@413 36
Chris@413 37 ModelDataTableModel::~ModelDataTableModel()
Chris@413 38 {
Chris@413 39 }
Chris@413 40
Chris@413 41 QVariant
Chris@413 42 ModelDataTableModel::data(const QModelIndex &index, int role) const
Chris@413 43 {
Chris@424 44 if (role != Qt::EditRole && role != Qt::DisplayRole) return QVariant();
Chris@413 45 if (!index.isValid()) return QVariant();
Chris@420 46 return m_model->getData(getUnsorted(index.row()), index.column(), role);
Chris@413 47 }
Chris@413 48
Chris@413 49 bool
Chris@413 50 ModelDataTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
Chris@413 51 {
Chris@420 52 if (!index.isValid()) return false;
Chris@421 53 std::cerr << "ModelDataTableModel::setData(" << index.row() << ", " << index.column() << ", " << value.toString().toStdString() << ", " << role << ")" << std::endl;
Chris@421 54 Command *command = m_model->getSetDataCommand(getUnsorted(index.row()),
Chris@421 55 index.column(),
Chris@421 56 value, role);
Chris@420 57 if (command) {
Chris@421 58 std::cerr << "emitting executeCommand" << std::endl;
Chris@420 59 emit executeCommand(command);
Chris@420 60 return true;
Chris@420 61 } else {
Chris@416 62 return false;
Chris@416 63 }
Chris@413 64 }
Chris@413 65
Chris@413 66 Qt::ItemFlags
Chris@413 67 ModelDataTableModel::flags(const QModelIndex &index) const
Chris@413 68 {
Chris@416 69 Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsEditable |
Chris@416 70 Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsSelectable;
Chris@416 71 return flags;
Chris@413 72 }
Chris@413 73
Chris@413 74 QVariant
Chris@413 75 ModelDataTableModel::headerData(int section, Qt::Orientation orientation, int role) const
Chris@413 76 {
Chris@425 77 if (orientation == Qt::Vertical && role == Qt::DisplayRole) {
Chris@425 78 return section + 1;
Chris@425 79 }
Chris@413 80 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
Chris@420 81 return m_model->getHeading(section);
Chris@425 82 }
Chris@413 83 return QVariant();
Chris@413 84 }
Chris@413 85
Chris@413 86 QModelIndex
Chris@413 87 ModelDataTableModel::index(int row, int column, const QModelIndex &parent) const
Chris@413 88 {
Chris@413 89 return createIndex(row, column, 0);
Chris@413 90 }
Chris@413 91
Chris@413 92 QModelIndex
Chris@413 93 ModelDataTableModel::parent(const QModelIndex &index) const
Chris@413 94 {
Chris@413 95 return QModelIndex();
Chris@413 96 }
Chris@413 97
Chris@413 98 int
Chris@413 99 ModelDataTableModel::rowCount(const QModelIndex &parent) const
Chris@413 100 {
Chris@413 101 if (parent.isValid()) return 0;
Chris@420 102 return m_model->getRowCount();
Chris@413 103 }
Chris@413 104
Chris@413 105 int
Chris@413 106 ModelDataTableModel::columnCount(const QModelIndex &parent) const
Chris@413 107 {
Chris@413 108 if (parent.isValid()) return 0;
Chris@420 109 return m_model->getColumnCount();
Chris@416 110 }
Chris@416 111
Chris@416 112 QModelIndex
Chris@416 113 ModelDataTableModel::getModelIndexForFrame(size_t frame) const
Chris@416 114 {
Chris@420 115 int row = m_model->getRowForFrame(frame);
Chris@420 116 return createIndex(getSorted(row), 0, 0);
Chris@413 117 }
Chris@413 118
Chris@419 119 size_t
Chris@419 120 ModelDataTableModel::getFrameForModelIndex(const QModelIndex &index) const
Chris@419 121 {
Chris@420 122 return m_model->getFrameForRow(getUnsorted(index.row()));
Chris@420 123 }
Chris@420 124
Chris@420 125 void
Chris@420 126 ModelDataTableModel::sort(int column, Qt::SortOrder sortOrder)
Chris@420 127 {
Chris@420 128 std::cerr << "ModelDataTableModel::sort(" << column << ", " << sortOrder
Chris@420 129 << ")" << std::endl;
Chris@422 130 if (m_sortColumn != column) {
Chris@422 131 m_sort.clear();
Chris@422 132 }
Chris@420 133 m_sortColumn = column;
Chris@420 134 m_sortOrdering = sortOrder;
Chris@420 135 emit layoutChanged();
Chris@419 136 }
Chris@419 137
Chris@413 138 void
Chris@413 139 ModelDataTableModel::modelChanged()
Chris@413 140 {
Chris@420 141 m_sort.clear();
Chris@413 142 emit layoutChanged();
Chris@413 143 }
Chris@413 144
Chris@413 145 void
Chris@416 146 ModelDataTableModel::modelChanged(size_t f0, size_t f1)
Chris@416 147 {
Chris@420 148 //!!! inefficient
Chris@420 149 m_sort.clear();
Chris@416 150 emit layoutChanged();
Chris@416 151 }
Chris@413 152
Chris@420 153 int
Chris@426 154 ModelDataTableModel::getSorted(int row) const
Chris@413 155 {
Chris@420 156 if (m_model->isColumnTimeValue(m_sortColumn)) {
Chris@420 157 if (m_sortOrdering == Qt::AscendingOrder) {
Chris@420 158 return row;
Chris@420 159 } else {
Chris@420 160 return rowCount() - row - 1;
Chris@420 161 }
Chris@420 162 }
Chris@413 163
Chris@420 164 if (m_sort.empty()) {
Chris@420 165 resort();
Chris@413 166 }
Chris@422 167 int result = 0;
Chris@422 168 if (row >= 0 && row < m_sort.size()) {
Chris@422 169 result = m_sort[row];
Chris@422 170 }
Chris@422 171 if (m_sortOrdering == Qt::DescendingOrder) {
Chris@422 172 result = rowCount() - result - 1;
Chris@422 173 }
Chris@422 174
Chris@422 175 return result;
Chris@413 176 }
Chris@413 177
Chris@420 178 int
Chris@426 179 ModelDataTableModel::getUnsorted(int row) const
Chris@413 180 {
Chris@420 181 if (m_model->isColumnTimeValue(m_sortColumn)) {
Chris@420 182 if (m_sortOrdering == Qt::AscendingOrder) {
Chris@420 183 return row;
Chris@420 184 } else {
Chris@420 185 return rowCount() - row - 1;
Chris@420 186 }
Chris@413 187 }
Chris@422 188
Chris@420 189 if (m_sort.empty()) {
Chris@420 190 resort();
Chris@420 191 }
Chris@422 192
Chris@422 193 int result = 0;
Chris@422 194 if (row >= 0 && row < m_sort.size()) {
Chris@422 195 if (m_sortOrdering == Qt::AscendingOrder) {
Chris@422 196 result = m_rsort[row];
Chris@422 197 } else {
Chris@422 198 result = m_rsort[rowCount() - row - 1];
Chris@422 199 }
Chris@422 200 }
Chris@422 201
Chris@422 202 return result;
Chris@413 203 }
Chris@413 204
Chris@420 205 void
Chris@426 206 ModelDataTableModel::resort() const
Chris@413 207 {
Chris@422 208 bool numeric = (m_model->getSortType(m_sortColumn) ==
Chris@422 209 TabularModel::SortNumeric);
Chris@422 210
Chris@422 211 m_sort.clear();
Chris@422 212 m_rsort.clear();
Chris@422 213
Chris@422 214 if (numeric) resortNumeric();
Chris@422 215 else resortAlphabetical();
Chris@422 216
Chris@422 217 std::map<int, int> tmp;
Chris@422 218
Chris@422 219 // rsort maps from sorted row number to original row number
Chris@422 220
Chris@422 221 for (int i = 0; i < m_rsort.size(); ++i) {
Chris@422 222 tmp[m_rsort[i]] = i;
Chris@422 223 }
Chris@422 224
Chris@422 225 // tmp now maps from original row number to sorted row number
Chris@422 226
Chris@422 227 for (std::map<int, int>::const_iterator i = tmp.begin(); i != tmp.end(); ++i) {
Chris@422 228 m_sort.push_back(i->second);
Chris@422 229 }
Chris@422 230
Chris@422 231 // and sort now maps from original row number to sorted row number
Chris@413 232 }
Chris@413 233
Chris@422 234 void
Chris@426 235 ModelDataTableModel::resortNumeric() const
Chris@422 236 {
Chris@422 237 typedef std::multimap<double, int> MapType;
Chris@422 238
Chris@422 239 MapType rowMap;
Chris@422 240 int rows = m_model->getRowCount();
Chris@422 241
Chris@422 242 for (int i = 0; i < rows; ++i) {
Chris@424 243 QVariant value = m_model->getData(i, m_sortColumn, TabularModel::SortRole);
Chris@422 244 rowMap.insert(MapType::value_type(value.toDouble(), i));
Chris@422 245 }
Chris@422 246
Chris@422 247 for (MapType::iterator i = rowMap.begin(); i != rowMap.end(); ++i) {
Chris@422 248 m_rsort.push_back(i->second);
Chris@422 249 }
Chris@422 250
Chris@422 251 // rsort now maps from sorted row number to original row number
Chris@422 252 }
Chris@422 253
Chris@422 254 void
Chris@426 255 ModelDataTableModel::resortAlphabetical() const
Chris@422 256 {
Chris@422 257 typedef std::multimap<QString, int> MapType;
Chris@422 258
Chris@422 259 MapType rowMap;
Chris@422 260 int rows = m_model->getRowCount();
Chris@422 261
Chris@422 262 for (int i = 0; i < rows; ++i) {
Chris@422 263 QVariant value =
Chris@422 264 m_model->getData(i, m_sortColumn, TabularModel::SortRole);
Chris@422 265 rowMap.insert(MapType::value_type(value.toString(), i));
Chris@422 266 }
Chris@422 267
Chris@422 268 for (MapType::iterator i = rowMap.begin(); i != rowMap.end(); ++i) {
Chris@422 269 m_rsort.push_back(i->second);
Chris@422 270 }
Chris@422 271
Chris@422 272 // rsort now maps from sorted row number to original row number
Chris@422 273 }
Chris@422 274