From 2574067ad94913facfdda282e2ef5301e58963d3 Mon Sep 17 00:00:00 2001 From: Spekular Date: Mon, 23 Mar 2020 17:15:30 +0100 Subject: [PATCH 01/18] Dropdown edits, attempted refactor --- include/FileBrowser.h | 12 ++-- src/gui/FileBrowser.cpp | 125 +++++++++++++++++++++++++++------------- 2 files changed, 91 insertions(+), 46 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index d36eacf0775..da4dda6f9f3 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -109,7 +109,7 @@ class FileBrowserTreeWidget : public QTreeWidget private: void handleFile( FileItem * fi, InstrumentTrack * it ); - void openInNewInstrumentTrack( TrackContainer* tc ); + void openInNewInstrumentTrack( TrackContainer* tc, FileItem* item ); bool m_mousePressed; @@ -118,14 +118,16 @@ class FileBrowserTreeWidget : public QTreeWidget PlayHandle* m_previewPlayHandle; QMutex m_pphMutex; - FileItem * m_contextMenuItem; + void populateSampleMenu(QMenu& contextMenu, FileItem* item); + void populatePluginMenu(QMenu& contextMenu, FileItem* item); private slots: void activateListItem( QTreeWidgetItem * item, int column ); - void openInNewInstrumentTrackBBE( void ); - void openInNewInstrumentTrackSE( void ); - void sendToActiveInstrumentTrack( void ); + void openInNewInstrumentTrackBBE( FileItem* item ); + void openInNewInstrumentTrackSE( FileItem* item ); + void openInNewSampleTrack( FileItem* item ); + void sendToActiveInstrumentTrack( FileItem* item ); void updateDirectory( QTreeWidgetItem * item ); void openContainingFolder(); diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index b37bf03f207..b9d23f4dcee 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -322,8 +322,7 @@ FileBrowserTreeWidget::FileBrowserTreeWidget(QWidget * parent ) : m_mousePressed( false ), m_pressPos(), m_previewPlayHandle( NULL ), - m_pphMutex( QMutex::Recursive ), - m_contextMenuItem( NULL ) + m_pphMutex( QMutex::Recursive ) { setColumnCount( 1 ); headerItem()->setHidden( true ); @@ -364,42 +363,82 @@ QList FileBrowserTreeWidget::expandedDirs( QTreeWidgetItem * item ) con void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) { - FileItem * f = dynamic_cast(itemAt(e->pos())); - if (f == nullptr) + FileItem * file = dynamic_cast( itemAt( e->pos() ) ); + if( file != NULL ) { - return; + QMenu contextMenu( this ); + switch( file-> type() ) + { + case FileItem::SampleFile: + populateSampleMenu(contextMenu, file); + break; + default: + if ( file->handling() == FileItem::LoadByPlugin || + file->handling() == FileItem::LoadAsPreset) + { + populatePluginMenu(contextMenu, file); + } + } + if (!contextMenu.isEmpty()) { contextMenu.exec( e->globalPos() ); } } +} - if (f->handling() == FileItem::LoadAsPreset || f->handling() == FileItem::LoadByPlugin) - { - // Set the member to the current FileItem so that it is available during the - // execution of the slots of the context menu we are about to create and execute. - m_contextMenuItem = f; - - QMenu contextMenu(this); - - contextMenu.addAction(tr("Send to active instrument-track"), +void FileBrowserTreeWidget::populateSampleMenu(QMenu& contextMenu, FileItem* file) +{ + contextMenu.addAction( tr( "Send to active instrument-track" ), this, - SLOT(sendToActiveInstrumentTrack())); - contextMenu.addAction(tr("Open in new instrument-track/Song Editor"), + SLOT( sendToActiveInstrumentTrack(file) ) ); + + QAction *songEditorHeader = new QAction(tr("Song Editor")); + songEditorHeader->setDisabled(true); + contextMenu.addAction(songEditorHeader); + contextMenu.addAction( tr( "Send to new AFP Instance (Right Arrow)"), this, - SLOT(openInNewInstrumentTrackSE())); - contextMenu.addAction(tr("Open in new instrument-track/B+B Editor"), + SLOT( openInNewInstrumentTrackSE(file) ) ); + + QAction *bbEditorHeader = new QAction(tr("B+B Editor")); + bbEditorHeader->setDisabled(true); + contextMenu.addAction(bbEditorHeader); + contextMenu.addAction( tr("Send to new AFP Instance (Ctrl + Right Arrow)"), this, - SLOT(openInNewInstrumentTrackBBE())); + SLOT( openInNewInstrumentTrackBBE(file) ) ); + + contextMenu.addSeparator(); - contextMenu.addSeparator(); + contextMenu.addAction(QIcon(embed::getIconPixmap("folder")), + tr("Open containing folder"), + this, + SLOT(openContainingFolder())); - contextMenu.addAction(QIcon(embed::getIconPixmap("folder")), - tr("Open containing folder"), +} + +void FileBrowserTreeWidget::populatePluginMenu(QMenu& contextMenu, FileItem* file) +{ + contextMenu.addAction( tr( "Send to active instrument-track" ), this, - SLOT(openContainingFolder())); + SLOT( sendToActiveInstrumentTrack(file) ) ); - contextMenu.exec(e->globalPos()); + QAction *songEditorHeader = new QAction(tr("Song Editor")); + songEditorHeader->setDisabled(true); + contextMenu.addAction(songEditorHeader); + contextMenu.addAction( tr( "Send to new Instrument Track (Right Arrow)"), + this, + SLOT( openInNewInstrumentTrackSE(file) ) ); - // The context menu has been executed so we can reset this member back to nullptr. - m_contextMenuItem = nullptr; - } + QAction *bbEditorHeader = new QAction(tr("B+B Editor")); + bbEditorHeader->setDisabled(true); + contextMenu.addAction(bbEditorHeader); + contextMenu.addAction( tr( "Send to new Instrument Track " + "(Ctrl + Right Arrow)" ), + this, + SLOT( openInNewInstrumentTrackBBE(file) ) ); + + contextMenu.addSeparator(); + + contextMenu.addAction(QIcon(embed::getIconPixmap("folder")), + tr("Open containing folder"), + this, + SLOT(openContainingFolder())); } @@ -663,31 +702,31 @@ void FileBrowserTreeWidget::activateListItem(QTreeWidgetItem * item, -void FileBrowserTreeWidget::openInNewInstrumentTrack( TrackContainer* tc ) +void FileBrowserTreeWidget::openInNewInstrumentTrack( TrackContainer* tc, FileItem* item ) { - if( m_contextMenuItem->handling() == FileItem::LoadAsPreset || - m_contextMenuItem->handling() == FileItem::LoadByPlugin ) + if( item->handling() == FileItem::LoadAsPreset || + item->handling() == FileItem::LoadByPlugin ) { InstrumentTrack * it = dynamic_cast( Track::create( Track::InstrumentTrack, tc ) ); - handleFile( m_contextMenuItem, it ); + handleFile( item, it ); } } -void FileBrowserTreeWidget::openInNewInstrumentTrackBBE( void ) +void FileBrowserTreeWidget::openInNewInstrumentTrackBBE( FileItem* item ) { - openInNewInstrumentTrack( Engine::getBBTrackContainer() ); + openInNewInstrumentTrack( Engine::getBBTrackContainer(), item ); } -void FileBrowserTreeWidget::openInNewInstrumentTrackSE( void ) +void FileBrowserTreeWidget::openInNewInstrumentTrackSE( FileItem* item ) { - openInNewInstrumentTrack( Engine::getSong() ); + openInNewInstrumentTrack( Engine::getSong(), item ); } @@ -709,7 +748,15 @@ void FileBrowserTreeWidget::openContainingFolder() -void FileBrowserTreeWidget::sendToActiveInstrumentTrack( void ) +void FileBrowserTreeWidget::openInNewSampleTrack( FileItem* item ) +{ + +} + + + + +void FileBrowserTreeWidget::sendToActiveInstrumentTrack( FileItem* item ) { // get all windows opened in the workspace QList pl = @@ -726,7 +773,7 @@ void FileBrowserTreeWidget::sendToActiveInstrumentTrack( void ) w.previous()->widget() ); if( itw != NULL && itw->isHidden() == false ) { - handleFile( m_contextMenuItem, itw->model() ); + handleFile( item, itw->model() ); break; } } @@ -1111,7 +1158,3 @@ QString FileItem::extension(const QString & file ) { return QFileInfo( file ).suffix().toLower(); } - - - - From 50cc2519c550be337c8a1be79ab2d1c607f22977 Mon Sep 17 00:00:00 2001 From: Spekular Date: Mon, 23 Mar 2020 22:01:31 +0100 Subject: [PATCH 02/18] Working preview and add shortcuts --- include/FileBrowser.h | 15 +- src/gui/FileBrowser.cpp | 327 +++++++++++++++++++++++++--------------- 2 files changed, 217 insertions(+), 125 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index da4dda6f9f3..5a543504d18 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -99,6 +99,10 @@ class FileBrowserTreeWidget : public QTreeWidget //! that are expanded in the tree. QList expandedDirs( QTreeWidgetItem * item = nullptr ) const; + void tryAddSEInstrumentTrack(FileItem* file); + void tryAddBBInstrumentTrack(FileItem* file); + void previewFileItem(FileItem* file); + protected: void contextMenuEvent( QContextMenuEvent * e ) override; @@ -108,6 +112,8 @@ class FileBrowserTreeWidget : public QTreeWidget private: + void keyPressEvent( QKeyEvent * ke ) override; + void handleFile( FileItem * fi, InstrumentTrack * it ); void openInNewInstrumentTrack( TrackContainer* tc, FileItem* item ); @@ -118,8 +124,8 @@ class FileBrowserTreeWidget : public QTreeWidget PlayHandle* m_previewPlayHandle; QMutex m_pphMutex; - void populateSampleMenu(QMenu& contextMenu, FileItem* item); - void populatePluginMenu(QMenu& contextMenu, FileItem* item); + QList getContextActionsSE(FileItem* item); + QList getContextActionsBBE(FileItem* item); private slots: @@ -236,6 +242,11 @@ class FileItem : public QTreeWidgetItem return( m_handling ); } + inline bool isTrack( void ) const + { + return m_handling == LoadAsPreset || m_handling == LoadByPlugin; + } + QString extension( void ); static QString extension( const QString & file ); diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index b9d23f4dcee..f356f103f15 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -300,13 +300,12 @@ void FileBrowser::addItems(const QString & path ) void FileBrowser::keyPressEvent(QKeyEvent * ke ) { - if( ke->key() == Qt::Key_F5 ) - { - reloadTree(); - } - else - { - ke->ignore(); + switch( ke->key() ){ + case Qt::Key_F5: + reloadTree(); + break; + default: + ke->ignore(); } } @@ -337,6 +336,9 @@ FileBrowserTreeWidget::FileBrowserTreeWidget(QWidget * parent ) : } + + + QList FileBrowserTreeWidget::expandedDirs( QTreeWidgetItem * item ) const { int numChildren = item ? item->childCount() : topLevelItemCount(); @@ -361,84 +363,140 @@ QList FileBrowserTreeWidget::expandedDirs( QTreeWidgetItem * item ) con return dirs; } -void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) + + + +void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) { - FileItem * file = dynamic_cast( itemAt( e->pos() ) ); - if( file != NULL ) - { - QMenu contextMenu( this ); - switch( file-> type() ) - { - case FileItem::SampleFile: - populateSampleMenu(contextMenu, file); + auto selection = currentItem(); + FileItem * file = dynamic_cast( selection ); + + switch( ke->key() ){ + case Qt::Key_Up: + { + QTreeWidget::keyPressEvent(ke); + file = dynamic_cast( currentItem() ); + if (file != NULL && !ke->isAutoRepeat()) + { previewFileItem(file); } break; - default: - if ( file->handling() == FileItem::LoadByPlugin || - file->handling() == FileItem::LoadAsPreset) - { - populatePluginMenu(contextMenu, file); - } + } + case Qt::Key_Down: + { + QTreeWidget::keyPressEvent(ke); + file = dynamic_cast( currentItem() ); + if (file != NULL && !ke->isAutoRepeat()) + { previewFileItem(file); } + break; + } + case Qt::Key_Right: + { + if (!ke->isAutoRepeat()){ + if (!ke->modifiers()) + { tryAddSEInstrumentTrack(file); } + else if (ke->modifiers() & Qt::ControlModifier) + { tryAddBBInstrumentTrack(file); } + } + break; + } + case Qt::Key_Left: + { + if (file != NULL && !ke->isAutoRepeat()) + { previewFileItem(file); } } - if (!contextMenu.isEmpty()) { contextMenu.exec( e->globalPos() ); } + default: + if (!ke->isAutoRepeat() && ke->key() != Qt::Key_Left)//!ke->matches(QKeySequence::MoveToPreviousChar)) + { QTreeWidget::keyPressEvent(ke); } } + } -void FileBrowserTreeWidget::populateSampleMenu(QMenu& contextMenu, FileItem* file) + + + +void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) { - contextMenu.addAction( tr( "Send to active instrument-track" ), - this, - SLOT( sendToActiveInstrumentTrack(file) ) ); + FileItem * file = dynamic_cast( itemAt( e->pos() ) ); + if( file != NULL && (file->handling() == FileItem::LoadByPlugin || + file->handling() == FileItem::LoadAsPreset) ) + { + QMenu contextMenu( this ); - QAction *songEditorHeader = new QAction(tr("Song Editor")); - songEditorHeader->setDisabled(true); - contextMenu.addAction(songEditorHeader); - contextMenu.addAction( tr( "Send to new AFP Instance (Right Arrow)"), + QAction* toActiveInstrument = new QAction( + tr( "Send to active instrument-track" ) ); + connect(toActiveInstrument, &QAction::triggered, + [=]{ sendToActiveInstrumentTrack(file); }); + contextMenu.addAction( toActiveInstrument ); + + QAction* songEditorHeader = new QAction( tr("Song Editor") ); + songEditorHeader->setDisabled(true); + contextMenu.addAction( songEditorHeader ); + contextMenu.addActions( getContextActionsSE(file) ); + + QAction* bbEditorHeader = new QAction( tr("BB Editor") ); + bbEditorHeader->setDisabled(true); + contextMenu.addAction( bbEditorHeader ); + contextMenu.addActions( getContextActionsBBE(file) ); + + contextMenu.addSeparator(); + + contextMenu.addAction(QIcon(embed::getIconPixmap("folder")), + tr("Open containing folder"), this, - SLOT( openInNewInstrumentTrackSE(file) ) ); + SLOT(openContainingFolder())); + + //If all we have is the first action + two headers, the item isn't + //valid, so we shouldn't show the menu + if (!contextMenu.isEmpty()) + { contextMenu.exec( e->globalPos() ); } + } +} - QAction *bbEditorHeader = new QAction(tr("B+B Editor")); - bbEditorHeader->setDisabled(true); - contextMenu.addAction(bbEditorHeader); - contextMenu.addAction( tr("Send to new AFP Instance (Ctrl + Right Arrow)"), - this, - SLOT( openInNewInstrumentTrackBBE(file) ) ); - - contextMenu.addSeparator(); - contextMenu.addAction(QIcon(embed::getIconPixmap("folder")), - tr("Open containing folder"), - this, - SLOT(openContainingFolder())); -} -void FileBrowserTreeWidget::populatePluginMenu(QMenu& contextMenu, FileItem* file) +QList FileBrowserTreeWidget::getContextActionsSE(FileItem* file) { - contextMenu.addAction( tr( "Send to active instrument-track" ), - this, - SLOT( sendToActiveInstrumentTrack(file) ) ); + QList result = QList(); + if (file->type() == FileItem::SampleFile) + { + QAction* toAFP = new QAction( + tr("Send to new AFP Instance (Right Arrow)") ); + connect(toAFP, &QAction::triggered, + [=]{ openInNewInstrumentTrackSE(file); }); + result.append(toAFP); + } + else { + QAction* toInstrument = new QAction( + tr("Send to new Instrument Track (Right Arrow)") ); + connect(toInstrument, &QAction::triggered, + [=]{ openInNewInstrumentTrackSE(file); }); + result.append(toInstrument); + } + return result; +} - QAction *songEditorHeader = new QAction(tr("Song Editor")); - songEditorHeader->setDisabled(true); - contextMenu.addAction(songEditorHeader); - contextMenu.addAction( tr( "Send to new Instrument Track (Right Arrow)"), - this, - SLOT( openInNewInstrumentTrackSE(file) ) ); - QAction *bbEditorHeader = new QAction(tr("B+B Editor")); - bbEditorHeader->setDisabled(true); - contextMenu.addAction(bbEditorHeader); - contextMenu.addAction( tr( "Send to new Instrument Track " - "(Ctrl + Right Arrow)" ), - this, - SLOT( openInNewInstrumentTrackBBE(file) ) ); - - contextMenu.addSeparator(); - - contextMenu.addAction(QIcon(embed::getIconPixmap("folder")), - tr("Open containing folder"), - this, - SLOT(openContainingFolder())); + + +QList FileBrowserTreeWidget::getContextActionsBBE(FileItem* file) +{ + QList result = QList(); + if (file->type() == FileItem::SampleFile) + { + QAction* toAFP = new QAction( + tr("Send to new AFP Instance (Ctrl + Right Arrow)") ); + connect(toAFP, &QAction::triggered, + [=]{ openInNewInstrumentTrackBBE(file); }); + result.append(toAFP); + } + else { + QAction* toInstrument = new QAction( + tr("Send to new Instrument Track (Ctrl + Right Arrow)") ); + connect(toInstrument, &QAction::triggered, + [=]{ openInNewInstrumentTrackBBE(file); }); + result.append(toInstrument); + } + return result; } @@ -470,66 +528,73 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) FileItem * f = dynamic_cast( i ); if( f != NULL ) { - m_pphMutex.lock(); - if( m_previewPlayHandle != NULL ) - { - Engine::mixer()->removePlayHandle( - m_previewPlayHandle ); - m_previewPlayHandle = NULL; - } + previewFileItem(f); + } +} - // in special case of sample-files we do not care about - // handling() rather than directly creating a SamplePlayHandle - if( f->type() == FileItem::SampleFile ) - { - TextFloat * tf = TextFloat::displayMessage( - tr( "Loading sample" ), - tr( "Please wait, loading sample for " - "preview..." ), - embed::getIconPixmap( "sample_file", - 24, 24 ), 0 ); - qApp->processEvents( - QEventLoop::ExcludeUserInputEvents ); - SamplePlayHandle * s = new SamplePlayHandle( - f->fullName() ); - s->setDoneMayReturnTrue( false ); - m_previewPlayHandle = s; - delete tf; - } - else if ( ( f->extension ()== "xiz" || f->extension() == "sf2" || f->extension() == "sf3" || f->extension() == "gig" || f->extension() == "pat" -#ifdef LMMS_HAVE_LV2 - || f->extension() == "lv2" -#endif - ) && - ! pluginFactory->pluginSupportingExtension(f->extension()).info.isNull() ) - { - m_previewPlayHandle = new PresetPreviewPlayHandle( f->fullName(), f->handling() == FileItem::LoadByPlugin ); - } - else if( f->type() != FileItem::VstPluginFile && - ( f->handling() == FileItem::LoadAsPreset || - f->handling() == FileItem::LoadByPlugin ) ) + + + +void FileBrowserTreeWidget::previewFileItem(FileItem* file) +{ + m_pphMutex.lock(); + if( m_previewPlayHandle != NULL ) + { + Engine::mixer()->removePlayHandle( + m_previewPlayHandle ); + m_previewPlayHandle = NULL; + } + + // in special case of sample-files we do not care about + // handling() rather than directly creating a SamplePlayHandle + if( file->type() == FileItem::SampleFile ) + { + TextFloat * tf = TextFloat::displayMessage( + tr( "Loading sample" ), + tr( "Please wait, loading sample for " + "preview..." ), + embed::getIconPixmap( "sample_file", + 24, 24 ), 0 ); + qApp->processEvents( + QEventLoop::ExcludeUserInputEvents ); + SamplePlayHandle * s = new SamplePlayHandle( file->fullName() ); + s->setDoneMayReturnTrue( false ); + m_previewPlayHandle = s; + delete tf; + } + else if( + ( file->extension ()== "xiz" || file->extension() == "sf2" || + file->extension() == "sf3" || file->extension() == "gig" || + file ->extension() == "pat" ) && + ! pluginFactory->pluginSupportingExtension(file->extension()).info.isNull() ) + { + m_previewPlayHandle = new PresetPreviewPlayHandle( + file->fullName(), file->handling() == FileItem::LoadByPlugin ); + } + else if( file->type() != FileItem::VstPluginFile && + ( file->handling() == FileItem::LoadAsPreset || + file->handling() == FileItem::LoadByPlugin ) ) + { + DataFile dataFile( file->fullName() ); + if( !dataFile.validate( file->extension() ) ) { - DataFile dataFile( f->fullName() ); - if( !dataFile.validate( f->extension() ) ) - { - QMessageBox::warning( 0, tr ( "Error" ), - tr( "%1 does not appear to be a valid %2 file" ).arg( f->fullName(), f->extension() ), - QMessageBox::Ok, QMessageBox::NoButton ); - m_pphMutex.unlock(); - return; - } - m_previewPlayHandle = new PresetPreviewPlayHandle( f->fullName(), f->handling() == FileItem::LoadByPlugin, &dataFile ); + QMessageBox::warning( 0, tr ( "Error" ), + tr( "%1 does not appear to be a valid %2 file" ).arg( file->fullName(), file->extension() ), + QMessageBox::Ok, QMessageBox::NoButton ); + m_pphMutex.unlock(); + return; } - if( m_previewPlayHandle != NULL ) + m_previewPlayHandle = new PresetPreviewPlayHandle( file->fullName(), file->handling() == FileItem::LoadByPlugin, &dataFile ); + } + if( m_previewPlayHandle != NULL ) + { + if( !Engine::mixer()->addPlayHandle( + m_previewPlayHandle ) ) { - if( !Engine::mixer()->addPlayHandle( - m_previewPlayHandle ) ) - { - m_previewPlayHandle = NULL; - } + m_previewPlayHandle = NULL; } - m_pphMutex.unlock(); } + m_pphMutex.unlock(); } @@ -748,6 +813,22 @@ void FileBrowserTreeWidget::openContainingFolder() +void FileBrowserTreeWidget::tryAddSEInstrumentTrack(FileItem* file) +{ + if (file != NULL && file->isTrack()){ openInNewInstrumentTrackSE(file); } +} + + + + +void FileBrowserTreeWidget::tryAddBBInstrumentTrack(FileItem* file) +{ + if (file != NULL && file->isTrack()){ openInNewInstrumentTrackBBE(file); } +} + + + + void FileBrowserTreeWidget::openInNewSampleTrack( FileItem* item ) { From 87c51f6b270d92467eff03e8c8f1129232007570 Mon Sep 17 00:00:00 2001 From: Spekular Date: Mon, 23 Mar 2020 22:09:33 +0100 Subject: [PATCH 03/18] Cleanup --- src/gui/FileBrowser.cpp | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index f356f103f15..17f059d4483 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -390,11 +390,11 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) } case Qt::Key_Right: { - if (!ke->isAutoRepeat()){ + if (!ke->isAutoRepeat() && file != NULL){ if (!ke->modifiers()) - { tryAddSEInstrumentTrack(file); } + { openInNewInstrumentTrackSE(file); } else if (ke->modifiers() & Qt::ControlModifier) - { tryAddBBInstrumentTrack(file); } + { openInNewInstrumentTrackBBE(file); } } break; } @@ -416,8 +416,7 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) { FileItem * file = dynamic_cast( itemAt( e->pos() ) ); - if( file != NULL && (file->handling() == FileItem::LoadByPlugin || - file->handling() == FileItem::LoadAsPreset) ) + if( file != NULL && file->isTrack() ) { QMenu contextMenu( this ); @@ -571,9 +570,7 @@ void FileBrowserTreeWidget::previewFileItem(FileItem* file) m_previewPlayHandle = new PresetPreviewPlayHandle( file->fullName(), file->handling() == FileItem::LoadByPlugin ); } - else if( file->type() != FileItem::VstPluginFile && - ( file->handling() == FileItem::LoadAsPreset || - file->handling() == FileItem::LoadByPlugin ) ) + else if( file->type() != FileItem::VstPluginFile && file->isTrack() ) { DataFile dataFile( file->fullName() ); if( !dataFile.validate( file->extension() ) ) @@ -769,8 +766,7 @@ void FileBrowserTreeWidget::activateListItem(QTreeWidgetItem * item, void FileBrowserTreeWidget::openInNewInstrumentTrack( TrackContainer* tc, FileItem* item ) { - if( item->handling() == FileItem::LoadAsPreset || - item->handling() == FileItem::LoadByPlugin ) + if( item->isTrack() ) { InstrumentTrack * it = dynamic_cast( Track::create( Track::InstrumentTrack, tc ) ); @@ -813,22 +809,6 @@ void FileBrowserTreeWidget::openContainingFolder() -void FileBrowserTreeWidget::tryAddSEInstrumentTrack(FileItem* file) -{ - if (file != NULL && file->isTrack()){ openInNewInstrumentTrackSE(file); } -} - - - - -void FileBrowserTreeWidget::tryAddBBInstrumentTrack(FileItem* file) -{ - if (file != NULL && file->isTrack()){ openInNewInstrumentTrackBBE(file); } -} - - - - void FileBrowserTreeWidget::openInNewSampleTrack( FileItem* item ) { From e0e1f1c4268b8bbb9d672dc9891a799e5f5c1584 Mon Sep 17 00:00:00 2001 From: Spekular Date: Wed, 23 Sep 2020 17:00:17 +0200 Subject: [PATCH 04/18] Fixes after merge --- include/FileBrowser.h | 2 +- src/gui/FileBrowser.cpp | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index 5a543504d18..7f38ab4d374 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -135,7 +135,7 @@ private slots: void openInNewSampleTrack( FileItem* item ); void sendToActiveInstrumentTrack( FileItem* item ); void updateDirectory( QTreeWidgetItem * item ); - void openContainingFolder(); + void openContainingFolder( FileItem* item ); } ; diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 17f059d4483..0fb2404feec 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -438,10 +438,13 @@ void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) contextMenu.addSeparator(); - contextMenu.addAction(QIcon(embed::getIconPixmap("folder")), - tr("Open containing folder"), - this, - SLOT(openContainingFolder())); + QAction* openFolder = new QAction( + QIcon(embed::getIconPixmap("folder")), + tr("Open containing folder") + ); + connect(openFolder, &QAction::triggered, + [=]{ openContainingFolder(file); }); + contextMenu.addAction(openFolder); //If all we have is the first action + two headers, the item isn't //valid, so we shouldn't show the menu @@ -792,19 +795,16 @@ void FileBrowserTreeWidget::openInNewInstrumentTrackSE( FileItem* item ) -void FileBrowserTreeWidget::openContainingFolder() +void FileBrowserTreeWidget::openContainingFolder(FileItem* item) { - if (m_contextMenuItem) - { - // Delegate to QDesktopServices::openUrl with the directory of the selected file. Please note that - // this will only open the directory but not select the file as this is much more complicated due - // to different implementations that are needed for different platforms (Linux/Windows/MacOS). - - // Using QDesktopServices::openUrl seems to be the most simple cross platform way which uses - // functionality that's already available in Qt. - QFileInfo fileInfo(m_contextMenuItem->fullName()); - QDesktopServices::openUrl(QUrl::fromLocalFile(fileInfo.dir().path())); - } + // Delegate to QDesktopServices::openUrl with the directory of the selected file. Please note that + // this will only open the directory but not select the file as this is much more complicated due + // to different implementations that are needed for different platforms (Linux/Windows/MacOS). + + // Using QDesktopServices::openUrl seems to be the most simple cross platform way which uses + // functionality that's already available in Qt. + QFileInfo fileInfo(item->fullName()); + QDesktopServices::openUrl(QUrl::fromLocalFile(fileInfo.dir().path())); } From 88f57b49af203f259bf113aa5b8dd960c62ee6df Mon Sep 17 00:00:00 2001 From: Spekular Date: Wed, 23 Sep 2020 20:51:28 +0200 Subject: [PATCH 05/18] DRY up code and prevent endless previews --- include/FileBrowser.h | 13 +- src/gui/FileBrowser.cpp | 259 ++++++++++++++++++---------------------- 2 files changed, 125 insertions(+), 147 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index 7f38ab4d374..28265d8705f 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -101,7 +101,6 @@ class FileBrowserTreeWidget : public QTreeWidget void tryAddSEInstrumentTrack(FileItem* file); void tryAddBBInstrumentTrack(FileItem* file); - void previewFileItem(FileItem* file); protected: @@ -112,7 +111,13 @@ class FileBrowserTreeWidget : public QTreeWidget private: + //Preview a file + void previewFileItem(FileItem* file); + //If a preview is playing, stop it and return true. Otherwise return false + bool stopPreview(); + void keyPressEvent( QKeyEvent * ke ) override; + void keyReleaseEvent( QKeyEvent * ke ) override; void handleFile( FileItem * fi, InstrumentTrack * it ); void openInNewInstrumentTrack( TrackContainer* tc, FileItem* item ); @@ -124,14 +129,12 @@ class FileBrowserTreeWidget : public QTreeWidget PlayHandle* m_previewPlayHandle; QMutex m_pphMutex; - QList getContextActionsSE(FileItem* item); - QList getContextActionsBBE(FileItem* item); + QList getContextActions(FileItem* item, bool songEditor); private slots: void activateListItem( QTreeWidgetItem * item, int column ); - void openInNewInstrumentTrackBBE( FileItem* item ); - void openInNewInstrumentTrackSE( FileItem* item ); + void openInNewInstrumentTrack( FileItem* item, bool songEditor ); void openInNewSampleTrack( FileItem* item ); void sendToActiveInstrumentTrack( FileItem* item ); void updateDirectory( QTreeWidgetItem * item ); diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 0fb2404feec..6024b31b320 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -368,46 +368,48 @@ QList FileBrowserTreeWidget::expandedDirs( QTreeWidgetItem * item ) con void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) { - auto selection = currentItem(); - FileItem * file = dynamic_cast( selection ); - - switch( ke->key() ){ - case Qt::Key_Up: - { - QTreeWidget::keyPressEvent(ke); - file = dynamic_cast( currentItem() ); - if (file != NULL && !ke->isAutoRepeat()) - { previewFileItem(file); } - break; - } - case Qt::Key_Down: - { - QTreeWidget::keyPressEvent(ke); - file = dynamic_cast( currentItem() ); - if (file != NULL && !ke->isAutoRepeat()) - { previewFileItem(file); } - break; - } - case Qt::Key_Right: - { - if (!ke->isAutoRepeat() && file != NULL){ - if (!ke->modifiers()) - { openInNewInstrumentTrackSE(file); } - else if (ke->modifiers() & Qt::ControlModifier) - { openInNewInstrumentTrackBBE(file); } - } - break; - } - case Qt::Key_Left: - { - if (file != NULL && !ke->isAutoRepeat()) - { previewFileItem(file); } - } - default: - if (!ke->isAutoRepeat() && ke->key() != Qt::Key_Left)//!ke->matches(QKeySequence::MoveToPreviousChar)) - { QTreeWidget::keyPressEvent(ke); } + // Convenient things to check + const auto key = ke->key(); + const bool vertical = key == Qt::Key_Up || key == Qt::Key_Down; + const bool horizontal = key == Qt::Key_Left || key == Qt::Key_Right; + + if (vertical || horizontal){ stopPreview(); } + + // We hijack left/right for preview/add, so don't let them navigate the tree + if (!horizontal){ QTreeWidget::keyPressEvent(ke); } + // We don't want to spam previews or track addition when a key is held + if (ke->isAutoRepeat()){ return; } + + // The currently selected file item + FileItem * file = dynamic_cast(currentItem()); + // If it's null, there's nothing for us to do + if (file == NULL){ return; } + + // On navigation up/down, preview samples + // Don't automatically preview presets, because they can play forever + if (vertical && file->type() == FileItem::SampleFile) + { + previewFileItem(file); } + + //On right arrow pressed, add the item + if (key == Qt::Key_Right) + { + bool songEditor = !(ke->modifiers() & Qt::ControlModifier); + openInNewInstrumentTrack(file, songEditor); + } + + //On left arrow pressed, start previewing the item + if (key == Qt::Key_Left) { previewFileItem(file); } +} + + + +void FileBrowserTreeWidget::keyReleaseEvent(QKeyEvent * ke ) +{ + //Cancel previews when the left key is released + if (ke->key() == Qt::Key_Left && !ke->isAutoRepeat()){ stopPreview(); } } @@ -429,12 +431,12 @@ void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) QAction* songEditorHeader = new QAction( tr("Song Editor") ); songEditorHeader->setDisabled(true); contextMenu.addAction( songEditorHeader ); - contextMenu.addActions( getContextActionsSE(file) ); + contextMenu.addActions( getContextActions(file, true) ); QAction* bbEditorHeader = new QAction( tr("BB Editor") ); bbEditorHeader->setDisabled(true); contextMenu.addAction( bbEditorHeader ); - contextMenu.addActions( getContextActionsBBE(file) ); + contextMenu.addActions( getContextActions(file, false) ); contextMenu.addSeparator(); @@ -456,48 +458,20 @@ void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) -QList FileBrowserTreeWidget::getContextActionsSE(FileItem* file) -{ - QList result = QList(); - if (file->type() == FileItem::SampleFile) - { - QAction* toAFP = new QAction( - tr("Send to new AFP Instance (Right Arrow)") ); - connect(toAFP, &QAction::triggered, - [=]{ openInNewInstrumentTrackSE(file); }); - result.append(toAFP); - } - else { - QAction* toInstrument = new QAction( - tr("Send to new Instrument Track (Right Arrow)") ); - connect(toInstrument, &QAction::triggered, - [=]{ openInNewInstrumentTrackSE(file); }); - result.append(toInstrument); - } - return result; -} - - - - -QList FileBrowserTreeWidget::getContextActionsBBE(FileItem* file) +QList FileBrowserTreeWidget::getContextActions(FileItem* file, bool songEditor) { QList result = QList(); - if (file->type() == FileItem::SampleFile) - { - QAction* toAFP = new QAction( - tr("Send to new AFP Instance (Ctrl + Right Arrow)") ); - connect(toAFP, &QAction::triggered, - [=]{ openInNewInstrumentTrackBBE(file); }); - result.append(toAFP); - } - else { - QAction* toInstrument = new QAction( - tr("Send to new Instrument Track (Ctrl + Right Arrow)") ); - connect(toInstrument, &QAction::triggered, - [=]{ openInNewInstrumentTrackBBE(file); }); - result.append(toInstrument); - } + + QString destination = (file->type() == FileItem::SampleFile) ? + "AFP Instance" : "Instrument Track"; + QString shortcutMod = songEditor ? "" : "Ctrl + "; + + QAction* toInstrument = new QAction( + tr("Send to new %1 (%2Right Arrow)").arg(destination, shortcutMod)); + connect(toInstrument, &QAction::triggered, + [=]{ openInNewInstrumentTrack(file, songEditor); }); + result.append(toInstrument); + return result; } @@ -506,14 +480,13 @@ QList FileBrowserTreeWidget::getContextActionsBBE(FileItem* file) void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) { - QTreeWidget::mousePressEvent( me ); - if( me->button() != Qt::LeftButton ) - { - return; - } + // Forward the event + QTreeWidget::mousePressEvent(me); + // QTreeWidget handles right clicks for us, so we only care about left clicks + if(me->button() != Qt::LeftButton){ return; } - QTreeWidgetItem * i = itemAt( me->pos() ); - if ( i ) + QTreeWidgetItem * i = itemAt(me->pos()); + if (i) { // TODO: Restrict to visible selection // if ( _me->x() > header()->cellPos( header()->mapToActual( 0 ) ) @@ -527,11 +500,8 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) // } } - FileItem * f = dynamic_cast( i ); - if( f != NULL ) - { - previewFileItem(f); - } + FileItem * f = dynamic_cast(i); + if(f != NULL){ previewFileItem(f); } } @@ -540,56 +510,51 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) void FileBrowserTreeWidget::previewFileItem(FileItem* file) { m_pphMutex.lock(); - if( m_previewPlayHandle != NULL ) - { - Engine::mixer()->removePlayHandle( - m_previewPlayHandle ); - m_previewPlayHandle = NULL; - } + //If something is already playing, stop it + stopPreview(); // in special case of sample-files we do not care about // handling() rather than directly creating a SamplePlayHandle - if( file->type() == FileItem::SampleFile ) + if(file->type() == FileItem::SampleFile) { TextFloat * tf = TextFloat::displayMessage( - tr( "Loading sample" ), - tr( "Please wait, loading sample for " - "preview..." ), - embed::getIconPixmap( "sample_file", - 24, 24 ), 0 ); - qApp->processEvents( - QEventLoop::ExcludeUserInputEvents ); - SamplePlayHandle * s = new SamplePlayHandle( file->fullName() ); - s->setDoneMayReturnTrue( false ); + tr("Loading sample"), + tr("Please wait, loading sample for preview..."), + embed::getIconPixmap("sample_file", 24, 24), 0); + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); + SamplePlayHandle * s = new SamplePlayHandle(file->fullName()); + s->setDoneMayReturnTrue(false); m_previewPlayHandle = s; delete tf; } else if( - ( file->extension ()== "xiz" || file->extension() == "sf2" || - file->extension() == "sf3" || file->extension() == "gig" || - file ->extension() == "pat" ) && - ! pluginFactory->pluginSupportingExtension(file->extension()).info.isNull() ) + (file->extension() == "xiz" || file->extension() == "sf2" || + file->extension() == "sf3" || file->extension() == "gig" || + file ->extension() == "pat") && + !pluginFactory->pluginSupportingExtension(file->extension()).info.isNull()) { m_previewPlayHandle = new PresetPreviewPlayHandle( - file->fullName(), file->handling() == FileItem::LoadByPlugin ); + file->fullName(), file->handling() == FileItem::LoadByPlugin); } - else if( file->type() != FileItem::VstPluginFile && file->isTrack() ) + else if(file->type() != FileItem::VstPluginFile && file->isTrack()) { - DataFile dataFile( file->fullName() ); - if( !dataFile.validate( file->extension() ) ) + DataFile dataFile(file->fullName()); + if(!dataFile.validate(file->extension())) { - QMessageBox::warning( 0, tr ( "Error" ), - tr( "%1 does not appear to be a valid %2 file" ).arg( file->fullName(), file->extension() ), - QMessageBox::Ok, QMessageBox::NoButton ); + QMessageBox::warning(0, tr ("Error"), + tr("%1 does not appear to be a valid %2 file") + .arg(file->fullName(), file->extension()), + QMessageBox::Ok, QMessageBox::NoButton); m_pphMutex.unlock(); return; } - m_previewPlayHandle = new PresetPreviewPlayHandle( file->fullName(), file->handling() == FileItem::LoadByPlugin, &dataFile ); + m_previewPlayHandle = new PresetPreviewPlayHandle( + file->fullName(), file->handling() == FileItem::LoadByPlugin, &dataFile + ); } - if( m_previewPlayHandle != NULL ) + if(m_previewPlayHandle != NULL) { - if( !Engine::mixer()->addPlayHandle( - m_previewPlayHandle ) ) + if(!Engine::mixer()->addPlayHandle(m_previewPlayHandle)) { m_previewPlayHandle = NULL; } @@ -600,6 +565,22 @@ void FileBrowserTreeWidget::previewFileItem(FileItem* file) +bool FileBrowserTreeWidget::stopPreview() +{ + if (m_previewPlayHandle != NULL) + { + m_pphMutex.lock(); + Engine::mixer()->removePlayHandle(m_previewPlayHandle); + m_previewPlayHandle = NULL; + m_pphMutex.unlock(); + return true; + } + else { return false; } +} + + + + void FileBrowserTreeWidget::mouseMoveEvent( QMouseEvent * me ) { if( m_mousePressed == true && @@ -661,26 +642,24 @@ void FileBrowserTreeWidget::mouseReleaseEvent(QMouseEvent * me ) m_mousePressed = false; m_pphMutex.lock(); - if( m_previewPlayHandle != NULL ) + if(m_previewPlayHandle != NULL) { // if there're samples shorter than 3 seconds, we don't // stop them if the user releases mouse-button... - if( m_previewPlayHandle->type() == PlayHandle::TypeSamplePlayHandle ) + if(m_previewPlayHandle->type() == PlayHandle::TypeSamplePlayHandle) { - SamplePlayHandle * s = dynamic_cast( - m_previewPlayHandle ); - if( s && s->totalFrames() - s->framesDone() <= - static_cast( Engine::mixer()-> - processingSampleRate() * 3 ) ) + SamplePlayHandle * s = dynamic_cast(m_previewPlayHandle); + if(s && s->totalFrames() - s->framesDone() <= + static_cast(Engine::mixer()-> + processingSampleRate() * 3)) { - s->setDoneMayReturnTrue( true ); + s->setDoneMayReturnTrue(true); m_previewPlayHandle = NULL; m_pphMutex.unlock(); return; } } - Engine::mixer()->removePlayHandle( m_previewPlayHandle ); - m_previewPlayHandle = NULL; + else { stopPreview(); } } m_pphMutex.unlock(); } @@ -780,21 +759,17 @@ void FileBrowserTreeWidget::openInNewInstrumentTrack( TrackContainer* tc, FileIt -void FileBrowserTreeWidget::openInNewInstrumentTrackBBE( FileItem* item ) +void FileBrowserTreeWidget::openInNewInstrumentTrack(FileItem* item, bool songEditor) { - openInNewInstrumentTrack( Engine::getBBTrackContainer(), item ); + //Ternary doesn't compile here so do it the long way + TrackContainer* tc = Engine::getSong(); + if (!songEditor) { tc = Engine::getBBTrackContainer(); } + openInNewInstrumentTrack(tc, item); } -void FileBrowserTreeWidget::openInNewInstrumentTrackSE( FileItem* item ) -{ - openInNewInstrumentTrack( Engine::getSong(), item ); -} - - - void FileBrowserTreeWidget::openContainingFolder(FileItem* item) { // Delegate to QDesktopServices::openUrl with the directory of the selected file. Please note that From 7e3eb83ed54d02092a973ab51cb9af266d3a8918 Mon Sep 17 00:00:00 2001 From: Spekular Date: Wed, 23 Sep 2020 21:59:10 +0200 Subject: [PATCH 06/18] Initial send to new sample track implementation --- include/FileBrowser.h | 2 +- src/gui/FileBrowser.cpp | 49 ++++++++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index 28265d8705f..cf958893edf 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -135,7 +135,7 @@ class FileBrowserTreeWidget : public QTreeWidget private slots: void activateListItem( QTreeWidgetItem * item, int column ); void openInNewInstrumentTrack( FileItem* item, bool songEditor ); - void openInNewSampleTrack( FileItem* item ); + bool openInNewSampleTrack( FileItem* item, bool songEditor ); void sendToActiveInstrumentTrack( FileItem* item ); void updateDirectory( QTreeWidgetItem * item ); void openContainingFolder( FileItem* item ); diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 6024b31b320..84866f94927 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -50,6 +50,7 @@ #include "PluginFactory.h" #include "PresetPreviewPlayHandle.h" #include "SamplePlayHandle.h" +#include "SampleTrack.h" #include "Song.h" #include "StringPairDrag.h" #include "TextFloat.h" @@ -396,7 +397,8 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) if (key == Qt::Key_Right) { bool songEditor = !(ke->modifiers() & Qt::ControlModifier); - openInNewInstrumentTrack(file, songEditor); + if (ke->modifiers() & Qt::ShiftModifier){ openInNewSampleTrack(file, songEditor); } + else { openInNewInstrumentTrack(file, songEditor); } } //On left arrow pressed, start previewing the item @@ -668,7 +670,7 @@ void FileBrowserTreeWidget::mouseReleaseEvent(QMouseEvent * me ) -void FileBrowserTreeWidget::handleFile(FileItem * f, InstrumentTrack * it ) +void FileBrowserTreeWidget::handleFile(FileItem * f, InstrumentTrack * it) { Engine::mixer()->requestChangeInModel(); switch( f->handling() ) @@ -746,13 +748,13 @@ void FileBrowserTreeWidget::activateListItem(QTreeWidgetItem * item, -void FileBrowserTreeWidget::openInNewInstrumentTrack( TrackContainer* tc, FileItem* item ) +void FileBrowserTreeWidget::openInNewInstrumentTrack(TrackContainer* tc, FileItem* item) { - if( item->isTrack() ) + if(item->isTrack()) { InstrumentTrack * it = dynamic_cast( - Track::create( Track::InstrumentTrack, tc ) ); - handleFile( item, it ); + Track::create(Track::InstrumentTrack, tc)); + handleFile(item, it); } } @@ -761,15 +763,39 @@ void FileBrowserTreeWidget::openInNewInstrumentTrack( TrackContainer* tc, FileIt void FileBrowserTreeWidget::openInNewInstrumentTrack(FileItem* item, bool songEditor) { - //Ternary doesn't compile here so do it the long way + //Get the correcy TrackContainer, ternary doesn't compile here so do it the long way TrackContainer* tc = Engine::getSong(); - if (!songEditor) { tc = Engine::getBBTrackContainer(); } + if (!songEditor){ tc = Engine::getBBTrackContainer(); } openInNewInstrumentTrack(tc, item); } +bool FileBrowserTreeWidget::openInNewSampleTrack(FileItem* item, bool songEditor) +{ + // Can't add non-samples to a sample track + if (item->type() != FileItem::SampleFile){ return false; } + if (!songEditor){ } + + TrackContainer* trackContainer = Engine::getSong(); + if (!songEditor){ trackContainer = Engine::getBBTrackContainer(); } + + // Create a new sample track for this sample + SampleTrack* sampleTrack = dynamic_cast( + Track::create(Track::SampleTrack, trackContainer)); + + // Add the sample clip to the track + Engine::mixer()->requestChangeInModel(); + SampleTCO* clip = dynamic_cast(sampleTrack->createTCO(0)); + clip->setSampleFile(item->fullName()); + Engine::mixer()->doneChangeInModel(); + return true; +} + + + + void FileBrowserTreeWidget::openContainingFolder(FileItem* item) { // Delegate to QDesktopServices::openUrl with the directory of the selected file. Please note that @@ -784,13 +810,6 @@ void FileBrowserTreeWidget::openContainingFolder(FileItem* item) -void FileBrowserTreeWidget::openInNewSampleTrack( FileItem* item ) -{ - -} - - - void FileBrowserTreeWidget::sendToActiveInstrumentTrack( FileItem* item ) { From 69ae7d1cba83ce6bd676ebaf285c805f9273710c Mon Sep 17 00:00:00 2001 From: Spekular Date: Wed, 23 Sep 2020 22:13:45 +0200 Subject: [PATCH 07/18] Don't send sample tracks to BB Editor --- include/FileBrowser.h | 2 +- src/gui/FileBrowser.cpp | 52 +++++++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index cf958893edf..7169fea6e96 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -135,7 +135,7 @@ class FileBrowserTreeWidget : public QTreeWidget private slots: void activateListItem( QTreeWidgetItem * item, int column ); void openInNewInstrumentTrack( FileItem* item, bool songEditor ); - bool openInNewSampleTrack( FileItem* item, bool songEditor ); + bool openInNewSampleTrack( FileItem* item ); void sendToActiveInstrumentTrack( FileItem* item ); void updateDirectory( QTreeWidgetItem * item ); void openContainingFolder( FileItem* item ); diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 84866f94927..f41d4b29c09 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -373,13 +373,13 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) const auto key = ke->key(); const bool vertical = key == Qt::Key_Up || key == Qt::Key_Down; const bool horizontal = key == Qt::Key_Left || key == Qt::Key_Right; - - if (vertical || horizontal){ stopPreview(); } // We hijack left/right for preview/add, so don't let them navigate the tree if (!horizontal){ QTreeWidget::keyPressEvent(ke); } // We don't want to spam previews or track addition when a key is held - if (ke->isAutoRepeat()){ return; } + if (ke->isAutoRepeat()){ return; } + // We should stop previews before we do anything new + if (vertical || horizontal){ stopPreview(); } // The currently selected file item FileItem * file = dynamic_cast(currentItem()); @@ -397,8 +397,10 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) if (key == Qt::Key_Right) { bool songEditor = !(ke->modifiers() & Qt::ControlModifier); - if (ke->modifiers() & Qt::ShiftModifier){ openInNewSampleTrack(file, songEditor); } - else { openInNewInstrumentTrack(file, songEditor); } + bool sampleTrack = ke->modifiers() & Qt::ShiftModifier; + //We can only send to sample tracks in the song editor + if (sampleTrack && songEditor){ openInNewSampleTrack(file); } + else if (!sampleTrack){ openInNewInstrumentTrack(file, songEditor); } } //On left arrow pressed, start previewing the item @@ -429,16 +431,6 @@ void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) connect(toActiveInstrument, &QAction::triggered, [=]{ sendToActiveInstrumentTrack(file); }); contextMenu.addAction( toActiveInstrument ); - - QAction* songEditorHeader = new QAction( tr("Song Editor") ); - songEditorHeader->setDisabled(true); - contextMenu.addAction( songEditorHeader ); - contextMenu.addActions( getContextActions(file, true) ); - - QAction* bbEditorHeader = new QAction( tr("BB Editor") ); - bbEditorHeader->setDisabled(true); - contextMenu.addAction( bbEditorHeader ); - contextMenu.addActions( getContextActions(file, false) ); contextMenu.addSeparator(); @@ -450,6 +442,16 @@ void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) [=]{ openContainingFolder(file); }); contextMenu.addAction(openFolder); + QAction* songEditorHeader = new QAction( tr("Song Editor") ); + songEditorHeader->setDisabled(true); + contextMenu.addAction( songEditorHeader ); + contextMenu.addActions( getContextActions(file, true) ); + + QAction* bbEditorHeader = new QAction( tr("BB Editor") ); + bbEditorHeader->setDisabled(true); + contextMenu.addAction( bbEditorHeader ); + contextMenu.addActions( getContextActions(file, false) ); + //If all we have is the first action + two headers, the item isn't //valid, so we shouldn't show the menu if (!contextMenu.isEmpty()) @@ -463,9 +465,9 @@ void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) QList FileBrowserTreeWidget::getContextActions(FileItem* file, bool songEditor) { QList result = QList(); + const bool fileIsSample = file->type() == FileItem::SampleFile; - QString destination = (file->type() == FileItem::SampleFile) ? - "AFP Instance" : "Instrument Track"; + QString destination = fileIsSample ? "AFP Instance" : "Instrument Track"; QString shortcutMod = songEditor ? "" : "Ctrl + "; QAction* toInstrument = new QAction( @@ -474,6 +476,14 @@ QList FileBrowserTreeWidget::getContextActions(FileItem* file, bool so [=]{ openInNewInstrumentTrack(file, songEditor); }); result.append(toInstrument); + if(songEditor && fileIsSample){ + QAction* toSampleTrack = new QAction( + tr("Send to new Sample Track (Shift + Right Arrow)")); + connect(toSampleTrack, &QAction::triggered, + [=]{ openInNewSampleTrack(file); }); + result.append(toSampleTrack); + } + return result; } @@ -772,18 +782,14 @@ void FileBrowserTreeWidget::openInNewInstrumentTrack(FileItem* item, bool songEd -bool FileBrowserTreeWidget::openInNewSampleTrack(FileItem* item, bool songEditor) +bool FileBrowserTreeWidget::openInNewSampleTrack(FileItem* item) { // Can't add non-samples to a sample track if (item->type() != FileItem::SampleFile){ return false; } - if (!songEditor){ } - - TrackContainer* trackContainer = Engine::getSong(); - if (!songEditor){ trackContainer = Engine::getBBTrackContainer(); } // Create a new sample track for this sample SampleTrack* sampleTrack = dynamic_cast( - Track::create(Track::SampleTrack, trackContainer)); + Track::create(Track::SampleTrack, Engine::getSong())); // Add the sample clip to the track Engine::mixer()->requestChangeInModel(); From 53b4bcc34c8110164d9688b10d4276d5b70ec276 Mon Sep 17 00:00:00 2001 From: Spekular Date: Thu, 24 Sep 2020 16:43:51 +0200 Subject: [PATCH 08/18] Qt 5.6 compat, better comments, remove usused methods --- include/FileBrowser.h | 7 +-- src/gui/FileBrowser.cpp | 105 +++++++++++++++++++++------------------- 2 files changed, 58 insertions(+), 54 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index 7169fea6e96..8545e5795dd 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -99,9 +99,6 @@ class FileBrowserTreeWidget : public QTreeWidget //! that are expanded in the tree. QList expandedDirs( QTreeWidgetItem * item = nullptr ) const; - void tryAddSEInstrumentTrack(FileItem* file); - void tryAddBBInstrumentTrack(FileItem* file); - protected: void contextMenuEvent( QContextMenuEvent * e ) override; @@ -111,9 +108,9 @@ class FileBrowserTreeWidget : public QTreeWidget private: - //Preview a file + //! Start a preview of a file item void previewFileItem(FileItem* file); - //If a preview is playing, stop it and return true. Otherwise return false + //! If a preview is playing, stop it. Returns false if nothing was playing bool stopPreview(); void keyPressEvent( QKeyEvent * ke ) override; diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index f41d4b29c09..4366ee21430 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -55,7 +55,7 @@ #include "StringPairDrag.h" #include "TextFloat.h" - +#include enum TreeWidgetItemTypes { @@ -369,42 +369,49 @@ QList FileBrowserTreeWidget::expandedDirs( QTreeWidgetItem * item ) con void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) { - // Convenient things to check + // Shorter names for some commonly used properties of the event const auto key = ke->key(); const bool vertical = key == Qt::Key_Up || key == Qt::Key_Down; const bool horizontal = key == Qt::Key_Left || key == Qt::Key_Right; - - // We hijack left/right for preview/add, so don't let them navigate the tree + + // First of all, forward all keypresses except left/right. Since we use them + // for preview & add, we have to ensure that they don't navigate in the tree if (!horizontal){ QTreeWidget::keyPressEvent(ke); } - // We don't want to spam previews or track addition when a key is held + // Then, ignore all autorepeats (they would spam new tracks or previews) if (ke->isAutoRepeat()){ return; } - // We should stop previews before we do anything new - if (vertical || horizontal){ stopPreview(); } - - // The currently selected file item + + // Now add keys to expand/collapse folders, since we hijacked left/right + if (key == Qt::Key_Return || key == Qt::Key_Enter || key == Qt::Key_Space) + { currentItem()->setExpanded(!currentItem()->isExpanded()); } + // We should stop any running previews before we do anything new + else if (vertical || horizontal){ stopPreview(); } + + // Try to get the currently selected item as a FileItem FileItem * file = dynamic_cast(currentItem()); - // If it's null, there's nothing for us to do + // If it's null (folder, separator, etc.), there's nothing left for us to do if (file == NULL){ return; } - - // On navigation up/down, preview samples - // Don't automatically preview presets, because they can play forever + + // When moving to a new sound, preview it. Skip presets, they can play forever if (vertical && file->type() == FileItem::SampleFile) { previewFileItem(file); } - - //On right arrow pressed, add the item + + // When right arrow is pressed, add the selected item... if (key == Qt::Key_Right) { + // ...to the song editor by default, or to the BB editor if ctrl is held bool songEditor = !(ke->modifiers() & Qt::ControlModifier); + // If shift is held, we send the item to a new sample track... bool sampleTrack = ke->modifiers() & Qt::ShiftModifier; - //We can only send to sample tracks in the song editor + // ...but only in the song editor. So, ctrl+shift+right does nothing if (sampleTrack && songEditor){ openInNewSampleTrack(file); } + // Otherwise we send the item as a new instrument track else if (!sampleTrack){ openInNewInstrumentTrack(file, songEditor); } } - //On left arrow pressed, start previewing the item - if (key == Qt::Key_Left) { previewFileItem(file); } + // When left arrow is pressed, start a preview of the selected item + if (key == Qt::Key_Left){ previewFileItem(file); } } @@ -412,7 +419,7 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) void FileBrowserTreeWidget::keyReleaseEvent(QKeyEvent * ke ) { - //Cancel previews when the left key is released + // Cancel previews when the left key is released if (ke->key() == Qt::Key_Left && !ke->isAutoRepeat()){ stopPreview(); } } @@ -426,36 +433,31 @@ void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) { QMenu contextMenu( this ); - QAction* toActiveInstrument = new QAction( - tr( "Send to active instrument-track" ) ); - connect(toActiveInstrument, &QAction::triggered, - [=]{ sendToActiveInstrumentTrack(file); }); - contextMenu.addAction( toActiveInstrument ); - + contextMenu.addAction( + tr( "Send to active instrument-track" ), + [=]{ sendToActiveInstrumentTrack(file); } + ); + contextMenu.addSeparator(); - QAction* openFolder = new QAction( + contextMenu.addAction( QIcon(embed::getIconPixmap("folder")), - tr("Open containing folder") + tr("Open containing folder"), + [=]{ openContainingFolder(file); } ); - connect(openFolder, &QAction::triggered, - [=]{ openContainingFolder(file); }); - contextMenu.addAction(openFolder); - QAction* songEditorHeader = new QAction( tr("Song Editor") ); + QAction* songEditorHeader = new QAction( tr("Song Editor"), nullptr ); songEditorHeader->setDisabled(true); contextMenu.addAction( songEditorHeader ); contextMenu.addActions( getContextActions(file, true) ); - QAction* bbEditorHeader = new QAction( tr("BB Editor") ); + QAction* bbEditorHeader = new QAction( tr("BB Editor"), nullptr ); bbEditorHeader->setDisabled(true); contextMenu.addAction( bbEditorHeader ); contextMenu.addActions( getContextActions(file, false) ); - //If all we have is the first action + two headers, the item isn't - //valid, so we shouldn't show the menu - if (!contextMenu.isEmpty()) - { contextMenu.exec( e->globalPos() ); } + // We should only show the menu if it contains items + if (!contextMenu.isEmpty()){ contextMenu.exec( e->globalPos() ); } } } @@ -466,24 +468,29 @@ QList FileBrowserTreeWidget::getContextActions(FileItem* file, bool so { QList result = QList(); const bool fileIsSample = file->type() == FileItem::SampleFile; - + QString destination = fileIsSample ? "AFP Instance" : "Instrument Track"; QString shortcutMod = songEditor ? "" : "Ctrl + "; - + QAction* toInstrument = new QAction( - tr("Send to new %1 (%2Right Arrow)").arg(destination, shortcutMod)); + tr("Send to new %1 (%2Right Arrow)") + .arg(destination, shortcutMod), + nullptr + ); connect(toInstrument, &QAction::triggered, [=]{ openInNewInstrumentTrack(file, songEditor); }); result.append(toInstrument); - - if(songEditor && fileIsSample){ + + if (songEditor && fileIsSample){ QAction* toSampleTrack = new QAction( - tr("Send to new Sample Track (Shift + Right Arrow)")); + tr("Send to new Sample Track (Shift + Right Arrow)"), + nullptr + ); connect(toSampleTrack, &QAction::triggered, - [=]{ openInNewSampleTrack(file); }); + [=]{ openInNewSampleTrack(file); }); result.append(toSampleTrack); } - + return result; } @@ -522,10 +529,10 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) void FileBrowserTreeWidget::previewFileItem(FileItem* file) { m_pphMutex.lock(); - //If something is already playing, stop it + // If something is already playing, stop it before we continue stopPreview(); - // in special case of sample-files we do not care about + // In special case of sample-files we do not care about // handling() rather than directly creating a SamplePlayHandle if(file->type() == FileItem::SampleFile) { @@ -773,7 +780,7 @@ void FileBrowserTreeWidget::openInNewInstrumentTrack(TrackContainer* tc, FileIte void FileBrowserTreeWidget::openInNewInstrumentTrack(FileItem* item, bool songEditor) { - //Get the correcy TrackContainer, ternary doesn't compile here so do it the long way + // Get the correct TrackContainer. Ternary doesn't compile here TrackContainer* tc = Engine::getSong(); if (!songEditor){ tc = Engine::getBBTrackContainer(); } openInNewInstrumentTrack(tc, item); @@ -786,11 +793,11 @@ bool FileBrowserTreeWidget::openInNewSampleTrack(FileItem* item) { // Can't add non-samples to a sample track if (item->type() != FileItem::SampleFile){ return false; } - + // Create a new sample track for this sample SampleTrack* sampleTrack = dynamic_cast( Track::create(Track::SampleTrack, Engine::getSong())); - + // Add the sample clip to the track Engine::mixer()->requestChangeInModel(); SampleTCO* clip = dynamic_cast(sampleTrack->createTCO(0)); From 72bf01148049f030a5d63a0b2b8ee0671ff1ab07 Mon Sep 17 00:00:00 2001 From: Spekular Date: Sat, 26 Sep 2020 17:19:08 +0200 Subject: [PATCH 09/18] Change preview/add shortcut to space/enter --- src/gui/FileBrowser.cpp | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 4366ee21430..4a8810351c2 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -55,7 +55,7 @@ #include "StringPairDrag.h" #include "TextFloat.h" -#include + enum TreeWidgetItemTypes { @@ -372,19 +372,15 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) // Shorter names for some commonly used properties of the event const auto key = ke->key(); const bool vertical = key == Qt::Key_Up || key == Qt::Key_Down; - const bool horizontal = key == Qt::Key_Left || key == Qt::Key_Right; + const bool preview = key == Qt::Key_Space; + const bool insert = key == Qt::Key_Enter || key == Qt::Key_Return; - // First of all, forward all keypresses except left/right. Since we use them - // for preview & add, we have to ensure that they don't navigate in the tree - if (!horizontal){ QTreeWidget::keyPressEvent(ke); } + // First of all, forward all keypresses + QTreeWidget::keyPressEvent(ke); // Then, ignore all autorepeats (they would spam new tracks or previews) if (ke->isAutoRepeat()){ return; } - - // Now add keys to expand/collapse folders, since we hijacked left/right - if (key == Qt::Key_Return || key == Qt::Key_Enter || key == Qt::Key_Space) - { currentItem()->setExpanded(!currentItem()->isExpanded()); } // We should stop any running previews before we do anything new - else if (vertical || horizontal){ stopPreview(); } + else if (vertical || preview || insert){ stopPreview(); } // Try to get the currently selected item as a FileItem FileItem * file = dynamic_cast(currentItem()); @@ -397,21 +393,21 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) previewFileItem(file); } - // When right arrow is pressed, add the selected item... - if (key == Qt::Key_Right) + // When enter is pressed, add the selected item... + if (insert) { // ...to the song editor by default, or to the BB editor if ctrl is held bool songEditor = !(ke->modifiers() & Qt::ControlModifier); // If shift is held, we send the item to a new sample track... bool sampleTrack = ke->modifiers() & Qt::ShiftModifier; - // ...but only in the song editor. So, ctrl+shift+right does nothing + // ...but only in the song editor. So, ctrl+shift enter does nothing if (sampleTrack && songEditor){ openInNewSampleTrack(file); } // Otherwise we send the item as a new instrument track else if (!sampleTrack){ openInNewInstrumentTrack(file, songEditor); } } - // When left arrow is pressed, start a preview of the selected item - if (key == Qt::Key_Left){ previewFileItem(file); } + // When space is pressed, start a preview of the selected item + if (preview){ previewFileItem(file); } } @@ -419,8 +415,8 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) void FileBrowserTreeWidget::keyReleaseEvent(QKeyEvent * ke ) { - // Cancel previews when the left key is released - if (ke->key() == Qt::Key_Left && !ke->isAutoRepeat()){ stopPreview(); } + // Cancel previews when the space key is released + if (ke->key() == Qt::Key_Space && !ke->isAutoRepeat()){ stopPreview(); } } @@ -470,10 +466,10 @@ QList FileBrowserTreeWidget::getContextActions(FileItem* file, bool so const bool fileIsSample = file->type() == FileItem::SampleFile; QString destination = fileIsSample ? "AFP Instance" : "Instrument Track"; - QString shortcutMod = songEditor ? "" : "Ctrl + "; + QString shortcutMod = songEditor ? "" : "Ctrl +"; QAction* toInstrument = new QAction( - tr("Send to new %1 (%2Right Arrow)") + tr("Send to new %1 (%2 Enter)") .arg(destination, shortcutMod), nullptr ); @@ -483,7 +479,7 @@ QList FileBrowserTreeWidget::getContextActions(FileItem* file, bool so if (songEditor && fileIsSample){ QAction* toSampleTrack = new QAction( - tr("Send to new Sample Track (Shift + Right Arrow)"), + tr("Send to new Sample Track (Shift + Enter)"), nullptr ); connect(toSampleTrack, &QAction::triggered, From 6f1441d6e7d03c02cb2357643d3af643926c4f7f Mon Sep 17 00:00:00 2001 From: Spekular Date: Sat, 26 Sep 2020 17:25:00 +0200 Subject: [PATCH 10/18] Left/right keys should still stop previews --- src/gui/FileBrowser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 4a8810351c2..f8f77f68d7e 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -372,6 +372,7 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) // Shorter names for some commonly used properties of the event const auto key = ke->key(); const bool vertical = key == Qt::Key_Up || key == Qt::Key_Down; + const bool horizontal = key == Qt::Key_Left || key == Qt::Key_Right; const bool preview = key == Qt::Key_Space; const bool insert = key == Qt::Key_Enter || key == Qt::Key_Return; @@ -380,7 +381,7 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) // Then, ignore all autorepeats (they would spam new tracks or previews) if (ke->isAutoRepeat()){ return; } // We should stop any running previews before we do anything new - else if (vertical || preview || insert){ stopPreview(); } + else if (vertical || horizontal || preview || insert){ stopPreview(); } // Try to get the currently selected item as a FileItem FileItem * file = dynamic_cast(currentItem()); From 5a22a20230cfaa6dfa1d51e0d4601fd6d427a175 Mon Sep 17 00:00:00 2001 From: Spekular Date: Sat, 26 Sep 2020 19:17:32 +0200 Subject: [PATCH 11/18] Formatting and NULL -> nullptr changes --- include/FileBrowser.h | 6 +-- src/gui/FileBrowser.cpp | 88 ++++++++++++++++++++--------------------- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index 8545e5795dd..6bae220ade3 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -63,9 +63,9 @@ class FileBrowser : public SideBarWidget private slots: void reloadTree( void ); - void expandItems( QTreeWidgetItem * item=NULL, QList expandedDirs = QList() ); + void expandItems( QTreeWidgetItem * item=nullptr, QList expandedDirs = QList() ); // call with item=NULL to filter the entire tree - bool filterItems( const QString & filter, QTreeWidgetItem * item=NULL ); + bool filterItems( const QString & filter, QTreeWidgetItem * item=nullptr ); void giveFocusToFilter(); private: @@ -112,7 +112,7 @@ class FileBrowserTreeWidget : public QTreeWidget void previewFileItem(FileItem* file); //! If a preview is playing, stop it. Returns false if nothing was playing bool stopPreview(); - + void keyPressEvent( QKeyEvent * ke ) override; void keyReleaseEvent( QKeyEvent * ke ) override; diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index f8f77f68d7e..01aa4c791d1 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -174,7 +174,7 @@ void FileBrowser::reloadTree( void ) { addItems( *it ); } - expandItems(NULL, expandedDirs); + expandItems(nullptr, expandedDirs); m_filterEdit->setText( text ); filterItems( text ); } @@ -241,7 +241,7 @@ void FileBrowser::addItems(const QString & path ) { Directory * d = dynamic_cast( m_fileBrowserTreeWidget->topLevelItem( i ) ); - if( d == NULL || cur_file < d->text( 0 ) ) + if( d == nullptr || cur_file < d->text( 0 ) ) { // insert before item, we're done Directory *dd = new Directory( cur_file, path, @@ -321,7 +321,7 @@ FileBrowserTreeWidget::FileBrowserTreeWidget(QWidget * parent ) : QTreeWidget( parent ), m_mousePressed( false ), m_pressPos(), - m_previewPlayHandle( NULL ), + m_previewPlayHandle( nullptr ), m_pphMutex( QMutex::Recursive ) { setColumnCount( 1 ); @@ -371,10 +371,10 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) { // Shorter names for some commonly used properties of the event const auto key = ke->key(); - const bool vertical = key == Qt::Key_Up || key == Qt::Key_Down; - const bool horizontal = key == Qt::Key_Left || key == Qt::Key_Right; - const bool preview = key == Qt::Key_Space; - const bool insert = key == Qt::Key_Enter || key == Qt::Key_Return; + const bool vertical = (key == Qt::Key_Up || key == Qt::Key_Down); + const bool horizontal = (key == Qt::Key_Left || key == Qt::Key_Right); + const bool insert = (key == Qt::Key_Enter || key == Qt::Key_Return); + const bool preview = (key == Qt::Key_Space); // First of all, forward all keypresses QTreeWidget::keyPressEvent(ke); @@ -386,7 +386,7 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) // Try to get the currently selected item as a FileItem FileItem * file = dynamic_cast(currentItem()); // If it's null (folder, separator, etc.), there's nothing left for us to do - if (file == NULL){ return; } + if (file == nullptr){ return; } // When moving to a new sound, preview it. Skip presets, they can play forever if (vertical && file->type() == FileItem::SampleFile) @@ -426,7 +426,7 @@ void FileBrowserTreeWidget::keyReleaseEvent(QKeyEvent * ke ) void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) { FileItem * file = dynamic_cast( itemAt( e->pos() ) ); - if( file != NULL && file->isTrack() ) + if( file != nullptr && file->isTrack() ) { QMenu contextMenu( this ); @@ -517,7 +517,7 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) } FileItem * f = dynamic_cast(i); - if(f != NULL){ previewFileItem(f); } + if(f != nullptr){ previewFileItem(f); } } @@ -547,7 +547,7 @@ void FileBrowserTreeWidget::previewFileItem(FileItem* file) (file->extension() == "xiz" || file->extension() == "sf2" || file->extension() == "sf3" || file->extension() == "gig" || file ->extension() == "pat") && - !pluginFactory->pluginSupportingExtension(file->extension()).info.isNull()) + !pluginFactory->pluginSupportingExtension(file->extension()).isNull()) { m_previewPlayHandle = new PresetPreviewPlayHandle( file->fullName(), file->handling() == FileItem::LoadByPlugin); @@ -568,11 +568,11 @@ void FileBrowserTreeWidget::previewFileItem(FileItem* file) file->fullName(), file->handling() == FileItem::LoadByPlugin, &dataFile ); } - if(m_previewPlayHandle != NULL) + if(m_previewPlayHandle != nullptr) { if(!Engine::mixer()->addPlayHandle(m_previewPlayHandle)) { - m_previewPlayHandle = NULL; + m_previewPlayHandle = nullptr; } } m_pphMutex.unlock(); @@ -583,11 +583,11 @@ void FileBrowserTreeWidget::previewFileItem(FileItem* file) bool FileBrowserTreeWidget::stopPreview() { - if (m_previewPlayHandle != NULL) + if (m_previewPlayHandle != nullptr) { m_pphMutex.lock(); Engine::mixer()->removePlayHandle(m_previewPlayHandle); - m_previewPlayHandle = NULL; + m_previewPlayHandle = nullptr; m_pphMutex.unlock(); return true; } @@ -607,7 +607,7 @@ void FileBrowserTreeWidget::mouseMoveEvent( QMouseEvent * me ) mouseReleaseEvent( NULL ); FileItem * f = dynamic_cast( itemAt( m_pressPos ) ); - if( f != NULL ) + if( f != nullptr ) { switch( f->type() ) { @@ -658,7 +658,7 @@ void FileBrowserTreeWidget::mouseReleaseEvent(QMouseEvent * me ) m_mousePressed = false; m_pphMutex.lock(); - if(m_previewPlayHandle != NULL) + if(m_previewPlayHandle != nullptr) { // if there're samples shorter than 3 seconds, we don't // stop them if the user releases mouse-button... @@ -670,7 +670,7 @@ void FileBrowserTreeWidget::mouseReleaseEvent(QMouseEvent * me ) processingSampleRate() * 3)) { s->setDoneMayReturnTrue(true); - m_previewPlayHandle = NULL; + m_previewPlayHandle = nullptr; m_pphMutex.unlock(); return; } @@ -700,7 +700,7 @@ void FileBrowserTreeWidget::handleFile(FileItem * f, InstrumentTrack * it) { const QString e = f->extension(); Instrument * i = it->instrument(); - if( i == NULL || + if( i == nullptr || !i->descriptor()->supportsFileType( e ) ) { PluginFactory::PluginInfoAndKey piakn = @@ -740,7 +740,7 @@ void FileBrowserTreeWidget::activateListItem(QTreeWidgetItem * item, int column ) { FileItem * f = dynamic_cast( item ); - if( f == NULL ) + if( f == nullptr ) { return; } @@ -748,7 +748,7 @@ void FileBrowserTreeWidget::activateListItem(QTreeWidgetItem * item, if( f->handling() == FileItem::LoadAsProject || f->handling() == FileItem::ImportAsProject ) { - handleFile( f, NULL ); + handleFile( f, nullptr ); } else if( f->handling() != FileItem::NotSupported ) { @@ -836,7 +836,7 @@ void FileBrowserTreeWidget::sendToActiveInstrumentTrack( FileItem* item ) InstrumentTrackWindow * itw = dynamic_cast( w.previous()->widget() ); - if( itw != NULL && itw->isHidden() == false ) + if( itw != nullptr && itw->isHidden() == false ) { handleFile( item, itw->model() ); break; @@ -850,7 +850,7 @@ void FileBrowserTreeWidget::sendToActiveInstrumentTrack( FileItem* item ) void FileBrowserTreeWidget::updateDirectory(QTreeWidgetItem * item ) { Directory * dir = dynamic_cast( item ); - if( dir != NULL ) + if( dir != nullptr ) { dir->update(); } @@ -861,9 +861,9 @@ void FileBrowserTreeWidget::updateDirectory(QTreeWidgetItem * item ) -QPixmap * Directory::s_folderPixmap = NULL; -QPixmap * Directory::s_folderOpenedPixmap = NULL; -QPixmap * Directory::s_folderLockedPixmap = NULL; +QPixmap * Directory::s_folderPixmap = nullptr; +QPixmap * Directory::s_folderOpenedPixmap = nullptr; +QPixmap * Directory::s_folderLockedPixmap = nullptr; Directory::Directory(const QString & filename, const QString & path, @@ -892,19 +892,19 @@ Directory::Directory(const QString & filename, const QString & path, void Directory::initPixmaps( void ) { - if( s_folderPixmap == NULL ) + if( s_folderPixmap == nullptr ) { s_folderPixmap = new QPixmap( embed::getIconPixmap( "folder" ) ); } - if( s_folderOpenedPixmap == NULL ) + if( s_folderOpenedPixmap == nullptr ) { s_folderOpenedPixmap = new QPixmap( embed::getIconPixmap( "folder_opened" ) ); } - if( s_folderLockedPixmap == NULL ) + if( s_folderLockedPixmap == nullptr ) { s_folderLockedPixmap = new QPixmap( embed::getIconPixmap( "folder_locked" ) ); @@ -982,7 +982,7 @@ bool Directory::addItems(const QString & path ) { Directory * d = dynamic_cast( child( i ) ); - if( d == NULL || cur_file < d->text( 0 ) ) + if( d == nullptr || cur_file < d->text( 0 ) ) { // insert before item, we're done insertChild( i, new Directory( cur_file, @@ -1040,13 +1040,13 @@ bool Directory::addItems(const QString & path ) -QPixmap * FileItem::s_projectFilePixmap = NULL; -QPixmap * FileItem::s_presetFilePixmap = NULL; -QPixmap * FileItem::s_sampleFilePixmap = NULL; -QPixmap * FileItem::s_soundfontFilePixmap = NULL; -QPixmap * FileItem::s_vstPluginFilePixmap = NULL; -QPixmap * FileItem::s_midiFilePixmap = NULL; -QPixmap * FileItem::s_unknownFilePixmap = NULL; +QPixmap * FileItem::s_projectFilePixmap = nullptr; +QPixmap * FileItem::s_presetFilePixmap = nullptr; +QPixmap * FileItem::s_sampleFilePixmap = nullptr; +QPixmap * FileItem::s_soundfontFilePixmap = nullptr; +QPixmap * FileItem::s_vstPluginFilePixmap = nullptr; +QPixmap * FileItem::s_midiFilePixmap = nullptr; +QPixmap * FileItem::s_unknownFilePixmap = nullptr; FileItem::FileItem(QTreeWidget * parent, const QString & name, @@ -1074,43 +1074,43 @@ FileItem::FileItem(const QString & name, const QString & path ) : void FileItem::initPixmaps( void ) { - if( s_projectFilePixmap == NULL ) + if( s_projectFilePixmap == nullptr ) { s_projectFilePixmap = new QPixmap( embed::getIconPixmap( "project_file", 16, 16 ) ); } - if( s_presetFilePixmap == NULL ) + if( s_presetFilePixmap == nullptr ) { s_presetFilePixmap = new QPixmap( embed::getIconPixmap( "preset_file", 16, 16 ) ); } - if( s_sampleFilePixmap == NULL ) + if( s_sampleFilePixmap == nullptr ) { s_sampleFilePixmap = new QPixmap( embed::getIconPixmap( "sample_file", 16, 16 ) ); } - if ( s_soundfontFilePixmap == NULL ) + if ( s_soundfontFilePixmap == nullptr ) { s_soundfontFilePixmap = new QPixmap( embed::getIconPixmap( "soundfont_file", 16, 16 ) ); } - if ( s_vstPluginFilePixmap == NULL ) + if ( s_vstPluginFilePixmap == nullptr ) { s_vstPluginFilePixmap = new QPixmap( embed::getIconPixmap( "vst_plugin_file", 16, 16 ) ); } - if( s_midiFilePixmap == NULL ) + if( s_midiFilePixmap == nullptr ) { s_midiFilePixmap = new QPixmap( embed::getIconPixmap( "midi_file", 16, 16 ) ); } - if( s_unknownFilePixmap == NULL ) + if( s_unknownFilePixmap == nullptr ) { s_unknownFilePixmap = new QPixmap( embed::getIconPixmap( "unknown_file" ) ); From 3700c721666d08cbbb825934a9db6bc3e2f5f881 Mon Sep 17 00:00:00 2001 From: Spekular Date: Sat, 26 Sep 2020 19:19:26 +0200 Subject: [PATCH 12/18] Missed one --- src/gui/FileBrowser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 01aa4c791d1..0bbb321d161 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -604,7 +604,7 @@ void FileBrowserTreeWidget::mouseMoveEvent( QMouseEvent * me ) QApplication::startDragDistance() ) { // make sure any playback is stopped - mouseReleaseEvent( NULL ); + mouseReleaseEvent( nullptr ); FileItem * f = dynamic_cast( itemAt( m_pressPos ) ); if( f != nullptr ) From 098fe629a8e665a8a655413793a118f3a1e2fa88 Mon Sep 17 00:00:00 2001 From: Spekular Date: Tue, 29 Sep 2020 17:20:42 +0200 Subject: [PATCH 13/18] Attempt to fix lag when spamming preview --- include/FileBrowser.h | 1 + src/gui/FileBrowser.cpp | 71 ++++++++++++++++++++++------------------- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index 6bae220ade3..1f0d1622ea3 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -125,6 +125,7 @@ class FileBrowserTreeWidget : public QTreeWidget PlayHandle* m_previewPlayHandle; QMutex m_pphMutex; + FileItem* m_previewFileItem; QList getContextActions(FileItem* item, bool songEditor); diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 0bbb321d161..e1d9cad37f0 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -322,7 +322,8 @@ FileBrowserTreeWidget::FileBrowserTreeWidget(QWidget * parent ) : m_mousePressed( false ), m_pressPos(), m_previewPlayHandle( nullptr ), - m_pphMutex( QMutex::Recursive ) + m_pphMutex( QMutex::Recursive ), + m_previewFileItem( nullptr ) { setColumnCount( 1 ); headerItem()->setHidden( true ); @@ -525,34 +526,41 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) void FileBrowserTreeWidget::previewFileItem(FileItem* file) { - m_pphMutex.lock(); + // Lock the preview mutex + QMutexLocker locker(&m_pphMutex); // If something is already playing, stop it before we continue stopPreview(); + // Let it be known that we're intend to preview this file + m_previewFileItem = file; + // Then unlock, since we don't need to touch the shared data for a while + locker.unlock(); + + PlayHandle* newHandle = nullptr; // In special case of sample-files we do not care about // handling() rather than directly creating a SamplePlayHandle - if(file->type() == FileItem::SampleFile) + if (file->type() == FileItem::SampleFile) { TextFloat * tf = TextFloat::displayMessage( - tr("Loading sample"), - tr("Please wait, loading sample for preview..."), - embed::getIconPixmap("sample_file", 24, 24), 0); + tr("Loading sample"), + tr("Please wait, loading sample for preview..."), + embed::getIconPixmap("sample_file", 24, 24), 0); qApp->processEvents(QEventLoop::ExcludeUserInputEvents); - SamplePlayHandle * s = new SamplePlayHandle(file->fullName()); + SamplePlayHandle* s = new SamplePlayHandle(file->fullName()); s->setDoneMayReturnTrue(false); - m_previewPlayHandle = s; + newHandle = s; delete tf; } - else if( + else if ( (file->extension() == "xiz" || file->extension() == "sf2" || file->extension() == "sf3" || file->extension() == "gig" || file ->extension() == "pat") && !pluginFactory->pluginSupportingExtension(file->extension()).isNull()) { - m_previewPlayHandle = new PresetPreviewPlayHandle( + newHandle = new PresetPreviewPlayHandle( file->fullName(), file->handling() == FileItem::LoadByPlugin); } - else if(file->type() != FileItem::VstPluginFile && file->isTrack()) + else if (file->type() != FileItem::VstPluginFile && file->isTrack()) { DataFile dataFile(file->fullName()); if(!dataFile.validate(file->extension())) @@ -561,21 +569,24 @@ void FileBrowserTreeWidget::previewFileItem(FileItem* file) tr("%1 does not appear to be a valid %2 file") .arg(file->fullName(), file->extension()), QMessageBox::Ok, QMessageBox::NoButton); - m_pphMutex.unlock(); return; } - m_previewPlayHandle = new PresetPreviewPlayHandle( - file->fullName(), file->handling() == FileItem::LoadByPlugin, &dataFile - ); + newHandle = new PresetPreviewPlayHandle( + file->fullName(), file->handling() == FileItem::LoadByPlugin, &dataFile); } - if(m_previewPlayHandle != nullptr) + + // Lock the preview mutex since we're about to access shared data again + locker.relock(); + // If someone else changed the item to be previewed, or if our handle is + // null, we shouldn't start a new preview. + if (m_previewFileItem == file && newHandle != nullptr) { - if(!Engine::mixer()->addPlayHandle(m_previewPlayHandle)) + if (Engine::mixer()->addPlayHandle(newHandle)) { - m_previewPlayHandle = nullptr; + m_previewPlayHandle = newHandle; } + else { m_previewPlayHandle = nullptr; } } - m_pphMutex.unlock(); } @@ -583,12 +594,12 @@ void FileBrowserTreeWidget::previewFileItem(FileItem* file) bool FileBrowserTreeWidget::stopPreview() { + QMutexLocker locker(&m_pphMutex); + m_previewFileItem = nullptr; if (m_previewPlayHandle != nullptr) { - m_pphMutex.lock(); Engine::mixer()->removePlayHandle(m_previewPlayHandle); m_previewPlayHandle = nullptr; - m_pphMutex.unlock(); return true; } else { return false; } @@ -657,27 +668,23 @@ void FileBrowserTreeWidget::mouseReleaseEvent(QMouseEvent * me ) { m_mousePressed = false; - m_pphMutex.lock(); - if(m_previewPlayHandle != nullptr) + QMutexLocker locker(&m_pphMutex); + + if (m_previewPlayHandle != nullptr) { // if there're samples shorter than 3 seconds, we don't // stop them if the user releases mouse-button... - if(m_previewPlayHandle->type() == PlayHandle::TypeSamplePlayHandle) + if (m_previewPlayHandle->type() == PlayHandle::TypeSamplePlayHandle) { - SamplePlayHandle * s = dynamic_cast(m_previewPlayHandle); - if(s && s->totalFrames() - s->framesDone() <= - static_cast(Engine::mixer()-> - processingSampleRate() * 3)) + SamplePlayHandle* s = dynamic_cast(m_previewPlayHandle); + auto second = static_cast(Engine::mixer()->processingSampleRate()); + if (s && s->totalFrames() - s->framesDone() <= second * 3) { s->setDoneMayReturnTrue(true); - m_previewPlayHandle = nullptr; - m_pphMutex.unlock(); - return; } } else { stopPreview(); } } - m_pphMutex.unlock(); } From cdb4e5c914114eb18189bf422ef6711f25dff13d Mon Sep 17 00:00:00 2001 From: Spekular Date: Tue, 29 Sep 2020 19:49:00 +0200 Subject: [PATCH 14/18] Simplify locking, stop previews when tab hidden --- include/FileBrowser.h | 3 +- src/gui/FileBrowser.cpp | 71 +++++++++++++++++++++-------------------- 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index 1f0d1622ea3..f7aee65fd8a 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -115,6 +115,7 @@ class FileBrowserTreeWidget : public QTreeWidget void keyPressEvent( QKeyEvent * ke ) override; void keyReleaseEvent( QKeyEvent * ke ) override; + void hideEvent( QHideEvent * he ) override; void handleFile( FileItem * fi, InstrumentTrack * it ); void openInNewInstrumentTrack( TrackContainer* tc, FileItem* item ); @@ -123,9 +124,9 @@ class FileBrowserTreeWidget : public QTreeWidget bool m_mousePressed; QPoint m_pressPos; + //! This should only be accessed or modified when m_pphMutex is held PlayHandle* m_previewPlayHandle; QMutex m_pphMutex; - FileItem* m_previewFileItem; QList getContextActions(FileItem* item, bool songEditor); diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index e1d9cad37f0..198df9b6254 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -322,8 +322,7 @@ FileBrowserTreeWidget::FileBrowserTreeWidget(QWidget * parent ) : m_mousePressed( false ), m_pressPos(), m_previewPlayHandle( nullptr ), - m_pphMutex( QMutex::Recursive ), - m_previewFileItem( nullptr ) + m_pphMutex( QMutex::Recursive ) { setColumnCount( 1 ); headerItem()->setHidden( true ); @@ -415,7 +414,7 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) -void FileBrowserTreeWidget::keyReleaseEvent(QKeyEvent * ke ) +void FileBrowserTreeWidget::keyReleaseEvent(QKeyEvent* ke) { // Cancel previews when the space key is released if (ke->key() == Qt::Key_Space && !ke->isAutoRepeat()){ stopPreview(); } @@ -424,6 +423,16 @@ void FileBrowserTreeWidget::keyReleaseEvent(QKeyEvent * ke ) +void FileBrowserTreeWidget::hideEvent(QHideEvent* he) +{ + // Cancel previews when the user switches tabs or hides the sidebar + stopPreview(); + QTreeWidget::hideEvent(he); +} + + + + void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) { FileItem * file = dynamic_cast( itemAt( e->pos() ) ); @@ -527,15 +536,13 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) void FileBrowserTreeWidget::previewFileItem(FileItem* file) { // Lock the preview mutex - QMutexLocker locker(&m_pphMutex); + QMutexLocker previewLocker(&m_pphMutex); // If something is already playing, stop it before we continue stopPreview(); - // Let it be known that we're intend to preview this file - m_previewFileItem = file; - // Then unlock, since we don't need to touch the shared data for a while - locker.unlock(); - PlayHandle* newHandle = nullptr; + PlayHandle* newPPH = nullptr; + const QString fileName = file->fullName(); + const QString ext = file->extension(); // In special case of sample-files we do not care about // handling() rather than directly creating a SamplePlayHandle @@ -546,44 +553,41 @@ void FileBrowserTreeWidget::previewFileItem(FileItem* file) tr("Please wait, loading sample for preview..."), embed::getIconPixmap("sample_file", 24, 24), 0); qApp->processEvents(QEventLoop::ExcludeUserInputEvents); - SamplePlayHandle* s = new SamplePlayHandle(file->fullName()); + SamplePlayHandle* s = new SamplePlayHandle(fileName); s->setDoneMayReturnTrue(false); - newHandle = s; + newPPH = s; delete tf; } else if ( - (file->extension() == "xiz" || file->extension() == "sf2" || - file->extension() == "sf3" || file->extension() == "gig" || - file ->extension() == "pat") && - !pluginFactory->pluginSupportingExtension(file->extension()).isNull()) + (ext == "xiz" || ext == "sf2" || ext == "sf3" || + ext == "gig" || ext == "pat") + && !pluginFactory->pluginSupportingExtension(ext).isNull()) { - newHandle = new PresetPreviewPlayHandle( - file->fullName(), file->handling() == FileItem::LoadByPlugin); + const bool isPlugin = file->handling() == FileItem::LoadByPlugin; + newPPH = new PresetPreviewPlayHandle(fileName, isPlugin); } else if (file->type() != FileItem::VstPluginFile && file->isTrack()) { - DataFile dataFile(file->fullName()); - if(!dataFile.validate(file->extension())) + DataFile dataFile(fileName); + if (dataFile.validate(ext)) + { + const bool isPlugin = file->handling() == FileItem::LoadByPlugin; + newPPH = new PresetPreviewPlayHandle(fileName, isPlugin, &dataFile); + } + else { QMessageBox::warning(0, tr ("Error"), tr("%1 does not appear to be a valid %2 file") - .arg(file->fullName(), file->extension()), + .arg(fileName, ext), QMessageBox::Ok, QMessageBox::NoButton); - return; } - newHandle = new PresetPreviewPlayHandle( - file->fullName(), file->handling() == FileItem::LoadByPlugin, &dataFile); } - // Lock the preview mutex since we're about to access shared data again - locker.relock(); - // If someone else changed the item to be previewed, or if our handle is - // null, we shouldn't start a new preview. - if (m_previewFileItem == file && newHandle != nullptr) + if (newPPH != nullptr) { - if (Engine::mixer()->addPlayHandle(newHandle)) + if (Engine::mixer()->addPlayHandle(newPPH)) { - m_previewPlayHandle = newHandle; + m_previewPlayHandle = newPPH; } else { m_previewPlayHandle = nullptr; } } @@ -594,8 +598,7 @@ void FileBrowserTreeWidget::previewFileItem(FileItem* file) bool FileBrowserTreeWidget::stopPreview() { - QMutexLocker locker(&m_pphMutex); - m_previewFileItem = nullptr; + QMutexLocker previewLocker(&m_pphMutex); if (m_previewPlayHandle != nullptr) { Engine::mixer()->removePlayHandle(m_previewPlayHandle); @@ -668,11 +671,11 @@ void FileBrowserTreeWidget::mouseReleaseEvent(QMouseEvent * me ) { m_mousePressed = false; - QMutexLocker locker(&m_pphMutex); + QMutexLocker previewLocker(&m_pphMutex); if (m_previewPlayHandle != nullptr) { - // if there're samples shorter than 3 seconds, we don't + // If less than 3 seconds remain of the sample, we don't // stop them if the user releases mouse-button... if (m_previewPlayHandle->type() == PlayHandle::TypeSamplePlayHandle) { From 5e0b8e7aed37793bd4618232ba5554268c97eeb8 Mon Sep 17 00:00:00 2001 From: Spekular Date: Thu, 1 Oct 2020 14:57:41 +0200 Subject: [PATCH 15/18] Fixes from Dom's review --- include/FileBrowser.h | 2 +- src/gui/FileBrowser.cpp | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index f7aee65fd8a..dec088f0dbf 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -111,7 +111,7 @@ class FileBrowserTreeWidget : public QTreeWidget //! Start a preview of a file item void previewFileItem(FileItem* file); //! If a preview is playing, stop it. Returns false if nothing was playing - bool stopPreview(); + void stopPreview(); void keyPressEvent( QKeyEvent * ke ) override; void keyReleaseEvent( QKeyEvent * ke ) override; diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 198df9b6254..915220649e7 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -476,12 +476,13 @@ QList FileBrowserTreeWidget::getContextActions(FileItem* file, bool so QList result = QList(); const bool fileIsSample = file->type() == FileItem::SampleFile; - QString destination = fileIsSample ? "AFP Instance" : "Instrument Track"; - QString shortcutMod = songEditor ? "" : "Ctrl +"; + QString instrumentAction = fileIsSample ? + tr("Send to new AudioFileProcessor instance") : + tr("Send to new instrument track"); + QString shortcutMod = songEditor ? "" : UI_CTRL_KEY + QString(" + "); QAction* toInstrument = new QAction( - tr("Send to new %1 (%2 Enter)") - .arg(destination, shortcutMod), + instrumentAction + tr(" (%2Enter)").arg(shortcutMod), nullptr ); connect(toInstrument, &QAction::triggered, @@ -490,7 +491,7 @@ QList FileBrowserTreeWidget::getContextActions(FileItem* file, bool so if (songEditor && fileIsSample){ QAction* toSampleTrack = new QAction( - tr("Send to new Sample Track (Shift + Enter)"), + tr("Send to new sample track (Shift + Enter)"), nullptr ); connect(toSampleTrack, &QAction::triggered, @@ -596,16 +597,14 @@ void FileBrowserTreeWidget::previewFileItem(FileItem* file) -bool FileBrowserTreeWidget::stopPreview() +void FileBrowserTreeWidget::stopPreview() { QMutexLocker previewLocker(&m_pphMutex); if (m_previewPlayHandle != nullptr) { Engine::mixer()->removePlayHandle(m_previewPlayHandle); m_previewPlayHandle = nullptr; - return true; } - else { return false; } } @@ -685,8 +684,8 @@ void FileBrowserTreeWidget::mouseReleaseEvent(QMouseEvent * me ) { s->setDoneMayReturnTrue(true); } + else { stopPreview(); } } - else { stopPreview(); } } } @@ -802,7 +801,7 @@ bool FileBrowserTreeWidget::openInNewSampleTrack(FileItem* item) if (item->type() != FileItem::SampleFile){ return false; } // Create a new sample track for this sample - SampleTrack* sampleTrack = dynamic_cast( + SampleTrack* sampleTrack = static_cast( Track::create(Track::SampleTrack, Engine::getSong())); // Add the sample clip to the track From 4a314ab4d019ef35044670fe6dd862166305bdc5 Mon Sep 17 00:00:00 2001 From: Spekular Date: Thu, 1 Oct 2020 15:28:39 +0200 Subject: [PATCH 16/18] TODO comments --- src/gui/FileBrowser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 915220649e7..95d23df6814 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -535,7 +535,7 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) void FileBrowserTreeWidget::previewFileItem(FileItem* file) -{ +{ // TODO: We should do this work outside the event thread // Lock the preview mutex QMutexLocker previewLocker(&m_pphMutex); // If something is already playing, stop it before we continue @@ -553,6 +553,7 @@ void FileBrowserTreeWidget::previewFileItem(FileItem* file) tr("Loading sample"), tr("Please wait, loading sample for preview..."), embed::getIconPixmap("sample_file", 24, 24), 0); + // TODO: this can be removed once we do this outside the event thread qApp->processEvents(QEventLoop::ExcludeUserInputEvents); SamplePlayHandle* s = new SamplePlayHandle(fileName); s->setDoneMayReturnTrue(false); From 638d717d1b9eba6cd221b3ace609f04d440a0c11 Mon Sep 17 00:00:00 2001 From: Spekular Date: Fri, 2 Oct 2020 21:36:44 +0200 Subject: [PATCH 17/18] Formatting changes from Veratil's review --- include/FileBrowser.h | 7 +++---- src/gui/FileBrowser.cpp | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index dec088f0dbf..70dc82426f6 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -105,6 +105,9 @@ class FileBrowserTreeWidget : public QTreeWidget void mousePressEvent( QMouseEvent * me ) override; void mouseMoveEvent( QMouseEvent * me ) override; void mouseReleaseEvent( QMouseEvent * me ) override; + void keyPressEvent( QKeyEvent * ke ) override; + void keyReleaseEvent( QKeyEvent * ke ) override; + void hideEvent( QHideEvent * he ) override; private: @@ -113,10 +116,6 @@ class FileBrowserTreeWidget : public QTreeWidget //! If a preview is playing, stop it. Returns false if nothing was playing void stopPreview(); - void keyPressEvent( QKeyEvent * ke ) override; - void keyReleaseEvent( QKeyEvent * ke ) override; - void hideEvent( QHideEvent * he ) override; - void handleFile( FileItem * fi, InstrumentTrack * it ); void openInNewInstrumentTrack( TrackContainer* tc, FileItem* item ); diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 95d23df6814..6b050cdfec8 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -379,14 +379,14 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) // First of all, forward all keypresses QTreeWidget::keyPressEvent(ke); // Then, ignore all autorepeats (they would spam new tracks or previews) - if (ke->isAutoRepeat()){ return; } + if (ke->isAutoRepeat()) { return; } // We should stop any running previews before we do anything new - else if (vertical || horizontal || preview || insert){ stopPreview(); } + else if (vertical || horizontal || preview || insert) { stopPreview(); } // Try to get the currently selected item as a FileItem FileItem * file = dynamic_cast(currentItem()); // If it's null (folder, separator, etc.), there's nothing left for us to do - if (file == nullptr){ return; } + if (file == nullptr) { return; } // When moving to a new sound, preview it. Skip presets, they can play forever if (vertical && file->type() == FileItem::SampleFile) @@ -408,7 +408,7 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) } // When space is pressed, start a preview of the selected item - if (preview){ previewFileItem(file); } + if (preview) { previewFileItem(file); } } @@ -417,7 +417,7 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) void FileBrowserTreeWidget::keyReleaseEvent(QKeyEvent* ke) { // Cancel previews when the space key is released - if (ke->key() == Qt::Key_Space && !ke->isAutoRepeat()){ stopPreview(); } + if (ke->key() == Qt::Key_Space && !ke->isAutoRepeat()) { stopPreview(); } } @@ -464,7 +464,7 @@ void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) contextMenu.addActions( getContextActions(file, false) ); // We should only show the menu if it contains items - if (!contextMenu.isEmpty()){ contextMenu.exec( e->globalPos() ); } + if (!contextMenu.isEmpty()) { contextMenu.exec( e->globalPos() ); } } } @@ -489,7 +489,8 @@ QList FileBrowserTreeWidget::getContextActions(FileItem* file, bool so [=]{ openInNewInstrumentTrack(file, songEditor); }); result.append(toInstrument); - if (songEditor && fileIsSample){ + if (songEditor && fileIsSample) + { QAction* toSampleTrack = new QAction( tr("Send to new sample track (Shift + Enter)"), nullptr @@ -510,7 +511,7 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) // Forward the event QTreeWidget::mousePressEvent(me); // QTreeWidget handles right clicks for us, so we only care about left clicks - if(me->button() != Qt::LeftButton){ return; } + if(me->button() != Qt::LeftButton) { return; } QTreeWidgetItem * i = itemAt(me->pos()); if (i) @@ -528,7 +529,7 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) } FileItem * f = dynamic_cast(i); - if(f != nullptr){ previewFileItem(f); } + if(f != nullptr) { previewFileItem(f); } } @@ -693,7 +694,6 @@ void FileBrowserTreeWidget::mouseReleaseEvent(QMouseEvent * me ) - void FileBrowserTreeWidget::handleFile(FileItem * f, InstrumentTrack * it) { Engine::mixer()->requestChangeInModel(); @@ -789,7 +789,7 @@ void FileBrowserTreeWidget::openInNewInstrumentTrack(FileItem* item, bool songEd { // Get the correct TrackContainer. Ternary doesn't compile here TrackContainer* tc = Engine::getSong(); - if (!songEditor){ tc = Engine::getBBTrackContainer(); } + if (!songEditor) { tc = Engine::getBBTrackContainer(); } openInNewInstrumentTrack(tc, item); } @@ -799,7 +799,7 @@ void FileBrowserTreeWidget::openInNewInstrumentTrack(FileItem* item, bool songEd bool FileBrowserTreeWidget::openInNewSampleTrack(FileItem* item) { // Can't add non-samples to a sample track - if (item->type() != FileItem::SampleFile){ return false; } + if (item->type() != FileItem::SampleFile) { return false; } // Create a new sample track for this sample SampleTrack* sampleTrack = static_cast( From 9d60c0ea58f99493b255d9a5e3232281b755a581 Mon Sep 17 00:00:00 2001 From: Spekular Date: Sat, 3 Oct 2020 18:52:39 +0200 Subject: [PATCH 18/18] More review fixes --- include/FileBrowser.h | 2 +- src/gui/FileBrowser.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index 70dc82426f6..a890506bdf3 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -113,7 +113,7 @@ class FileBrowserTreeWidget : public QTreeWidget private: //! Start a preview of a file item void previewFileItem(FileItem* file); - //! If a preview is playing, stop it. Returns false if nothing was playing + //! If a preview is playing, stop it. void stopPreview(); void handleFile( FileItem * fi, InstrumentTrack * it ); diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 6b050cdfec8..0524146069e 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -688,6 +688,7 @@ void FileBrowserTreeWidget::mouseReleaseEvent(QMouseEvent * me ) } else { stopPreview(); } } + else { stopPreview(); } } } @@ -807,7 +808,7 @@ bool FileBrowserTreeWidget::openInNewSampleTrack(FileItem* item) // Add the sample clip to the track Engine::mixer()->requestChangeInModel(); - SampleTCO* clip = dynamic_cast(sampleTrack->createTCO(0)); + SampleTCO* clip = static_cast(sampleTrack->createTCO(0)); clip->setSampleFile(item->fullName()); Engine::mixer()->doneChangeInModel(); return true;