/* BEGIN software license
 *
 * msXpertSuite - mass spectrometry software suite
 * -----------------------------------------------
 * Copyright(C) 2009,...,2018 Filippo Rusconi
 *
 * http://www.msxpertsuite.org
 *
 * This file is part of the msXpertSuite project.
 *
 * The msXpertSuite project is the successor of the massXpert project. This
 * project now includes various independent modules:
 *
 * - massXpert, model polymer chemistries and simulate mass spectrometric data;
 * - mineXpert, a powerful TIC chromatogram/mass spectrum viewer/miner;
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * END software license
 */


/////////////////////// Local includes
#include "SequenceEditorGraphicsViewKeySequenceHandling.hpp"


namespace msxps
{

namespace massxpert
{


  void
  SequenceEditorGraphicsView::MoveToPreviousChar(QKeyEvent *event)
  {
    if(m_kbdShiftDown)
      return SelectPreviousChar(event);

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();

    if(!m_kbdCtrlDown || !multiRegionSelection)
      resetSelection();

    if(m_lastClickedVignette <= 0)
      return event->accept();

    --m_lastClickedVignette;
    //     qDebug() << __FILE__ << __LINE__
    // 	      << "m_lastClickedVignette:" << m_lastClickedVignette;

    m_selectionFirstPoint  = vignetteLocation(m_lastClickedVignette, CENTER);
    m_selectionSecondPoint = m_selectionFirstPoint;

    positionCursor();

    QPointF point =
      mapFromScene(vignetteLocation(m_lastClickedVignette, CENTER));

    if(point.y() <= (m_requestedVignetteSize / 4))
      vScrollBarActionTriggered(QAbstractSlider::SliderSingleStepSub);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::MoveToNextChar(QKeyEvent *event)
  {
    if(m_kbdShiftDown)
      return SelectNextChar(event);

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();

    if(!m_kbdCtrlDown || !multiRegionSelection)
      resetSelection();

    if(m_lastClickedVignette >= mp_polymer->size())
      return event->accept();

    ++m_lastClickedVignette;
    //     qDebug() << __FILE__ << __LINE__
    // 	      << "m_lastClickedVignette:" << m_lastClickedVignette;

    m_selectionFirstPoint  = vignetteLocation(m_lastClickedVignette, CENTER);
    m_selectionSecondPoint = m_selectionFirstPoint;

    positionCursor();

    QPointF point =
      mapFromScene(vignetteLocation(m_lastClickedVignette, CENTER));

    if(point.y() >= rect().height() - (m_requestedVignetteSize / 4))
      vScrollBarActionTriggered(QAbstractSlider::SliderSingleStepAdd);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::MoveToPreviousLine(QKeyEvent *event)
  {
    if(m_kbdShiftDown)
      return SelectPreviousLine(event);

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();

    if(!m_kbdCtrlDown || !multiRegionSelection)
      resetSelection();

    if(m_lastClickedVignette <= 0)
      return event->accept();

    int targetIndex = m_lastClickedVignette - m_columns;

    if(targetIndex < 0)
      return;

    m_lastClickedVignette = targetIndex;
    //     qDebug() << __FILE__ << __LINE__
    // 	      << "m_lastClickedVignette:" << m_lastClickedVignette;

    m_selectionFirstPoint  = vignetteLocation(m_lastClickedVignette, CENTER);
    m_selectionSecondPoint = m_selectionFirstPoint;

    positionCursor();

    QPointF point =
      mapFromScene(vignetteLocation(m_lastClickedVignette, CENTER));

    if(point.y() <= (m_requestedVignetteSize / 4))
      vScrollBarActionTriggered(QAbstractSlider::SliderSingleStepSub);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::MoveToNextLine(QKeyEvent *event)
  {
    if(m_kbdShiftDown)
      return SelectNextLine(event);

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();

    if(!m_kbdCtrlDown || !multiRegionSelection)
      resetSelection();

    if(m_lastClickedVignette >= mp_polymer->size())
      return event->accept();

    int targetIndex = m_lastClickedVignette + m_columns;

    if(targetIndex >= mp_polymer->size())
      return;

    m_lastClickedVignette = targetIndex;
    //     qDebug() << __FILE__ << __LINE__
    // 	      << "m_lastClickedVignette:" << m_lastClickedVignette;

    m_selectionFirstPoint  = vignetteLocation(m_lastClickedVignette, CENTER);
    m_selectionSecondPoint = m_selectionFirstPoint;

    positionCursor();

    QPointF point =
      mapFromScene(vignetteLocation(m_lastClickedVignette, CENTER));

    if(point.y() >= rect().height() - (m_requestedVignetteSize / 4))
      vScrollBarActionTriggered(QAbstractSlider::SliderSingleStepAdd);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::MoveToPreviousPage(QKeyEvent *event)
  {
    if(m_kbdShiftDown)
      return SelectPreviousPage(event);

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();

    if(!m_kbdCtrlDown || !multiRegionSelection)
      resetSelection();

    if(m_lastClickedVignette <= 0)
      return event->accept();

    int visibleRows = rect().height() / m_requestedVignetteSize;
    int targetIndex = m_lastClickedVignette - (m_columns * visibleRows);

    if(targetIndex < 0)
      targetIndex = 0;

    m_lastClickedVignette = targetIndex;
    //     qDebug() << __FILE__ << __LINE__
    // 	      << "m_lastClickedVignette:" << m_lastClickedVignette;

    m_selectionFirstPoint  = vignetteLocation(m_lastClickedVignette, CENTER);
    m_selectionSecondPoint = m_selectionFirstPoint;

    positionCursor(END_OF_LINE);

    QScrollBar *vScrollBar = verticalScrollBar();
    int curVal             = vScrollBar->value();
    vScrollBar->setValue(curVal - (visibleRows * m_requestedVignetteSize));

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::MoveToNextPage(QKeyEvent *event)
  {
    if(m_kbdShiftDown)
      return SelectNextPage(event);

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();

    if(!m_kbdCtrlDown || !multiRegionSelection)
      resetSelection();

    if(m_lastClickedVignette >= mp_polymer->size())
      return event->accept();

    int visibleRows = rect().height() / m_requestedVignetteSize;
    int targetIndex = m_lastClickedVignette + (m_columns * visibleRows);

    if(targetIndex >= mp_polymer->size())
      targetIndex = mp_polymer->size();

    m_lastClickedVignette = targetIndex;
    //     qDebug() << __FILE__ << __LINE__
    // 	      << "m_lastClickedVignette:" << m_lastClickedVignette;

    m_selectionFirstPoint  = vignetteLocation(m_lastClickedVignette, CENTER);
    m_selectionSecondPoint = m_selectionFirstPoint;

    positionCursor(END_OF_LINE);

    QScrollBar *vScrollBar = verticalScrollBar();
    int curVal             = vScrollBar->value();
    vScrollBar->setValue(curVal + (visibleRows * m_requestedVignetteSize));

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::MoveToStartOfLine(QKeyEvent *event)
  {
    resetSelection();

    if(m_lastClickedVignette <= 0)
      return event->accept();

    double rowIndex = m_lastClickedVignette / m_columns;
    int targetIndex = static_cast<int>(rowIndex) * m_columns;

    m_lastClickedVignette = targetIndex;
    //     qDebug() << __FILE__ << __LINE__
    // 	      << "m_lastClickedVignette:" << m_lastClickedVignette;

    m_selectionFirstPoint  = vignetteLocation(m_lastClickedVignette, CENTER);
    m_selectionSecondPoint = m_selectionFirstPoint;

    positionCursor(START_OF_LINE);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::MoveToEndOfLine(QKeyEvent *event)
  {
    resetSelection();

    if(m_lastClickedVignette >= mp_polymer->size())
      return event->accept();

    double rowIndex = m_lastClickedVignette / m_columns;
    int targetIndex = static_cast<int>(rowIndex + 1) * m_columns;

    m_lastClickedVignette = targetIndex;
    //     qDebug() << __FILE__ << __LINE__
    // 	      << "m_lastClickedVignette:" << m_lastClickedVignette;

    m_selectionFirstPoint  = vignetteLocation(m_lastClickedVignette, CENTER);
    m_selectionSecondPoint = m_selectionFirstPoint;

    positionCursor(END_OF_LINE);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::MoveToStartOfDocument(QKeyEvent *event)
  {
    if(selectionIndices(static_cast<CoordinateList *>(0)))
      resetSelection();

    if(m_lastClickedVignette <= 0)
      return event->accept();

    int targetIndex = 0;

    m_lastClickedVignette = targetIndex;
    //     qDebug() << __FILE__ << __LINE__
    // 	      << "m_lastClickedVignette:" << m_lastClickedVignette;

    m_selectionFirstPoint  = vignetteLocation(m_lastClickedVignette, CENTER);
    m_selectionSecondPoint = m_selectionFirstPoint;

    positionCursor(START_OF_LINE);

    QScrollBar *vScrollBar = verticalScrollBar();
    vScrollBar->setValue(0);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::MoveToEndOfDocument(QKeyEvent *event)
  {
    if(selectionIndices(static_cast<CoordinateList *>(0)))
      resetSelection();

    if(m_lastClickedVignette >= mp_polymer->size())
      return event->accept();

    int targetIndex = mp_polymer->size();

    m_lastClickedVignette = targetIndex;
    //     qDebug() << __FILE__ << __LINE__
    // 	      << "m_lastClickedVignette:" << m_lastClickedVignette;

    m_selectionFirstPoint  = vignetteLocation(m_lastClickedVignette, CENTER);
    m_selectionSecondPoint = m_selectionFirstPoint;

    positionCursor(END_OF_LINE);

    QScrollBar *vScrollBar = verticalScrollBar();
    vScrollBar->setValue(m_rows * m_requestedVignetteSize);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::SelectPreviousChar(QKeyEvent *event)
  {
    if(m_lastClickedVignette <= 0)
      return event->accept();

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();
    bool multiSelectionRegion = mp_editorWnd->isMultiSelectionRegion();

    if(m_ongoingKeyboardMultiSelection)
      {
        mpa_selection->deselectLastRegion();

        --m_lastClickedVignette;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);
      }
    else
      {
        m_selectionFirstPoint = vignetteLocation(m_lastClickedVignette, CENTER);

        --m_lastClickedVignette;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);

        m_ongoingKeyboardMultiSelection = true;
      }

    positionCursor();

    QPointF point =
      mapFromScene(vignetteLocation(m_lastClickedVignette, CENTER));

    if(point.y() <= (m_requestedVignetteSize / 4))
      vScrollBarActionTriggered(QAbstractSlider::SliderSingleStepSub);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::SelectNextChar(QKeyEvent *event)
  {
    if(m_lastClickedVignette >= mp_polymer->size())
      return event->accept();

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();
    bool multiSelectionRegion = mp_editorWnd->isMultiSelectionRegion();

    if(m_ongoingKeyboardMultiSelection)
      {
        mpa_selection->deselectLastRegion();

        ++m_lastClickedVignette;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);
      }
    else
      {
        m_selectionFirstPoint = vignetteLocation(m_lastClickedVignette, CENTER);

        ++m_lastClickedVignette;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);

        m_ongoingKeyboardMultiSelection = true;
      }

    positionCursor();

    QPointF point =
      mapFromScene(vignetteLocation(m_lastClickedVignette, CENTER));

    if(point.y() >= rect().height() - (m_requestedVignetteSize / 4))
      vScrollBarActionTriggered(QAbstractSlider::SliderSingleStepAdd);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::SelectNextLine(QKeyEvent *event)
  {
    if(m_lastClickedVignette >= mp_polymer->size())
      return event->accept();

    int targetIndex = m_lastClickedVignette + m_columns;

    if(targetIndex >= mp_polymer->size())
      return;

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();
    bool multiSelectionRegion = mp_editorWnd->isMultiSelectionRegion();

    if(m_ongoingKeyboardMultiSelection)
      {
        mpa_selection->deselectLastRegion();

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);
      }
    else
      {
        m_selectionFirstPoint = vignetteLocation(m_lastClickedVignette, CENTER);

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);

        m_ongoingKeyboardMultiSelection = true;
      }

    positionCursor();

    QPointF point =
      mapFromScene(vignetteLocation(m_lastClickedVignette, CENTER));

    if(point.y() >= rect().height() - (m_requestedVignetteSize / 4))
      vScrollBarActionTriggered(QAbstractSlider::SliderSingleStepAdd);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::SelectPreviousLine(QKeyEvent *event)
  {
    if(m_lastClickedVignette <= 0)
      return event->accept();

    int targetIndex = m_lastClickedVignette - m_columns;

    if(targetIndex < 0)
      return;

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();
    bool multiSelectionRegion = mp_editorWnd->isMultiSelectionRegion();

    if(m_ongoingKeyboardMultiSelection)
      {
        mpa_selection->deselectLastRegion();

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);
      }
    else
      {
        m_selectionFirstPoint = vignetteLocation(m_lastClickedVignette, CENTER);

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);

        m_ongoingKeyboardMultiSelection = true;
      }

    positionCursor();

    QPointF point =
      mapFromScene(vignetteLocation(m_lastClickedVignette, CENTER));

    if(point.y() <= (m_requestedVignetteSize / 4))
      vScrollBarActionTriggered(QAbstractSlider::SliderSingleStepSub);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::SelectNextPage(QKeyEvent *event)
  {
    if(m_lastClickedVignette >= mp_polymer->size())
      return event->accept();

    int visibleRows = rect().height() / m_requestedVignetteSize;
    int targetIndex = m_lastClickedVignette + (m_columns * visibleRows);

    if(targetIndex >= mp_polymer->size())
      targetIndex = mp_polymer->size();

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();
    bool multiSelectionRegion = mp_editorWnd->isMultiSelectionRegion();

    if(m_ongoingKeyboardMultiSelection)
      {
        mpa_selection->deselectLastRegion();

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);
      }
    else
      {
        m_selectionFirstPoint = vignetteLocation(m_lastClickedVignette, CENTER);

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);

        m_ongoingKeyboardMultiSelection = true;
      }

    positionCursor();

    QScrollBar *vScrollBar = verticalScrollBar();
    int curVal             = vScrollBar->value();
    vScrollBar->setValue(curVal + (visibleRows * m_requestedVignetteSize));

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::SelectPreviousPage(QKeyEvent *event)
  {
    if(m_lastClickedVignette <= 0)
      return event->accept();

    int visibleRows = rect().height() / m_requestedVignetteSize;
    int targetIndex = m_lastClickedVignette - (m_columns * visibleRows);

    if(targetIndex < 0)
      targetIndex = 0;

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();
    bool multiSelectionRegion = mp_editorWnd->isMultiSelectionRegion();

    if(m_ongoingKeyboardMultiSelection)
      {
        mpa_selection->deselectLastRegion();

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);
      }
    else
      {
        m_selectionFirstPoint = vignetteLocation(m_lastClickedVignette, CENTER);

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);
        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);

        m_ongoingKeyboardMultiSelection = true;
      }

    positionCursor();

    QScrollBar *vScrollBar = verticalScrollBar();
    int curVal             = vScrollBar->value();
    vScrollBar->setValue(curVal - (visibleRows * m_requestedVignetteSize));

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::SelectStartOfLine(QKeyEvent *event)
  {
    if(m_lastClickedVignette <= 0)
      return event->accept();

    double rowIndex = m_lastClickedVignette / m_columns;
    int targetIndex = static_cast<int>(rowIndex) * m_columns;

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();
    bool multiSelectionRegion = mp_editorWnd->isMultiSelectionRegion();

    if(m_ongoingKeyboardMultiSelection)
      {
        mpa_selection->deselectLastRegion();

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);
      }
    else
      {
        m_selectionFirstPoint = vignetteLocation(m_lastClickedVignette, CENTER);

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);
        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);

        m_ongoingKeyboardMultiSelection = true;
      }

    positionCursor(START_OF_LINE);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::SelectEndOfLine(QKeyEvent *event)
  {
    if(m_lastClickedVignette >= mp_polymer->size())
      return event->accept();

    double rowIndex = m_lastClickedVignette / m_columns;
    int targetIndex = static_cast<int>(rowIndex + 1) * m_columns;

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();
    bool multiSelectionRegion = mp_editorWnd->isMultiSelectionRegion();

    if(m_ongoingKeyboardMultiSelection)
      {
        mpa_selection->deselectLastRegion();

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);
      }
    else
      {
        m_selectionFirstPoint = vignetteLocation(m_lastClickedVignette, CENTER);

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);

        m_ongoingKeyboardMultiSelection = true;
      }

