Chris@392: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@392: Chris@392: /* Chris@392: Sonic Visualiser Chris@392: An audio file viewer and annotation editor. Chris@392: Centre for Digital Music, Queen Mary, University of London. Chris@392: This file copyright 2008 QMUL. Chris@392: Chris@392: This program is free software; you can redistribute it and/or Chris@392: modify it under the terms of the GNU General Public License as Chris@392: published by the Free Software Foundation; either version 2 of the Chris@392: License, or (at your option) any later version. See the file Chris@392: COPYING included with this distribution for more information. Chris@392: */ Chris@392: Chris@392: #include "ModelDataTableDialog.h" Chris@392: Chris@392: #include "data/model/ModelDataTableModel.h" Chris@395: #include "data/model/TabularModel.h" Chris@398: #include "data/model/Model.h" Chris@392: Chris@393: #include "CommandHistory.h" Chris@399: #include "IconLoader.h" Chris@393: Chris@392: #include Chris@552: #include Chris@392: #include Chris@552: #include Chris@392: #include Chris@392: #include Chris@392: #include Chris@392: #include Chris@392: #include Chris@399: #include Chris@399: #include Chris@392: Chris@393: #include Chris@393: Chris@404: ModelDataTableDialog::ModelDataTableDialog(TabularModel *model, Chris@404: QString title, QWidget *parent) : Chris@400: QMainWindow(parent), Chris@401: m_currentRow(0), Chris@404: m_trackPlayback(true) Chris@392: { Chris@392: setWindowTitle(tr("Data Editor")); Chris@392: Chris@404: QToolBar *toolbar; Chris@399: Chris@404: toolbar = addToolBar(tr("Playback Toolbar")); Chris@404: m_playToolbar = toolbar; Chris@404: toolbar = addToolBar(tr("Play Mode Toolbar")); Chris@404: Chris@399: IconLoader il; Chris@399: Chris@402: QAction *action = new QAction(il.load("playfollow"), tr("Track Playback"), this); Chris@402: action->setStatusTip(tr("Toggle tracking of playback position")); Chris@402: action->setCheckable(true); Chris@404: action->setChecked(m_trackPlayback); Chris@402: connect(action, SIGNAL(triggered()), this, SLOT(togglePlayTracking())); Chris@402: toolbar->addAction(action); Chris@402: Chris@404: toolbar = addToolBar(tr("Edit Toolbar")); Chris@402: Chris@402: action = new QAction(il.load("datainsert"), tr("Insert New Item"), this); Chris@399: action->setShortcut(tr("Insert")); Chris@399: action->setStatusTip(tr("Insert a new item")); Chris@399: connect(action, SIGNAL(triggered()), this, SLOT(insertRow())); Chris@399: toolbar->addAction(action); Chris@399: Chris@399: action = new QAction(il.load("datadelete"), tr("Delete Selected Items"), this); Chris@399: action->setShortcut(tr("Delete")); Chris@399: action->setStatusTip(tr("Delete the selected item or items")); Chris@400: connect(action, SIGNAL(triggered()), this, SLOT(deleteRows())); Chris@399: toolbar->addAction(action); Chris@399: Chris@404: CommandHistory::getInstance()->registerToolbar(toolbar); Chris@404: Chris@404: /* Chris@399: action = new QAction(il.load("dataedit"), tr("Edit Selected Item"), this); Chris@399: action->setShortcut(tr("Edit")); Chris@399: action->setStatusTip(tr("Edit the selected item")); Chris@399: connect(action, SIGNAL(triggered()), this, SLOT(editRow())); Chris@399: toolbar->addAction(action); Chris@404: */ Chris@399: Chris@396: QFrame *mainFrame = new QFrame; Chris@396: setCentralWidget(mainFrame); Chris@396: Chris@392: QGridLayout *grid = new QGridLayout; Chris@396: mainFrame->setLayout(grid); Chris@392: Chris@392: QGroupBox *box = new QGroupBox; Chris@398: if (title != "") { Chris@398: box->setTitle(title); Chris@398: } else { Chris@398: box->setTitle(tr("Data in Layer")); Chris@398: } Chris@392: grid->addWidget(box, 0, 0); Chris@392: grid->setRowStretch(0, 15); Chris@392: Chris@392: QGridLayout *subgrid = new QGridLayout; Chris@392: box->setLayout(subgrid); Chris@392: Chris@392: subgrid->setSpacing(0); Chris@392: subgrid->setMargin(5); Chris@392: Chris@552: subgrid->addWidget(new QLabel(tr("Find:")), 1, 0); Chris@552: subgrid->addWidget(new QLabel(tr(" ")), 1, 1); Chris@552: m_find = new QLineEdit; Chris@552: subgrid->addWidget(m_find, 1, 2); Chris@552: connect(m_find, SIGNAL(textChanged(const QString &)), Chris@552: this, SLOT(searchTextChanged(const QString &))); Chris@552: connect(m_find, SIGNAL(returnPressed()), Chris@552: this, SLOT(searchRepeated())); Chris@552: Chris@392: m_tableView = new QTableView; Chris@552: subgrid->addWidget(m_tableView, 0, 0, 1, 3); Chris@392: Chris@395: m_tableView->setSortingEnabled(true); Chris@396: m_tableView->sortByColumn(0, Qt::AscendingOrder); Chris@392: Chris@392: m_table = new ModelDataTableModel(model); Chris@392: m_tableView->setModel(m_table); Chris@392: Chris@552: m_tableView->horizontalHeader()->setStretchLastSection(true); Chris@552: Chris@393: connect(m_tableView, SIGNAL(clicked(const QModelIndex &)), Chris@393: this, SLOT(viewClicked(const QModelIndex &))); Chris@393: connect(m_tableView, SIGNAL(pressed(const QModelIndex &)), Chris@393: this, SLOT(viewPressed(const QModelIndex &))); Chris@400: connect(m_tableView->selectionModel(), Chris@400: SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), Chris@400: this, Chris@400: SLOT(currentChanged(const QModelIndex &, const QModelIndex &))); Chris@400: connect(m_table, SIGNAL(addCommand(Command *)), Chris@400: this, SLOT(addCommand(Command *))); Chris@401: connect(m_table, SIGNAL(currentChanged(const QModelIndex &)), Chris@401: this, SLOT(currentChangedThroughResort(const QModelIndex &))); Chris@428: connect(m_table, SIGNAL(modelRemoved()), Chris@428: this, SLOT(modelRemoved())); Chris@393: Chris@392: QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Close); Chris@396: connect(bb, SIGNAL(rejected()), this, SLOT(close())); Chris@392: grid->addWidget(bb, 2, 0); Chris@392: grid->setRowStretch(2, 0); Chris@392: Chris@392: QDesktopWidget *desktop = QApplication::desktop(); Chris@392: QRect available = desktop->availableGeometry(); Chris@392: Chris@392: int width = available.width() / 3; Chris@392: int height = available.height() / 2; Chris@392: if (height < 370) { Chris@392: if (available.height() > 500) height = 370; Chris@392: } Chris@552: if (width < 650) { Chris@552: if (available.width() > 750) width = 650; Chris@552: else if (width < 500) { Chris@552: if (available.width() > 650) width = 500; Chris@552: } Chris@392: } Chris@392: Chris@392: resize(width, height); Chris@392: } Chris@392: Chris@392: ModelDataTableDialog::~ModelDataTableDialog() Chris@392: { Chris@392: delete m_table; Chris@392: } Chris@392: Chris@393: void Chris@807: ModelDataTableDialog::userScrolledToFrame(int frame) Chris@393: { Chris@401: QModelIndex index = m_table->getModelIndexForFrame(frame); Chris@401: makeCurrent(index.row()); Chris@401: } Chris@401: Chris@401: void Chris@807: ModelDataTableDialog::playbackScrolledToFrame(int frame) Chris@401: { Chris@401: if (m_trackPlayback) { Chris@401: QModelIndex index = m_table->getModelIndexForFrame(frame); Chris@401: makeCurrent(index.row()); Chris@401: } Chris@401: } Chris@401: Chris@401: void Chris@552: ModelDataTableDialog::searchTextChanged(const QString &text) Chris@552: { Chris@552: QModelIndex mi = m_table->findText(text); Chris@552: if (mi.isValid()) { Chris@552: makeCurrent(mi.row()); Chris@552: m_tableView->selectionModel()->setCurrentIndex Chris@552: (mi, QItemSelectionModel::ClearAndSelect); Chris@552: } Chris@552: } Chris@552: Chris@552: void Chris@552: ModelDataTableDialog::searchRepeated() Chris@552: { Chris@552: QModelIndex mi = m_table->findText(m_find->text()); Chris@552: if (mi.isValid()) { Chris@552: makeCurrent(mi.row()); Chris@552: m_tableView->selectionModel()->setCurrentIndex Chris@552: (mi, QItemSelectionModel::ClearAndSelect); Chris@552: } Chris@552: } Chris@552: Chris@552: void Chris@401: ModelDataTableDialog::makeCurrent(int row) Chris@401: { Chris@401: int rh = m_tableView->height() / m_tableView->rowHeight(0); Chris@404: int topRow = row - rh/4; Chris@401: if (topRow < 0) topRow = 0; Chris@404: Chris@404: // should only scroll if the desired row is not currently visible Chris@404: Chris@404: // should only select if no part of the desired row is currently selected Chris@404: Chris@682: // cerr << "rh = " << rh << ", row = " << row << ", scrolling to " Chris@682: // << topRow << endl; Chris@404: Chris@404: int pos = m_tableView->rowViewportPosition(row); Chris@404: Chris@404: if (pos < 0 || pos >= m_tableView->height() - rh) { Chris@404: m_tableView->scrollTo(m_table->index(topRow, 0)); Chris@404: } Chris@404: Chris@404: bool haveRowSelected = false; Chris@404: for (int i = 0; i < m_table->columnCount(); ++i) { Chris@404: if (m_tableView->selectionModel()->isSelected(m_table->index(row, i))) { Chris@404: haveRowSelected = true; Chris@404: break; Chris@404: } Chris@404: } Chris@404: Chris@404: if (!haveRowSelected) { Chris@404: m_tableView->selectionModel()->setCurrentIndex Chris@404: (m_table->index(row, 0), Chris@404: QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); Chris@404: } Chris@393: } Chris@393: Chris@393: void Chris@393: ModelDataTableDialog::viewClicked(const QModelIndex &index) Chris@393: { Chris@587: // SVDEBUG << "ModelDataTableDialog::viewClicked: " << index.row() << ", " << index.column() << endl; Chris@394: emit scrollToFrame(m_table->getFrameForModelIndex(index)); Chris@393: } Chris@393: Chris@393: void Chris@807: ModelDataTableDialog::viewPressed(const QModelIndex &) Chris@393: { Chris@587: // SVDEBUG << "ModelDataTableDialog::viewPressed: " << index.row() << ", " << index.column() << endl; Chris@393: } Chris@393: Chris@393: void Chris@400: ModelDataTableDialog::currentChanged(const QModelIndex ¤t, Chris@807: const QModelIndex &) Chris@399: { Chris@587: // SVDEBUG << "ModelDataTableDialog::currentChanged: from " Chris@409: // << previous.row() << ", " << previous.column() Chris@409: // << " to " << current.row() << ", " << current.column() Chris@585: // << endl; Chris@400: m_currentRow = current.row(); Chris@401: m_table->setCurrentRow(m_currentRow); Chris@399: } Chris@399: Chris@399: void Chris@400: ModelDataTableDialog::insertRow() Chris@399: { Chris@400: m_table->insertRow(m_currentRow); Chris@400: } Chris@400: Chris@400: void Chris@400: ModelDataTableDialog::deleteRows() Chris@400: { Chris@400: // not efficient Chris@400: while (m_tableView->selectionModel()->hasSelection()) { Chris@400: m_table->removeRow Chris@400: (m_tableView->selectionModel()->selection().indexes().begin()->row()); Chris@400: } Chris@399: } Chris@399: Chris@399: void Chris@399: ModelDataTableDialog::editRow() Chris@399: { Chris@399: } Chris@399: Chris@399: void Chris@400: ModelDataTableDialog::addCommand(Command *command) Chris@393: { Chris@397: CommandHistory::getInstance()->addCommand(command, false, true); Chris@393: } Chris@393: Chris@401: void Chris@402: ModelDataTableDialog::togglePlayTracking() Chris@402: { Chris@402: m_trackPlayback = !m_trackPlayback; Chris@402: } Chris@402: Chris@402: void Chris@401: ModelDataTableDialog::currentChangedThroughResort(const QModelIndex &index) Chris@401: { Chris@587: // SVDEBUG << "ModelDataTableDialog::currentChangedThroughResort: row = " << index.row() << endl; Chris@401: // m_tableView->scrollTo(index); Chris@401: makeCurrent(index.row()); Chris@401: } Chris@401: Chris@428: void Chris@428: ModelDataTableDialog::modelRemoved() Chris@428: { Chris@428: close(); Chris@428: } Chris@401: Chris@401: