ModelView.cpp 5.78 KB
#include <QVBoxLayout>

#include "ModelView.h"
#include "Shot.h"
#include "VideoFrame.h"

#include <QDebug>

ModelView::ModelView(ProjectModel *project, int nVignettes, QWidget *parent)
  : QWidget(parent),
    m_currEpisode(0),
    m_project(project),
    m_nVignettes(nVignettes),
    m_playerPaused(true)
{
  m_treeView = new QTreeView;
  m_treeView->expandAll();

  QVBoxLayout *layout = new QVBoxLayout;
  layout->addWidget(m_treeView);
  setLayout(layout);

  m_treeView->setModel(m_project);
  m_selection = m_treeView->selectionModel();

  connect(m_selection, SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
	  this, SLOT(updatePlayer(const QModelIndex &, const QModelIndex &)));
}

void ModelView::adjust()
{
  m_treeView->resizeColumnToContents(0);
  m_treeView->resizeColumnToContents(1);
}

void ModelView::initPlayer()
{
  QModelIndex seasonIndex = m_project->index(0, 0);
  updatePlayer(seasonIndex, QModelIndex());
}

/////////////////////////////////////////////
// slot called when clicking on model view //
/////////////////////////////////////////////

void ModelView::updatePlayer(const QModelIndex &current, const QModelIndex &previous)
{
  Q_UNUSED(previous);

  Shot *shot;

  // scroll to selected segment
  m_treeView->scrollTo(current, QAbstractItemView::PositionAtCenter);

  // selected segment
  Segment *segment = static_cast<Segment *>(current.internalPointer());

  // emit signals when encountering shot
  if ((shot = dynamic_cast<Shot *>(segment)))
    emit currentShot(genPositionList(segment));

  updateCurrentEpisode(segment);
  emit setPlayer(m_currEpisode->getFName(), m_currEpisode->getResolution());
  emit setPlayerPosition(segment->getPosition());

  if (m_playerPaused) {
   
    qint64 position = segment->getPosition();
    VideoFrame *vFrame;
    int i;

    // retrieve current video frame
    while (!(vFrame = dynamic_cast<VideoFrame *>(segment))) {

      // closest segment index to current player position
      i = segment->childIndexFromPosition(position);

      // select possible children
      segment = segment->child(i);
    }

    emit displaySubtitle(vFrame->getSub());
  }
}

///////////////////////////////////////////
// slot called when player state changes //
///////////////////////////////////////////

void ModelView::playerPaused(bool pause)
{
  m_playerPaused = pause;
}

//////////////////////////////////////////////
// slot called when player position changes //
//////////////////////////////////////////////

void ModelView::positionChanged(qint64 position)
{
  int i(-1);
  QModelIndex index;
  QModelIndex siblingIndex;
  VideoFrame *vFrame;

  m_selection->clearSelection();

  Segment *segment = m_currEpisode;

  // retrieve segment to select
  int depth = 0;
  while (depth++ < m_depth) {

    // closest segment index to current player position
    i = segment->childIndexFromPosition(position);

    // select possible children
    segment = segment->child(i);
  }

  // model indexes to select
  index = m_project->indexFromSegment(segment);
  siblingIndex = m_project->sibling(i, 1, index);
  
  // segment selection
  m_selection->setCurrentIndex(index, QItemSelectionModel::Select);
  m_selection->setCurrentIndex(siblingIndex, QItemSelectionModel::Select);

  // retrieve current video frame
  while (!(vFrame = dynamic_cast<VideoFrame *>(segment))) {

    // closest segment index to current player position
    i = segment->childIndexFromPosition(position);

    // select possible children
    segment = segment->child(i);
  }

  emit displaySubtitle(vFrame->getSub());
}

///////////////////////////////////
// slot called when pressing key //
///////////////////////////////////

void ModelView::keyPressEvent(QKeyEvent *event)
{
  Segment *segment = static_cast<Segment *>(m_selection->currentIndex().internalPointer());

  if (event->key() == Qt::Key_Return && dynamic_cast<VideoFrame *>(segment))
    emit insertShot(segment);
  else if (event->key() == Qt::Key_Backspace && dynamic_cast<Shot *>(segment))
    emit removeShot(segment);
  else if (event->key() == Qt::Key_Return && dynamic_cast<Shot *>(segment))
    emit editSimShots(segment);
}

///////////////////////////////////////////////////
// slots called when entering in annotation mode //
///////////////////////////////////////////////////

void ModelView::initShotAnnot(bool checked)
{
  Segment *segment = static_cast<Segment *>(m_selection->currentIndex().internalPointer());

  if (checked)
    emit initShotLevel(segment);
}

///////////////
// accessors //
///////////////

QString ModelView::getCurrentEpisodeFName() const
{
  return m_currEpisode->getFName();
}

/////////////////////
// private methods //
/////////////////////

void ModelView::updateCurrentEpisode(Segment *segment)
{
  Episode *episode = 0;

  // looking for corresponding episode
  Segment *tmp = segment;

  // searching among parent segments
  while (tmp != 0 && !(episode = dynamic_cast<Episode *>(tmp)))
    tmp = tmp->parent();

  // if not found, searching among child segments
  if (!tmp) {
    tmp = segment;
    while (tmp != 0 && !(episode = dynamic_cast<Episode *>(tmp)))
      tmp = tmp->child(0);
  }

  if (episode != m_currEpisode) {
    m_currEpisode = episode;
  }
}

QList<qint64> ModelView::genPositionList(Segment *segment)
{
  QList<qint64> positionList;
  qint64 segmentPosition;

  int iFirst = segment->row() - m_nVignettes / 2;
  int iLast = segment->row() + m_nVignettes / 2;

  for (int i(iFirst); i <= iLast; i++) {
    if (i >= 0 && i < segment->parent()->childCount()) {
      segmentPosition = segment->parent()->child(i)->getPosition();
      positionList.push_back(segmentPosition);
    }
    else
      positionList.push_back(-1);
  }

  return positionList;
}

///////////////
// modifiers //
///////////////

void ModelView::setDepth(int depth)
{
  m_depth = depth - 2;
  m_treeView->expandToDepth(m_depth);
  adjust();
}