annotate widgets/ModelDataTableDialog.cpp @ 1351:9fb7133dd818

Scale positioning
author Chris Cannam
date Wed, 03 Oct 2018 12:59:55 +0100
parents 0ded54e94332
children d39db4673676
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@1175 64 action = new QAction(il.load("draw"), 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@1271 211 if (m_table->rowCount() == 0 ||
Chris@1271 212 row >= m_table->rowCount() ||
Chris@1271 213 row < 0) {
Chris@1271 214 return;
Chris@1271 215 }
Chris@1271 216
Chris@401 217 int rh = m_tableView->height() / m_tableView->rowHeight(0);
Chris@404 218 int topRow = row - rh/4;
Chris@401 219 if (topRow < 0) topRow = 0;
Chris@404 220
Chris@404 221 // should only scroll if the desired row is not currently visible
Chris@404 222
Chris@404 223 // should only select if no part of the desired row is currently selected
Chris@404 224
Chris@682 225 // cerr << "rh = " << rh << ", row = " << row << ", scrolling to "
Chris@682 226 // << topRow << endl;
Chris@404 227
Chris@404 228 int pos = m_tableView->rowViewportPosition(row);
Chris@404 229
Chris@404 230 if (pos < 0 || pos >= m_tableView->height() - rh) {
Chris@404 231 m_tableView->scrollTo(m_table->index(topRow, 0));
Chris@404 232 }
Chris@404 233
Chris@404 234 bool haveRowSelected = false;
Chris@404 235 for (int i = 0; i < m_table->columnCount(); ++i) {
Chris@404 236 if (m_tableView->selectionModel()->isSelected(m_table->index(row, i))) {
Chris@404 237 haveRowSelected = true;
Chris@404 238 break;
Chris@404 239 }
Chris@404 240 }
Chris@404 241
Chris@404 242 if (!haveRowSelected) {
Chris@404 243 m_tableView->selectionModel()->setCurrentIndex
Chris@404 244 (m_table->index(row, 0),
Chris@404 245 QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
Chris@404 246 }
Chris@393 247 }
Chris@393 248
Chris@393 249 void
Chris@393 250 ModelDataTableDialog::viewClicked(const QModelIndex &index)
Chris@393 251 {
Chris@587 252 // SVDEBUG << "ModelDataTableDialog::viewClicked: " << index.row() << ", " << index.column() << endl;
Chris@394 253 emit scrollToFrame(m_table->getFrameForModelIndex(index));
Chris@393 254 }
Chris@393 255
Chris@393 256 void
Chris@807 257 ModelDataTableDialog::viewPressed(const QModelIndex &)
Chris@393 258 {
Chris@587 259 // SVDEBUG << "ModelDataTableDialog::viewPressed: " << index.row() << ", " << index.column() << endl;
Chris@393 260 }
Chris@393 261
Chris@393 262 void
Chris@400 263 ModelDataTableDialog::currentChanged(const QModelIndex &current,
Chris@1272 264 const QModelIndex &previous)
Chris@399 265 {
Chris@1272 266 SVDEBUG << "ModelDataTableDialog::currentChanged: from "
Chris@1272 267 << previous.row() << ", " << previous.column()
Chris@1272 268 << " to " << current.row() << ", " << current.column()
Chris@1272 269 << endl;
Chris@400 270 m_currentRow = current.row();
Chris@401 271 m_table->setCurrentRow(m_currentRow);
Chris@399 272 }
Chris@399 273
Chris@399 274 void
Chris@400 275 ModelDataTableDialog::insertRow()
Chris@399 276 {
Chris@400 277 m_table->insertRow(m_currentRow);
Chris@400 278 }
Chris@400 279
Chris@400 280 void
Chris@400 281 ModelDataTableDialog::deleteRows()
Chris@400 282 {
Chris@1272 283 std::set<int> selectedRows;
Chris@1272 284 if (m_tableView->selectionModel()->hasSelection()) {
Chris@1272 285 for (const auto &ix: m_tableView->selectionModel()->selectedIndexes()) {
Chris@1272 286 selectedRows.insert(ix.row());
Chris@1272 287 }
Chris@1272 288 }
Chris@1272 289 // Remove rows in reverse order, so as not to pull the rug from
Chris@1272 290 // under our own feet
Chris@1272 291 for (auto ri = selectedRows.rbegin(); ri != selectedRows.rend(); ++ri) {
Chris@1272 292 SVDEBUG << "ModelDataTableDialog: removing row " << *ri << endl;
Chris@1272 293 m_table->removeRow(*ri);
Chris@400 294 }
Chris@399 295 }
Chris@399 296
Chris@399 297 void
Chris@399 298 ModelDataTableDialog::editRow()
Chris@399 299 {
Chris@399 300 }
Chris@399 301
Chris@399 302 void
Chris@400 303 ModelDataTableDialog::addCommand(Command *command)
Chris@393 304 {
Chris@397 305 CommandHistory::getInstance()->addCommand(command, false, true);
Chris@393 306 }
Chris@393 307
Chris@401 308 void
Chris@402 309 ModelDataTableDialog::togglePlayTracking()
Chris@402 310 {
Chris@402 311 m_trackPlayback = !m_trackPlayback;
Chris@402 312 }
Chris@402 313
Chris@402 314 void
Chris@401 315 ModelDataTableDialog::currentChangedThroughResort(const QModelIndex &index)
Chris@401 316 {
Chris@587 317 // SVDEBUG << "ModelDataTableDialog::currentChangedThroughResort: row = " << index.row() << endl;
Chris@401 318 // m_tableView->scrollTo(index);
Chris@401 319 makeCurrent(index.row());
Chris@401 320 }
Chris@401 321
Chris@428 322 void
Chris@428 323 ModelDataTableDialog::modelRemoved()
Chris@428 324 {
Chris@428 325 close();
Chris@428 326 }
Chris@401 327
Chris@401 328