Merge pull request #80 from InkCanvasForClass/beta

合并分支
This commit is contained in:
CJK_mkp
2025-07-14 08:58:57 +08:00
committed by GitHub
7 changed files with 66 additions and 160 deletions
+1 -2
View File
@@ -2347,8 +2347,7 @@
<TextBlock Foreground="#fafafa" Text="墨迹与截图的保存路径" VerticalAlignment="Center" <TextBlock Foreground="#fafafa" Text="墨迹与截图的保存路径" VerticalAlignment="Center"
FontSize="14" Margin="0,0,16,0" /> FontSize="14" Margin="0,0,16,0" />
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="10"> <ui:SimpleStackPanel Orientation="Horizontal" Spacing="10">
<TextBox Width="320" x:Name="AutoSavedStrokesLocation" <TextBox Width="320" x:Name="AutoSavedStrokesLocation" Text="D:\Ink Canvas"
Text="{Binding AppDomain.CurrentDomain.BaseDirectory, StringFormat={}Saves}"
TextWrapping="Wrap" TextWrapping="Wrap"
TextChanged="AutoSavedStrokesLocationTextBox_TextChanged" /> TextChanged="AutoSavedStrokesLocationTextBox_TextChanged" />
<Button Name="AutoSavedStrokesLocationButton" Content="浏览" <Button Name="AutoSavedStrokesLocationButton" Content="浏览"
+20 -23
View File
@@ -665,12 +665,6 @@ namespace Ink_Canvas {
private async void PptApplication_SlideShowBegin(SlideShowWindow Wn) { private async void PptApplication_SlideShowBegin(SlideShowWindow Wn) {
try { try {
// 修改加载路径到软件根目录下的Saves文件夹
var folderPath = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"Saves",
@"Auto Saved - Presentations\" + Wn.Presentation.Name + "_" + Wn.Presentation.Slides.Count
);
if (Settings.Automation.IsAutoFoldInPPTSlideShow && !isFloatingBarFolded) if (Settings.Automation.IsAutoFoldInPPTSlideShow && !isFloatingBarFolded)
await FoldFloatingBar(new object()); await FoldFloatingBar(new object());
@@ -710,9 +704,13 @@ namespace Ink_Canvas {
//检查是否有已有墨迹,并加载 //检查是否有已有墨迹,并加载
if (Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint) if (Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint)
if (Directory.Exists(folderPath)) { if (Directory.Exists(Settings.Automation.AutoSavedStrokesLocation +
@"\Auto Saved - Presentations\" + Wn.Presentation.Name + "_" +
Wn.Presentation.Slides.Count)) {
LogHelper.WriteLogToFile("Found saved strokes", LogHelper.LogType.Trace); LogHelper.WriteLogToFile("Found saved strokes", LogHelper.LogType.Trace);
var files = new DirectoryInfo(folderPath).GetFiles(); var files = new DirectoryInfo(Settings.Automation.AutoSavedStrokesLocation +
@"\Auto Saved - Presentations\" + Wn.Presentation.Name + "_" +
Wn.Presentation.Slides.Count).GetFiles();
var count = 0; var count = 0;
foreach (var file in files) foreach (var file in files)
if (file.Name != "Position") { if (file.Name != "Position") {
@@ -794,16 +792,9 @@ namespace Ink_Canvas {
isEnteredSlideShowEndEvent = true; isEnteredSlideShowEndEvent = true;
if (Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint) { if (Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint) {
// 修改保存路径到软件根目录下的Saves文件夹 var folderPath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - Presentations\" +
var folderPath = Path.Combine( Pres.Name + "_" + Pres.Slides.Count;
AppDomain.CurrentDomain.BaseDirectory,
"Saves",
@"Auto Saved - Presentations\" + Pres.Name + "_" + Pres.Slides.Count
);
// 确保目录存在
if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath); if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);
try { try {
File.WriteAllText(folderPath + "/Position", previousSlideID.ToString()); File.WriteAllText(folderPath + "/Position", previousSlideID.ToString());
} }
@@ -819,15 +810,21 @@ namespace Ink_Canvas {
memoryStreams[i].Position = 0; memoryStreams[i].Position = 0;
var byteLength = memoryStreams[i].Read(srcBuf, 0, srcBuf.Length); var byteLength = memoryStreams[i].Read(srcBuf, 0, srcBuf.Length);
// 使用Path.Combine构建文件路径 // 使用Path.Combine构建文件路径
File.WriteAllBytes(Path.Combine(folderPath, i.ToString("0000") + ".icstk"), srcBuf); File.WriteAllBytes(folderPath + @"\" + i.ToString("0000") + ".icstk", srcBuf);
LogHelper.WriteLogToFile(string.Format(
"Saved strokes for Slide {0}, size={1}, byteLength={2}", i.ToString(),
memoryStreams[i].Length, byteLength));
} else { } else {
var filePath = Path.Combine(folderPath, i.ToString("0000") + ".icstk"); if (File.Exists(folderPath + @"\" + i.ToString("0000") + ".icstk"))
if (File.Exists(filePath)) File.Delete(filePath); File.Delete(folderPath + @"\" + i.ToString("0000") + ".icstk");
} }
} }
catch (Exception ex) { catch (Exception ex) {
// 新增错误处理逻辑 LogHelper.WriteLogToFile(
LogHelper.WriteLogToFile($"保存第{i}页墨迹失败: {ex.Message}", LogHelper.LogType.Error); $"Failed to save strokes for Slide {i}\n{ex.ToString()}",
LogHelper.LogType.Error);
if (File.Exists(folderPath + @"\" + i.ToString("0000") + ".icstk"))
File.Delete(folderPath + @"\" + i.ToString("0000") + ".icstk");
} }
} }
@@ -1230,4 +1227,4 @@ namespace Ink_Canvas {
BtnPPTSlideShowEnd_Click(BtnPPTSlideShowEnd, null); BtnPPTSlideShowEnd_Click(BtnPPTSlideShowEnd, null);
} }
} }
} }
+15 -54
View File
@@ -20,61 +20,21 @@ namespace Ink_Canvas {
SaveInkCanvasStrokes(true, true); SaveInkCanvasStrokes(true, true);
} }
private void SaveInkCanvasStrokes(Boolean newNotice, Boolean saveByUser, string userSavePath = null) { private void SaveInkCanvasStrokes(bool newNotice = true, bool saveByUser = false) {
try { try {
// 优先使用用户指定的保存路径,否则使用默认路径 var savePath = Settings.Automation.AutoSavedStrokesLocation
+ (saveByUser ? @"\User Saved - " : @"\Auto Saved - ")
+ (currentMode == 0 ? "Annotation Strokes" : "BlackBoard Strokes");
if (!Directory.Exists(savePath)) Directory.CreateDirectory(savePath);
string savePathWithName; string savePathWithName;
if (!string.IsNullOrEmpty(userSavePath)) { if (currentMode != 0) // 黑板模式下
// 用户指定了完整保存路径(含文件名) savePathWithName = savePath + @"\" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff") + " Page-" +
savePathWithName = userSavePath; CurrentWhiteboardIndex + " StrokesCount-" + inkCanvas.Strokes.Count + ".icstk";
string dir = Path.GetDirectoryName(savePathWithName); else
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); //savePathWithName = savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".icstk";
} else { savePathWithName = savePath + @"\" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff") + ".icstk";
// 默认保存到软件根目录下的Saves文件夹 var fs = new FileStream(savePathWithName, FileMode.Create);
string appDirectory = AppDomain.CurrentDomain.BaseDirectory; inkCanvas.Strokes.Save(fs);
if (string.IsNullOrEmpty(appDirectory))
appDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string savePath = Path.Combine(appDirectory, "Saves",
(saveByUser ? @"User Saved - " : @"Auto Saved - ") +
(currentMode == 0 ? "Annotation Strokes" : "BlackBoard Strokes"));
if (!Directory.Exists(savePath)) Directory.CreateDirectory(savePath);
if (currentMode != 0) // 黑板模式下
savePathWithName = Path.Combine(savePath, DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff") +
" Page-" + CurrentWhiteboardIndex + " StrokesCount-" + inkCanvas.Strokes.Count + ".icstk");
else
savePathWithName = Path.Combine(savePath, DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff") + ".icstk");
}
try {
using (FileStream fs = new FileStream(savePathWithName, FileMode.Create)) {
inkCanvas.Strokes.Save(fs);
}
}
catch (Exception ex) when (ex is UnauthorizedAccessException || ex is DirectoryNotFoundException) {
// 异常时备用路径仍为默认Saves文件夹
string appDirectory = AppDomain.CurrentDomain.BaseDirectory;
if (string.IsNullOrEmpty(appDirectory))
appDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string fallbackPath = Path.Combine(appDirectory, "Saves");
Directory.CreateDirectory(fallbackPath);
string fileName = Path.GetFileNameWithoutExtension(savePathWithName) + "_retry.icstk";
string newPath = Path.Combine(fallbackPath, fileName);
try {
using (FileStream fs = new FileStream(newPath, FileMode.Create)) {
inkCanvas.Strokes.Save(fs);
savePathWithName = newPath;
}
}
catch (Exception fallbackEx) {
ShowNotification($"墨迹保存失败: {fallbackEx.Message}");
return;
}
}
catch (Exception ex) {
ShowNotification($"墨迹保存失败: {ex.Message}");
return;
}
if (newNotice) ShowNotification("墨迹成功保存至 " + savePathWithName); if (newNotice) ShowNotification("墨迹成功保存至 " + savePathWithName);
} }
catch (Exception ex) { catch (Exception ex) {
@@ -89,6 +49,7 @@ namespace Ink_Canvas {
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
var openFileDialog = new OpenFileDialog(); var openFileDialog = new OpenFileDialog();
openFileDialog.InitialDirectory = Settings.Automation.AutoSavedStrokesLocation;
openFileDialog.Title = "打开墨迹文件"; openFileDialog.Title = "打开墨迹文件";
openFileDialog.Filter = "Ink Canvas Strokes File (*.icstk)|*.icstk"; openFileDialog.Filter = "Ink Canvas Strokes File (*.icstk)|*.icstk";
if (openFileDialog.ShowDialog() != true) return; if (openFileDialog.ShowDialog() != true) return;
@@ -124,4 +85,4 @@ namespace Ink_Canvas {
} }
} }
} }
} }
+19 -68
View File
@@ -1,7 +1,6 @@
using System; using System;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
namespace Ink_Canvas { namespace Ink_Canvas {
@@ -36,90 +35,42 @@ namespace Ink_Canvas {
using (var memoryGraphics = System.Drawing.Graphics.FromImage(bitmap)) { using (var memoryGraphics = System.Drawing.Graphics.FromImage(bitmap)) {
memoryGraphics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, System.Drawing.CopyPixelOperation.SourceCopy); memoryGraphics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, System.Drawing.CopyPixelOperation.SourceCopy);
// 确保目录存在
var directory = Path.GetDirectoryName(savePath); var directory = Path.GetDirectoryName(savePath);
if (!Directory.Exists(directory)) { if (!Directory.Exists(directory)) {
Directory.CreateDirectory(directory); Directory.CreateDirectory(directory);
} }
try { bitmap.Save(savePath, ImageFormat.Png);
// 新增双重目录检查
Directory.CreateDirectory(directory); // 防止多线程场景下的竞争条件
bitmap.Save(savePath, ImageFormat.Png);
}
catch (Exception ex) when (ex is IOException ||
ex is UnauthorizedAccessException ||
ex is ExternalException) { // 新增GDI+异常捕获
// 改进备用路径处理
var docPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
"Auto Saved - Screenshots",
DateTime.Now.ToString("yyyyMMdd"),
Path.GetFileNameWithoutExtension(savePath) + "_retry.png"); // 添加重试后缀
try {
var docDir = Path.GetDirectoryName(docPath);
Directory.CreateDirectory(docDir);
bitmap.Save(docPath, ImageFormat.Png);
savePath = docPath;
}
catch (Exception fallbackEx) {
// 最终错误处理
if (!isHideNotification) {
ShowNotification($"截图保存失败: {fallbackEx.Message}");
}
return;
}
}
} }
if (!isHideNotification) { if (!isHideNotification) {
try { ShowNotification($"截图成功保存至 {savePath}");
ShowNotification($"截图成功保存至 {savePath}");
}
catch {
// 防止通知系统自身异常导致崩溃
}
} }
} }
// 获取日期文件夹路径 // 获取日期文件夹路径
private string GetDateFolderPath(string fileName) { private string GetDateFolderPath(string fileName) {
var basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Saves"); if (string.IsNullOrWhiteSpace(fileName)) {
var dateFolder = DateTime.Now.ToString("yyyyMMdd"); fileName = DateTime.Now.ToString("HH-mm-ss");
var fullPath = Path.Combine(basePath, "Auto Saved - Screenshots", dateFolder);
try {
if (!Directory.Exists(fullPath)) {
Directory.CreateDirectory(fullPath);
}
}
catch (Exception ex) when
(ex is IOException ||
ex is UnauthorizedAccessException)
{
// 如果创建失败则使用软件根目录作为最终备选
basePath = AppDomain.CurrentDomain.BaseDirectory;
fullPath = Path.Combine(basePath, "Auto Saved - Screenshots", dateFolder);
Directory.CreateDirectory(fullPath);
} }
return Path.Combine(fullPath, $"{fileName}.png"); var basePath = Settings.Automation.AutoSavedStrokesLocation;
var dateFolder = DateTime.Now.ToString("yyyyMMdd");
return Path.Combine(
basePath,
"Auto Saved - Screenshots",
dateFolder,
$"{fileName}.png");
} }
// 获取默认文件夹路径
private string GetDefaultFolderPath() { private string GetDefaultFolderPath() {
var basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Saves"); var basePath = Settings.Automation.AutoSavedStrokesLocation;
var screenshotsFolder = Path.Combine(basePath, "Auto Saved - Screenshots"); var screenshotsFolder = Path.Combine(basePath, "Auto Saved - Screenshots");
try { if (!Directory.Exists(screenshotsFolder)) {
if (!Directory.Exists(screenshotsFolder)) {
Directory.CreateDirectory(screenshotsFolder);
}
}
catch (Exception) {
// 如果创建失败则使用文档目录
basePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
screenshotsFolder = Path.Combine(basePath, "Auto Saved - Screenshots");
Directory.CreateDirectory(screenshotsFolder); Directory.CreateDirectory(screenshotsFolder);
} }
@@ -128,4 +79,4 @@ namespace Ink_Canvas {
$"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.png"); $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.png");
} }
} }
} }
+7 -7
View File
@@ -1259,18 +1259,18 @@ namespace Ink_Canvas {
var folderBrowser = new System.Windows.Forms.FolderBrowserDialog(); var folderBrowser = new System.Windows.Forms.FolderBrowserDialog();
folderBrowser.ShowDialog(); folderBrowser.ShowDialog();
if (folderBrowser.SelectedPath.Length > 0) AutoSavedStrokesLocation.Text = folderBrowser.SelectedPath; if (folderBrowser.SelectedPath.Length > 0) AutoSavedStrokesLocation.Text = folderBrowser.SelectedPath;
SaveSettingsToFile();
} }
private void SetAutoSavedStrokesLocationToDiskDButton_Click(object sender, RoutedEventArgs e) { private void SetAutoSavedStrokesLocationToDiskDButton_Click(object sender, RoutedEventArgs e) {
// 修改默认路径为软件根目录下的 Saves 文件夹 AutoSavedStrokesLocation.Text = @"D:\Ink Canvas";
string appDirectory = AppDomain.CurrentDomain.BaseDirectory; SaveSettingsToFile();
string savesPath = System.IO.Path.Combine(appDirectory, "Saves");
AutoSavedStrokesLocation.Text = savesPath;
} }
private void SetAutoSavedStrokesLocationToDocumentFolderButton_Click(object sender, RoutedEventArgs e) { private void SetAutoSavedStrokesLocationToDocumentFolderButton_Click(object sender, RoutedEventArgs e) {
AutoSavedStrokesLocation.Text = AutoSavedStrokesLocation.Text =
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Ink Canvas"; Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Ink Canvas";
SaveSettingsToFile();
} }
private void ToggleSwitchAutoDelSavedFiles_Toggled(object sender, RoutedEventArgs e) { private void ToggleSwitchAutoDelSavedFiles_Toggled(object sender, RoutedEventArgs e) {
@@ -1814,12 +1814,12 @@ namespace Ink_Canvas {
} }
private void HyperlinkSourceToPresentRepository_Click(object sender, RoutedEventArgs e) { private void HyperlinkSourceToPresentRepository_Click(object sender, RoutedEventArgs e) {
Process.Start("https://github.com/ChangSakura/Ink-Canvas"); Process.Start("https://bgithub.xyz/ChangSakura/Ink-Canvas");
HideSubPanels(); HideSubPanels();
} }
private void HyperlinkSourceToOringinalRepository_Click(object sender, RoutedEventArgs e) { private void HyperlinkSourceToOringinalRepository_Click(object sender, RoutedEventArgs e) {
Process.Start("https://github.com/WXRIW/Ink-Canvas"); Process.Start("https://bgithub.xyz/WXRIW/Ink-Canvas");
HideSubPanels(); HideSubPanels();
} }
@@ -1879,4 +1879,4 @@ namespace Ink_Canvas {
} }
} }
} }
} }
+3 -2
View File
@@ -1,4 +1,5 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System.IO;
namespace Ink_Canvas namespace Ink_Canvas
{ {
@@ -347,7 +348,7 @@ namespace Ink_Canvas
public int MinimumAutomationStrokeNumber { get; set; } = 0; public int MinimumAutomationStrokeNumber { get; set; } = 0;
[JsonProperty("autoSavedStrokesLocation")] [JsonProperty("autoSavedStrokesLocation")]
public string AutoSavedStrokesLocation = @"D:\Ink Canvas"; public string AutoSavedStrokesLocation = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "saves");
[JsonProperty("autoDelSavedFiles")] [JsonProperty("autoDelSavedFiles")]
public bool AutoDelSavedFiles = false; public bool AutoDelSavedFiles = false;
@@ -437,4 +438,4 @@ namespace Ink_Canvas
[JsonProperty("directCallCiRand")] [JsonProperty("directCallCiRand")]
public bool DirectCallCiRand { get; set; } = false; public bool DirectCallCiRand { get; set; } = false;
} }
} }
+1 -4
View File
@@ -65,9 +65,6 @@
不能,但是你可以期待 icc-gtk4,是正在开发的仅支持 Linux 平台的 icc 移植版本。 不能,但是你可以期待 icc-gtk4,是正在开发的仅支持 Linux 平台的 icc 移植版本。
## ✏️ 贡献指南 ## ✏️ 贡献指南
> [!NOTE]
>
> 请注意,本贡献指南由 Hydrogen @Hydro11451 )撰写,尚未受到官方认可,并且尚未完成。
请前往 InkCanvasForClass/dubious-notes 请前往 InkCanvasForClass/dubious-notes
@@ -79,7 +76,7 @@
## 贡献者 ## 贡献者
> [!NOTE] > [!NOTE]
> 此列表通过[All Contributers](https://allcontributors.org/)实现。<br>由于此存储库使用“Beta优先”策略(即在`beta`分支中修改并PR到`main`),而@all-contributors Bot默认会将修改提交到`main`分支,这意味着此列表可能发生错误。<br>正在商议的解决方案:<br>1. 将默认分支切换为`beta`<br>2. *将代码迁移到`community-beta`(?)* > 此列表通过[All Contributers](https://allcontributors.org/)实现。
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start --> <!-- prettier-ignore-start -->
<!-- markdownlint-disable --> <!-- markdownlint-disable -->