add_assisted_conflict_resolution5.patch
AMC/DataModule/layout.pm 2015-09-25 14:51:21.966144277 -0700 | ||
---|---|---|
445 | 445 |
." AS ratio" |
446 | 446 |
." FROM ".$self->table("page") |
447 | 447 |
." )"}, |
448 |
'MapQuestionPage'=> |
|
449 |
{'sql'=>"SELECT student, page, question " |
|
450 |
." FROM ".$self->table("box")." WHERE answer=1" |
|
451 |
}, |
|
448 | 452 |
}; |
449 | 453 |
} |
450 | 454 | |
... | ... | |
525 | 529 |
return($self->sql_list($self->statement('FULLIDS'))); |
526 | 530 |
} |
527 | 531 | |
532 |
#Return list of student, page, question |
|
533 |
sub student_question_page{ |
|
534 |
my ($self)=@_; |
|
535 |
my @list = @{$self->dbh |
|
536 |
->selectall_arrayref($self->statement('MapQuestionPage'))}; |
|
537 |
return(@list); |
|
538 |
} |
|
539 | ||
528 | 540 |
# page_info returns a HASH reference containing all fields in the |
529 | 541 |
# layout_page row corresponding to the student,page page. |
530 | 542 |
AMC/DataModule/scoring.pm 2015-09-25 14:26:09.170493471 -0700 | ||
---|---|---|
519 | 519 |
." WHERE student=? AND copy=?"}, |
520 | 520 |
'deleteCodes'=>{'sql'=>"DELETE FROM ".$self->table('code') |
521 | 521 |
." WHERE student=? AND copy=?"}, |
522 |
'conflicts'=> |
|
523 |
{'sql'=>"SELECT student, copy, question" |
|
524 |
." FROM ".$self->table('score')." WHERE (why = 'E') OR (why = 'V')" }, |
|
522 | 525 |
}; |
523 | 526 |
} |
524 | 527 | |
528 |
sub get_conflicts{ |
|
529 |
my ($self)=@_; |
|
530 |
my @list = @{$self->dbh |
|
531 |
->selectall_arrayref($self->statement('conflicts'))}; |
|
532 |
return(@list); |
|
533 |
} |
|
534 | ||
535 | ||
525 | 536 |
# default_strategy($type) returns the default scoring strategy string |
526 | 537 |
# to be used for questions with type $type (QUESTION_SIMPLE or |
527 | 538 |
# QUESTION_MULT). |
AMC/Gui/Manuel.glade 2015-09-25 14:34:29.625620711 -0700 | ||
---|---|---|
304 | 304 |
</packing> |
305 | 305 |
</child> |
306 | 306 |
<child> |
307 |
<placeholder/> |
|
307 |
<object class="GtkHButtonBox" id="hbuttonbox6"> |
|
308 |
<property name="visible">True</property> |
|
309 |
<property name="can_focus">False</property> |
|
310 |
<child> |
|
311 |
<object class="GtkButton" id="button9"> |
|
312 |
<property name="label">Previous Error</property> |
|
313 |
<property name="visible">True</property> |
|
314 |
<property name="can_focus">True</property> |
|
315 |
<property name="receives_default">True</property> |
|
316 |
<property name="has_tooltip">True</property> |
|
317 |
<property name="tooltip_text" translatable="yes">Save this page modifications, then go to the previous page.</property> |
|
318 |
<signal name="clicked" handler="previous_error" swapped="no"/> |
|
319 |
</object> |
|
320 |
<packing> |
|
321 |
<property name="expand">False</property> |
|
322 |
<property name="fill">False</property> |
|
323 |
<property name="position">0</property> |
|
324 |
</packing> |
|
325 |
</child> |
|
326 |
<child> |
|
327 |
<object class="GtkLabel" id="con_label"> |
|
328 |
<property name="visible">True</property> |
|
329 |
<property name="can_focus">False</property> |
|
330 |
<property name="label" translatable="yes">label</property> |
|
331 |
</object> |
|
332 |
<packing> |
|
333 |
<property name="expand">False</property> |
|
334 |
<property name="fill">False</property> |
|
335 |
<property name="position">1</property> |
|
336 |
</packing> |
|
337 |
</child> |
|
338 |
<child> |
|
339 |
<object class="GtkButton" id="button10"> |
|
340 |
<property name="label">Next Error</property> |
|
341 |
<property name="visible">True</property> |
|
342 |
<property name="can_focus">True</property> |
|
343 |
<property name="receives_default">True</property> |
|
344 |
<property name="has_tooltip">True</property> |
|
345 |
<property name="tooltip_text" translatable="yes">Save this page modifications, then go to next page.</property> |
|
346 |
<signal name="clicked" handler="next_error" swapped="no"/> |
|
347 |
</object> |
|
348 |
<packing> |
|
349 |
<property name="expand">False</property> |
|
350 |
<property name="fill">False</property> |
|
351 |
<property name="position">2</property> |
|
352 |
</packing> |
|
353 |
</child> |
|
354 |
</object> |
|
355 |
<packing> |
|
356 |
<property name="expand">False</property> |
|
357 |
<property name="fill">False</property> |
|
358 |
<property name="position">2</property> |
|
359 |
</packing> |
|
308 | 360 |
</child> |
309 | 361 |
<child> |
310 | 362 |
<object class="GtkScrolledWindow" id="scrolledwindow1"> |
AMC/Gui/Manuel.pm 2015-09-25 14:45:58.579004192 -0700 | ||
---|---|---|
33 | 33 |
use AMC::Data; |
34 | 34 |
use AMC::DataModule::capture qw/:zone/; |
35 | 35 | |
36 | ||
37 |
my $conflict_num=-1; # which conflict is currently being viewed |
|
38 |
my $num_conflicts=0; # how man conflicts in the list |
|
39 |
my @hconflicts=(); # holds id=student,page,copy and question |
|
40 |
#conflicts should be an array of hashes |
|
41 |
|
|
36 | 42 |
use constant { |
37 | 43 |
MDIAG_ID => 0, |
38 | 44 |
MDIAG_ID_BACK => 1, |
... | ... | |
82 | 88 |
$self->{'data'}=AMC::Data->new($self->{'data-dir'}); |
83 | 89 |
$self->{'layout'}=$self->{'data'}->module('layout'); |
84 | 90 |
$self->{'capture'}=$self->{'data'}->module('capture'); |
91 |
$self->{'scoring'}=$self->{'data'}->module('scoring'); |
|
85 | 92 | |
86 | 93 |
die "No PDF subject file" if(! $self->{'sujet'}); |
87 | 94 |
die "Subject file ".$self->{'sujet'}." not found" if(! -f $self->{'sujet'}); |
... | ... | |
101 | 108 |
$self->{'gui'}->set_translation_domain('auto-multiple-choice'); |
102 | 109 |
$self->{'gui'}->add_from_file($glade_xml); |
103 | 110 | |
104 |
for my $k (qw/general area navigation_h navigation_v goto goto_v diag_tree button_photocopy scan_view/) { |
|
111 |
for my $k (qw/general area navigation_h navigation_v goto goto_v diag_tree button_photocopy scan_view con_label/) {
|
|
105 | 112 |
$self->{$k}=$self->{'gui'}->get_object($k); |
106 | 113 |
} |
107 | 114 | |
... | ... | |
178 | 185 | |
179 | 186 |
$self->select_page(0); |
180 | 187 | |
188 |
|
|
189 |
## Build list of marking conflicts (duplicate or blanks) |
|
190 |
$conflict_num=-1; # which conflict is currently being viewed |
|
191 |
$num_conflicts=0; # how many conflicts in the list |
|
192 |
@hconflicts=(); # holds id=student,page,copy and question |
|
193 |
$self->{'layout'}->begin_read_transaction; |
|
194 |
my @con_table=$self->{'layout'}->student_question_page; |
|
195 |
$self->{'layout'}->end_transaction; |
|
196 | ||
197 |
# print the elements: |
|
198 |
my $lent = @con_table; |
|
199 |
# for (my $i=0;$i<$lent;$i++){ |
|
200 |
# print $con_table[$i][0]." "; #student |
|
201 |
# print $con_table[$i][1]." "; #page |
|
202 |
# print $con_table[$i][2]."\n"; #question # |
|
203 |
# } |
|
204 | ||
205 |
# ok, got student, page, question. |
|
206 |
# now need student question, why, questionID, copy |
|
207 |
$self->{'scoring'}->begin_read_transaction; |
|
208 |
my @score_table=$self->{'scoring'}->get_conflicts; |
|
209 |
$self->{'scoring'}->end_transaction; |
|
210 |
$lens = @score_table; |
|
211 |
# for (my $i=0;$i<$lens;$i++){ |
|
212 |
# print $score_table[$i][0]." "; # student |
|
213 |
# print $score_table[$i][1]." "; #copy # |
|
214 |
# print $score_table[$i][2]."\n"; #question # |
|
215 |
# } |
|
216 |
#now match student & question#'s to build student/page list |
|
217 |
for (my $i=0 ; $i < $lens ; $i++){ |
|
218 |
for (my $j=0 ; $j < $lent ; $j++){ |
|
219 |
if (($score_table[$i][0] eq $con_table[$j][0]) and ($score_table[$i][2] eq $con_table[$j][2])){ |
|
220 |
my @id=[$con_table[$j][0], $con_table[$j][1], $score_table[$i][1]]; |
|
221 |
push @hconflicts, { id => @id, question => $con_table[$j][2] }; |
|
222 |
# print "$i $j added $con_table[$j][0]/$con_table[$j][1] question $con_table[$j][2]\n"; |
|
223 |
last; |
|
224 |
} |
|
225 |
} |
|
226 | ||
227 |
} |
|
228 |
$num_conflicts=@hconflicts; |
|
229 |
my $lnum = $conflict_num+1; |
|
230 |
$self->{'con_label'}->set_text("Errs: $lnum/$num_conflicts"); |
|
231 |
debug "number of conflicts: $num_conflicts\n"; |
|
181 | 232 |
return($self); |
182 | 233 |
} |
183 | 234 | |
... | ... | |
521 | 572 |
} |
522 | 573 | |
523 | 574 |
# mise a jour des cases suivant saisies deja presentes |
524 | ||
575 |
my @con_id=(); |
|
576 |
if ($conflict_num ge 0){ |
|
577 |
@con_id=@{$hconflicts[$conflict_num]->{'id'}}; |
|
578 |
} |
|
525 | 579 |
for my $i (@{$self->{'layinfo'}->{'box'}}) { |
526 | 580 |
my $id=$i->{'question'}."." |
527 | 581 |
.$i->{'answer'}; |
... | ... | |
532 | 586 |
debug "Q=$id R=$t"; |
533 | 587 |
$i->{'id'}=[@spc]; |
534 | 588 |
$i->{'ticked'}=$t; |
589 |
$i->{'cur_conflict'}=0; |
|
590 |
if ($conflict_num ge 0){ |
|
591 |
if ( $con_id[0] eq ${$i->{'id'}}[0] and |
|
592 |
$con_id[1] eq ${$i->{'id'}}[1] and |
|
593 |
$con_id[2] eq ${$i->{'id'}}[2] and |
|
594 |
$hconflicts[$conflict_num]->{'question'} eq $i->{'question'}){ |
|
595 |
$i->{'cur_conflict'} = 1; |
|
596 |
debug "marked current_conflict: stud, page: ${$i->{'id'}}[0], ${$i->{'id'}}[1]\n"; |
|
597 |
} |
|
598 |
} |
|
535 | 599 |
} |
536 | 600 |
} |
537 | 601 | |
... | ... | |
587 | 651 |
$self->maj_list_i; |
588 | 652 |
} |
589 | 653 | |
654 |
sub next_error{ |
|
655 |
my ($self)=@_; |
|
656 |
return if ($num_conflicts <= 0); |
|
657 |
if ($conflict_num < $num_conflicts-1){ |
|
658 |
$conflict_num += 1; |
|
659 |
} |
|
660 |
if (${$hconflicts[$conflict_num]->{'id'}}[2] eq '0'){ |
|
661 |
my $dest=$self->{($self->{'editable'} ? 'goto' : 'goto_v')}->set_text("${$hconflicts[$conflict_num]->{'id'}}[0]/${$hconflicts[$conflict_num]->{'id'}}[1]"); |
|
662 |
} |
|
663 |
else{ |
|
664 |
my $dest=$self->{($self->{'editable'} ? 'goto' : 'goto_v')}->set_text("${$hconflicts[$conflict_num]->{'id'}}[0]/${$hconflicts[$conflict_num]->{'id'}}[1]:${$hconflicts[$conflict_num]->{'id'}}[2]"); |
|
665 |
} |
|
666 |
my $lnum = $conflict_num+1; |
|
667 |
$self->{'con_label'}->set_text("Errs: $lnum/$num_conflicts"); |
|
668 |
$self->goto_activate_cb(); |
|
669 | ||
670 |
} |
|
671 | ||
672 |
sub previous_error{ |
|
673 |
my ($self)=(@_); |
|
674 |
return if ($num_conflicts <= 0); |
|
675 |
if ( $conflict_num >0 ){ |
|
676 |
$conflict_num -= 1; |
|
677 |
} |
|
678 |
if (${$hconflicts[$conflict_num]->{'id'}}[2] eq '0'){ |
|
679 |
my $dest=$self->{($self->{'editable'} ? 'goto' : 'goto_v')}->set_text("${$hconflicts[$conflict_num]->{'id'}}[0]/${$hconflicts[$conflict_num]->{'id'}}[1]"); |
|
680 |
} |
|
681 |
else{ |
|
682 |
my $dest=$self->{($self->{'editable'} ? 'goto' : 'goto_v')}->set_text("${$hconflicts[$conflict_num]->{'id'}}[0]/${$hconflicts[$conflict_num]->{'id'}}[1]:${$hconflicts[$conflict_num]->{'id'}}[2]"); |
|
683 |
} |
|
684 |
my $lnum = $conflict_num+1; |
|
685 |
$self->{'con_label'}->set_text("Errs: $lnum/$num_conflicts"); |
|
686 |
$self->goto_activate_cb(); |
|
687 | ||
688 |
} |
|
689 | ||
590 | 690 |
sub passe_precedent { |
591 | 691 |
my ($self)=@_; |
592 | 692 |
my ($path)=$self->{'diag_tree'}->get_cursor(); |
AMC/Gui/PageArea.pm 2015-09-25 14:49:39.077056320 -0700 | ||
---|---|---|
47 | 47 | |
48 | 48 |
$self->{'onscan'}=''; |
49 | 49 |
$self->{'unticked_color_name'}="#429DE5"; |
50 | ||
50 |
$self->{'conflict_color_name'}="#00FF00"; |
|
51 |
|
|
51 | 52 |
$self->{'font'}=Pango::FontDescription->from_string("128"); |
52 | 53 | |
53 | 54 |
for (keys %oo) { |
... | ... | |
59 | 60 |
$self->{'color'}= Gtk2::Gdk::Color->parse($coul); |
60 | 61 |
$self->{'unticked_color'}= |
61 | 62 |
Gtk2::Gdk::Color->parse($self->{'unticked_color_name'}); |
62 |
for my $ck (qw/color unticked_color/) { |
|
63 |
$self->{'conflict_color'}= |
|
64 |
Gtk2::Gdk::Color->parse($self->{'conflict_color_name'}); |
|
65 |
for my $ck (qw/color unticked_color conflict_color/) { |
|
63 | 66 |
$self->window->get_colormap->alloc_color($self->{$ck},TRUE,TRUE); |
64 | 67 |
} |
65 | 68 | |
... | ... | |
175 | 178 |
} |
176 | 179 | |
177 | 180 |
sub draw_box { |
178 |
my ($self,$box,$fill)=@_; |
|
181 |
my ($self,$box,$fill,$expand)=@_;
|
|
179 | 182 |
if($box->{'xy'}) { |
183 |
if ($expand > 0){ |
|
184 |
$self->window->draw_polygon |
|
185 |
($self->{'gc'}, |
|
186 |
$fill,($box->{'xy'}->[0]-$expand)*$self->{'rx'}, ($box->{'xy'}->[1]-$expand)*$self->{'ry'}, |
|
187 |
($box->{'xy'}->[2]+$expand)*$self->{'rx'}, ($box->{'xy'}->[3]-$expand)*$self->{'ry'}, |
|
188 |
($box->{'xy'}->[4]+$expand)*$self->{'rx'}, ($box->{'xy'}->[5]+$expand)*$self->{'ry'}, |
|
189 |
($box->{'xy'}->[6]-$expand)*$self->{'rx'}, ($box->{'xy'}->[7]+$expand)*$self->{'ry'}); |
|
190 |
}else{ #original code: |
|
180 | 191 |
$self->window->draw_polygon |
181 | 192 |
($self->{'gc'}, |
182 | 193 |
$fill,map { ($box->{'xy'}->[$_*2]*$self->{'rx'}, |
183 | 194 |
$box->{'xy'}->[$_*2+1]*$self->{'ry'}) } (0..3) ); |
195 |
} |
|
184 | 196 |
} else { |
185 | 197 |
$self->window->draw_rectangle |
186 | 198 |
($self->{'gc'}, |
187 | 199 |
$fill, |
188 |
$box->{'xmin'}*$self->{'rx'},
|
|
189 |
$box->{'ymin'}*$self->{'ry'},
|
|
190 |
($box->{'xmax'}-$box->{'xmin'})*$self->{'rx'}, |
|
191 |
($box->{'ymax'}-$box->{'ymin'})*$self->{'ry'} |
|
200 |
($box->{'xmin'}-$expand)*$self->{'rx'},
|
|
201 |
($box->{'ymin'}-$expand)*$self->{'ry'},
|
|
202 |
($box->{'xmax'}-$box->{'xmin'}+2*$expand)*$self->{'rx'},
|
|
203 |
($box->{'ymax'}-$box->{'ymin'}+2*$expand)*$self->{'ry'}
|
|
192 | 204 |
); |
193 | 205 |
} |
194 | 206 |
} |
... | ... | |
270 | 282 |
$self->{'gc'}->set_foreground($self->{'colormark'}); |
271 | 283 | |
272 | 284 |
for $box (@{$self->{'layinfo'}->{'namefield'}}) { |
273 |
$self->draw_box($box,''); |
|
285 |
$self->draw_box($box,'',0);
|
|
274 | 286 |
} |
275 | 287 | |
276 | 288 |
$box=$self->{'layinfo'}->{'mark'}; |
... | ... | |
288 | 300 |
} |
289 | 301 | |
290 | 302 |
for my $box (@{$self->{'layinfo'}->{'digit'}}) { |
291 |
$self->draw_box($box,''); |
|
303 |
$self->draw_box($box,'',0);
|
|
292 | 304 |
} |
293 | 305 | |
294 | 306 |
} |
... | ... | |
300 | 312 |
if($self->{'onscan'}) { |
301 | 313 |
for $box (grep { $_->{'ticked'} } |
302 | 314 |
@{$self->{'layinfo'}->{'box'}}) { |
303 |
$self->draw_box($box,''); |
|
315 |
$self->draw_box($box,'',0);
|
|
304 | 316 |
} |
305 | 317 |
$self->{'gc'}->set_foreground($self->{'unticked_color'}); |
306 | 318 |
for $box (grep { ! $_->{'ticked'} } |
307 | 319 |
@{$self->{'layinfo'}->{'box'}}) { |
308 |
$self->draw_box($box,''); |
|
320 |
$self->draw_box($box,'',0); |
|
321 |
} |
|
322 |
$self->{'gc'}->set_foreground($self->{'conflict_color'}); |
|
323 |
for $box (grep { $_->{'cur_conflict'} } |
|
324 |
@{$self->{'layinfo'}->{'box'}}) { |
|
325 |
$self->draw_box($box,'',6); |
|
309 | 326 |
} |
310 | 327 |
} else { |
311 | 328 |
for $box (@{$self->{'layinfo'}->{'box'}}) { |
312 |
$self->draw_box($box,$box->{'ticked'}); |
|
329 |
$self->draw_box($box,$box->{'ticked'},0); |
|
330 |
} |
|
331 |
$self->{'gc'}->set_foreground($self->{'conflict_color'}); |
|
332 |
for $box (grep { $_->{'cur_conflict'} } |
|
333 |
@{$self->{'layinfo'}->{'box'}}) { |
|
334 |
$self->draw_box($box,'',6); |
|
313 | 335 |
} |
314 | 336 |
} |
315 | 337 |