private String getRepetitionText(String type, FormIndex index, boolean newrep) {
    if (element instanceof GroupDef
        && ((GroupDef) element).getRepeat()
        && index.getElementMultiplicity() >= 0) {
      GroupDef g = (GroupDef) element;

      String title = getLongText();
      int ix = index.getElementMultiplicity() + 1;
      int count = getNumRepetitions();

      String caption = null;
      if ("header".equals(type)) {
        caption = g.entryHeader;
      } else if ("choose".equals(type)) {
        caption = g.chooseCaption;
        if (caption == null) {
          caption = g.entryHeader;
        }
      }
      if (caption == null) {
        return title + " " + ix + "/" + count;
      }

      HashMap<String, Object> vars = new HashMap<String, Object>();
      vars.put("name", title);
      vars.put("i", Integer.valueOf(ix));
      vars.put("n", Integer.valueOf(count));
      vars.put("new", new Boolean(newrep));
      return form.fillTemplateString(caption, index.getReference(), vars);
    } else {
      return null;
    }
  }
Exemple #2
0
  public boolean equals(Object o) {
    if (!(o instanceof FormIndex)) return false;

    FormIndex a = this;
    FormIndex b = (FormIndex) o;

    return (a.compareTo(b) == 0);

    //		//TODO: while(true) loops freak me out, this should probably
    //		//get written more safely. -ctsims
    //
    //		//Iterate over each level of reference, and identify whether
    //		//each object stays in sync
    //		while(true) {
    //			if(index.isTerminal() != local.isTerminal() ||
    //					index.getLocalIndex() != local.getLocalIndex() ||
    //					index.getInstanceIndex() != local.getInstanceIndex()) {
    //				return false;
    //			}
    //			if(index.isTerminal()) {
    //				return true;
    //			}
    //			local = local.getNextLevel();
    //			index = index.getNextLevel();
    //		}
    //
  }
Exemple #3
0
 public IFormElement getChild(FormIndex index) {
   IFormElement element = this;
   while (index != null && index.isInForm()) {
     element = element.getChild(index.getLocalIndex());
     index = index.getNextLevel();
   }
   return element;
 }
Exemple #4
0
 public String toString() {
   String ret = "";
   FormIndex ref = this;
   while (ref != null) {
     ret += ref.getLocalIndex();
     ret += ref.getInstanceIndex() == -1 ? ", " : "_" + ref.getInstanceIndex() + ", ";
     ref = ref.nextLevel;
   }
   return ret;
 }
Exemple #5
0
 /**
  * Trims any negative indices from the end of the passed in index.
  *
  * @param index
  * @return
  */
 public static FormIndex trimNegativeIndices(FormIndex index) {
   if (!index.isTerminal()) {
     return new FormIndex(trimNegativeIndices(index.nextLevel), index);
   } else {
     if (index.getLocalIndex() < 0) {
       return null;
     } else {
       return index;
     }
   }
 }
Exemple #6
0
 /**
  * Takes in a form index which is a subset of this index, and returns the total difference between
  * them. This is useful for stepping up the level of index specificty. If the subIndex is not a
  * valid subIndex of this index, null is returned. Since the FormIndex represented by null is
  * always a subset, if null is passed in as a subIndex, the full index is returned
  *
  * <p>For example: Indices a = 1_0,2,1,3 b = 1,3
  *
  * <p>a.diff(b) = 1_0,2
  *
  * @param subIndex
  * @return
  */
 public FormIndex diff(FormIndex subIndex) {
   if (subIndex == null) {
     return this;
   }
   if (!isSubIndex(this, subIndex)) {
     return null;
   }
   if (subIndex.equals(this)) {
     return null;
   }
   return new FormIndex(nextLevel.diff(subIndex), this.snip());
 }
