Skip to content
This repository has been archived by the owner on Oct 20, 2024. It is now read-only.

保存ボタンを実装する #41

Merged
merged 5 commits into from
Jun 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class English : LanguageData
public override string ControllerView_Copy => "Copy selected logs";
public override string ControllerView_CopyAsMarkdown => "Copy as Markdown";
public override string ControllerView_Copy_MessageBox => "Copied details of selected logs into the clipboard.";
public override string ControllerView_Save => "Save to other location";
public override string LogFileView_MessageBox_Title => "Open a log file";
public override string LogFileView_MessageBox_Failed => "An unexpected error occurred while opening a log file.";
public override string LogFileModel_InvalidLog_Short => "INVALID LOG";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<StartupObject>Covid19Radar.LogViewer.Launcher.Program.DebugEnvironment</StartupObject>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<StartupObject>Covid19Radar.LogViewer.Launcher.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../Covid19Radar.LogViewer/Covid19Radar.LogViewer.csproj" />
<Content Include="c19r.lv.bat">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ internal PluginMenuItem(FormMain mwnd, IPlugin plugin) : base(

if (plugin.GetChildPlugins() is not null and var plugins) {
foreach (var childPlugin in plugins) {
this.DropDownItems.Add(new PluginMenuItem(mwnd, childPlugin));
if (childPlugin.Visible) {
this.DropDownItems.Add(new PluginMenuItem(mwnd, childPlugin));
}
}
}

Expand Down
25 changes: 23 additions & 2 deletions src/Covid19Radar.LogViewer.Launcher/FormReceiver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,15 @@ private async void FormReceiver_Load(object sender, EventArgs e)
bool allowEscape;

while (!_cts.IsCancellationRequested) {
string temp = Path.GetTempFileName();
byte[] buf = new byte[1024];
string temp = Path.GetTempFileName();
IPAddress? ipa = null;
byte[] buf = new byte[1024];

using (var client = await Task.Run(listener.AcceptTcpClientAsync, _cts.Token)) {
var ns = client.GetStream();
if (client.Client.RemoteEndPoint is IPEndPoint ep) {
ipa = ep.Address;
}
await using (ns.ConfigureAwait(false)) {
using (var br = new BinaryReader(ns)) {
while (!ns.DataAvailable) {
Expand All @@ -80,6 +84,7 @@ private async void FormReceiver_Load(object sender, EventArgs e)
}
}

await SaveZoneIdentifier(temp, ipa);
await _owner.OpenFileAsync(temp, allowEscape);
}
} finally {
Expand All @@ -97,5 +102,21 @@ private static async ValueTask<IPAddress> GetLocalIPAddress()
var addrs = await Dns.GetHostAddressesAsync(Dns.GetHostName());
return addrs.Length > 0 ? addrs[0] : IPAddress.Loopback;
}

private static async ValueTask SaveZoneIdentifier(string filename, IPAddress? ipa)
{
var fs = new FileStream(filename + ":Zone.Identifier", FileMode.Create, FileAccess.Write, FileShare.None);
await using (fs.ConfigureAwait(false)) {
var sw = new StreamWriter(fs);
await using (sw.ConfigureAwait(false)) {
await sw.WriteLineAsync("[ZoneTransfer]");
await sw.WriteLineAsync("ZoneId=3");
if (ipa is not null) {
await sw.WriteLineAsync($"HostIpAddress={ipa}");
}
await sw.WriteLineAsync("CocoaLogViewer=FormReceiver");
}
}
}
}
}
38 changes: 34 additions & 4 deletions src/Covid19Radar.LogViewer.Launcher/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
Expand All @@ -25,25 +26,42 @@ internal static class Program
private static int Main(string[] args)
{
try {
var context = new ModuleInitializationContextInternal(args);
var modules = ModuleLoader.LoadModules(context);
ShowWindow(modules, context);
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
Application.ThreadException += Application_ThreadException;

Run(args);
return 0;
} catch (Exception e) {
HandleException(e);
return e.HResult;
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Run(string[] args)
{
var context = new ModuleInitializationContextInternal(args);
var modules = ModuleLoader.LoadModules(context);
ShowWindow(modules, context);
}

private static void ShowWindow(IEnumerable<CocoaLogViewerModule> modules, ModuleInitializationContext context)
{
Application.ThreadException += Application_ThreadException;
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FormMain(modules, context));
}

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
if (e.ExceptionObject is Exception exception) {
HandleException(exception);
} else {
HandleException(new Exception((sender, e).ToString()));
}
}

