Skip to content
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
15 changes: 14 additions & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# CHANGELOG
## COMPASS v1.8.8 (28 June 2025)
## COMPASS v1.8.9 (26 October 2025)

### Improvements

- Improved performance of pdf thumbnail generation

### Fixes

- Fixed "Create Tag Group" creating regular tags instead
- Fixed content extending out of window bounds when maximized
- Fixed a crash when preferences file is corrupted
- Fixed rare crash when displaying the update notification
- Fixed multiple possible crashes when dropping files
## COMPASS v1.8.8 (28 June 2025)

### Fixes
- Fix crashes on commands in context menu when no items are selected.
Expand Down
4 changes: 1 addition & 3 deletions Deployment/install.iss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "COMPASS"
#define MyAppVersion "1.8.8"
#define MyAppVersion "1.8.9"
#define MyAppPublisher "Paul De Smul"
#define MyAppURL "https://www.compassapp.info"
#define MyAppExeName "COMPASS.exe"
Expand Down Expand Up @@ -39,8 +39,6 @@ Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{
[Files]
Source: "..\src\bin\Publish\win-x64\*"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\src\bin\Publish\win-x64\Media\*"; DestDir: "{app}\Media"; Flags: ignoreversion
Source: "..\src\bin\Publish\win-x64\gs\*"; DestDir: "{app}\gs"; Flags: ignoreversion
Source: "..\src\bin\Publish\win-x64\selenium-manager\windows\*"; DestDir : "{app}\selenium-manager\windows"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Expand Down
8 changes: 4 additions & 4 deletions Tests/IntegrationTests/Satchels_Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public async Task TestSatchelExportImport()

Assert.IsTrue(importViewModel.ContentSelectorVM.HasCodices, "deserialized satchel has no Codices");
Assert.IsTrue(importViewModel.ContentSelectorVM.HasTags, "deserialized satchel has no Tags");
Assert.AreEqual(testCollection.AllCodices.Count, deserializedCollection.AllCodices.Count);
Assert.AreEqual(testCollection.AllTags.Count, deserializedCollection.AllTags.Count);
Assert.HasCount(testCollection.AllCodices.Count, deserializedCollection.AllCodices);
Assert.HasCount(testCollection.AllTags.Count, deserializedCollection.AllTags);

//Complete import to new Collection
importViewModel.CollectionName = "Imported_Satchel"; //cannot use a protect __ name because it is an illegal name
Expand All @@ -55,8 +55,8 @@ public async Task TestSatchelExportImport()

importedCollection = MainViewModel.CollectionVM.CurrentCollection;

Assert.AreEqual(deserializedCollection.AllCodices.Count, importedCollection.AllCodices.Count);
Assert.AreEqual(deserializedCollection.AllTags.Count, importedCollection.AllTags.Count);
Assert.HasCount(deserializedCollection.AllCodices.Count, importedCollection.AllCodices);
Assert.HasCount(deserializedCollection.AllTags.Count, importedCollection.AllTags);
}
finally
{
Expand Down
10 changes: 5 additions & 5 deletions Tests/Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="coverlet.msbuild" Version="6.0.1">
<PackageReference Include="coverlet.msbuild" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.2.2" />
<PackageReference Include="MSTest.TestFramework" Version="3.2.2" />
<PackageReference Include="coverlet.collector" Version="6.0.1">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.0" />
<PackageReference Include="MSTest.TestAdapter" Version="4.0.1" />
<PackageReference Include="MSTest.TestFramework" Version="4.0.1" />
<PackageReference Include="coverlet.collector" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
6 changes: 3 additions & 3 deletions Tests/UnitTests/Serialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public void SerializeSatchelInfo()

var newSatchelInfo = JsonSerializer.Deserialize<SatchelInfo>(json);
Assert.IsNotNull(newSatchelInfo);
Assert.IsTrue(newSatchelInfo.CreationVersion == Reflection.Version);
Assert.AreEqual(Reflection.Version, newSatchelInfo.CreationVersion);
Assert.IsTrue(newSatchelInfo.CreationDate < DateTime.Now);
}

Expand All @@ -40,7 +40,7 @@ public void DeserializeSatchelInfoExtraFields()

var satchelInfo = JsonSerializer.Deserialize<SatchelInfo>(json);
Assert.IsNotNull(satchelInfo);
Assert.IsTrue(satchelInfo.CreationVersion == "1.200.0");
Assert.AreEqual("1.200.0", satchelInfo.CreationVersion);
}

