improve:PPT墨迹管理
This commit is contained in:
@@ -3,6 +3,7 @@ using iNKORE.UI.WPF.Modern;
|
|||||||
using Microsoft.Office.Core;
|
using Microsoft.Office.Core;
|
||||||
using Microsoft.Office.Interop.PowerPoint;
|
using Microsoft.Office.Interop.PowerPoint;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
@@ -99,6 +100,9 @@ namespace Ink_Canvas
|
|||||||
private readonly object _slideSwitchLock = new object();
|
private readonly object _slideSwitchLock = new object();
|
||||||
private bool _isProcessingSlideSwitch = false;
|
private bool _isProcessingSlideSwitch = false;
|
||||||
|
|
||||||
|
private Dictionary<int, MemoryStream> _memoryStreams = new Dictionary<int, MemoryStream>();
|
||||||
|
private int _previousSlideID = 0;
|
||||||
|
|
||||||
private DispatcherTimer _exitPPTModeAfterDisconnectTimer;
|
private DispatcherTimer _exitPPTModeAfterDisconnectTimer;
|
||||||
private const int ExitPPTModeAfterDisconnectDelayMs = 1200;
|
private const int ExitPPTModeAfterDisconnectDelayMs = 1200;
|
||||||
#endregion
|
#endregion
|
||||||
@@ -665,7 +669,12 @@ namespace Ink_Canvas
|
|||||||
{
|
{
|
||||||
Application.Current.Dispatcher.InvokeAsync(() =>
|
Application.Current.Dispatcher.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
_singlePPTInkManager?.SaveAllStrokesToFile(pres);
|
lock (_memoryStreams)
|
||||||
|
{
|
||||||
|
foreach (var stream in _memoryStreams.Values)
|
||||||
|
stream?.Dispose();
|
||||||
|
_memoryStreams.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
_pptUIManager?.UpdateConnectionStatus(false);
|
_pptUIManager?.UpdateConnectionStatus(false);
|
||||||
});
|
});
|
||||||
@@ -725,40 +734,88 @@ namespace Ink_Canvas
|
|||||||
|
|
||||||
isStopInkReplay = true;
|
isStopInkReplay = true;
|
||||||
|
|
||||||
await Application.Current.Dispatcher.InvokeAsync(async () =>
|
int currentSlide = 0;
|
||||||
|
int totalSlides = 0;
|
||||||
|
string presentationName = null;
|
||||||
|
Presentation activePresentation = null;
|
||||||
|
|
||||||
|
if (wn?.View != null && wn.Presentation != null)
|
||||||
{
|
{
|
||||||
Presentation activePresentation = null;
|
activePresentation = wn.Presentation;
|
||||||
int currentSlide = 0;
|
currentSlide = wn.View.CurrentShowPosition;
|
||||||
int totalSlides = 0;
|
totalSlides = activePresentation.Slides.Count;
|
||||||
|
presentationName = activePresentation.Name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activePresentation = _pptManager?.GetCurrentActivePresentation() as Presentation;
|
||||||
|
currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
|
||||||
|
totalSlides = _pptManager?.SlidesCount ?? 0;
|
||||||
|
presentationName = _pptManager?.GetPresentationName() ?? activePresentation?.Name;
|
||||||
|
}
|
||||||
|
|
||||||
if (wn?.View != null && wn.Presentation != null)
|
_currentSlideShowPosition = currentSlide;
|
||||||
{
|
_previousSlideID = currentSlide;
|
||||||
activePresentation = wn.Presentation;
|
|
||||||
currentSlide = wn.View.CurrentShowPosition;
|
|
||||||
totalSlides = activePresentation.Slides.Count;
|
|
||||||
// 初始化当前播放页码跟踪
|
|
||||||
_currentSlideShowPosition = currentSlide;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
activePresentation = _pptManager?.GetCurrentActivePresentation() as Presentation;
|
|
||||||
currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
|
|
||||||
totalSlides = _pptManager?.SlidesCount ?? 0;
|
|
||||||
// 初始化当前播放页码跟踪
|
|
||||||
_currentSlideShowPosition = currentSlide;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activePresentation != null)
|
foreach (var stream in _memoryStreams.Values)
|
||||||
|
{
|
||||||
|
stream?.Dispose();
|
||||||
|
}
|
||||||
|
_memoryStreams.Clear();
|
||||||
|
|
||||||
|
if (Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint && !string.IsNullOrEmpty(presentationName))
|
||||||
|
{
|
||||||
|
string strokePath = Path.Combine(Settings.Automation.AutoSavedStrokesLocation, "Auto Saved - Presentations", presentationName + "_" + totalSlides);
|
||||||
|
if (Directory.Exists(strokePath))
|
||||||
{
|
{
|
||||||
if (_singlePPTInkManager != null)
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_singlePPTInkManager.InitializePresentation(activePresentation);
|
var files = new DirectoryInfo(strokePath).GetFiles("*.icstk");
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
int pageNum = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string name = Path.GetFileNameWithoutExtension(file.Name);
|
||||||
|
if (int.TryParse(name, out pageNum) && pageNum > 0)
|
||||||
|
{
|
||||||
|
byte[] bytes = File.ReadAllBytes(file.FullName);
|
||||||
|
if (bytes.Length > 8)
|
||||||
|
{
|
||||||
|
lock (_memoryStreams)
|
||||||
|
{
|
||||||
|
_memoryStreams[pageNum] = new MemoryStream(bytes);
|
||||||
|
_memoryStreams[pageNum].Position = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"加载第 {pageNum} 页墨迹文件失败: {ex}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
LogHelper.WriteLogToFile($"加载PPT墨迹文件失败: {ex}", LogHelper.LogType.Error);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Application.Current.Dispatcher.InvokeAsync(async () =>
|
||||||
|
{
|
||||||
|
if (activePresentation != null && _singlePPTInkManager != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_singlePPTInkManager.InitializePresentation(activePresentation);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -889,38 +946,61 @@ namespace Ink_Canvas
|
|||||||
int currentSlide = wn.View.CurrentShowPosition;
|
int currentSlide = wn.View.CurrentShowPosition;
|
||||||
int totalSlides = wn.Presentation.Slides.Count;
|
int totalSlides = wn.Presentation.Slides.Count;
|
||||||
|
|
||||||
|
if (currentSlide == _previousSlideID) return;
|
||||||
|
|
||||||
lock (_slideSwitchLock)
|
lock (_slideSwitchLock)
|
||||||
{
|
{
|
||||||
if (currentSlide == _currentSlideShowPosition) return;
|
if (currentSlide == _currentSlideShowPosition) return;
|
||||||
if (_isProcessingSlideSwitch) return;
|
if (_isProcessingSlideSwitch) return;
|
||||||
|
|
||||||
_isProcessingSlideSwitch = true;
|
_isProcessingSlideSwitch = true;
|
||||||
int prev = _currentSlideShowPosition;
|
}
|
||||||
|
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
int prev = _currentSlideShowPosition;
|
||||||
|
|
||||||
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
|
if (inkCanvas.Strokes.Count > 0 && prev > 0 && prev != currentSlide)
|
||||||
|
{
|
||||||
|
var ms = new MemoryStream();
|
||||||
|
inkCanvas.Strokes.Save(ms);
|
||||||
|
ms.Position = 0;
|
||||||
|
if (_memoryStreams.ContainsKey(prev))
|
||||||
|
_memoryStreams[prev]?.Dispose();
|
||||||
|
_memoryStreams[prev] = ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearStrokes(true);
|
||||||
|
timeMachine.ClearStrokeHistory();
|
||||||
|
|
||||||
|
// 从内存流加载新页墨迹(无文件I/O)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (inkCanvas.Strokes.Count > 0 && prev > 0 && prev != currentSlide)
|
if (_memoryStreams.ContainsKey(currentSlide) && _memoryStreams[currentSlide] != null)
|
||||||
_singlePPTInkManager?.SaveCurrentSlideStrokes(prev, inkCanvas.Strokes);
|
{
|
||||||
|
_memoryStreams[currentSlide].Position = 0;
|
||||||
ClearStrokes(true);
|
inkCanvas.Strokes.Add(new StrokeCollection(_memoryStreams[currentSlide]));
|
||||||
timeMachine.ClearStrokeHistory();
|
}
|
||||||
|
|
||||||
StrokeCollection newStrokes = _singlePPTInkManager?.LoadSlideStrokes(currentSlide);
|
|
||||||
if (newStrokes != null && newStrokes.Count > 0)
|
|
||||||
inkCanvas.Strokes.Add(newStrokes);
|
|
||||||
|
|
||||||
_singlePPTInkManager?.LockInkForSlide(currentSlide);
|
|
||||||
_pptUIManager?.UpdateCurrentSlideNumber(currentSlide, totalSlides);
|
|
||||||
}
|
}
|
||||||
finally
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"从内存流加载第 {currentSlide} 页墨迹失败: {ex}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
_singlePPTInkManager?.LockInkForSlide(currentSlide);
|
||||||
|
_pptUIManager?.UpdateCurrentSlideNumber(currentSlide, totalSlides);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_currentSlideShowPosition = currentSlide;
|
||||||
|
_previousSlideID = currentSlide;
|
||||||
|
lock (_slideSwitchLock)
|
||||||
{
|
{
|
||||||
_currentSlideShowPosition = currentSlide;
|
|
||||||
_isProcessingSlideSwitch = false;
|
_isProcessingSlideSwitch = false;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -966,13 +1046,79 @@ namespace Ink_Canvas
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 先保存当前画布墨迹到当前页
|
|
||||||
await Application.Current.Dispatcher.InvokeAsync(() =>
|
await Application.Current.Dispatcher.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
if (currentPage > 0 && _singlePPTInkManager != null && inkCanvas?.Strokes != null)
|
if (currentPage > 0 && inkCanvas?.Strokes != null && inkCanvas.Strokes.Count > 0)
|
||||||
_singlePPTInkManager.ForceSaveSlideStrokes(currentPage, inkCanvas.Strokes);
|
{
|
||||||
|
var ms = new MemoryStream();
|
||||||
|
inkCanvas.Strokes.Save(ms);
|
||||||
|
ms.Position = 0;
|
||||||
|
if (_memoryStreams.ContainsKey(currentPage))
|
||||||
|
_memoryStreams[currentPage]?.Dispose();
|
||||||
|
_memoryStreams[currentPage] = ms;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
_singlePPTInkManager?.SaveAllStrokesToFile(pres, currentPage);
|
|
||||||
|
string presentationNameForSave = _pptManager?.GetPresentationName() ?? (pres != null ? pres.Name : null);
|
||||||
|
int totalSlidesForSave = _pptManager?.SlidesCount ?? (pres != null ? pres.Slides.Count : 0);
|
||||||
|
|
||||||
|
if (Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint && !string.IsNullOrEmpty(presentationNameForSave) && totalSlidesForSave > 0)
|
||||||
|
{
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string folderPath = Path.Combine(Settings.Automation.AutoSavedStrokesLocation, "Auto Saved - Presentations", presentationNameForSave + "_" + totalSlidesForSave);
|
||||||
|
if (!Directory.Exists(folderPath))
|
||||||
|
Directory.CreateDirectory(folderPath);
|
||||||
|
|
||||||
|
lock (_memoryStreams)
|
||||||
|
{
|
||||||
|
for (int i = 1; i <= totalSlidesForSave; i++)
|
||||||
|
{
|
||||||
|
if (_memoryStreams.TryGetValue(i, out MemoryStream value) && value != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] allBytes = value.ToArray();
|
||||||
|
string filePath = Path.Combine(folderPath, i.ToString("0000") + ".icstk");
|
||||||
|
if (allBytes.Length > 8)
|
||||||
|
File.WriteAllBytes(filePath, allBytes);
|
||||||
|
else if (File.Exists(filePath))
|
||||||
|
File.Delete(filePath);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"为第 {i} 页保存墨迹文件失败: {ex}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"保存PPT墨迹文件失败: {ex}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
lock (_memoryStreams)
|
||||||
|
{
|
||||||
|
foreach (var stream in _memoryStreams.Values)
|
||||||
|
stream?.Dispose();
|
||||||
|
_memoryStreams.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lock (_memoryStreams)
|
||||||
|
{
|
||||||
|
foreach (var stream in _memoryStreams.Values)
|
||||||
|
stream?.Dispose();
|
||||||
|
_memoryStreams.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await Application.Current.Dispatcher.InvokeAsync(() =>
|
await Application.Current.Dispatcher.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
@@ -1250,11 +1396,17 @@ namespace Ink_Canvas
|
|||||||
ClearStrokes(true);
|
ClearStrokes(true);
|
||||||
timeMachine.ClearStrokeHistory();
|
timeMachine.ClearStrokeHistory();
|
||||||
|
|
||||||
StrokeCollection strokes = _singlePPTInkManager?.LoadSlideStrokes(slideIndex);
|
if (_memoryStreams.ContainsKey(slideIndex) && _memoryStreams[slideIndex] != null)
|
||||||
|
|
||||||
if (strokes != null && strokes.Count > 0)
|
|
||||||
{
|
{
|
||||||
inkCanvas.Strokes.Add(strokes);
|
try
|
||||||
|
{
|
||||||
|
_memoryStreams[slideIndex].Position = 0;
|
||||||
|
inkCanvas.Strokes.Add(new StrokeCollection(_memoryStreams[slideIndex]));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"从内存流加载第 {slideIndex} 页墨迹失败: {ex}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -1297,11 +1449,17 @@ namespace Ink_Canvas
|
|||||||
|
|
||||||
// 重置当前播放页码跟踪
|
// 重置当前播放页码跟踪
|
||||||
_currentSlideShowPosition = 0;
|
_currentSlideShowPosition = 0;
|
||||||
|
_previousSlideID = 0;
|
||||||
lock (_slideSwitchLock)
|
lock (_slideSwitchLock)
|
||||||
{
|
{
|
||||||
_isProcessingSlideSwitch = false;
|
_isProcessingSlideSwitch = false;
|
||||||
}
|
}
|
||||||
|
lock (_memoryStreams)
|
||||||
|
{
|
||||||
|
foreach (var stream in _memoryStreams.Values)
|
||||||
|
stream?.Dispose();
|
||||||
|
_memoryStreams.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
LogHelper.WriteLogToFile("PPT状态变量已重置", LogHelper.LogType.Trace);
|
LogHelper.WriteLogToFile("PPT状态变量已重置", LogHelper.LogType.Trace);
|
||||||
}
|
}
|
||||||
@@ -1630,13 +1788,20 @@ namespace Ink_Canvas
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 保存当前页墨迹
|
|
||||||
var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
|
var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
|
||||||
if (currentSlide > 0)
|
if (currentSlide > 0)
|
||||||
{
|
{
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
{
|
{
|
||||||
_singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
|
if (inkCanvas?.Strokes != null && inkCanvas.Strokes.Count > 0)
|
||||||
|
{
|
||||||
|
var ms = new MemoryStream();
|
||||||
|
inkCanvas.Strokes.Save(ms);
|
||||||
|
ms.Position = 0;
|
||||||
|
if (_memoryStreams.ContainsKey(currentSlide))
|
||||||
|
_memoryStreams[currentSlide]?.Dispose();
|
||||||
|
_memoryStreams[currentSlide] = ms;
|
||||||
|
}
|
||||||
timeMachine.ClearStrokeHistory();
|
timeMachine.ClearStrokeHistory();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user