View | Details | Raw Unified | Return to bug 515507
Collapse All | Expand All

(-)UiaAtkBridge/Test/AtkTest/Makefile.am (-1 / +2 lines)
Lines 44-50 Link Here
44
	AtSpiEvent.cs \
44
	AtSpiEvent.cs \
45
	BasicWidgetType.cs \
45
	BasicWidgetType.cs \
46
	EventCollection.cs \
46
	EventCollection.cs \
47
	EventMonitor.cs
47
	EventMonitor.cs \
48
	TestBase.cs
48
49
49
DATA_FILES = 
50
DATA_FILES = 
50
51
(-)UiaAtkBridge/Test/AtkTest/AtkTester.cs (-78 / +5 lines)
Lines 33-39 Link Here
33
namespace UiaAtkBridgeTest
33
namespace UiaAtkBridgeTest
34
{
34
{
35
	
35
	
36
	public abstract class AtkTester {
36
	public abstract class AtkTester : TestBase {
37
37
38
		public abstract Atk.Object GetAccessible (BasicWidgetType type);
38
		public abstract Atk.Object GetAccessible (BasicWidgetType type);
39
		
39
		
Lines 343-348 Link Here
343
				               "menu child of combobox should be visible and showing NOW!");
343
				               "menu child of combobox should be visible and showing NOW!");
344
			}
344
			}
345
345
346
			GlibSync ();
346
			if (type == BasicWidgetType.ComboBoxItem)
347
			if (type == BasicWidgetType.ComboBoxItem)
347
				Assert.AreEqual (accessible.Name, accessible.Parent.Parent.Name, "action on combobox item should yield selection");
348
				Assert.AreEqual (accessible.Name, accessible.Parent.Parent.Name, "action on combobox item should yield selection");
348
			
349
			
Lines 561-566 Link Here
561
				         type == BasicWidgetType.ListBox ||
562
				         type == BasicWidgetType.ListBox ||
562
				         type == BasicWidgetType.CheckedListBox)
563
				         type == BasicWidgetType.CheckedListBox)
563
					accName = null;
564
					accName = null;
565
				GlibSync ();
564
				Assert.AreEqual (accName, accessible.Name, "AtkObj Name #" + i + ", we got: " + accessible.Name);
566
				Assert.AreEqual (accName, accessible.Name, "AtkObj Name #" + i + ", we got: " + accessible.Name);
565
567
566
				Atk.Object refSelObj = implementor.RefSelection (0);
568
				Atk.Object refSelObj = implementor.RefSelection (0);
Lines 949-954 Link Here
949
		
951
		
950
		protected void PropertyRole (BasicWidgetType type, Atk.Object accessible)
952
		protected void PropertyRole (BasicWidgetType type, Atk.Object accessible)
951
		{
953
		{
954
			GlibSync ();
952
			Atk.Role role = GetRole (type);
955
			Atk.Role role = GetRole (type);
953
			Assert.AreEqual (role, accessible.Role, "Atk.Role, we got " + accessible.Role);
956
			Assert.AreEqual (role, accessible.Role, "Atk.Role, we got " + accessible.Role);
954
		}
957
		}
Lines 1918-1956 Link Here
1918
			                   " contains the following states: " + res);
1921
			                   " contains the following states: " + res);
1919
		}
1922
		}
1920
			
1923
			
1921
		public static void States (Atk.Object accessible, params Atk.StateType [] expected)
1922
		{
1923
			List <Atk.StateType> expectedStates = new List <Atk.StateType> (expected);
1924
			List <Atk.StateType> missingStates = new List <Atk.StateType> ();
1925
			List <Atk.StateType> superfluousStates = new List <Atk.StateType> ();
1926
			
1927
			Atk.StateSet stateSet = accessible.RefStateSet ();
1928
			foreach (Atk.StateType state in Enum.GetValues (typeof (Atk.StateType))) {
1929
				if (expectedStates.Contains (state) && 
1930
				    (!(stateSet.ContainsState (state))))
1931
					missingStates.Add (state);
1932
				else if ((!expectedStates.Contains (state)) && 
1933
					     (stateSet.ContainsState (state)))
1934
					superfluousStates.Add (state);
1935
			}
1936
1937
			string missingStatesMsg = string.Empty;
1938
			string superfluousStatesMsg = string.Empty;
1939
1940
			if (missingStates.Count != 0) {
1941
				missingStatesMsg = "Missing states: ";
1942
				foreach (Atk.StateType state in missingStates)
1943
					missingStatesMsg += state.ToString () + ",";
1944
			}
1945
			if (superfluousStates.Count != 0) {
1946
				superfluousStatesMsg = "Superfluous states: ";
1947
				foreach (Atk.StateType state in superfluousStates)
1948
					superfluousStatesMsg += state.ToString () + ",";
1949
			}
1950
			Assert.IsTrue ((missingStates.Count == 0) && (superfluousStates.Count == 0),
1951
				missingStatesMsg + " .. " + superfluousStatesMsg);
1952
		}
1953
1954
		protected void Relations (Atk.Object accessible, BasicWidgetType type)
1924
		protected void Relations (Atk.Object accessible, BasicWidgetType type)
