comparison src/uk/ac/qmul/eecs/ccmi/activities/TreeNavigation.java @ 1:66b3a838feca logging tip

Added logging of user interaction
author Fiore Martin <fiore@eecs.qmul.ac.uk>
date Tue, 12 Feb 2013 15:31:48 +0000
parents e0ee6ac3a45f
children
comparison
equal deleted inserted replaced
0:e0ee6ac3a45f 1:66b3a838feca
28 28
29 import uk.ac.qmul.eecs.ccmi.accessibility.AccessibilityService; 29 import uk.ac.qmul.eecs.ccmi.accessibility.AccessibilityService;
30 import uk.ac.qmul.eecs.ccmi.accessibility.AccessibilityService.SoundEvent; 30 import uk.ac.qmul.eecs.ccmi.accessibility.AccessibilityService.SoundEvent;
31 import uk.ac.qmul.eecs.ccmi.accessibility.AccessibleCheckbox; 31 import uk.ac.qmul.eecs.ccmi.accessibility.AccessibleCheckbox;
32 import uk.ac.qmul.eecs.ccmi.accessibility.AccessibleDialogBuilder; 32 import uk.ac.qmul.eecs.ccmi.accessibility.AccessibleDialogBuilder;
33 import uk.ac.qmul.eecs.ccmi.utilities.ILogger;
33 import uk.ac.qmul.eecs.ccmi.utilities.Stack; 34 import uk.ac.qmul.eecs.ccmi.utilities.Stack;
34 import uk.ac.qmul.eecs.ccmi.xmlparser.Diagram; 35 import uk.ac.qmul.eecs.ccmi.xmlparser.Diagram;
35 import uk.ac.qmul.eecs.ccmi.xmlparser.DiagramUpdater; 36 import uk.ac.qmul.eecs.ccmi.xmlparser.DiagramUpdater;
36 import uk.ac.qmul.eecs.ccmi.xmlparser.Edge; 37 import uk.ac.qmul.eecs.ccmi.xmlparser.Edge;
37 import uk.ac.qmul.eecs.ccmi.xmlparser.EdgeNode; 38 import uk.ac.qmul.eecs.ccmi.xmlparser.EdgeNode;
499 Controller(AccessibleDialogBuilder dialogBuilder){ 500 Controller(AccessibleDialogBuilder dialogBuilder){
500 this.dialogBuilder = dialogBuilder; 501 this.dialogBuilder = dialogBuilder;
501 }; 502 };
502 503
503 /* 504 /*
504 * Responds to the long cick of the user. It acts according to the list item clicked 505 * Responds to the long click of the user. It acts according to the list item clicked
505 * by the user (and therefore according to the hierarchy level currently displayed). 506 * by the user (and therefore according to the hierarchy level currently displayed).
506 * When a dialog needs to be shown, it used dialogBuilder.displayDialog() and register itself 507 * When a dialog needs to be shown, it used dialogBuilder.displayDialog() and register itself
507 * as buttoClickListener to handle the click of the user in the same class. 508 * as buttoClickListener to handle the click of the user in the same class.
508 */ 509 */
509 public boolean performEditAction(AdapterView<?> parent, View view, 510 public boolean performEditAction(AdapterView<?> parent, View view,
520 properties.add(new NodeProperty(pType.getType())); 521 properties.add(new NodeProperty(pType.getType()));
521 } 522 }
522 /* construct the node and add it to the diagram */ 523 /* construct the node and add it to the diagram */
523 Node node = new Node(((NodeType)clickedItem).getType(),properties); 524 Node node = new Node(((NodeType)clickedItem).getType(),properties);
524 diagramUpdater.addNode(node); 525 diagramUpdater.addNode(node);
526 dialogBuilder.getAccessibilityService().playSound(SoundEvent.V_OK);
525 dialogBuilder.getAccessibilityService().speak("Node "+ node +" created"); 527 dialogBuilder.getAccessibilityService().speak("Node "+ node +" created");
528 ILogger.log("Node "+ node +" created");
526 }else{ // user clicked on edge 529 }else{ // user clicked on edge
527 List<EdgeType> edgeTypes = diagram.getPrototypes().getEdgeTypes(); 530 List<EdgeType> edgeTypes = diagram.getPrototypes().getEdgeTypes();
528 clickedItem = edgeTypes.get(position - nodeTypes.size()); 531 clickedItem = edgeTypes.get(position - nodeTypes.size());
529 /* respect min and max attached nodes */ 532 /* respect min and max attached nodes */
530 if(selectedNodes.size() < ((EdgeType)clickedItem).getMinAttachedNodes()){ 533 if(selectedNodes.size() < ((EdgeType)clickedItem).getMinAttachedNodes()){
534 dialogBuilder.getAccessibilityService().playSound(SoundEvent.V_ERROR);
531 dialogBuilder.getAccessibilityService().speak("you must select at least "+ 535 dialogBuilder.getAccessibilityService().speak("you must select at least "+
532 ((EdgeType)clickedItem).getMinAttachedNodes()+" nodes"); 536 ((EdgeType)clickedItem).getMinAttachedNodes()+" nodes");
537 ILogger.logError("selected nodes < "+((EdgeType)clickedItem).getMinAttachedNodes());
533 return true; 538 return true;
534 } 539 }
535 if(selectedNodes.size() > ((EdgeType)clickedItem).getMaxAttachedNodes()){ 540 if(selectedNodes.size() > ((EdgeType)clickedItem).getMaxAttachedNodes()){
541 dialogBuilder.getAccessibilityService().playSound(SoundEvent.V_ERROR);
536 dialogBuilder.getAccessibilityService().speak("you must select at most "+ 542 dialogBuilder.getAccessibilityService().speak("you must select at most "+
537 ((EdgeType)clickedItem).getMaxAttachedNodes()+" nodes"); 543 ((EdgeType)clickedItem).getMaxAttachedNodes()+" nodes");
544 ILogger.logError("selected nodes > "+((EdgeType)clickedItem).getMaxAttachedNodes());
538 return true; 545 return true;
539 } 546 }
540 547
541 /* create the edge and add the edge nodes */ 548 /* create the edge and add the edge nodes */
542 Edge edge = new Edge(((EdgeType)clickedItem).getType()); 549 Edge edge = new Edge(((EdgeType)clickedItem).getType());
545 for(Node n : diagram.getComponents().getNodes()){ 552 for(Node n : diagram.getComponents().getNodes()){
546 if(selectedNodes.contains(n)) 553 if(selectedNodes.contains(n))
547 edge.getAttachedNodes().add(new EdgeNode(n.getId())); 554 edge.getAttachedNodes().add(new EdgeNode(n.getId()));
548 } 555 }
549 diagramUpdater.addEdge(edge); 556 diagramUpdater.addEdge(edge);
557 dialogBuilder.getAccessibilityService().playSound(SoundEvent.V_OK);
550 StringBuilder builder = new StringBuilder(); 558 StringBuilder builder = new StringBuilder();
551 builder.append(edge).append(" created between "); 559 builder.append(edge).append(" created between ");
552 for(int i=0; i<selectedNodes.size(); i++){ 560 for(int i=0; i<selectedNodes.size(); i++){
553 Node sn = selectedNodes.get(i); 561 Node sn = selectedNodes.get(i);
554 builder.append(sn.getName()); 562 builder.append(sn.getName());
558 builder.append(", "); 566 builder.append(", ");
559 } 567 }
560 } 568 }
561 selectedNodes.clear(); // when an edge is added the selected node are cleared 569 selectedNodes.clear(); // when an edge is added the selected node are cleared
562 dialogBuilder.getAccessibilityService().speak(builder.toString()); 570 dialogBuilder.getAccessibilityService().speak(builder.toString());
571 ILogger.log(builder.toString());
563 } 572 }
564 /* update the view */ 573 /* update the view */
565 cachedList = buildCurrentChildList(); 574 cachedList = buildCurrentChildList();
566 updateable.update(); 575 updateable.update();
567 return true; 576 return true;
609 } 618 }
610 } 619 }
611 return false; 620 return false;
612 } 621 }
613 622
614 /* this is the callback triggered when the user clicks on any bottom of the dialog shown. v is the button 623 /* this is the callback triggered when the user clicks on any botton of the dialog shown. v is the button
615 * The method first checks for the dialog tag to understand which dialog it's handling, then it checks 624 * The method first checks for the dialog tag to understand which dialog it's handling, then it checks
616 * for the button tag to understand which button the user pressed. The first check though is on "CANCEL" 625 * for the button tag to understand which button the user pressed. The first check though is on "CANCEL"
617 * button as its tag it's the same for all the dialog */ 626 * button as its tag it's the same for all the dialog */
618 @Override 627 @Override
619 public void onClick(View v, DialogFragment dialogFragment, String dialogTag) { 628 public void onClick(View v, DialogFragment dialogFragment, String dialogTag) {
620 Object buttonTag = v.getTag(); 629 Object buttonTag = v.getTag();
630 ILogger.logButton(buttonTag.toString());
621 AccessibilityService accessibility = dialogBuilder.getAccessibilityService(); 631 AccessibilityService accessibility = dialogBuilder.getAccessibilityService();
622 632
623 if("CANCEL".equals(buttonTag)){ 633 if("CANCEL".equals(buttonTag)){
634 accessibility.playSound(SoundEvent.V_CANCEL);
624 accessibility.speak("Cancel"); 635 accessibility.speak("Cancel");
625 dialogFragment.dismiss(); 636 dialogFragment.dismiss();
626 return; 637 return;
627 } 638 }
628 639
629 if(EDIT_NODE_DIALOG_TAG.equals(dialogTag) || EDIT_EDGE_DIALOG_TAG.equals(dialogTag)){ 640 if(EDIT_NODE_DIALOG_TAG.equals(dialogTag) || EDIT_EDGE_DIALOG_TAG.equals(dialogTag)){
630 if("SELECT".equals(buttonTag)){ 641 if("SELECT".equals(buttonTag)){
631 selectedNodes.add((Node)clickedItem); 642 selectedNodes.add((Node)clickedItem);
632 accessibility.playSound(SoundEvent.V_OK); 643 accessibility.playSound(SoundEvent.V_OK);
633 accessibility.speak(clickedItem + " selected"); 644 accessibility.speak(clickedItem + " selected");
645 ILogger.log(clickedItem + " selected");
634 }else if("UNSELECT".equals(buttonTag)){ 646 }else if("UNSELECT".equals(buttonTag)){
635 selectedNodes.remove(clickedItem); 647 selectedNodes.remove(clickedItem);
636 accessibility.playSound(SoundEvent.V_OK); 648 accessibility.playSound(SoundEvent.V_OK);
637 accessibility.speak(clickedItem + " unselected"); 649 accessibility.speak(clickedItem + " unselected");
650 ILogger.log(clickedItem + " unselected");
638 }else if("RENAME".equals(buttonTag)){ 651 }else if("RENAME".equals(buttonTag)){
639 dialogFragment.dismiss(); 652 dialogFragment.dismiss();
640 dialogBuilder.displayDialog(R.layout.alert_dialog_rename, RENAME_DIALOG_TAG+clickedItem, this); 653 dialogBuilder.displayDialog(R.layout.alert_dialog_rename, RENAME_DIALOG_TAG+clickedItem, this);
641 }else if("DELETE".equals(buttonTag)){ 654 }else if("DELETE".equals(buttonTag)){
642 dialogFragment.dismiss(); 655 dialogFragment.dismiss();
652 EditText editText = (EditText)dialogFragment.getDialog().findViewById(R.id.text_edit); 665 EditText editText = (EditText)dialogFragment.getDialog().findViewById(R.id.text_edit);
653 String text = editText.getText().toString().trim(); 666 String text = editText.getText().toString().trim();
654 if(text.length() == 0){ 667 if(text.length() == 0){
655 accessibility.playSound(SoundEvent.V_ERROR); 668 accessibility.playSound(SoundEvent.V_ERROR);
656 accessibility.speak("Text cannot be empty"); 669 accessibility.speak("Text cannot be empty");
670 ILogger.logError("text empty");
657 return; 671 return;
658 } 672 }
659 String oldName = clickedItem.toString(); 673 String oldName = clickedItem.toString();
660 diagramUpdater.rename(clickedItem,text); 674 diagramUpdater.rename(clickedItem,text);
661 accessibility.playSound(SoundEvent.V_OK); 675 accessibility.playSound(SoundEvent.V_OK);
662 accessibility.speak(oldName+" renamed to "+clickedItem); 676 accessibility.speak(oldName+" renamed to "+clickedItem);
677 ILogger.log(oldName+" renamed to "+clickedItem);
663 }else if(dialogTag.startsWith(CONFIRMATION_DIALOG_TAG)){ 678 }else if(dialogTag.startsWith(CONFIRMATION_DIALOG_TAG)){
664 /* if it reaches this point it's a "YES" as a "NO" button has "CANCEL" as its tag */ 679 /* if it reaches this point it's a "YES" as a "NO" button has "CANCEL" as its tag */
665 /* and the match against "CANCEL" match is performed first of all */ 680 /* and the match against "CANCEL" match is performed first of all */
666 diagramUpdater.delete(clickedItem); 681 diagramUpdater.delete(clickedItem);
667 /* if it's a selected node, remove it from selected */ 682 /* if it's a selected node, remove it from selected */
668 selectedNodes.remove(clickedItem); 683 selectedNodes.remove(clickedItem);
684 accessibility.playSound(SoundEvent.V_OK);
669 accessibility.speak(clickedItem+" Deleted"); 685 accessibility.speak(clickedItem+" Deleted");
686 ILogger.log(clickedItem+" Deleted");
670 /* update the headers which show the number of children the current item contains */ 687 /* update the headers which show the number of children the current item contains */
671 if(path.current() instanceof NodeType || path.current() instanceof EdgeType){ 688 if(path.current() instanceof NodeType || path.current() instanceof EdgeType){
672 cachedHeaderTexts.pop(); 689 cachedHeaderTexts.pop();
673 cachedHeaderTexts.push(path.current()+" ("+count(path.current())+')'); 690 cachedHeaderTexts.push(path.current()+" ("+count(path.current())+')');
674 }else if(path.current() instanceof NodeProperty){ 691 }else if(path.current() instanceof NodeProperty){
681 EditText editText = (EditText)dialogFragment.getDialog().findViewById(R.id.text_edit); 698 EditText editText = (EditText)dialogFragment.getDialog().findViewById(R.id.text_edit);
682 String text = editText.getText().toString().trim(); 699 String text = editText.getText().toString().trim();
683 if(text.length() == 0){ 700 if(text.length() == 0){
684 accessibility.playSound(SoundEvent.V_ERROR); 701 accessibility.playSound(SoundEvent.V_ERROR);
685 accessibility.speak("Text cannot be empty"); 702 accessibility.speak("Text cannot be empty");
703 ILogger.logError("text empty");
686 return; 704 return;
687 } 705 }
688 diagramUpdater.addProperty((Node)path.get(ITEM_LEVEL),((NodeProperty)clickedItem),text); 706 diagramUpdater.addProperty((Node)path.get(ITEM_LEVEL),((NodeProperty)clickedItem),text);
689 accessibility.playSound(SoundEvent.V_OK); 707 accessibility.playSound(SoundEvent.V_OK);
690 accessibility.speak("Property "+text+" added"); 708 accessibility.speak("Property "+text+" added");
709 ILogger.log("Property "+text+" added");
691 }else if(EDIT_NODE_REF_DIALOG_TAG.equals(dialogTag)){ 710 }else if(EDIT_NODE_REF_DIALOG_TAG.equals(dialogTag)){
692 if("EDIT_LABEL".equals(buttonTag)){ 711 if("EDIT_LABEL".equals(buttonTag)){
693 dialogFragment.dismiss(); 712 dialogFragment.dismiss();
694 dialogBuilder.displayDialog(R.layout.alert_dialog_rename, EDIT_LABEL_DIALOG_TAG, this); 713 dialogBuilder.displayDialog(R.layout.alert_dialog_rename, EDIT_LABEL_DIALOG_TAG, this);
695 }else{ // EDIT_ARROWHEAD 714 }else{ // EDIT_ARROWHEAD
706 } 725 }
707 } 726 }
708 if(heads == null || heads.length == 0){ 727 if(heads == null || heads.length == 0){
709 accessibility.playSound(SoundEvent.V_ERROR); 728 accessibility.playSound(SoundEvent.V_ERROR);
710 accessibility.speak("There are no arrow heads defined for "+edge); 729 accessibility.speak("There are no arrow heads defined for "+edge);
730 ILogger.logError("There are no arrow heads defined for "+edge);
711 return; 731 return;
712 } 732 }
713 dialogBuilder.displaySelectionDialog(EDIT_ARROWHEAD_DIALOG_TAG, heads, this); 733 dialogBuilder.displaySelectionDialog(EDIT_ARROWHEAD_DIALOG_TAG, heads, this);
714 } 734 }
715 }else if(EDIT_LABEL_DIALOG_TAG.equals(dialogTag)){ 735 }else if(EDIT_LABEL_DIALOG_TAG.equals(dialogTag)){
716 EditText editText = (EditText)dialogFragment.getDialog().findViewById(R.id.text_edit); 736 EditText editText = (EditText)dialogFragment.getDialog().findViewById(R.id.text_edit);
717 String text = editText.getText().toString().trim(); 737 String text = editText.getText().toString().trim();
718 if(text.length() == 0){ 738 if(text.length() == 0){
719 accessibility.playSound(SoundEvent.V_ERROR); 739 accessibility.playSound(SoundEvent.V_ERROR);
720 accessibility.speak("Text cannot be empty"); 740 accessibility.speak("Text cannot be empty");
741 ILogger.logError("Text empty");
721 return; 742 return;
722 } 743 }
723 diagramUpdater.setLabel((EdgeNode)clickedItem,text); 744 diagramUpdater.setLabel((EdgeNode)clickedItem,text);
724 accessibility.playSound(SoundEvent.V_OK); 745 accessibility.playSound(SoundEvent.V_OK);
725 accessibility.speak("Label set to "+clickedItem);// EdgeNode.toString = EdgeNode.getLabel 746 accessibility.speak("Label set to "+clickedItem);// EdgeNode.toString = EdgeNode.getLabel
747 ILogger.log("Label set to "+clickedItem);
726 }else if(EDIT_ARROWHEAD_DIALOG_TAG.equals(dialogTag)){ 748 }else if(EDIT_ARROWHEAD_DIALOG_TAG.equals(dialogTag)){
727 Spinner spinner = (Spinner)dialogFragment.getDialog().findViewById(R.id.selectionSpinner); 749 Spinner spinner = (Spinner)dialogFragment.getDialog().findViewById(R.id.selectionSpinner);
728 ((EdgeNode)clickedItem).setHead(spinner.getSelectedItem().toString()); 750 diagramUpdater.setArrowHead((EdgeNode)clickedItem, spinner.getSelectedItem().toString());
729 accessibility.playSound(SoundEvent.V_OK); 751 accessibility.playSound(SoundEvent.V_OK);
730 accessibility.speak("Arrow head set to "+spinner.getSelectedItem().toString()); 752 accessibility.speak("Arrow head set to "+spinner.getSelectedItem().toString());
753 ILogger.log("Arrow head set to "+spinner.getSelectedItem().toString());
731 }else if(EDIT_PROPERTY_DIALOG_TAG.equals(dialogTag)){ 754 }else if(EDIT_PROPERTY_DIALOG_TAG.equals(dialogTag)){
732 if("RENAME".equals(buttonTag)){ 755 if("RENAME".equals(buttonTag)){
733 dialogFragment.dismiss(); 756 dialogFragment.dismiss();
734 dialogBuilder.displayDialog(R.layout.alert_dialog_rename, RENAME_DIALOG_TAG, this); 757 dialogBuilder.displayDialog(R.layout.alert_dialog_rename, RENAME_DIALOG_TAG, this);
735 }else if("DELETE".equals(buttonTag)){ 758 }else if("DELETE".equals(buttonTag)){
764 }else if(EDIT_MODIFIERS_DIALOG_TAG.equals(dialogTag)){ 787 }else if(EDIT_MODIFIERS_DIALOG_TAG.equals(dialogTag)){
765 /* pressed button is OK as CANCEL would have been cought at the beginning */ 788 /* pressed button is OK as CANCEL would have been cought at the beginning */
766 AccessibleCheckbox checkbox = (AccessibleCheckbox)dialogFragment.getDialog().findViewById(R.id.checkBox); 789 AccessibleCheckbox checkbox = (AccessibleCheckbox)dialogFragment.getDialog().findViewById(R.id.checkBox);
767 boolean[] checks = checkbox.getChecks(); 790 boolean[] checks = checkbox.getChecks();
768 List<Integer> modifiers = new ArrayList<Integer>(checks.length); 791 List<Integer> modifiers = new ArrayList<Integer>(checks.length);
792 StringBuilder modifiersString = new StringBuilder();
769 for(int i=0; i<checks.length; i++){ 793 for(int i=0; i<checks.length; i++){
770 if(checks[i]) 794 if(checks[i]){
771 modifiers.add(i); 795 modifiers.add(i);
796 modifiersString.append(i).append(' ');
797 }
772 } 798 }
773 diagramUpdater.setModifiers((PropertyValue)clickedItem, modifiers); 799 diagramUpdater.setModifiers((PropertyValue)clickedItem, modifiers);
800 accessibility.playSound(SoundEvent.V_OK);
801 accessibility.speak("modifiers set for "+path.current());
802 if(modifiersString.length() == 0)
803 modifiersString.append("no modifiers");
804 ILogger.log("modifiers set for "+path.current()+": "+ modifiersString.toString());
774 } 805 }
775 /* update the view */ 806 /* update the view */
776 cachedList = buildCurrentChildList(); 807 cachedList = buildCurrentChildList();
777 updateable.update(); 808 updateable.update();
778 dialogFragment.dismiss(); 809 dialogFragment.dismiss();