Exemple #7
0
 /**
  * Constructs an index which references an element past the level of specificity of the current
  * context, founded by the currentLevel index. (currentLevel, (nextLevel...))
  */
 public FormIndex(FormIndex nextLevel, FormIndex currentLevel) {
   if (currentLevel == null) {
     this.nextLevel = nextLevel.nextLevel;
     this.localIndex = nextLevel.localIndex;
     this.instanceIndex = nextLevel.instanceIndex;
     this.reference = nextLevel.reference;
   } else {
     this.nextLevel = nextLevel;
     this.localIndex = currentLevel.getLocalIndex();
     this.instanceIndex = currentLevel.getInstanceIndex();
     this.reference = currentLevel.reference;
   }
 }
Exemple #8
0
  public boolean canCreateRepeat(TreeReference repeatRef, FormIndex repeatIndex) {
    GroupDef repeat = (GroupDef) this.getChild(repeatIndex);

    // Check to see if this repeat can have children added by the user
    if (repeat.noAddRemove) {
      // Check to see if there's a count to use to determine how many children this repeat
      // should have
      if (repeat.getCountReference() != null) {
        int currentMultiplicity = repeatIndex.getElementMultiplicity();

        // get the total multiplicity possible
        long fullcount =
            ((Integer) this.getInstance().getDataValue(repeat.getCountReference()).getValue())
                .intValue();

        if (fullcount <= currentMultiplicity) {
          return false;
        }
      } else {
        // Otherwise the user can never add repeat instances
        return false;
      }
    }

    // TODO: If we think the node is still relevant, we also need to figure out a way to test that
    // assumption against
    // the repeat's constraints.

    return true;
  }
  // TODO: this is explicitly missing integration with the new multi-media support
  // TODO: localize the default captions
  public String getRepeatText(String typeKey) {
    GroupDef g = (GroupDef) element;
    if (!g.getRepeat()) {
      throw new RuntimeException("not a repeat");
    }

    String title = getLongText();
    int count = getNumRepetitions();

    String caption = null;
    if ("mainheader".equals(typeKey)) {
      caption = g.mainHeader;
      if (caption == null) {
        return title;
      }
    } else if ("add".equals(typeKey)) {
      caption = g.addCaption;
      if (caption == null) {
        return "Add another " + title;
      }
    } else if ("add-empty".equals(typeKey)) {
      caption = g.addEmptyCaption;
      if (caption == null) {
        caption = g.addCaption;
      }
      if (caption == null) {
        return "None - Add " + title;
      }
    } else if ("del".equals(typeKey)) {
      caption = g.delCaption;
      if (caption == null) {
        return "Delete " + title;
      }
    } else if ("done".equals(typeKey)) {
      caption = g.doneCaption;
      if (caption == null) {
        return "Done";
      }
    } else if ("done-empty".equals(typeKey)) {
      caption = g.doneEmptyCaption;
      if (caption == null) {
        caption = g.doneCaption;
      }
      if (caption == null) {
        return "Skip";
      }
    } else if ("delheader".equals(typeKey)) {
      caption = g.delHeader;
      if (caption == null) {
        return "Delete which " + title + "?";
      }
    }

    HashMap<String, Object> vars = new HashMap<String, Object>();
    vars.put("name", title);
    vars.put("n", Integer.valueOf(count));
    return form.fillTemplateString(caption, index.getReference(), vars);
  }
Exemple #10
0
  public void collapseIndex(
      FormIndex index, Vector indexes, Vector multiplicities, Vector elements) {
    if (!index.isInForm()) {
      return;
    }

    IFormElement element = this;
    while (index != null) {
      int i = index.getLocalIndex();
      element = element.getChild(i);

      indexes.addElement(new Integer(i));
      multiplicities.addElement(
          new Integer(index.getInstanceIndex() == -1 ? 0 : index.getInstanceIndex()));
      elements.addElement(element);

      index = index.getNextLevel();
    }
  }
Exemple #11
0
 public static boolean isSubIndex(FormIndex parent, FormIndex child) {
   if (child.equals(parent)) {
     return true;
   } else {
     if (parent == null) {
       return false;
     }
     return isSubIndex(parent.nextLevel, child);
   }
 }