1955
		{
1925
		{
1956
			if (type != BasicWidgetType.RadioButton) {
1926
			if (type != BasicWidgetType.RadioButton) {
Lines 2151-2156 Link Here
2151
			Atk.Component atkComponent = CastToAtkInterface<Atk.Component> (accessible);
2121
			Atk.Component atkComponent = CastToAtkInterface<Atk.Component> (accessible);
2152
			EventMonitor.Start ();
2122
			EventMonitor.Start ();
2153
			atkComponent.GrabFocus ();
2123
			atkComponent.GrabFocus ();
2124
			GlibSync ();
2154
			EventCollection events = EventMonitor.Pause ();
2125
			EventCollection events = EventMonitor.Pause ();
2155
			int expectedCount = (transient ? 1 : 2);
2126
			int expectedCount = (transient ? 1 : 2);
2156
			string evType = (transient? "object:active-descendant-changed": "object:state-changed:focused");
2127
			string evType = (transient? "object:active-descendant-changed": "object:state-changed:focused");
Lines 2194-2243 Link Here
2194
			return value.SetCurrentValue (gv);
2165
			return value.SetCurrentValue (gv);
2195
		}
2166
		}
2196
2167
2197
		private EventCollection events = null;
2198
2199
		protected void StartEventMonitor ()
2200
		{
2201
			events = null;
2202
			EventMonitor.Start ();
2203
		}
2204
2205
		protected void ExpectEvents (int count, Atk.Role role, string evType)
2206
		{
2207
			if (events == null)
2208
				events = EventMonitor.Pause ();
2209
			EventCollection evs = events.FindByRole (role).FindByType (evType);
2210
			string eventsInXml = String.Format (" events in XML: {0}", Environment.NewLine + events.OriginalGrossXml);
2211
			Assert.AreEqual (count, evs.Count, "bad number of " + evType + " events: " + eventsInXml);
2212
		}
2213
2214
		protected void ExpectEvents (int count, Atk.Role role, string evType, int detail1)
2215
		{
2216
			if (events == null)
2217
				events = EventMonitor.Pause ();
2218
			EventCollection evs = events.FindByRole (role).FindByType (evType).FindWithDetail1 (detail1.ToString ());
2219
			string eventsInXml = String.Format (" events in XML: {0}", Environment.NewLine + events.OriginalGrossXml);
2220
			Assert.AreEqual (count, evs.Count, "bad number of " + evType + " events: " + eventsInXml);
2221
		}
2222
2223
		protected void ExpectEvents (int count, Atk.Role role, string evType, string name)
2224
		{
2225
			if (events == null)
2226
				events = EventMonitor.Pause ();
2227
			EventCollection evs = events.FindByRole (role).FindByType (evType).FindByName (name);
2228
			string eventsInXml = String.Format (" events in XML: {0}", Environment.NewLine + events.OriginalGrossXml);
2229
			Assert.AreEqual (count, evs.Count, "bad number of " + evType + " events: " + eventsInXml);
2230
		}
2231
2232
		protected void ExpectEvents (int min, int max, Atk.Role role, string evType)
2233
		{
2234
			if (events == null)
2235
				events = EventMonitor.Pause ();
2236
			EventCollection evs = events.FindByRole (role).FindByType (evType);
2237
			string eventsInXml = String.Format (" events in XML: {0}", Environment.NewLine + events.OriginalGrossXml);
2238
			Assert.IsTrue (evs.Count >= min && evs.Count <= max, "Expected " + min +"-" + max +" " + evType + " events but got " + evs.Count +": " + eventsInXml);
2239
		}
2240
2241
		protected bool DoActionByName (Atk.Object accessible, string name)
2168
		protected bool DoActionByName (Atk.Object accessible, string name)
2242
		{
2169
		{
2243
			Atk.Action atkAction = CastToAtkInterface<Atk.Action> (accessible);
2170
			Atk.Action atkAction = CastToAtkInterface<Atk.Action> (accessible);
(-)UiaAtkBridge/Test/AtkTest/EventMonitor.cs (+2 lines)
Lines 38-43 Link Here
38
		static object locking = new object ();
38
		static object locking = new object ();
39
		
39
		
40
		public static void Start () {
40
		public static void Start () {
41
			TestBase.GlibSync ();
41
			lock (locking) {
42
			lock (locking) {
42
				if (singleton == null)
43
				if (singleton == null)
43
					singleton = new EventMonitor ();
44
					singleton = new EventMonitor ();
Lines 76-81 Link Here
76
		}
77
		}
77
78
78
		public static EventCollection Pause () {
79
		public static EventCollection Pause () {
80
			TestBase.GlibSync ();
79
			lock (locking) {
81
			lock (locking) {
80
				if (singleton == null)
82
				if (singleton == null)
81
					throw new Exception ("EventMonitor has not been started yet");
83
					throw new Exception ("EventMonitor has not been started yet");
(-)UiaAtkBridge/Test/AtkTest/TestBase.cs (+130 lines)
Line 0 Link Here
1
// Permission is hereby granted, free of charge, to any person obtaining 
2
// a copy of this software and associated documentation files (the 
3
// "Software"), to deal in the Software without restriction, including 
4
// without limitation the rights to use, copy, modify, merge, publish, 
5
// distribute, sublicense, and/or sell copies of the Software, and to 
6
// permit persons to whom the Software is furnished to do so, subject to 
7
// the following conditions: 
8
//  
9
// The above copyright notice and this permission notice shall be 
10
// included in all copies or substantial portions of the Software. 
11
//  
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
13
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
14
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
15
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
16
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
17
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
18
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
19
// 
20
// Copyright (c) 2008,2009 Novell, Inc. (http://www.novell.com) 
21
// 
22
// Authors: 
23
//      Andres G. Aragoneses <aaragoneses@novell.com>
24
// 
25
26
using System;
27
using System.Xml;
28
29
using System.Collections.Generic;
30
31
using NUnit.Framework;
32
33
namespace UiaAtkBridgeTest
34
{
35
	
36
	public abstract class TestBase {
37
38
		private EventCollection events = null;
39
40
		public static void GlibSync ()
41
		{
42
			System.Threading.AutoResetEvent sync = new System.Threading.AutoResetEvent (false);
43
			GLib.Timeout.Add (0, new GLib.TimeoutHandler (delegate {
44
				sync.Set ();
45
				return false;
46
			}));
47
			sync.WaitOne ();
48
			sync.Close ();
49
		}
50
51
		protected void StartEventMonitor ()
52
		{
53
			events = null;
54
			EventMonitor.Start ();
55
		}
56
57
		protected void ExpectEvents (int count, Atk.Role role, string evType)
58
		{
59
			if (events == null)
60
				events = EventMonitor.Pause ();
61
			EventCollection evs = events.FindByRole (role).FindByType (evType);
62
			string eventsInXml = String.Format (" events in XML: {0}", Environment.NewLine + events.OriginalGrossXml);
63
			Assert.AreEqual (count, evs.Count, "bad number of " + evType + " events: " + eventsInXml);
64
		}
65
66
		protected void ExpectEvents (int count, Atk.Role role, string evType, int detail1)
67
		{
68
			GlibSync ();
69
			if (events == null)
70
				events = EventMonitor.Pause ();
71
			EventCollection evs = events.FindByRole (role).FindByType (evType).FindWithDetail1 (detail1.ToString ());
72
			string eventsInXml = String.Format (" events in XML: {0}", Environment.NewLine + events.OriginalGrossXml);
73
			Assert.AreEqual (count, evs.Count, "bad number of " + evType + " events: " + eventsInXml);
74
		}
75
76
		protected void ExpectEvents (int count, Atk.Role role, string evType, string name)
77
		{
78
			GlibSync ();
79
			if (events == null)
80
				events = EventMonitor.Pause ();
81
			EventCollection evs = events.FindByRole (role).FindByType (evType).FindByName (name);
82
			string eventsInXml = String.Format (" events in XML: {0}", Environment.NewLine + events.OriginalGrossXml);
83
			Assert.AreEqual (count, evs.Count, "bad number of " + evType + " events: " + eventsInXml);
84
		}
85
86
		protected void ExpectEvents (int min, int max, Atk.Role role, string evType)
87
		{
88
			GlibSync ();
89
			if (events == null)
90
				events = EventMonitor.Pause ();
91
			EventCollection evs = events.FindByRole (role).FindByType (evType);
92
			string eventsInXml = String.Format (" events in XML: {0}", Environment.NewLine + events.OriginalGrossXml);
93
			Assert.IsTrue (evs.Count >= min && evs.Count <= max, "Expected " + min +"-" + max +" " + evType + " events but got " + evs.Count +": " + eventsInXml);
94
		}
95
96
		public static void States (Atk.Object accessible, params Atk.StateType [] expected)
97
		{
98
			List <Atk.StateType> expectedStates = new List <Atk.StateType> (expected);
99
			List <Atk.StateType> missingStates = new List <Atk.StateType> ();
100
			List <Atk.StateType> superfluousStates = new List <Atk.StateType> ();
101
			
102
			Atk.StateSet stateSet = accessible.RefStateSet ();
103
			foreach (Atk.StateType state in Enum.GetValues (typeof (Atk.StateType))) {
104
				if (expectedStates.Contains (state) && 
105
				    (!(stateSet.ContainsState (state))))
106
					missingStates.Add (state);
107
				else if ((!expectedStates.Contains (state)) && 
108
					     (stateSet.ContainsState (state)))
109
					superfluousStates.Add (state);
110
			}
111
112
			string missingStatesMsg = string.Empty;
113
			string superfluousStatesMsg = string.Empty;
114
115
			if (missingStates.Count != 0) {
116
				missingStatesMsg = "Missing states: ";
117
				foreach (Atk.StateType state in missingStates)
118
					missingStatesMsg += state.ToString () + ",";
119
			}
120
			if (superfluousStates.Count != 0) {
121
				superfluousStatesMsg = "Superfluous states: ";
122
				foreach (Atk.StateType state in superfluousStates)
123
					superfluousStatesMsg += state.ToString () + ",";
124
			}
125
			Assert.IsTrue ((missingStates.Count == 0) && (superfluousStates.Count == 0),
126
				missingStatesMsg + " .. " + superfluousStatesMsg);
127
		}
128
129
	}
130
}
(-)UiaAtkBridge/Test/UiaAtkBridgeTest/BridgeTests.cs (+6 lines)
Lines 289-294 Link Here
289
			Assert.IsNotNull (accessible, "Adapter should not be null");
289
			Assert.IsNotNull (accessible, "Adapter should not be null");
290
			// 2 groups
290
			// 2 groups
291
			Assert.AreEqual (2, accessible.NAccessibleChildren, "NAccessibleChildren #1");
291
			Assert.AreEqual (2, accessible.NAccessibleChildren, "NAccessibleChildren #1");
292
			GlibSync ();
292
			Atk.Object group1 = FindObjectByName (accessible, groupName);
293
			Atk.Object group1 = FindObjectByName (accessible, groupName);
293
			Assert.IsNotNull (group1, "FindObjectByName (" + groupName + ")");
294
			Assert.IsNotNull (group1, "FindObjectByName (" + groupName + ")");
294
			Assert.AreEqual (Atk.Role.LayeredPane, group1.Role, "Group1 role");
295
			Assert.AreEqual (Atk.Role.LayeredPane, group1.Role, "Group1 role");
Lines 366-371 Link Here
366
			Assert.AreEqual ("item2", atkTable.RefAt (row2, col2).Name, "Cell ("+row2+", " +col2 + ")");
367
			Assert.AreEqual ("item2", atkTable.RefAt (row2, col2).Name, "Cell ("+row2+", " +col2 + ")");
367
			row2 = (atkTable.NRows == 4? 2: 1);
368
			row2 = (atkTable.NRows == 4? 2: 1);
368
			col2 = 0;
369
			col2 = 0;
370
			GlibSync ();
369
			Assert.AreEqual ("item3", atkTable.RefAt (row2, col2).Name, "Cell ("+row2+", " +col2 + ")");
371
			Assert.AreEqual ("item3", atkTable.RefAt (row2, col2).Name, "Cell ("+row2+", " +col2 + ")");
370
			row2 = (atkTable.NRows == 4? 3: 1);
372
			row2 = (atkTable.NRows == 4? 3: 1);
371
			col2 = (atkTable.NRows == 4? 0: 1);
373
			col2 = (atkTable.NRows == 4? 0: 1);
Lines 518-523 Link Here
518
			Assert.AreEqual (3, accessible.NAccessibleChildren, "NAccessibleChildren");
520
			Assert.AreEqual (3, accessible.NAccessibleChildren, "NAccessibleChildren");
519
521
520
			Atk.Object cell = accessible.RefAccessibleChild (2);
522
			Atk.Object cell = accessible.RefAccessibleChild (2);
523
			GlibSync ();
521
			Assert.AreEqual (Atk.Role.TableCell, cell.Role, "cell Role");
524
			Assert.AreEqual (Atk.Role.TableCell, cell.Role, "cell Role");
522
525
523
			// Calling Focus on the DataGrid appears not to work.
526
			// Calling Focus on the DataGrid appears not to work.
Lines 632-637 Link Here
632
			Assert.AreEqual (3, accessible.NAccessibleChildren, "NAccessibleChildren #1");
635
			Assert.AreEqual (3, accessible.NAccessibleChildren, "NAccessibleChildren #1");
633
			
636
			
634
			Atk.Object child1 = accessible.RefAccessibleChild (0);
637
			Atk.Object child1 = accessible.RefAccessibleChild (0);
638
			GlibSync ();
635
			Assert.AreEqual (Atk.Role.Label, child1.Role, "Child role #1");
639
			Assert.AreEqual (Atk.Role.Label, child1.Role, "Child role #1");
636
			InterfaceText (child1, "first item");
640
			InterfaceText (child1, "first item");
637
			
641
			
Lines 885-890 Link Here
885
			InterfaceComponent (type, atkComponent);
889
			InterfaceComponent (type, atkComponent);
886
890
887
			Assert.AreEqual (panel.NAccessibleChildren, 0, "StatusBar panel should not have children");
891
			Assert.AreEqual (panel.NAccessibleChildren, 0, "StatusBar panel should not have children");
892
			GlibSync ();
888
			Assert.AreEqual (panelText, panel.Name, "Panel name should match the text");
893
			Assert.AreEqual (panelText, panel.Name, "Panel name should match the text");
889
			InterfaceText (panel, panelText);
894
			InterfaceText (panel, panelText);
890
895
Lines 1173-1178 Link Here
1173
			lab.IsLink = true;
1178
			lab.IsLink = true;
1174
			toolStrip.Items.Add (lab);
1179
			toolStrip.Items.Add (lab);
1175
			Atk.Object accessible = GetAdapterForWidget (lab);
1180
			Atk.Object accessible = GetAdapterForWidget (lab);
1181
			GlibSync ();
1176
			Assert.AreEqual (Atk.Role.Label, accessible.Role, "A ToolStripLabel with IsLink==True should not have an unknown role");
1182
			Assert.AreEqual (Atk.Role.Label, accessible.Role, "A ToolStripLabel with IsLink==True should not have an unknown role");
1177
			toolStrip.Items.Remove (lab);
1183
			toolStrip.Items.Remove (lab);
1178
		}
1184
		}
(-)UiaAtkBridge/Test/UiaAtkBridgeTest/BridgeTester.cs (+3 lines)
Lines 684-689 Link Here
684
					type.ToString ());
684
					type.ToString ());
685
			}
685
			}
686
686
687
			GlibSync ();
687
			return accessible;
688
			return accessible;
688
		}
689
		}
689
		
690
		
Lines 1012-1017 Link Here
1012
					type.ToString ());
1013
					type.ToString ());