    positionCursor(END_OF_LINE);

    QPointF point =
      mapFromScene(vignetteLocation(m_lastClickedVignette, CENTER));

    if(point.y() >= rect().height() - (m_requestedVignetteSize / 4))
      vScrollBarActionTriggered(QAbstractSlider::SliderSingleStepAdd);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::SelectStartOfDocument(QKeyEvent *event)
  {
    if(m_lastClickedVignette <= 0)
      return event->accept();

    int targetIndex = 0;

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();
    bool multiSelectionRegion = mp_editorWnd->isMultiSelectionRegion();

    if(m_ongoingKeyboardMultiSelection)
      {
        mpa_selection->deselectLastRegion();

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);
      }
    else
      {
        m_selectionFirstPoint = vignetteLocation(m_lastClickedVignette, CENTER);

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);

        m_ongoingKeyboardMultiSelection = true;
      }

    positionCursor(START_OF_LINE);

    QScrollBar *vScrollBar = verticalScrollBar();
    vScrollBar->setValue(0);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::SelectEndOfDocument(QKeyEvent *event)
  {
    if(m_lastClickedVignette >= mp_polymer->size())
      return event->accept();

    int targetIndex = mp_polymer->size();

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();
    bool multiSelectionRegion = mp_editorWnd->isMultiSelectionRegion();

    if(m_ongoingKeyboardMultiSelection)
      {
        mpa_selection->deselectLastRegion();

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);
      }
    else
      {
        m_selectionFirstPoint = vignetteLocation(m_lastClickedVignette, CENTER);

        m_lastClickedVignette = targetIndex;
        // 	qDebug() << __FILE__ << __LINE__
        // 		  << "m_lastClickedVignette:" << m_lastClickedVignette;

        m_selectionSecondPoint =
          vignetteLocation(m_lastClickedVignette, CENTER);

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);

