using System;
|
using System.ComponentModel;
|
using System.IO;
|
using System.Numerics;
|
using System.Runtime.CompilerServices;
|
|
namespace OpenTap.Addin.Util
|
{
|
public class LocationString : INotifyPropertyChanged
|
{
|
#region ...
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
public void OnPropertyChanged(string propertyName)
|
{
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
UserInput.NotifyChanged(this, propertyName);
|
}
|
|
protected void Set([CallerMemberName] string name = null)
|
{
|
OnPropertyChanged(name);
|
}
|
|
protected void Set<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
|
{
|
old = @new;
|
if (propertyName != null)
|
{
|
Set(propertyName);
|
}
|
}
|
#endregion
|
|
private string relativeLocation = string.Empty;
|
public string RelativeLocation
|
{
|
get => relativeLocation;
|
set
|
{
|
Set(ref relativeLocation, value);
|
}
|
}
|
|
private string absoluteLocation = string.Empty;
|
public string AbsoluteLocation
|
{
|
get => absoluteLocation;
|
set
|
{
|
Set(ref absoluteLocation, value);
|
}
|
}
|
|
private static string AppendDirectorySeparator(string path)
|
{
|
// 如果是目录路径,确保以分隔符结尾
|
if (!path.EndsWith(Path.DirectorySeparatorChar.ToString()) &&
|
!path.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
|
{
|
// 检查是否是目录(简单判断:没有扩展名或明确是目录)
|
if (Directory.Exists(path))
|
path += Path.DirectorySeparatorChar;
|
}
|
return path;
|
}
|
|
public static string GetRelativePath(string fromPath, string toPath)
|
{
|
// 获取绝对路径
|
fromPath = Path.GetFullPath(fromPath);
|
toPath = Path.GetFullPath(toPath);
|
|
// 如果路径不在同一根目录下(如 C:\ 和 D:\),无法计算相对路径
|
if (!string.Equals(Path.GetPathRoot(fromPath),
|
Path.GetPathRoot(toPath),
|
StringComparison.OrdinalIgnoreCase))
|
{
|
return toPath; // 返回绝对路径
|
}
|
|
// 使用 Uri 计算相对路径
|
Uri fromUri = new Uri(AppendDirectorySeparator(fromPath));
|
Uri toUri = new Uri(AppendDirectorySeparator(toPath));
|
|
Uri relativeUri = fromUri.MakeRelativeUri(toUri);
|
string relativePath = Uri.UnescapeDataString(relativeUri.ToString());
|
|
// 转换为文件路径格式
|
relativePath = relativePath.Replace('/', Path.DirectorySeparatorChar);
|
|
// 移除开头的分隔符(如果有)
|
if (relativePath.StartsWith(Path.DirectorySeparatorChar.ToString()))
|
relativePath = relativePath.Substring(1);
|
|
return relativePath;
|
}
|
|
public static string GetAbsolutePath(string basePath, string relativePath)
|
{
|
if (string.IsNullOrEmpty(basePath))
|
{
|
return relativePath;
|
}
|
string dirPath = Path.GetDirectoryName(basePath);
|
string combinedPath = Path.Combine(dirPath, relativePath);
|
return Path.GetFullPath(combinedPath);
|
}
|
|
public void Refresh(string basePath)
|
{
|
if (string.IsNullOrEmpty(basePath))
|
{
|
return;
|
}
|
|
string path = LocationString.GetAbsolutePath(basePath, RelativeLocation);
|
if (File.Exists(path))
|
{
|
if (Path.IsPathRooted(RelativeLocation))
|
{
|
RelativeLocation = LocationString.GetRelativePath(basePath, path);
|
}
|
AbsoluteLocation = path;
|
return;
|
}
|
if (File.Exists(AbsoluteLocation))
|
{
|
path = LocationString.GetRelativePath(basePath, AbsoluteLocation);
|
RelativeLocation = path;
|
return;
|
}
|
}
|
|
public bool GetLocation(string basePath, out string location)
|
{
|
location = null;
|
if (Path.IsPathRooted(RelativeLocation))
|
{
|
if (File.Exists(RelativeLocation))
|
{
|
location = RelativeLocation;
|
return true;
|
}
|
}
|
else
|
{
|
string path = GetAbsolutePath(basePath, RelativeLocation);
|
if (File.Exists(path))
|
{
|
location = path;
|
return true;
|
}
|
}
|
|
if (File.Exists(AbsoluteLocation))
|
{
|
location = AbsoluteLocation;
|
return true;
|
}
|
return false;
|
}
|
}
|
}
|