1013
			}
1014
			}
1014
1015
1016
			GlibSync ();
1015
			return accessible;
1017
			return accessible;
1016
		}
1018
		}
1017
1019
Lines 1053-1058 Link Here
1053
				contextMenu.Show (lab1, 0, 0);
1055
				contextMenu.Show (lab1, 0, 0);
1054
				widget = contextMenu;
1056
				widget = contextMenu;
1055
			}
1057
			}
1058
			GlibSync ();
1056
			return GetAdapterForWidget (widget);
1059
			return GetAdapterForWidget (widget);
1057
		}
1060
		}
1058
1061
(-)UiaAtkBridge/Test/UiaAtkBridgeTest/DialogTester.cs (-2 / +3 lines)
Lines 32-38 Link Here
32
{
32
{
33
33
34
	[TestFixture]
34
	[TestFixture]
35
	public class DialogTester {
35
	public class DialogTester : TestBase {
36
36
37
		[Test]
37
		[Test]
38
		public void OpenFileDialog ()
38
		public void OpenFileDialog ()
Lines 47-53 Link Here
47
				Assert.AreEqual (5, popupButtonPanelAdapter.NAccessibleChildren, "PopupButtonPanel (toolbar) should have 5 children");
47
				Assert.AreEqual (5, popupButtonPanelAdapter.NAccessibleChildren, "PopupButtonPanel (toolbar) should have 5 children");
48
48
49
				Atk.Object popupButtonAdapter1 = popupButtonPanelAdapter.RefAccessibleChild (0).RefAccessibleChild (0);
49
				Atk.Object popupButtonAdapter1 = popupButtonPanelAdapter.RefAccessibleChild (0).RefAccessibleChild (0);
50
				AtkTester.States (popupButtonAdapter1,
50
				States (popupButtonAdapter1,
51
				                  Atk.StateType.Enabled,
51
				                  Atk.StateType.Enabled,
52
				                  Atk.StateType.Selectable,
52
				                  Atk.StateType.Selectable,
53
				                  Atk.StateType.Focusable,
53
				                  Atk.StateType.Focusable,
Lines 67-72 Link Here
67
				//Assert.AreEqual ("invoke", atkAction.GetName (1), "TableCell Action.GetName (1)");
67
				//Assert.AreEqual ("invoke", atkAction.GetName (1), "TableCell Action.GetName (1)");
68
68
69
				Atk.Object comboBox = dialogAdapter.RefAccessibleChild (8);
69
				Atk.Object comboBox = dialogAdapter.RefAccessibleChild (8);
70
				GlibSync ();
70
				Assert.AreEqual (Atk.Role.ComboBox, comboBox.Role, "ComboBox Role");
71
				Assert.AreEqual (Atk.Role.ComboBox, comboBox.Role, "ComboBox Role");
71
				Atk.Object list = comboBox.RefAccessibleChild (0);
72
				Atk.Object list = comboBox.RefAccessibleChild (0);
72
				Assert.IsTrue (list.NAccessibleChildren > 0, "ComboBox child should have children");
73
				Assert.IsTrue (list.NAccessibleChildren > 0, "ComboBox child should have children");
(-)UiaAtkBridge/UiaAtkBridge/Button.cs (-4 / +2 lines)
Lines 234-245 Link Here
234
			if (fromCtor)
234
			if (fromCtor)
235
				return;
235
				return;
236
236
237
			Atk.TextAdapter adapter = new Atk.TextAdapter (this);
238
239
			// First delete all text, then insert the new text
237
			// First delete all text, then insert the new text
240
			adapter.EmitTextChanged (Atk.TextChangedDetail.Delete, 0, textExpert.Length);
238
			textExpert.EmitTextChanged (Atk.TextChangedDetail.Delete, 0, textExpert.Length);
241
239
242
			adapter.EmitTextChanged (Atk.TextChangedDetail.Insert, 0,
240
			textExpert.EmitTextChanged (Atk.TextChangedDetail.Insert, 0,
243
						 newName == null ? 0 : newName.Length);
241
						 newName == null ? 0 : newName.Length);
244
			EmitVisibleDataChanged ();
242
			EmitVisibleDataChanged ();
245
		}
243
		}
(-)UiaAtkBridge/UiaAtkBridge/Spinner.cs (-4 / +2 lines)
Lines 287-298 Link Here
287
			if (textExpert.HandleSimpleChange (ref oldText, ref caretOffset))
287
			if (textExpert.HandleSimpleChange (ref oldText, ref caretOffset))
288
				return;
288
				return;
289
289
290
			Atk.TextAdapter adapter = new Atk.TextAdapter (this);
291
292
			// First delete all text, then insert the new text
290
			// First delete all text, then insert the new text
293
			adapter.EmitTextChanged (Atk.TextChangedDetail.Delete, 0, oldText.Length);
291
			textExpert.EmitTextChanged (Atk.TextChangedDetail.Delete, 0, oldText.Length, oldText);
294
292
295
			adapter.EmitTextChanged (Atk.TextChangedDetail.Insert, 0,
293
			textExpert.EmitTextChanged (Atk.TextChangedDetail.Insert, 0,
296
				                 newText == null ? 0 : newText.Length);
294
				                 newText == null ? 0 : newText.Length);
297
			oldText = newText;
295
			oldText = newText;
298
		}
296
		}
(-)UiaAtkBridge/UiaAtkBridge/ParentAdapter.cs (-1 / +10 lines)
Lines 98-104 Link Here
98
			}
98
			}
