diff --git a/include/PathUtil.h b/include/PathUtil.h new file mode 100644 index 000000000..cc6b982a1 --- /dev/null +++ b/include/PathUtil.h @@ -0,0 +1,41 @@ +#ifndef PATHUTIL_H +#define PATHUTIL_H + +#include "lmms_export.h" + +#include + +namespace PathUtil +{ + enum class Base { Absolute, ProjectDir, FactorySample, UserSample, UserVST, Preset, + UserLADSPA, DefaultLADSPA, UserSoundfont, DefaultSoundfont, UserGIG, DefaultGIG }; + + //! Return the directory associated with a given base as a QString + QString LMMS_EXPORT baseLocation(const Base base); + //! Return the directory associated with a given base as a QDir + QDir LMMS_EXPORT baseQDir (const Base base); + //! Return the prefix used to denote this base in path strings + QString LMMS_EXPORT basePrefix(const Base base); + //! Check the prefix of a path and return the base it corresponds to + //! Defaults to Base::Absolute + Base LMMS_EXPORT baseLookup(const QString & path); + + //! Remove the prefix from a path, iff there is one + QString LMMS_EXPORT stripPrefix(const QString & path); + //! Get the filename for a path, handling prefixed paths correctly + QString LMMS_EXPORT cleanName(const QString & path); + + //! Upgrade prefix-less relative paths to the new format + QString LMMS_EXPORT oldRelativeUpgrade(const QString & input); + + //! Make this path absolute + QString LMMS_EXPORT toAbsolute(const QString & input); + //! Make this path relative to a given base, return an absolute path if that fails + QString LMMS_EXPORT relativeOrAbsolute(const QString & input, const Base base); + //! Make this path relative to any base, choosing the shortest if there are + //! multiple options. Defaults to an absolute path if all bases fail. + QString LMMS_EXPORT toShortestRelative(const QString & input); + +} + +#endif diff --git a/include/SampleBuffer.h b/include/SampleBuffer.h index 26e856025..89a3add3b 100644 --- a/include/SampleBuffer.h +++ b/include/SampleBuffer.h @@ -84,7 +84,7 @@ public: { m_isBackwards = _backwards; } - + int interpolationMode() const { return m_interpolationMode; @@ -251,9 +251,6 @@ public: m_varLock.unlock(); } - static QString tryToMakeRelative( const QString & _file ); - static QString tryToMakeAbsolute(const QString & file); - public slots: void setAudioFile( const QString & _audio_file ); diff --git a/plugins/GigPlayer/GigPlayer.cpp b/plugins/GigPlayer/GigPlayer.cpp index b358e24e9..334e2bd77 100644 --- a/plugins/GigPlayer/GigPlayer.cpp +++ b/plugins/GigPlayer/GigPlayer.cpp @@ -28,6 +28,7 @@ * */ +#include "GigPlayer.h" #include #include @@ -35,18 +36,18 @@ #include #include -#include "FileDialog.h" -#include "GigPlayer.h" -#include "Engine.h" -#include "InstrumentTrack.h" -#include "InstrumentPlayHandle.h" -#include "Mixer.h" -#include "NotePlayHandle.h" -#include "Knob.h" -#include "SampleBuffer.h" -#include "Song.h" #include "ConfigManager.h" #include "endian_handling.h" +#include "Engine.h" +#include "FileDialog.h" +#include "InstrumentTrack.h" +#include "InstrumentPlayHandle.h" +#include "Knob.h" +#include "Mixer.h" +#include "NotePlayHandle.h" +#include "PathUtil.h" +#include "SampleBuffer.h" +#include "Song.h" #include "PatchesDialog.h" #include "ToolTip.h" @@ -211,8 +212,8 @@ void GigInstrument::openFile( const QString & _gigFile, bool updateTrackName ) try { - m_instance = new GigInstance( SampleBuffer::tryToMakeAbsolute( _gigFile ) ); - m_filename = SampleBuffer::tryToMakeRelative( _gigFile ); + m_instance = new GigInstance( PathUtil::toAbsolute( _gigFile ) ); + m_filename = PathUtil::toShortestRelative( _gigFile ); } catch( ... ) { @@ -225,7 +226,7 @@ void GigInstrument::openFile( const QString & _gigFile, bool updateTrackName ) if( updateTrackName == true ) { - instrumentTrack()->setName( QFileInfo( _gigFile ).baseName() ); + instrumentTrack()->setName(PathUtil::cleanName( _gigFile ) ); updatePatch(); } } @@ -1057,7 +1058,7 @@ void GigInstrumentView::showFileDialog() if( k->m_filename != "" ) { - QString f = SampleBuffer::tryToMakeAbsolute( k->m_filename ); + QString f = PathUtil::toAbsolute( k->m_filename ); ofd.setDirectory( QFileInfo( f ).absolutePath() ); ofd.selectFile( QFileInfo( f ).fileName() ); } diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index c8850392e..51af71f55 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -22,6 +22,7 @@ * */ +#include "audio_file_processor.h" #include #include @@ -31,18 +32,18 @@ #include -#include "audio_file_processor.h" #include "ConfigManager.h" +#include "DataFile.h" #include "Engine.h" -#include "Song.h" +#include "gui_templates.h" #include "InstrumentTrack.h" +#include "interpolation.h" #include "Mixer.h" #include "NotePlayHandle.h" -#include "interpolation.h" -#include "gui_templates.h" -#include "ToolTip.h" +#include "PathUtil.h" +#include "Song.h" #include "StringPairDrag.h" -#include "DataFile.h" +#include "ToolTip.h" #include "embed.h" #include "plugin_export.h" @@ -97,13 +98,13 @@ audioFileProcessor::audioFileProcessor( InstrumentTrack * _instrument_track ) : this, SLOT( loopPointChanged() ) ); connect( &m_stutterModel, SIGNAL( dataChanged() ), this, SLOT( stutterModelChanged() ) ); - + //interpolation modes m_interpolationModel.addItem( tr( "None" ) ); m_interpolationModel.addItem( tr( "Linear" ) ); m_interpolationModel.addItem( tr( "Sinc" ) ); m_interpolationModel.setValue( 1 ); - + pointChanged(); } @@ -237,7 +238,7 @@ void audioFileProcessor::loadSettings( const QDomElement & _this ) { setAudioFile( _this.attribute( "src" ), false ); - QString absolutePath = m_sampleBuffer.tryToMakeAbsolute( m_sampleBuffer.audioFile() ); + QString absolutePath = PathUtil::toAbsolute( m_sampleBuffer.audioFile() ); if ( !QFileInfo( absolutePath ).exists() ) { QString message = tr( "Sample not found: %1" ).arg( m_sampleBuffer.audioFile() ); @@ -329,7 +330,7 @@ void audioFileProcessor::setAudioFile( const QString & _audio_file, m_sampleBuffer.audioFile().isEmpty() ) ) { // then set it to new one - instrumentTrack()->setName( QFileInfo( _audio_file).fileName() ); + instrumentTrack()->setName( PathUtil::cleanName( _audio_file ) ); } // else we don't touch the track-name, because the user named it self @@ -363,7 +364,7 @@ void audioFileProcessor::stutterModelChanged() } -void audioFileProcessor::startPointChanged( void ) +void audioFileProcessor::startPointChanged( void ) { // check if start is over end and swap values if so if( m_startPointModel.value() > m_endPointModel.value() ) @@ -390,7 +391,7 @@ void audioFileProcessor::startPointChanged( void ) { m_endPointModel.setValue( qMin( m_endPointModel.value() + 0.001f, 1.0f ) ); } - + pointChanged(); } @@ -1284,7 +1285,3 @@ PLUGIN_EXPORT Plugin * lmms_plugin_main(Model * model, void *) } - - - - diff --git a/plugins/patman/patman.cpp b/plugins/patman/patman.cpp index 8a0c71340..e51703834 100644 --- a/plugins/patman/patman.cpp +++ b/plugins/patman/patman.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 2007-2008 Javier Serrano Polo * Copyright (c) 2009-2014 Tobias Doerffel - * + * * This file is part of LMMS - https://lmms.io * * This program is free software; you can redistribute it and/or @@ -32,15 +32,15 @@ #include "ConfigManager.h" #include "endian_handling.h" #include "Engine.h" +#include "FileDialog.h" #include "gui_templates.h" #include "InstrumentTrack.h" #include "NotePlayHandle.h" +#include "PathUtil.h" #include "PixmapButton.h" #include "Song.h" #include "StringPairDrag.h" #include "ToolTip.h" -#include "FileDialog.h" -#include "ConfigManager.h" #include "embed.h" @@ -192,14 +192,13 @@ void patmanInstrument::setFile( const QString & _patch_file, bool _rename ) m_patchFile == "" ) ) { // then set it to new one - instrumentTrack()->setName( QFileInfo( _patch_file - ).fileName() ); + instrumentTrack()->setName( PathUtil::cleanName( _patch_file ) ); } // else we don't touch the instrument-track-name, because the user // named it self - m_patchFile = SampleBuffer::tryToMakeRelative( _patch_file ); - LoadErrors error = loadPatch( SampleBuffer::tryToMakeAbsolute( _patch_file ) ); + m_patchFile = PathUtil::toShortestRelative( _patch_file ); + LoadErrors error = loadPatch( PathUtil::toAbsolute( _patch_file ) ); if( error ) { printf("Load error\n"); @@ -625,8 +624,8 @@ void PatmanView::paintEvent( QPaintEvent * ) QPainter p( this ); p.setFont( pointSize<8>( font() ) ); - p.drawText( 8, 116, 235, 16, - Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter, + p.drawText( 8, 116, 235, 16, + Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter, m_displayFilename ); } @@ -641,8 +640,3 @@ void PatmanView::modelChanged( void ) connect( m_pi, SIGNAL( fileChanged() ), this, SLOT( updateFilename() ) ); } - - - - - diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index 2f9456370..7065a0800 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -23,6 +23,8 @@ * */ +#include "sf2_player.h" + #include #include #include @@ -30,14 +32,14 @@ #include "ConfigManager.h" #include "FileDialog.h" -#include "sf2_player.h" #include "ConfigManager.h" #include "Engine.h" #include "InstrumentTrack.h" #include "InstrumentPlayHandle.h" +#include "Knob.h" #include "Mixer.h" #include "NotePlayHandle.h" -#include "Knob.h" +#include "PathUtil.h" #include "SampleBuffer.h" #include "Song.h" @@ -372,8 +374,8 @@ void sf2Instrument::openFile( const QString & _sf2File, bool updateTrackName ) emit fileLoading(); // Used for loading file - char * sf2Ascii = qstrdup( qPrintable( SampleBuffer::tryToMakeAbsolute( _sf2File ) ) ); - QString relativePath = SampleBuffer::tryToMakeRelative( _sf2File ); + char * sf2Ascii = qstrdup( qPrintable( PathUtil::toAbsolute( _sf2File ) ) ); + QString relativePath = PathUtil::toShortestRelative( _sf2File ); // free reference to soundfont if one is selected freeFont(); @@ -435,7 +437,7 @@ void sf2Instrument::openFile( const QString & _sf2File, bool updateTrackName ) if( updateTrackName || instrumentTrack()->displayName() == displayName() ) { - instrumentTrack()->setName( QFileInfo( _sf2File ).baseName() ); + instrumentTrack()->setName( PathUtil::cleanName( _sf2File ) ); } } @@ -1145,7 +1147,7 @@ void sf2InstrumentView::showFileDialog() if( k->m_filename != "" ) { - QString f = SampleBuffer::tryToMakeAbsolute( k->m_filename ); + QString f = PathUtil::toAbsolute( k->m_filename ); ofd.setDirectory( QFileInfo( f ).absolutePath() ); ofd.selectFile( QFileInfo( f ).fileName() ); } diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index 0d75992a4..b17a16845 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -40,24 +40,24 @@ #include -#include "ConfigManager.h" #include "BufferManager.h" #include "ConfigManager.h" #include "Engine.h" +#include "FileDialog.h" +#include "GuiApplication.h" #include "gui_templates.h" #include "InstrumentPlayHandle.h" #include "InstrumentTrack.h" #include "LocaleHelper.h" #include "MainWindow.h" #include "Mixer.h" -#include "GuiApplication.h" +#include "PathUtil.h" #include "PixmapButton.h" #include "SampleBuffer.h" #include "Song.h" #include "StringPairDrag.h" #include "TextFloat.h" #include "ToolTip.h" -#include "FileDialog.h" #include "embed.h" @@ -271,7 +271,7 @@ void vestigeInstrument::reloadPlugin() void vestigeInstrument::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - _this.setAttribute( "plugin", m_pluginDLL ); + _this.setAttribute( "plugin", PathUtil::toShortestRelative(m_pluginDLL) ); m_pluginMutex.lock(); if( m_plugin != NULL ) { @@ -338,14 +338,14 @@ void vestigeInstrument::loadFile( const QString & _file ) // if the same is loaded don't load again (for preview) if (instrumentTrack() != NULL && instrumentTrack()->isPreviewMode() && - m_pluginDLL == SampleBuffer::tryToMakeRelative( _file )) + m_pluginDLL == PathUtil::toShortestRelative( _file )) return; if ( m_plugin != NULL ) { closePlugin(); } - m_pluginDLL = SampleBuffer::tryToMakeRelative( _file ); + m_pluginDLL = PathUtil::toShortestRelative( _file ); TextFloat * tf = NULL; if( gui ) { @@ -686,7 +686,7 @@ void VestigeInstrumentView::openPlugin() if( m_vi->m_pluginDLL != "" ) { - QString f = SampleBuffer::tryToMakeAbsolute( m_vi->m_pluginDLL ); + QString f = PathUtil::toAbsolute( m_vi->m_pluginDLL ); ofd.setDirectory( QFileInfo( f ).absolutePath() ); ofd.selectFile( QFileInfo( f ).fileName() ); } @@ -1233,7 +1233,3 @@ Q_DECL_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) } - - - - diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index cd4844b81..7d6a45940 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -59,6 +59,7 @@ #include "LocaleHelper.h" #include "MainWindow.h" #include "Mixer.h" +#include "PathUtil.h" #include "Song.h" #include "FileDialog.h" @@ -121,7 +122,7 @@ private: VstPlugin::VstPlugin( const QString & _plugin ) : - m_plugin( _plugin ), + m_plugin( PathUtil::toAbsolute(_plugin) ), m_pluginWindowID( 0 ), m_embedMethod( gui ? ConfigManager::inst()->vstEmbedMethod() @@ -129,11 +130,6 @@ VstPlugin::VstPlugin( const QString & _plugin ) : m_version( 0 ), m_currentProgram() { - if( QDir::isRelativePath( m_plugin ) ) - { - m_plugin = ConfigManager::inst()->vstDir() + m_plugin; - } - setSplittedChannels( true ); PE::MachineType machineType; @@ -804,7 +800,3 @@ QString VstPlugin::embedMethod() const { return m_embedMethod; } - - - - diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 42d0f6784..730791bf7 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -46,6 +46,7 @@ set(LMMS_SRCS core/Note.cpp core/NotePlayHandle.cpp core/Oscillator.cpp + core/PathUtil.cpp core/PeakController.cpp core/PerfLog.cpp core/Piano.cpp diff --git a/src/core/PathUtil.cpp b/src/core/PathUtil.cpp new file mode 100644 index 000000000..ab81c4941 --- /dev/null +++ b/src/core/PathUtil.cpp @@ -0,0 +1,148 @@ +#include "PathUtil.h" + +#include +#include +#include + +#include "ConfigManager.h" + +namespace PathUtil +{ + Base relativeBases[] = { Base::ProjectDir, Base::FactorySample, Base::UserSample, Base::UserVST, Base::Preset, + Base::UserLADSPA, Base::DefaultLADSPA, Base::UserSoundfont, Base::DefaultSoundfont, Base::UserGIG, Base::DefaultGIG }; + + QString baseLocation(const Base base) + { + QString loc = ""; + switch (base) + { + case Base::ProjectDir : loc = ConfigManager::inst()->userProjectsDir(); break; + case Base::FactorySample : + { + QDir fsd = QDir(ConfigManager::inst()->factorySamplesDir()); + loc = fsd.absolutePath(); break; + } + case Base::UserSample : loc = ConfigManager::inst()->userSamplesDir(); break; + case Base::UserVST : loc = ConfigManager::inst()->userVstDir(); break; + case Base::Preset : loc = ConfigManager::inst()->userPresetsDir(); break; + case Base::UserLADSPA : loc = ConfigManager::inst()->ladspaDir(); break; + case Base::DefaultLADSPA : loc = ConfigManager::inst()->userLadspaDir(); break; + case Base::UserSoundfont : loc = ConfigManager::inst()->sf2Dir(); break; + case Base::DefaultSoundfont : loc = ConfigManager::inst()->userSf2Dir(); break; + case Base::UserGIG : loc = ConfigManager::inst()->gigDir(); break; + case Base::DefaultGIG : loc = ConfigManager::inst()->userGigDir(); break; + default : return QString(""); + } + return QDir::cleanPath(loc) + "/"; + } + + QDir baseQDir (const Base base) { return QDir(baseLocation(base)); } + + QString basePrefix(const Base base) + { + switch (base) + { + case Base::ProjectDir : return QStringLiteral("userprojects:"); + case Base::FactorySample : return QStringLiteral("factorysample:"); + case Base::UserSample : return QStringLiteral("usersample:"); + case Base::UserVST : return QStringLiteral("uservst:"); + case Base::Preset : return QStringLiteral("preset:"); + case Base::UserLADSPA : return QStringLiteral("userladspa:"); + case Base::DefaultLADSPA : return QStringLiteral("defaultladspa:"); + case Base::UserSoundfont : return QStringLiteral("usersoundfont:"); + case Base::DefaultSoundfont : return QStringLiteral("defaultsoundfont:"); + case Base::UserGIG : return QStringLiteral("usergig:"); + case Base::DefaultGIG : return QStringLiteral("defaultgig:"); + default : return QStringLiteral(""); + } + } + + Base baseLookup(const QString & path) + { + for (auto base: relativeBases) + { + QString prefix = basePrefix(base); + if ( path.startsWith(prefix) ) { return base; } + } + return Base::Absolute; + } + + + + + QString stripPrefix(const QString & path) + { + return path.mid( basePrefix(baseLookup(path)).length() ); + } + + QString cleanName(const QString & path) + { + return stripPrefix(QFileInfo(path).baseName()); + } + + + + + QString oldRelativeUpgrade(const QString & input) + { + if (input.isEmpty()) { return input; } + + //Start by assuming that the file is a user sample + Base assumedBase = Base::UserSample; + + //Check if it's a factory sample + QString factoryPath = baseLocation(Base::FactorySample) + input; + QFileInfo factoryInfo(factoryPath); + if (factoryInfo.exists()) { assumedBase = Base::FactorySample; } + + //Check if it's a VST + QString vstPath = baseLocation(Base::UserVST) + input; + QFileInfo vstInfo(vstPath); + if (vstInfo.exists()) { assumedBase = Base::UserVST; } + + //Assume we've found the correct base location, return the full path + return basePrefix(assumedBase) + input; + } + + + + + QString toAbsolute(const QString & input) + { + //First, do no harm to absolute paths + QFileInfo inputFileInfo = QFileInfo(input); + if (inputFileInfo.isAbsolute()) { return input; } + //Next, handle old relative paths with no prefix + QString upgraded = input.contains(":") ? input : oldRelativeUpgrade(input); + + Base base = baseLookup(upgraded); + return baseLocation(base) + upgraded.remove(0, basePrefix(base).length()); + } + + QString relativeOrAbsolute(const QString & input, const Base base) + { + if (input.isEmpty()) { return input; } + QString absolutePath = toAbsolute(input); + QString relativePath = baseQDir(base).relativeFilePath(absolutePath); + return relativePath.startsWith("..") ? absolutePath : relativePath; + } + + QString toShortestRelative(const QString & input) + { + QFileInfo inputFileInfo = QFileInfo(input); + QString absolutePath = inputFileInfo.isAbsolute() ? input : toAbsolute(input); + + Base shortestBase = Base::Absolute; + QString shortestPath = relativeOrAbsolute(absolutePath, shortestBase); + for (auto base: relativeBases) + { + QString otherPath = relativeOrAbsolute(absolutePath, base); + if (otherPath.length() < shortestPath.length()) + { + shortestBase = base; + shortestPath = otherPath; + } + } + return basePrefix(shortestBase) + relativeOrAbsolute(absolutePath, shortestBase); + } +} diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp index d0c39b13a..cd943638d 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -24,7 +24,6 @@ #include "SampleBuffer.h" - #include #include #include @@ -55,11 +54,11 @@ #include "Engine.h" #include "GuiApplication.h" #include "Mixer.h" +#include "PathUtil.h" #include "FileDialog.h" - SampleBuffer::SampleBuffer() : m_audioFile( "" ), m_origData( NULL ), @@ -179,7 +178,7 @@ void SampleBuffer::update( bool _keep_settings ) } else if( !m_audioFile.isEmpty() ) { - QString file = tryToMakeAbsolute( m_audioFile ); + QString file = PathUtil::toAbsolute( m_audioFile ); int_sample_t * buf = NULL; sample_t * fbuf = NULL; ch_cnt_t channels = DEFAULT_CHANNELS; @@ -781,7 +780,7 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state, } } - if( tmp != NULL ) + if( tmp != NULL ) { MM_FREE( tmp ); } @@ -1031,7 +1030,7 @@ QString SampleBuffer::openAudioFile() const { return QString(); } - return tryToMakeRelative( ofd.selectedFiles()[0] ); + return PathUtil::toShortestRelative( ofd.selectedFiles()[0] ); } return QString(); @@ -1222,7 +1221,7 @@ SampleBuffer * SampleBuffer::resample( const sample_rate_t _src_sr, void SampleBuffer::setAudioFile( const QString & _audio_file ) { - m_audioFile = tryToMakeRelative( _audio_file ); + m_audioFile = PathUtil::toShortestRelative( _audio_file ); update(); } @@ -1419,60 +1418,6 @@ void SampleBuffer::setReversed( bool _on ) -QString SampleBuffer::tryToMakeRelative( const QString & file ) -{ - if( QFileInfo( file ).isRelative() == false ) - { - // Normalize the path - QString f( QDir::cleanPath( file ) ); - - // First, look in factory samples - // Isolate "samples/" from "data:/samples/" - QString samplesSuffix = ConfigManager::inst()->factorySamplesDir().mid( ConfigManager::inst()->dataDir().length() ); - - // Iterate over all valid "data:/" searchPaths - for ( const QString & path : QDir::searchPaths( "data" ) ) - { - QString samplesPath = QDir::cleanPath( path + samplesSuffix ) + "/"; - if ( f.startsWith( samplesPath ) ) - { - return QString( f ).mid( samplesPath.length() ); - } - } - - // Next, look in user samples - QString usd = ConfigManager::inst()->userSamplesDir(); - usd.replace( QDir::separator(), '/' ); - if( f.startsWith( usd ) ) - { - return QString( f ).mid( usd.length() ); - } - } - return file; -} - - - - -QString SampleBuffer::tryToMakeAbsolute(const QString& file) -{ - QFileInfo f(file); - - if(f.isRelative()) - { - f = QFileInfo(ConfigManager::inst()->userSamplesDir() + file); - - if(! f.exists()) - { - f = QFileInfo(ConfigManager::inst()->factorySamplesDir() + file); - } - } - - if (f.exists()) { - return f.absoluteFilePath(); - } - return file; -} @@ -1488,7 +1433,7 @@ SampleBuffer::handleState::handleState( bool _varying_pitch, int interpolation_m { int error; m_interpolationMode = interpolation_mode; - + if( ( m_resamplingData = src_new( interpolation_mode, DEFAULT_CHANNELS, &error ) ) == NULL ) { qDebug( "Error: src_new() failed in sample_buffer.cpp!\n" ); diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 9232cc8b0..86e1861c6 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -34,23 +34,24 @@ #include #include +#include "BBTrack.h" +#include "EffectRackView.h" +#include "embed.h" +#include "FxMixerView.h" #include "gui_templates.h" #include "GuiApplication.h" -#include "Song.h" -#include "embed.h" -#include "ToolTip.h" -#include "BBTrack.h" -#include "SamplePlayHandle.h" -#include "SampleRecordHandle.h" -#include "SongEditor.h" -#include "StringPairDrag.h" -#include "TimeLineWidget.h" #include "Knob.h" #include "MainWindow.h" #include "Mixer.h" -#include "EffectRackView.h" -#include "FxMixerView.h" +#include "PathUtil.h" +#include "SamplePlayHandle.h" +#include "SampleRecordHandle.h" +#include "Song.h" +#include "SongEditor.h" +#include "StringPairDrag.h" #include "TabWidget.h" +#include "TimeLineWidget.h" +#include "ToolTip.h" #include "TrackLabelButton.h" SampleTCO::SampleTCO( Track * _track ) : @@ -333,7 +334,7 @@ void SampleTCOView::updateSample() // set tooltip to filename so that user can see what sample this // sample-tco contains ToolTip::add( this, ( m_tco->m_sampleBuffer->audioFile() != "" ) ? - m_tco->m_sampleBuffer->audioFile() : + PathUtil::toAbsolute(m_tco->m_sampleBuffer->audioFile()) : tr( "Double-click to open sample" ) ); } @@ -535,9 +536,8 @@ void SampleTCOView::paintEvent( QPaintEvent * pe ) qMax( static_cast( m_tco->sampleLength() * ppb / ticksPerBar ), 1 ), rect().bottom() - 2 * spacing ); m_tco->m_sampleBuffer->visualize( p, r, pe->rect() ); - QFileInfo fileInfo(m_tco->m_sampleBuffer->audioFile()); - QString filename = fileInfo.fileName(); - paintTextLabel(filename, p); + QString name = PathUtil::cleanName(m_tco->m_sampleBuffer->audioFile()); + paintTextLabel(name, p); // disable antialiasing for borders, since its not needed p.setRenderHint( QPainter::Antialiasing, false ); diff --git a/tests/src/core/RelativePathsTest.cpp b/tests/src/core/RelativePathsTest.cpp index 6a7548377..3f1712e1b 100644 --- a/tests/src/core/RelativePathsTest.cpp +++ b/tests/src/core/RelativePathsTest.cpp @@ -26,6 +26,7 @@ #include "ConfigManager.h" #include "SampleBuffer.h" +#include "PathUtil.h" #include @@ -33,18 +34,35 @@ class RelativePathsTest : QTestSuite { Q_OBJECT private slots: - void RelativePathComparisonTests() + void PathUtilComparisonTests() { QFileInfo fi(ConfigManager::inst()->factorySamplesDir() + "/drums/kick01.ogg"); QVERIFY(fi.exists()); QString absPath = fi.absoluteFilePath(); - QString relPath = "drums/kick01.ogg"; + QString oldRelPath = "drums/kick01.ogg"; + QString relPath = PathUtil::basePrefix(PathUtil::Base::FactorySample) + "drums/kick01.ogg"; QString fuzPath = absPath; fuzPath.replace(relPath, "drums/.///kick01.ogg"); - QCOMPARE(SampleBuffer::tryToMakeRelative(absPath), relPath); - QCOMPARE(SampleBuffer::tryToMakeAbsolute(relPath), absPath); - QCOMPARE(SampleBuffer::tryToMakeRelative(fuzPath), relPath); + + //Test nicely formatted paths + QCOMPARE(PathUtil::toShortestRelative(absPath), relPath); + QCOMPARE(PathUtil::toAbsolute(relPath), absPath); + + //Test upgrading old paths + QCOMPARE(PathUtil::toShortestRelative(oldRelPath), relPath); + QCOMPARE(PathUtil::toAbsolute(oldRelPath), absPath); + + //Test weird but valid paths + QCOMPARE(PathUtil::toShortestRelative(fuzPath), relPath); + QCOMPARE(PathUtil::toAbsolute(fuzPath), absPath); + + //Empty paths should stay empty + QString empty = QString(""); + QCOMPARE(PathUtil::stripPrefix(""), empty); + QCOMPARE(PathUtil::cleanName(""), empty); + QCOMPARE(PathUtil::toAbsolute(""), empty); + QCOMPARE(PathUtil::toShortestRelative(""), empty); } } RelativePathTests;