Logo Search packages:      
Sourcecode: rosegarden version File versions  Download package

ViewSegment.cpp
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */

/*
    Rosegarden
    A sequencer and musical notation editor.
    Copyright 2000-2011 the Rosegarden development team.
    See the AUTHORS file for more details.

    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 2 of the
    License, or (at your option) any later version.  See the file
    COPYING included with this distribution for more information.
*/

#include "ViewSegment.h"

namespace Rosegarden 
{

ViewSegment::ViewSegment(Segment &t) :
    m_segment(t),
    m_viewElementList(0)
{
    // empty
}

ViewSegment::~ViewSegment()
{
    if (m_viewElementList) m_segment.removeObserver(this);
    notifySourceDeletion();
    delete m_viewElementList;
}

ViewElementList *
00036 ViewSegment::getViewElementList()
{
    return getViewElementList(m_segment.begin(), m_segment.end());
}

ViewElementList *
00042 ViewSegment::getViewElementList(Segment::iterator from,
                        Segment::iterator to)
{
    if (!m_viewElementList) {

        m_viewElementList = new ViewElementList;

        for (Segment::iterator i = from; i != to; ++i) {

            if (!wrapEvent(*i)) continue;

            ViewElement *el = makeViewElement(*i);
            m_viewElementList->insert(el);
        }

        m_segment.addObserver(this);

    }
    
    return m_viewElementList;
}

bool
00065 ViewSegment::wrapEvent(Event *e)
{
    timeT emt = m_segment.getEndMarkerTime();
    return
      (e->getAbsoluteTime() <  emt) ||
      (e->getAbsoluteTime() == emt && e->getDuration() == 0);
}

ViewElementList::iterator
00074 ViewSegment::findEvent(Event *e)
{
    // Note that we have to create this using the virtual
    // makeViewElement, because the result of equal_range depends on
    // the value of the view absolute time for the element, which
    // depends on the particular subclass of ViewElement in use.
    
    // (This is also why this method has to be here and not in
    // ViewElementList -- ViewElementList has no equivalent of
    // makeViewElement.)
    
    ViewElement *dummy = makeViewElement(e);
    
    std::pair<ViewElementList::iterator,
            ViewElementList::iterator>
        r = m_viewElementList->equal_range(dummy);
 
    delete dummy;

    for (ViewElementList::iterator i = r.first; i != r.second; ++i) {
        if ((*i)->event() == e) {
            return i;
        }
    }

    return m_viewElementList->end();
}

void
00103 ViewSegment::eventAdded(const Segment *t, Event *e)
{
    assert(t == &m_segment);
    (void)t; // avoid warnings

    if (wrapEvent(e)) {
        ViewElement *el = makeViewElement(e);
        m_viewElementList->insert(el);
        notifyAdd(el);
    }
}

void
00116 ViewSegment::eventRemoved(const Segment *t, Event *e)
{
    assert(t == &m_segment);
    (void)t; // avoid warnings

    // If we have it, lose it

    ViewElementList::iterator i = findEvent(e);
    if (i != m_viewElementList->end()) {
        notifyRemove(*i);
        m_viewElementList->erase(i);
        return;
    }

//    std::cerr << "Event at " << e->getAbsoluteTime() << ", notation time " << e->getNotationAbsoluteTime() << ", type " << e->getType()
//          << " not found in ViewSegment" << std::endl;
}

void
00135 ViewSegment::endMarkerTimeChanged(const Segment *segment, bool shorten)
{
    Segment *s = const_cast<Segment *>(segment);

    assert(s == &m_segment);

    if (shorten) {

      m_viewElementList->erase
          (m_viewElementList->findTime(s->getEndMarkerTime()),
           m_viewElementList->end());

    } else {

      timeT myLastEltTime = s->getStartTime();
      if (m_viewElementList->end() != m_viewElementList->begin()) {
          ViewElementList::iterator i = m_viewElementList->end();
          myLastEltTime = (*--i)->event()->getAbsoluteTime();
      }
      
      for (Segment::iterator j = s->findTime(myLastEltTime);
           s->isBeforeEndMarker(j); ++j) {
          
          ViewElementList::iterator newi = findEvent(*j);
          if (newi == m_viewElementList->end()) {
            if (wrapEvent(*j)) {
                m_viewElementList->insert(makeViewElement(*j));
            }
          }
      }
    }
}
void
00168 ViewSegment::segmentDeleted(const Segment *s)
{
    assert(s == &m_segment);
    (void)s; // avoid warnings
    /*
    std::cerr << "WARNING: ViewSegment notified of segment deletion: this is probably a bug "
            << "(ViewSegment should have been deleted before Segment)" << std::endl;
              */
}

void
ViewSegment::notifyAdd(ViewElement *e) const
{
    for (ObserverSet::const_iterator i = m_observers.begin();
       i != m_observers.end(); ++i) {
      (*i)->elementAdded(this, e);
    }
}

void
ViewSegment::notifyRemove(ViewElement *e) const
{
    for (ObserverSet::const_iterator i = m_observers.begin();
       i != m_observers.end(); ++i) {
      (*i)->elementRemoved(this, e);
    }
}

void
ViewSegment::notifySourceDeletion() const
{
    for (ObserverSet::const_iterator i = m_observers.begin();
       i != m_observers.end(); ++i) {
      (*i)->viewSegmentDeleted(this);
    }
}


}

Generated by  Doxygen 1.6.0   Back to index