/* DDS3.2.12: Get Image Under Cursor */ struct image_set get_img_at_cursor(const struct cursor *cursor) { struct image_set set = { NULL, NULL, NULL }; const struct electorate *elec; elec = get_voter_electorate(); /* Are they on the group heading? */ if (cursor->screen_candidate_index == -1) { set.group = get_group_image(elec->code, cursor->group_index); } else { unsigned int dbci; struct ballot_contents *ballot; assert(cursor->screen_candidate_index >= 0); /* We need to know the number of candidates in this group */ ballot = get_ballot_contents(); /* They're on a candidate. Translate. */ dbci = translate_sci_to_dbci(ballot->num_candidates [cursor->group_index], cursor->screen_candidate_index, get_current_rotation()); set.candidate = get_candidate_image(elec->code, cursor->group_index, dbci); set.prefnumber = get_pref_img_for_candidate(elec, cursor->group_index, dbci); } return set; }
/* DDS3.18: Update DEO Preference */ void update_deo_preference(unsigned int pref) { struct cursor cursor; unsigned int group_index, dbci; int screen_candidate_index; const struct rotation *rotation; struct ballot_contents *ballot; cursor = get_cursor_position(); group_index = cursor.group_index; screen_candidate_index = cursor.screen_candidate_index; /* If screen candidate index is -1 then cursor is on a group heading */ if (screen_candidate_index > -1) { ballot = get_ballot_contents(); rotation = get_current_rotation(); /* SIPL 2011-06-28 Use updated translate function. */ dbci = translate_group_sci_to_dbci (group_index, screen_candidate_index, rotation); insert_preference_digit(group_index, dbci, pref); /* Redraw the candidates preference box with the new preference number */ draw_group_entry(cursor, YES, NO); } }
/* Number of groups in electorate */ static unsigned int num_groups(void) { struct ballot_contents *bc; bc = get_ballot_contents(); return bc->num_groups; }
/* DDS3.2.12: Get Number of Candidates in Group */ static unsigned int get_num_cands_in_gp(unsigned int group_index) { struct ballot_contents *bc; bc = get_ballot_contents(); return bc->num_candidates[group_index]; }
/* Number of candidates in a group */ static unsigned int num_candidates(unsigned int group) { struct ballot_contents *bc; bc = get_ballot_contents(); assert(group < bc->num_groups); return bc->num_candidates[group]; }
/* DDS3.2.12: Get Number of Groups in Electorate */ static unsigned int get_num_gps_electorate(void) { struct ballot_contents *bc; /* ballot_contents only contains details of current electorate */ bc = get_ballot_contents(); return bc->num_groups; }
unsigned int translate_group_dbci_to_sci(unsigned int group_index, unsigned int db_candidate_index, const struct rotation *rot) { unsigned int map[MAX_ELECTORATE_SEATS]; unsigned int i; struct ballot_contents *ballot; unsigned int physical_column_index; /* If the group is split into multiple columns, the sci and dbci values of a candidate _not_ in the first physical column of the group are offset by the total number of candidates in all of the preceding physical columns for the same group. The variable candidates_offset is used to keep track of that total. */ unsigned int candidates_offset = 0; unsigned int num_candidates; /* Skip to the appropriate physical column. */ ballot = get_ballot_contents(); physical_column_index = ballot->map_group_to_physical_column[group_index]; while (db_candidate_index >= ballot->num_candidates_in_physical_column[ physical_column_index]) { db_candidate_index = db_candidate_index - ballot->num_candidates_in_physical_column[ physical_column_index]; candidates_offset = candidates_offset + ballot->num_candidates_in_physical_column[ physical_column_index]; physical_column_index++; } num_candidates = ballot->num_candidates_in_physical_column[ physical_column_index]; assert(num_candidates <= rot->size); assert(db_candidate_index < rot->size); assert(db_candidate_index < num_candidates); produce_collapsed_map(rot, map, num_candidates); /* Look for the screen candidate index which maps onto this db_candidate_index */ for (i = 0; map[i] != db_candidate_index; i++) assert(i < num_candidates); /* Restore i to the appropriate range of values using candidates_offset. */ return i + candidates_offset; }
/* Send the electorate and ballot contents */ static struct http_vars *create_response(PGconn *conn, struct electorate *elec) { struct http_vars *vars; /* Start with the electorate information */ vars = malloc(sizeof(*vars) * 3); vars[0].name = strdup("electorate_name"); vars[0].value = strdup(elec->name); vars[1].name = strdup("electorate_code"); vars[1].value = sprintf_malloc("%u", elec->code); vars[2].name = strdup("electorate_seats"); vars[2].value = sprintf_malloc("%u", elec->num_seats); /* Get the ballot contents stuff. */ return get_ballot_contents(conn, elec->code,vars); }
/* DDS3.12: Display DEO Ballot Screen */ void dsp_mn_vt_scn(void) { const struct electorate *electorate; struct ballot_contents *bc; unsigned int group_index; unsigned int physical_column; unsigned int grid_block; int cand; struct cursor cursor_position; struct image *ballot_h_image; /* Number of grid blocks in each row. */ unsigned int groups_across; /* grid_block_mod_groups_across = (grid_block % groups_across) */ unsigned int grid_block_mod_groups_across; /* The first grid block of the next group (or the end of the ballot, if there is no next group). */ unsigned int next_grid_block; electorate = get_voter_electorate(); bc = get_ballot_contents(); ballot_h_image = get_bh_image(get_language(), electorate); paste_image(0,0,ballot_h_image); /* SIPL 2011-07-11 Need this to fill in map_physical_column_to_grid_block. */ groups_across = get_grid_blocks_across(electorate); /* SIPL 2011-06-29 Now loop over physical columns and grid blocks as well as groups. Fill in map_physical_column_to_grid_block during this process. */ group_index = 0; physical_column = 0; grid_block = 0; while (group_index < bc->num_groups) { /* Need to fill in all the map entries for the group before calling draw_group_entry. */ bc->map_physical_column_to_grid_block[physical_column] = grid_block; /* For the rest in the group, draw blank entry */ /* All physical columns but the last for this group. */ while (physical_column < bc->map_group_to_physical_column[group_index+1] - 1) { for (cand = bc->num_candidates_in_physical_column[ physical_column]; cand < electorate->num_seats; cand++) draw_blank_entry_no_divider_grid_block( grid_block, cand); physical_column++; grid_block++; bc->map_physical_column_to_grid_block[ physical_column] = grid_block; } /* The last physical column for this group. */ for (cand = bc->num_candidates_in_physical_column[ physical_column]; cand < electorate->num_seats; cand++) draw_blank_entry_grid_block(grid_block, cand); /* Now all of the entries in map_physical_column_to_grid_block required for this group have been filled in, so the candidates can be drawn. */ /* candidate -1 corresponds to group heading */ for (cand = -1; cand < (int)bc->num_candidates[group_index]; cand++) { cursor_position.group_index = group_index; cursor_position.screen_candidate_index = cand; draw_group_entry(cursor_position,NO,false); } group_index++; physical_column++; grid_block++; /* Is there a next group, and, if so, it there room for the next group? If this is the last group, set the map value to the grid block after the end of the entire screen. Otherwise, set the map value to the grid block at the beginning of the next row. Group group_index occupies (bc->map_group_to_physical_column[group_index+1] - bc->map_group_to_physical_column[group_index]) physical columns. */ grid_block_mod_groups_across = grid_block % groups_across; if (group_index < bc->num_groups) { if (grid_block_mod_groups_across + (bc->map_group_to_physical_column[group_index+1] - bc->map_group_to_physical_column[group_index]) > groups_across) /* No room. Move to the next row. */ next_grid_block = grid_block + (groups_across - grid_block_mod_groups_across); else /* There is room. */ next_grid_block = grid_block; } else { /* This is the last group. */ next_grid_block = grid_blocks_possible(); } /* Now fill in the map entry. */ bc->map_physical_column_to_grid_block[physical_column] = next_grid_block; /* Fill in any blank grid blocks at the end of the row, or the ballot. */ while (grid_block < next_grid_block) { draw_blank_group_entry_grid_block(grid_block); for (cand = 0; cand < (int)electorate->num_seats; cand++) draw_blank_entry_grid_block(grid_block, cand); grid_block++; } } }