99
			//we may want that a child has 2 parents
99
			//we may want that a child has 2 parents
100
			if (child.Parent == null)
100
			if (child.Parent == null)
101
				child.Parent = this;
101
				SetParent (child, this);
102
			EmitChildrenChanged (Atk.Object.ChildrenChangedDetail.Add, (uint)(children.Count - 1), child);
102
			EmitChildrenChanged (Atk.Object.ChildrenChangedDetail.Add, (uint)(children.Count - 1), child);
103
			Adapter adapter = child as Adapter;
103
			Adapter adapter = child as Adapter;
104
			if (adapter != null)
104
			if (adapter != null)
Lines 169-174 Link Here
169
				RequestChildren ();
169
				RequestChildren ();
170
			}
170
			}
171
		}
171
		}
172
173
		protected new void EmitChildrenChanged (ChildrenChangedDetail detail, uint child_index, Atk.Object child)
174
		{
175
			GLib.Timeout.Add (0, new GLib.TimeoutHandler (delegate {
176
			base.EmitChildrenChanged (detail, child_index, child);
177
				return false;
178
			}));
179
		}
180
			
172
#endregion
181
#endregion
173
182
174
		public override void RaiseAutomationEvent (AutomationEvent eventId, AutomationEventArgs args)
183
		public override void RaiseAutomationEvent (AutomationEvent eventId, AutomationEventArgs args)
(-)UiaAtkBridge/UiaAtkBridge/BaseTextImplementor.cs (-11 / +31 lines)
Lines 303-309 Link Here
303
303
304
		public string GetText (int startOffset, int endOffset)
304
		public string GetText (int startOffset, int endOffset)
305
		{
305
		{
306
			string text = (deleteHack != null? deleteHack: Text);
306
			if (cachedText != null && cachedTextStart == startOffset && cachedTextEnd == endOffset)
307
				return cachedText;
308
			string text = Text;
307
			if ((endOffset == -1) || (endOffset > text.Length))
309
			if ((endOffset == -1) || (endOffset > text.Length))
308
				endOffset = text.Length;
310
				endOffset = text.Length;
309
			if (endOffset < startOffset)
311
			if (endOffset < startOffset)
Lines 377-387 Link Here
377
			int offset;
379
			int offset;
378
			if (newLength > oldLength) {
380
			if (newLength > oldLength) {
379
				if (IsAddition (text, oldText, out offset)) {
381
				if (IsAddition (text, oldText, out offset)) {
380
					Atk.TextAdapter adapter = new Atk.TextAdapter ((Atk.TextImplementor)resource);
382
					EmitTextChanged (Atk.TextChangedDetail.Insert, offset, newLength - oldLength);
381
					adapter.EmitTextChanged (Atk.TextChangedDetail.Insert, offset, newLength - oldLength);
382
					if (updateCaret) {
383
					if (updateCaret) {
383
						caretOffset = offset + (newLength - oldLength);
384
						caretOffset = offset + (newLength - oldLength);
384
						GLib.Signal.Emit (resource, "text_caret_moved", caretOffset);
385
						resource.EmitSignal ("text_caret_moved", caretOffset);
385
					}
386
					}
386
					oldText = text;
387
					oldText = text;
387
					return true;
388
					return true;
Lines 389-403 Link Here
389
			}
390
			}
390
			else if (oldLength > newLength) {
391
			else if (oldLength > newLength) {
391
				if (IsAddition (oldText, text, out offset)) {
392
				if (IsAddition (oldText, text, out offset)) {
392
					Atk.TextAdapter adapter = new Atk.TextAdapter ((Atk.TextImplementor)resource);
393
					// Atk-bridge expects the text not to
393
					// Atk-bridge expects the text not to
394
					// have been deleted yet
394
					// have been deleted yet
395
					deleteHack = oldText;
395
					EmitTextChanged (Atk.TextChangedDetail.Delete, offset, oldLength - newLength, oldText);
396
					adapter.EmitTextChanged (Atk.TextChangedDetail.Delete, offset, oldLength - newLength);
397
					deleteHack = null;
398
					if (updateCaret) {
396
					if (updateCaret) {
399
						caretOffset = offset;
397
						caretOffset = offset;
400
						GLib.Signal.Emit (resource, "text_caret_moved", caretOffset);
398
						resource.EmitSignal ("text_caret_moved", caretOffset);
401
					}
399
					}
402
					oldText = text;
400
					oldText = text;
403
					return true;
401
					return true;
Lines 435-447 Link Here
435
				int newCaretOffset = caretProvider.CaretOffset;
433
				int newCaretOffset = caretProvider.CaretOffset;
436
				if (newCaretOffset != caretOffset) {
434
				if (newCaretOffset != caretOffset) {
437
					caretOffset = newCaretOffset;
435
					caretOffset = newCaretOffset;
438
					GLib.Signal.Emit (resource, "text_caret_moved", caretOffset);
436
					resource.EmitSignal ("text_caret_moved", caretOffset);
439
				}
437
				}
440
				return true;
438
				return true;
441
			}
439
			}
442
				
440
				
443
			return false;
441
			return false;
444
		}
442
		}
443
444
		public void EmitTextChanged (Atk.TextChangedDetail detail, int position, int length)
445
		{
446
			EmitTextChanged (detail, position, length, null);
447
		}
448
449
		public void EmitTextChanged (Atk.TextChangedDetail detail, int position, int length, string curText)
450
		{
451
			if (curText == null)
452
				curText = Text;
453
			GLib.Timeout.Add (0, new GLib.TimeoutHandler (delegate {
454
				cachedText = curText.Substring (position, length);
455
				cachedTextStart = position;
456
				cachedTextEnd = position + length;
457
				GLib.Signal.Emit (resource, "text_changed::" + detail.ToString ().ToLower (),
458
					position, length);
459
				cachedText = null;
460
				return false;
461
			}));
462
		}
445
#endregion
463
#endregion
446
464
447
#region Protected Fields
465
#region Protected Fields
Lines 633-639 Link Here
633
651
634
		private ICaretProvider caretProvider;
652
		private ICaretProvider caretProvider;
635
		private int caretOffset;
653
		private int caretOffset;
636
		private string deleteHack = null;
654
		private string cachedText = null;
655
		private int cachedTextStart = 0;
656
		private int cachedTextEnd = 0;
637
#endregion
657
#endregion
638
	}
658
	}
639
}
659
}
(-)UiaAtkBridge/UiaAtkBridge/Tree.cs (-2 / +2 lines)
Lines 214-220 Link Here
214
				// it is excessively verbose.
214
				// it is excessively verbose.
215
				if (!CanSelectMultiple)
215
				if (!CanSelectMultiple)
216
					NotifyItemSelected (item);
216
					NotifyItemSelected (item);
217
				GLib.Signal.Emit (this, "active-descendant-changed", item.Handle);
217
				EmitSignal ("active-descendant-changed", item.Handle);
218
			}
218
			}
219
			hasFocus = listFocused;
219
			hasFocus = listFocused;
220
		}
220
		}
Lines 419-425 Link Here
419
				if (IsListItem (child))
419
				if (IsListItem (child))
420
					rowCount++;
420
					rowCount++;
421
			if (rowCount > 0) {
421
			if (rowCount > 0) {
422
				GLib.Signal.Emit (this, (expanded? "row-inserted": "row-deleted"), row + 1, rowCount);
422
				EmitSignal ((expanded? "row-inserted": "row-deleted"), row + 1, rowCount);
423
				EmitVisibleDataChanged ();
423
				EmitVisibleDataChanged ();
424
			}
424
			}
