From 33ece139cc23ee7afed6e449598551cceb2eadac Mon Sep 17 00:00:00 2001
From: Gwenael Casaccio <mrgwen@gmail.com>
Date: Mon, 2 Dec 2013 11:38:06 +0100
Subject: [PATCH] Migrate the widgets to the new events that uses the
 announcement framework to be more coherent.

---
 packages/visualgst/ChangeLog                       | 20 ++++++++
 packages/visualgst/Debugger/GtkDebugger.st         | 14 ++---
 packages/visualgst/GtkHistoryWidget.st             | 10 ++--
 packages/visualgst/GtkLauncher.st                  | 31 +++++------
 packages/visualgst/Image/GtkImageWidget.st         | 14 ++---
 .../Inspector/GtkInspectorBrowserWidget.st         | 22 +++-----
 packages/visualgst/Inspector/GtkInspectorWidget.st |  7 +--
 packages/visualgst/SUnit/GtkSUnit.st               |  8 +--
 packages/visualgst/StBrowser/GtkCategoryWidget.st  |  6 ++-
 .../visualgst/StBrowser/GtkClassBrowserWidget.st   | 30 +++--------
 packages/visualgst/StBrowser/GtkMethodWidget.st    | 19 ++++++-
 packages/visualgst/Widget/Compoment.st             |  3 ++
 packages/visualgst/Widget/Entry.st                 |  5 +-
 .../Widget/Events/SelectionChangedAnnouncement.st  | 50 ++++++++++++++++++
 .../Widget/Events/TextChangedAnnouncement.st       | 44 ++++++++++++++++
 .../visualgst/Widget/Events/WidgetAnnouncement.st  | 60 ++++++++++++++++++++++
 packages/visualgst/Widget/List.st                  | 10 ++--
 packages/visualgst/Widget/Widget.st                |  4 +-
 packages/visualgst/package.xml                     |  3 ++
 19 files changed, 262 insertions(+), 98 deletions(-)
 create mode 100644 packages/visualgst/Widget/Events/SelectionChangedAnnouncement.st
 create mode 100644 packages/visualgst/Widget/Events/TextChangedAnnouncement.st
 create mode 100644 packages/visualgst/Widget/Events/WidgetAnnouncement.st

diff --git a/packages/visualgst/ChangeLog b/packages/visualgst/ChangeLog
index 8bc960c..6185ad2 100644
--- a/packages/visualgst/ChangeLog
+++ b/packages/visualgst/ChangeLog
@@ -1,5 +1,25 @@
 2013-12-02  Gwenael Casaccio  <gwenael.casaccio@gmail.com>
 
+	* Debugger/GtkDebugger.st: Migrate to new events.
+	* GtkHistoryWidget.st: Migrate to new events.
+	* GtkLauncher.st: Migrate to new events.
+	* Image/GtkImageWidget.st: Migrate to new events.
+	* Inspector/GtkInspectorBrowserWidget.st: Migrate to new events.
+	* Inspector/GtkInspectorWidget.st: Migrate to new events.
+	* SUnit/GtkSUnit.st: Migrate to new events.
+	* StBrowser/GtkCategoryWidget.st: Migrate to new events.
+	* StBrowser/GtkClassBrowserWidget.st: Migrate to new events.
+	* StBrowser/GtkMethodWidget.st: Migrate to new events.
+	* Widget/Compoment.st: Migrate to new events.
+	* Widget/Entry.st: Migrate to new events.
+	* Widget/List.st: Migrate to new events.
+	* Widget/Widget.st: Migrate to new events.
+	* Widget/Events/SelectionChangedAnnouncement.st: Selection event.
+	* Widget/Events/TextChangedAnnouncement.st: Text changed event.
+	* Widget/Events/WidgetAnnouncement.st: Widget event.
+
+2013-10-23  Gwenael Casaccio  <gwenael.casaccio@gmail.com>
+
 	* Commands/WorkspaceMenus/DeleteItemCommand.st: New UI support.
 	* Commands/WorkspaceMenus/InspectItemCommand.st: New UI support.
 	* Debugger/Extensions.st: Disable the debugger.
