/** * This function updates the checkboxes after a change by disabling packs that cannot be installed * anymore and enabling those that can after the change. This is accomplished by running a search * that pinpoints the packs that must be disabled by a non-fullfiled dependency. TODO: Look into * "+2" and "-2", doesn't look safe */ protected void updateDeps() { int[] statusArray = new int[packs.size()]; for (int i = 0; i < statusArray.length; i++) { statusArray[i] = 0; } dfs(statusArray); for (int i = 0; i < statusArray.length; i++) { if (statusArray[i] == 0 && checkValues[i] < 0) { checkValues[i] += PARTIAL_SELECTED; } if (statusArray[i] == 1 && checkValues[i] >= 0) { checkValues[i] = DEPENDENT_DESELECTED; } } // The required ones must propagate their required status to all the ones that they depend on for (Pack pack : packs) { if (pack.isRequired()) { String name = pack.getName(); if (!(!rules.canInstallPack(name, variables) && rules.canInstallPackOptional(name, variables))) { checkValues = propRequirement(name, checkValues); } } } }
/** * Select/Deselect pack(s) based on packsData mapping. This is related to the onSelect and * onDeselect attributes for packs. User is not allowed to has a required pack for onSelect and * onDeselect. * * @param packsData */ private void selectionUpdate(Map<String, String> packsData) { RulesEngine rules = installData.getRules(); for (Map.Entry<String, String> packData : packsData.entrySet()) { int value, packPos; String packName = packData.getKey(); String condition = packData.getValue(); if (condition != null && !rules.isConditionTrue(condition)) { return; // Do nothing if condition is false } Pack pack; if (packName.startsWith("!")) { packName = packName.substring(1); pack = nameToPack.get(packName); packPos = getPos(packName); value = DESELECTED; } else { pack = nameToPack.get(packName); packPos = getPos(packName); value = SELECTED; } if (!pack.isRequired() && dependenciesResolved(pack)) { checkValues[packPos] = value; } } }
/** * Update the conditions for dependent packages. Update the conditions for optional packages. * * @param initial indicates if its the first time updating conditions. */ private void updateConditions(boolean initial) { boolean changes = true; while (changes) { changes = false; for (Pack pack : packs) { String packName = pack.getName(); int pos = getPos(packName); logger.fine("Conditions fulfilled for: " + packName + "?"); if (!rules.canInstallPack(packName, variables)) { logger.fine("no"); if (rules.canInstallPackOptional(packName, variables)) { logger.fine("optional"); logger.fine(packName + " can be installed optionally."); if (initial) { if (checkValues[pos] != DESELECTED) { checkValues[pos] = DESELECTED; changes = true; } } } else { if (checkValues[pos] != DEPENDENT_DESELECTED) { logger.fine("Pack" + packName + " cannot be installed"); checkValues[pos] = DEPENDENT_DESELECTED; changes = true; } } } } } }
/* * @see TableModel#setValueAt(Object, int, int) * Update the value of some checkbox */ @Override public void setValueAt(Object checkValue, int rowIndex, int columnIndex) { if (columnIndex != 0 || !(checkValue instanceof Integer)) { return; } else { Pack pack = packs.get(rowIndex); boolean added; if ((Integer) checkValue == SELECTED) { added = true; String name = pack.getName(); if (rules.canInstallPack(name, variables) || rules.canInstallPackOptional(name, variables)) { if (pack.isRequired()) { checkValues[rowIndex] = REQUIRED_SELECTED; } else { checkValues[rowIndex] = SELECTED; } } } else { added = false; checkValues[rowIndex] = DESELECTED; } updateExcludes(rowIndex); updateDeps(); if (added) { onSelectionUpdate(rowIndex); this.packsToInstall.add(pack); // Temporarily add updateConditions(); this.packsToInstall.remove(pack); // Redo } else { onDeselectionUpdate(rowIndex); this.packsToInstall.remove(pack); // Temporarily remove updateConditions(); this.packsToInstall.add(pack); // Redo } updatePacksToInstall(); if (pack.hasParent()) { updateParent(pack); } else if (pack.hasChildren()) { updateChildren(pack); } fireTableDataChanged(); } }