[LDTP-Dev] [PATCH] Support for handling pop up menu !!

J Premkumar jpremkumar at novell.com
Mon Nov 7 23:27:47 PST 2005


Hi All,

I have been working on providing support for handling pop menu obtained
by clicking the right mouse button. I have attached patch for addressing
the same. I need your inputs on improving this functionality. The
attached patch introduces a new API with the following signature.

      rightclick ('<window name>', '<component name>', '<menu item
name>', '<optional data>')

The basic idea is to generate a right click mouse event on the gui
object with the given component-name present in the window with the
given window name. The optional-data might be used for selecting the
exact part of the component on which right click should be fired. For
example, in case of tree table objects, the optional data repreasents
the value that a cell must have on which right click will be performed.

We have to provide a component function named 'rightclick' for all the
gui objects, in which the right click event will be fired and the
select_popup_menu() function in gui.c will take care of selecting the
appropriate menu item with the given menu item name from the menu popped
up.I have provided this function for tree-table.c. Similarly, we have to
provide the same for other objects too. We welcome volunteers to take up
the task of providing right click component function for various gui
objects.

Following are the assumptions made as of now ...

* The pop up menu is always the last child of the application whenever
it appears.
* The pop up menu is made of a single menu object which intern contains
a list of menu item objects.

Following are the limitations of the current implementation ...

* Only menu items in the first level can be selected
* The accuracy of the right click event fired depends on the accuracy
of AccessibleComponent_getExtents API to provide extents of the required
component.

Please review the attached patch. Looking forward to your comments.

Thanks
Premkumar 

Index: gui.c
===================================================================
RCS file: /cvs/pyldtp/gui.c,v
retrieving revision 1.60
diff -r1.60 gui.c
112a113,186
> int select_popup_menu (GHashTable *app, char *cont, char
*menu_item_name)
> {
>   GHashTable *cur_window;
>   GHashTable *component;
> 
>   Accessible *app_handle = NULL;
>   Accessible *pop_menu = NULL;
>   Accessible *menu = NULL;
>   Accessible *menu_item = NULL;
> 
>   char *parent;
>   char *name;
>   int count = 0;
>   int i;
> 
>   cur_window = g_hash_table_lookup (app, cont);
>   if (cur_window)
>     {
>       component = g_hash_table_lookup (cur_window, cont);
>       if (component)
> 	{
> 	  parent = g_hash_table_lookup (component, "parent");
> 	  app_handle = get_accessible_app_handle (parent);
> 	  count = Accessible_getChildCount (app_handle);
> 	  pop_menu = Accessible_getChildAtIndex (app_handle, count -
1);
> 	  Accessible_unref (app_handle);
> 	  if (Accessible_getChildCount (pop_menu) == 1)
> 	    {
> 	      menu = Accessible_getChildAtIndex (pop_menu, 0);
> 	      if (Accessible_getRole (menu) == SPI_ROLE_MENU)
> 		{
> 		  count = Accessible_getChildCount (menu);
> 		  Accessible_unref (pop_menu);
> 		  for (i = 0; i < count; i++)
> 		    {
> 		      menu_item = Accessible_getChildAtIndex (menu, i);
> 		      name = Accessible_getName (menu_item);
> 		      g_print ("ITEM NAME: %s\n", name);
> 		      if (name && g_utf8_collate (name, menu_item_name)
== 0)
> 			{
> 			  menu_item_main (menu_item, SELECTMENUITEM,
NULL);
> 			  SPI_freeString (name);
> 			  Accessible_unref (menu_item);
> 			  Accessible_unref (menu);
> 			  return 1;
> 			}
> 		      Accessible_unref (menu_item);
> 		      SPI_freeString (name);
> 		    }
> 		  log_msg (LOG_CAUSE, "Unable to find menu item in the
pop window");
> 		}
> 	      else
> 		  log_msg (LOG_CAUSE, "Unable to obtain menu handle");
> 	      Accessible_unref (menu);
> 	      return 0;
> 	    }
> 	  else
> 	    log_msg (LOG_CAUSE, "Unable to find pop menu");
> 	  Accessible_unref (pop_menu);
> 	  return 0;
> 	}
>       else
> 	{
> 	  log_msg (LOG_CAUSE, "Unable to find window information in
appmap");
> 	  return 0;
> 	}
>     }
>   else
>     {
>       log_msg (LOG_CAUSE, "Unable to find window in appmap");
>       return 0;
>     }
> }
> 
Index: gui.h
===================================================================
RCS file: /cvs/pyldtp/gui.h,v
retrieving revision 1.30
diff -r1.30 gui.h
272a273,274
> int select_popup_menu (GHashTable *app, char *cont, char
*menu_item_name);
> 
Index: ldtp.c
===================================================================
RCS file: /cvs/pyldtp/ldtp.c,v
retrieving revision 1.144
diff -r1.144 ldtp.c
1101a1102,1104
>   char *data;
>   char *menu_item;
>   int flag;
1103c1106
<   if (!PyArg_ParseTuple (args, "ss", &window_name, &component_name))
---
>   if (!PyArg_ParseTuple (args, "sss|s", &window_name,
&component_name, &menu_item, &data))
1105a1109,1112
>   params = malloc (sizeof (char) * 2);
>   params[0] = g_strdup (data);
>   params[1] = g_strdup ("1");
> 
1106a1114,1128
>   if (status)
>     {
>       flag = select_popup_menu (appmap, window_name, menu_item);
>       if (flag)
> 	status = Py_BuildValue ("i", 1);
>       else
> 	status = Py_BuildValue ("i", 0);
>     }
>   else
>     status = Py_BuildValue ("i", 0);
> 
>   g_free (params[0]);
>   g_free (params[1]);
>   g_free (params);
> 
Index: tree_table.c
===================================================================
RCS file: /cvs/pyldtp/tree_table.c,v
retrieving revision 1.48
diff -r1.48 tree_table.c
622c622
< static int right_click (Accessible *object)
---
> static int right_click (Accessible *object, char **params)
624,628c624,637
<   int i;
<   int action_count;
<   AccessibleAction *action;
< 	
<   action = Accessible_getAction (object);
---
>   int i, j, flag = 0;
>   long n_rows, n_cols;
>   Accessible *cell;
>   AccessibleTable *table;
>   char *name = NULL;
>   int n_matches, matches = 1;
>   long x, y, height, width;
> 
>   n_matches = atoi (params[1]);
>     
>   table = Accessible_getTable (object);
>   n_rows = AccessibleTable_getNRows (table);
>   n_cols = AccessibleTable_getNColumns (table);
>   g_print ("Number of rows: %ld\tColumn: %ld\n", n_rows, n_cols);
630,631c639
<   action_count = AccessibleAction_getNActions (action);
<   for (i = 0; i < action_count; i++)
---
>   for (i = 0; i < n_rows; i++)
633,638c641,717
<       char *name, *desc;
<       name = AccessibleAction_getName (action, i);
<       desc = AccessibleAction_getDescription (action, i);
<       g_print ("Actions list - name: %s, desc: %s\n", name, desc);
<       SPI_freeString (name);
<       SPI_freeString (desc);
---
>       for (j = 0; j < n_cols; j++)
> 	{
> 	  long child_count;
> 	  cell = AccessibleTable_getAccessibleAt (table, i, j);
> 	  child_count = Accessible_getChildCount (cell);
> 	  if (child_count > 0)
> 	    {
> 	      int i;
> 
> 	      Accessible *child;
> 	      for (i = 0; i < child_count; i++)
> 		{
> 		  child = Accessible_getChildAtIndex (cell, i);
> 		  name = Accessible_getName (child);
> 		  if (g_utf8_collate (name, params[0]) == 0)
> 		    {
> 		      if (n_matches != matches)
> 			{
> 			  matches++;
> 			  Accessible_unref (child);
> 			  continue;
> 			} 
> 
> 		      if (Accessible_isComponent (cell))
> 			{
> 			  AccessibleComponent *accessible_component;
> 			  accessible_component = Accessible_getComponent
(cell);
> 			  AccessibleComponent_getExtents
(accessible_component,
> 							  &x, &y,
&height, &width,
> 							 
SPI_COORD_TYPE_SCREEN);
> 			  flag = 1;
> 			  Accessible_unref (accessible_component);
> 			}
> 		      SPI_freeString (name);
> 		      Accessible_unref (child);
> 		      Accessible_unref (cell);
> 		      break;
> 		    } // if
> 		  SPI_freeString (name);
> 		  Accessible_unref (child);
> 		} // for
> 	    } // if
> 	  else 
> 	    {
> 	      name = Accessible_getName (cell);
> 	      if (g_utf8_collate (name, params[0]) == 0)
> 		{
> 		  if (Accessible_isComponent (cell))
> 		    {
> 		      AccessibleComponent *accessible_component;
> 		      accessible_component = Accessible_getComponent
(cell);
> 		      AccessibleComponent_getExtents
(accessible_component,
> 						      &x, &y, &height,
&width,
> 						     
SPI_COORD_TYPE_SCREEN);
> 		      flag = 1;
> 		      Accessible_unref (accessible_component);
> 		    }
> 		  SPI_freeString (name);
> 		  Accessible_unref (cell);
> 		  break;
> 		}
> 	    }
> 	  Accessible_unref (cell);
> 	} // for j
>       if (flag == 1)
> 	break;
>     } // for i
>   Accessible_unref (table);
>   if (flag)
>     {
>       if (SPI_generateMouseEvent (x, y, "b3c"))
> 	{
> 	  sleep (5);
> 	  return 1;
> 	}
>       else
> 	return 0;
640,646c719,720
<   /*
<     FIXME: Need to execute dynamic types
<     To execute menu action
<   */
<   AccessibleAction_doAction (action, 1);
<   Accessible_unref (action);
<   return 1;
---
>   else
>     return 0;
649d722
< 
1062c1135
<       return right_click (object);
---
>       return right_click (object, params);



More information about the Ldtp-dev mailing list