File indexing completed on 2024-05-12 04:51:00

0001 /*
0002     SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "k3baudiodatasource.h"
0007 #include "k3baudiotrack.h"
0008 #include "k3baudiodoc.h"
0009 
0010 
0011 K3b::AudioDataSource::AudioDataSource()
0012     : QObject(),
0013       m_track(0),
0014       m_prev(0),
0015       m_next(0)
0016 {
0017 }
0018 
0019 
0020 K3b::AudioDataSource::AudioDataSource( const K3b::AudioDataSource& source )
0021     : QObject(),
0022       m_track( 0 ),
0023       m_prev( 0 ),
0024       m_next( 0 ),
0025       m_startOffset( source.m_startOffset ),
0026       m_endOffset( source.m_endOffset )
0027 {
0028 }
0029 
0030 
0031 K3b::AudioDataSource::~AudioDataSource()
0032 {
0033     take();
0034 }
0035 
0036 
0037 K3b::AudioDoc* K3b::AudioDataSource::doc() const
0038 {
0039     if( m_track )
0040         return m_track->doc();
0041     else
0042         return 0;
0043 }
0044 
0045 
0046 K3b::AudioDataSource* K3b::AudioDataSource::take()
0047 {
0048     // if we do not have a track we are not in any list
0049     if( m_track ) {
0050         m_track->emitSourceAboutToBeRemoved(this);
0051 
0052         // sets the first source of the track, if necessary
0053         if( m_prev )
0054             m_prev->m_next = m_next;
0055         if( m_next )
0056             m_next->m_prev = m_prev;
0057 
0058         // the emitSourceRemoved() function will take care of setting the
0059         // first source in the track (to avoid the track accessing a deleted
0060         // source, or a source accessing a deleted track
0061         m_track->emitSourceRemoved(this);
0062 
0063         m_prev = m_next = 0;
0064         m_track = 0;
0065     }
0066 
0067     return this;
0068 }
0069 
0070 
0071 void K3b::AudioDataSource::moveAfter( K3b::AudioDataSource* source )
0072 {
0073     // cannot create a list outside a track!
0074     if( !source->track() )
0075         return;
0076 
0077     if( source == this )
0078         return;
0079 
0080     source->track()->emitSourceAboutToBeAdded( source->sourceIndex()+1 );
0081 
0082     // remove this from the list
0083     take();
0084 
0085     K3b::AudioDataSource* oldNext = source->m_next;
0086 
0087     // set track as prev
0088     source->m_next = this;
0089     m_prev = source;
0090 
0091     // set oldNext as next
0092     if( oldNext )
0093         oldNext->m_prev = this;
0094     m_next = oldNext;
0095 
0096     m_track = source->track();
0097 
0098     m_track->emitSourceAdded( this );
0099 }
0100 
0101 
0102 void K3b::AudioDataSource::moveAhead( K3b::AudioDataSource* source )
0103 {
0104     // cannot create a list outside a track!
0105     if( !source->track() )
0106         return;
0107 
0108     if( source == this )
0109         return;
0110 
0111     source->track()->emitSourceAboutToBeAdded( source->sourceIndex() );
0112 
0113     // remove this from the list
0114     take();
0115 
0116     K3b::AudioDataSource* oldPrev = source->m_prev;
0117 
0118     // set track as next
0119     m_next = source;
0120     source->m_prev = this;
0121 
0122     // set oldPrev as prev
0123     m_prev = oldPrev;
0124     if( oldPrev )
0125         oldPrev->m_next = this;
0126 
0127     m_track = source->track();
0128 
0129     if( !m_prev )
0130         m_track->setFirstSource( this );
0131 
0132     m_track->emitSourceAdded( this );
0133 }
0134 
0135 
0136 void K3b::AudioDataSource::emitChange()
0137 {
0138     emit changed();
0139     if( m_track )
0140         m_track->sourceChanged( this );
0141 }
0142 
0143 
0144 K3b::AudioDataSource* K3b::AudioDataSource::split( const K3b::Msf& pos )
0145 {
0146     if( pos < length() ) {
0147         K3b::AudioDataSource* s = copy();
0148         s->setStartOffset( startOffset() + pos );
0149         s->setEndOffset( endOffset() );
0150         setEndOffset( startOffset() + pos );
0151         s->moveAfter( this );
0152         emitChange();
0153         return s;
0154     }
0155     else
0156         return 0;
0157 }
0158 
0159 
0160 K3b::Msf K3b::AudioDataSource::lastSector() const
0161 {
0162     if( endOffset() > 0 )
0163         return endOffset()-1;
0164     else
0165         return originalLength()-1;
0166 }
0167 
0168 
0169 K3b::Msf K3b::AudioDataSource::length() const
0170 {
0171     if( originalLength() == 0 )
0172         return 0;
0173     else if( lastSector() < m_startOffset )
0174         return 1;
0175     else
0176         return lastSector() - m_startOffset + 1;
0177 }
0178 
0179 
0180 int K3b::AudioDataSource::sourceIndex() const
0181 {
0182     if (!m_prev)
0183         return 0;
0184 
0185     return m_prev->sourceIndex() + 1;
0186 }
0187 
0188 
0189 void K3b::AudioDataSource::setStartOffset( const K3b::Msf& msf )
0190 {
0191     m_startOffset = msf;
0192     fixupOffsets();
0193     emitChange();
0194 }
0195 
0196 
0197 void K3b::AudioDataSource::setEndOffset( const K3b::Msf& msf )
0198 {
0199     m_endOffset = msf;
0200     fixupOffsets();
0201     emitChange();
0202 }
0203 
0204 
0205 void K3b::AudioDataSource::fixupOffsets()
0206 {
0207     // no length available yet
0208     if( originalLength() == 0 )
0209         return;
0210 
0211     if( startOffset() >= originalLength() ) {
0212         setStartOffset( 0 );
0213     }
0214     if( endOffset() > originalLength() ) {
0215         setEndOffset( 0 ); // whole source
0216     }
0217     if( endOffset() > 0 && endOffset() <= startOffset() ) {
0218         setEndOffset( startOffset() );
0219     }
0220 }
0221 
0222 #include "moc_k3baudiodatasource.cpp"