425
		}
425
		}
(-)UiaAtkBridge/UiaAtkBridge/List.cs (-2 / +2 lines)
Lines 189-195 Link Here
189
					Atk.Focus.TrackerNotify (this);
189
					Atk.Focus.TrackerNotify (this);
190
			}
190
			}
191
			if (itemFocused)
191
			if (itemFocused)
192
				GLib.Signal.Emit (this, "active-descendant-changed", item.Handle);
192
				EmitSignal ("active-descendant-changed", item.Handle);
193
			hasFocus = listFocused;
193
			hasFocus = listFocused;
194
		}
194
		}
195
195
Lines 294-301 Link Here
294
				throw new ArgumentException ("Provider does not implement IValue");
294
				throw new ArgumentException ("Provider does not implement IValue");
295
			}
295
			}
296
296
297
			editableTextExpert = new EditableTextImplementorHelper (this, this);
298
			text_helper = TextImplementorFactory.GetImplementor (this, provider);
297
			text_helper = TextImplementorFactory.GetImplementor (this, provider);
298
			editableTextExpert = new EditableTextImplementorHelper (this, this, text_helper);
299
		}
299
		}
300
300
301
		protected override Atk.StateSet OnRefStateSet ()
301
		protected override Atk.StateSet OnRefStateSet ()
(-)UiaAtkBridge/UiaAtkBridge/TextLabel.cs (-4 / +2 lines)
Lines 80-91 Link Here
80
			if (fromCtor)
80
			if (fromCtor)
81
				return;
81
				return;
82
82
83
			Atk.TextAdapter adapter = new Atk.TextAdapter (this);
84
85
			// First delete all text, then insert the new text
83
			// First delete all text, then insert the new text
86
			adapter.EmitTextChanged (Atk.TextChangedDetail.Delete, 0, textExpert.Length);
84
			textExpert.EmitTextChanged (Atk.TextChangedDetail.Delete, 0, textExpert.Length);
87
85
88
			adapter.EmitTextChanged (Atk.TextChangedDetail.Insert, 0,
86
			textExpert.EmitTextChanged (Atk.TextChangedDetail.Insert, 0,
89
						 newName == null ? 0 : newName.Length);
87
						 newName == null ? 0 : newName.Length);
90
88
91
			EmitVisibleDataChanged ();
89
			EmitVisibleDataChanged ();
(-)UiaAtkBridge/UiaAtkBridge/TextContainer.cs (-4 / +2 lines)
Lines 172-183 Link Here
172
			if (fromCtor)
172
			if (fromCtor)
173
				return;
173
				return;
174
174
175
			Atk.TextAdapter adapter = new Atk.TextAdapter (this);
176
177
			// First delete all text, then insert the new text
175
			// First delete all text, then insert the new text
178
			adapter.EmitTextChanged (Atk.TextChangedDetail.Delete, 0, textExpert.Length);
176
		textExpert.EmitTextChanged (Atk.TextChangedDetail.Delete, 0, textExpert.Length);
179
177
180
			adapter.EmitTextChanged (Atk.TextChangedDetail.Insert, 0,
178
			textExpert.EmitTextChanged (Atk.TextChangedDetail.Insert, 0,
181
						 newName == null ? 0 : newName.Length);
179
						 newName == null ? 0 : newName.Length);
182
180
183
			EmitVisibleDataChanged ();
181
			EmitVisibleDataChanged ();
(-)UiaAtkBridge/UiaAtkBridge/Monitor.cs (-3 / +8 lines)
Lines 124-132 Link Here
124
				return;
124
				return;
125
			}
125
			}
126
126
127
			Thread glibThread = new Thread (new ThreadStart (GLibMainLoopThread));
127
			CheckMainLoop ();
128
			glibThread.IsBackground = true;
129
			glibThread.Start ();
