Skip to content

Commit 4ea3623

Browse files
committed
Adding support for proper absolute/canonical path detection and replacement
1 parent 8b3167a commit 4ea3623

File tree

1 file changed

+38
-12
lines changed

1 file changed

+38
-12
lines changed

src/Timeline.cpp

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -117,28 +117,54 @@ Timeline::Timeline(std::string projectPath, bool convert_absolute_paths) :
117117
QDir asset_folder(filePath.dir().filePath(asset_name));
118118
if (!asset_folder.exists()) {
119119
// Create directory if needed
120-
asset_folder.makeAbsolute();
120+
asset_folder.mkpath(".");
121121
}
122122

123123
// Load UTF-8 project file into QString
124124
QFile projectFile(QString::fromStdString(path));
125125
projectFile.open(QFile::ReadOnly);
126126
QString projectContents = QString::fromUtf8(projectFile.readAll());
127127

128-
// Convert all relative paths into absolute paths (does not support relative paths with ../)
129-
// In otherwords, assets and files must be located in a child/sub-folder (and not from outside this folder)
128+
// Convert all relative paths into absolute paths (if requested)
130129
if (convert_absolute_paths) {
131-
// Convert all paths into absolute (if requested)
132-
QRegularExpression pathRegex(QStringLiteral("\"(image|path)\":.*?\"(?:\\./)?(?!@assets|@transitions+)(.*?)\""));
133-
projectContents.replace(pathRegex, "\"\\1\": \"" + filePath.absoluteDir().absoluteFilePath("\\2") + "\"");
134130

135-
// Convert all transitions paths into absolute (if requested)
136-
QRegularExpression transRegex(QStringLiteral("\"(image|path)\":.*?\"@transitions/*(.*?)\""));
137-
projectContents.replace(transRegex, "\"\\1\": \"" + openshotTransPath.absoluteFilePath("\\2") + "\"");
131+
// Find all "image" or "path" references in JSON (using regex). Must loop through match results
132+
// due to our path matching needs, which are not possible with the QString::replace() function.
133+
QRegularExpression allPathsRegex(QStringLiteral("\"(image|path)\":.*?\"(.*?)\""));
134+
std::vector<QRegularExpressionMatch> matchedPositions;
135+
QRegularExpressionMatchIterator i = allPathsRegex.globalMatch(projectContents);
136+
while (i.hasNext()) {
137+
QRegularExpressionMatch match = i.next();
138+
if (match.hasMatch()) {
139+
// Push all match objects into a vector (so we can reverse them later)
140+
matchedPositions.push_back(match);
141+
}
142+
}
143+
144+
// Reverse the matches (bottom of file to top, so our replacements don't break our match positions)
145+
std::vector<QRegularExpressionMatch>::reverse_iterator itr;
146+
for (itr = matchedPositions.rbegin(); itr != matchedPositions.rend(); itr++) {
147+
QRegularExpressionMatch match = *itr;
148+
QString relativeKey = match.captured(1); // image or path
149+
QString relativePath = match.captured(2); // relative file path
150+
QString absolutePath = "";
151+
152+
// Find absolute path of all path, image (including special replacements of @assets and @transitions)
153+
if (relativePath.startsWith("@assets")) {
154+
absolutePath = QFileInfo(asset_folder.absoluteFilePath(relativePath.replace("@assets", "."))).canonicalFilePath();
155+
} else if (relativePath.startsWith("@transitions")) {
156+
absolutePath = QFileInfo(openshotTransPath.absoluteFilePath(relativePath.replace("@transitions", "."))).canonicalFilePath();
157+
} else {
158+
absolutePath = QFileInfo(filePath.absoluteDir().absoluteFilePath(relativePath)).canonicalFilePath();
159+
}
138160

139-
// Convert all assets paths into absolute
140-
QRegularExpression assetRegex(QStringLiteral("\"(image|path)\":.*?\"@assets/*(.*?)\""));
141-
projectContents.replace(assetRegex, "\"\\1\": \"" + asset_folder.absoluteFilePath("\\2") + "\"");
161+
// Replace path in JSON content, if an absolute path was successfully found
162+
if (!absolutePath.isEmpty()) {
163+
projectContents.replace(match.capturedStart(0), match.capturedLength(0), "\"" + relativeKey + "\": \"" + absolutePath + "\"");
164+
}
165+
}
166+
// Clear matches
167+
matchedPositions.clear();
142168
}
143169

144170
// Set JSON of project

0 commit comments

Comments
 (0)