File indexing completed on 2024-05-05 04:51:42
0001 /* 0002 SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "k3baudiotracksplitdialog.h" 0007 #include "k3baudiotrack.h" 0008 #include "k3baudioeditorwidget.h" 0009 0010 #include "k3bmsf.h" 0011 #include "k3bmsfedit.h" 0012 0013 #include <KLocalizedString> 0014 #include <KActionCollection> 0015 0016 #include <QEvent> 0017 #include <QContextMenuEvent> 0018 #include <QMouseEvent> 0019 #include <QAction> 0020 #include <QDialogButtonBox> 0021 #include <QGridLayout> 0022 #include <QLabel> 0023 #include <QLayout> 0024 #include <QMenu> 0025 0026 0027 K3b::AudioTrackSplitDialog::AudioTrackSplitDialog( K3b::AudioTrack* track, QWidget* parent ) 0028 : QDialog( parent), 0029 m_track(track) 0030 { 0031 setWindowTitle(i18n("Split Audio Track")); 0032 0033 m_editorWidget = new K3b::AudioEditorWidget( this ); 0034 m_msfEditStart = new K3b::MsfEdit( this ); 0035 m_msfEditEnd = new K3b::MsfEdit( this ); 0036 0037 QVBoxLayout* layout = new QVBoxLayout( this ); 0038 0039 // FIXME: After the string freeze replace the text with a better one explaining how to use this dialog 0040 layout->addWidget( new QLabel( i18n("Please select the position where the track should be split."), 0041 this ) ); 0042 layout->addWidget( m_editorWidget ); 0043 0044 QHBoxLayout* rangeLayout = new QHBoxLayout; 0045 rangeLayout->addWidget( new QLabel( i18n("Split track at:"), this ), 1 ); 0046 rangeLayout->addWidget( m_msfEditStart, 0 ); 0047 rangeLayout->addWidget( new QLabel( " - ", this ), 0, Qt::AlignCenter ); 0048 rangeLayout->addWidget( m_msfEditEnd, 0 ); 0049 layout->addLayout( rangeLayout ); 0050 0051 m_editorWidget->setAllowOverlappingRanges( false ); 0052 m_editorWidget->enableRangeSelection( true ); 0053 m_editorWidget->installEventFilter( this ); 0054 0055 connect( m_editorWidget, SIGNAL(rangeChanged(int,K3b::Msf,K3b::Msf)), 0056 this, SLOT(slotRangeModified(int,K3b::Msf,K3b::Msf)) ); 0057 connect( m_editorWidget, SIGNAL(selectedRangeChanged(int)), 0058 this, SLOT(slotRangeSelectionChanged(int)) ); 0059 connect( m_msfEditStart, SIGNAL(valueChanged(K3b::Msf)), 0060 this, SLOT(slotMsfEditChanged(K3b::Msf)) ); 0061 connect( m_msfEditEnd, SIGNAL(valueChanged(K3b::Msf)), 0062 this, SLOT(slotMsfEditChanged(K3b::Msf)) ); 0063 0064 setupActions(); 0065 0066 // load the track 0067 m_editorWidget->setLength( m_track->length() ); 0068 0069 // default split 0070 K3b::Msf mid = m_track->length().lba() / 2; 0071 m_editorWidget->addRange( 0, mid-1 ); 0072 m_editorWidget->addRange( mid, m_track->length()-1 ); 0073 0074 QDialogButtonBox* buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this ); 0075 connect( buttonBox, SIGNAL(accepted()), SLOT(accept()) ); 0076 connect( buttonBox, SIGNAL(rejected()), SLOT(reject()) ); 0077 layout->addWidget( buttonBox ); 0078 0079 slotRangeSelectionChanged( 0 ); 0080 } 0081 0082 0083 K3b::AudioTrackSplitDialog::~AudioTrackSplitDialog() 0084 { 0085 } 0086 0087 0088 void K3b::AudioTrackSplitDialog::setupActions() 0089 { 0090 m_popupMenu = new QMenu( this ); 0091 0092 QAction* actionSplitHere = new QAction( this ); 0093 actionSplitHere->setText( i18n("Split Here") ); 0094 connect( actionSplitHere, SIGNAL(triggered()), this, SLOT(slotSplitHere()) ); 0095 0096 QAction* actionRemoveRange = new QAction( this ); 0097 actionRemoveRange->setText( i18n("Remove part") ); 0098 connect( actionRemoveRange, SIGNAL(triggered()), this, SLOT(slotRemoveRange()) ); 0099 0100 m_popupMenu->addAction( actionSplitHere ); 0101 m_popupMenu->addAction( actionRemoveRange ); 0102 } 0103 0104 0105 void K3b::AudioTrackSplitDialog::slotRangeModified( int id, const K3b::Msf& start, const K3b::Msf& end ) 0106 { 0107 if( id == m_editorWidget->selectedRange() ) { 0108 m_msfEditStart->blockSignals( true ); 0109 m_msfEditEnd->blockSignals( true ); 0110 0111 m_msfEditStart->setValue( start ); 0112 m_msfEditEnd->setValue( end ); 0113 0114 m_msfEditStart->blockSignals( false ); 0115 m_msfEditEnd->blockSignals( false ); 0116 } 0117 } 0118 0119 0120 void K3b::AudioTrackSplitDialog::slotMsfEditChanged( const K3b::Msf& ) 0121 { 0122 m_editorWidget->modifyRange( m_editorWidget->selectedRange(), m_msfEditStart->value(), m_msfEditEnd->value() ); 0123 } 0124 0125 0126 void K3b::AudioTrackSplitDialog::slotRangeSelectionChanged( int id ) 0127 { 0128 if( id > 0 ) { 0129 m_msfEditStart->blockSignals( true ); 0130 m_msfEditEnd->blockSignals( true ); 0131 0132 m_msfEditStart->setValue( m_editorWidget->rangeStart( id ) ); 0133 m_msfEditEnd->setValue( m_editorWidget->rangeEnd( id ) ); 0134 m_msfEditStart->setEnabled( true ); 0135 m_msfEditEnd->setEnabled( true ); 0136 0137 m_msfEditStart->blockSignals( false ); 0138 m_msfEditEnd->blockSignals( false ); 0139 } 0140 else { 0141 m_msfEditStart->setEnabled( false ); 0142 m_msfEditEnd->setEnabled( false ); 0143 } 0144 } 0145 0146 0147 void K3b::AudioTrackSplitDialog::splitAt( const QPoint& p ) 0148 { 0149 int id = m_editorWidget->findRange( p.x() ); 0150 if( id ) { 0151 K3b::Msf msf = m_editorWidget->posToMsf( p.x() ); 0152 m_editorWidget->addRange( msf+1, m_editorWidget->rangeEnd( id ) ); 0153 m_editorWidget->modifyRange( id, m_editorWidget->rangeStart( id ), msf ); 0154 slotRangeSelectionChanged( m_editorWidget->selectedRange() ); 0155 } 0156 } 0157 0158 0159 bool K3b::AudioTrackSplitDialog::eventFilter( QObject* o, QEvent* e ) 0160 { 0161 if( o == m_editorWidget ) { 0162 if( e->type() == QEvent::MouseButtonDblClick ) { 0163 QMouseEvent* me = static_cast<QMouseEvent*>( e ); 0164 splitAt( me->pos() ); 0165 } 0166 else if( e->type() == QEvent::ContextMenu ) { 0167 QContextMenuEvent* ce = static_cast<QContextMenuEvent*>( e ); 0168 ce->accept(); 0169 m_lastClickPosition = ce->pos(); 0170 if( m_editorWidget->findRange( ce->pos().x() ) > 0 ) 0171 m_popupMenu->popup( ce->globalPos() ); 0172 } 0173 } 0174 0175 return QDialog::eventFilter( o, e ); 0176 } 0177 0178 0179 void K3b::AudioTrackSplitDialog::slotSplitHere() 0180 { 0181 splitAt( m_lastClickPosition ); 0182 } 0183 0184 0185 void K3b::AudioTrackSplitDialog::slotRemoveRange() 0186 { 0187 m_editorWidget->removeRange( m_editorWidget->findRange( m_lastClickPosition.x() ) ); 0188 } 0189 0190 0191 void K3b::AudioTrackSplitDialog::splitTrack( K3b::AudioTrack* track, 0192 QWidget* parent ) 0193 { 0194 if ( !track ) { 0195 return; 0196 } 0197 0198 K3b::AudioTrackSplitDialog d( track, parent ); 0199 if( d.exec() == QDialog::Accepted ) { 0200 QList<int> ranges = d.m_editorWidget->allRanges(); 0201 // we split the track at all range ends and just delete those that relate to the gaps in between 0202 K3b::Msf pos = 0; 0203 for( QList<int>::const_iterator it = ranges.constBegin(); 0204 it != ranges.constEnd(); ++it ) { 0205 0206 // delete the unwanted part 0207 if( d.m_editorWidget->rangeStart( *it ) > pos ) { 0208 // split so the range's start is the first frame of the new track 0209 K3b::AudioTrack* nextTrack = track->split( d.m_editorWidget->rangeStart( *it ) - pos ); 0210 delete track; 0211 track = nextTrack; 0212 } 0213 0214 // create a new track part for the range itself 0215 pos = d.m_editorWidget->rangeStart( *it ); 0216 if( d.m_editorWidget->rangeEnd( *it ) < d.m_editorWidget->length()-1 ) { 0217 // split so the range's end is the last frame in the old track 0218 // and thus, the range's end + 1 the first frame in the new track 0219 track = track->split( d.m_editorWidget->rangeEnd( *it ) - pos + 1 ); 0220 } 0221 pos = d.m_editorWidget->rangeEnd( *it )+1; 0222 } 0223 0224 // remove the last unwanted part 0225 if( pos < d.m_editorWidget->length() ) { 0226 delete track; 0227 } 0228 } 0229 } 0230 0231 #include "moc_k3baudiotracksplitdialog.cpp"