soundeditor/qatsh/PartialsFrameTableView.cpp

271 lines
11 KiB
C++

// PartialsFrameTableView class implementation
//
// The table view for 1 frame of the partials.
//
// QATSH Copyright 2009 Jean-Philippe MEURET <jpmeuret@free.fr>
#include <iostream>
#include "ATSMath.h"
#include <QHeaderView>
#include <QItemSelection>
#include <QItemSelectionModel>
#include "ATSModelItems.h"
#include "ATSModelManager.h"
#include "ATSPartialsProxyModel.h"
#include "ATSPartialsFrameProxyModel.h"
#include "FrameAndDataProcessor.h"
#include "PartialsFrameTableView.h"
#include "ui_PartialsFrameTableView.h"
PartialsFrameTableView::PartialsFrameTableView(QWidget *parent)
: QFrame(parent), _pui(new Ui::PartialsFrameTableView), _pModelMgr(0)
{
_pui->setupUi(this);
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
_pui->qtvPartials->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
#else
_pui->qtvPartials->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
#endif
// Enable control value synchronization
_bSynchronizeControls = true;
}
PartialsFrameTableView::~PartialsFrameTableView()
{
delete _pui;
}
void PartialsFrameTableView::setModelManager(ATSModelManager* pModelMgr)
{
_pModelMgr = pModelMgr;
// Set table view model.
_pui->qtvPartials->setModel(_pModelMgr->partialsFrameModel());
connect(_pui->qtvPartials->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&,
const QItemSelection&)),
this, SLOT(onFrameSelectionChanged(const QItemSelection&, const QItemSelection&)));
connect(_pModelMgr->partialsSelectionModel(), SIGNAL(selectionChanged(const QItemSelection&,
const QItemSelection&)),
this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&)));
//std::cout << "PartialsFrameTableView::setModelManager" << std::endl;
_nMaxFrameIndex = _pModelMgr->partialsFrameModel()->nbFrames() - 1;
_dFrameDuration = _pModelMgr->partialsFrameModel()->frameDuration();
// Reset maximum value for sliders
_pui->qsdCurrentIndex->setMaximum(_nMaxFrameIndex);
// Reset maximum value for index spin-boxes
_pui->qsbCurrentIndex->setMaximum(_nMaxFrameIndex);
// Reset minimum/maximum/step value for time spin-boxes
_pui->qsbCurrentStartTime->setSingleStep(_dFrameDuration);
_pui->qsbCurrentStartTime->setMaximum(_nMaxFrameIndex*_dFrameDuration);
_pui->qsbCurrentEndTime->setSingleStep(_dFrameDuration);
_pui->qsbCurrentEndTime->setMinimum(_dFrameDuration);
_pui->qsbCurrentEndTime->setMaximum((_nMaxFrameIndex+1)*_dFrameDuration);
// Connect controls to local changed() slots for synchronisation
connect(_pui->qsdCurrentIndex, SIGNAL(valueChanged(int)),
this, SLOT(onCurrentIndexChanged(int)));
connect(_pui->qsbCurrentIndex, SIGNAL(valueChanged(int)),
this, SLOT(onCurrentIndexChanged(int)));
connect(_pui->qsbCurrentStartTime, SIGNAL(valueChanged(double)),
this, SLOT(onCurrentStartTimeChanged(double)));
connect(_pui->qsbCurrentEndTime, SIGNAL(valueChanged(double)),
this, SLOT(onCurrentEndTimeChanged(double)));
// Connect add/remove partials buttons to local slots.
connect(_pui->qpbAddPartial, SIGNAL(clicked()), this, SLOT(onAddPartial()));
connect(_pui->qpbRemovePartial, SIGNAL(clicked()), this, SLOT(onRemovePartial()));
}
void PartialsFrameTableView::setFrameAndDataProcessor(FrameAndDataProcessor* pProcessor)
{
_pProcessor = pProcessor;
}
int PartialsFrameTableView::currentFrameIndex() const
{
return _pui->qsdCurrentIndex->value();
}
void PartialsFrameTableView::onFrameSelectionChanged(const QItemSelection& qisSelected,
const QItemSelection& qisDeselected)
{
// Here, we convert input ATSPartialsFrameModel (de)selections (from table view)
// to an ATSPartialsModel selection, suitable for the partials graphics views.
std::cout << "PartialsFrameTableView::onFrameSelectionChanged" << std::endl;
// 1) Disconnect graphics views selection model change propagation to table view.
disconnect(_pModelMgr->partialsSelectionModel(), SIGNAL(selectionChanged(const QItemSelection&,
const QItemSelection&)),
this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&)));
// 2) Selection.
// Map the input ATSPartialsFrameModel selection to an ATSPartialsModel selection.
const QItemSelection qisSelParts =
_pModelMgr->partialsFrameModel()->mapSelectionToSource(qisSelected);
// Apply it to the graphics views selectionModel.
_pModelMgr->partialsSelectionModel()->select(qisSelParts, QItemSelectionModel::Select);
// 3) Deselection.
// Map the input ATSPartialsFrameModel deselection to an ATSPartialsModel deselection.
const QItemSelection qisDeselParts =
_pModelMgr->partialsFrameModel()->mapSelectionToSource(qisDeselected);
// Apply it to the graphics views selectionModel.
_pModelMgr->partialsSelectionModel()->select(qisDeselParts, QItemSelectionModel::Deselect);
// 4) Reconnect graphics views selection model change propagation to table view.
connect(_pModelMgr->partialsSelectionModel(), SIGNAL(selectionChanged(const QItemSelection&,
const QItemSelection&)),
this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&)));
}
void PartialsFrameTableView::onSelectionChanged(const QItemSelection& qisSelected,
const QItemSelection& qisDeselected)
{
// Here, we convert input ATSPartialsModel (de)selections (from graphics views)
// to an ATSPartialsFrameModel selection, suitable for the table view.
//std::cout << "PartialsFrameTableView::onSelectionChanged" << std::endl;
// 1) Disconnect table view selection model change propagation to graphics views.
disconnect(_pui->qtvPartials->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&,
const QItemSelection&)),
this, SLOT(onFrameSelectionChanged(const QItemSelection&, const QItemSelection&)));
// 2) Selection.
// Map this ATSPartialsModel selection to an output ATSPartialsFrameModel selection.
const QItemSelection qisSelPartsFrame =
_pModelMgr->partialsFrameModel()->mapSelectionFromSource(qisSelected);
// foreach (QModelIndex mi, qisSelPartsFrame.indexes())
// {
// std::cout << "PartialsFrameTableView::onSelectionChanged : selected(PartsFrame) : "
// << mi.row() << ',' << mi.column()
// << ':' << static_cast<const ATSModelItem*>(mi.internalPointer()) //->type()
// << std::endl;
// }
//std::cout << "selPartsFrame=" << qisSelPartsFrame.count() << std::endl;
// Apply it to the table view selectionModel.
_pui->qtvPartials->selectionModel()->select(qisSelPartsFrame, QItemSelectionModel::Select);
// 3) Deselection.
// Map this ATSPartialsModel deselection to an output ATSPartialsFrameModel deselection.
const QItemSelection qisDeselPartsFrame =
_pModelMgr->partialsFrameModel()->mapSelectionFromSource(qisDeselected);
//std::cout << "deselPartsFrame="<< qisDeselPartsFrame.count() << std::endl;
// Apply it from the table view selectionModel.
_pui->qtvPartials->selectionModel()->select(qisDeselPartsFrame, QItemSelectionModel::Deselect);
// 3) Reconnect table view selection model change propagation to graphics views.
connect(_pui->qtvPartials->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&,
const QItemSelection&)),
this, SLOT(onFrameSelectionChanged(const QItemSelection&, const QItemSelection&)));
}
// Slots to synchronize control values ===============================
void PartialsFrameTableView::onCurrentIndexChanged(int nNewIndex)
{
// Nothing to do if control synchronization is blocked.
if (!_bSynchronizeControls)
return;
// Synchronize attached controls.
_bSynchronizeControls = false;
_pui->qsbCurrentIndex->setValue(nNewIndex);
_pui->qsdCurrentIndex->setValue(nNewIndex);
_pui->qsbCurrentStartTime->setValue(nNewIndex*_dFrameDuration);
_pui->qsbCurrentEndTime->setValue((nNewIndex+1)*_dFrameDuration);
_bSynchronizeControls = true;
// Update model.
_pModelMgr->partialsFrameModel()->setCurrentFrame(nNewIndex);
// Notify the world in case usefull.
emit currentFrameChanged(nNewIndex);
}
void PartialsFrameTableView::onCurrentStartTimeChanged(double dNewTime)
{
// Nothing to do if control synchronization is blocked.
if (!_bSynchronizeControls)
return;
// Synchronize attached controls.
_bSynchronizeControls = false;
const int nFrameIndex = (int)round(dNewTime / _dFrameDuration);
_pui->qsbCurrentIndex->setValue(nFrameIndex);
_pui->qsdCurrentIndex->setValue(nFrameIndex);
_pui->qsbCurrentEndTime->setValue(dNewTime + _dFrameDuration);
_bSynchronizeControls = true;
// Update model.
_pModelMgr->partialsFrameModel()->setCurrentFrame(nFrameIndex);
// Notify the world in case usefull.
emit currentFrameChanged(nFrameIndex);
}
void PartialsFrameTableView::onCurrentEndTimeChanged(double dNewTime)
{
// Nothing to do if control synchronization is blocked.
if (!_bSynchronizeControls)
return;
// Synchronize attached controls.
_bSynchronizeControls = false;
const int nFrameIndex = (int)round(dNewTime / _dFrameDuration) - 1;
_pui->qsbCurrentIndex->setValue(nFrameIndex);
_pui->qsdCurrentIndex->setValue(nFrameIndex);
_pui->qsbCurrentStartTime->setValue(dNewTime - _dFrameDuration);
_bSynchronizeControls = true;
// Update model.
_pModelMgr->partialsFrameModel()->setCurrentFrame(nFrameIndex);
// Notify the world in case usefull.
emit currentFrameChanged(nFrameIndex);
}
// Slots to add/remove partials ====================================
void PartialsFrameTableView::onAddPartial()
{
// Retrieve the index of 1st selected partial if any.
const QModelIndexList qisSelParts =
_pModelMgr->partialsSelectionModel()->selection().indexes();
QModelIndex qmi1stSelPart; // Invalid for the moment
if (!qisSelParts.isEmpty())
qmi1stSelPart = qisSelParts[0];
// Add the partial as a copy (if any) of the 1st selected partial.
_pModelMgr->partialsModel()->addPartial(qmi1stSelPart);
}
void PartialsFrameTableView::onRemovePartial()
{
// Retrieve the selected partial indexes if any.
const QModelIndexList qlmiSelParts =
_pModelMgr->partialsSelectionModel()->selection().indexes();
// Remove the selected partials if any.
if (!qlmiSelParts.isEmpty())
_pModelMgr->partialsModel()->removePartials(qlmiSelParts);
}