build: get doxygen generating selective
[platform/core/uifw/aurum.git] / libaurum / src / AccessibleNode.cc
1 #include "AccessibleNode.h"
2 #include <string.h>
3 #include <iostream>
4 #include <vector>
5
6 #include <loguru.hpp>
7 #include "config.h"
8
9 std::map<AtspiAccessible *, AccessibleNode *> AccessibleNode::mNodeMap{};
10
11 AccessibleNode::~AccessibleNode()
12 {
13
14 }
15
16 AccessibleNode::AccessibleNode() : AccessibleNode(nullptr)
17 {
18     // No meaning without AtspiAccessbile object
19     // prohibited to create this object with this constructor
20 }
21
22 AccessibleNode::AccessibleNode(AtspiAccessible *node)
23     : mNode(make_gobj_ref_unique(node)), mBoundingBox{0,0,0,0}, mSupportingIfaces(0), mFeatureProperty(0), mIsAlive(true)
24 {
25     // prohibited to create this object this constructor
26     // better to use AccessibleNode::get factory method.
27
28     LOG_SCOPE_F(1, "AccessibleNode constructor %p", mNode.get());
29     GArray *ifaces = atspi_accessible_get_interfaces(mNode.get());
30     if (ifaces) {
31         for (unsigned int i = 0; i < ifaces->len; i++) {
32             char *iface = g_array_index(ifaces, char *, i);
33             if (!strcmp(iface, "Action"))
34                 mSupportingIfaces |=
35                     static_cast<int>(AccessibleNodeInterface::ACTION);
36             else if (!strcmp(iface, "Collection"))
37                 mSupportingIfaces |=
38                     static_cast<int>(AccessibleNodeInterface::COLLECTION);
39             else if (!strcmp(iface, "Component"))
40                 mSupportingIfaces |=
41                     static_cast<int>(AccessibleNodeInterface::COMPONENT);
42             else if (!strcmp(iface, "Document"))
43                 mSupportingIfaces |=
44                     static_cast<int>(AccessibleNodeInterface::DOCUMENT);
45             else if (!strcmp(iface, "EditableText"))
46                 mSupportingIfaces |=
47                     static_cast<int>(AccessibleNodeInterface::EDITABLETEXT);
48             else if (!strcmp(iface, "Hypertext"))
49                 mSupportingIfaces |=
50                     static_cast<int>(AccessibleNodeInterface::HYPERTEXT);
51             else if (!strcmp(iface, "Image"))
52                 mSupportingIfaces |=
53                     static_cast<int>(AccessibleNodeInterface::IMAGE);
54             else if (!strcmp(iface, "Selection"))
55                 mSupportingIfaces |=
56                     static_cast<int>(AccessibleNodeInterface::SELECTION);
57             else if (!strcmp(iface, "Text"))
58                 mSupportingIfaces |=
59                     static_cast<int>(AccessibleNodeInterface::TEXT);
60             else if (!strcmp(iface, "Value"))
61                 mSupportingIfaces |=
62                     static_cast<int>(AccessibleNodeInterface::VALUE);
63             else if (!strcmp(iface, "Accessible"))
64                 mSupportingIfaces |=
65                     static_cast<int>(AccessibleNodeInterface::ACCESSIBLE);
66             else if (!strcmp(iface, "Table"))
67                 mSupportingIfaces |=
68                     static_cast<int>(AccessibleNodeInterface::TABLE);
69             else if (!strcmp(iface, "TableCell"))
70                 mSupportingIfaces |=
71                     static_cast<int>(AccessibleNodeInterface::TABLECELL);
72             else
73                 LOG_F(WARNING, "Not Supported interface found %s", iface);
74
75             g_free(iface);
76         }
77
78         g_array_free(ifaces, FALSE);
79     }
80     this->refresh();
81 }
82
83 std::unique_ptr<AccessibleNode> AccessibleNode::get(AtspiAccessible *node)
84 {
85     return std::make_unique<AccessibleNode>(node);
86 }
87
88 void AccessibleNode::refresh() const
89 {
90     gchar *rolename = atspi_accessible_get_role_name(mNode.get(), NULL);
91     if (rolename) {
92         mRole = rolename;
93         g_free(rolename);
94     }
95
96     gchar *uID = atspi_accessible_get_unique_id(mNode.get(), NULL);
97     if (uID) {
98         mRes = uID;
99         g_free(uID);
100     }
101
102     GHashTable *attributes = atspi_accessible_get_attributes(mNode.get(), NULL);
103     char *t = (char*)g_hash_table_lookup(attributes, "type");
104     char *s = (char*)g_hash_table_lookup(attributes, "style");
105
106     if (t) mType =  std::string(t);
107     if (s) mStyle = std::string(s);
108
109     free(t);
110     free(s);
111
112     g_hash_table_unref(attributes);
113
114     AtspiStateSet *st = atspi_accessible_get_state_set(mNode.get());
115     GArray *states = atspi_state_set_get_states(st);
116
117     char *state_name = NULL;
118     AtspiStateType stat;
119     for (int i = 0; states && (i < states->len); ++i) {
120         stat = g_array_index(states, AtspiStateType, i);
121         setFeatureProperty(stat);
122     }
123
124     if (states) g_array_free(states, 0);
125     g_object_unref(st);
126 }
127
128 int AccessibleNode::getChildCount() const
129 {
130     return atspi_accessible_get_child_count(mNode.get(), NULL);
131 }
132
133 std::unique_ptr<AccessibleNode> AccessibleNode::getChildAt(int index) const
134 {
135     AtspiAccessible *child =
136         atspi_accessible_get_child_at_index(mNode.get(), index, NULL);
137     if (child) {
138         auto node = AccessibleNode::get(child);
139         g_object_unref(child);
140         return node;
141     }
142     return AccessibleNode::get(nullptr);
143 }
144
145 std::unique_ptr<AccessibleNode> AccessibleNode::getParent() const
146 {
147     AtspiAccessible *parent = atspi_accessible_get_parent(mNode.get(), NULL);
148     auto node = AccessibleNode::get(parent);
149     if (parent) g_object_unref(parent);
150     return node;
151 }
152
153 void AccessibleNode::print(int d, int m) const
154 {
155     if (m <= 0 || d > m) return;
156
157     int             n = 0;
158     this->print(d);
159     n = getChildCount();
160
161     for (int i = 0; i < n; i++) {
162         auto child = getChildAt(i);
163         if (child) child->print(d + 1, m);
164     }
165 }
166
167 void AccessibleNode::print(int d) const
168 {
169     char *name = atspi_accessible_get_name(mNode.get(), NULL);
170     char *role = atspi_accessible_get_role_name(mNode.get(), NULL);
171     LOG_F(INFO, "%s - %p(%s)  /  role:%s, pkg:%s, text:%s",
172           std::string(d, ' ').c_str(), mNode.get(), name, role, getPkg().c_str(),
173           getText().c_str());
174     free(name);
175     free(role);
176 }
177
178 bool AccessibleNode::isSupporting(AccessibleNodeInterface thisIface) const
179 {
180     return (mSupportingIfaces & static_cast<int>(thisIface)) != 0;
181 }
182
183 bool AccessibleNode::hasFeatureProperty(NodeFeatureProperties prop) const
184 {
185     return (mFeatureProperty & static_cast<int>(prop)) != 0;
186 }
187
188 void AccessibleNode::setFeatureProperty(AtspiStateType type) const
189 {
190 /*
191     LONGCLICKABLE = 0X0040,
192     SCROLLABLE = 0X0080,
193 */
194     switch(type) {
195         case ATSPI_STATE_CHECKED:
196             setFeatureProperty(NodeFeatureProperties::CHECKED, true);
197             break;
198         case ATSPI_STATE_CHECKABLE:
199             setFeatureProperty(NodeFeatureProperties::CHECKABLE, true);
200             break;
201         case ATSPI_STATE_ENABLED:
202             setFeatureProperty(NodeFeatureProperties::ENABLED, true);
203             break;
204         case ATSPI_STATE_FOCUSABLE:
205             setFeatureProperty(NodeFeatureProperties::FOCUSABLE, true);
206             break;
207         case ATSPI_STATE_FOCUSED:
208             setFeatureProperty(NodeFeatureProperties::FOCUSED, true);
209             break;
210         case ATSPI_STATE_SELECTABLE:
211             setFeatureProperty(NodeFeatureProperties::SELECTABLE, true);
212             break;
213         case ATSPI_STATE_SELECTED:
214             setFeatureProperty(NodeFeatureProperties::SELECTED, true);
215             break;
216         case ATSPI_STATE_SHOWING:
217             setFeatureProperty(NodeFeatureProperties::SHOWING, true);
218             break;
219         case ATSPI_STATE_VISIBLE:
220             setFeatureProperty(NodeFeatureProperties::VISIBLE, true);
221             break;
222         case ATSPI_STATE_ACTIVE:
223             setFeatureProperty(NodeFeatureProperties::ACTIVE, true);
224             break;
225         case ATSPI_STATE_SENSITIVE:
226             setFeatureProperty(NodeFeatureProperties::CLICKABLE, true);
227             break;
228
229         case ATSPI_STATE_TRANSIENT:
230         case ATSPI_STATE_TRUNCATED:
231         case ATSPI_STATE_ANIMATED:
232         case ATSPI_STATE_INVALID:
233         case ATSPI_STATE_ARMED:
234         case ATSPI_STATE_BUSY:
235         case ATSPI_STATE_COLLAPSED:
236         case ATSPI_STATE_DEFUNCT:
237         case ATSPI_STATE_EDITABLE:
238         case ATSPI_STATE_EXPANDABLE:
239         case ATSPI_STATE_EXPANDED:
240         case ATSPI_STATE_HAS_TOOLTIP:
241         case ATSPI_STATE_HORIZONTAL:
242         case ATSPI_STATE_ICONIFIED:
243         case ATSPI_STATE_MODAL:
244         case ATSPI_STATE_MULTI_LINE:
245         case ATSPI_STATE_MULTISELECTABLE:
246         case ATSPI_STATE_OPAQUE:
247         case ATSPI_STATE_PRESSED:
248         case ATSPI_STATE_RESIZABLE:
249         case ATSPI_STATE_SINGLE_LINE:
250         case ATSPI_STATE_STALE:
251         case ATSPI_STATE_VERTICAL:
252         case ATSPI_STATE_MANAGES_DESCENDANTS:
253         case ATSPI_STATE_INDETERMINATE:
254         case ATSPI_STATE_REQUIRED:
255         case ATSPI_STATE_INVALID_ENTRY:
256         case ATSPI_STATE_SUPPORTS_AUTOCOMPLETION:
257         case ATSPI_STATE_SELECTABLE_TEXT:
258         case ATSPI_STATE_IS_DEFAULT:
259         case ATSPI_STATE_VISITED:
260         case ATSPI_STATE_HAS_POPUP:
261         case ATSPI_STATE_READ_ONLY:
262         case ATSPI_STATE_LAST_DEFINED:
263         break;
264     }
265 }
266
267 void AccessibleNode::setFeatureProperty(NodeFeatureProperties prop, bool has) const
268 {
269     if (has)
270         mFeatureProperty |= static_cast<int>(prop);
271     else
272         mFeatureProperty &= ~static_cast<int>(prop);
273 }
274
275 std::string AccessibleNode::getDesc() const
276 {
277     return mDesc;
278 }
279
280 std::string AccessibleNode::getText() const
281 {
282     gchar *name = atspi_accessible_get_name(mNode.get(), NULL);
283     mText = name;
284     mPkg = name;
285     g_free(name);
286
287     return mText;
288 }
289
290 std::string AccessibleNode::getPkg() const
291 {
292     return mPkg;
293 }
294
295 std::string AccessibleNode::getRes() const
296 {
297     return mRes;
298 }
299
300 std::string AccessibleNode::getType() const
301 {
302     return mType;
303 }
304
305 std::string AccessibleNode::getStyle() const
306 {
307     return mStyle;
308 }
309
310 Rect<int> AccessibleNode::getBoundingBox() const
311 {
312     AtspiComponent *component = atspi_accessible_get_component_iface(mNode.get());
313     if (component) {
314         AtspiRect *extent = atspi_component_get_extents(
315             component, ATSPI_COORD_TYPE_SCREEN, NULL);
316         if (extent) {
317             mBoundingBox =
318                 Rect<int>{extent->x, extent->y, extent->x + extent->width,
319                           extent->y + extent->height};
320             g_free(extent);
321         }
322         g_object_unref(component);
323     }
324
325     return mBoundingBox;
326 }
327
328 bool AccessibleNode::isCheckable() const
329 {
330     return hasFeatureProperty(NodeFeatureProperties::CHECKABLE);
331 }
332
333 bool AccessibleNode::isChecked() const
334 {
335     return hasFeatureProperty(NodeFeatureProperties::CHECKED);
336 }
337
338 bool AccessibleNode::isClickable() const
339 {
340     return hasFeatureProperty(NodeFeatureProperties::CLICKABLE);
341 }
342
343 bool AccessibleNode::isEnabled() const
344 {
345     return hasFeatureProperty(NodeFeatureProperties::ENABLED);
346 }
347
348 bool AccessibleNode::isFocusable() const
349 {
350     return hasFeatureProperty(NodeFeatureProperties::FOCUSABLE);
351 }
352
353 bool AccessibleNode::isFocused() const
354 {
355     return hasFeatureProperty(NodeFeatureProperties::FOCUSED);
356 }
357
358 bool AccessibleNode::isLongClickable() const
359 {
360     return hasFeatureProperty(NodeFeatureProperties::LONGCLICKABLE);
361 }
362
363 bool AccessibleNode::isScrollable() const
364 {
365     return hasFeatureProperty(NodeFeatureProperties::SCROLLABLE);
366 }
367
368 bool AccessibleNode::isSelectable() const
369 {
370     return hasFeatureProperty(NodeFeatureProperties::SELECTABLE);
371 }
372
373 bool AccessibleNode::isSelected() const
374 {
375     return hasFeatureProperty(NodeFeatureProperties::SELECTED);
376 }
377
378 bool AccessibleNode::isVisible() const
379 {
380     return hasFeatureProperty(NodeFeatureProperties::VISIBLE);
381 }
382
383 bool AccessibleNode::isShowing() const
384 {
385     return hasFeatureProperty(NodeFeatureProperties::SHOWING);
386 }
387
388 bool AccessibleNode::isActive() const
389 {
390     return hasFeatureProperty(NodeFeatureProperties::ACTIVE);
391 }
392
393 AtspiAccessible *AccessibleNode::getAccessible() const
394 {
395     return mNode.get();
396 }
397
398 void AccessibleNode::setValue(std::string text) const
399 {
400     AtspiEditableText *iface = atspi_accessible_get_editable_text(mNode.get());
401     LOG_F(INFO,"set Value iface:%p obj:%p text:%s", iface, mNode.get(), text.c_str() );
402     if (iface) {
403         int len = getText().length();
404         atspi_editable_text_delete_text(iface, 0, len, NULL);
405         atspi_editable_text_insert_text(iface, 0, text.c_str(), text.length(),
406                                         NULL);
407     }
408 }
409
410 std::vector<std::string> AccessibleNode::getActions() const
411 {
412     std::vector<std::string> result{};
413     const char *name;
414     AtspiAction *action;
415
416     action = atspi_accessible_get_action_iface(mNode.get());
417     if (action) {
418         int a;
419         int n_actions = atspi_action_get_n_actions(action, NULL);
420
421         for (a = 0; a < n_actions; a++) {
422             char *action_name = atspi_action_get_action_name(action, a, NULL);
423             if (!action_name) continue;
424             result.push_back(std::string{action_name});
425             g_free(action_name);
426         }
427         g_object_unref(action);
428     }
429     return result;
430 }
431
432 bool AccessibleNode::doAction(std::string actionName) const
433 {
434     const char *name;
435     AtspiAction *action;
436
437     action = atspi_accessible_get_action_iface(mNode.get());
438     if (action) {
439         int a;
440         int n_actions = atspi_action_get_n_actions(action, NULL);
441
442         for (a = 0; a < n_actions; a++) {
443             char *action_name = atspi_action_get_action_name(action, a, NULL);
444             if (!action_name) return false;
445
446             if (!strcmp(actionName.c_str(), action_name)) {
447                 atspi_action_do_action(action, a, NULL);
448                 g_free(action_name);
449                 g_object_unref(action);
450                 return true;
451             }
452             g_free(action_name);
453         }
454         g_object_unref(action);
455     }
456     return false;
457 }