Allow relative paths on non-existent directories - #4271
Conversation
| { | ||
| // Normalize the path | ||
| QString f = QFileInfo( file ).canonicalFilePath().replace( QDir::separator(), '/' ); | ||
| QString f( QDir::cleanPath( file ).replace( QDir::separator(), '/' ) ); |
There was a problem hiding this comment.
Just a reminder, .replace( QDir::separator(), '/' ) can be removed when Qt4 support is completely dropped later.
There was a problem hiding this comment.
Just a reminder,
.replace( QDir::separator(), '/' )can be removed when Qt4 support is completely dropped later.
Good to know... can you elaborate? Is the default behavior to use / in Qt5? If so where is this documented and is this across all Qt functions?
There was a problem hiding this comment.
Documented in http://doc.qt.io/qt-5/qdir.html#cleanPath
There was a problem hiding this comment.
Documented in http://doc.qt.io/qt-5/qdir.html#cleanPath
Yeah that doesn't have any "since qt5" warnings, so I just thought it was an example. Thanks for clarification.
There was a problem hiding this comment.
For comparison:
4.8:
Removes all multiple directory separators
"/"and resolves any"."s or".."s found in the path,path.
5.x:
Returns path with directory separators normalized (converted to
"/") and redundant ones removed, and"."s and".."s resolved (as far as possible).
So I hope you understand my hesitation. :)
There was a problem hiding this comment.
Hmm.... Here's the code for posterity...
static QString qt_cleanPath(const QString &path, bool *ok)
--
{
if (path.isEmpty())
return path;
QString name = path;
QChar dir_separator = QDir::separator();
if (dir_separator != QLatin1Char('/'))
name.replace(dir_separator, QLatin1Char('/'));
QString ret = qt_normalizePathSegments(name, OSSupportsUncPaths, ok);
// Strip away last slash except for root directories
if (ret.length() > 1 && ret.endsWith(QLatin1Char('/'))) {
#if defined (Q_OS_WIN)
# if defined(Q_OS_WINRT)
if (!((ret.length() == 3 \|\| ret.length() == QDir::rootPath().length()) && ret.at(1) == QLatin1Char(':')))
# else
if (!(ret.length() == 3 && ret.at(1) == QLatin1Char(':')))
# endif
#endif
ret.chop(1);
}
return ret;
}
The only function that seems like it would touch \\ would be the qt_normalizePathSegments.cpp, but that specifically says in the source
// This method is shared with QUrl, so it doesn't deal with QDir::separator() ...I guess I'll take your word for it. :)
There was a problem hiding this comment.
@tresf it's about a third of the way down in that qt_cleanPath function:
name.replace(dir_separator, QLatin1Char('/'));
How do you feel about adding a short code comment explaining why we run .replace( QDir::separator(), '/' ) (maybe just linking to #4271 ) so that nobody else accidentally removes it, forgetting about Qt4 support?
There was a problem hiding this comment.
Looking into Qt4's code, I found that even Qt 4.0 has the replacement logic. So we can safely remove that.
There was a problem hiding this comment.
dir_separator, got it! Missed that one. Thanks!
So we can safely remove that.
Agreed. Will do.
|
I haven't actually tested any of this code myself (e.g for regressions to #4267). For starters, I was confused that @PhysSong I'll let you merge this one since you're the bug submitter and the most likely to have tested this. :) |
|
Seems like a lot of chatter over a string replacement, but this knowledge is only going to benefit the project for years to come. Thanks for the digging. |
|
I found some more places where |
|
@PhysSong Given this PR is from a tresf branch, I don't think you can easily add your own changes on top of this PR. I would say merge this one and then create a new PR for your changes. |
|
Actually GitHub allows PRs to be modified now. It's a great feature especially for abandoned ones. we do it fairly often now. :) |
|
What I'd like to do is using index 141085dd2..62bebff7c 100644
--- a/src/core/SampleBuffer.cpp
+++ b/src/core/SampleBuffer.cpp
@@ -1425,7 +1425,7 @@ QString SampleBuffer::tryToMakeRelative( const QString & file )
// Iterate over all valid "data:/" searchPaths
for ( const QString & path : QDir::searchPaths( "data" ) )
{
- QString samplesPath = QString( path + samplesSuffix ).replace( QDir::separator(), '/' );
+ QString samplesPath = QDir::cleanPath( path + samplesSuffix ) + "/";
if ( f.startsWith( samplesPath ) )
{
return QString( f ).mid( samplesPath.length() ); |
|
Not sure how well the |
| for ( const QString & path : QDir::searchPaths( "data" ) ) | ||
| { | ||
| QString samplesPath = QString( path + samplesSuffix ).replace( QDir::separator(), '/' ); | ||
| QString samplesPath = QDir::cleanPath( path + samplesSuffix ) + "/"; |
There was a problem hiding this comment.
I believe ensureTrailingSlash may be better here. The previous logic doesn't add any slashes.
There was a problem hiding this comment.
Maybe, but don't have to be. QDir::cleanPath always strips trailing slash and previous logic always gives a path with trailing slash.
BTW, ensureTrailingSlash is defined in ConfigManager.cpp. If you want to use that function, you should move that into an header first.
|
Didn't know about trailing slash strip. That's nice. Looks good then. Merge? |
* Use cleanPath for calculating relative directories Closes LMMS#4267
Switch
SampleBuffer::tryToMakeRelative(...)to usecleanPathinstead ofcanonicalFilePath.canonicalFilePathhas several limitations including: