TCO drag: Fix Ctrl+Drag crash
Fix some assumptions that source and target of a drag actions are the same track container. Instead of looking up necessary information (track name, type and container id) by track index, add it to the metadata. Refactor canPasteSelection to take QDropEvent instead of the drop event's QMimeData. Coincidentally, this fixes the method to be consistent with its documentation. Fixes #4844
This commit is contained in:
@@ -341,7 +341,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool canPasteSelection( MidiTime tcoPos, const QMimeData * mimeData );
|
||||
bool canPasteSelection( MidiTime tcoPos, const QDropEvent *de );
|
||||
bool pasteSelection( MidiTime tcoPos, QDropEvent * de );
|
||||
|
||||
MidiTime endPosition( const MidiTime & posStart );
|
||||
|
||||
@@ -497,7 +497,7 @@ void TrackContentObjectView::dragEnterEvent( QDragEnterEvent * dee )
|
||||
{
|
||||
TrackContentWidget * tcw = getTrackView()->getTrackContentWidget();
|
||||
MidiTime tcoPos = MidiTime( m_tco->startPosition().getTact(), 0 );
|
||||
if( tcw->canPasteSelection( tcoPos, dee->mimeData() ) == false )
|
||||
if( tcw->canPasteSelection( tcoPos, dee ) == false )
|
||||
{
|
||||
dee->ignore();
|
||||
}
|
||||
@@ -602,9 +602,12 @@ DataFile TrackContentObjectView::createTCODataFiles(
|
||||
it != tcoViews.end(); ++it )
|
||||
{
|
||||
// Insert into the dom under the "tcos" element
|
||||
int trackIndex = tc->tracks().indexOf( ( *it )->m_trackView->getTrack() );
|
||||
Track* tcoTrack = ( *it )->m_trackView->getTrack();
|
||||
int trackIndex = tc->tracks().indexOf( tcoTrack );
|
||||
QDomElement tcoElement = dataFile.createElement( "tco" );
|
||||
tcoElement.setAttribute( "trackIndex", trackIndex );
|
||||
tcoElement.setAttribute( "trackType", tcoTrack->type() );
|
||||
tcoElement.setAttribute( "trackName", tcoTrack->name() );
|
||||
( *it )->m_tco->saveState( dataFile, tcoElement );
|
||||
tcoParent.appendChild( tcoElement );
|
||||
}
|
||||
@@ -621,6 +624,7 @@ DataFile TrackContentObjectView::createTCODataFiles(
|
||||
QDomElement metadata = dataFile.createElement( "copyMetadata" );
|
||||
// initialTrackIndex is the index of the track that was touched
|
||||
metadata.setAttribute( "initialTrackIndex", initialTrackIndex );
|
||||
metadata.setAttribute( "trackContainerId", tc->id() );
|
||||
// grabbedTCOPos is the pos of the tact containing the TCO we grabbed
|
||||
metadata.setAttribute( "grabbedTCOPos", m_tco->startPosition() );
|
||||
|
||||
@@ -1316,7 +1320,7 @@ MidiTime TrackContentWidget::getPosition( int mouseX )
|
||||
void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee )
|
||||
{
|
||||
MidiTime tcoPos = MidiTime( getPosition( dee->pos().x() ).getTact(), 0 );
|
||||
if( canPasteSelection( tcoPos, dee->mimeData() ) == false )
|
||||
if( canPasteSelection( tcoPos, dee ) == false )
|
||||
{
|
||||
dee->ignore();
|
||||
}
|
||||
@@ -1335,8 +1339,10 @@ void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee )
|
||||
* \param tcoPos the position of the TCO slot being pasted on
|
||||
* \param de the DropEvent generated
|
||||
*/
|
||||
bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * mimeData )
|
||||
bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QDropEvent* de )
|
||||
{
|
||||
const QMimeData * mimeData = de->mimeData();
|
||||
|
||||
Track * t = getTrack();
|
||||
QString type = StringPairDrag::decodeMimeKey( mimeData );
|
||||
QString value = StringPairDrag::decodeMimeValue( mimeData );
|
||||
@@ -1366,7 +1372,9 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m
|
||||
const int currentTrackIndex = tracks.indexOf( t );
|
||||
|
||||
// Don't paste if we're on the same tact
|
||||
if( tcoPos == grabbedTCOTact && currentTrackIndex == initialTrackIndex )
|
||||
auto sourceTrackContainerId = metadata.attributeNode( "trackContainerId" ).value().toUInt();
|
||||
if( de->source() && sourceTrackContainerId == t->trackContainer()->id() &&
|
||||
tcoPos == grabbedTCOTact && currentTrackIndex == initialTrackIndex )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1389,9 +1397,9 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m
|
||||
}
|
||||
|
||||
// Track must be of the same type
|
||||
Track * startTrack = tracks.at( trackIndex );
|
||||
auto startTrackType = tcoElement.attributeNode("trackType").value().toInt();
|
||||
Track * endTrack = tracks.at( finalTrackIndex );
|
||||
if( startTrack->type() != endTrack->type() )
|
||||
if( startTrackType != endTrack->type() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1407,7 +1415,7 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m
|
||||
*/
|
||||
bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de )
|
||||
{
|
||||
if( canPasteSelection( tcoPos, de->mimeData() ) == false )
|
||||
if( canPasteSelection( tcoPos, de ) == false )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1478,7 +1486,8 @@ bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de )
|
||||
tco->selectViewOnCreate( true );
|
||||
}
|
||||
//check tco name, if the same as source track name dont copy
|
||||
if( tco->name() == tracks[trackIndex]->name() )
|
||||
QString sourceTrackName = outerTCOElement.attributeNode( "trackName" ).value();
|
||||
if( tco->name() == sourceTrackName )
|
||||
{
|
||||
tco->setName( "" );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user