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:
Lukas W
2019-03-01 09:00:46 +01:00
parent dd6c18e62b
commit e1adfc3952
2 changed files with 19 additions and 10 deletions

View File

@@ -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 );

View File

@@ -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( "" );
}