diff --git a/dezentrale-members.csproj b/dezentrale-members.csproj index fe74559..079731b 100644 --- a/dezentrale-members.csproj +++ b/dezentrale-members.csproj @@ -202,13 +202,14 @@ - + + diff --git a/model/Blob.cs b/model/Attachment.cs similarity index 71% rename from model/Blob.cs rename to model/Attachment.cs index d7e5755..da3112a 100644 --- a/model/Blob.cs +++ b/model/Attachment.cs @@ -6,25 +6,29 @@ using ICSharpCode.SharpZipLib.Zip; namespace dezentrale.model { - public class Blob + public class Attachment { - [XmlAttribute] public string FileName { get; set; } = ""; - [XmlAttribute] public DateTime Added { get; set; } = DateTime.Now; - [XmlAttribute] public DateTime Modified { get; set; } - [XmlAttribute] public int Size { get; set; } = 0; + [XmlAttribute] public string FileName { get; set; } = ""; + [XmlAttribute] public DateTime Added { get; set; } = DateTime.Now; + [XmlAttribute] public DateTime Modified { get; set; } + [XmlAttribute] public int Size { get; set; } = 0; [XmlAttribute] public string DataFileName { get; set; } = null; - [XmlIgnore] public string CompletePath - { get { - return System.IO.Path.Combine(Program.config.DbDirectory, DataFileName); - } } + [XmlIgnore] + public string CompletePath + { + get + { + return System.IO.Path.Combine(Program.config.DbDirectory, DataFileName); + } + } - public Blob() : base() { } - public Blob(string fileName) : base() + public Attachment() : base() { } + public Attachment(string fileName) : base() { Added = DateTime.Now; FileName = fileName; } - public Blob(string fileName, byte[] contents) : base() + public Attachment(string fileName, byte[] contents) : base() { Added = DateTime.Now; FileName = fileName; @@ -43,13 +47,14 @@ namespace dezentrale.model Console.WriteLine(theEntry.Name); string fileName = Path.GetFileName(theEntry.Name); - if(fileName == FileName) + if (fileName == FileName) { long size = theEntry.Size; if (size != this.Size) throw new Exception($"Size in file {DataFileName} ({FileName}) differs from expected."); byte[] contents = new byte[size]; - size = s.Read(contents, 0, size); - if(size != Size) throw new Exception($"Size in file {DataFileName} ({FileName}) differs from expected."); + size = s.Read(contents, 0, (int)size); + if (size != Size) throw new Exception($"Size in file {DataFileName} ({FileName}) differs from expected."); + return contents; } } } @@ -60,7 +65,7 @@ namespace dezentrale.model public void SetContents(byte[] contents, bool deleteOldContentFile = true) { Modified = DateTime.Now; - if (DataFileName != null) + if (!string.IsNullOrEmpty(DataFileName)) { //Delete old contents try @@ -69,26 +74,26 @@ namespace dezentrale.model Console.WriteLine($"Old content file {DataFileName} deleted."); DataFileName = null; Size = 0; - } catch(Exception ex) + } + catch (Exception ex) { Console.WriteLine($"Cannot delete file {DataFileName}:"); Console.WriteLine(ex.Message); } - } else + } + else { Console.WriteLine($"Old content file {DataFileName} kept. This is an orphan now."); } if (contents != null) { - //store into file - string completePath = ""; - do { DataFileName = $"{Guid.NewGuid().ToString()}.zip"; } while (File.Exists(CompletePath)); //should never happen but we're checking to be sure. + string completePath = System.IO.Path.Combine(Program.config.DbDirectory, DataFileName); Size = contents.Length; using (ZipOutputStream s = new ZipOutputStream(File.Create(completePath))) diff --git a/model/FormMail.cs b/model/FormMail.cs index 5f4bd07..b5ce4d5 100644 --- a/model/FormMail.cs +++ b/model/FormMail.cs @@ -67,7 +67,7 @@ namespace dezentrale.model message.Body = src.Body; if (files != null) foreach (string f in files) - message.Attachments.Add(new Attachment(f)); + message.Attachments.Add(new System.Net.Mail.Attachment(f)); #pragma warning disable CS0618 //Suppress deprecation warning /* Warning CS0618: 'SmtpClient' is obsolete: 'SmtpClient diff --git a/model/IAttachmentOwner.cs b/model/IAttachmentOwner.cs new file mode 100644 index 0000000..bad8897 --- /dev/null +++ b/model/IAttachmentOwner.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; + +namespace dezentrale.model +{ + public enum eAttachmentAction + { + Added = 0, + Deleted = 1, + NameChange = 2, + ContentsChange = 3 + } + + /** \brief an attachment owner holds a list of attachment metadata objects + * (dezentrale.model.Attachment), and an attachments changed callback + * for notifications that can trigger e.g. a serialization process. + */ + public interface IAttachmentOwner + { + + List Attachments { get; set; } + void AttachmentChanged(Attachment attachment, eAttachmentAction action); + } +} diff --git a/model/Mv.cs b/model/Mv.cs index 799ac50..41e6876 100644 --- a/model/Mv.cs +++ b/model/Mv.cs @@ -43,7 +43,7 @@ namespace dezentrale.model } } - public class Mv : XmlLog + public class Mv : XmlLog, IAttachmentOwner { public enum MvStatus { @@ -76,7 +76,7 @@ namespace dezentrale.model [XmlElement] public List Members { get; set; } = new List(); [XmlElement] public string Protocol { get { return protocol; } set { LogPropertyChange("Protocol", protocol, value); protocol = value; } } - [XmlElement] public List Attachments { get; set; } = new List(); + [XmlElement("Attachments")] public List Attachments { get; set; } = new List(); [XmlIgnore] public string AgendaNumberedString { @@ -203,5 +203,10 @@ namespace dezentrale.model if(m != null) fm = fm.ReplaceReflect(m); return fm; } + + public void AttachmentChanged(Attachment attachment, eAttachmentAction action) + { + + } } } diff --git a/model/XmlLog.cs b/model/XmlLog.cs index bfadc95..995b445 100644 --- a/model/XmlLog.cs +++ b/model/XmlLog.cs @@ -25,6 +25,7 @@ namespace dezentrale.model Log.Add(CurrentLog); return CurrentLog; } + protected void LogPropertyChange(string propertyName, object oldValue, object newValue) { if (XmlLog.SuppressAllLogging || SuppressLogging) return; diff --git a/view/LvAttachments.cs b/view/LvAttachments.cs index a7f6627..9eb6445 100644 --- a/view/LvAttachments.cs +++ b/view/LvAttachments.cs @@ -7,7 +7,7 @@ using dezentrale.model; namespace dezentrale.view { - public class LvAttachments : CustomListView + public class LvAttachments : CustomListView { protected override List DefaultColumns { @@ -19,21 +19,73 @@ namespace dezentrale.view { Name = "fileName", Display = "FileName", - Width = 40, - CustomToString = x => ((MvInvitedMember)x).NumberString, + Width = 80, + CustomToString = x => ((Attachment)x).FileName, }, new ConfigLVDataHandler() { Name = "added", Display = "Added", Width = 88, - CustomToString = ( x => (((MvInvitedMember)x).InvitationDate.Year > 1 ? ((MvInvitedMember)x).InvitationDate.ToString() : "-") ), + CustomToString = ( x => (((Attachment)x).Added.Year > 1 ? ((Attachment)x).Added.ToString() : "-") ), }, }; } } - public LvAttachments() : base(Program.config.AttachmentsColumns, LvAttachments_ColumnsChanged) { } + private IAttachmentOwner owner; + public LvAttachments(IAttachmentOwner owner) : base(Program.config.AttachmentsColumns, LvAttachments_ColumnsChanged) + { + this.owner = owner; + LoadFromList(owner.Attachments); + + AddMenuItem("Add file...", (sender, e) => + { + OpenFileDialog ofd = new OpenFileDialog(); + DialogResult dr = ofd.ShowDialog(); + if(dr == DialogResult.OK) + { + try + { + byte[] data = System.IO.File.ReadAllBytes(ofd.FileName); + + Attachment a = new Attachment(System.IO.Path.GetFileName(ofd.FileName), data); + owner.Attachments.Add(a); + owner.AttachmentChanged(a, eAttachmentAction.Added); + AddEntry(a); + } catch(Exception ex) + { + MessageBox.Show($"Error:\r\n{ex.Message}"); + } + } + }); + AddMenuItem("Save file as...", (sender, e) => + { + List save = GetSelectedItems(); + if(save.Count < 1) + { + MessageBox.Show("No file selected."); + return; + } + SaveFileDialog sfd = new SaveFileDialog(); + sfd.FileName = save[0].FileName; + DialogResult dr = sfd.ShowDialog(); + if(dr == DialogResult.OK) + { + try + { + byte[] data = save[0].GetContents(); + System.IO.File.WriteAllBytes(sfd.FileName, data); + } catch(Exception ex) + { + MessageBox.Show($"Error:\r\n{ex.Message}"); + } + } + }); + AddMenuItem("Delete file(s)", (sender, e) => + { + }); + } private static void LvAttachments_ColumnsChanged(object sender, ColumnsChangedArgs e) { diff --git a/view/LvMvInvitations.cs b/view/LvMvInvitations.cs index 8cd1a9e..1651c01 100644 --- a/view/LvMvInvitations.cs +++ b/view/LvMvInvitations.cs @@ -54,7 +54,10 @@ namespace dezentrale.view } } - public LvMvInvitations() : base(Program.config.MvInvitationsListColumns, LvMvInvitations_ColumnsChanged) { } + public LvMvInvitations() : base(Program.config.MvInvitationsListColumns, LvMvInvitations_ColumnsChanged) + { + //TODO: add menu entries for adding/removing/editing attachments + } private static void LvMvInvitations_ColumnsChanged(object sender, ColumnsChangedArgs e) {