1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
4 /* ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
17 * The Original Code is mozilla.org code.
19 * The Initial Developer of the Original Code is
21 * Portions created by the Initial Developer are Copyright (C) 2007
22 * the Initial Developer. All Rights Reserved.
25 * Bolian Yin <bolian.yin@sun.com>
26 * Ginn Chen <ginn.chen@sun.com>
27 * Alexander Surkov <surkov.alexander@gmail.com>
29 * Alternatively, the contents of this file may be used under the terms of
30 * either the GNU General Public License Version 2 or later (the "GPL"), or
31 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
32 * in which case the provisions of the GPL or the LGPL are applicable instead
33 * of those above. If you wish to allow use of your version of this file only
34 * under the terms of either the GPL or the LGPL, and not to allow others to
35 * use your version of this file under the terms of the MPL, indicate your
36 * decision by deleting the provisions above and replace them with the notice
37 * and other provisions required by the GPL or the LGPL. If you do not delete
38 * the provisions above, a recipient may use your version of this file under
39 * the terms of any one of the MPL, the GPL or the LGPL.
41 * ***** END LICENSE BLOCK ***** */
43 #include "nsApplicationAccessible.h"
45 #include "nsIComponentManager.h"
46 #include "nsServiceManagerUtils.h"
48 nsApplicationAccessible::nsApplicationAccessible():
49 nsAccessibleWrap(nsnull
, nsnull
), mChildren(nsnull
)
53 ////////////////////////////////////////////////////////////////////////////////
56 NS_IMPL_CYCLE_COLLECTION_CLASS(nsApplicationAccessible
)
58 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsApplicationAccessible
,
61 nsCOMPtr
<nsISimpleEnumerator
> enumerator
;
62 tmp
->mChildren
->Enumerate(getter_AddRefs(enumerator
));
64 nsCOMPtr
<nsIWeakReference
> childWeakRef
;
65 nsCOMPtr
<nsIAccessible
> accessible
;
67 PRBool hasMoreElements
;
68 while(NS_SUCCEEDED(enumerator
->HasMoreElements(&hasMoreElements
))
71 enumerator
->GetNext(getter_AddRefs(childWeakRef
));
72 accessible
= do_QueryReferent(childWeakRef
);
74 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb
, "nsApplicationAccessible child");
75 cb
.NoteXPCOMChild(accessible
);
79 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
81 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsApplicationAccessible
,
83 tmp
->mChildren
->Clear();
84 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
86 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsApplicationAccessible
)
87 NS_INTERFACE_MAP_END_INHERITING(nsAccessible
)
89 NS_IMPL_ADDREF_INHERITED(nsApplicationAccessible
, nsAccessible
)
90 NS_IMPL_RELEASE_INHERITED(nsApplicationAccessible
, nsAccessible
)
92 ////////////////////////////////////////////////////////////////////////////////
96 nsApplicationAccessible::Init()
99 mChildren
= do_CreateInstance(NS_ARRAY_CONTRACTID
, &rv
);
106 nsApplicationAccessible::GetName(nsAString
& aName
)
110 nsCOMPtr
<nsIStringBundleService
> bundleService
=
111 do_GetService(NS_STRINGBUNDLE_CONTRACTID
);
113 NS_ASSERTION(bundleService
, "String bundle service must be present!");
114 NS_ENSURE_STATE(bundleService
);
116 nsCOMPtr
<nsIStringBundle
> bundle
;
117 nsresult rv
= bundleService
->CreateBundle("chrome://branding/locale/brand.properties",
118 getter_AddRefs(bundle
));
119 NS_ENSURE_SUCCESS(rv
, rv
);
121 nsXPIDLString appName
;
122 rv
= bundle
->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
123 getter_Copies(appName
));
124 if (NS_FAILED(rv
) || appName
.IsEmpty()) {
125 NS_WARNING("brandShortName not found, using default app name");
126 appName
.AssignLiteral("Gecko based application");
129 aName
.Assign(appName
);
134 nsApplicationAccessible::GetRole(PRUint32
*aRole
)
136 *aRole
= nsIAccessibleRole::ROLE_APP_ROOT
;
141 nsApplicationAccessible::GetFinalRole(PRUint32
*aFinalRole
)
143 return GetRole(aFinalRole
);
147 nsApplicationAccessible::GetStateInternal(PRUint32
*aState
,
148 PRUint32
*aExtraState
)
158 nsApplicationAccessible::GetParent(nsIAccessible
**aParent
)
165 nsApplicationAccessible::GetChildAt(PRInt32 aChildNum
, nsIAccessible
**aChild
)
167 NS_ENSURE_ARG_POINTER(aChild
);
174 rv
= mChildren
->GetLength(&count
);
175 NS_ENSURE_SUCCESS(rv
, rv
);
178 if (aChildNum
>= static_cast<PRInt32
>(count
) || count
== 0)
179 return NS_ERROR_INVALID_ARG
;
182 aChildNum
= count
- 1;
184 nsCOMPtr
<nsIWeakReference
> childWeakRef
;
185 rv
= mChildren
->QueryElementAt(aChildNum
, NS_GET_IID(nsIWeakReference
),
186 getter_AddRefs(childWeakRef
));
187 NS_ENSURE_SUCCESS(rv
, rv
);
190 nsCOMPtr
<nsIAccessible
> childAcc(do_QueryReferent(childWeakRef
));
191 NS_IF_ADDREF(*aChild
= childAcc
);
198 nsApplicationAccessible::GetNextSibling(nsIAccessible
**aNextSibling
)
200 NS_ENSURE_ARG_POINTER(aNextSibling
);
202 *aNextSibling
= nsnull
;
207 nsApplicationAccessible::GetPreviousSibling(nsIAccessible
**aPreviousSibling
)
209 NS_ENSURE_ARG_POINTER(aPreviousSibling
);
211 *aPreviousSibling
= nsnull
;
216 nsApplicationAccessible::GetIndexInParent(PRInt32
*aIndexInParent
)
218 NS_ENSURE_ARG_POINTER(aIndexInParent
);
220 *aIndexInParent
= -1;
225 nsApplicationAccessible::CacheChildren()
228 mAccChildCount
= eChildCountUninitialized
;
232 if (mAccChildCount
== eChildCountUninitialized
) {
233 mAccChildCount
= 0;// Prevent reentry
234 nsCOMPtr
<nsISimpleEnumerator
> enumerator
;
235 mChildren
->Enumerate(getter_AddRefs(enumerator
));
237 nsCOMPtr
<nsIWeakReference
> childWeakRef
;
238 nsCOMPtr
<nsIAccessible
> accessible
;
239 nsCOMPtr
<nsPIAccessible
> previousAccessible
;
240 PRBool hasMoreElements
;
241 while(NS_SUCCEEDED(enumerator
->HasMoreElements(&hasMoreElements
))
242 && hasMoreElements
) {
243 enumerator
->GetNext(getter_AddRefs(childWeakRef
));
244 accessible
= do_QueryReferent(childWeakRef
);
246 if (previousAccessible
)
247 previousAccessible
->SetNextSibling(accessible
);
249 SetFirstChild(accessible
);
251 previousAccessible
= do_QueryInterface(accessible
);
252 previousAccessible
->SetParent(this);
257 mChildren
->GetLength(&count
);
258 mAccChildCount
= static_cast<PRInt32
>(count
);
262 // nsApplicationAccessible
265 nsApplicationAccessible::AddRootAccessible(nsIAccessible
*aRootAccessible
)
267 NS_ENSURE_ARG_POINTER(aRootAccessible
);
269 // add by weak reference
270 nsresult rv
= mChildren
->AppendElement(aRootAccessible
, PR_TRUE
);
271 NS_ENSURE_SUCCESS(rv
, rv
);
273 InvalidateChildren();
278 nsApplicationAccessible::RemoveRootAccessible(nsIAccessible
*aRootAccessible
)
280 NS_ENSURE_ARG_POINTER(aRootAccessible
);
284 // we must use weak ref to get the index
285 nsCOMPtr
<nsIWeakReference
> weakPtr
= do_GetWeakReference(aRootAccessible
);
286 nsresult rv
= mChildren
->IndexOf(0, weakPtr
, &index
);
287 NS_ENSURE_SUCCESS(rv
, rv
);
289 rv
= mChildren
->RemoveElementAt(index
);
290 NS_ENSURE_SUCCESS(rv
, rv
);
292 InvalidateChildren();