annotate widgets/ModelDataTableDialog.cpp @ 959:2633a1d73e39

Address #1214, layer import produces wrong layer type. We needed a more principled approach to making sure the format gets updated properly and the dialog elements are consistent (basically separating making the dialog elements consistent from subsequently updating the format). This change should provide that, though there may be gotchas still.
author Chris Cannam
date Tue, 12 May 2015 12:31:37 +0100
parents 4a578a360011
children c02c51ae5238 a7df0d728020
rev   line source
Chris@392 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@392 2
Chris@392 3 /*
Chris@392 4 Sonic Visualiser
Chris@392 5 An audio file viewer and annotation editor.
Chris@392 6 Centre for Digital Music, Queen Mary, University of London.
Chris@392 7 This file copyright 2008 QMUL.
Chris@392 8
Chris@392 9 This program is free software; you can redistribute it and/or
Chris@392 10 modify it under the terms of the GNU General Public License as
Chris@392 11 published by the Free Software Foundation; either version 2 of the
Chris@392 12 License, or (at your option) any later version. See the file
Chris@392 13 COPYING included with this distribution for more information.
Chris@392 14 */
Chris@392 15
Chris@392 16 #include "ModelDataTableDialog.h"
Chris@392 17
Chris@392 18 #include "data/model/ModelDataTableModel.h"
Chris@395 19 #include "data/model/TabularModel.h"
Chris@398 20 #include "data/model/Model.h"
Chris@392 21
Chris@393 22 #include "CommandHistory.h"
Chris@399 23 #include "IconLoader.h"
Chris@393 24
Chris@392 25 #include <QTableView>
Chris@552 26 #include <QLineEdit>
Chris@392 27 #include <QGridLayout>
Chris@552 28 #include <QLabel>
Chris@392 29 #include <QGroupBox>
Chris@392 30 #include <QDialogButtonBox>
Chris@392 31 #include <QHeaderView>
Chris@392 32 #include <QApplication>
Chris@392 33 #include <QDesktopWidget>
Chris@399 34 #include <QAction>
Chris@399 35 #include <QToolBar>
Chris@392 36
Chris@393 37 #include <iostream>
Chris@393 38
Chris@404 39 ModelDataTableDialog::ModelDataTableDialog(TabularModel *model,
Chris@404 40 QString title, QWidget *parent) :
Chris@400 41 QMainWindow(parent),
Chris@401 42 m_currentRow(0),
Chris@404 43 m_trackPlayback(true)
Chris@392 44 {
Chris@392 45 setWindowTitle(tr("Data Editor"));
Chris@392 46
Chris@404 47 QToolBar *toolbar;
Chris@399 48
Chris@404 49 toolbar = addToolBar(tr("Playback Toolbar"));
Chris@404 50 m_playToolbar = toolbar;
Chris@404 51 toolbar = addToolBar(tr("Play Mode Toolbar"));
Chris@404 52
Chris@399 53 IconLoader il;
Chris@399 54
Chris@402 55 QAction *action = new QAction(il.load("playfollow"), tr("Track Playback"), this);
Chris@402 56 action->setStatusTip(tr("Toggle tracking of playback position"));
Chris@402 57 action->setCheckable(true);
Chris@404 58 action->setChecked(m_trackPlayback);
Chris@402 59 connect(action, SIGNAL(triggered()), this, SLOT(togglePlayTracking()));
Chris@402 60 toolbar->addAction(action);
Chris@402 61
Chris@404 62 toolbar = addToolBar(tr("Edit Toolbar"));
Chris@402 63
Chris@402 64 action = new QAction(il.load("datainsert"), tr("Insert New Item"), this);
Chris@399 65 action->setShortcut(tr("Insert"));
Chris@399 66 action->setStatusTip(tr("Insert a new item"));
Chris@399 67 connect(action, SIGNAL(triggered()), this, SLOT(insertRow()));
Chris@399 68 toolbar->addAction(action);
Chris@399 69
Chris@399 70 action = new QAction(il.load("datadelete"), tr("Delete Selected Items"), this);
Chris@399 71 action->setShortcut(tr("Delete"));
Chris@399 72 action->setStatusTip(tr("Delete the selected item or items"));
Chris@400 73 connect(action, SIGNAL(triggered()), this, SLOT(deleteRows()));
Chris@399 74 toolbar->addAction(action);
Chris@399 75
Chris@404 76 CommandHistory::getInstance()->registerToolbar(toolbar);
Chris@404 77
Chris@404 78 /*
Chris@399 79 action = new QAction(il.load("dataedit"), tr("Edit Selected Item"), this);
Chris@399 80 action->setShortcut(tr("Edit"));
Chris@399 81 action->setStatusTip(tr("Edit the selected item"));
Chris@399 82 connect(action, SIGNAL(triggered()), this, SLOT(editRow()));
Chris@399 83 toolbar->addAction(action);
Chris@404 84 */
Chris@399 85
Chris@396 86 QFrame *mainFrame = new QFrame;
Chris@396 87 setCentralWidget(mainFrame);
Chris@396 88
Chris@392 89 QGridLayout *grid = new QGridLayout;
Chris@396 90 mainFrame->setLayout(grid);
Chris@392 91
Chris@392 92 QGroupBox *box = new QGroupBox;
Chris@398 93 if (title != "") {
Chris@398 94 box->setTitle(title);
Chris@398 95 } else {
Chris@398 96 box->setTitle(tr("Data in Layer"));
Chris@398 97 }
Chris@392 98 grid->addWidget(box, 0, 0);
Chris@392 99 grid->setRowStretch(0, 15);
Chris@392 100
Chris@392 101 QGridLayout *subgrid = new QGridLayout;
Chris@392 102 box->setLayout(subgrid);
Chris@392 103
Chris@392 104 subgrid->setSpacing(0);
Chris@392 105 subgrid->setMargin(5);
Chris@392 106
Chris@552 107 subgrid->addWidget(new QLabel(tr("Find:")), 1, 0);
Chris@552 108 subgrid->addWidget(new QLabel(tr(" ")), 1, 1);
Chris@552 109 m_find = new QLineEdit;
Chris@552 110 subgrid->addWidget(m_find, 1, 2);
Chris@552 111 connect(m_find, SIGNAL(textChanged(const QString &)),
Chris@552 112 this, SLOT(searchTextChanged(const QString &)));
Chris@552 113 connect(m_find, SIGNAL(returnPressed()),
Chris@552 114 this, SLOT(searchRepeated()));
Chris@552 115
Chris@392 116 m_tableView = new QTableView;
Chris@552 117 subgrid->addWidget(m_tableView, 0, 0, 1, 3);
Chris@392 118
Chris@395 119 m_tableView->setSortingEnabled(true);
Chris@396 120 m_tableView->sortByColumn(0, Qt::AscendingOrder);
Chris@392 121
Chris@392 122 m_table = new ModelDataTableModel(model);
Chris@392 123 m_tableView->setModel(m_table);
Chris@392 124
Chris@552 125 m_tableView->horizontalHeader()->setStretchLastSection(true);
Chris@552 126
Chris@393 127 connect(m_tableView, SIGNAL(clicked(const QModelIndex &)),
Chris@393 128 this, SLOT(viewClicked(const QModelIndex &)));
Chris@393 129 connect(m_tableView, SIGNAL(pressed(const QModelIndex &)),
Chris@393 130 this, SLOT(viewPressed(const QModelIndex &)));
Chris@400 131 connect(m_tableView->selectionModel(),
Chris@400 132 SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
Chris@400 133 this,
Chris@400 134 SLOT(currentChanged(const QModelIndex &, const QModelIndex &)));
Chris@400 135 connect(m_table, SIGNAL(addCommand(Command *)),
Chris@400 136 this, SLOT(addCommand(Command *)));
Chris@401 137 connect(m_table, SIGNAL(currentChanged(const QModelIndex &)),
Chris@401 138 this, SLOT(currentChangedThroughResort(const QModelIndex &)));
Chris@428 139 connect(m_table, SIGNAL(modelRemoved()),
Chris@428 140 this, SLOT(modelRemoved()));
Chris@393 141
Chris@392 142 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Close);
Chris@396 143 connect(bb, SIGNAL(rejected()), this, SLOT(close()));
Chris@392 144 grid->addWidget(bb, 2, 0);
Chris@392 145 grid->setRowStretch(2, 0);
Chris@392 146
Chris@392 147 QDesktopWidget *desktop = QApplication::desktop();
Chris@392 148 QRect available = desktop->availableGeometry();
Chris@392 149
Chris@392 150 int width = available.width() / 3;
Chris@392 151 int height = available.height() / 2;
Chris@392 152 if (height < 370) {
Chris@392 153 if (available.height() > 500) height = 370;
Chris@392 154 }
Chris@552 155 if (width < 650) {
Chris@552 156 if (available.width() > 750) width = 650;
Chris@552 157 else if (width < 500) {
Chris@552 158 if (available.width() > 650) width = 500;
Chris@552 159 }
Chris@392 160 }
Chris@392 161
Chris@392 162 resize(width, height);
Chris@392 163 }
Chris@392 164
Chris@392 165 ModelDataTableDialog::~ModelDataTableDialog()
Chris@392 166 {
Chris@392 167 delete m_table;
Chris@392 168 }
Chris@392 169
Chris@393 170 void
Chris@908 171 ModelDataTableDialog::userScrolledToFrame(sv_frame_t frame)
Chris@393 172 {
Chris@401 173 QModelIndex index = m_table->getModelIndexForFrame(frame);
Chris@401 174 makeCurrent(index.row());
Chris@401 175 }
Chris@401 176
Chris@401 177 void
Chris@908 178 ModelDataTableDialog::playbackScrolledToFrame(sv_frame_t frame)
Chris@401 179 {
Chris@401 180 if (m_trackPlayback) {
Chris@401 181 QModelIndex index = m_table->getModelIndexForFrame(frame);
Chris@401 182 makeCurrent(index.row());
Chris@401 183 }
Chris@401 184 }
Chris@401 185
Chris@401 186 void
Chris@552 187 ModelDataTableDialog::searchTextChanged(const QString &text)
Chris@552 188 {
Chris@552 189 QModelIndex mi = m_table->findText(text);
Chris@552 190 if (mi.isValid()) {
Chris@552 191 makeCurrent(mi.row());
Chris@552 192 m_tableView->selectionModel()->setCurrentIndex
Chris@552 193 (mi, QItemSelectionModel::ClearAndSelect);
Chris@552 194 }
Chris@552 195 }
Chris@552 196
Chris@552 197 void
Chris@552 198 ModelDataTableDialog::searchRepeated()
Chris@552 199 {
Chris@552 200 QModelIndex mi = m_table->findText(m_find->text());
Chris@552 201 if (mi.isValid()) {
Chris@552 202 makeCurrent(mi.row());
Chris@552 203 m_tableView->selectionModel()->setCurrentIndex
Chris@552 204 (mi, QItemSelectionModel::ClearAndSelect);
Chris@552 205 }
Chris@552 206 }
Chris@552 207
Chris@552 208 void
Chris@401 209 ModelDataTableDialog::makeCurrent(int row)
Chris@401 210 {
Chris@401 211 int rh = m_tableView->height() / m_tableView->rowHeight(0);
Chris@404 212 int topRow = row - rh/4;
Chris@401 213 if (topRow < 0) topRow = 0;
Chris@404 214
Chris@404 215 // should only scroll if the desired row is not currently visible
Chris@404 216
Chris@404 217 // should only select if no part of the desired row is currently selected
Chris@404 218
Chris@682 219 // cerr << "rh = " << rh << ", row = " << row << ", scrolling to "
Chris@682 220 // << topRow << endl;
Chris@404 221
Chris@404 222 int pos = m_tableView->rowViewportPosition(row);
Chris@404 223
Chris@404 224 if (pos < 0 || pos >= m_tableView->height() - rh) {
Chris@404 225 m_tableView->scrollTo(m_table->index(topRow, 0));
Chris@404 226 }
Chris@404 227
Chris@404 228 bool haveRowSelected = false;
Chris@404 229 for (int i = 0; i < m_table->columnCount(); ++i) {
Chris@404 230 if (m_tableView->selectionModel()->isSelected(m_table->index(row, i))) {
Chris@404 231 haveRowSelected = true;
Chris@404 232 break;
Chris@404 233 }
Chris@404 234 }
Chris@404 235
Chris@404 236 if (!haveRowSelected) {
Chris@404 237 m_tableView->selectionModel()->setCurrentIndex
Chris@404 238 (m_table->index(row, 0),
Chris@404 239 QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
Chris@404 240 }
Chris@393 241 }
Chris@393 242
Chris@393 243 void
Chris@393 244 ModelDataTableDialog::viewClicked(const QModelIndex &index)
Chris@393 245 {
Chris@587 246 // SVDEBUG << "ModelDataTableDialog::viewClicked: " << index.row() << ", " << index.column() << endl;
Chris@394 247 emit scrollToFrame(m_table->getFrameForModelIndex(index));
Chris@393 248 }
Chris@393 249
Chris@393 250 void
Chris@807 251 ModelDataTableDialog::viewPressed(const QModelIndex &)
Chris@393 252 {
Chris@587 253 // SVDEBUG << "ModelDataTableDialog::viewPressed: " << index.row() << ", " << index.column() << endl;
Chris@393 254 }
Chris@393 255
Chris@393 256 void
Chris@400 257 ModelDataTableDialog::currentChanged(const QModelIndex &current,
Chris@807 258 const QModelIndex &)
Chris@399 259 {
Chris@587 260 // SVDEBUG << "ModelDataTableDialog::currentChanged: from "
Chris@409 261 // << previous.row() << ", " << previous.column()
Chris@409 262 // << " to " << current.row() << ", " << current.column()
Chris@585 263 // << endl;
Chris@400 264 m_currentRow = current.row();
Chris@401 265 m_table->setCurrentRow(m_currentRow);
Chris@399 266 }
Chris@399 267
Chris@399 268 void
Chris@400 269 ModelDataTableDialog::insertRow()
Chris@399 270 {
Chris@400 271 m_table->insertRow(m_currentRow);
Chris@400 272 }
Chris@400 273
Chris@400 274 void
Chris@400 275 ModelDataTableDialog::deleteRows()
Chris@400 276 {
Chris@400 277 // not efficient
Chris@400 278 while (m_tableView->selectionModel()->hasSelection()) {
Chris@400 279 m_table->removeRow
Chris@400 280 (m_tableView->selectionModel()->selection().indexes().begin()->row());
Chris@400 281 }
Chris@399 282 }
Chris@399 283
Chris@399 284 void
Chris@399 285 ModelDataTableDialog::editRow()
Chris@399 286 {
Chris@399 287 }
Chris@399 288
Chris@399 289 void
Chris@400 290 ModelDataTableDialog::addCommand(Command *command)
Chris@393 291 {
Chris@397 292 CommandHistory::getInstance()->addCommand(command, false, true);
Chris@393 293 }
Chris@393 294
Chris@401 295 void
Chris@402 296 ModelDataTableDialog::togglePlayTracking()
Chris@402 297 {
Chris@402 298 m_trackPlayback = !m_trackPlayback;
Chris@402 299 }
Chris@402 300
Chris@402 301 void
Chris@401 302 ModelDataTableDialog::currentChangedThroughResort(const QModelIndex &index)
Chris@401 303 {
Chris@587 304 // SVDEBUG << "ModelDataTableDialog::currentChangedThroughResort: row = " << index.row() << endl;
Chris@401 305 // m_tableView->scrollTo(index);
Chris@401 306 makeCurrent(index.row());
Chris@401 307 }
Chris@401 308
Chris@428 309 void
Chris@428 310 ModelDataTableDialog::modelRemoved()
Chris@428 311 {
Chris@428 312 close();
Chris@428 313 }
Chris@401 314
Chris@401 315