2013-03-03 22:24:41 +01:00
|
|
|
// ATSPartialsFrameProxyModel class definition
|
|
|
|
//
|
|
|
|
// ATS proxy model for the partials data associated to 1 given frame
|
|
|
|
// (Row = Partial index, Column = property id)
|
|
|
|
//
|
|
|
|
// QATSH Copyright 2009 Jean-Philippe MEURET <jpmeuret@free.fr>
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
2013-04-20 18:33:09 +02:00
|
|
|
#include <QItemSelection>
|
2013-03-03 22:24:41 +01:00
|
|
|
|
|
|
|
#include "ATSModelItems.h"
|
|
|
|
#include "ATSPartialsProxyModel.h"
|
|
|
|
#include "ATSPartialsFrameProxyModel.h"
|
|
|
|
|
|
|
|
|
|
|
|
// Constructors / Destructor ===============================================
|
|
|
|
ATSPartialsFrameProxyModel::ATSPartialsFrameProxyModel(QObject *parent)
|
|
|
|
: ATSFrameProxyModel(parent)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ATSPartialsFrameProxyModel::~ATSPartialsFrameProxyModel()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get number of partials ==================================================
|
|
|
|
int ATSPartialsFrameProxyModel::nbPartials() const
|
|
|
|
{
|
|
|
|
return static_cast<ATSPartialsProxyModel*>(sourceModel())->nbPartials();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Proxy <-> Main model index conversions ==================================
|
|
|
|
QModelIndex ATSPartialsFrameProxyModel::mapFromSource(const QModelIndex& miSource) const
|
|
|
|
{
|
|
|
|
// Is this really ever called ?
|
|
|
|
if (miSource.isValid())
|
|
|
|
{
|
|
|
|
const ATSModelItem *pmiSourceItem =
|
|
|
|
static_cast<const ATSModelItem*>(miSource.internalPointer());
|
|
|
|
if (pmiSourceItem && pmiSourceItem->type() == ATSPartialItem::ePartial)
|
|
|
|
{
|
|
|
|
const ATSPartialItem *pmiPartItem =
|
|
|
|
static_cast<const ATSPartialItem*>(pmiSourceItem);
|
|
|
|
// Here, we select the first column=property ... what else anyway ?
|
|
|
|
return createIndex(pmiPartItem->partialIndex(), 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return QModelIndex();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Implementation for source model = partials model
|
|
|
|
QModelIndex ATSPartialsFrameProxyModel::mapToSource(const QModelIndex& miProxy) const
|
|
|
|
{
|
|
|
|
if (miProxy.isValid())
|
|
|
|
{
|
|
|
|
// std::cout << "ATSPartialsFrameProxyModel::mapToSource : currFrameIdx = "
|
|
|
|
// << _nCurrFrameIndex << ", miProxy = "
|
|
|
|
// << miProxy.row() << ',' << miProxy.column()
|
|
|
|
// << ':' << (miProxy.internalPointer() ? static_cast<const ATSModelItem*>(miProxy.internalPointer())->type() : -1)
|
|
|
|
// << std::endl;
|
|
|
|
const ATSPartialsProxyModel* pSourceModel =
|
|
|
|
static_cast<const ATSPartialsProxyModel*>(sourceModel());
|
|
|
|
QModelIndex miSource =
|
|
|
|
pSourceModel->index(_nCurrFrameIndex, miProxy.column(),
|
|
|
|
pSourceModel->index(0, miProxy.row(), QModelIndex()));
|
|
|
|
// std::cout << "ATSPartialsFrameProxyModel::mapToSource : miSource = "
|
|
|
|
// << miSource.row() << ',' << miSource.column()
|
|
|
|
// << ':' << (miSource.internalPointer() ? static_cast<const ATSModelItem*>(miSource.internalPointer())->type() : -1)
|
|
|
|
// << std::endl;
|
|
|
|
return pSourceModel->index(_nCurrFrameIndex, miProxy.column(),
|
|
|
|
pSourceModel->index(0, miProxy.row(), QModelIndex()));
|
|
|
|
}
|
|
|
|
|
|
|
|
return QModelIndex();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Proxy <-> Main model selection conversions ==============================
|
|
|
|
QItemSelection ATSPartialsFrameProxyModel::mapSelectionFromSource(const QItemSelection& isSource) const
|
|
|
|
{
|
|
|
|
// Specialized implementation, as we only consider whole partial selection here
|
|
|
|
// (i.e. We consider all partial properties selected as soon as the partial is selected).
|
|
|
|
// Question: Shouldn't this trick moved to the model manager ?
|
|
|
|
QItemSelection isProxy;
|
|
|
|
foreach (QModelIndex miSource, isSource.indexes())
|
|
|
|
{
|
|
|
|
const ATSModelItem *pmiSourceItem =
|
|
|
|
static_cast<const ATSModelItem*>(miSource.internalPointer());
|
|
|
|
if (pmiSourceItem && pmiSourceItem->type() == ATSPartialItem::ePartial)
|
|
|
|
{
|
|
|
|
const ATSPartialItem *pmiPartItem =
|
|
|
|
static_cast<const ATSPartialItem*>(pmiSourceItem);
|
|
|
|
const QModelIndex miProxyFirst = createIndex(pmiPartItem->partialIndex(), 0);
|
|
|
|
const QModelIndex miProxyLast = createIndex(pmiPartItem->partialIndex(), pmiPartItem->nbProperties() - 1);
|
|
|
|
isProxy.select(miProxyFirst, miProxyLast);
|
|
|
|
// std::cout << "ATSPartialsFrameProxyModel::mapSelectionToSource : miSource :"
|
|
|
|
// << miSource.row() << ',' << miSource.column()
|
|
|
|
// << ':' << static_cast<const ATSModelItem*>(miSource.internalPointer())->type()
|
|
|
|
// << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return isProxy;
|
|
|
|
}
|
|
|
|
|
|
|
|
QItemSelection ATSPartialsFrameProxyModel::mapSelectionToSource(const QItemSelection& isProxy) const
|
|
|
|
{
|
|
|
|
// Specialized implementation, as we only consider whole partial selection here
|
|
|
|
// (i.e. We consider a partial is selected as soon as 1 property for 1 frame of it is).
|
|
|
|
// Question: Shouldn't this trick moved to the model manager ?
|
|
|
|
const ATSPartialsProxyModel* pSourceModel = static_cast<ATSPartialsProxyModel*>(sourceModel());
|
|
|
|
|
|
|
|
QItemSelection isSource;
|
|
|
|
foreach (QModelIndex miProxy, isProxy.indexes())
|
|
|
|
{
|
|
|
|
const QModelIndex miSource = pSourceModel->index(0, miProxy.row(), QModelIndex());
|
|
|
|
if (!isSource.contains(miSource))
|
|
|
|
isSource.select(miSource, miSource);
|
|
|
|
// std::cout << "ATSPartialsFrameProxyModel::mapSelectionToSource : miSource :"
|
|
|
|
// << miSource.row() << ',' << miSource.column()
|
|
|
|
// << ':' << static_cast<const ATSModelItem*>(miSource.internalPointer())->type()
|
|
|
|
// << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
return isSource;
|
|
|
|
}
|
|
|
|
|
|
|
|
// QAbstractItemModel implementation =======================================
|
|
|
|
QModelIndex ATSPartialsFrameProxyModel::index(int row, int column, const QModelIndex &miParent) const
|
|
|
|
{
|
|
|
|
if (!miParent.isValid()) // Only the root item is supported.
|
|
|
|
{
|
|
|
|
return createIndex(row, column); // And (row, column) is sufficient as an identifier.
|
|
|
|
}
|
|
|
|
|
|
|
|
return QModelIndex();
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant ATSPartialsFrameProxyModel::data(const QModelIndex &miIndex, int role) const
|
|
|
|
{
|
|
|
|
// Note: Here, we specialize standard QAbstractModelItem::data(...) implementation
|
|
|
|
// only to be able to format each column in a different and customized way.
|
|
|
|
QVariant qvValue;
|
|
|
|
|
|
|
|
// Get data to display and format it smartly but differently for each column
|
|
|
|
if (role == Qt::DisplayRole)
|
|
|
|
{
|
|
|
|
const double dValue = sourceModel()->data(mapToSource(miIndex), role).toDouble();
|
|
|
|
|
|
|
|
switch ((ATSPartialItem::EPropertyId)miIndex.column())
|
|
|
|
{
|
|
|
|
case ATSPartialItem::ePropFrequency:
|
|
|
|
qvValue = QString::number(dValue, 'f', 2);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ATSPartialItem::ePropAmplitude:
|
|
|
|
qvValue = QString::number(dValue, 'f', 6);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ATSPartialItem::ePropPhase:
|
|
|
|
qvValue = QString::number(dValue, 'f', 3);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ATSPartialItem::ePropSMR:
|
|
|
|
qvValue = QString::number(dValue, 'f', 1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
// As columnCount() returns ePropNumber - 1, should never happen.
|
|
|
|
case ATSPartialItem::ePropTime:
|
|
|
|
break;
|
|
|
|
|
|
|
|
// N/A.
|
|
|
|
case ATSPartialItem::ePropNumber:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Always align right (we only have numerical values).
|
|
|
|
else if (role == Qt::TextAlignmentRole)
|
|
|
|
qvValue = Qt::AlignRight;
|
|
|
|
|
|
|
|
return qvValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ATSPartialsFrameProxyModel::columnCount(const QModelIndex &miParent) const
|
|
|
|
{
|
|
|
|
int nCount = 0;
|
|
|
|
|
|
|
|
if (!miParent.isValid()) // Only the root item is supported.
|
|
|
|
{
|
|
|
|
nCount = ATSPartialItem::nbProperties() - 1; // We don't display the "time" column.
|
|
|
|
}
|
|
|
|
|
|
|
|
// std::cout << "ATSPartialsFrameProxyModel::columnCount("
|
|
|
|
// << miParent.row() << ',' << miParent.column()
|
|
|
|
// << ':' << miParent.internalPointer() << ") = " << nCount << std::endl;
|
|
|
|
|
|
|
|
return nCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ATSPartialsFrameProxyModel::rowCount(const QModelIndex &miParent) const
|
|
|
|
{
|
|
|
|
int nCount = 0;
|
|
|
|
|
|
|
|
if (!miParent.isValid()) // Only the root item is supported.
|
|
|
|
{
|
|
|
|
nCount = nbPartials();
|
|
|
|
}
|
|
|
|
|
|
|
|
// std::cout << "ATSPartialsFrameProxyModel::rowCount("
|
|
|
|
// << miParent.row() << ',' << miParent.column()
|
|
|
|
// << ':' << miParent.internalPointer() << ") = " << nCount << std::endl;
|
|
|
|
|
|
|
|
return nCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant ATSPartialsFrameProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
|
|
{
|
|
|
|
switch (orientation)
|
|
|
|
{
|
|
|
|
case Qt::Horizontal:
|
|
|
|
if (role == Qt::DisplayRole)
|
|
|
|
return ATSPartialItem::propertyName((ATSPartialItem::EPropertyId)section);
|
|
|
|
else if (role == Qt::ToolTipRole)
|
|
|
|
return ATSPartialItem::propertyToolTip((ATSPartialItem::EPropertyId)section);
|
|
|
|
case Qt::Vertical:
|
|
|
|
if (role == Qt::DisplayRole)
|
|
|
|
return section+1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return QVariant();
|
|
|
|
}
|
|
|
|
|
|
|
|
QModelIndex ATSPartialsFrameProxyModel::parent(const QModelIndex &miChild) const
|
|
|
|
{
|
|
|
|
return QModelIndex(); // No parent here (flat model).
|
|
|
|
}
|