diff --git a/Tomboy.sln b/Tomboy.sln
index d9a1be53..6a32dbf0 100644
--- a/Tomboy.sln
+++ b/Tomboy.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25420.1
+# Visual Studio 15
+VisualStudioVersion = 15.0.26403.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tomboy", "Tomboy.csproj", "{315DBB30-1461-4A41-A23F-A888D84E1EA0}"
EndProject
@@ -25,7 +25,9 @@ Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Setup", "Setup\Setup.wixpro
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PrintNotes", "Tomboy\Addins\PrintNotes\PrintNotes.csproj", "{A13FBE2F-C5FF-4E8D-B687-4A309D3FE08F}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Underline", "Tomboy\Addins\Underline\Underline.csproj", "{15A0F2C4-9BAD-11DE-B022-C19356D89593}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Underline", "Tomboy\Addins\Underline\Underline.csproj", "{15A0F2C4-C5FF-11CF-B022-C19356D89593}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PassEncrypt", "Tomboy\Addins\PassEncrypt\PassEncrypt.csproj", "{15AC9F12-9BAD-11DE-B022-C97A56D78593}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebSyncService", "Tomboy\Addins\WebSyncService\WebSyncService.csproj", "{A207AD10-9C5E-495F-9DEF-E7321A6FCB8F}"
EndProject
@@ -104,12 +106,18 @@ Global
{A13FBE2F-C5FF-4E8D-B687-4A309D3FE08F}.Mac|Any CPU.Build.0 = Mac|Any CPU
{A13FBE2F-C5FF-4E8D-B687-4A309D3FE08F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A13FBE2F-C5FF-4E8D-B687-4A309D3FE08F}.Release|Any CPU.Build.0 = Release|Any CPU
- {15A0F2C4-9BAD-11DE-B022-C19356D89593}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {15A0F2C4-9BAD-11DE-B022-C19356D89593}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {15A0F2C4-9BAD-11DE-B022-C19356D89593}.Mac|Any CPU.ActiveCfg = Mac|Any CPU
- {15A0F2C4-9BAD-11DE-B022-C19356D89593}.Mac|Any CPU.Build.0 = Mac|Any CPU
- {15A0F2C4-9BAD-11DE-B022-C19356D89593}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {15A0F2C4-9BAD-11DE-B022-C19356D89593}.Release|Any CPU.Build.0 = Release|Any CPU
+ {15A0F2C4-C5FF-11CF-B022-C19356D89593}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {15A0F2C4-C5FF-11CF-B022-C19356D89593}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {15A0F2C4-C5FF-11CF-B022-C19356D89593}.Mac|Any CPU.ActiveCfg = Mac|Any CPU
+ {15A0F2C4-C5FF-11CF-B022-C19356D89593}.Mac|Any CPU.Build.0 = Mac|Any CPU
+ {15A0F2C4-C5FF-11CF-B022-C19356D89593}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {15A0F2C4-C5FF-11CF-B022-C19356D89593}.Release|Any CPU.Build.0 = Release|Any CPU
+ {15AC9F12-9BAD-11DE-B022-C97A56D78593}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {15AC9F12-9BAD-11DE-B022-C97A56D78593}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {15AC9F12-9BAD-11DE-B022-C97A56D78593}.Mac|Any CPU.ActiveCfg = Mac|Any CPU
+ {15AC9F12-9BAD-11DE-B022-C97A56D78593}.Mac|Any CPU.Build.0 = Mac|Any CPU
+ {15AC9F12-9BAD-11DE-B022-C97A56D78593}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {15AC9F12-9BAD-11DE-B022-C97A56D78593}.Release|Any CPU.Build.0 = Release|Any CPU
{A207AD10-9C5E-495F-9DEF-E7321A6FCB8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A207AD10-9C5E-495F-9DEF-E7321A6FCB8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A207AD10-9C5E-495F-9DEF-E7321A6FCB8F}.Mac|Any CPU.ActiveCfg = Mac|Any CPU
diff --git a/Tomboy/Addins/PassEncrypt/Encrypter.cs b/Tomboy/Addins/PassEncrypt/Encrypter.cs
new file mode 100644
index 00000000..08d4e4f2
--- /dev/null
+++ b/Tomboy/Addins/PassEncrypt/Encrypter.cs
@@ -0,0 +1,112 @@
+//According to https://stackoverflow.com/questions/10168240/encrypting-decrypting-a-string-in-c-sharp CraigTP answer.
+using System;
+using System.Text;
+using System.Security.Cryptography;
+using System.IO;
+using System.Linq;
+
+namespace Tomboy.PassEncrypt
+{
+ public static class Encrypter
+ {
+ // This constant is used to determine the keysize of the encryption algorithm in bits.
+ // We divide this by 8 within the code below to get the equivalent number of bytes.
+ private const int Keysize = 256;
+
+ // This constant determines the number of iterations for the password bytes generation function.
+ private const int DerivationIterations = 1000;
+
+ public static string Encrypt(string plainText, string passPhrase)
+ {
+ // Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
+ // so that the same Salt and IV values can be used when decrypting.
+ var saltStringBytes = Generate256BitsOfRandomEntropy();
+ var ivStringBytes = Generate256BitsOfRandomEntropy();
+ var plainTextBytes = Encoding.Unicode.GetBytes(plainText);
+ using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
+ {
+ var keyBytes = password.GetBytes(Keysize / 8);
+ using (var symmetricKey = new RijndaelManaged())
+ {
+ symmetricKey.BlockSize = 256;
+ symmetricKey.Mode = CipherMode.CBC;
+ symmetricKey.Padding = PaddingMode.PKCS7;
+ using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
+ {
+ using (var memoryStream = new MemoryStream())
+ {
+ using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
+ {
+ cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
+ cryptoStream.FlushFinalBlock();
+ // Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
+ var cipherTextBytes = saltStringBytes;
+ cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
+ cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
+ memoryStream.Close();
+ cryptoStream.Close();
+ return Convert.ToBase64String(cipherTextBytes);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public static string Decrypt(string cipherText, string passPhrase)
+ {
+ try
+ {
+ // Get the complete stream of bytes that represent:
+ // [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
+ var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
+ // Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
+ var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
+ // Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
+ var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
+ // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
+ var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
+
+ using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
+ {
+ var keyBytes = password.GetBytes(Keysize / 8);
+ using (var symmetricKey = new RijndaelManaged())
+ {
+ symmetricKey.BlockSize = 256;
+ symmetricKey.Mode = CipherMode.CBC;
+ symmetricKey.Padding = PaddingMode.PKCS7;
+ using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
+ {
+ using (var memoryStream = new MemoryStream(cipherTextBytes))
+ {
+ using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
+ {
+ var plainTextBytes = new byte[cipherTextBytes.Length];
+ var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
+ memoryStream.Close();
+ cryptoStream.Close();
+ return Encoding.Unicode.GetString(plainTextBytes, 0, decryptedByteCount);
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (CryptographicException)
+ {
+ return Encrypt(cipherText, passPhrase);
+ }
+ }
+
+ private static byte[] Generate256BitsOfRandomEntropy()
+ {
+ var randomBytes = new byte[32]; // 32 Bytes will give us 256 bits.
+ using (var rngCsp = new RNGCryptoServiceProvider())
+ {
+ // Fill the array with cryptographically secure random bytes.
+ rngCsp.GetBytes(randomBytes);
+ }
+ return randomBytes;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Tomboy/Addins/PassEncrypt/Makefile.am b/Tomboy/Addins/PassEncrypt/Makefile.am
new file mode 100644
index 00000000..801979d5
--- /dev/null
+++ b/Tomboy/Addins/PassEncrypt/Makefile.am
@@ -0,0 +1,41 @@
+include $(top_srcdir)/Makefile.include
+
+CSFLAGS = \
+ -debug \
+ -define:DEBUG \
+ -target:library
+
+ASSEMBLIES = \
+ $(LINK_TOMBOY_EXE) \
+ $(GTKSHARP_LIBS) \
+ $(LINK_MONO_ADDINS) \
+ -r:Mono.Posix
+
+ADDIN_NAME = PassEncrypt
+TARGET = $(top_builddir)/bin/addins/$(ADDIN_NAME).dll
+CSFILES = \
+ $(srcdir)/PassEncryptMenuItem.cs \
+ $(srcdir)/PassEncryptNoteAddin.cs \
+ $(srcdir)/PassEncryptTag.cs
+RESOURCES = \
+ -resource:$(srcdir)/$(ADDIN_NAME).addin.xml
+
+$(TARGET).mdb: $(TARGET)
+
+$(TARGET): $(CSFILES) $(TOMBOY_EXE_PATH)
+ mkdir -p `dirname $(TARGET)` && $(CSC) -out:$@ $(CSFLAGS) $(ASSEMBLIES) $(CSFILES) $(RESOURCES)
+
+
+addinsdir = $(pkglibdir)/addins
+addins_DATA = \
+ $(TARGET) \
+ $(TARGET).mdb
+
+EXTRA_DIST = \
+ $(CSFILES) \
+ $(srcdir)/$(ADDIN_NAME).addin.xml
+
+CLEANFILES = \
+ $(TARGET).mdb \
+ $(TARGET)
+
diff --git a/Tomboy/Addins/PassEncrypt/PassEncrypt-mac.csproj b/Tomboy/Addins/PassEncrypt/PassEncrypt-mac.csproj
new file mode 100644
index 00000000..24640ef4
--- /dev/null
+++ b/Tomboy/Addins/PassEncrypt/PassEncrypt-mac.csproj
@@ -0,0 +1,95 @@
+
+
+
+ Debug
+ AnyCPU
+ {15A0F2C4-9BAD-11DE-B022-C19356D89593}
+ 9.0.21022
+ 2.0
+ Library
+ false
+ PassEncrypt
+ v3.5
+ 512
+ PassEncrypt
+ OnBuildSuccess
+ False
+ False
+ false
+
+
+ true
+ full
+ false
+ ..\..\..\bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ False
+
+
+ False
+ Auto
+ 4194304
+ AnyCPU
+
+
+
+ False
+ ..\..\..\..\..\..\..\Library\Frameworks\Mono.framework\Versions\Current\lib\mono\gac\gtk-sharp\2.12.0.0__35e10195dab3c99f\gtk-sharp.dll
+ False
+
+
+ False
+ ..\..\..\..\..\..\..\Library\Frameworks\Mono.framework\Versions\Current\lib\mono\gac\glib-sharp\2.12.0.0__35e10195dab3c99f\glib-sharp.dll
+ False
+
+
+ False
+ ..\..\..\..\..\..\..\Library\Frameworks\Mono.framework\Versions\Current\lib\mono\gac\gdk-sharp\2.12.0.0__35e10195dab3c99f\gdk-sharp.dll
+ False
+
+
+ False
+ ..\..\..\..\..\..\..\Library\Frameworks\Mono.framework\Versions\Current\lib\mono\gac\atk-sharp\2.12.0.0__35e10195dab3c99f\atk-sharp.dll
+ False
+
+
+ False
+ ..\..\..\..\..\..\..\Library\Frameworks\Mono.framework\Versions\Current\lib\mono\gac\pango-sharp\2.12.0.0__35e10195dab3c99f\pango-sharp.dll
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {315DBB30-1461-4A41-A23F-A888D84E1EA0}
+ Tomboy-mac
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Tomboy/Addins/PassEncrypt/PassEncrypt.addin.xml b/Tomboy/Addins/PassEncrypt/PassEncrypt.addin.xml
new file mode 100644
index 00000000..11ff03ae
--- /dev/null
+++ b/Tomboy/Addins/PassEncrypt/PassEncrypt.addin.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tomboy/Addins/PassEncrypt/PassEncrypt.csproj b/Tomboy/Addins/PassEncrypt/PassEncrypt.csproj
new file mode 100644
index 00000000..71ef6815
--- /dev/null
+++ b/Tomboy/Addins/PassEncrypt/PassEncrypt.csproj
@@ -0,0 +1,138 @@
+
+
+
+ Debug
+ AnyCPU
+ {15AC9F12-9BAD-11DE-B022-C97A56D78593}
+ 9.0.21022
+ 2.0
+ Library
+ false
+ PassEncrypt
+ 512
+ PassEncrypt
+ OnBuildSuccess
+ False
+ False
+ false
+
+
+ 3.5
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+ v4.5
+
+
+
+ true
+ full
+ false
+ ..\..\..\bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ AnyCPU
+ False
+ Auto
+ 4194304
+ false
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ False
+ Auto
+ 4194304
+ AnyCPU
+ false
+
+
+ False
+
+
+ False
+ Auto
+ 4194304
+ AnyCPU
+
+
+ true
+ bin\Mac\
+ DEBUG;TRACE
+ full
+ prompt
+ 4
+ false
+ false
+
+
+
+
+
+
+
+
+
+ ..\..\..\winbin\Mono.Posix.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {315DBB30-1461-4A41-A23F-A888D84E1EA0}
+ Tomboy
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Tomboy/Addins/PassEncrypt/PassEncryptMenuItem.cs b/Tomboy/Addins/PassEncrypt/PassEncryptMenuItem.cs
new file mode 100644
index 00000000..1a38aed6
--- /dev/null
+++ b/Tomboy/Addins/PassEncrypt/PassEncryptMenuItem.cs
@@ -0,0 +1,82 @@
+
+// (C) 2018 Piotr Wiœniowski , LGPL 2.1 or later.
+using System;
+using Gtk;
+using Mono.Unix;
+
+namespace Tomboy.PassEncrypt
+{
+ class PassEncryptMenuItem : CheckMenuItem
+ {
+ NoteAddin Addin;
+ bool event_freeze;
+
+ public PassEncryptMenuItem (NoteAddin addin) : base ( Catalog.GetString ("_PassEncrypt"))
+ {
+ ((Label) Child).UseMarkup = true;
+
+ Addin = addin;
+ Addin.Window.TextMenu.Shown += MenuShown;
+ AddAccelerator ("activate", Addin.Window.AccelGroup,
+ (uint) Gdk.Key.e, Gdk.ModifierType.ControlMask,
+ Gtk.AccelFlags.Visible);
+
+ ShowAll();
+ }
+
+ protected void MenuShown (object sender, EventArgs e)
+ {
+ event_freeze = true;
+ Active = Addin.Buffer.IsActiveTag ("encpass");
+ event_freeze = false;
+ }
+
+ protected async override void OnActivated ()
+ {
+
+ string tagName = PassEncryptTag.TagName;
+ if (!event_freeze && Addin.Buffer.HasSelection && !Addin.Buffer.IsActiveTag(tagName))
+ {
+ string selection = Addin.Buffer.Selection.Trim();
+ TextIter start, end;
+ Addin.Note.Buffer.GetSelectionBounds(out start, out end);
+ if (string.IsNullOrWhiteSpace(selection))
+ return;
+
+ PasswordWindow passwordWindow = new PasswordWindow(true);
+ passwordWindow.ShowAll();
+ string passPhrase = await passwordWindow.GetPassword();
+ if (string.IsNullOrWhiteSpace(passPhrase))
+ return;
+ string encPassword = Encrypter.Encrypt(selection, passPhrase);
+ PassEncryptTag encPassTag = (PassEncryptTag) Addin.Note.TagTable.CreateDynamicTag(PassEncryptTag.TagName);
+ encPassTag.SetPassword(encPassword);
+ Gtk.TextTag[] tags = { encPassTag };
+ Addin.Note.Buffer.DeleteInteractive(ref start, ref end, true);
+ Addin.Note.Buffer.InsertWithTags(ref start, Catalog.GetString(" -Encoded Password- "), tags);
+ //PassEncryptTag encPassTag = new PassEncryptTag(encPassword);
+ //encPassTag.Initialize(PassEncryptTag.TagName);
+ //if (Addin.Note.TagTable.Lookup(encPassTag.ElementName) != null)
+ //{
+ // // error same passwort hashcode
+ // PasswordWindow showException= new PasswordWindow(false);
+ // showException.ShowAll();
+ // showException.ShowNonEditableText(Catalog.GetString(" Error - same password Id detected: " + encPassTag.Name));
+ // return;
+ //}
+ //Addin.Note.TagTable.Add(encPassTag);
+ //Addin.Note.Buffer.DeleteInteractive(ref start, ref end, true);
+ //Addin.Note.Buffer.InsertInteractive(ref start, Catalog.GetString(" -Encoded Password- "), true);
+ //Addin.Note.Buffer.InsertWithTagsByName(ref start, Catalog.GetString(" -Encoded Password- "), encPassTag.ElementName);
+ }
+ }
+
+ protected override void OnDestroyed ()
+ {
+ if (Addin.HasWindow)
+ Addin.Window.TextMenu.Shown -= MenuShown;
+
+ base.OnDestroyed();
+ }
+ }
+}
diff --git a/Tomboy/Addins/PassEncrypt/PassEncryptNoteAddin.cs b/Tomboy/Addins/PassEncrypt/PassEncryptNoteAddin.cs
new file mode 100644
index 00000000..482a146b
--- /dev/null
+++ b/Tomboy/Addins/PassEncrypt/PassEncryptNoteAddin.cs
@@ -0,0 +1,37 @@
+// Add an PassEncrypt item to the font styles menu. Just select text and press ctrl+e.
+// (C) 2018 Piotr Wiœniowski , LGPL 2.1 or later.
+
+using Mono.Unix;
+using System;
+using Gtk;
+using Tomboy;
+
+namespace Tomboy.PassEncrypt
+{
+ public class PassEncryptNoteAddin : NoteAddin
+ {
+
+ public override void Initialize ()
+ {
+ if (!Note.TagTable.IsDynamicTagRegistered(PassEncryptTag.TagName))
+ {
+ Note.TagTable.RegisterDynamicTag(PassEncryptTag.TagName, typeof(PassEncryptTag));
+ }
+ //Note.TagTable.RegisterDynamicTag(PassEncryptTag.TagName, typeof(PassEncryptTag));
+ }
+
+ public override void Shutdown ()
+ {
+ }
+
+ public override void OnNoteOpened ()
+ {
+ // Add here instead of in Initialize to avoid creating unopened
+ // notes' windows/buffers.
+ AddTextMenuItem (new PassEncryptMenuItem (this));
+ // get all note xml and search for passencrypt tags
+ string xml = Note.TextContent;
+
+ }
+ }
+}
diff --git a/Tomboy/Addins/PassEncrypt/PassEncryptTag.cs b/Tomboy/Addins/PassEncrypt/PassEncryptTag.cs
new file mode 100644
index 00000000..51c76c75
--- /dev/null
+++ b/Tomboy/Addins/PassEncrypt/PassEncryptTag.cs
@@ -0,0 +1,92 @@
+
+// (C) 2018 Piotr Wiœniowski , LGPL 2.1 or later.
+using Gtk;
+using System;
+using System.Xml;
+using Tomboy;
+
+namespace Tomboy.PassEncrypt
+{
+ class PassEncryptTag : DynamicNoteTag
+ {
+ public static string TagName = "encpass";
+ protected static string AtrName = "password";
+
+ public PassEncryptTag () //(TagName + encryptedPass.GetHashCode().ToString())
+ {
+ //Initialize(encryptedPass);
+ //this.Attributes.Add(AtrName, EncryptedPass);
+ }
+
+ public override void Initialize(string element_name)
+ {
+ base.Initialize(element_name);
+ this.Editable = false;
+ this.CanSplit = false;
+ this.CanSpellCheck = false;
+ this.CanGrow = false;
+ this.CanActivate = true;
+ this.Activated += PassEncryptTag_Activated;
+ this.SaveType = TagSaveType.Content;
+ }
+ public void SetPassword(string encryptedPass)
+ {
+ //EncryptedPass = encryptedPass;
+ this.Attributes.Add(AtrName, encryptedPass);
+ }
+
+ //public string EncryptedPass { get; private set; }
+
+ protected bool PassEncryptTag_Activated(NoteTag tag, NoteEditor editor, Gtk.TextIter start, Gtk.TextIter end)
+ {
+ string encPass = (tag as PassEncryptTag).Attributes[AtrName];
+ // .Ens editor.Buffer.GetText(start, end, false);
+ if (string.IsNullOrWhiteSpace(encPass))
+ return false;
+ DecryptPassAsync(encPass);
+ return true;
+ }
+ protected async void DecryptPassAsync(string encPass)
+ {
+ PasswordWindow passwordWindow = new PasswordWindow(false);
+ passwordWindow.ShowAll();
+ string passPhrase = await passwordWindow.GetPassword();
+ if (string.IsNullOrEmpty(passPhrase))
+ return;
+
+ string decrypted = Encrypter.Decrypt(encPass, passPhrase);
+ passwordWindow.ShowNonEditableText(decrypted);
+ }
+
+ //// XmlTextWriter is required, because an XmlWriter created with
+ //// XmlWriter.Create considers ":" to be an invalid character
+ //// for an element name.
+ //// http://bugzilla.gnome.org/show_bug.cgi?id=559094
+ //public override void Write(XmlTextWriter xml, bool start)
+ //{
+ // if (CanSerialize && !string.IsNullOrWhiteSpace(EncryptedPass))
+ // {
+ // if (start)
+ // {
+ // xml.WriteStartElement(null, ElementName, null);
+ // xml.WriteAttributeString(AtrName, EncryptedPass);
+ // }
+ // else
+ // {
+ // xml.WriteEndElement();
+ // }
+ // }
+ //}
+ //public override void Read(XmlTextReader xml, bool start)
+ //{
+ // if (CanSerialize)
+ // {
+ // if (start)
+ // {
+ // EncryptedPass = xml.GetAttribute(TagName);
+ // }
+ // }
+ // base.Read(xml, start);
+ //}
+ }
+}
diff --git a/Tomboy/Addins/PassEncrypt/PasswordWindow.cs b/Tomboy/Addins/PassEncrypt/PasswordWindow.cs
new file mode 100644
index 00000000..d21ca8ab
--- /dev/null
+++ b/Tomboy/Addins/PassEncrypt/PasswordWindow.cs
@@ -0,0 +1,109 @@
+
+// (C) 2018 Piotr Wiśniowski , LGPL 2.1 or later.
+using Gtk;
+using Mono.Unix;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Tomboy.PassEncrypt
+{
+ class PasswordWindow : Window
+ {
+ public Entry firstEntry = new Entry();
+ public Entry secondEntry = new Entry();
+ VBox vbox = new VBox();
+ public TaskCompletionSource EnteredPass = new TaskCompletionSource();
+ private bool WithConfirmation = true;
+
+ public PasswordWindow(bool withConfirmation) : base(WindowType.Toplevel)
+ {
+ WithConfirmation = withConfirmation;
+ firstEntry.GrabFocus();
+ firstEntry.Text = Catalog.GetString("Please enter password");
+ firstEntry.Changed += Entry_Changed;
+ firstEntry.Activated += Entry_Activated;
+ vbox.PackStart(firstEntry, false, true, 2);
+
+ if (withConfirmation)
+ {
+ secondEntry.Text = Catalog.GetString("Reenter password");
+ secondEntry.Changed += Entry_Changed;
+ secondEntry.Activated += Entry_Activated;
+ }
+ else
+ {
+ secondEntry.Text = Catalog.GetString("Decoded text");
+ secondEntry.Visibility = true;
+ secondEntry.IsEditable = false;
+ }
+ vbox.PackStart(secondEntry, false, true, 2);
+
+ this.Add(vbox);
+ this.Title = Catalog.GetString("Enter Password");
+ this.SetPosition(WindowPosition.Mouse);
+ this.FocusOutEvent += PasswordWindow_FocusOutEvent;
+ }
+
+ private void PasswordWindow_FocusOutEvent(object o, FocusOutEventArgs args)
+ {
+ EnteredPass.TrySetResult(string.Empty);
+ this.Destroy();
+ }
+
+ private void Entry_Changed(object sender, EventArgs e)
+ {
+ firstEntry.Changed -= Entry_Changed;
+ firstEntry.Text = string.Empty;
+ firstEntry.Visibility = false;
+
+ secondEntry.Changed -= Entry_Changed;
+ secondEntry.Text = string.Empty;
+ secondEntry.Visibility = false;
+ }
+
+ private void Entry_Activated(object sender, EventArgs e)
+ {
+ if (string.IsNullOrWhiteSpace(firstEntry.Text))
+ {
+ firstEntry.GrabFocus();
+ return;
+ }
+ if (WithConfirmation && (string.IsNullOrWhiteSpace(secondEntry.Text) || secondEntry.Text.Trim() != firstEntry.Text.Trim()))
+ {
+ secondEntry.GrabFocus();
+ return;
+ }
+ else
+ {
+ firstEntry.IsEditable = false;
+ secondEntry.IsEditable = false;
+
+ firstEntry.Activated -= Entry_Activated;
+ secondEntry.Activated -= Entry_Activated;
+
+ EnteredPass.SetResult(firstEntry.Text.Trim());
+
+ if (WithConfirmation)
+ this.Destroy();
+ return;
+ }
+ }
+
+ public void ShowNonEditableText(string text)
+ {
+ secondEntry.Text = text;
+ secondEntry.Visibility = true;
+ secondEntry.IsEditable = false;
+ secondEntry.GetClipboard(Gdk.Selection.Clipboard).Text = text;
+ }
+
+ public async Task GetPassword()
+ {
+ return await this.EnteredPass.Task;
+ }
+ }
+}
diff --git a/Tomboy/Addins/Underline/Underline.csproj b/Tomboy/Addins/Underline/Underline.csproj
index d7a22da6..3cde3baa 100644
--- a/Tomboy/Addins/Underline/Underline.csproj
+++ b/Tomboy/Addins/Underline/Underline.csproj
@@ -3,7 +3,7 @@
Debug
AnyCPU
- {15A0F2C4-9BAD-11DE-B022-C19356D89593}
+ {15A0F2C4-C5FF-11CF-B022-C19356D89593}
9.0.21022
2.0
Library
diff --git a/UpgradeLog.htm b/UpgradeLog.htm
new file mode 100644
index 00000000..33eaa06f
Binary files /dev/null and b/UpgradeLog.htm differ
diff --git a/UpgradeLog2.htm b/UpgradeLog2.htm
new file mode 100644
index 00000000..33eaa06f
Binary files /dev/null and b/UpgradeLog2.htm differ