Remove obsolete VisualAge-related files.
[wxWidgets.git] / samples / access / accesstest.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: accesstest.cpp
3 // Purpose: wxWidgets accessibility sample
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 2002-02-12
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx/wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 // for all others, include the necessary headers (this file is usually all you
27 // need because it includes almost all "standard" wxWidgets headers)
28 #ifndef WX_PRECOMP
29 #include "wx/wx.h"
30 #endif
31
32 #if wxUSE_ACCESSIBILITY
33 #include "wx/access.h"
34 #endif // wxUSE_ACCESSIBILITY
35
36 #include "wx/splitter.h"
37 #include "wx/cshelp.h"
38
39 #ifdef __WXMSW__
40 #include "windows.h"
41 #include <ole2.h>
42 #include <oleauto.h>
43
44 #if wxUSE_ACCESSIBILITY
45 #include <oleacc.h>
46 #endif // wxUSE_ACCESSIBILITY
47
48 #include "wx/msw/ole/oleutils.h"
49 #include "wx/msw/winundef.h"
50
51 #ifndef OBJID_CLIENT
52 #define OBJID_CLIENT 0xFFFFFFFC
53 #endif
54 #endif
55
56 // ----------------------------------------------------------------------------
57 // resources
58 // ----------------------------------------------------------------------------
59
60 // the application icon (under Windows and OS/2 it is in resources)
61 #ifndef wxHAS_IMAGES_IN_RESOURCES
62 #include "../sample.xpm"
63 #endif
64
65 // ----------------------------------------------------------------------------
66 // private classes
67 // ----------------------------------------------------------------------------
68
69 // Define a new application type, each program should derive a class from wxApp
70 class MyApp : public wxApp
71 {
72 public:
73 // override base class virtuals
74 // ----------------------------
75
76 // this one is called on application startup and is a good place for the app
77 // initialization (doing it here and not in the ctor allows to have an error
78 // return: if OnInit() returns false, the application terminates)
79 virtual bool OnInit();
80
81 };
82
83 #if wxUSE_ACCESSIBILITY
84
85 // Define a new frame type: this is going to be our main frame
86 class MyFrame : public wxFrame
87 {
88 public:
89 // ctor(s)
90 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
91 long style = wxDEFAULT_FRAME_STYLE);
92
93 // event handlers (these functions should _not_ be virtual)
94 void OnQuit(wxCommandEvent& event);
95 void OnQuery(wxCommandEvent& event);
96 void OnAbout(wxCommandEvent& event);
97
98 // Log messages to the text control
99 void Log(const wxString& text);
100
101 // Recursively give information about an object
102 void LogObject(int indent, IAccessible* obj);
103
104 // Get info for a child (id > 0) or object (id == 0)
105 void GetInfo(IAccessible* accessible, int id, wxString& name, wxString& role);
106 private:
107 wxTextCtrl* m_textCtrl;
108
109 // any class wishing to process wxWidgets events must use this macro
110 DECLARE_EVENT_TABLE()
111 };
112
113 // ----------------------------------------------------------------------------
114 // constants
115 // ----------------------------------------------------------------------------
116
117 // IDs for the controls and the menu commands
118 enum
119 {
120 // menu items
121 AccessTest_Quit = 1,
122
123 // query the hierarchy
124 AccessTest_Query,
125
126 // it is important for the id corresponding to the "About" command to have
127 // this standard value as otherwise it won't be handled properly under Mac
128 // (where it is special and put into the "Apple" menu)
129 AccessTest_About = wxID_ABOUT
130 };
131
132 // ----------------------------------------------------------------------------
133 // event tables and other macros for wxWidgets
134 // ----------------------------------------------------------------------------
135
136 // the event tables connect the wxWidgets events with the functions (event
137 // handlers) which process them. It can be also done at run-time, but for the
138 // simple menu events like this the static method is much simpler.
139 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
140 EVT_MENU(AccessTest_Quit, MyFrame::OnQuit)
141 EVT_MENU(AccessTest_Query, MyFrame::OnQuery)
142 EVT_MENU(AccessTest_About, MyFrame::OnAbout)
143 END_EVENT_TABLE()
144
145 #endif // wxUSE_ACCESSIBILITY
146
147 // Create a new application object: this macro will allow wxWidgets to create
148 // the application object during program execution (it's better than using a
149 // static object for many reasons) and also declares the accessor function
150 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
151 // not wxApp)
152 IMPLEMENT_APP(MyApp)
153
154 // ============================================================================
155 // implementation
156 // ============================================================================
157
158 // ----------------------------------------------------------------------------
159 // the application class
160 // ----------------------------------------------------------------------------
161
162 // 'Main program' equivalent: the program execution "starts" here
163 bool MyApp::OnInit()
164 {
165 if ( !wxApp::OnInit() )
166 return false;
167
168 #if wxUSE_ACCESSIBILITY
169 // Note: JAWS for Windows will only speak the context-sensitive
170 // help if you use this help provider:
171 // wxHelpProvider::Set(new wxHelpControllerHelpProvider(m_helpController)).
172 // JAWS does not seem to be getting the help text from
173 // the wxAccessible object.
174 wxHelpProvider::Set(new wxSimpleHelpProvider());
175
176 // create the main application window
177 MyFrame *frame = new MyFrame(wxT("AccessTest wxWidgets App"),
178 wxPoint(50, 50), wxSize(450, 340));
179
180 // and show it (the frames, unlike simple controls, are not shown when
181 // created initially)
182 frame->Show(true);
183
184 // success: wxApp::OnRun() will be called which will enter the main message
185 // loop and the application will run. If we returned false here, the
186 // application would exit immediately.
187 return true;
188 #else
189 wxMessageBox( wxT("This sample has to be compiled with wxUSE_ACCESSIBILITY"), wxT("Building error"), wxOK);
190 return false;
191 #endif // wxUSE_ACCESSIBILITY
192 }
193
194 #if wxUSE_ACCESSIBILITY
195
196 class FrameAccessible: public wxWindowAccessible
197 {
198 public:
199 FrameAccessible(wxWindow* win): wxWindowAccessible(win) {}
200
201 // Gets the name of the specified object.
202 virtual wxAccStatus GetName(int childId, wxString* name)
203 {
204 if (childId == wxACC_SELF)
205 {
206 * name = wxT("Julian's Frame");
207 return wxACC_OK;
208 }
209 else
210 return wxACC_NOT_IMPLEMENTED;
211 }
212 };
213
214 class ScrolledWindowAccessible: public wxWindowAccessible
215 {
216 public:
217 ScrolledWindowAccessible(wxWindow* win): wxWindowAccessible(win) {}
218
219 // Gets the name of the specified object.
220 virtual wxAccStatus GetName(int childId, wxString* name)
221 {
222 if (childId == wxACC_SELF)
223 {
224 * name = wxT("My scrolled window");
225 return wxACC_OK;
226 }
227 else
228 return wxACC_NOT_IMPLEMENTED;
229 }
230 };
231
232 class SplitterWindowAccessible: public wxWindowAccessible
233 {
234 public:
235 SplitterWindowAccessible(wxWindow* win): wxWindowAccessible(win) {}
236
237 // Gets the name of the specified object.
238 virtual wxAccStatus GetName(int childId, wxString* name);
239
240 // Can return either a child object, or an integer
241 // representing the child element, starting from 1.
242 virtual wxAccStatus HitTest(const wxPoint& pt, int* childId, wxAccessible** childObject);
243
244 // Returns the rectangle for this object (id = 0) or a child element (id > 0).
245 virtual wxAccStatus GetLocation(wxRect& rect, int elementId);
246
247 // Navigates from fromId to toId/toObject.
248 virtual wxAccStatus Navigate(wxNavDir navDir, int fromId,
249 int* toId, wxAccessible** toObject);
250
251 // Gets the number of children.
252 virtual wxAccStatus GetChildCount(int* childCount);
253
254 // Gets the specified child (starting from 1).
255 // If *child is NULL and return value is wxACC_OK,
256 // this means that the child is a simple element and
257 // not an accessible object.
258 virtual wxAccStatus GetChild(int childId, wxAccessible** child);
259
260 // Gets the parent, or NULL.
261 virtual wxAccStatus GetParent(wxAccessible** parent);
262
263 // Performs the default action. childId is 0 (the action for this object)
264 // or > 0 (the action for a child).
265 // Return wxACC_NOT_SUPPORTED if there is no default action for this
266 // window (e.g. an edit control).
267 virtual wxAccStatus DoDefaultAction(int childId);
268
269 // Gets the default action for this object (0) or > 0 (the action for a child).
270 // Return wxACC_OK even if there is no action. actionName is the action, or the empty
271 // string if there is no action.
272 // The retrieved string describes the action that is performed on an object,
273 // not what the object does as a result. For example, a toolbar button that prints
274 // a document has a default action of "Press" rather than "Prints the current document."
275 virtual wxAccStatus GetDefaultAction(int childId, wxString* actionName);
276
277 // Returns the description for this object or a child.
278 virtual wxAccStatus GetDescription(int childId, wxString* description);
279
280 // Returns help text for this object or a child, similar to tooltip text.
281 virtual wxAccStatus GetHelpText(int childId, wxString* helpText);
282
283 // Returns the keyboard shortcut for this object or child.
284 // Return e.g. ALT+K
285 virtual wxAccStatus GetKeyboardShortcut(int childId, wxString* shortcut);
286
287 // Returns a role constant.
288 virtual wxAccStatus GetRole(int childId, wxAccRole* role);
289
290 // Returns a state constant.
291 virtual wxAccStatus GetState(int childId, long* state);
292
293 // Returns a localized string representing the value for the object
294 // or child.
295 virtual wxAccStatus GetValue(int childId, wxString* strValue);
296
297 // Selects the object or child.
298 virtual wxAccStatus Select(int childId, wxAccSelectionFlags selectFlags);
299
300 // Gets the window with the keyboard focus.
301 // If childId is 0 and child is NULL, no object in
302 // this subhierarchy has the focus.
303 // If this object has the focus, child should be 'this'.
304 virtual wxAccStatus GetFocus(int* childId, wxAccessible** child);
305
306 // Gets a variant representing the selected children
307 // of this object.
308 // Acceptable values:
309 // - a null variant (IsNull() returns true)
310 // - a list variant (GetType() == wxT("list"))
311 // - an integer representing the selected child element,
312 // or 0 if this object is selected (GetType() == wxT("long"))
313 // - a "void*" pointer to a wxAccessible child object
314 virtual wxAccStatus GetSelections(wxVariant* selections);
315
316 };
317
318 // ----------------------------------------------------------------------------
319 // main frame
320 // ----------------------------------------------------------------------------
321
322 // frame constructor
323 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, long style)
324 : wxFrame(NULL, wxID_ANY, title, pos, size, style)
325 {
326 m_textCtrl = NULL;
327
328 SetAccessible(new FrameAccessible(this));
329
330 // set the frame icon
331 SetIcon(wxICON(sample));
332
333 #if wxUSE_MENUS
334 // create a menu bar
335 wxMenu *menuFile = new wxMenu;
336
337 // the "About" item should be in the help menu
338 wxMenu *helpMenu = new wxMenu;
339 helpMenu->Append(AccessTest_About, wxT("&About"), wxT("Show about dialog"));
340
341 menuFile->Append(AccessTest_Query, wxT("Query"), wxT("Query the window hierarchy"));
342 menuFile->AppendSeparator();
343 menuFile->Append(AccessTest_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
344
345 // now append the freshly created menu to the menu bar...
346 wxMenuBar *menuBar = new wxMenuBar();
347 menuBar->Append(menuFile, wxT("&File"));
348 menuBar->Append(helpMenu, wxT("&Help"));
349
350 // ... and attach this menu bar to the frame
351 SetMenuBar(menuBar);
352 #endif // wxUSE_MENUS
353
354 #if 0 // wxUSE_STATUSBAR
355 // create a status bar just for fun (by default with 1 pane only)
356 CreateStatusBar(2);
357 SetStatusText(wxT("Welcome to wxWidgets!"));
358 #endif // wxUSE_STATUSBAR
359
360
361 wxSplitterWindow* splitter = new wxSplitterWindow(this, wxID_ANY);
362 splitter->SetAccessible(new SplitterWindowAccessible(splitter));
363
364 wxListBox* listBox = new wxListBox(splitter, wxID_ANY);
365 listBox->Append(wxT("Cabbages"));
366 listBox->Append(wxT("Kings"));
367 listBox->Append(wxT("Sealing wax"));
368 listBox->Append(wxT("Strings"));
369 listBox->CreateAccessible();
370 listBox->SetHelpText(wxT("This is a sample wxWidgets listbox, with a number of items in it."));
371
372 m_textCtrl = new wxTextCtrl(splitter, wxID_ANY, wxT(""), wxDefaultPosition,
373 wxDefaultSize, wxTE_MULTILINE);
374 m_textCtrl->CreateAccessible();
375 m_textCtrl->SetHelpText(wxT("This is a sample wxWidgets multiline text control."));
376
377 splitter->SplitHorizontally(listBox, m_textCtrl, 150);
378
379 #if 0
380 wxScrolledWindow* scrolledWindow = new wxScrolledWindow(this, wxID_ANY);
381 scrolledWindow->SetAccessible(new ScrolledWindowAccessible(scrolledWindow));
382 #endif
383 }
384
385
386 // event handlers
387
388 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
389 {
390 // true is to force the frame to close
391 Close(true);
392 }
393
394 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
395 {
396 wxString msg;
397 msg.Printf( wxT("This is the About dialog of the AccessTest sample.\n")
398 wxT("Welcome to %s"), wxVERSION_STRING);
399
400 wxMessageBox(msg, wxT("About AccessTest"), wxOK | wxICON_INFORMATION, this);
401 }
402
403 void MyFrame::OnQuery(wxCommandEvent& WXUNUSED(event))
404 {
405 m_textCtrl->Clear();
406 IAccessible* accessibleFrame = NULL;
407 if (S_OK != AccessibleObjectFromWindow((HWND) GetHWND(), OBJID_CLIENT,
408 IID_IAccessible, (void**) & accessibleFrame))
409 {
410 Log(wxT("Could not get object."));
411 return;
412 }
413 if (accessibleFrame)
414 {
415 //Log(wxT("Got an IAccessible for the frame."));
416 LogObject(0, accessibleFrame);
417 Log(wxT("Checking children using AccessibleChildren()..."));
418
419 // Now check the AccessibleChildren function works OK
420 long childCount = 0;
421 if (S_OK != accessibleFrame->get_accChildCount(& childCount))
422 {
423 Log(wxT("Could not get number of children."));
424 accessibleFrame->Release();
425 return;
426 }
427 else if (childCount == 0)
428 {
429 Log(wxT("No children."));
430 accessibleFrame->Release();
431 return;
432 }
433
434
435 long obtained = 0;
436 VARIANT *var = new VARIANT[childCount];
437 int i;
438 for (i = 0; i < childCount; i++)
439 {
440 VariantInit(& (var[i]));
441 var[i].vt = VT_DISPATCH;
442 }
443
444 if (S_OK == AccessibleChildren(accessibleFrame, 0, childCount, var, &obtained))
445 {
446 for (i = 0; i < childCount; i++)
447 {
448 IAccessible* childAccessible = NULL;
449 if (var[i].pdispVal)
450 {
451 if (var[i].pdispVal->QueryInterface(IID_IAccessible, (LPVOID*) & childAccessible) == S_OK)
452 {
453 var[i].pdispVal->Release();
454
455 wxString name, role;
456 GetInfo(childAccessible, 0, name, role);
457 wxString str;
458 str.Printf(wxT("Found child %s/%s"), name.c_str(), role.c_str());
459 Log(str);
460 childAccessible->Release();
461 }
462 else
463 {
464 var[i].pdispVal->Release();
465 }
466 }
467 }
468 }
469 else
470 {
471 Log(wxT("AccessibleChildren failed."));
472 }
473 delete[] var;
474
475
476 accessibleFrame->Release();
477 }
478 }
479
480 // Log messages to the text control
481 void MyFrame::Log(const wxString& text)
482 {
483 if (m_textCtrl)
484 {
485 wxString text2(text);
486 text2.Replace(wxT("\n"), wxT(" "));
487 text2.Replace(wxT("\r"), wxT(" "));
488 m_textCtrl->SetInsertionPointEnd();
489 m_textCtrl->WriteText(text2 + wxT("\n"));
490 }
491 }
492
493 // Recursively give information about an object
494 void MyFrame::LogObject(int indent, IAccessible* obj)
495 {
496 wxString name, role;
497 if (indent == 0)
498 {
499 GetInfo(obj, 0, name, role);
500
501 wxString str;
502 str.Printf(wxT("Name = %s; Role = %s"), name.c_str(), role.c_str());
503 str.Pad(indent, wxT(' '), false);
504 Log(str);
505 }
506
507 long childCount = 0;
508 if (S_OK == obj->get_accChildCount(& childCount))
509 {
510 wxString str;
511 str.Printf(wxT("There are %d children."), (int) childCount);
512 str.Pad(indent, wxT(' '), false);
513 Log(str);
514 Log(wxT(""));
515 }
516
517 int i;
518 for (i = 1; i <= childCount; i++)
519 {
520 GetInfo(obj, i, name, role);
521
522 wxString str;
523 str.Printf(wxT("%d) Name = %s; Role = %s"), i, name.c_str(), role.c_str());
524 str.Pad(indent, wxT(' '), false);
525 Log(str);
526
527 VARIANT var;
528 VariantInit(& var);
529 var.vt = VT_I4;
530 var.lVal = i;
531 IDispatch* pDisp = NULL;
532 IAccessible* childObject = NULL;
533
534 if (S_OK == obj->get_accChild(var, & pDisp) && pDisp)
535 {
536 wxString str;
537 str.Printf(wxT("This is a real object."));
538 str.Pad(indent+4, wxT(' '), false);
539 Log(str);
540
541 if (pDisp->QueryInterface(IID_IAccessible, (LPVOID*) & childObject) == S_OK)
542 {
543 LogObject(indent + 4, childObject);
544 childObject->Release();
545 }
546 pDisp->Release();
547 }
548 else
549 {
550 wxString str;
551 str.Printf(wxT("This is an element."));
552 str.Pad(indent+4, wxT(' '), false);
553 Log(str);
554 }
555 // Log(wxT(""));
556 }
557
558 }
559
560 // Get info for a child (id > 0) or object (id == 0)
561 void MyFrame::GetInfo(IAccessible* accessible, int id, wxString& name, wxString& role)
562 {
563 VARIANT var;
564 VariantInit(& var);
565 var.vt = VT_I4;
566 var.lVal = id;
567
568 BSTR bStrName = 0;
569 HRESULT hResult = accessible->get_accName(var, & bStrName);
570
571 if (hResult == S_OK)
572 {
573 name = wxConvertStringFromOle(bStrName);
574 SysFreeString(bStrName);
575 }
576 else
577 {
578 name = wxT("NO NAME");
579 }
580
581 VARIANT varRole;
582 VariantInit(& varRole);
583
584 hResult = accessible->get_accRole(var, & varRole);
585
586 if (hResult == S_OK && varRole.vt == VT_I4)
587 {
588 wxChar buf[256];
589 GetRoleText(varRole.lVal, buf, 256);
590
591 role = buf;
592 }
593 else
594 {
595 role = wxT("NO ROLE");
596 }
597 }
598
599 /*
600 * SplitterWindowAccessible implementation
601 */
602
603 // Gets the name of the specified object.
604 wxAccStatus SplitterWindowAccessible::GetName(int childId, wxString* name)
605 {
606 if (childId == wxACC_SELF)
607 {
608 * name = wxT("Splitter window");
609 return wxACC_OK;
610 }
611 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
612 if (splitter)
613 {
614 if (splitter->IsSplit())
615 {
616 // Two windows, and the sash.
617 if (childId == 1 || childId == 3)
618 return wxACC_NOT_IMPLEMENTED;
619 else if (childId == 2)
620 {
621 *name = wxT("Sash");
622 return wxACC_OK;
623 }
624 }
625 }
626 // Let the framework handle the other cases.
627 return wxACC_NOT_IMPLEMENTED;
628 }
629
630 // Can return either a child object, or an integer
631 // representing the child element, starting from 1.
632 wxAccStatus SplitterWindowAccessible::HitTest(const wxPoint& pt, int* childId, wxAccessible** WXUNUSED(childObject))
633 {
634 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
635 if (splitter)
636 {
637 if (splitter->IsSplit())
638 {
639 wxPoint clientPt = splitter->ScreenToClient(pt);
640 if (splitter->SashHitTest(clientPt.x, clientPt.y, 1))
641 {
642 // We're over the sash
643 *childId = 2;
644 return wxACC_OK;
645 }
646 }
647 }
648 // Let the framework handle the other cases.
649 return wxACC_NOT_IMPLEMENTED;
650 }
651
652 // Returns the rectangle for this object (id = 0) or a child element (id > 0).
653 wxAccStatus SplitterWindowAccessible::GetLocation(wxRect& rect, int elementId)
654 {
655 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
656 if (splitter && elementId == 2 && splitter->IsSplit())
657 {
658 wxSize clientSize = splitter->GetClientSize();
659 if (splitter->GetSplitMode() == wxSPLIT_VERTICAL)
660 {
661 rect.x = splitter->GetSashPosition();
662 rect.y = 0;
663 rect.SetPosition(splitter->ClientToScreen(rect.GetPosition()));
664 rect.width = splitter->GetSashSize();
665 rect.height = clientSize.y;
666 }
667 else
668 {
669 rect.x = 0;
670 rect.y = splitter->GetSashPosition();
671 rect.SetPosition(splitter->ClientToScreen(rect.GetPosition()));
672 rect.width = clientSize.x;
673 rect.height = splitter->GetSashSize();
674 }
675 return wxACC_OK;
676 }
677 // Let the framework handle the other cases.
678 return wxACC_NOT_IMPLEMENTED;
679 }
680
681 // Navigates from fromId to toId/toObject.
682 wxAccStatus SplitterWindowAccessible::Navigate(wxNavDir navDir, int fromId,
683 int* toId, wxAccessible** toObject)
684 {
685 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
686 if (splitter && splitter->IsSplit())
687 {
688 switch (navDir)
689 {
690 case wxNAVDIR_DOWN:
691 {
692 if (splitter->GetSplitMode() != wxSPLIT_VERTICAL)
693 {
694 if (fromId == 1)
695 {
696 *toId = 2;
697 *toObject = NULL;
698 return wxACC_OK;
699 }
700 else if (fromId == 2)
701 {
702 *toId = 3;
703 *toObject = splitter->GetWindow2()->GetAccessible();
704 return wxACC_OK;
705 }
706 }
707 return wxACC_FALSE;
708 #if 0
709 // below line is not executed due to earlier return
710 break;
711 #endif
712 }
713 case wxNAVDIR_FIRSTCHILD:
714 {
715 if (fromId == 2)
716 return wxACC_FALSE;
717 }
718 break;
719
720 case wxNAVDIR_LASTCHILD:
721 {
722 if (fromId == 2)
723 return wxACC_FALSE;
724 }
725 break;
726
727 case wxNAVDIR_LEFT:
728 {
729 if (splitter->GetSplitMode() != wxSPLIT_HORIZONTAL)
730 {
731 if (fromId == 3)
732 {
733 *toId = 2;
734 *toObject = NULL;
735 return wxACC_OK;
736 }
737 else if (fromId == 2)
738 {
739 *toId = 1;
740 *toObject = splitter->GetWindow1()->GetAccessible();
741 return wxACC_OK;
742 }
743 }
744 return wxACC_FALSE;
745 }
746 #if 0
747 // below line is not executed due to earlier return
748 break;
749 #endif
750
751 case wxNAVDIR_NEXT:
752 {
753 if (fromId == 1)
754 {
755 *toId = 2;
756 *toObject = NULL;
757 return wxACC_OK;
758 }
759 else if (fromId == 2)
760 {
761 *toId = 3;
762 *toObject = splitter->GetWindow2()->GetAccessible();
763 return wxACC_OK;
764 }
765 return wxACC_FALSE;
766 }
767 #if 0
768 // below line is not executed due to earlier return
769 break;
770 #endif
771
772 case wxNAVDIR_PREVIOUS:
773 {
774 if (fromId == 3)
775 {
776 *toId = 2;
777 *toObject = NULL;
778 return wxACC_OK;
779 }
780 else if (fromId == 2)
781 {
782 *toId = 1;
783 *toObject = splitter->GetWindow1()->GetAccessible();
784 return wxACC_OK;
785 }
786 return wxACC_FALSE;
787 }
788 #if 0
789 // below line is not executed due to earlier return
790 break;
791 #endif
792
793 case wxNAVDIR_RIGHT:
794 {
795 if (splitter->GetSplitMode() != wxSPLIT_HORIZONTAL)
796 {
797 if (fromId == 1)
798 {
799 *toId = 2;
800 *toObject = NULL;
801 return wxACC_OK;
802 }
803 else if (fromId == 2)
804 {
805 *toId = 3;
806 *toObject = splitter->GetWindow2()->GetAccessible();
807 return wxACC_OK;
808 }
809 }
810 // Can't go right spatially if split horizontally.
811 return wxACC_FALSE;
812 }
813 #if 0
814 // below line is not executed due to earlier return
815 break;
816 #endif
817
818 case wxNAVDIR_UP:
819 {
820 if (splitter->GetSplitMode() != wxSPLIT_VERTICAL)
821 {
822 if (fromId == 3)
823 {
824 *toId = 2;
825 return wxACC_OK;
826 }
827 else if (fromId == 2)
828 {
829 *toId = 1;
830 *toObject = splitter->GetWindow1()->GetAccessible();
831 return wxACC_OK;
832 }
833 }
834
835 // Can't go up spatially if split vertically.
836 return wxACC_FALSE;
837 #if 0
838 // below line is not executed due to earlier return
839 break;
840 #endif
841 }
842 }
843
844 }
845 // Let the framework handle the other cases.
846 return wxACC_NOT_IMPLEMENTED;
847 }
848
849 // Gets the number of children.
850 wxAccStatus SplitterWindowAccessible::GetChildCount(int* childCount)
851 {
852 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
853 if (splitter)
854 {
855 if (splitter->IsSplit())
856 {
857 // Two windows, and the sash.
858 *childCount = 3;
859 return wxACC_OK;
860 }
861 else
862 {
863 // No sash -- 1 or 0 windows.
864 if (splitter->GetWindow1() || splitter->GetWindow2())
865 {
866 *childCount = 1;
867 return wxACC_OK;
868 }
869 else
870 {
871 *childCount = 0;
872 return wxACC_OK;
873 }
874 }
875 }
876 // Let the framework handle the other cases.
877 return wxACC_NOT_IMPLEMENTED;
878 }
879
880 // Gets the specified child (starting from 1).
881 // If *child is NULL and return value is wxACC_OK,
882 // this means that the child is a simple element and
883 // not an accessible object.
884 wxAccStatus SplitterWindowAccessible::GetChild(int childId, wxAccessible** child)
885 {
886 if (childId == wxACC_SELF)
887 {
888 *child = this;
889 return wxACC_OK;
890 }
891
892 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
893 if (splitter)
894 {
895 if (splitter->IsSplit())
896 {
897 // Two windows, and the sash.
898 if (childId == 1)
899 {
900 *child = splitter->GetWindow1()->GetAccessible();
901 }
902 else if (childId == 2)
903 {
904 *child = NULL; // Sash
905 }
906 else if (childId == 3)
907 {
908 *child = splitter->GetWindow2()->GetAccessible();
909 }
910 else
911 {
912 return wxACC_FAIL;
913 }
914 return wxACC_OK;
915 }
916 else
917 {
918 // No sash -- 1 or 0 windows.
919 if (childId == 1)
920 {
921 if (splitter->GetWindow1())
922 {
923 *child = splitter->GetWindow1()->GetAccessible();
924 return wxACC_OK;
925 }
926 else if (splitter->GetWindow2())
927 {
928 *child = splitter->GetWindow2()->GetAccessible();
929 return wxACC_OK;
930 }
931 else
932 {
933 return wxACC_FAIL;
934 }
935 }
936 else
937 return wxACC_FAIL;
938 }
939 }
940 // Let the framework handle the other cases.
941 return wxACC_NOT_IMPLEMENTED;
942 }
943
944 // Gets the parent, or NULL.
945 wxAccStatus SplitterWindowAccessible::GetParent(wxAccessible** WXUNUSED(parent))
946 {
947 return wxACC_NOT_IMPLEMENTED;
948 }
949
950 // Performs the default action. childId is 0 (the action for this object)
951 // or > 0 (the action for a child).
952 // Return wxACC_NOT_SUPPORTED if there is no default action for this
953 // window (e.g. an edit control).
954 wxAccStatus SplitterWindowAccessible::DoDefaultAction(int WXUNUSED(childId))
955 {
956 return wxACC_NOT_IMPLEMENTED;
957 }
958
959 // Gets the default action for this object (0) or > 0 (the action for a child).
960 // Return wxACC_OK even if there is no action. actionName is the action, or the empty
961 // string if there is no action.
962 // The retrieved string describes the action that is performed on an object,
963 // not what the object does as a result. For example, a toolbar button that prints
964 // a document has a default action of "Press" rather than "Prints the current document."
965 wxAccStatus SplitterWindowAccessible::GetDefaultAction(int childId, wxString* WXUNUSED(actionName))
966 {
967 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
968 if (splitter && splitter->IsSplit() && childId == 2)
969 {
970 // No default action for the splitter.
971 return wxACC_FALSE;
972 }
973 // Let the framework handle the other cases.
974 return wxACC_NOT_IMPLEMENTED;
975 }
976
977 // Returns the description for this object or a child.
978 wxAccStatus SplitterWindowAccessible::GetDescription(int childId, wxString* description)
979 {
980 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
981 if (splitter)
982 {
983 if (splitter->IsSplit())
984 {
985 if (childId == 2)
986 {
987 * description = _("The splitter window sash.");
988 return wxACC_OK;
989 }
990 }
991 }
992 // Let the framework handle the other cases.
993 return wxACC_NOT_IMPLEMENTED;
994 }
995
996 // Returns help text for this object or a child, similar to tooltip text.
997 wxAccStatus SplitterWindowAccessible::GetHelpText(int childId, wxString* helpText)
998 {
999 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1000 if (splitter)
1001 {
1002 if (splitter->IsSplit())
1003 {
1004 if (childId == 2)
1005 {
1006 * helpText = _("The splitter window sash.");
1007 return wxACC_OK;
1008 }
1009 }
1010 }
1011 // Let the framework handle the other cases.
1012 return wxACC_NOT_IMPLEMENTED;
1013 }
1014
1015 // Returns the keyboard shortcut for this object or child.
1016 // Return e.g. ALT+K
1017 wxAccStatus SplitterWindowAccessible::GetKeyboardShortcut(int childId, wxString* WXUNUSED(shortcut))
1018 {
1019 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1020 if (splitter && splitter->IsSplit() && childId == 2)
1021 {
1022 // No keyboard shortcut for the splitter.
1023 return wxACC_FALSE;
1024 }
1025 // Let the framework handle the other cases.
1026 return wxACC_NOT_IMPLEMENTED;
1027 }
1028
1029 // Returns a role constant.
1030 wxAccStatus SplitterWindowAccessible::GetRole(int childId, wxAccRole* role)
1031 {
1032 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1033 if (splitter)
1034 {
1035 if (splitter->IsSplit())
1036 {
1037 if (childId == 2)
1038 {
1039 * role = wxROLE_SYSTEM_GRIP;
1040 return wxACC_OK;
1041 }
1042 }
1043 }
1044 // Let the framework handle the other cases.
1045 return wxACC_NOT_IMPLEMENTED;
1046 }
1047
1048 // Returns a state constant.
1049 wxAccStatus SplitterWindowAccessible::GetState(int childId, long* state)
1050 {
1051 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1052 if (splitter && splitter->IsSplit() && childId == 2)
1053 {
1054 // No particular state. Not sure what would be appropriate here.
1055 *state = wxACC_STATE_SYSTEM_UNAVAILABLE;
1056 return wxACC_OK;
1057 }
1058 // Let the framework handle the other cases.
1059 return wxACC_NOT_IMPLEMENTED;
1060 }
1061
1062 // Returns a localized string representing the value for the object
1063 // or child.
1064 wxAccStatus SplitterWindowAccessible::GetValue(int childId, wxString* strValue)
1065 {
1066 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1067 if (splitter && splitter->IsSplit() && childId == 2)
1068 {
1069 // The sash position is the value.
1070 wxString pos;
1071 pos << splitter->GetSashPosition();
1072 *strValue = pos;
1073
1074 return wxACC_OK;
1075 }
1076 // Let the framework handle the other cases.
1077 return wxACC_NOT_IMPLEMENTED;
1078 }
1079
1080 // Selects the object or child.
1081 wxAccStatus SplitterWindowAccessible::Select(int childId, wxAccSelectionFlags WXUNUSED(selectFlags))
1082 {
1083 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1084 if (splitter && splitter->IsSplit() && childId == 2)
1085 {
1086 // Can't select the sash.
1087 return wxACC_FALSE;
1088 }
1089 // Let the framework handle the other cases.
1090 return wxACC_NOT_IMPLEMENTED;
1091 }
1092
1093 // Gets the window with the keyboard focus.
1094 // If childId is 0 and child is NULL, no object in
1095 // this subhierarchy has the focus.
1096 // If this object has the focus, child should be 'this'.
1097 wxAccStatus SplitterWindowAccessible::GetFocus(int* WXUNUSED(childId), wxAccessible** WXUNUSED(child))
1098 {
1099 return wxACC_NOT_IMPLEMENTED;
1100 }
1101
1102 // Gets a variant representing the selected children
1103 // of this object.
1104 // Acceptable values:
1105 // - a null variant (IsNull() returns true)
1106 // - a list variant (GetType() == wxT("list"))
1107 // - an integer representing the selected child element,
1108 // or 0 if this object is selected (GetType() == wxT("long"))
1109 // - a "void*" pointer to a wxAccessible child object
1110 wxAccStatus SplitterWindowAccessible::GetSelections(wxVariant* WXUNUSED(selections))
1111 {
1112 return wxACC_NOT_IMPLEMENTED;
1113 }
1114
1115 #endif // wxUSE_ACCESSIBILITY