130
			AutoResetEvent sync = GLibHacks.Invoke (delegate (object sender, EventArgs args) {
128
			AutoResetEvent sync = GLibHacks.Invoke (delegate (object sender, EventArgs args) {
131
				Environment.SetEnvironmentVariable (ATK_BRIDGE_ENVVAR_NAME, null);
129
				Environment.SetEnvironmentVariable (ATK_BRIDGE_ENVVAR_NAME, null);
132
				LaunchAtkBridge ();
130
				LaunchAtkBridge ();
Lines 139-144 Link Here
139
			Environment.SetEnvironmentVariable (GTK_MODULES_ENVVAR_NAME, gtk_modules_envvar_content);
137
			Environment.SetEnvironmentVariable (GTK_MODULES_ENVVAR_NAME, gtk_modules_envvar_content);
140
		}
138
		}
141
		
139
		
140
		public void CheckMainLoop ()
141
		{
142
			Thread glibThread = new Thread (new ThreadStart (GLibMainLoopThread));
143
			glibThread.IsBackground = true;
144
			glibThread.Start ();
145
		}
146
142
		private void GLibMainLoopThread ()
147
		private void GLibMainLoopThread ()
143
		{
148
		{
144
			mainLoop = new GLib.MainLoop ();
149
			mainLoop = new GLib.MainLoop ();
(-)UiaAtkBridge/UiaAtkBridge/Table.cs (-3 / +3 lines)
Lines 43-49 Link Here
43
		public override void RaiseAutomationEvent (AutomationEvent eventId, AutomationEventArgs e)
43
		public override void RaiseAutomationEvent (AutomationEvent eventId, AutomationEventArgs e)
44
		{
44
		{
45
			if (eventId == GridPatternIdentifiers.ColumnReorderedEvent)
45
			if (eventId == GridPatternIdentifiers.ColumnReorderedEvent)
46
				GLib.Signal.Emit (this, "column_reordered");
46
				EmitSignal ("column_reordered");
47
			else
47
			else
48
				base.RaiseAutomationEvent (eventId, e);
48
				base.RaiseAutomationEvent (eventId, e);
49
			// TODO
49
			// TODO
Lines 214-221 Link Here
214
214
215
		internal void EmitRowReorderingSignal ()
215
		internal void EmitRowReorderingSignal ()
216
		{
216
		{
217
			GLib.Signal.Emit (this, "row-reordered");
217
			EmitSignal ("row-reordered");
218
			GLib.Signal.Emit (this, "visible-data-changed");
218
			EmitVisibleDataChanged ();
219
		}
219
		}
220
220
221
		protected override Atk.StateSet OnRefStateSet ()
221
		protected override Atk.StateSet OnRefStateSet ()
(-)UiaAtkBridge/UiaAtkBridge/EditableTextImplementorHelper.cs (-13 / +11 lines)
Lines 35-50 Link Here
35
	internal class EditableTextImplementorHelper
35
	internal class EditableTextImplementorHelper
36
	{
36
	{
37
		
37
		
38
		public EditableTextImplementorHelper (Adapter adapter, Atk.TextImplementor textImplementor)
38
		public EditableTextImplementorHelper (Adapter adapter, Atk.TextImplementor textImplementor, ITextImplementor textExpert)
39
		{
39
		{
40
			this.adapter = adapter;
40
			this.adapter = adapter;
41
			this.textImplementor = textImplementor;
42
41
43
			valueProvider 
42
			valueProvider 
44
				= adapter.Provider.GetPatternProvider (ValuePatternIdentifiers.Pattern.Id)
43
				= adapter.Provider.GetPatternProvider (ValuePatternIdentifiers.Pattern.Id)
45
					as IValueProvider;
44
					as IValueProvider;
46
45
47
			textExpert = TextImplementorFactory.GetImplementor (adapter, adapter.Provider);
46
			this.textExpert = textExpert;
48
47
49
			if (valueProvider != null)
48
			if (valueProvider != null)
50
				editable = !valueProvider.IsReadOnly;
49
				editable = !valueProvider.IsReadOnly;
Lines 251-274 Link Here
251
				                                   false))
250
				                                   false))
252
					return true;
251
					return true;
253
252
254
				Atk.TextAdapter textAdapter = new Atk.TextAdapter (textImplementor);
255
				string newText = textExpert.Text;
253
				string newText = textExpert.Text;
256
254
257
				// First delete all text, then insert the new text
255
				// First delete all text, then insert the new text
258
				textAdapter.EmitTextChanged (Atk.TextChangedDetail.Delete, 
256
				textExpert.EmitTextChanged (Atk.TextChangedDetail.Delete, 
259
				                             0, 
257
				                            0, 
260
				                             oldText.Length);
258
				                            oldText.Length,
259
				                            oldText);
261
260
262
				textAdapter.EmitTextChanged (Atk.TextChangedDetail.Insert, 
261
				textExpert.EmitTextChanged (Atk.TextChangedDetail.Insert, 
263
				                             0,
262
				                            0,
264
				                             newText == null ? 0 : newText.Length);
263
				                            newText == null ? 0 : newText.Length);
265
264
266
				if (caretProvider == null)
265
				if (caretProvider == null)
267
					caretOffset = textExpert.Length;
266
					caretOffset = textExpert.Length;
268
267
269
				oldText = newText;
268
				oldText = newText;
270
269
271
				GLib.Signal.Emit (adapter, "visible-data-changed");
270
				adapter.EmitVisibleDataChanged ();
272
271
273
				return true;
272
				return true;
274
			} else if (e.Property.Id == ValuePatternIdentifiers.IsReadOnlyProperty.Id) {
273
			} else if (e.Property.Id == ValuePatternIdentifiers.IsReadOnlyProperty.Id) {
Lines 293-299 Link Here
293
292
294
				return true;
293
				return true;
295
			} else if (eventId == TextPatternIdentifiers.TextSelectionChangedEvent) {
294
			} else if (eventId == TextPatternIdentifiers.TextSelectionChangedEvent) {
296
				GLib.Signal.Emit (adapter, "text_selection_changed");
295
				adapter.EmitSignal ("text_selection_changed");
297
				return true;
296
				return true;
298
			} 
297
			} 
299
			
298
			
Lines 320-326 Link Here
320
		private bool editable;
319
		private bool editable;
321
		private string oldText;
320
		private string oldText;
322
		private ITextImplementor textExpert;		
321
		private ITextImplementor textExpert;		
323
		private Atk.TextImplementor textImplementor;
324
		private IValueProvider valueProvider;
322
		private IValueProvider valueProvider;
325
		private IInsertDeleteTextProvider insertDeleteProvider;
323
		private IInsertDeleteTextProvider insertDeleteProvider;
326
324
(-)UiaAtkBridge/UiaAtkBridge/Menu.cs (-3 / +2 lines)
Lines 147-157 Link Here
147
				if (changed_selected_child) {
147
				if (changed_selected_child) {
148
					Atk.SelectionImplementor selImplementor = this as Atk.SelectionImplementor;
148
					Atk.SelectionImplementor selImplementor = this as Atk.SelectionImplementor;
149
					if (selImplementor != null) {
149
					if (selImplementor != null) {
150
						var sel_adapter = new Atk.SelectionAdapter (selImplementor);
151
						if (any_child_was_selected)
150
						if (any_child_was_selected)
152
							//2 times: because we deselect a child and select another one
151
							//2 times: because we deselect a child and select another one
153
							sel_adapter.EmitSelectionChanged ();
152
							EmitSelectionChanged ();
154
						sel_adapter.EmitSelectionChanged ();
153
						EmitSelectionChanged ();
155
					}
154
					}
156
				}
155
				}
157
			}
156
			}
(-)UiaAtkBridge/UiaAtkBridge/Tab.cs (-1 / +1 lines)
Lines 61-67 Link Here
61
		public override void RaiseAutomationPropertyChangedEvent (AutomationPropertyChangedEventArgs e)
61
		public override void RaiseAutomationPropertyChangedEvent (AutomationPropertyChangedEventArgs e)
62
		{
62
		{
63
			if (e.Property == SelectionPatternIdentifiers.SelectionProperty) {
63
			if (e.Property == SelectionPatternIdentifiers.SelectionProperty) {
64
				GLib.Signal.Emit (this, "selection_changed");
64
				EmitSignal ("selection_changed");
65
				EmitVisibleDataChanged ();
65
				EmitVisibleDataChanged ();
66
			} else
66
			} else
67
				base.RaiseAutomationPropertyChangedEvent (e);
67
				base.RaiseAutomationPropertyChangedEvent (e);
(-)UiaAtkBridge/UiaAtkBridge/TreeItem.cs (-4 / +4 lines)
Lines 72-78 Link Here
72
			Role = (ToggleProvider != null? Atk.Role.CheckBox: Atk.Role.TableCell);
72
			Role = (ToggleProvider != null? Atk.Role.CheckBox: Atk.Role.TableCell);
73
73
74
			imageExpert = new ImageImplementorHelper (this);
74
			imageExpert = new ImageImplementorHelper (this);
75
			editableTextExpert = new EditableTextImplementorHelper (this, this);
75
			editableTextExpert = new EditableTextImplementorHelper (this, this, textExpert);
76
		}
76
		}
77
		
77
		
78
		protected IToggleProvider ToggleProvider {
78
		protected IToggleProvider ToggleProvider {
Lines 216-227 Link Here
216
				if (list != null)
216
				if (list != null)
217
					list.NotifyItemSelected (this);
217
					list.NotifyItemSelected (this);
218
				else
218
				else
219
				NotifyStateChange ((ulong) Atk.StateType.Selected, true);
219
				NotifyStateChange (Atk.StateType.Selected, true);
220
			}
220
			}
221
			else if (eventId == SelectionItemPatternIdentifiers.ElementAddedToSelectionEvent)
221
			else if (eventId == SelectionItemPatternIdentifiers.ElementAddedToSelectionEvent)
222
				NotifyStateChange ((ulong) Atk.StateType.Selected, true);
222
				NotifyStateChange (Atk.StateType.Selected, true);
223
			else if (eventId == SelectionItemPatternIdentifiers.ElementRemovedFromSelectionEvent) {
223
			else if (eventId == SelectionItemPatternIdentifiers.ElementRemovedFromSelectionEvent) {
224
				NotifyStateChange ((ulong) Atk.StateType.Selected, false);
224
				NotifyStateChange (Atk.StateType.Selected, false);
225
				Tree list = Parent as Tree;
225
				Tree list = Parent as Tree;
226
				if (list != null)
226
				if (list != null)
227
					list.NotifyItemSelectionRemoved (this);
227
					list.NotifyItemSelectionRemoved (this);
(-)UiaAtkBridge/UiaAtkBridge/Slider.cs (-4 / +2 lines)
Lines 236-247 Link Here
236
			if (textExpert.HandleSimpleChange (ref oldText, ref caretOffset))
236
			if (textExpert.HandleSimpleChange (ref oldText, ref caretOffset))
237
				return;
237
				return;
238
238
239
			Atk.TextAdapter adapter = new Atk.TextAdapter (this);
240
241
			// First delete all text, then insert the new text
239
			// First delete all text, then insert the new text
242
			adapter.EmitTextChanged (Atk.TextChangedDetail.Delete, 0, oldText.Length);
240
			textExpert.EmitTextChanged (Atk.TextChangedDetail.Delete, 0, oldText.Length, oldText);
243
241
244
			adapter.EmitTextChanged (Atk.TextChangedDetail.Insert, 0,
242
			textExpert.EmitTextChanged (Atk.TextChangedDetail.Insert, 0,
245
				                 newText == null ? 0 : newText.Length);
243
				                 newText == null ? 0 : newText.Length);
246
			oldText = newText;
244
			oldText = newText;
247
		}
245
		}
(-)UiaAtkBridge/UiaAtkBridge/ListItem.cs (-4 / +4 lines)
Lines 54-60 Link Here
54
			textExpert = TextImplementorFactory.GetImplementor (this, provider);
54
			textExpert = TextImplementorFactory.GetImplementor (this, provider);
55
			imageExpert = new ImageImplementorHelper (this);
55
			imageExpert = new ImageImplementorHelper (this);
56
			actionExpert = new ActionImplementorHelper ();
56
			actionExpert = new ActionImplementorHelper ();
57
			editableTextExpert = new EditableTextImplementorHelper (this, this);
57
			editableTextExpert = new EditableTextImplementorHelper (this, this, textExpert);
58
58
59
			// TODO: Localize the name?s
59
			// TODO: Localize the name?s
60
			actionExpert.Add ("click", "click", null, DoClick);
60
			actionExpert.Add ("click", "click", null, DoClick);
Lines 182-193 Link Here
182
				if (list != null)
182
				if (list != null)
183
					list.NotifyItemSelected (this);
183
					list.NotifyItemSelected (this);
184
				else
184
				else
185
				NotifyStateChange ((ulong) Atk.StateType.Selected, true);
185
				NotifyStateChange (Atk.StateType.Selected, true);
186
			}
186
			}
187
			else if (eventId == SelectionItemPatternIdentifiers.ElementAddedToSelectionEvent)