Exemple #12
0
  // if exact = true: return the index of a value, -1 if not present
  // if exact = false: return the index of the highest value <= the target value, -1 if all values
  // are greater than the target value
  public int indexOf(FormIndex index, boolean exact) {
    int lo = 0;
    int hi = v.size() - 1;

    while (lo <= hi) {
      int mid = (lo + hi) / 2;
      FormIndex val = get(mid);

      if (val.compareTo(index) < 0) {
        lo = mid + 1;
      } else if (val.compareTo(index) > 0) {
        hi = mid - 1;
      } else {
        return mid;
      }
    }

    return exact ? -1 : lo - 1;
  }
Exemple #13
0
  public int getNumRepetitions(FormIndex index) {
    Vector indexes = new Vector();
    Vector multiplicities = new Vector();
    Vector elements = new Vector();

    if (!index.isInForm()) {
      throw new RuntimeException("not an in-form index");
    }

    collapseIndex(index, indexes, multiplicities, elements);

    if (!(elements.lastElement() instanceof GroupDef)
        || !((GroupDef) elements.lastElement()).getRepeat()) {
      throw new RuntimeException("current element not a repeat");
    }

    // so painful
    TreeElement templNode = instance.getTemplate(index.getReference());
    TreeReference parentPath = templNode.getParent().getRef().genericize();
    TreeElement parentNode =
        instance.resolveReference(parentPath.contextualize(index.getReference()));
    return parentNode.getChildMultiplicity(templNode.getName());
  }
  private FormEntryPrompt findQuestion(
      FormEntryController formEntryContorller, TreeReference treeReferenceToMatch) {
    formEntryContorller.jumpToIndex(FormIndex.createBeginningOfFormIndex());
    int event;
    while ((event = formEntryContorller.stepToNextEvent())
        != FormEntryController.EVENT_END_OF_FORM) {
      if (event == FormEntryController.EVENT_QUESTION) {
        FormEntryPrompt questionPrompt = formEntryContorller.getModel().getQuestionPrompt();
        QuestionDef thisQuestionDef = questionPrompt.getQuestion();
        TreeReference thisTreeReference = (TreeReference) thisQuestionDef.getBind().getReference();
        if (thisTreeReference.equals(treeReferenceToMatch)) return questionPrompt;
      }
    }

    return null;
  }
 protected String substituteStringArgs(String templateStr) {
   if (templateStr == null) {
     return null;
   }
   return form.fillTemplateString(templateStr, index.getReference());
 }
Exemple #16
0
 public static FormIndex createEndOfFormIndex() {
   FormIndex end = new FormIndex(-1, null);
   end.endOfForm = true;
   return end;
 }
Exemple #17
0
 public static FormIndex createBeginningOfFormIndex() {
   FormIndex begin = new FormIndex(-1, null);
   begin.beginningOfForm = true;
   return begin;
 }
