瀏覽代碼

Use performNativeCopy instead of copy (#6185)

George King 2 周之前
父節點
當前提交
4fcca634ea

+ 22 - 16
launcher/helper.cpp

@@ -42,6 +42,19 @@ static QScrollerProperties generateScrollerProperties()
 }
 #endif
 
+#ifdef VCMI_ANDROID
+static QString safeEncode(QString uri)
+{
+	// %-encode unencoded parts of string.
+	// This is needed because Qt returns a mixed content url with %-encoded and unencoded parts. On Android >= 13 this causes problems reading these files, when using spaces and unicode characters in folder or filename.
+	// Only these should be encoded (other typically %-encoded chars should not be encoded because this leads to errors).
+	// Related, but seems not completly fixed (at least in our setup): https://bugreports.qt.io/browse/QTBUG-114435
+	if (!uri.startsWith("content://", Qt::CaseInsensitive))
+		return uri;
+	return QString::fromUtf8(QUrl::toPercentEncoding(uri, "!#$&'()*+,/:;=?@[]<>{}\"`^~%"));
+}
+#endif
+
 namespace Helper
 {
 void loadSettings()
@@ -77,35 +90,28 @@ QString getRealPath(QString path)
 #ifdef VCMI_ANDROID
 	if(path.contains("content://", Qt::CaseInsensitive))
 	{
-		auto str = QAndroidJniObject::fromString(path);
+		auto str = QAndroidJniObject::fromString(safeEncode(path));
 		return QAndroidJniObject::callStaticObjectMethod("eu/vcmi/vcmi/util/FileUtil", "getFilenameFromUri", "(Ljava/lang/String;Landroid/content/Context;)Ljava/lang/String;", str.object<jstring>(), QtAndroid::androidContext().object()).toString();
 	}
-	else
-		return path;
+	return path;
 #else
 	return path;
 #endif
 }
 
-void performNativeCopy(QString src, QString dst)
+bool performNativeCopy(QString src, QString dst)
 {
 #ifdef VCMI_ANDROID
-	// %-encode unencoded parts of string.
-	// This is needed because Qt returns a mixed content url with %-encoded and unencoded parts. On Android >= 13 this causes problems reading these files, when using spaces and unicode characters in folder or filename.
-	// Only these should be encoded (other typically %-encoded chars should not be encoded because this leads to errors).
-	// Related, but seems not completly fixed (at least in our setup): https://bugreports.qt.io/browse/QTBUG-114435
-	auto safeEncode = [&](QString uri) -> QString
-	{
-		if(!uri.startsWith("content://", Qt::CaseInsensitive))
-			return uri;
-		return QString::fromUtf8(QUrl::toPercentEncoding(uri, "!#$&'()*+,/:;=?@[]<>{}\"`^~%"));
-	};
-
 	auto srcStr = QAndroidJniObject::fromString(safeEncode(src));
 	auto dstStr = QAndroidJniObject::fromString(safeEncode(dst));
 	QAndroidJniObject::callStaticObjectMethod("eu/vcmi/vcmi/util/FileUtil", "copyFileFromUri", "(Ljava/lang/String;Ljava/lang/String;Landroid/content/Context;)V", srcStr.object<jstring>(), dstStr.object<jstring>(), QtAndroid::androidContext().object());
+
+	if(QFileInfo(dst).exists())
+		return true;
+	else
+		return false;
 #else
-	QFile::copy(src, dst);
+	return QFile::copy(src, dst);
 #endif
 }
 

+ 1 - 1
launcher/helper.h

@@ -20,7 +20,7 @@ void loadSettings();
 void reLoadSettings();
 void enableScrollBySwiping(QObject * scrollTarget);
 QString getRealPath(QString path);
-void performNativeCopy(QString src, QString dst);
+bool performNativeCopy(QString src, QString dst);
 void revealDirectoryInFileBrowser(QString path);
 MainWindow * getMainWindow();
 void keepScreenOn(bool isEnabled);

+ 1 - 1
launcher/mainwindow_moc.cpp

@@ -295,7 +295,7 @@ void MainWindow::manualInstallFile(QString filePath)
 			{
 				const auto configFilePath = configDir.filePath(configFile[0]);
 				QFile::remove(configFilePath);
-				QFile::copy(filePath, configFilePath);
+				Helper::performNativeCopy(filePath, configFilePath);
 
 				Helper::reLoadSettings();
 			}

+ 2 - 2
launcher/modManager/chroniclesextractor.cpp

@@ -133,7 +133,7 @@ void ChroniclesExtractor::createBaseMod() const
 		{
 			QDir().mkpath(pathToQString(destFolder));
 			QFile::remove(destFile);
-			QFile::copy(file, destFile);
+			Helper::performNativeCopy(file, destFile);
 		}
 	}
 }
@@ -237,7 +237,7 @@ void ChroniclesExtractor::extractFiles(int no) const
 				continue;
 			auto srcName = vstd::reverseMap(mapping).at(no);
 			auto dstName = (no == 7 || no == 8) ? srcName : "Intro";
-			QFile::copy(tmpDir.filePath(QString::fromStdString(srcName + ending)), outDirVideo.filePath(QString::fromStdString(dstName + ending)));
+			Helper::performNativeCopy(tmpDir.filePath(QString::fromStdString(srcName + ending)), outDirVideo.filePath(QString::fromStdString(dstName + ending)));
 		}
 	}
 

+ 1 - 1
launcher/modManager/cmodlistview_moc.cpp

@@ -1212,7 +1212,7 @@ void CModListView::installMaps(QStringList maps)
 				QFile::remove(destFile);
 			}
 
-			if (QFile::copy(map, destFile))
+			if (Helper::performNativeCopy(map, destFile))
 				successCount++;
 			else
 			{