187
			else if (eventId == SelectionItemPatternIdentifiers.ElementAddedToSelectionEvent)
188
				NotifyStateChange ((ulong) Atk.StateType.Selected, true);
188
				NotifyStateChange (Atk.StateType.Selected, true);
189
			else if (eventId == SelectionItemPatternIdentifiers.ElementRemovedFromSelectionEvent)
189
			else if (eventId == SelectionItemPatternIdentifiers.ElementRemovedFromSelectionEvent)
190
				NotifyStateChange ((ulong) Atk.StateType.Selected, false);
190
				NotifyStateChange (Atk.StateType.Selected, false);
191
		}
191
		}
192
		
192
		
193
		public int CaretOffset {
193
		public int CaretOffset {
(-)UiaAtkBridge/UiaAtkBridge/Hyperlink.cs (-4 / +2 lines)
Lines 100-111 Link Here
100
					return;
100
					return;
101
				}
101
				}
102
102
103
				Atk.TextAdapter adapter = new Atk.TextAdapter (this);
104
105
				// First delete all text, then insert the new text
103
				// First delete all text, then insert the new text
106
				adapter.EmitTextChanged (Atk.TextChangedDetail.Delete, 0, textExpert.Length);
104
				textExpert.EmitTextChanged (Atk.TextChangedDetail.Delete, 0, textExpert.Length);
107
105
108
				adapter.EmitTextChanged (Atk.TextChangedDetail.Insert, 0,
106
				textExpert.EmitTextChanged (Atk.TextChangedDetail.Insert, 0,
109
				                         newText == null ? 0 : newText.Length);
107
				                         newText == null ? 0 : newText.Length);
110
108
111
				// Accessible name and label text are one and
109
				// Accessible name and label text are one and
(-)UiaAtkBridge/UiaAtkBridge/Window.cs (-8 / +8 lines)
Lines 116-134 Link Here
116
				WindowVisualState newValue = (WindowVisualState) e.NewValue;
116
				WindowVisualState newValue = (WindowVisualState) e.NewValue;
117
				
117
				
118
				if (newValue == WindowVisualState.Maximized)
118
				if (newValue == WindowVisualState.Maximized)
119
					GLib.Signal.Emit (this, "maximize");
119
					EmitSignal ("maximize");
120
				else if (newValue == WindowVisualState.Minimized)
120
				else if (newValue == WindowVisualState.Minimized)
121
					GLib.Signal.Emit (this, "minimize");
121
					EmitSignal ("minimize");
122
				else // Back to Normal, so is Restored
122
				else // Back to Normal, so is Restored
123
					GLib.Signal.Emit (this, "restore");
123
					EmitSignal ("restore");
124
			} else if (e.Property == AutomationElementIdentifiers.BoundingRectangleProperty) {
124
			} else if (e.Property == AutomationElementIdentifiers.BoundingRectangleProperty) {
125
				Rect oldValue = (Rect) e.OldValue;
125
				Rect oldValue = (Rect) e.OldValue;
126
				Rect newValue = (Rect) e.NewValue;
126
				Rect newValue = (Rect) e.NewValue;
127
				
127
				
128
				if (oldValue.X != newValue.X || oldValue.Y != newValue.Y)
128
				if (oldValue.X != newValue.X || oldValue.Y != newValue.Y)
129
					GLib.Signal.Emit (this, "move");
129
					EmitSignal ("move");
130
				if (oldValue.Width != newValue.Width || oldValue.Height != newValue.Height)
130
				if (oldValue.Width != newValue.Width || oldValue.Height != newValue.Height)
131
					GLib.Signal.Emit (this, "resize");
131
					EmitSignal ("resize");
132
132
133
				base.RaiseAutomationPropertyChangedEvent (e);
133
				base.RaiseAutomationPropertyChangedEvent (e);
134
			} else
134
			} else
Lines 203-209 Link Here
203
						continue;
203
						continue;
204
					}
204
					}
205
					RemoveChild (obj, false);
205
					RemoveChild (obj, false);
206
					obj.Parent = child;
206
					SetParent (obj, child);
207
					splitter.AddOneChild (obj);
207
					splitter.AddOneChild (obj);
208
					count--;
208
					count--;
209
				}
209
				}
Lines 221-227 Link Here
221
				while (count > 0) {
221
				while (count > 0) {
222
					Atk.Object obj = parentAdapter.RefAccessibleChild (0);
222
					Atk.Object obj = parentAdapter.RefAccessibleChild (0);
223
					parentAdapter.RemoveChild (obj, false);
223
					parentAdapter.RemoveChild (obj, false);
224
					obj.Parent = this;
224
					SetParent (obj, this);
225
					AddOneChild (obj);
225
					AddOneChild (obj);
226
					count--;
226
					count--;
227
				}
227
				}
Lines 235-241 Link Here
235
				return;
235
				return;
236
			this.active = active;
236
			this.active = active;
237
			if (active)
237
			if (active)
238
				GLib.Signal.Emit (this, "activate");
238
				EmitSignal ("activate");
239
			needStateChange = true;
239
			needStateChange = true;
240
		}
240
		}
241
		
241
		
(-)UiaAtkBridge/UiaAtkBridge/ComboBox.cs (-1 / +1 lines)
Lines 167-173 Link Here
167
				name = String.Empty;
167
				name = String.Empty;
168
			
168
			
169
			Name = name;
169
			Name = name;
170
			GLib.Signal.Emit (this, "selection-changed");
170
			EmitSelectionChanged ();
171
		}
171
		}
172
		
172
		
173
		public override void RaiseAutomationEvent (AutomationEvent eventId, AutomationEventArgs e)
173
		public override void RaiseAutomationEvent (AutomationEvent eventId, AutomationEventArgs e)
(-)UiaAtkBridge/UiaAtkBridge/TextBoxEntryView.cs (-2 / +2 lines)
Lines 51-58 Link Here
51
			else
51
			else
52
				Role = Atk.Role.Text;
52
				Role = Atk.Role.Text;
53
53
54
			editableTextExpert = new EditableTextImplementorHelper (this, this);
55
56
			if (provider.GetPatternProvider (TextPatternIdentifiers.Pattern.Id) == null
54
			if (provider.GetPatternProvider (TextPatternIdentifiers.Pattern.Id) == null
57
			    && provider.GetPatternProvider (ValuePatternIdentifiers.Pattern.Id) == null)
55
			    && provider.GetPatternProvider (ValuePatternIdentifiers.Pattern.Id) == null)
58
				throw new ArgumentException ("Provider for TextBox should either implement IValue or IText");
56
				throw new ArgumentException ("Provider for TextBox should either implement IValue or IText");
Lines 61-66 Link Here
61
			if ((int) provider.GetPropertyValue (AutomationElementIdentifiers.ControlTypeProperty.Id) 
59
			if ((int) provider.GetPropertyValue (AutomationElementIdentifiers.ControlTypeProperty.Id) 
62
			    == ControlType.Document.Id)
60
			    == ControlType.Document.Id)
63
				multiLine = true;
61
				multiLine = true;
62
63
			editableTextExpert = new EditableTextImplementorHelper (this, this, textExpert);
64
		}
64
		}
65
65
66
		protected bool IsTableCell {
66
		protected bool IsTableCell {
(-)UiaAtkBridge/UiaAtkBridge/DataGrid.cs (-1 / +1 lines)
Lines 53-59 Link Here
53
					Atk.Focus.TrackerNotify (this);
53
					Atk.Focus.TrackerNotify (this);
54
			}
54
			}
55
			if (itemFocused)
55
			if (itemFocused)
56
				GLib.Signal.Emit (this, "active-descendant-changed", item.Handle);
56
				EmitSignal ("active-descendant-changed", item.Handle);
57
			hasFocus = tableFocused;
57
			hasFocus = tableFocused;
58
		}
58
		}
59
59
(-)UiaAtkBridge/UiaAtkBridge/Adapter.cs (-5 / +120 lines)
Lines 53-58 Link Here
53
			NotifyStateChange (state, RefStateSet ().ContainsState (state));
53
			NotifyStateChange (state, RefStateSet ().ContainsState (state));
54
		}
54
		}
55
		
55
		
56
		internal new void NotifyStateChange (Atk.StateType state, bool val)
57
		{
58
			GLib.Timeout.Add (0, new GLib.TimeoutHandler (delegate {
59
				base.NotifyStateChange (state, val);
60
				return false;
61
			}));
62
		}
63
64
		internal void EmitSignal (string name)