[TestMethod]
Expand All @@ -54,7 +54,7 @@ public void DeserializeIncompleteSatchelInfo()

var satchelInfo = JsonSerializer.Deserialize<SatchelInfo>(json);
Assert.IsNotNull(satchelInfo);
Assert.IsTrue(satchelInfo.MinTagsVersion == new SatchelInfo().MinTagsVersion);
Assert.AreEqual(new SatchelInfo().MinTagsVersion, satchelInfo.MinTagsVersion);
}

[TestMethod]
Expand Down
38 changes: 14 additions & 24 deletions src/COMPASS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,12 @@

<ItemGroup>
<None Remove="Media\CompassLogo.png" />
<None Remove="gs\gsdll64.dll" />
<None Remove="gs\gswin64c.exe" />
</ItemGroup>

<ItemGroup>

<Content Include="COMPASS.ico" />

<Content Include="gs\gsdll64.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

<Content Include="gs\gswin64c.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

<Resource Include="Media\CompassLogo.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Resource>
Expand All @@ -49,31 +39,31 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Autofac" Version="8.3.0" />
<PackageReference Include="Autofac" Version="8.4.0" />
<PackageReference Include="Autoupdater.NET.Official" Version="1.9.2" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="DotNetSeleniumExtras.WaitHelpers" Version="3.11.0" />
<PackageReference Include="FuzzySharp" Version="2.0.2" />
<PackageReference Include="gong-wpf-dragdrop" Version="4.0.0" />
<PackageReference Include="HtmlAgilityPack" Version="1.12.1" />
<PackageReference Include="itext7" Version="9.2.0" />
<PackageReference Include="itext7.bouncy-castle-adapter" Version="9.2.0" />
<PackageReference Include="log4net" Version="3.1.0" />
<PackageReference Include="Magick.NET-Q8-AnyCPU" Version="14.6.0" />
<PackageReference Include="Magick.NET.SystemDrawing" Version="8.0.6" />
<PackageReference Include="HtmlAgilityPack" Version="1.12.4" />
<PackageReference Include="itext" Version="9.3.0" />
<PackageReference Include="itext.bouncy-castle-adapter" Version="9.3.0" />
<PackageReference Include="log4net" Version="3.2.0" />
<PackageReference Include="Magick.NET-Q8-AnyCPU" Version="14.9.0" />
<PackageReference Include="Magick.NET.SystemDrawing" Version="8.0.11" />
<PackageReference Include="MaterialDesignThemes" Version="4.9.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" />
<PackageReference Include="OpenCvSharp4.Extensions" Version="4.11.0.20250507" />
<PackageReference Include="OpenCvSharp4.Windows" Version="4.11.0.20250507" />
<PackageReference Include="ScrapySharp" Version="3.0.0" />
<PackageReference Include="Selenium.Support" Version="4.33.0" />
<PackageReference Include="Selenium.WebDriver" Version="4.33.0" />
<PackageReference Include="SharpCompress" Version="0.40.0" />
<PackageReference Include="System.Drawing.Common" Version="9.0.6" />
<PackageReference Include="PDFtoImage" Version="5.1.1" />
<PackageReference Include="Selenium.Support" Version="4.38.0" />
<PackageReference Include="Selenium.WebDriver" Version="4.38.0" />
<PackageReference Include="SharpCompress" Version="0.41.0" />
<PackageReference Include="System.Drawing.Common" Version="9.0.10" />
<PackageReference Include="VirtualizingWrapPanel" Version="2.1.1" />
<PackageReference Include="WpfAnimatedGif" Version="2.0.2" />
<PackageReference Include="ZXing.Net" Version="0.16.10" />
<PackageReference Include="ZXing.Net" Version="0.16.11" />
<PackageReference Include="ZXing.Net.Bindings.Windows.Compatibility" Version="0.16.13" />
</ItemGroup>

Expand Down
2 changes: 1 addition & 1 deletion src/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
// app, or any theme specific resource dictionaries)
)]

[assembly: AssemblyVersion("1.8.8")]
[assembly: AssemblyVersion("1.8.9")]
[assembly: System.Runtime.Versioning.SupportedOSPlatform("windows")]


46 changes: 34 additions & 12 deletions src/Services/PreferencesService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,28 @@ public void SavePreferences()

string tempFileName = PreferencesFilePath + ".tmp";