Exemple #18
0
 public static boolean isSubElement(FormIndex parent, FormIndex child) {
   while (!parent.isTerminal() && !child.isTerminal()) {
     if (parent.getLocalIndex() != child.getLocalIndex()) {
       return false;
     }
     if (parent.getInstanceIndex() != child.getInstanceIndex()) {
       return false;
     }
     parent = parent.nextLevel;
     child = child.nextLevel;
   }
   // If we've gotten this far, at least one of the two is terminal
   if (!parent.isTerminal() && child.isTerminal()) {
     // can't be the parent if the child is earlier on
     return false;
   } else if (parent.getLocalIndex() != child.getLocalIndex()) {
     // Either they're at the same level, in which case only
     // identical indices should match, or they should have
     // the same root
     return false;
   } else if (parent.getInstanceIndex() != -1
       && (parent.getInstanceIndex() != child.getInstanceIndex())) {
     return false;
   }
   // Barring all of these cases, it should be true.
   return true;
 }
 public int getMultiplicity() {
   return index.getElementMultiplicity();
 }
  public void refreshView() {
    try {
      FormController formController = Collect.getInstance().getFormController();
      // Record the current index so we can return to the same place if the user hits 'back'.
      currentIndex = formController.getFormIndex();

      // If we're not at the first level, we're inside a repeated group so we want to only display
      // everything enclosed within that group.
      String contextGroupRef = "";
      formList = new ArrayList<HierarchyElement>();

      // If we're currently at a repeat node, record the name of the node and step to the next
      // node to display.
      if (formController.getEvent() == FormEntryController.EVENT_REPEAT) {
        contextGroupRef = formController.getFormIndex().getReference().toString(true);
        formController.stepToNextEvent(FormController.STEP_INTO_GROUP);
      } else {
        FormIndex startTest = formController.stepIndexOut(currentIndex);
        // If we have a 'group' tag, we want to step back until we hit a repeat or the
        // beginning.
        while (startTest != null
            && formController.getEvent(startTest) == FormEntryController.EVENT_GROUP) {
          startTest = formController.stepIndexOut(startTest);
        }
        if (startTest == null) {
          // check to see if the question is at the first level of the hierarchy. If it is,
          // display the root level from the beginning.
          formController.jumpToIndex(FormIndex.createBeginningOfFormIndex());
        } else {
          // otherwise we're at a repeated group
          formController.jumpToIndex(startTest);
        }

        // now test again for repeat. This should be true at this point or we're at the
        // beginning
        if (formController.getEvent() == FormEntryController.EVENT_REPEAT) {
          contextGroupRef = formController.getFormIndex().getReference().toString(true);
          formController.stepToNextEvent(FormController.STEP_INTO_GROUP);
        }
      }

      int event = formController.getEvent();
      if (event == FormEntryController.EVENT_BEGINNING_OF_FORM) {
        // The beginning of form has no valid prompt to display.
        formController.stepToNextEvent(FormController.STEP_INTO_GROUP);
        contextGroupRef =
            formController.getFormIndex().getReference().getParentRef().toString(true);
        mPath.setVisibility(View.GONE);
        jumpPreviousButton.setEnabled(false);
      } else {
        mPath.setVisibility(View.VISIBLE);
        mPath.setText(getCurrentPath());
        jumpPreviousButton.setEnabled(true);
      }

      // Refresh the current event in case we did step forward.
      event = formController.getEvent();

      // Big change from prior implementation:
      //
      // The ref strings now include the instance number designations
      // i.e., [0], [1], etc. of the repeat groups (and also [1] for
      // non-repeat elements).
      //
      // The contextGroupRef is now also valid for the top-level form.
      //
      // The repeatGroupRef is null if we are not skipping a repeat
      // section.
      //
      String repeatGroupRef = null;

      event_search:
      while (event != FormEntryController.EVENT_END_OF_FORM) {

        // get the ref to this element
        String currentRef = formController.getFormIndex().getReference().toString(true);

        // retrieve the current group
        String curGroup = (repeatGroupRef == null) ? contextGroupRef : repeatGroupRef;

        if (!currentRef.startsWith(curGroup)) {
          // We have left the current group
          if (repeatGroupRef == null) {
            // We are done.
            break event_search;
          } else {
            // exit the inner repeat group
            repeatGroupRef = null;
          }
        }

        if (repeatGroupRef != null) {
          // We're in a repeat group within the one we want to list
          // skip this question/group/repeat and move to the next index.
          event = formController.stepToNextEvent(FormController.STEP_INTO_GROUP);
          continue;
        }

        switch (event) {
          case FormEntryController.EVENT_QUESTION:
            FormEntryPrompt fp = formController.getQuestionPrompt();
            String label = fp.getLongText();
            if (!fp.isReadOnly() || (label != null && label.length() > 0)) {
              // show the question if it is an editable field.
              // or if it is read-only and the label is not blank.
              formList.add(
                  new HierarchyElement(
                      fp.getLongText(),
                      fp.getAnswerText(),
                      null,
                      Color.WHITE,
                      QUESTION,
                      fp.getIndex()));
            }
            break;
          case FormEntryController.EVENT_GROUP:
            // ignore group events
            break;
          case FormEntryController.EVENT_PROMPT_NEW_REPEAT:
            // this would display the 'add new repeat' dialog
            // ignore it.
            break;
          case FormEntryController.EVENT_REPEAT:
            FormEntryCaption fc = formController.getCaptionPrompt();
            // push this repeat onto the stack.
            repeatGroupRef = currentRef;
            // Because of the guard conditions above, we will skip
            // everything until we exit this repeat.
            //
            // Note that currentRef includes the multiplicity of the
            // repeat (e.g., [0], [1], ...), so every repeat will be
            // detected as different and reach this case statement.
            // Only the [0] emits the repeat header.
            // Every one displays the descend-into action element.

            if (fc.getMultiplicity() == 0) {
              // Display the repeat header for the group.
              HierarchyElement group =
                  new HierarchyElement(
                      fc.getLongText(),
                      null,
                      getResources().getDrawable(R.drawable.expander_ic_minimized),
                      Color.WHITE,
                      COLLAPSED,
                      fc.getIndex());
              formList.add(group);
            }
            // Add this group name to the drop down list for this repeating group.
            HierarchyElement h = formList.get(formList.size() - 1);
            h.addChild(
                new HierarchyElement(
                    mIndent + fc.getLongText() + " " + (fc.getMultiplicity() + 1),
                    null,
                    null,
                    Color.WHITE,
                    CHILD,
                    fc.getIndex()));
            break;
        }
        event = formController.stepToNextEvent(FormController.STEP_INTO_GROUP);
      }

      HierarchyListAdapter itla = new HierarchyListAdapter(this);
      itla.setListItems(formList);
      setListAdapter(itla);

      // set the controller back to the current index in case the user hits 'back'
      formController.jumpToIndex(currentIndex);
    } catch (Exception e) {
      Log.e(t, e.getMessage(), e);
      createErrorDialog(e.getMessage());
    }
  }
