Config basic implementation (untested)

This commit is contained in:
Ben Olden-Cooligan 2019-03-15 14:27:14 -04:00
parent 80420f964e
commit 5cb1350857
15 changed files with 473 additions and 232 deletions

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace NAPS2.Config.Experimental
{
public class CommonConfig
{
public bool? SingleInstance { get; set; }
public string Culture { get; set; }
public NestedConfig Nested { get; set; }
}
public class NestedConfig
{
public int? SomeInt { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace NAPS2.Config.Experimental
{
public static class ConfigCopier
{
public static void Copy<T>(T src, T dst)
{
// TODO
throw new NotImplementedException();
}
public static T Copy<T>(T src)
{
var copy = (T)Activator.CreateInstance(typeof(T));
Copy(src, copy);
return copy;
}
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace NAPS2.Config.Experimental
{
public abstract class ConfigProvider
{
public T Get<T>(Func<CommonConfig, T> func) where T : class => GetInternal(func);
public T Get<T>(Func<CommonConfig, T?> func) where T : struct => GetInternal(func) ?? default;
protected abstract T GetInternal<T>(Func<CommonConfig, T> func);
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace NAPS2.Config.Experimental
{
public enum ConfigReadMode
{
All,
LockedOnly,
DefaultOnly
}
}

View File

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace NAPS2.Config.Experimental
{
public abstract class ConfigScope
{
protected ConfigScope(ConfigScopeMode mode)
{
Mode = mode;
}
public ConfigScopeMode Mode { get; }
public T Get<T>(Func<CommonConfig, T> func)
{
lock (this)
{
return GetInternal(func);
}
}
public void Set(Action<CommonConfig> func)
{
if (Mode == ConfigScopeMode.ReadOnly)
{
throw new NotSupportedException("This config scope is in ReadOnly mode.");
}
lock (this)
{
SetInternal(func);
}
}
public void SetAll(CommonConfig changes)
{
if (Mode == ConfigScopeMode.ReadOnly)
{
throw new NotSupportedException("This config scope is in ReadOnly mode.");
}
lock (this)
{
SetAllInternal(changes);
}
}
protected abstract T GetInternal<T>(Func<CommonConfig, T> func);
protected abstract void SetInternal(Action<CommonConfig> func);
public abstract void SetAllInternal(CommonConfig delta);
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace NAPS2.Config.Experimental
{
public enum ConfigScopeMode
{
ReadOnly,
ReadWrite
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace NAPS2.Config.Experimental
{
public class ConfigScopes
{
public ConfigScopes(string appConfigPath, string userConfigPath)
{
AppLocked = new FileConfigScope(appConfigPath, new ConfigSerializer(ConfigReadMode.LockedOnly), ConfigScopeMode.ReadOnly);
Run = new ObjectConfigScope(new CommonConfig(), ConfigScopeMode.ReadWrite);
User = new FileConfigScope(userConfigPath, new ConfigSerializer(ConfigReadMode.All), ConfigScopeMode.ReadWrite);
AppDefault = new FileConfigScope(appConfigPath, new ConfigSerializer(ConfigReadMode.DefaultOnly), ConfigScopeMode.ReadOnly);
InternalDefault = new ObjectConfigScope(InternalDefaults.GetCommonConfig(), ConfigScopeMode.ReadOnly);
Provider = new ScopeSetConfigProvider(AppLocked, Run, User, AppDefault, InternalDefault);
}
public ConfigProvider Provider { get; }
public ConfigScope AppLocked { get; }
public ConfigScope Run { get; }
public ConfigScope User { get; }
public ConfigScope AppDefault { get; }
public ConfigScope InternalDefault { get; }
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NAPS2.Util;
namespace NAPS2.Config.Experimental
{
public class ConfigSerializer : ISerializer<CommonConfig>
{
public ConfigSerializer(ConfigReadMode mode)
{
throw new NotImplementedException();
}
public void Serialize(Stream stream, CommonConfig obj)
{
throw new NotImplementedException();
}
public CommonConfig Deserialize(Stream stream) => throw new NotImplementedException();
}
}

View File

@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NAPS2.Logging;
using NAPS2.Util;
namespace NAPS2.Config.Experimental
{
public class FileConfigScope : ConfigScope
{
private readonly string filePath;
private readonly ISerializer<CommonConfig> serializer;
private CommonConfig cache;
private CommonConfig changes;
public FileConfigScope(string filePath, ISerializer<CommonConfig> serializer, ConfigScopeMode mode) : base(mode)
{
this.filePath = filePath;
this.serializer = serializer;
cache = new CommonConfig();
changes = new CommonConfig();
}
protected override T GetInternal<T>(Func<CommonConfig, T> func)
{
// TODO: Use FileSystemWatcher to determine if we actually
// TODO: need to read from disk. Also to create change events.
ReadHandshake();
var value = func(changes);
if (value != null)
{
return value;
}
return func(cache);
}
protected override void SetInternal(Action<CommonConfig> func)
{
func(changes);
WriteHandshake();
}
public override void SetAllInternal(CommonConfig delta)
{
ConfigCopier.Copy(delta, changes);
WriteHandshake();
}
private void ReadHandshake()
{
// TODO: Retry
try
{
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
cache = serializer.Deserialize(stream);
}
}
catch (FileNotFoundException)
{
}
catch (IOException ex)
{
Log.ErrorException($"Error reading {filePath}", ex);
}
}
private void WriteHandshake()
{
// TODO: Retry, maybe async?
try
{
using (var stream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
cache = serializer.Deserialize(stream);
var copy = ConfigCopier.Copy(cache);
serializer.Serialize(stream, copy);
cache = copy;
changes = new CommonConfig();
}
}
catch (IOException ex)
{
Log.ErrorException($"Error writing {filePath}", ex);
}
}
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace NAPS2.Config.Experimental
{
public class InternalDefaults
{
// TODO: Test that no properties are null
public static CommonConfig GetCommonConfig() =>
new CommonConfig
{
SingleInstance = false,
Culture = "en",
Nested = new NestedConfig
{
SomeInt = 0
}
};
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace NAPS2.Config.Experimental
{
public class ObjectConfigScope : ConfigScope
{
private readonly CommonConfig obj;
public ObjectConfigScope(CommonConfig obj, ConfigScopeMode mode) : base(mode)
{
this.obj = obj;
}
protected override T GetInternal<T>(Func<CommonConfig, T> func) => func(obj);
protected override void SetInternal(Action<CommonConfig> func) => func(obj);
public override void SetAllInternal(CommonConfig delta)
{
ConfigCopier.Copy(delta, obj);
}
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace NAPS2.Config.Experimental
{
public class ScopeSetConfigProvider : ConfigProvider
{
private readonly ConfigScope[] scopes;
public ScopeSetConfigProvider(params ConfigScope[] scopes)
{
this.scopes = scopes.ToArray();
}
protected override T GetInternal<T>(Func<CommonConfig, T> func)
{
foreach (var scope in scopes)
{
var value = scope.Get(func);
if (value != null)
{
return value;
}
}
// TODO: Consider throwing an exception
return default;
}
}
}

View File

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace NAPS2.Config.Experimental
{
public class TransactionConfigScope : ConfigScope
{
private readonly ConfigScope store;
private CommonConfig changes;
public TransactionConfigScope(ConfigScope store) : base(ConfigScopeMode.ReadWrite)
{
if (store.Mode == ConfigScopeMode.ReadOnly)
{
throw new ArgumentException("A transaction can't be created for a ReadOnly scope.", nameof(store));
}
this.store = store;
changes = new CommonConfig();
}
public bool HasChanges { get; private set; }
public event EventHandler HasChangesChanged;
public void Commit()
{
lock (this)
{
lock (store)
{
store.SetAll(changes);
changes = new CommonConfig();
}
if (HasChanges)
{
HasChanges = false;
HasChangesChanged?.Invoke(this, EventArgs.Empty);
}
}
}
protected override T GetInternal<T>(Func<CommonConfig, T> func)
{
var value = func(changes);
if (value != null)
{
return value;
}
return store.Get(func);
}
protected override void SetInternal(Action<CommonConfig> func)
{
func(changes);
if (!HasChanges)
{
HasChanges = true;
HasChangesChanged?.Invoke(this, EventArgs.Empty);
}
}
public override void SetAllInternal(CommonConfig delta)
{
ConfigCopier.Copy(delta, changes);
}
}
}

View File

@ -147,6 +147,19 @@
<Compile Include="ClientServer\ScanCallback.cs" />
<Compile Include="ClientServer\ScanService.cs" />
<Compile Include="ClientServer\ServerDiscovery.cs" />
<Compile Include="Config\Experimental\CommonConfig.cs" />
<Compile Include="Config\Experimental\ConfigCopier.cs" />
<Compile Include="Config\Experimental\ConfigReadMode.cs" />
<Compile Include="Config\Experimental\ConfigScope.cs" />
<Compile Include="Config\Experimental\ConfigProvider.cs" />
<Compile Include="Config\Experimental\ConfigScopeMode.cs" />
<Compile Include="Config\Experimental\ConfigScopes.cs" />
<Compile Include="Config\Experimental\ConfigSerializer.cs" />
<Compile Include="Config\Experimental\FileConfigScope.cs" />
<Compile Include="Config\Experimental\InternalDefaults.cs" />
<Compile Include="Config\Experimental\ObjectConfigScope.cs" />
<Compile Include="Config\Experimental\ScopeSetConfigProvider.cs" />
<Compile Include="Config\Experimental\TransactionConfigScope.cs" />
<Compile Include="Config\StubConfigManager.cs" />
<Compile Include="Config\StubProfileManager.cs" />
<Compile Include="Dependencies\DownloadMirror.cs" />

View File

@ -177,126 +177,6 @@
<metadata name="ilProfileIcons.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<data name="&gt;&gt;txtKeywords.Name" xml:space="preserve">
<value>txtKeywords</value>
</data>
<data name="&gt;&gt;txtKeywords.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;txtKeywords.Parent" xml:space="preserve">
<value>groupMetadata</value>
</data>
<data name="&gt;&gt;txtKeywords.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;label6.Name" xml:space="preserve">
<value>label6</value>
</data>
<data name="&gt;&gt;label6.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label6.Parent" xml:space="preserve">
<value>groupMetadata</value>
</data>
<data name="&gt;&gt;label6.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="&gt;&gt;txtSubject.Name" xml:space="preserve">
<value>txtSubject</value>
</data>
<data name="&gt;&gt;txtSubject.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;txtSubject.Parent" xml:space="preserve">
<value>groupMetadata</value>
</data>
<data name="&gt;&gt;txtSubject.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="&gt;&gt;label5.Name" xml:space="preserve">
<value>label5</value>
</data>
<data name="&gt;&gt;label5.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label5.Parent" xml:space="preserve">
<value>groupMetadata</value>
</data>
<data name="&gt;&gt;label5.ZOrder" xml:space="preserve">
<value>3</value>
</data>
<data name="&gt;&gt;txtAuthor.Name" xml:space="preserve">
<value>txtAuthor</value>
</data>
<data name="&gt;&gt;txtAuthor.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;txtAuthor.Parent" xml:space="preserve">
<value>groupMetadata</value>
</data>
<data name="&gt;&gt;txtAuthor.ZOrder" xml:space="preserve">
<value>4</value>
</data>
<data name="&gt;&gt;label3.Name" xml:space="preserve">
<value>label3</value>
</data>
<data name="&gt;&gt;label3.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label3.Parent" xml:space="preserve">
<value>groupMetadata</value>
</data>
<data name="&gt;&gt;label3.ZOrder" xml:space="preserve">
<value>5</value>
</data>
<data name="&gt;&gt;txtTitle.Name" xml:space="preserve">
<value>txtTitle</value>
</data>
<data name="&gt;&gt;txtTitle.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;txtTitle.Parent" xml:space="preserve">
<value>groupMetadata</value>
</data>
<data name="&gt;&gt;txtTitle.ZOrder" xml:space="preserve">
<value>6</value>
</data>
<data name="&gt;&gt;label4.Name" xml:space="preserve">
<value>label4</value>
</data>
<data name="&gt;&gt;label4.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label4.Parent" xml:space="preserve">
<value>groupMetadata</value>
</data>
<data name="&gt;&gt;label4.ZOrder" xml:space="preserve">
<value>7</value>
</data>
<data name="groupMetadata.Location" type="System.Drawing.Point, System.Drawing">
<value>12, 91</value>
</data>
<data name="groupMetadata.Size" type="System.Drawing.Size, System.Drawing">
<value>408, 175</value>
</data>
<data name="groupMetadata.TabIndex" type="System.Int32, mscorlib">
<value>20</value>
</data>
<data name="groupMetadata.Text" xml:space="preserve">
<value>Metadata</value>
</data>
<data name="&gt;&gt;groupMetadata.Name" xml:space="preserve">
<value>groupMetadata</value>
</data>
<data name="&gt;&gt;groupMetadata.Type" xml:space="preserve">
<value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;groupMetadata.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;groupMetadata.ZOrder" xml:space="preserve">
<value>9</value>
</data>
<data name="txtKeywords.Location" type="System.Drawing.Point, System.Drawing">
<value>6, 149</value>
</data>
@ -501,125 +381,29 @@
<data name="&gt;&gt;label4.ZOrder" xml:space="preserve">
<value>7</value>
</data>
<data name="&gt;&gt;clbPerms.Name" xml:space="preserve">
<value>clbPerms</value>
<data name="groupMetadata.Location" type="System.Drawing.Point, System.Drawing">
<value>12, 91</value>
</data>
<data name="&gt;&gt;clbPerms.Type" xml:space="preserve">
<value>System.Windows.Forms.CheckedListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<data name="groupMetadata.Size" type="System.Drawing.Size, System.Drawing">
<value>408, 175</value>
</data>
<data name="&gt;&gt;clbPerms.Parent" xml:space="preserve">
<value>groupProtection</value>
<data name="groupMetadata.TabIndex" type="System.Int32, mscorlib">
<value>20</value>
</data>
<data name="&gt;&gt;clbPerms.ZOrder" xml:space="preserve">
<value>0</value>
<data name="groupMetadata.Text" xml:space="preserve">
<value>Metadata</value>
</data>
<data name="&gt;&gt;cbShowUserPassword.Name" xml:space="preserve">
<value>cbShowUserPassword</value>
<data name="&gt;&gt;groupMetadata.Name" xml:space="preserve">
<value>groupMetadata</value>
</data>
<data name="&gt;&gt;cbShowUserPassword.Type" xml:space="preserve">
<value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;cbShowUserPassword.Parent" xml:space="preserve">
<value>groupProtection</value>
</data>
<data name="&gt;&gt;cbShowUserPassword.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="&gt;&gt;cbShowOwnerPassword.Name" xml:space="preserve">
<value>cbShowOwnerPassword</value>
</data>
<data name="&gt;&gt;cbShowOwnerPassword.Type" xml:space="preserve">
<value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;cbShowOwnerPassword.Parent" xml:space="preserve">
<value>groupProtection</value>
</data>
<data name="&gt;&gt;cbShowOwnerPassword.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="&gt;&gt;txtUserPassword.Name" xml:space="preserve">
<value>txtUserPassword</value>
</data>
<data name="&gt;&gt;txtUserPassword.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;txtUserPassword.Parent" xml:space="preserve">
<value>groupProtection</value>
</data>
<data name="&gt;&gt;txtUserPassword.ZOrder" xml:space="preserve">
<value>3</value>
</data>
<data name="&gt;&gt;lblUserPassword.Name" xml:space="preserve">
<value>lblUserPassword</value>
</data>
<data name="&gt;&gt;lblUserPassword.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;lblUserPassword.Parent" xml:space="preserve">
<value>groupProtection</value>
</data>
<data name="&gt;&gt;lblUserPassword.ZOrder" xml:space="preserve">
<value>4</value>
</data>
<data name="&gt;&gt;txtOwnerPassword.Name" xml:space="preserve">
<value>txtOwnerPassword</value>
</data>
<data name="&gt;&gt;txtOwnerPassword.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;txtOwnerPassword.Parent" xml:space="preserve">
<value>groupProtection</value>
</data>
<data name="&gt;&gt;txtOwnerPassword.ZOrder" xml:space="preserve">
<value>5</value>
</data>
<data name="&gt;&gt;lblOwnerPassword.Name" xml:space="preserve">
<value>lblOwnerPassword</value>
</data>
<data name="&gt;&gt;lblOwnerPassword.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;lblOwnerPassword.Parent" xml:space="preserve">
<value>groupProtection</value>
</data>
<data name="&gt;&gt;lblOwnerPassword.ZOrder" xml:space="preserve">
<value>6</value>
</data>
<data name="&gt;&gt;cbEncryptPdf.Name" xml:space="preserve">
<value>cbEncryptPdf</value>
</data>
<data name="&gt;&gt;cbEncryptPdf.Type" xml:space="preserve">
<value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;cbEncryptPdf.Parent" xml:space="preserve">
<value>groupProtection</value>
</data>
<data name="&gt;&gt;cbEncryptPdf.ZOrder" xml:space="preserve">
<value>7</value>
</data>
<data name="groupProtection.Location" type="System.Drawing.Point, System.Drawing">
<value>12, 272</value>
</data>
<data name="groupProtection.Size" type="System.Drawing.Size, System.Drawing">
<value>408, 250</value>
</data>
<data name="groupProtection.TabIndex" type="System.Int32, mscorlib">
<value>21</value>
</data>
<data name="groupProtection.Text" xml:space="preserve">
<value>Encryption</value>
</data>
<data name="&gt;&gt;groupProtection.Name" xml:space="preserve">
<value>groupProtection</value>
</data>
<data name="&gt;&gt;groupProtection.Type" xml:space="preserve">
<data name="&gt;&gt;groupMetadata.Type" xml:space="preserve">
<value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;groupProtection.Parent" xml:space="preserve">
<data name="&gt;&gt;groupMetadata.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;groupProtection.ZOrder" xml:space="preserve">
<value>8</value>
<data name="&gt;&gt;groupMetadata.ZOrder" xml:space="preserve">
<value>9</value>
</data>
<data name="clbPerms.Items" xml:space="preserve">
<value>Allow Printing</value>
@ -849,6 +633,30 @@
<data name="&gt;&gt;cbEncryptPdf.ZOrder" xml:space="preserve">
<value>7</value>
</data>
<data name="groupProtection.Location" type="System.Drawing.Point, System.Drawing">
<value>12, 272</value>
</data>
<data name="groupProtection.Size" type="System.Drawing.Size, System.Drawing">
<value>408, 250</value>
</data>
<data name="groupProtection.TabIndex" type="System.Int32, mscorlib">
<value>21</value>
</data>
<data name="groupProtection.Text" xml:space="preserve">
<value>Encryption</value>
</data>
<data name="&gt;&gt;groupProtection.Name" xml:space="preserve">
<value>groupProtection</value>
</data>
<data name="&gt;&gt;groupProtection.Type" xml:space="preserve">
<value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;groupProtection.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;groupProtection.ZOrder" xml:space="preserve">
<value>8</value>
</data>
<data name="cbRememberSettings.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
@ -1129,12 +937,12 @@
<value>ilProfileIcons</value>
</data>
<data name="&gt;&gt;ilProfileIcons.Type" xml:space="preserve">
<value>NAPS2.WinForms.ILProfileIcons, NAPS2.Core, Version=5.7.1.29988, Culture=neutral, PublicKeyToken=null</value>
<value>NAPS2.WinForms.ILProfileIcons, NAPS2.Core, Version=6.0.4.42667, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>FPdfSettings</value>
</data>
<data name="&gt;&gt;$this.Type" xml:space="preserve">
<value>NAPS2.WinForms.FormBase, NAPS2.Core, Version=5.7.1.29988, Culture=neutral, PublicKeyToken=null</value>
<value>NAPS2.WinForms.FormBase, NAPS2.Core, Version=6.0.4.42667, Culture=neutral, PublicKeyToken=null</value>
</data>
</root>