65
		{
66
			GLib.Timeout.Add (0, new GLib.TimeoutHandler (delegate {
67
				GLib.Signal.Emit (this, name);
68
				return false;
69
			}));
70
		}
71
72
		internal void EmitSignal (string name, object o)
73
		{
74
			GLib.Timeout.Add (0, new GLib.TimeoutHandler (delegate {
75
				GLib.Signal.Emit (this, name, o);
76
				return false;
77
			}));
78
		}
79
80
		internal void EmitSignal (string name, object o1, object o2)
81
		{
82
			GLib.Timeout.Add (0, new GLib.TimeoutHandler (delegate {
83
				GLib.Signal.Emit (this, name, o1, o2);
84
				return false;
85
			}));
86
		}
87
88
		internal void EmitSelectionChanged ()
89
		{
90
			GLib.Timeout.Add (0, new GLib.TimeoutHandler (delegate {
91
				GLib.Signal.Emit (this, "selection_changed");
92
				return false;
93
			}));
94
		}
95
96
		internal new void EmitVisibleDataChanged ()
97
		{
98
			GLib.Timeout.Add (0, new GLib.TimeoutHandler (delegate {
99
				base.EmitVisibleDataChanged ();
100
				return false;
101
			}));
102
		}
103
104
		// Unfortunately, we can't just override atk's set name/parent/
105
		// role, since atk calls g_object_notify, which must be called
106
		// in the glib thread.
107
		internal new Atk.Object Parent {
108
			get {
109
				return parent;
110
			}
111
			set {
112
				parent = value;
113
				GLib.Timeout.Add (0, new GLib.TimeoutHandler (delegate {
114
					base.Parent = value;
115
					return false;
116
				}));
117
			}
118
		}
119
120
		protected static void SetParent (Atk.Object child, Atk.Object newParent)
121
		{
122
			if (child is Adapter)
123
				((Adapter)child).Parent = newParent;
124
			else
125
				child.Parent = newParent;
126
		}
127
128
		protected static Atk.Object GetParent (Atk.Object child)
129
		{
130
			if (child is Adapter)
131
				return ((Adapter)child).Parent;
132
			else
133
				return child.Parent;
134
		}
135
136
		public new string Name {
137
			get {
138
				return name;
139
			}
140
			set {
141
				name = value;
142
				GLib.Timeout.Add (0, new GLib.TimeoutHandler (delegate {
143
					base.Name = value;
144
					return false;
145
				}));
146
			}
147
		}
148
149
		public new Atk.Role Role {
150
			get {
151
				return role;
152
			}
153
			set {
154
				role = value;
155
				GLib.Timeout.Add (0, new GLib.TimeoutHandler (delegate {
156
					base.Role = value;
157
					return false;
158
				}));
159
			}
160
		}
161
56
		protected void NotifyFocused (bool focused)
162
		protected void NotifyFocused (bool focused)
57
		{
163
		{
58
			NotifyStateChange (Atk.StateType.Focused, focused);
164
			NotifyStateChange (Atk.StateType.Focused, focused);
Lines 72-79 Link Here
72
				}
178
				}
73
			}
179
			}
74
180
75
			if (focused)
181
			if (focused) {
76
				Atk.Focus.TrackerNotify (this);
182
				GLib.Timeout.Add (0, new GLib.TimeoutHandler (delegate {
183
					Atk.Focus.TrackerNotify (this);
184
					return false;
185
				}));
186
			}
77
			if (focusWindow != null)
187
			if (focusWindow != null)
78
				focusWindow.SendActiveStateChange ();
188
				focusWindow.SendActiveStateChange ();
79
		}
189
		}
Lines 100-106 Link Here
100
					Log.Error ("Parent of an object should not be null");
210
					Log.Error ("Parent of an object should not be null");
101
					return;
211
					return;
102
				}
212
				}
103
				parent = parent.Parent;
213
				parent = GetParent (parent);
104
			}
214
			}
105
			TopLevelRootItem.Instance.CheckAndHandleNewActiveWindow ((UiaAtkBridge.Window)parent);
215
			TopLevelRootItem.Instance.CheckAndHandleNewActiveWindow ((UiaAtkBridge.Window)parent);
106
		}
216
		}
Lines 147-154 Link Here
147
			if (parent == Parent)
257
			if (parent == Parent)
148
				Parent = null;
258
				Parent = null;
149
259
150
			if (terminate)
260
			if (terminate && !defunct) {
151
				defunct = true;
261
				defunct = true;
262
				NotifyStateChange (Atk.StateType.Defunct, true);
263
			}
152
		}
264
		}
153
		
265
		
154
		internal virtual void PostInit ()
266
		internal virtual void PostInit ()
Lines 291-296 Link Here
291
#endregion
403
#endregion
292
404
293
#region Private Fields
405
#region Private Fields
406
		private Atk.Object parent;
407
		private Atk.Role role;
408
		private string name;
294
		private bool defunct = false;
409
		private bool defunct = false;
295
#endregion
410
#endregion
296
411
Lines 344-350 Link Here
344
			atkRect.Y = (int)rect.Y;
459
			atkRect.Y = (int)rect.Y;
345
			atkRect.Width = (int)rect.Width;
460
			atkRect.Width = (int)rect.Width;
346
			atkRect.Height = (int)rect.Height;
461
			atkRect.Height = (int)rect.Height;
347
			GLib.Signal.Emit (this, "bounds_changed", atkRect);
462
			EmitSignal ("bounds_changed", atkRect);
348
		}
463
		}
349
	}
464
	}
350
}
465
}
(-)UiaAtkBridge/UiaAtkBridge/AutomationBridge.cs (-3 / +6 lines)
Lines 734-741 Link Here
734
			} else if (controlTypeId == ControlType.Window.Id) {
734
			} else if (controlTypeId == ControlType.Window.Id) {
735
				// We should do the following, but it would
735
				// We should do the following, but it would
736
				// reintroduce bug 427857.
736
				// reintroduce bug 427857.
737
				//GLib.Signal.Emit (adapter, "deactivate");
737
				//Adapter.EmitSignal ("deactivate");
738
				//GLib.Signal.Emit (adapter, "destroy");
738
				//Adapter.EmitSignal ("destroy");
739
				TopLevelRootItem.Instance.RemoveChild (adapter);
739
				TopLevelRootItem.Instance.RemoveChild (adapter);
740
				windowProviders--;
740
				windowProviders--;
741
				if (windowProviders == 0)
741
				if (windowProviders == 0)
Lines 850-855 Link Here
850
850
851
		private static void HandleNewWindowControlType (IRawElementProviderSimple provider)
851
		private static void HandleNewWindowControlType (IRawElementProviderSimple provider)
852
		{
852
		{
853
			// make sure we have a main loop.  We may not, ie, if
854
			// a form has already been created and then destroyed.
855
			Monitor.Instance.CheckMainLoop ();
853
			var newWindow = CreateAdapter<Window> (provider);
856
			var newWindow = CreateAdapter<Window> (provider);
854
857
855
			if (newWindow == null)
858
			if (newWindow == null)
Lines 860-866 Link Here
860
			IntPtr providerHandle = (IntPtr) provider.GetPropertyValue (AutomationElementIdentifiers.NativeWindowHandleProperty.Id);
863
			IntPtr providerHandle = (IntPtr) provider.GetPropertyValue (AutomationElementIdentifiers.NativeWindowHandleProperty.Id);
861
			pointerProviderMapping [providerHandle] = provider;
864
			pointerProviderMapping [providerHandle] = provider;
862
865
863
			GLib.Signal.Emit (newWindow, "create");
866
			newWindow.EmitSignal ("create");
864
			
867
			
865
			windowProviders++;
868
			windowProviders++;
866
		}
869
		}
(-)UiaAtkBridge/UiaAtkBridge/ITextImplementor.cs (+2 lines)
Lines 82-86 Link Here
82
82
83
		bool RaiseAutomationEvent (AutomationEvent eventId, AutomationEventArgs e);
83
		bool RaiseAutomationEvent (AutomationEvent eventId, AutomationEventArgs e);
84
		bool RaiseAutomationPropertyChangedEvent (AutomationPropertyChangedEventArgs e);
84
		bool RaiseAutomationPropertyChangedEvent (AutomationPropertyChangedEventArgs e);
85
		void EmitTextChanged (Atk.TextChangedDetail detail, int position, int length);
86
		void EmitTextChanged (Atk.TextChangedDetail detail, int position, int length, string curText);
85
	}
87
	}
86
}
88
}

Return to bug 515507