private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
HandleException(e.Exception);
Expand All @@ -70,5 +88,17 @@ private static void HandleException(Exception exception)
sw.WriteLine();
}
}

#if DEBUG
private static class DebugEnvironment
{
[STAThread()]
[Conditional("DEBUG")]
private static void Main(string[] args)
{
Run(args);
}
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public sealed class TransformerSwitcher : ILauncherFeature
private readonly ModuleInitializationContext _context;
private TransformerPipeline? _default;
public string? DisplayName => Resources.TransformerSwitcher_DisplayName;
public bool Visible => true;
public bool IsChecked => _context.TransformerPipeline == EmptyTransformerPipeline.Instance;

public TransformerSwitcher(ModuleInitializationContext moduleInitializationContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ public abstract class CocoaLogViewerModule : IPlugin
public virtual string? DisplayName => this.GetType().Assembly.FullName;
public virtual Image? Logo => null;

// 必ずメニューに表示する。(モジュールの Visible は無視される)
bool IPlugin.Visible => true;

public void Initialize(ModuleInitializationContext context)
{
if (context is null) {
Expand Down
1 change: 1 addition & 0 deletions src/Covid19Radar.LogViewer/Extensibility/IPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace Covid19Radar.LogViewer.Extensibility
public interface IPlugin
{
public string? DisplayName { get; }
public bool Visible { get; }

public IEnumerable<IPlugin>? GetChildPlugins()
{
Expand Down
1 change: 1 addition & 0 deletions src/Covid19Radar.LogViewer/Globalization/Japanese.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class Japanese : LanguageData
public override string ControllerView_Copy => "選択範囲を一括コピー";
public override string ControllerView_CopyAsMarkdown => "Markdownとしてコピー";
public override string ControllerView_Copy_MessageBox => "クリップボードに選択されたログの詳細情報をコピーしました。";
public override string ControllerView_Save => "別の場所に保存";
public override string LogFileView_MessageBox_Title => "動作情報ファイルを開く";
public override string LogFileView_MessageBox_Failed => "動作情報ファイルの読み込み中に予期せぬエラーが発生しました。";
public override string LogFileModel_InvalidLog_Short => "無効なログ";
Expand Down
1 change: 1 addition & 0 deletions src/Covid19Radar.LogViewer/Globalization/LanguageData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ public virtual string MainWindow_OFD_Filter()
public abstract string ControllerView_Copy { get; }
public abstract string ControllerView_CopyAsMarkdown { get; }
public abstract string ControllerView_Copy_MessageBox { get; }
public abstract string ControllerView_Save { get; }

public abstract string ControllerView_Refresh_Failed(MainWindow? mwnd);

Expand Down
42 changes: 41 additions & 1 deletion src/Covid19Radar.LogViewer/ViewModels/ControllerViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,30 @@
****/

using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using Covid19Radar.LogViewer.Globalization;
using Covid19Radar.LogViewer.Models;
using Covid19Radar.LogViewer.Views;
using Clipboard = System.Windows.Clipboard;
using ListView = System.Windows.Controls.ListView;

namespace Covid19Radar.LogViewer.ViewModels
{
public class ControllerViewModel : ViewModelBase
{
private MainWindow? _mwnd;
private LogFileView? _log_file_view;

public MainWindow? MainWindow
{
get => _mwnd;
set => this.RaisePropertyChanged(ref _mwnd, value, nameof(this.MainWindow));
}

public LogFileView? LogFileView
{
get => _log_file_view;
Expand All @@ -32,12 +42,14 @@ public LogFileView? LogFileView
public DelegateCommand Refresh { get; }
public DelegateCommand ClickCopy { get; }
public DelegateCommand ClickCopyAsMarkdown { get; }
public DelegateCommand ClickSave { get; }

public ControllerViewModel()
{
this.Refresh = new(this.RefreshCore);
this.ClickCopy = new(this.ClickCopyCore);
this.ClickCopyAsMarkdown = new(this.ClickCopyAsMarkdownCore);
this.ClickSave = new(this.ClickSaveCore);
}

private async ValueTask RefreshCore(object? ignored)
Expand Down Expand Up @@ -74,6 +86,34 @@ private ValueTask ClickCopyAsMarkdownCore(object? ignored)
return default;
}

private ValueTask ClickSaveCore(object? ignored)
{
if (_mwnd is not null && _mwnd.FilePath is not null and var path) {
using (var sfd = new SaveFileDialog() {
Title = LanguageData.Current.ControllerView_Save,
Filter = LanguageData.Current.MainWindow_OFD_Filter(),
RestoreDirectory = true,
DereferenceLinks = true,
AddExtension = false,
SupportMultiDottedExtensions = true,
CheckPathExists = false,
CheckFileExists = false,
ValidateNames = true,
AutoUpgradeEnabled = true,
OverwritePrompt = true
}) {
if (sfd.ShowDialog() == DialogResult.OK) {
string? dir = Path.GetDirectoryName(path);
if (dir is not null && !Directory.Exists(dir)) {
Directory.CreateDirectory(dir);
}
File.Copy(path, sfd.FileName, true);
}
}
}
return default;
}

private static void ForAllLogData(StringBuilder sb, ListView listView, Action<StringBuilder, LogDataModel> action)
{
var items = listView.SelectedItems;
Expand Down
8 changes: 8 additions & 0 deletions src/Covid19Radar.LogViewer/Views/ControllerView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<KeyBinding Command="{Binding Refresh}" Gesture="F5" />
<KeyBinding Command="{Binding ClickCopy}" Gesture="Ctrl+C" />
<KeyBinding Command="{Binding ClickCopyAsMarkdown}" Gesture="Ctrl+Shift+C" />
<KeyBinding Command="{Binding ClickSave}" Gesture="Ctrl+S" />
</UserControl.InputBindings>
<Grid>
<Grid.ColumnDefinitions>
Expand Down Expand Up @@ -47,5 +48,12 @@
d:Content="copyAsMd"
Margin="4,4,4,4"
Command="{Binding ClickCopyAsMarkdown}" />
<!-- TODO: 検索ボタン -->
<Button
Grid.Column="4"
x:Name="save"
d:Content="save"
Margin="4,4,4,4"
Command="{Binding ClickSave}" />
</Grid>
</UserControl>
7 changes: 7 additions & 0 deletions src/Covid19Radar.LogViewer/Views/ControllerView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ public partial class ControllerView : UserControl
{
private readonly ControllerViewModel _view_model;

public MainWindow? MainWindow
{
get => _view_model.MainWindow;
set => _view_model.MainWindow = value;
}

public LogFileView? LogFileView
{
get => _view_model.LogFileView;
Expand All @@ -29,6 +35,7 @@ public ControllerView()
refresh .Content = LanguageData.Current.ControllerView_Refresh;
copy .Content = LanguageData.Current.ControllerView_Copy;
copyAsMd.Content = LanguageData.Current.ControllerView_CopyAsMarkdown;
save .Content = LanguageData.Current.ControllerView_Save;
}
}
}
9 changes: 8 additions & 1 deletion src/Covid19Radar.LogViewer/Views/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public partial class MainWindow : Window
private static readonly TransformerPipeline _default = new TransformerPipeline().ConfigureDefaults();
private readonly Func<string?, string> _transformer;
private bool _file_loaded;
private string? _file_path;

public string? FilePath => _file_path;

public MainWindow() : this(_default) { }

Expand All @@ -35,6 +38,7 @@ public MainWindow(TransformerPipeline transformerPipeline)
this.Title = LanguageData.Current.MainWindow_Title;
btnOpen .Content = LanguageData.Current.MainWindow_ButtonOpen;
lblVersion.Content = $"{VersionInfo.GetCaption()}\t{VersionInfo.GetCopyright()}";
controller.MainWindow = this;
controller.LogFileView = lfv;
}

Expand Down Expand Up @@ -77,7 +81,10 @@ private async ValueTask<bool> OpenFile(Func<(string path, Func<Stream> open)?> f
try {
var f = file();
if (f.HasValue) {
await this.Dispatcher.InvokeAsync(() => this.Title = Path.GetFileName(f.Value.path));
await this.Dispatcher.InvokeAsync(() => {
_file_path = f.Value.path;
this.Title = Path.GetFileName(_file_path);
});
lfv.ViewModel.LogFile = await Task.Run(() => new LogFileModel(f.Value.open(), _transformer, allowEscape)).ConfigureAwait(false);
await this.Dispatcher.InvokeAsync(() => {
btnOpen.Visibility = Visibility.Collapsed;
Expand Down