Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e90a624c9a | ||
|
|
dd85ccd3f8 | ||
|
|
fc54e19ce2 | ||
|
|
118a920e57 | ||
|
|
975a335538 | ||
|
|
c6ec4f38b0 | ||
|
|
5a5d686be1 | ||
|
|
8fc430d124 | ||
|
|
721eb40a8a | ||
|
|
f18103751f |
@@ -228,15 +228,21 @@ namespace v2rayN.Handler
|
||||
string fileName = CoreFindexe(coreInfo);
|
||||
if (fileName == "") return -1;
|
||||
|
||||
var pathTemp = Utils.GetConfigPath($"temp_{Utils.GetGUID(false)}.json");
|
||||
File.WriteAllText(pathTemp, configStr);
|
||||
if (!File.Exists(pathTemp))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
Process p = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
Arguments = "-config stdin:",
|
||||
Arguments = $"-config \"{pathTemp}\"",
|
||||
WorkingDirectory = Utils.GetConfigPath(),
|
||||
UseShellExecute = false,
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true,
|
||||
@@ -255,15 +261,16 @@ namespace v2rayN.Handler
|
||||
p.Start();
|
||||
p.BeginOutputReadLine();
|
||||
|
||||
p.StandardInput.Write(configStr);
|
||||
p.StandardInput.Close();
|
||||
|
||||
if (p.WaitForExit(1000))
|
||||
{
|
||||
throw new Exception(p.StandardError.ReadToEnd());
|
||||
}
|
||||
|
||||
Global.processJob.AddProcess(p.Handle);
|
||||
|
||||
Thread.Sleep(1000);
|
||||
File.Delete(pathTemp);
|
||||
|
||||
return p.Id;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace v2rayN.Handler
|
||||
private Config _config;
|
||||
private CoreHandler _coreHandler;
|
||||
private List<ServerTestItem> _selecteds;
|
||||
private ESpeedActionType _actionType;
|
||||
Action<string, string, string> _updateFunc;
|
||||
|
||||
public SpeedtestHandler(Config config)
|
||||
@@ -23,7 +24,7 @@ namespace v2rayN.Handler
|
||||
{
|
||||
_config = config;
|
||||
_coreHandler = coreHandler;
|
||||
//_selecteds = Utils.DeepCopy(selecteds);
|
||||
_actionType = actionType;
|
||||
_updateFunc = update;
|
||||
|
||||
_selecteds = new List<ServerTestItem>();
|
||||
@@ -106,7 +107,7 @@ namespace v2rayN.Handler
|
||||
});
|
||||
}
|
||||
|
||||
private async Task RunRealPing()
|
||||
private Task RunRealPing()
|
||||
{
|
||||
int pid = -1;
|
||||
try
|
||||
@@ -117,7 +118,7 @@ namespace v2rayN.Handler
|
||||
if (pid < 0)
|
||||
{
|
||||
UpdateFunc("", ResUI.FailedToRunCore);
|
||||
return;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
DownloadHandle downloadHandle = new DownloadHandle();
|
||||
@@ -144,6 +145,8 @@ namespace v2rayN.Handler
|
||||
|
||||
LazyConfig.Instance.SetTestResult(it.indexId, output, "");
|
||||
UpdateFunc(it.indexId, output);
|
||||
int.TryParse(output, out int delay);
|
||||
it.delay = delay;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -162,10 +165,17 @@ namespace v2rayN.Handler
|
||||
{
|
||||
if (pid > 0) _coreHandler.CoreStopPid(pid);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task RunSpeedTestAsync()
|
||||
{
|
||||
int pid = -1;
|
||||
if (_actionType == ESpeedActionType.Mixedtest)
|
||||
{
|
||||
_selecteds = _selecteds.OrderBy(t => t.delay).ToList();
|
||||
}
|
||||
|
||||
pid = _coreHandler.LoadCoreConfigString(_config, _selecteds);
|
||||
if (pid < 0)
|
||||
@@ -177,7 +187,7 @@ namespace v2rayN.Handler
|
||||
string url = _config.constItem.speedTestUrl;
|
||||
DownloadHandle downloadHandle = new DownloadHandle();
|
||||
|
||||
var timeout = 10;
|
||||
var timeout = 8;
|
||||
foreach (var it in _selecteds)
|
||||
{
|
||||
if (!it.allowTest)
|
||||
@@ -188,6 +198,10 @@ namespace v2rayN.Handler
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (it.delay < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
_ = LazyConfig.Instance.SetTestResult(it.indexId, "", "-1");
|
||||
UpdateFunc(it.indexId, "", ResUI.Speedtesting);
|
||||
|
||||
@@ -216,6 +230,8 @@ namespace v2rayN.Handler
|
||||
{
|
||||
await RunRealPing();
|
||||
|
||||
Thread.Sleep(1000);
|
||||
|
||||
await RunSpeedTestAsync();
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ namespace v2rayN.Handler
|
||||
|
||||
if (_serverStatItem == null)
|
||||
{
|
||||
_serverStatItem = _lstServerStat.FirstOrDefault(t => t.indexId == indexId);
|
||||
_serverStatItem = _lstServerStat.FirstOrDefault(t => t.indexId == indexId);
|
||||
if (_serverStatItem == null)
|
||||
{
|
||||
_serverStatItem = new ServerStatItem
|
||||
|
||||
@@ -72,7 +72,16 @@ namespace v2rayN.Base
|
||||
private bool Init()
|
||||
{
|
||||
coreInfo = LazyConfig.Instance.GetCoreInfo(ECoreType.sing_box);
|
||||
//Template
|
||||
string configStr = Utils.GetEmbedText(Global.TunSingboxFileName);
|
||||
if (!Utils.IsNullOrEmpty(_config.tunModeItem.customTemplate) && File.Exists(_config.tunModeItem.customTemplate))
|
||||
{
|
||||
var customTemplate = File.ReadAllText(_config.tunModeItem.customTemplate);
|
||||
if (!Utils.IsNullOrEmpty(customTemplate))
|
||||
{
|
||||
configStr = customTemplate;
|
||||
}
|
||||
}
|
||||
if (Utils.IsNullOrEmpty(configStr))
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -232,6 +232,11 @@ namespace v2rayN.Handler
|
||||
}
|
||||
|
||||
int ret = ConfigHandler.AddBatchServers(ref config, result, id, true);
|
||||
if (ret <= 0)
|
||||
{
|
||||
Utils.SaveLog("FailedImportSubscription");
|
||||
Utils.SaveLog(result);
|
||||
}
|
||||
_updateFunc(false,
|
||||
ret > 0
|
||||
? $"{hashCode}{ResUI.MsgUpdateSubscriptionEnd}"
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace v2rayN.Mode
|
||||
public bool colorModeDark { get; set; }
|
||||
public string? colorPrimaryName { get; set; }
|
||||
public string currentLanguage { get; set; }
|
||||
public bool enableDragDropSort { get; set; }
|
||||
public Dictionary<string, int> mainLvColWidth { get; set; }
|
||||
}
|
||||
|
||||
@@ -102,6 +103,7 @@ namespace v2rayN.Mode
|
||||
public bool strictRoute { get; set; }
|
||||
public string stack { get; set; }
|
||||
public int mtu { get; set; }
|
||||
public string customTemplate { get; set; }
|
||||
public List<string> directIP { get; set; }
|
||||
public List<string> directProcess { get; set; }
|
||||
|
||||
|
||||
@@ -3,25 +3,11 @@
|
||||
[Serializable]
|
||||
class ServerTestItem
|
||||
{
|
||||
public string indexId
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string address
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public int port
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public EConfigType configType
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public bool allowTest
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string indexId { get; set; }
|
||||
public string address { get; set; }
|
||||
public int port { get; set; }
|
||||
public EConfigType configType { get; set; }
|
||||
public bool allowTest { get; set; }
|
||||
public int delay { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
18
v2rayN/v2rayN/Resx/ResUI.Designer.cs
generated
18
v2rayN/v2rayN/Resx/ResUI.Designer.cs
generated
@@ -2392,6 +2392,15 @@ namespace v2rayN.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Enable Server Drag Drop Sort(Require restart) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSettingsEnableDragDropSort {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSettingsEnableDragDropSort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Exception 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2644,6 +2653,15 @@ namespace v2rayN.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Custom Template 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSettingsTunModeCustomTemplate {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSettingsTunModeCustomTemplate", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Direct IP CIDR, separated by commas (,) 的本地化字符串。
|
||||
/// </summary>
|
||||
|
||||
@@ -1063,4 +1063,10 @@
|
||||
<data name="menuMoveToGroup" xml:space="preserve">
|
||||
<value>Move to group</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunModeCustomTemplate" xml:space="preserve">
|
||||
<value>Custom Template</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableDragDropSort" xml:space="preserve">
|
||||
<value>Enable Server Drag Drop Sort(Require restart)</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -851,7 +851,7 @@
|
||||
<value>开机启动(可能会不成功)</value>
|
||||
</data>
|
||||
<data name="TbSettingsStatistics" xml:space="preserve">
|
||||
<value>启用统计(实时网速显示,需要重启)</value>
|
||||
<value>启用统计(实时网速显示,需重启)</value>
|
||||
</data>
|
||||
<data name="TbSettingsStatisticsFreshRate" xml:space="preserve">
|
||||
<value>统计刷新频率(单位秒)</value>
|
||||
@@ -1063,4 +1063,10 @@
|
||||
<data name="menuMoveToGroup" xml:space="preserve">
|
||||
<value>移至订阅分组</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunModeCustomTemplate" xml:space="preserve">
|
||||
<value>自定义配置模板</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableDragDropSort" xml:space="preserve">
|
||||
<value>启用服务器拖放排序(需重启)</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -752,14 +752,14 @@ namespace v2rayN
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Auto Start via TaskService
|
||||
/// </summary>
|
||||
/// <param name="taskName"></param>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="description"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// Auto Start via TaskService
|
||||
/// </summary>
|
||||
/// <param name="taskName"></param>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="description"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public static void AutoStart(string taskName, string fileName, string description)
|
||||
{
|
||||
if (string.IsNullOrEmpty(taskName))
|
||||
|
||||
@@ -86,6 +86,7 @@ namespace v2rayN.ViewModels
|
||||
item.remarks = SelectedSource.remarks;
|
||||
item.address = SelectedSource.address;
|
||||
item.coreType = SelectedSource.coreType;
|
||||
item.displayLog = SelectedSource.displayLog;
|
||||
item.preSocksPort = SelectedSource.preSocksPort;
|
||||
}
|
||||
|
||||
|
||||
@@ -1064,6 +1064,17 @@ namespace v2rayN.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveServerTo(int startIndex, ProfileItemModel targetItem)
|
||||
{
|
||||
var targetIndex = _profileItems.IndexOf(targetItem);
|
||||
if (startIndex >= 0 && targetIndex >= 0 && startIndex != targetIndex)
|
||||
{
|
||||
if (ConfigHandler.MoveServer(ref _config, ref _lstProfile, startIndex, EMove.Position, targetIndex) == 0)
|
||||
{
|
||||
RefreshServers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ServerSpeedtest(ESpeedActionType actionType)
|
||||
{
|
||||
@@ -1076,7 +1087,7 @@ namespace v2rayN.ViewModels
|
||||
return;
|
||||
}
|
||||
//ClearTestResult();
|
||||
SpeedtestHandler statistics = new SpeedtestHandler(_config, _coreHandler, lstSelecteds, actionType, UpdateSpeedtestHandler);
|
||||
new SpeedtestHandler(_config, _coreHandler, lstSelecteds, actionType, UpdateSpeedtestHandler);
|
||||
}
|
||||
|
||||
private void Export2ClientConfig()
|
||||
|
||||
@@ -55,6 +55,7 @@ namespace v2rayN.ViewModels
|
||||
[Reactive] public bool EnableSecurityProtocolTls13 { get; set; }
|
||||
[Reactive] public bool AutoHideStartup { get; set; }
|
||||
[Reactive] public bool EnableCheckPreReleaseUpdate { get; set; }
|
||||
[Reactive] public bool EnableDragDropSort { get; set; }
|
||||
[Reactive] public int autoUpdateInterval { get; set; }
|
||||
[Reactive] public int autoUpdateSubInterval { get; set; }
|
||||
[Reactive] public int trayMenuServersLimit { get; set; }
|
||||
@@ -70,6 +71,7 @@ namespace v2rayN.ViewModels
|
||||
[Reactive] public bool TunStrictRoute { get; set; }
|
||||
[Reactive] public string TunStack { get; set; }
|
||||
[Reactive] public int TunMtu { get; set; }
|
||||
[Reactive] public string TunCustomTemplate { get; set; }
|
||||
[Reactive] public string TunDirectIP { get; set; }
|
||||
[Reactive] public string TunDirectProcess { get; set; }
|
||||
#endregion
|
||||
@@ -134,6 +136,7 @@ namespace v2rayN.ViewModels
|
||||
EnableSecurityProtocolTls13 = _config.enableSecurityProtocolTls13;
|
||||
AutoHideStartup = _config.autoHideStartup;
|
||||
EnableCheckPreReleaseUpdate = _config.checkPreReleaseUpdate;
|
||||
EnableDragDropSort = _config.uiItem.enableDragDropSort;
|
||||
autoUpdateInterval = _config.autoUpdateInterval;
|
||||
autoUpdateSubInterval = _config.autoUpdateSubInterval;
|
||||
trayMenuServersLimit = _config.trayMenuServersLimit;
|
||||
@@ -150,6 +153,7 @@ namespace v2rayN.ViewModels
|
||||
TunStrictRoute = _config.tunModeItem.strictRoute;
|
||||
TunStack = _config.tunModeItem.stack;
|
||||
TunMtu = _config.tunModeItem.mtu;
|
||||
TunCustomTemplate = _config.tunModeItem.customTemplate;
|
||||
TunDirectIP = Utils.List2String(_config.tunModeItem.directIP, true);
|
||||
TunDirectProcess = Utils.List2String(_config.tunModeItem.directProcess, true);
|
||||
|
||||
@@ -297,6 +301,7 @@ namespace v2rayN.ViewModels
|
||||
_config.autoUpdateInterval = autoUpdateInterval;
|
||||
_config.autoUpdateSubInterval = autoUpdateSubInterval;
|
||||
_config.checkPreReleaseUpdate = EnableCheckPreReleaseUpdate;
|
||||
_config.uiItem.enableDragDropSort = EnableDragDropSort;
|
||||
_config.trayMenuServersLimit = trayMenuServersLimit;
|
||||
|
||||
//systemProxy
|
||||
@@ -308,6 +313,7 @@ namespace v2rayN.ViewModels
|
||||
_config.tunModeItem.strictRoute = TunStrictRoute;
|
||||
_config.tunModeItem.stack = TunStack;
|
||||
_config.tunModeItem.mtu = TunMtu;
|
||||
_config.tunModeItem.customTemplate = TunCustomTemplate;
|
||||
_config.tunModeItem.directIP = Utils.String2List(TunDirectIP);
|
||||
_config.tunModeItem.directProcess = Utils.String2List(TunDirectProcess);
|
||||
|
||||
|
||||
@@ -350,11 +350,12 @@
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
x:Name="spEnableTun"
|
||||
Width="auto"
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left">
|
||||
<TextBlock x:Name="txtEnableTun" Text="{x:Static resx:ResUI.TbEnableTunAs}" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbEnableTunAs}" />
|
||||
<ToggleButton
|
||||
x:Name="togEnableTun"
|
||||
Margin="4"
|
||||
|
||||
@@ -8,10 +8,12 @@ using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using v2rayN.Handler;
|
||||
using v2rayN.Mode;
|
||||
using v2rayN.Resx;
|
||||
using v2rayN.ViewModels;
|
||||
using Point = System.Windows.Point;
|
||||
using SystemInformation = System.Windows.Forms.SystemInformation;
|
||||
|
||||
namespace v2rayN.Views
|
||||
@@ -31,6 +33,14 @@ namespace v2rayN.Views
|
||||
lstProfiles.PreviewKeyDown += LstProfiles_PreviewKeyDown;
|
||||
lstProfiles.SelectionChanged += lstProfiles_SelectionChanged;
|
||||
lstProfiles.LoadingRow += LstProfiles_LoadingRow;
|
||||
if (_config.uiItem.enableDragDropSort)
|
||||
{
|
||||
lstProfiles.AllowDrop = true;
|
||||
lstProfiles.PreviewMouseLeftButtonDown += LstProfiles_PreviewMouseLeftButtonDown;
|
||||
lstProfiles.MouseMove += LstProfiles_MouseMove;
|
||||
lstProfiles.DragEnter += LstProfiles_DragEnter;
|
||||
lstProfiles.Drop += LstProfiles_Drop;
|
||||
}
|
||||
|
||||
ViewModel = new MainWindowViewModel(MainSnackbar.MessageQueue!, UpdateViewHandler);
|
||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
|
||||
@@ -171,8 +181,7 @@ namespace v2rayN.Views
|
||||
var IsAdministrator = Utils.IsAdministrator();
|
||||
this.Title = $"{Utils.GetVersion()} - {(IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||
|
||||
togEnableTun.Visibility = IsAdministrator ? Visibility.Visible : Visibility.Hidden;
|
||||
txtEnableTun.Visibility = IsAdministrator ? Visibility.Visible : Visibility.Hidden;
|
||||
spEnableTun.Visibility = IsAdministrator ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
#region Event
|
||||
@@ -438,6 +447,100 @@ namespace v2rayN.Views
|
||||
|
||||
|
||||
#endregion
|
||||
#region Drag and Drop
|
||||
|
||||
private Point startPoint = new Point();
|
||||
private int startIndex = -1;
|
||||
private string formatData = "ProfileItemModel";
|
||||
|
||||
/// <summary>
|
||||
/// Helper to search up the VisualTree
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="current"></param>
|
||||
/// <returns></returns>
|
||||
private static T? FindAnchestor<T>(DependencyObject current) where T : DependencyObject
|
||||
{
|
||||
do
|
||||
{
|
||||
if (current is T)
|
||||
{
|
||||
return (T)current;
|
||||
}
|
||||
current = VisualTreeHelper.GetParent(current);
|
||||
}
|
||||
while (current != null);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private void LstProfiles_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
// Get current mouse position
|
||||
startPoint = e.GetPosition(null);
|
||||
}
|
||||
private void LstProfiles_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
// Get the current mouse position
|
||||
Point mousePos = e.GetPosition(null);
|
||||
Vector diff = startPoint - mousePos;
|
||||
|
||||
if (e.LeftButton == MouseButtonState.Pressed &&
|
||||
(Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
|
||||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
|
||||
{
|
||||
// Get the dragged Item
|
||||
var listView = sender as DataGrid;
|
||||
if (listView == null) return;
|
||||
var listViewItem = FindAnchestor<DataGridRow>((DependencyObject)e.OriginalSource);
|
||||
if (listViewItem == null) return; // Abort
|
||||
// Find the data behind the ListViewItem
|
||||
ProfileItemModel item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
|
||||
if (item == null) return; // Abort
|
||||
// Initialize the drag & drop operation
|
||||
startIndex = lstProfiles.SelectedIndex;
|
||||
DataObject dragData = new DataObject(formatData, item);
|
||||
DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Copy | DragDropEffects.Move);
|
||||
}
|
||||
}
|
||||
|
||||
private void LstProfiles_DragEnter(object sender, DragEventArgs e)
|
||||
{
|
||||
if (!e.Data.GetDataPresent(formatData) || sender != e.Source)
|
||||
{
|
||||
e.Effects = DragDropEffects.None;
|
||||
}
|
||||
}
|
||||
|
||||
private void LstProfiles_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data.GetDataPresent(formatData) && sender == e.Source)
|
||||
{
|
||||
// Get the drop Item destination
|
||||
var listView = sender as DataGrid;
|
||||
if (listView == null) return;
|
||||
var listViewItem = FindAnchestor<DataGridRow>((DependencyObject)e.OriginalSource);
|
||||
if (listViewItem == null)
|
||||
{
|
||||
// Abort
|
||||
e.Effects = DragDropEffects.None;
|
||||
return;
|
||||
}
|
||||
// Find the data behind the Item
|
||||
ProfileItemModel item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
|
||||
if (item == null) return;
|
||||
// Move item into observable collection
|
||||
// (this will be automatically reflected to lstView.ItemsSource)
|
||||
e.Effects = DragDropEffects.Move;
|
||||
|
||||
ViewModel?.MoveServerTo(startIndex, item);
|
||||
|
||||
startIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,6 +415,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
@@ -553,16 +554,30 @@
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsEnableDragDropSort}" />
|
||||
<ToggleButton
|
||||
x:Name="togEnableDragDropSort"
|
||||
Grid.Row="10"
|
||||
Grid.Column="1"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="11"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsAutoUpdateInterval}" />
|
||||
<TextBox
|
||||
x:Name="txtautoUpdateInterval"
|
||||
Grid.Row="10"
|
||||
Grid.Row="11"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource SettingItemMargin}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="11"
|
||||
Grid.Row="12"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
VerticalAlignment="Center"
|
||||
@@ -570,13 +585,13 @@
|
||||
Text="{x:Static resx:ResUI.TbSettingsAutoUpdate}" />
|
||||
<TextBox
|
||||
x:Name="txtautoUpdateSubInterval"
|
||||
Grid.Row="11"
|
||||
Grid.Row="12"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource SettingItemMargin}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="12"
|
||||
Grid.Row="13"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
VerticalAlignment="Center"
|
||||
@@ -584,7 +599,7 @@
|
||||
Text="{x:Static resx:ResUI.TbSettingsTrayMenuServersLimit}" />
|
||||
<TextBox
|
||||
x:Name="txttrayMenuServersLimit"
|
||||
Grid.Row="12"
|
||||
Grid.Row="13"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource SettingItemMargin}" />
|
||||
@@ -646,6 +661,7 @@
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock
|
||||
@@ -688,7 +704,8 @@
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource SettingItemMargin}" />
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
@@ -702,7 +719,34 @@
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource SettingItemMargin}" />
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsTunModeCustomTemplate}" />
|
||||
<TextBox
|
||||
x:Name="txtCustomTemplate"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Width="600"
|
||||
Margin="{StaticResource SettingItemMargin}"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
TextWrapping="Wrap" />
|
||||
<Button
|
||||
x:Name="btnBrowse"
|
||||
Grid.Row="5"
|
||||
Grid.Column="2"
|
||||
Width="100"
|
||||
Margin="2,0,8,0"
|
||||
Click="btnBrowse_Click"
|
||||
Content="{x:Static resx:ResUI.TbBrowse}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
</Grid>
|
||||
|
||||
<Grid Margin="{StaticResource SettingItemMargin}">
|
||||
|
||||
@@ -87,6 +87,7 @@ namespace v2rayN.Views
|
||||
this.Bind(ViewModel, vm => vm.EnableSecurityProtocolTls13, v => v.togEnableSecurityProtocolTls13.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.AutoHideStartup, v => v.togAutoHideStartup.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.EnableDragDropSort, v => v.togEnableDragDropSort.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.autoUpdateInterval, v => v.txtautoUpdateInterval.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.autoUpdateSubInterval, v => v.txtautoUpdateSubInterval.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.trayMenuServersLimit, v => v.txttrayMenuServersLimit.Text).DisposeWith(disposables);
|
||||
@@ -100,6 +101,7 @@ namespace v2rayN.Views
|
||||
this.Bind(ViewModel, vm => vm.TunStrictRoute, v => v.togStrictRoute.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunStack, v => v.cmbStack.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunCustomTemplate, v => v.txtCustomTemplate.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunDirectIP, v => v.txtDirectIP.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunDirectProcess, v => v.txtDirectProcess.Text).DisposeWith(disposables);
|
||||
|
||||
@@ -124,6 +126,13 @@ namespace v2rayN.Views
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
private void btnBrowse_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
var openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
|
||||
openFileDialog1.Filter = "tunConfig|*.json|All|*.*";
|
||||
openFileDialog1.ShowDialog();
|
||||
|
||||
txtCustomTemplate.Text = openFileDialog1.FileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<ApplicationIcon>v2rayN.ico</ApplicationIcon>
|
||||
<Copyright>Copyright © 2017-2023 (GPLv3)</Copyright>
|
||||
<FileVersion>6.3</FileVersion>
|
||||
<FileVersion>6.5</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user