add_assisted_conflict_resolution6.patch
AMC/DataModule/layout.pm 2015-10-05 10:34:24.836998363 -0700 | ||
---|---|---|
493 | 493 |
." AS ratio" |
494 | 494 |
." FROM ".$self->table("page") |
495 | 495 |
." )"}, |
496 |
'MapQuestionPage'=> |
|
497 |
{'sql'=>"SELECT student, page, question " |
|
498 |
." FROM ".$self->table("box")." WHERE answer=1" |
|
499 |
}, |
|
496 | 500 |
}; |
497 | 501 |
} |
498 | 502 | |
... | ... | |
573 | 577 |
return($self->sql_list($self->statement('FULLIDS'))); |
574 | 578 |
} |
575 | 579 | |
580 |
#Return list of student, page, question |
|
581 |
sub student_question_page{ |
|
582 |
my ($self)=@_; |
|
583 |
my @list = @{$self->dbh |
|
584 |
->selectall_arrayref($self->statement('MapQuestionPage'))}; |
|
585 |
return(@list); |
|
586 |
} |
|
587 | ||
576 | 588 |
# page_info returns a HASH reference containing all fields in the |
577 | 589 |
# layout_page row corresponding to the student,page page. |
578 | 590 |
AMC/DataModule/scoring.pm 2015-10-05 10:34:24.836998363 -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-10-05 10:34:24.836998363 -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-10-05 10:36:07.396012391 -0700 | ||
---|---|---|
34 | 34 |
use AMC::Data; |
35 | 35 |
use AMC::DataModule::capture qw/:zone/; |
36 | 36 | |
37 | ||
38 |
my $conflict_num=-1; # which conflict is currently being viewed |
|
39 |
my $num_conflicts=0; # how man conflicts in the list |
|
40 |
my @hconflicts=(); # holds id=student,page,copy and question |
|
41 |
#conflicts should be an array of hashes |
|
42 |
|
|
37 | 43 |
use constant { |
38 | 44 |
MDIAG_ID => 0, |
39 | 45 |
MDIAG_ID_BACK => 1, |
... | ... | |
85 | 91 |
$self->{'layout'}=$self->{'data'}->module('layout'); |
86 | 92 |
$self->{'capture'}=$self->{'data'}->module('capture'); |
87 | 93 |
$self->{'scoring'}=$self->{'data'}->module('scoring'); |
94 |
$self->{'scoring'}=$self->{'data'}->module('scoring'); |
|
88 | 95 | |
89 | 96 |
die "No PDF subject file" if(! $self->{'sujet'}); |
90 | 97 |
die "Subject file ".$self->{'sujet'}." not found" if(! -f $self->{'sujet'}); |
... | ... | |
104 | 111 |
$self->{'gui'}->set_translation_domain('auto-multiple-choice'); |
105 | 112 |
$self->{'gui'}->add_from_file($glade_xml); |
106 | 113 | |
107 |
for my $k (qw/general area navigation_h navigation_v goto goto_v diag_tree button_photocopy scan_view/) { |
|
114 |
for my $k (qw/general area navigation_h navigation_v goto goto_v diag_tree button_photocopy scan_view con_label/) {
|
|
108 | 115 |
$self->{$k}=$self->{'gui'}->get_object($k); |
109 | 116 |
} |
110 | 117 | |
... | ... | |
181 | 188 | |
182 | 189 |
$self->select_page(0); |
183 | 190 | |
191 |
|
|
192 |
## Build list of marking conflicts (duplicate or blanks) |
|
193 |
$conflict_num=-1; # which conflict is currently being viewed |
|
194 |
$num_conflicts=0; # how many conflicts in the list |
|
195 |
@hconflicts=(); # holds id=student,page,copy and question |
|
196 |
$self->{'layout'}->begin_read_transaction; |
|
197 |
my @con_table=$self->{'layout'}->student_question_page; |
|
198 |
$self->{'layout'}->end_transaction; |
|
199 | ||
200 |
# print the elements: |
|
201 |
my $lent = @con_table; |
|
202 |
# for (my $i=0;$i<$lent;$i++){ |
|
203 |
# print $con_table[$i][0]." "; #student |
|
204 |
# print $con_table[$i][1]." "; #page |
|
205 |
# print $con_table[$i][2]."\n"; #question # |
|
206 |
# } |
|
207 | ||
208 |
# ok, got student, page, question. |
|
209 |
# now need student question, why, questionID, copy |
|
210 |
$self->{'scoring'}->begin_read_transaction; |
|
211 |
my @score_table=$self->{'scoring'}->get_conflicts; |
|
212 |
$self->{'scoring'}->end_transaction; |
|
213 |
$lens = @score_table; |
|
214 |
# for (my $i=0;$i<$lens;$i++){ |
|
215 |
# print $score_table[$i][0]." "; # student |
|
216 |
# print $score_table[$i][1]." "; #copy # |
|
217 |
# print $score_table[$i][2]."\n"; #question # |
|
218 |
# } |
|
219 |
#now match student & question#'s to build student/page list |
|
220 |
for (my $i=0 ; $i < $lens ; $i++){ |
|
221 |
for (my $j=0 ; $j < $lent ; $j++){ |
|
222 |
if (($score_table[$i][0] eq $con_table[$j][0]) and ($score_table[$i][2] eq $con_table[$j][2])){ |
|
223 |
my @id=[$con_table[$j][0], $con_table[$j][1], $score_table[$i][1]]; |
|
224 |
push @hconflicts, { id => @id, question => $con_table[$j][2] }; |
|
225 |
# print "$i $j added $con_table[$j][0]/$con_table[$j][1] question $con_table[$j][2]\n"; |
|
226 |
last; |
|
227 |
} |
|
228 |
} |
|
229 | ||
230 |
} |
|
231 |
$num_conflicts=@hconflicts; |
|
232 |
my $lnum = $conflict_num+1; |
|
233 |
$self->{'con_label'}->set_text("Errs: $lnum/$num_conflicts"); |
|
234 |
debug "number of conflicts: $num_conflicts\n"; |
|
184 | 235 |
return($self); |
185 | 236 |
} |
186 | 237 | |
... | ... | |
535 | 586 |
} |
536 | 587 | |
537 | 588 |
# mise a jour des cases suivant saisies deja presentes |
589 |
my @con_id=(); |
|
590 |
if ($conflict_num ge 0){ |
|
591 |
@con_id=@{$hconflicts[$conflict_num]->{'id'}}; |
|
592 |
} |
|
538 | 593 | |
539 | 594 |
for my $i (@{$self->{'layinfo'}->{'box'}}) { |
540 | 595 |
my $id=$i->{'question'}."." |
... | ... | |
546 | 601 |
debug "Q=$id R=$t"; |
547 | 602 |
$i->{'id'}=[@spc]; |
548 | 603 |
$i->{'ticked'}=$t; |
604 |
$i->{'cur_conflict'}=0; |
|
605 |
if ($conflict_num ge 0){ |
|
606 |
if ( $con_id[0] eq ${$i->{'id'}}[0] and |
|
607 |
$con_id[1] eq ${$i->{'id'}}[1] and |
|
608 |
$con_id[2] eq ${$i->{'id'}}[2] and |
|
609 |
$hconflicts[$conflict_num]->{'question'} eq $i->{'question'}){ |
|
610 |
$i->{'cur_conflict'} = 1; |
|
611 |
debug "marked current_conflict: stud, page: ${$i->{'id'}}[0], ${$i->{'id'}}[1]\n"; |
|
612 |
} |
|
613 |
} |
|
549 | 614 |
} |
550 | 615 |
} |
551 | 616 |
} |
... | ... | |
602 | 667 |
$self->maj_list_i; |
603 | 668 |
} |
604 | 669 | |
670 |
sub next_error{ |
|
671 |
my ($self)=@_; |
|
672 |
return if ($num_conflicts <= 0); |
|
673 |
if ($conflict_num < $num_conflicts-1){ |
|
674 |
$conflict_num += 1; |
|
675 |
} |
|
676 |
if (${$hconflicts[$conflict_num]->{'id'}}[2] eq '0'){ |
|
677 |
my $dest=$self->{($self->{'editable'} ? 'goto' : 'goto_v')}->set_text("${$hconflicts[$conflict_num]->{'id'}}[0]/${$hconflicts[$conflict_num]->{'id'}}[1]"); |
|
678 |
} |
|
679 |
else{ |
|
680 |
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]"); |
|
681 |
} |
|
682 |
my $lnum = $conflict_num+1; |
|
683 |
$self->{'con_label'}->set_text("Errs: $lnum/$num_conflicts"); |
|
684 |
$self->goto_activate_cb(); |
|
685 | ||
686 |
} |
|
687 | ||
688 |
sub previous_error{ |
|
689 |
my ($self)=(@_); |
|
690 |
return if ($num_conflicts <= 0); |
|
691 |
if ( $conflict_num >0 ){ |
|
692 |
$conflict_num -= 1; |
|
693 |
} |
|
694 |
if (${$hconflicts[$conflict_num]->{'id'}}[2] eq '0'){ |
|
695 |
my $dest=$self->{($self->{'editable'} ? 'goto' : 'goto_v')}->set_text("${$hconflicts[$conflict_num]->{'id'}}[0]/${$hconflicts[$conflict_num]->{'id'}}[1]"); |
|
696 |
} |
|
697 |
else{ |
|
698 |
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]"); |
|
699 |
} |
|
700 |
my $lnum = $conflict_num+1; |
|
701 |
$self->{'con_label'}->set_text("Errs: $lnum/$num_conflicts"); |
|
702 |
$self->goto_activate_cb(); |
|
703 | ||
704 |
} |
|
705 | ||
605 | 706 |
sub passe_precedent { |
606 | 707 |
my ($self)=@_; |
607 | 708 |
my ($path)=$self->{'diag_tree'}->get_cursor(); |
AMC/Gui/PageArea.pm 2015-10-05 10:46:21.052131121 -0700 | ||
---|---|---|
51 | 51 |
$self->{scorezone_color_name}="#DE61E2"; |
52 | 52 |
$self->{empty_color_name}="#78FFED"; |
53 | 53 |
$self->{invalid_color_name}="#FFEF3B"; |
54 | ||
54 |
$self->{'conflict_color_name'}="#00FF00"; |
|
55 |
|
|
55 | 56 |
$self->{linewidth_zone}=1; |
56 | 57 |
$self->{linewidth_box}=1; |
57 | 58 |
$self->{linewidth_box_scan}=2; |
... | ... | |
67 | 68 |
$self->{'gc'} = Gtk2::Gdk::GC->new($self->window); |
68 | 69 | |
69 | 70 |
$self->{'color'}= Gtk2::Gdk::Color->parse($coul); |
70 |
for my $type ('',qw/scorezone_ question_ unticked_ empty_ invalid_/) { |
|
71 |
for my $type ('',qw/scorezone_ question_ unticked_ empty_ invalid_ conflict_/) {
|
|
71 | 72 |
$self->{$type.'color'}= |
72 | 73 |
Gtk2::Gdk::Color->parse($self->{$type.'color_name'}) if($type); |
73 | 74 |
$self->window->get_colormap->alloc_color($self->{$type.'color'},TRUE,TRUE); |
... | ... | |
305 | 306 |
$self->{'gc'}->set_foreground($self->{'colormark'}); |
306 | 307 | |
307 | 308 |
for $box (@{$self->{'layinfo'}->{'namefield'}}) { |
308 |
$self->draw_box($box,''); |
|
309 |
$self->draw_box($box,'',0);
|
|
309 | 310 |
} |
310 | 311 | |
311 | 312 |
$box=$self->{'layinfo'}->{'mark'}; |
... | ... | |
323 | 324 |
} |
324 | 325 | |
325 | 326 |
for my $box (@{$self->{'layinfo'}->{'digit'}}) { |
326 |
$self->draw_box($box,''); |
|
327 |
$self->draw_box($box,'',0);
|
|
327 | 328 |
} |
328 | 329 | |
329 | 330 |
} |
... | ... | |
355 | 356 |
@{$self->{'layinfo'}->{'box'}}) { |
356 | 357 |
$self->draw_box($box,''); |
357 | 358 |
} |
359 |
$self->{'gc'}->set_foreground($self->{'conflict_color'}); |
|
360 |
for $box (grep { $_->{'cur_conflict'} } |
|
361 |
@{$self->{'layinfo'}->{'box'}}) { |
|
362 |
$self->draw_box($box,'',$self->{box_external}); |
|
363 |
} |
|
358 | 364 |
} else { |
359 | 365 |
$self->{'gc'}->set_line_attributes($self->{linewidth_special}, |
360 | 366 |
GDK_LINE_SOLID,GDK_CAP_BUTT,GDK_JOIN_MITER); |
... | ... | |
380 | 386 |
for $box (@{$self->{'layinfo'}->{'questionbox'}}) { |
381 | 387 |
$self->draw_box($box,''); |
382 | 388 |
} |
389 |
$self->{'gc'}->set_foreground($self->{'conflict_color'}); |
|
390 |
for $box (grep { $_->{'cur_conflict'} } |
|
391 |
@{$self->{'layinfo'}->{'box'}}) { |
|
392 |
$self->draw_box($box,'',$self->{box_external}); |
|
393 |
} |
|
383 | 394 |
} |
384 | 395 |
$self->{'gc'}->set_line_attributes($self->{linewidth_zone}, |
385 | 396 |
GDK_LINE_SOLID,GDK_CAP_BUTT,GDK_JOIN_MITER); |