Exemple #21
0
  public int compareTo(Object o) {
    if (!(o instanceof FormIndex))
      throw new IllegalArgumentException(
          "Attempt to compare Object of type " + o.getClass().getName() + " to a FormIndex");

    FormIndex a = this;
    FormIndex b = (FormIndex) o;

    if (a.beginningOfForm) {
      return (b.beginningOfForm ? 0 : -1);
    } else if (a.endOfForm) {
      return (b.endOfForm ? 0 : 1);
    } else {
      // a is in form
      if (b.beginningOfForm) {
        return 1;
      } else if (b.endOfForm) {
        return -1;
      }
    }

    if (a.localIndex != b.localIndex) {
      return (a.localIndex < b.localIndex ? -1 : 1);
    } else if (a.instanceIndex != b.instanceIndex) {
      return (a.instanceIndex < b.instanceIndex ? -1 : 1);
    } else if ((a.getNextLevel() == null) != (b.getNextLevel() == null)) {
      return (a.getNextLevel() == null ? -1 : 1);
    } else if (a.getNextLevel() != null) {
      return a.getNextLevel().compareTo(b.getNextLevel());
    } else {
      return 0;
    }

    //		int comp = 0;
    //
    //		//TODO: while(true) loops freak me out, this should probably
    //		//get written more safely. -ctsims
    //		while(comp == 0) {
    //			if(index.isTerminal() != local.isTerminal() ||
    //					index.getLocalIndex() != local.getLocalIndex() ||
    //					index.getInstanceIndex() != local.getInstanceIndex()) {
    //				if(local.localIndex > index.localIndex) {
    //					return 1;
    //				} else if(local.localIndex < index.localIndex) {
    //					return -1;
    //				} else if (local.instanceIndex > index.instanceIndex) {
    //					return 1;
    //				} else if (local.instanceIndex < index.instanceIndex) {
    //					return -1;
    //				}
    //
    //				//This case is here as a fallback, but it shouldn't really
    //				//ever be the case that two references have the same chain
    //				//of indices without terminating at the same level.
    //				else if (local.isTerminal() && !index.isTerminal()) {
    //					return -1;
    //				} else {
    //					return 1;
    //				}
    //			}
    //			else if(local.isTerminal()) {
    //				break;
    //			}
    //			local = local.getNextLevel();
    //			index = index.getNextLevel();
    //		}
    //		return comp;
  }