diff --git a/packages/visualgst/Debugger/GtkDebugger.st b/packages/visualgst/Debugger/GtkDebugger.st
index 7576bb0..17789bb 100644
--- a/packages/visualgst/Debugger/GtkDebugger.st
+++ b/packages/visualgst/Debugger/GtkDebugger.st
@@ -92,7 +92,7 @@ GtkBrowsingTool subclass: GtkDebugger [
 	<category: 'user interface'>
 
 	^ contextWidget := (GtkContextWidget parentWindow: window)
-				whenSelectionChangedSend: #contextChanged to: self;
+				whenSelectionChangedSend: #contextChanged: to: self;
 				yourself
     ]
 
@@ -266,20 +266,20 @@ GtkBrowsingTool subclass: GtkDebugger [
         ^codeWidget hasSelection
     ]
 
-    contextChanged [
+    contextChanged: aSelectionChanged [
 	<category: 'context events'>
 
 	self checkCodeWidgetAndUpdate: [
             | line |
-	    contextWidget hasSelectedContext ifFalse: [ ^ self ].
-	    codeWidget source: (BrowserMethodSource on: contextWidget selectedContext method).
-            contextWidget selectedContext currentLine ~= 0
-                ifTrue: [ line := contextWidget selectedContext currentLine ]
+	    aSelectionChanged hasSelection ifFalse: [ ^ self ].
+	    codeWidget source: (BrowserMethodSource on: aSelectionChanged selection method).
+            aSelectionChanged selection currentLine ~= 0
+                ifTrue: [ line := aSelectionChanged selection currentLine ]
                 ifFalse: [ line := 1 ].
             codeWidget
                 applyTag: #debug forLine: line;
                 centerViewAtLine: line.
-	    self updateInspectorWidget: contextWidget selectedContext ]
+	    self updateInspectorWidget: aSelectionChanged selection ]
     ]
 
     stepInto [
diff --git a/packages/visualgst/GtkHistoryWidget.st b/packages/visualgst/GtkHistoryWidget.st
index 0a297e4..c522b21 100644
--- a/packages/visualgst/GtkHistoryWidget.st
+++ b/packages/visualgst/GtkHistoryWidget.st
@@ -57,7 +57,7 @@ Compoment subclass: GtkHistoryWidget [
                            {'Open in new tab'. self. #browseTabbedClass}.
                           {'Open in new window'. self. #browseClass}}".
         widget singleSelection.
-        widget whenSelectionChangedSend: #onSelectionChanged to: self.
+        widget whenSelectionChangedSend: #onSelectionChanged: to: self.
     ]
 
     refresh: historyStack [
@@ -97,12 +97,12 @@ Compoment subclass: GtkHistoryWidget [
 	InspectItCommand executeOn: self
     ]
 
-    onSelectionChanged [
+    onSelectionChanged: aSelectionChanged [
 	<category: 'event'>
 
-	widget hasSelection ifFalse: [ ^ self ].
-        stack selectedIndex = widget selectionIndex ifTrue: [^self].
-        stack selectItem: widget selectionIndex.
+	aSelectionChanged hasSelection ifFalse: [ ^ self ].
+        stack selectedIndex = aSelectionChanged widget selectionIndex ifTrue: [ ^ self ].
+        stack selectItem: aSelectionChanged widget selectionIndex.
     ]
 
     browseTabbedClass [
diff --git a/packages/visualgst/GtkLauncher.st b/packages/visualgst/GtkLauncher.st
index fb62e3d..41ec9f6 100644
--- a/packages/visualgst/GtkLauncher.st
+++ b/packages/visualgst/GtkLauncher.st
@@ -400,7 +400,7 @@ GtkVisualGSTTool subclass: GtkLauncher [
        <category: 'user interface'>
 
         ^ implementorWidget := self buildImageView
-			    whenSelectionChangedSend: #implementorSelected to: self;
+			    whenSelectionChangedSend: #implementorSelected: to: self;
 			    yourself.
     ]
 
@@ -408,7 +408,7 @@ GtkVisualGSTTool subclass: GtkLauncher [
        <category: 'user interface'>
 
         ^ senderWidget := self buildImageView
-			    whenSelectionChangedSend: #senderSelected to: self;
+			    whenSelectionChangedSend: #senderSelected: to: self;
 			    yourself.
     ]
 
@@ -430,7 +430,7 @@ GtkVisualGSTTool subclass: GtkLauncher [
         <category: 'user interface'>
 
         ^ implementorResultWidget := GtkImplementorResultsWidget new
-					    whenSelectionChangedSend: #resultImplementorSelected to: self;
+					    whenSelectionChangedSend: #resultImplementorSelected: to: self;
 					    yourself
     ]
 
@@ -438,7 +438,7 @@ GtkVisualGSTTool subclass: GtkLauncher [
         <category: 'user interface'>
 
         ^ senderResultWidget := GtkSenderResultsWidget new
-					    whenSelectionChangedSend: #resultSenderSelected to: self;
+					    whenSelectionChangedSend: #resultSenderSelected: to: self;
 					    yourself
     ]
 
@@ -928,25 +928,18 @@ GtkVisualGSTTool subclass: GtkLauncher [
 	topSidebar hideAll
     ]
 
-    senderSelected [
+    implementorSelected: aSelectionChanged [
         <category: 'pane events'>
 
-        senderWidget hasSelection ifFalse: [ ^ self ].
-        self findInMethod: (senderWidget matchSelector: senderWidget selection) values first element
+        aSelectionChanged hasSelection ifFalse: [ ^ self ].
+        self imageSelectorForImplementor: aSelectionChanged selection
     ]
 
-    implementorSelected [
-        <category: 'pane events'>
-
-        implementorWidget hasSelection ifFalse: [ ^ self ].
-        self imageSelectorForImplementor: implementorWidget selection
-    ]
-
-    senderSelected [
+    senderSelected: aSelectionChanged [
 	<category: 'pane events'>
 
-        senderWidget hasSelection ifFalse: [ ^ self ].
-        self imageSelectorForSender: senderWidget selection
+        aSelectionChanged hasSelection ifFalse: [ ^ self ].
+        self imageSelectorForSender: aSelectionChanged selection
     ]
 
     imageSelectorForImplementor: aSymbol [
@@ -961,13 +954,13 @@ GtkVisualGSTTool subclass: GtkLauncher [
 	senderResultWidget appendSenderResults: (senderWidget matchSelector: aSymbol)
     ]
 
-    resultImplementorSelected [
+    resultImplementorSelected: aSelectionChanged [
         <category: 'pane events'>
 
 	implementorResultWidget selectedResult: self currentWidgetOfBrowser
     ]
 
-    resultSenderSelected [
+    resultSenderSelected: aSelectionChanged [
         <category: 'pane events'>
 
         senderResultWidget selectedResult: self currentWidgetOfBrowser
diff --git a/packages/visualgst/Image/GtkImageWidget.st b/packages/visualgst/Image/GtkImageWidget.st
index 15c8782..76cf471 100644
--- a/packages/visualgst/Image/GtkImageWidget.st
+++ b/packages/visualgst/Image/GtkImageWidget.st
@@ -56,7 +56,7 @@ Compoment subclass: GtkImageWidget [
         <category: 'user interface'>
 
         searchEntry := Entry new
-			    whenTextChangedSend: #searchValidate to: self;
+			    whenTextChangedSend: #searchValidate: to: self;
 			    yourself.
         ^ HBox new
             add: (Label text: 'Class or method :');
@@ -79,12 +79,6 @@ Compoment subclass: GtkImageWidget [
         imageTree whenSelectionChangedSend: aSelector to: anObject
     ]
 
-    whenTextChangedSend: aSelector to: anObject [
-	<category: 'events'>
-
-        searchEntry connectSignal: 'activate' to: anObject selector: aSelector
-    ]
-
     grabFocus [
 	<category: 'focus events'>
 
@@ -97,12 +91,12 @@ Compoment subclass: GtkImageWidget [
 	^ searchEntry text
     ]
 
-    searchValidate [
+    searchValidate: aTextChanged [
 	<category: 'search entry events'>
 
-	searchEntry text isEmpty 
+	aTextChanged text isEmpty 
 		    ifTrue: [ imageTree item: image ]
-		    ifFalse: [ imageTree item: (image matchRegex: searchEntry text) ].
+		    ifFalse: [ imageTree item: (image matchRegex: aTextChanged text) ].
 	imageTree refresh
     ]
 
diff --git a/packages/visualgst/Inspector/GtkInspectorBrowserWidget.st b/packages/visualgst/Inspector/GtkInspectorBrowserWidget.st
index 98eb66a..2cc7335 100644
--- a/packages/visualgst/Inspector/GtkInspectorBrowserWidget.st
+++ b/packages/visualgst/Inspector/GtkInspectorBrowserWidget.st
@@ -94,7 +94,7 @@ Compoment subclass: GtkInspectorBrowserWidget [
 	<category: 'user interface'>
 
 	^ cMethodWidget := GtkMethodWidget new
-			    whenSelectionChangedSend: #onClassSideMethodChanged to: self;
+			    whenSelectionChangedSend: #onMethodChanged: to: self;
 			    yourself.
     ]
 
@@ -102,13 +102,14 @@ Compoment subclass: GtkInspectorBrowserWidget [
         <category: 'user interface'>
 
         ^ iMethodWidget := GtkMethodWidget new
-                            whenSelectionChangedSend: #onInstanceSideMethodChanged to: self;
+                            whenSelectionChangedSend: #onMethodChanged: to: self;
                             yourself.
     ]
 
     initialize [
 	<category: 'initialize-release'>
 
+        super initialize.
 	classHierarchyUpdate := false.
 	checkCode := true.
 	state := NamespaceState on: self with: Smalltalk.
@@ -146,24 +147,13 @@ Compoment subclass: GtkInspectorBrowserWidget [
 	    state := CategoryState on: self with: classHierarchyWidget selectedClass -> '*' ]
     ]
 
-    onInstanceSideMethodChanged [
+    onMethodChanged: aSelectionChanged [
 	<category: 'events'>
 
 	| method |
 	self checkCodeWidgetAndUpdate: [
-	    iMethodWidget hasSelectedMethod ifFalse: [ ^ self ].
-	    method := iMethodWidget selectedMethod.
-	    codeWidget source: (BrowserMethodSource on: method).
-	    state := MethodState on: self with: method ]
-    ]
-
-    onClassSideMethodChanged [
-	<category: 'events'>
-
-	| method |
-	self checkCodeWidgetAndUpdate: [
-	    cMethodWidget hasSelectedMethod ifFalse: [ ^ self ].
-	    method := cMethodWidget selectedMethod.
+	    aSelectionChanged hasSelection ifFalse: [ ^ self ].
+	    method := aSelectionChanged selection.
 	    codeWidget source: (BrowserMethodSource on: method).
 	    state := MethodState on: self with: method ]
     ]
diff --git a/packages/visualgst/Inspector/GtkInspectorWidget.st b/packages/visualgst/Inspector/GtkInspectorWidget.st
index 74f5342..5a255e9 100644
--- a/packages/visualgst/Inspector/GtkInspectorWidget.st
+++ b/packages/visualgst/Inspector/GtkInspectorWidget.st
@@ -48,9 +48,10 @@ Compoment subclass: GtkInspectorWidget [
     initialize [
 	<category: 'initialization'>
 
+        super initialize.
 	stack := OrderedCollection new.
 	self buildView.
-	inspectorTree whenSelectionChangedSend: #onVariableChanged to: self.
+	inspectorTree whenSelectionChangedSend: #onVariableChanged: to: self.
     ]
 
     postInitialize [
@@ -112,10 +113,10 @@ Compoment subclass: GtkInspectorWidget [
         ^ inspectorTree hasSelection
     ]
 
-    onVariableChanged [
+    onVariableChanged: aSelectionChanged [
 	<category: 'events'>
 
-	self hasSelectedValue ifFalse: [ workspaceWidget text: ''. ^ self ].
+	aSelectionChanged hasSelection ifFalse: [ workspaceWidget text: ''. ^ self ].
 	workspaceWidget text: self selectedValue displayString
     ]
 
diff --git a/packages/visualgst/SUnit/GtkSUnit.st b/packages/visualgst/SUnit/GtkSUnit.st
index 4bd167a..938f087 100644
--- a/packages/visualgst/SUnit/GtkSUnit.st
+++ b/packages/visualgst/SUnit/GtkSUnit.st
@@ -152,7 +152,7 @@ GtkBrowsingTool subclass: GtkSUnit [
 	<category: 'user interface'>
 
 	^ methodWidget := GtkMethodSUnitWidget new
-				whenSelectionChangedSend: #onMethodChanged to: self;
+				whenSelectionChangedSend: #onMethodChanged: to: self;
                                 yourself.
     ]
 
@@ -221,12 +221,12 @@ GtkBrowsingTool subclass: GtkSUnit [
 	state := CategoryState on: self with: class -> '*'
     ]
 
-    onMethodChanged [
+    onMethodChanged: aSelectionChanged [
 	<category: 'method events'>
 
 	self checkCodeWidgetAndUpdate: [
-	    methodWidget hasSelectedMethod ifFalse: [^self].
-	    self selectAnInstanceMethod: methodWidget selectedMethodSymbol ]
+	    aSelectionChanged hasSelection ifFalse: [^self].
+	    self selectAnInstanceMethod: aSelectionChanged selection selector ]
     ]
 
     selectAnInstanceMethod: aSymbol [
diff --git a/packages/visualgst/StBrowser/GtkCategoryWidget.st b/packages/visualgst/StBrowser/GtkCategoryWidget.st
index adbecce..0fcccca 100644
--- a/packages/visualgst/StBrowser/GtkCategoryWidget.st
+++ b/packages/visualgst/StBrowser/GtkCategoryWidget.st
@@ -48,6 +48,7 @@ Compoment subclass: GtkCategoryWidget [
     initialize [
 	<category: 'initialization'>
 
+        super initialize.
 	self initializeCategories.
 	self buildTreeView.
 	self registerNotifier
@@ -120,7 +121,10 @@ Compoment subclass: GtkCategoryWidget [
     whenSelectionChangedSend: aSelector to: anObject [
 	<category: 'events'>
 
-	widget whenSelectionChangedSend: aSelector to: anObject
+        (events includes: #'selection-changed') ifFalse:
+            [ events add: #'selection-changed'.
+	      widget whenSelectionChangedSend: #value: to: [ :ann | announcer announce: (SelectionChangedAnnouncement widget: self) ] ].
+        announcer on: SelectionChangedAnnouncement do: [ :ann | anObject perform: aSelector with: ann ].
     ]
 
     state [
diff --git a/packages/visualgst/StBrowser/GtkClassBrowserWidget.st b/packages/visualgst/StBrowser/GtkClassBrowserWidget.st
index e51e6ff..7bc2366 100644
--- a/packages/visualgst/StBrowser/GtkClassBrowserWidget.st
+++ b/packages/visualgst/StBrowser/GtkClassBrowserWidget.st
@@ -143,19 +143,19 @@ Compoment subclass: GtkClassBrowserWidget [
     buildInstanceCategoryView [
         <category: 'user interface'>
 
-        ^ (iCategoryWidget := self buildWidget: GtkCategoryWidget whenSelectionChangedSend: #onInstanceSideCategoryChanged)
+        ^ (iCategoryWidget := self buildWidget: GtkCategoryWidget whenSelectionChangedSend: #onCategoryOrMethodChanged:)
     ]
 
     buildClassCategoryView [
 	<category: 'user interface'>
 
-	^ (cCategoryWidget := self buildWidget: GtkCategoryWidget whenSelectionChangedSend: #onClassSideCategoryChanged)
+	^ (cCategoryWidget := self buildWidget: GtkCategoryWidget whenSelectionChangedSend: #onCategoryOrMethodChanged:)
     ]
 
     buildClassMethodView [
 	<category: 'user interface'>
 
-	^ (cMethodWidget := self buildWidget: GtkMethodWidget whenSelectionChangedSend: #onClassSideMethodChanged)
+	^ (cMethodWidget := self buildWidget: GtkMethodWidget whenSelectionChangedSend: #onCategoryOrMethodChanged:)
             browser: self;
             yourself
     ]
@@ -163,7 +163,7 @@ Compoment subclass: GtkClassBrowserWidget [
     buildInstanceMethodView [
         <category: 'user interface'>
 
-        ^ (iMethodWidget := self buildWidget: GtkMethodWidget whenSelectionChangedSend: #onInstanceSideMethodChanged)
+        ^ (iMethodWidget := self buildWidget: GtkMethodWidget whenSelectionChangedSend: #onCategoryOrMethodChanged:)
             browser: self;
             yourself
     ]
@@ -270,28 +270,10 @@ Compoment subclass: GtkClassBrowserWidget [
 	    ensure: [classHierarchyUpdate := false ]
     ]
 
-    onInstanceSideCategoryChanged [
+    onCategoryOrMethodChanged: aSelectionChanged [
 	<category: 'events'>
 
-	self updateState: iCategoryWidget state
-    ]
-
-    onClassSideCategoryChanged [
-	<category: 'events'>
-
-	self updateState: cCategoryWidget state
-    ]
-
-    onInstanceSideMethodChanged [
-	<category: 'events'>
-
-	self updateState: iMethodWidget state
-    ]
-
-    onClassSideMethodChanged [
-	<category: 'events'>
-
-	self updateState: cMethodWidget state
+	self updateState: aSelectionChanged widget state
     ]
 
     undoStack [
diff --git a/packages/visualgst/StBrowser/GtkMethodWidget.st b/packages/visualgst/StBrowser/GtkMethodWidget.st
index d28d6e5..22441a4 100644
--- a/packages/visualgst/StBrowser/GtkMethodWidget.st
+++ b/packages/visualgst/StBrowser/GtkMethodWidget.st
@@ -48,6 +48,7 @@ Compoment subclass: GtkMethodWidget [
     initialize [
 	<category: 'initialization'>
 
+        super initialize.
 	self 
 	    buildTreeView;
 	    registerNotifier
@@ -144,7 +145,10 @@ Compoment subclass: GtkMethodWidget [
     whenSelectionChangedSend: aSelector to: anObject [
 	<category: 'events'>
 
-	widget whenSelectionChangedSend: aSelector to: anObject
+        (events includes: #'selection-changed') ifFalse:
+            [ events add: #'selection-changed'.
+              widget whenSelectionChangedSend: #value: to: [ :ann | announcer announce: (SelectionChangedAnnouncement widget: self) ] ].
+        announcer on: SelectionChangedAnnouncement do: [ :ann | anObject perform: aSelector with: ann ].
     ]
 
     launcher [
@@ -179,6 +183,12 @@ Compoment subclass: GtkMethodWidget [
 	    ifFalse: [ category ]
     ]
 
+    hasSelection [
+	<category: 'testing'>
+
+	^ widget hasSelection
+    ]
+
     hasSelectedMethod [
 	<category: 'testing'>
 
@@ -197,6 +207,13 @@ Compoment subclass: GtkMethodWidget [
         ^ self selectedMethod selector
     ]
 
+    selection [
+	<category: 'accessing'>
+
+	self ifNoSelection: [ self error: 'nothing is selected' ].
+        ^ widget selection 
+    ]
+
     selectedMethod [
 	<category: 'accessing'>
 
diff --git a/packages/visualgst/Widget/Compoment.st b/packages/visualgst/Widget/Compoment.st
index 752d220..48f3b18 100644
--- a/packages/visualgst/Widget/Compoment.st
+++ b/packages/visualgst/Widget/Compoment.st
@@ -40,6 +40,8 @@ Widget subclass: Compoment [
     initialize [
 	<category: 'initialization'>
 
+        announcer := Announcer new.
+        events := Set new.
     ]
 
     widget: aWidget [
@@ -63,3 +65,4 @@ Widget subclass: Compoment [
 	widget hideAll
     ]
 ]
+
diff --git a/packages/visualgst/Widget/Entry.st b/packages/visualgst/Widget/Entry.st
index 251f46c..440ab24 100644
--- a/packages/visualgst/Widget/Entry.st
+++ b/packages/visualgst/Widget/Entry.st
@@ -61,7 +61,10 @@ Widget subclass: Entry [
     whenTextChangedSend: aSelector to: anObject [
         <category: 'events'>
 
-        child connectSignal: 'activate' to: anObject selector: aSelector
+        (events includes: #activate) ifFalse: 
+            [ events add: #activate. 
+              child connectSignal: 'activate' to: [ announcer announce: (TextChangedAnnouncement widget: self) ] selector: #value ].
+        announcer on: TextChangedAnnouncement do: [ :ann | anObject perform: aSelector with: ann ]
     ]
 ]
 
diff --git a/packages/visualgst/Widget/Events/SelectionChangedAnnouncement.st b/packages/visualgst/Widget/Events/SelectionChangedAnnouncement.st
new file mode 100644
index 0000000..24eb336
--- /dev/null
+++ b/packages/visualgst/Widget/Events/SelectionChangedAnnouncement.st
@@ -0,0 +1,50 @@
+"======================================================================
+|
+| SelectionChangedAnnouncement class definition
+|
+======================================================================"
+
+"======================================================================
+|
+| Copyright (c) 2013
+| Gwenael Casaccio <gwenael.casaccio@gmail.com>,
+|
+|
+| This file is part of VisualGST.
+|
+| Permission is hereby granted, free of charge, to any person obtaining
+| a copy of this software and associated documentation files (the
+| 'Software'), to deal in the Software without restriction, including
+| without limitation the rights to use, copy, modify, merge, publish,
+| distribute, sublicense, and/or sell copies of the Software, and to
+| permit persons to whom the Software is furnished to do so, subject to
+| the following conditions:
+|
+| The above copyright notice and this permission notice shall be
+| included in all copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+|
+======================================================================"
+
+WidgetAnnouncement subclass: SelectionChangedAnnouncement [
+
+    hasSelection [
+        <category: 'testing'>
+
+        ^ self widget hasSelection
+    ]
+
+    selection [
+        <category: 'accessing'>
+
+        ^ self widget selection
+    ]
+]
+
diff --git a/packages/visualgst/Widget/Events/TextChangedAnnouncement.st b/packages/visualgst/Widget/Events/TextChangedAnnouncement.st
new file mode 100644
index 0000000..12c53a3
--- /dev/null
+++ b/packages/visualgst/Widget/Events/TextChangedAnnouncement.st
@@ -0,0 +1,44 @@
+"======================================================================
+|
+| TextChangedAnnouncement class definition
+|
+======================================================================"
+
+"======================================================================
+|
+| Copyright (c) 2013
+| Gwenael Casaccio <gwenael.casaccio@gmail.com>,
+|
+|
+| This file is part of VisualGST.
+|
+| Permission is hereby granted, free of charge, to any person obtaining
+| a copy of this software and associated documentation files (the
+| 'Software'), to deal in the Software without restriction, including
+| without limitation the rights to use, copy, modify, merge, publish,
+| distribute, sublicense, and/or sell copies of the Software, and to
+| permit persons to whom the Software is furnished to do so, subject to
+| the following conditions:
+|
+| The above copyright notice and this permission notice shall be
+| included in all copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+|
+======================================================================"
+
+WidgetAnnouncement subclass: TextChangedAnnouncement [
+
+    text [
+        <category: 'accessing'>
+
+        ^ self widget text
+    ]
+]
+
diff --git a/packages/visualgst/Widget/Events/WidgetAnnouncement.st b/packages/visualgst/Widget/Events/WidgetAnnouncement.st
new file mode 100644
index 0000000..63fbebc
--- /dev/null
+++ b/packages/visualgst/Widget/Events/WidgetAnnouncement.st
@@ -0,0 +1,60 @@
+"======================================================================
+|
+| WidgetAnnouncement class definition
+|
+======================================================================"
+
+"======================================================================
+|
+| Copyright (c) 2013
+| Gwenael Casaccio <gwenael.casaccio@gmail.com>,
+|
+|
+| This file is part of VisualGST.
+|
+| Permission is hereby granted, free of charge, to any person obtaining
+| a copy of this software and associated documentation files (the
+| 'Software'), to deal in the Software without restriction, including
+| without limitation the rights to use, copy, modify, merge, publish,
+| distribute, sublicense, and/or sell copies of the Software, and to
+| permit persons to whom the Software is furnished to do so, subject to
+| the following conditions:
+|
+| The above copyright notice and this permission notice shall be
+| included in all copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+|
+======================================================================"
+
+Announcement subclass: WidgetAnnouncement [
+
+    | widget |
+
+    WidgetAnnouncement class >> widget: aWidget [
+        <category: 'instance creation'>
+
+        ^ self new
+            widget: aWidget;
+            yourself
+    ]
+
+    widget [
+	<category: 'accessing'>
+
+	^ widget
+    ]
+
+    widget: aWidget [
+	<category: 'accessing'>
+
+	widget := aWidget
+    ]
+]
+
diff --git a/packages/visualgst/Widget/List.st b/packages/visualgst/Widget/List.st
index 7ede3fc..de761bb 100644
--- a/packages/visualgst/Widget/List.st
+++ b/packages/visualgst/Widget/List.st
@@ -154,7 +154,10 @@ Widget subclass: List [
 
     whenSelectionChangedSend: aSymbol to: anObject [
 
-        list getSelection connectSignal: 'changed' to: anObject selector: aSymbol
+        (events includes: #changed) ifFalse:
+            [ events add: #changed.
+              list getSelection connectSignal: 'changed' to: [ announcer announce: (SelectionChangedAnnouncement widget: self) ] selector: #value ].
+        announcer on: SelectionChangedAnnouncement do: [ :ann | anObject perform: aSymbol with: ann ]
     ]
 
     onPress: aGtkWidget event: aGdkEvent [
@@ -169,10 +172,5 @@ Widget subclass: List [
         menu showAll.
         ^ true
     ]
-
-    list [
-
-        ^ list
-    ]
 ]
 
diff --git a/packages/visualgst/Widget/Widget.st b/packages/visualgst/Widget/Widget.st
index 594b053..11979a3 100644
--- a/packages/visualgst/Widget/Widget.st
+++ b/packages/visualgst/Widget/Widget.st
@@ -35,7 +35,7 @@
 
 Object subclass: Widget [
 
-    | child parent parentWindow popupMenu |
+    | child parent parentWindow popupMenu announcer events |
 
     Widget class >> new [
 	<category: 'instance creation'>
@@ -64,6 +64,8 @@ Object subclass: Widget [
     initialize [
 	<category: 'initialize'>
 
+        announcer := Announcer new.
+        events := Set new.
         self showAll
     ]
 
diff --git a/packages/visualgst/package.xml b/packages/visualgst/package.xml
index 4fc96eb..611a812 100644
--- a/packages/visualgst/package.xml
+++ b/packages/visualgst/package.xml
@@ -165,6 +165,9 @@
   <filein>Category/AbstractNamespace.st</filein>
   <filein>Category/Class.st</filein>
   <filein>GtkConcreteWidget.st</filein>
+  <filein>Widget/Events/WidgetAnnouncement.st</filein>
+  <filein>Widget/Events/TextChangedAnnouncement.st</filein>
+  <filein>Widget/Events/SelectionChangedAnnouncement.st</filein>
   <filein>Widget/Widget.st</filein>
   <filein>Widget/Compoment.st</filein>
   <filein>Widget/Label.st</filein>
-- 
1.8.3.2

