Mercurial > hg > ccmiandroid
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(); |