lock (writeLocker)
{
//cleanup any previous temp file
File.Delete(tempFileName);

//Write to the temp file
using (var writer = XmlWriter.Create(tempFileName, XmlService.XmlWriteSettings))
{
XmlSerializer serializer = new(typeof(PreferencesDto));
serializer.Serialize(writer, dto);
}

// Verify the temp file was written successfully and has content
if (!File.Exists(tempFileName) || new FileInfo(tempFileName).Length <= 0)
{
Logger.Error($"Failed to write preferences to {tempFileName}", new Exception());
return;
}

//if successfully written to the tmp file, move to actual path
File.Move(tempFileName, PreferencesFilePath, true);
File.Delete(tempFileName);
}
}
catch (UnauthorizedAccessException ex)
Expand All @@ -65,7 +76,13 @@ public void SavePreferences()

public Preferences? LoadPreferences()
{
if (File.Exists(PreferencesFilePath))
if (!File.Exists(PreferencesFilePath))
{
Logger.Warn($"{PreferencesFilePath} does not exist.", new FileNotFoundException());
return null;
}

try
{
//Label of codexProperties should still be deserialized for backwards compatibility
var overrides = new XmlAttributeOverrides();
Expand All @@ -76,20 +93,25 @@ public void SavePreferences()
XmlSerializer serializer = new(typeof(PreferencesDto), overrides);
if (serializer.Deserialize(reader) is PreferencesDto prefsDto)
{
return prefsDto is null ? new() : prefsDto.ToModel();
}
else
{
Logger.Error($"{PreferencesFilePath} could not be read.", new Exception());
return null;
return prefsDto.ToModel();
}

Logger.Error($"{PreferencesFilePath} could not be read.", new Exception());
}
else
catch (XmlException ex)
{
Logger.Warn($"{PreferencesFilePath} does not exist.", new FileNotFoundException());
return null;
Logger.Error($"XML parsing error in {PreferencesFilePath}. File may be corrupted or empty.", ex);
}
catch (InvalidOperationException ex) when (ex.InnerException is XmlException)
{
Logger.Error($"XML deserialization error in {PreferencesFilePath}. File may be corrupted or empty.", ex);
}
catch (Exception ex)
{
Logger.Error($"Unexpected error loading preferences from {PreferencesFilePath}", ex);
}
}

return null;
}
}
}
50 changes: 37 additions & 13 deletions src/ViewModels/CodexEditViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows;

Expand Down Expand Up @@ -254,28 +255,51 @@ public void OKBtn()

public void DragOver(IDropInfo dropInfo)
{
if (dropInfo.Data is DataObject data
&& data.GetFileDropList().Count == 1
&& IOService.IsImageFile(data.GetFileDropList().Cast<string>().First()))
try
{
dropInfo.DropTargetAdorner = DropTargetAdorners.Highlight;
dropInfo.Effects = DragDropEffects.Copy;
if (dropInfo.Data is DataObject data &&
data.GetFileDropList() is { Count: 1 } fileDropList &&
IOService.IsImageFile(fileDropList.Cast<string>().First()))
{
dropInfo.DropTargetAdorner = DropTargetAdorners.Highlight;
dropInfo.Effects = DragDropEffects.Copy;
return;
}
}
else
catch (COMException ex)
{
dropInfo.Effects = DragDropEffects.None;
Logger.Error($"COM error accessing drag-drop data during DragOver", ex);
}
catch (Exception ex)
{
Logger.Error($"Unexpected error accessing drag-drop data during DragOver", ex);
}

dropInfo.Effects = DragDropEffects.None;
}

public void Drop(IDropInfo dropInfo)
{
if (dropInfo.Data is DataObject data
&& data.GetFileDropList().Count == 1
&& IOService.IsImageFile(data.GetFileDropList().Cast<string>().First()))
try
{
string path = data.GetFileDropList().Cast<string>().First();
CoverService.GetCoverFromImage(path, TempCodex);
RefreshCover();
if (dropInfo.Data is DataObject data &&
data.GetFileDropList() is { Count: 1 } fileDropList &&
fileDropList.Cast<string>().Single() is string imgPath &&
IOService.IsImageFile(imgPath))
{
{
CoverService.GetCoverFromImage(imgPath, TempCodex);
RefreshCover();
}
}
}
catch (COMException ex)
{
Logger.Error($"COM error accessing drag-drop data during Drop", ex);
}
catch (Exception ex)
{
Logger.Error($"Unexpected error during drag-drop operation", ex);
}
}
#endregion
Expand Down
Loading