diff --git a/Ink Canvas/InkCanvasForClass.csproj b/Ink Canvas/InkCanvasForClass.csproj
index fdd34062..494283dd 100644
--- a/Ink Canvas/InkCanvasForClass.csproj
+++ b/Ink Canvas/InkCanvasForClass.csproj
@@ -132,6 +132,8 @@
+
+
diff --git a/Ink Canvas/MainWindow_cs/MW_Save&OpenStrokes.cs b/Ink Canvas/MainWindow_cs/MW_Save&OpenStrokes.cs
index 41d013a0..5d5c22a7 100644
--- a/Ink Canvas/MainWindow_cs/MW_Save&OpenStrokes.cs
+++ b/Ink Canvas/MainWindow_cs/MW_Save&OpenStrokes.cs
@@ -2,6 +2,7 @@ using Ink_Canvas.Helpers;
using Microsoft.Win32;
using System;
using System.IO;
+using System.IO.Compression;
using System.Windows;
using System.Windows.Ink;
using System.Windows.Input;
@@ -311,38 +312,240 @@ namespace Ink_Canvas {
var openFileDialog = new OpenFileDialog();
openFileDialog.InitialDirectory = Settings.Automation.AutoSavedStrokesLocation;
openFileDialog.Title = "打开墨迹文件";
- openFileDialog.Filter = "Ink Canvas Strokes File (*.icstk)|*.icstk";
+ openFileDialog.Filter = "Ink Canvas Strokes File (*.icstk)|*.icstk|ICC压缩包 (*.zip)|*.zip";
if (openFileDialog.ShowDialog() != true) return;
LogHelper.WriteLogToFile($"Strokes Insert: Name: {openFileDialog.FileName}",
LogHelper.LogType.Event);
+
try {
- var fileStreamHasNoStroke = false;
- using (var fs = new FileStream(openFileDialog.FileName, FileMode.Open, FileAccess.Read)) {
- var strokes = new StrokeCollection(fs);
- fileStreamHasNoStroke = strokes.Count == 0;
- if (!fileStreamHasNoStroke) {
- ClearStrokes(true);
- timeMachine.ClearStrokeHistory();
- inkCanvas.Strokes.Add(strokes);
- LogHelper.NewLog($"Strokes Insert: Strokes Count: {inkCanvas.Strokes.Count.ToString()}");
- }
+ string fileExtension = Path.GetExtension(openFileDialog.FileName).ToLower();
+
+ if (fileExtension == ".zip") {
+ // 处理ICC压缩包
+ OpenICCZipFile(openFileDialog.FileName);
+ } else {
+ // 处理单个墨迹文件
+ OpenSingleStrokeFile(openFileDialog.FileName);
}
- if (fileStreamHasNoStroke)
- using (var ms = new MemoryStream(File.ReadAllBytes(openFileDialog.FileName))) {
- ms.Seek(0, SeekOrigin.Begin);
- var strokes = new StrokeCollection(ms);
- ClearStrokes(true);
- timeMachine.ClearStrokeHistory();
- inkCanvas.Strokes.Add(strokes);
- LogHelper.NewLog($"Strokes Insert (2): Strokes Count: {strokes.Count.ToString()}");
- }
-
if (inkCanvas.Visibility != Visibility.Visible) SymbolIconCursor_Click(sender, null);
}
- catch {
+ catch (Exception ex) {
ShowNotification("墨迹打开失败");
+ LogHelper.WriteLogToFile($"墨迹打开失败: {ex.ToString()}", LogHelper.LogType.Error);
}
}
+
+ ///
+ /// 打开ICC创建的.zip压缩包
+ ///
+ private void OpenICCZipFile(string zipFilePath) {
+ try {
+ // 创建临时目录来解压文件
+ string tempDir = Path.Combine(Path.GetTempPath(), $"InkCanvas_Open_{DateTime.Now:yyyyMMdd_HHmmss}");
+ Directory.CreateDirectory(tempDir);
+
+ try {
+ // 解压ZIP文件
+ System.IO.Compression.ZipFile.ExtractToDirectory(zipFilePath, tempDir);
+
+ // 读取元数据文件
+ string metadataFile = Path.Combine(tempDir, "metadata.txt");
+ if (!File.Exists(metadataFile)) {
+ throw new Exception("压缩包中未找到元数据文件");
+ }
+
+ var metadata = ReadMetadataFile(metadataFile);
+
+ // 根据元数据信息决定恢复模式
+ bool isPPTMode = metadata.ContainsKey("模式") && metadata["模式"].Contains("PPT放映");
+ bool isWhiteboardMode = metadata.ContainsKey("模式") && metadata["模式"].Contains("白板");
+
+ // 检查当前是否处于PPT模式
+ bool isCurrentlyInPPTMode = BtnPPTSlideShowEnd.Visibility == Visibility.Visible && pptApplication != null;
+
+ // 根据当前模式和保存模式决定恢复策略
+ if (isPPTMode && isCurrentlyInPPTMode) {
+ // PPT模式下恢复PPT墨迹
+ RestorePPTStrokesFromZip(tempDir, metadata);
+ } else if (isWhiteboardMode) {
+ // 白板模式下恢复白板墨迹
+ RestoreWhiteboardStrokesFromZip(tempDir, metadata);
+ } else {
+ // 其他情况只恢复白板墨迹
+ RestoreWhiteboardStrokesFromZip(tempDir, metadata);
+ }
+
+ ShowNotification($"成功打开ICC压缩包,共{(metadata.ContainsKey("总页数") ? metadata["总页数"] : "0")}页");
+ }
+ finally {
+ // 清理临时目录
+ try {
+ if (Directory.Exists(tempDir))
+ Directory.Delete(tempDir, true);
+ }
+ catch (Exception ex) {
+ LogHelper.WriteLogToFile($"清理临时目录失败: {ex.ToString()}", LogHelper.LogType.Warning);
+ }
+ }
+ }
+ catch (Exception ex) {
+ LogHelper.WriteLogToFile($"打开ICC压缩包失败: {ex.ToString()}", LogHelper.LogType.Error);
+ throw;
+ }
+ }
+
+ ///
+ /// 读取元数据文件
+ ///
+ private Dictionary ReadMetadataFile(string metadataPath) {
+ var metadata = new Dictionary();
+
+ using (var reader = new StreamReader(metadataPath, System.Text.Encoding.UTF8)) {
+ string line;
+ while ((line = reader.ReadLine()) != null) {
+ if (line.Contains(":")) {
+ var parts = line.Split(new[] { ':' }, 2);
+ if (parts.Length == 2) {
+ metadata[parts[0].Trim()] = parts[1].Trim();
+ }
+ }
+ }
+ }
+
+ return metadata;
+ }
+
+ ///
+ /// 从ZIP文件恢复PPT墨迹
+ ///
+ private void RestorePPTStrokesFromZip(string tempDir, Dictionary metadata) {
+ try {
+ // 清空当前墨迹
+ ClearStrokes(true);
+ timeMachine.ClearStrokeHistory();
+
+ // 重置PPT墨迹存储
+ if (memoryStreams == null) {
+ memoryStreams = new MemoryStream[50];
+ }
+
+ // 读取所有页面的墨迹文件
+ var files = Directory.GetFiles(tempDir, "page_*.icstk");
+ foreach (var file in files) {
+ var fileName = Path.GetFileNameWithoutExtension(file);
+ if (fileName.StartsWith("page_") && int.TryParse(fileName.Substring(5), out int pageNumber)) {
+ using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read)) {
+ var strokes = new StrokeCollection(fs);
+ if (strokes.Count > 0) {
+ var ms = new MemoryStream();
+ strokes.Save(ms);
+ ms.Position = 0;
+ memoryStreams[pageNumber] = ms;
+ }
+ }
+ }
+ }
+
+ // 恢复当前页面的墨迹
+ if (pptApplication != null && pptApplication.SlideShowWindows.Count > 0) {
+ int currentSlide = pptApplication.SlideShowWindows[1].View.CurrentShowPosition;
+ if (memoryStreams[currentSlide] != null && memoryStreams[currentSlide].Length > 0) {
+ memoryStreams[currentSlide].Position = 0;
+ inkCanvas.Strokes.Add(new StrokeCollection(memoryStreams[currentSlide]));
+ }
+ previousSlideID = currentSlide;
+ }
+
+ LogHelper.WriteLogToFile($"成功恢复PPT墨迹,共{files.Length}页");
+ }
+ catch (Exception ex) {
+ LogHelper.WriteLogToFile($"恢复PPT墨迹失败: {ex.ToString()}", LogHelper.LogType.Error);
+ throw;
+ }
+ }
+
+ ///
+ /// 从ZIP文件恢复白板墨迹
+ ///
+ private void RestoreWhiteboardStrokesFromZip(string tempDir, Dictionary metadata) {
+ try {
+ // 清空当前墨迹
+ ClearStrokes(true);
+ timeMachine.ClearStrokeHistory();
+
+ // 读取总页数
+ int totalPages = 1;
+ if (metadata.ContainsKey("总页数") && int.TryParse(metadata["总页数"], out int parsedPages)) {
+ totalPages = parsedPages;
+ }
+
+ // 重置白板状态
+ WhiteboardTotalCount = totalPages;
+ CurrentWhiteboardIndex = 1;
+
+ // 清空历史记录
+ for (int i = 0; i < TimeMachineHistories.Length; i++) {
+ TimeMachineHistories[i] = null;
+ }
+
+ // 读取所有页面的墨迹文件
+ var files = Directory.GetFiles(tempDir, "page_*.icstk");
+ foreach (var file in files) {
+ var fileName = Path.GetFileNameWithoutExtension(file);
+ if (fileName.StartsWith("page_") && int.TryParse(fileName.Substring(5), out int pageNumber)) {
+ using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read)) {
+ var strokes = new StrokeCollection(fs);
+ if (strokes.Count > 0) {
+ // 创建历史记录
+ var history = new TimeMachineHistory(strokes, TimeMachineHistoryType.UserInput, false);
+ TimeMachineHistories[pageNumber] = new TimeMachineHistory[] { history };
+ }
+ }
+ }
+ }
+
+ // 恢复第一页的墨迹
+ if (TimeMachineHistories[1] != null) {
+ RestoreStrokes();
+ }
+
+ // 更新UI显示
+ UpdateIndexInfoDisplay();
+
+ LogHelper.WriteLogToFile($"成功恢复白板墨迹,共{totalPages}页");
+ }
+ catch (Exception ex) {
+ LogHelper.WriteLogToFile($"恢复白板墨迹失败: {ex.ToString()}", LogHelper.LogType.Error);
+ throw;
+ }
+ }
+
+ ///
+ /// 打开单个墨迹文件
+ ///
+ private void OpenSingleStrokeFile(string filePath) {
+ var fileStreamHasNoStroke = false;
+ using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) {
+ var strokes = new StrokeCollection(fs);
+ fileStreamHasNoStroke = strokes.Count == 0;
+ if (!fileStreamHasNoStroke) {
+ ClearStrokes(true);
+ timeMachine.ClearStrokeHistory();
+ inkCanvas.Strokes.Add(strokes);
+ LogHelper.NewLog($"Strokes Insert: Strokes Count: {inkCanvas.Strokes.Count.ToString()}");
+ }
+ }
+
+ if (fileStreamHasNoStroke)
+ using (var ms = new MemoryStream(File.ReadAllBytes(filePath))) {
+ ms.Seek(0, SeekOrigin.Begin);
+ var strokes = new StrokeCollection(ms);
+ ClearStrokes(true);
+ timeMachine.ClearStrokeHistory();
+ inkCanvas.Strokes.Add(strokes);
+ LogHelper.NewLog($"Strokes Insert (2): Strokes Count: {strokes.Count.ToString()}");
+ }
+ }
}
}
diff --git a/Ink Canvas/obj/Debug/net472/InkCanvasForClass.csproj.AssemblyReference.cache b/Ink Canvas/obj/Debug/net472/InkCanvasForClass.csproj.AssemblyReference.cache
index 93610cbd..4af914e2 100644
Binary files a/Ink Canvas/obj/Debug/net472/InkCanvasForClass.csproj.AssemblyReference.cache and b/Ink Canvas/obj/Debug/net472/InkCanvasForClass.csproj.AssemblyReference.cache differ
diff --git a/Ink Canvas/obj/Debug/net472/InkCanvasForClass_MarkupCompile.cache b/Ink Canvas/obj/Debug/net472/InkCanvasForClass_MarkupCompile.cache
index 6236f501..9b3fbcb7 100644
--- a/Ink Canvas/obj/Debug/net472/InkCanvasForClass_MarkupCompile.cache
+++ b/Ink Canvas/obj/Debug/net472/InkCanvasForClass_MarkupCompile.cache
@@ -13,7 +13,7 @@ E:\ICC CE\ICC CE main\community\Ink Canvas\App.xaml
21348134359
731095817143
-46-932173576
+471037513499
Helpers\Plugins\BuiltIn\SuperLauncher\LauncherSettingsControl.xaml;Helpers\Plugins\BuiltIn\SuperLauncher\LauncherWindow.xaml;MainWindow.xaml;MainWindow_cs\MW_Eraser.xaml;Resources\DrawShapeImageDictionary.xaml;Resources\IconImageDictionary.xaml;Resources\SeewoImageDictionary.xaml;Resources\Styles\Dark.xaml;Resources\Styles\Light.xaml;Windows\AddCustomIconWindow.xaml;Windows\AddPickNameBackgroundWindow.xaml;Windows\CountdownTimerWindow.xaml;Windows\CustomIconWindow.xaml;Windows\CycleProcessBar.xaml;Windows\HasNewUpdateWindow.xaml;Windows\ManagePickNameBackgroundsWindow.xaml;Windows\NamesInputWindow.xaml;Windows\OperatingGuideWindow.xaml;Windows\PluginSettingsWindow.xaml;Windows\RandWindow.xaml;Windows\YesOrNoNotificationWindow.xaml;
False