[blam: 2/4] Channel: implement INotifyPropertyChanged



commit 4a82bf8531f4ac1a610df559a03d5501eb181901
Author: Carlos Martín Nieto <cmn dwim me>
Date:   Mon Jun 17 17:57:59 2013 +0200

    Channel: implement INotifyPropertyChanged
    
    This will hopefully lead to more fine-grained update notifications and
    less signaling spaghetti.

 src/Application.cs       |    2 -
 src/Channel.cs           |  114 ++++++++++++++++++++++++++-------------------
 src/ChannelCollection.cs |   24 ++++++---
 src/ChannelDialog.cs     |    1 -
 src/ChannelGroup.cs      |   20 +++++++-
 src/ChannelList.cs       |   23 +++++----
 6 files changed, 113 insertions(+), 71 deletions(-)
---
diff --git a/src/Application.cs b/src/Application.cs
index 05d22e8..1db2dd7 100644
--- a/src/Application.cs
+++ b/src/Application.cs
@@ -713,7 +713,6 @@ namespace Imendio.Blam {
 
         private void ChannelUpdatedCb (IChannel channel)
         {
-            channelList.Updated (channel);
             UpdateTotalNumberOfUnread ();
         }
 
@@ -738,7 +737,6 @@ namespace Imendio.Blam {
             uint contextId = statusbar.GetContextId("update-status");
 
             statusbar.Pop (contextId);
-            channelList.Updated (channel);
             UpdateTotalNumberOfUnread ();
 
             if (channelList.GetSelected () == channel) {
diff --git a/src/Channel.cs b/src/Channel.cs
index 6a4446b..0b4cb5b 100644
--- a/src/Channel.cs
+++ b/src/Channel.cs
@@ -16,6 +16,7 @@ using System.Threading.Tasks;
 using System.ComponentModel;
 using System.ServiceModel.Syndication;
 using System.Security.Cryptography.X509Certificates;
+using System.Runtime.CompilerServices;
 
 namespace Imendio.Blam {
 
@@ -30,15 +31,12 @@ namespace Imendio.Blam {
         bool MarkAsRead();
         Item GetItem(string id);
         void Setup();
-        event ChannelEventHandler Updated;
+        event PropertyChangedEventHandler PropertyChanged;
         void RemoveItems();
                Task<bool> RefreshAsync();
     }
 
-    public class Channel : IChannel {
-               [XmlAttribute("Name")] public string Int_Name = "";
-               [XmlAttribute("Url")] public string Int_Url = "";
-
+    public class Channel : IChannel, INotifyPropertyChanged {
                // Used when updating the feed
                [XmlAttribute] public string LastModified = "";
                [XmlAttribute] public string ETag = "";
@@ -54,27 +52,37 @@ namespace Imendio.Blam {
         ArrayList item_list = null;
         Object obj = new Object();
 
-        public event ChannelEventHandler Updated;
+               public event PropertyChangedEventHandler PropertyChanged;
 
-        private Gtk.TreeIter mIter;
+               string name;
+               [XmlAttribute]
+               public string Name {
+                       get {
+                               return name;
+                       }
+                       set {
+                               if (name != value) {
+                                       name = value;
+                                       NotifyPropertyChanged();
+                               }
+                       }
+               }
 
-        public string Name {
-            get {
-                return Int_Name;
-            }
-            set {
-                Int_Name = value;
-            }
-        }
+               string url;
+               [XmlAttribute]
+               public string Url {
+                       get {
+                               return url;
+                       }
+                       set {
+                               if (url != value) {
+                                       url = value;
+                                       NotifyPropertyChanged();
+                               }
+                       }
+               }
 
-        public string Url {
-            get {
-                return Int_Url;
-            }
-            set {
-                Int_Url = value;
-            }
-        }
+        private Gtk.TreeIter mIter;
 
                public int NrOfItems {
                        get {
@@ -138,6 +146,13 @@ namespace Imendio.Blam {
             }
         }
 
+               void NotifyPropertyChanged([CallerMemberName] string name = "")
+               {
+                       if (PropertyChanged != null) {
+                               PropertyChanged(this, new PropertyChangedEventArgs(name));
+                       }
+               }
+
                [XmlIgnore]
         public Gtk.TreeIter Iter {
             get {
@@ -198,33 +213,28 @@ namespace Imendio.Blam {
                public bool MarkAsRead ()
                {
                        bool updated = false;
-            Item item;
+                       Item item;
+
+                       lock (obj) {
+                               foreach (string id in item_list) {
+                                       if (id == null) {
+                                               System.Console.WriteLine("null id {0} on {1}", id, Url);
+                                               continue;
+                                       }
+                                       item = store.Get(id);
+                                       if (item.Unread) {
+                                               item.Unread = false;
+                                               updated = true;
+                                       }
+                               }
+                       }
 
-            lock(obj){
-                foreach(string id in item_list){
-                    if(id == null){
-                        System.Console.WriteLine("null id {0} on {1}", id, Url);
-                        continue;
-                    }
-                    item = store.Get(id);
-                    if (item.Unread) {
-                        item.Unread = false;
-                        updated = true;
-                        EmitUpdated();
-                    }
-                }
-            }
+                       if (updated)
+                               NotifyPropertyChanged("NrOfUnreadItems");
 
                        return updated;
                }
 
-        public void EmitUpdated()
-        {
-            if(Updated != null){
-                Updated(this);
-            }
-        }
-
         /**
          * Update this channel with the given feed
          */
@@ -254,14 +264,22 @@ namespace Imendio.Blam {
                                        store.Remove(id);
 
                                item_list = new ArrayList(ids.ToArray());
-
-                               return true;
                        }
+
+                       NotifyPropertyChanged("NrOfUnreadItems");
+                       return true;
                }
 
                void ItemChanged(object sender, PropertyChangedEventArgs args)
                {
-                       EmitUpdated();
+                       switch (args.PropertyName) {
+                               case "Unread":
+                                       NotifyPropertyChanged("NrOfUnreadItems");
+                                       break;
+                               default:
+                                       throw new InvalidOperationException("Item changed in unexpected way. 
Shouldn't happen");
+                                       break;
+                       }
                }
 
         /**
diff --git a/src/ChannelCollection.cs b/src/ChannelCollection.cs
index 0d0eb28..a78a6b3 100644
--- a/src/ChannelCollection.cs
+++ b/src/ChannelCollection.cs
@@ -14,6 +14,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Xml;
 using System.Xml.Serialization;
+using System.ComponentModel;
 
 namespace Imendio.Blam {
 
@@ -104,15 +105,12 @@ namespace Imendio.Blam {
            }
 
            collection.FileName = file;
-            /*
-             * FIXME: Each chan should listen to each of its items
-             */
             foreach(ChannelGroup chan in collection.Groups){
-                chan.Updated += collection.Updated;
+                chan.PropertyChanged += collection.ChannelChanged;
                 chan.Setup();
             }
             foreach(Channel chan in collection.mChannels){
-                chan.Updated += collection.Updated;
+                               chan.PropertyChanged += collection.ChannelChanged;
                 chan.Setup();
             }
 
@@ -189,16 +187,26 @@ namespace Imendio.Blam {
         {
             group.Add(channel);
                        bool updated = await channel.RefreshAsync();
-                       channel.Updated += Updated;
+                       channel.PropertyChanged += ChannelChanged;
 
                        if(ChannelGroupAdded != null){
                                ChannelGroupAdded(group, channel);
                        }
 
                        MarkAsDirty();
-        }
+               }
+
+               void ChannelChanged(object sender, PropertyChangedEventArgs args)
+               {
+                       IChannel channel = (IChannel)sender;
+                       MarkAsDirty();
+
+                       if (ChannelUpdated != null) {
+                               ChannelUpdated (channel);
+                       }
+               }
 
-       public void Updated (IChannel channel)
+               public void Updated (IChannel channel)
        {
            MarkAsDirty();
 
diff --git a/src/ChannelDialog.cs b/src/ChannelDialog.cs
index 55a1050..dc3728b 100644
--- a/src/ChannelDialog.cs
+++ b/src/ChannelDialog.cs
@@ -89,7 +89,6 @@ namespace Imendio.Blam {
            mChannel.Keywords = keywordEntry.Text;
            mChannel.http_username = usernameEntry.Text;
            mChannel.http_password = passwordEntry.Text;
-            mChannel.EmitUpdated();
 
            channelDialog.Hide ();
        }
diff --git a/src/ChannelGroup.cs b/src/ChannelGroup.cs
index b6f4486..045022d 100644
--- a/src/ChannelGroup.cs
+++ b/src/ChannelGroup.cs
@@ -9,18 +9,20 @@ using System.Collections;
 using System.Xml.Serialization;
 using System.Threading.Tasks;
 using System.Linq;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
 
 namespace Imendio.Blam
 {
     [XmlType("group")]
-    public class ChannelGroup : IChannel
+    public class ChannelGroup : IChannel, INotifyPropertyChanged
     {
         [XmlAttribute("Name")] public string Int_Name = null;
         [XmlAttribute("Url")] public string Int_Url = null;
         [XmlElement("Channel", typeof(Channel))] public ArrayList Channels;
         private Gtk.TreeIter mIter;
 
-        public event ChannelEventHandler Updated;
+               public event PropertyChangedEventHandler PropertyChanged;
 
         public ArrayList ItemList {
             get { /* FIXME: Cache this value. */
@@ -131,10 +133,24 @@ namespace Imendio.Blam
                 Channels = new ArrayList();
         }
 
+               void ChannelChanged(object sender, PropertyChangedEventArgs args)
+               {
+                       // Whatever's changed in the children has changed for us as well
+                       NotifyPropertyChanged(args.PropertyName);
+               }
+
+               void NotifyPropertyChanged([CallerMemberName] string name = "")
+               {
+                       if (PropertyChanged != null) {
+                               PropertyChanged(this, new PropertyChangedEventArgs(name));
+                       }
+               }
+
         public void Setup()
         {
             foreach(Channel chan in Channels){
                 chan.Setup();
+                               chan.PropertyChanged += ChannelChanged;
             }
         }
 
diff --git a/src/ChannelList.cs b/src/ChannelList.cs
index 2a9a51e..a7de14a 100644
--- a/src/ChannelList.cs
+++ b/src/ChannelList.cs
@@ -11,6 +11,7 @@ using GtkSharp;
 using System;
 using System.Collections;
 using System.Runtime.InteropServices;
+using System.ComponentModel;
 using Mono.Unix;
 
 namespace Imendio.Blam {
@@ -184,13 +185,13 @@ namespace Imendio.Blam {
         public void Add (IChannel channel)
         {
             channel.Iter = (this.Model as TreeStore).AppendValues(channel);
-            channel.Updated += Updated;
+                       channel.PropertyChanged += ChannelChanged;
         }
 
                public void AddToGroup(IChannel group, IChannel channel)
                {
                        channel.Iter = (Model as TreeStore).AppendValues(group.Iter, channel);
-            channel.Updated += Updated;
+                       channel.PropertyChanged += ChannelChanged;
                }
 
         public void AddGroup(IChannel channel)
@@ -218,17 +219,19 @@ namespace Imendio.Blam {
             return(IChannel)model.GetValue(iter, 0);
         }
 
-        public void Updated (IChannel channel)
-        {
-            TreeIter iter = FindChannel (channel);
+               void ChannelChanged(object sender, PropertyChangedEventArgs args)
+               {
+                       var channel = (IChannel)sender;
 
-            if (!iter.Equals(TreeIter.Zero)) {
-                this.Model.EmitRowChanged (this.Model.GetPath(iter), iter);
-            }
+                       TreeIter iter = FindChannel (channel);
 
-            ForceResort();
+                       if (!iter.Equals(TreeIter.Zero)) {
+                               this.Model.EmitRowChanged (this.Model.GetPath(iter), iter);
+                       }
 
-        }
+                       ForceResort();
+
+               }
 
         public void Remove (IChannel channel)
         {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]