        m_ongoingKeyboardMultiSelection = true;
      }

    positionCursor(END_OF_LINE);

    QScrollBar *vScrollBar = verticalScrollBar();
    vScrollBar->setValue(m_rows * m_requestedVignetteSize);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }


  void
  SequenceEditorGraphicsView::SelectAll(QKeyEvent *event)
  {
    m_lastClickedVignette = 0;

    m_selectionFirstPoint = vignetteLocation(m_lastClickedVignette, CENTER);

    m_lastClickedVignette = mp_polymer->size();
    //     qDebug() << __FILE__ << __LINE__
    // 	      << "m_lastClickedVignette:" << m_lastClickedVignette;

    m_selectionSecondPoint = vignetteLocation(m_lastClickedVignette, CENTER);

    bool multiRegionSelection = mp_editorWnd->isMultiRegionSelection();
    bool multiSelectionRegion = mp_editorWnd->isMultiSelectionRegion();

    if(m_ongoingKeyboardMultiSelection)
      {
        mpa_selection->deselectLastRegion();

        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);
      }
    else
      {
        mpa_selection->selectRegion(m_selectionFirstPoint,
                                    m_selectionSecondPoint,
                                    multiRegionSelection,
                                    multiSelectionRegion);

        m_ongoingKeyboardMultiSelection = true;
      }

    positionCursor(END_OF_LINE);

    QScrollBar *vScrollBar = verticalScrollBar();
    vScrollBar->setValue(m_rows * m_requestedVignetteSize);

    mp_editorWnd->updateSelectedSequenceMasses();

    return event->accept();
  }

} // namespace massxpert

} // namespace msxps
