+
+XMLEDIT
+}
+
+sub insert_folding_button {
+ my $curDepth = $Apache::lonxml::curdepth;
+ my $lastresource = $env{'request.ambiguous'};
+
+ return "";
+}
+
=pod
=head1 Excel and CSV file utility routines
@@ -2363,6 +2600,8 @@ Outputs:
=item * $clientinfo
+=item * $clientosversion
+
=back
=back
@@ -2382,8 +2621,9 @@ sub decode_user_agent {
my $clientmathml='';
my $clientunicode='0';
my $clientmobile=0;
+ my $clientosversion='';
for (my $i=0;$i<=$#browsertype;$i++) {
- my ($bname,$match,$notmatch,$vreg,$minv,$univ)=split(/\:/,$browsertype[$i]);
+ my ($bname,$match,$notmatch,$vreg,$minv,$univ)=split(/\%/,$browsertype[$i]);
if (($httpbrowser=~/$match/i) && ($httpbrowser!~/$notmatch/i)) {
$clientbrowser=$bname;
$httpbrowser=~/$vreg/i;
@@ -2403,7 +2643,12 @@ sub decode_user_agent {
if ($httpbrowser=~/next/i) { $clientos='next'; }
if (($httpbrowser=~/mac/i) ||
($httpbrowser=~/powerpc/i)) { $clientos='mac'; }
- if ($httpbrowser=~/win/i) { $clientos='win'; }
+ if ($httpbrowser=~/win/i) {
+ $clientos='win';
+ if ($httpbrowser =~/Windows\s+NT\s+(\d+\.\d+)/i) {
+ $clientosversion = $1;
+ }
+ }
if ($httpbrowser=~/embed/i) { $clientos='pda'; }
if ($httpbrowser=~/(Android|iPod|iPad|iPhone|webOS|Blackberry|Windows Phone|Opera m(?:ob|in)|Fennec)/i) {
$clientmobile=lc($1);
@@ -2414,7 +2659,8 @@ sub decode_user_agent {
$clientinfo = 'chromeframe-'.$1;
}
return ($httpbrowser,$clientbrowser,$clientversion,$clientmathml,
- $clientunicode,$clientos,$clientmobile,$clientinfo);
+ $clientunicode,$clientos,$clientmobile,$clientinfo,
+ $clientosversion);
}
###############################################################
@@ -3750,7 +3996,7 @@ sub user_lang {
=over 4
=item * &get_previous_attempt($symb, $username, $domain, $course,
- $getattempt, $regexp, $gradesub)
+ $getattempt, $regexp, $gradesub, $usec, $identifier)
Return string with previous attempt on problem. Arguments:
@@ -3772,6 +4018,11 @@ Return string with previous attempt on p
=item * $gradesub: routine that processes the string if it matches $regexp
+=item * $usec: section of the desired student
+
+=item * $identifier: counter for student (multiple students one problem) or
+ problem (one student; whole sequence).
+
=back
The output string is a table containing all desired attempts, if any.
@@ -3779,7 +4030,7 @@ The output string is a table containing
=cut
sub get_previous_attempt {
- my ($symb,$username,$domain,$course,$getattempt,$regexp,$gradesub)=@_;
+ my ($symb,$username,$domain,$course,$getattempt,$regexp,$gradesub,$usec,$identifier)=@_;
my $prevattempts='';
no strict 'refs';
if ($symb) {
@@ -3795,7 +4046,7 @@ sub get_previous_attempt {
}
$prevattempts=&start_data_table().&start_data_table_header_row();
$prevattempts.=''.&mt('History').' | ';
- my (%typeparts,%lasthidden);
+ my (%typeparts,%lasthidden,%regraded,%hidestatus);
my $showsurv=&Apache::lonnet::allowed('vas',$env{'request.course.id'});
foreach my $key (sort(keys(%lasthash))) {
my ($ign,@parts) = split(/\./,$key);
@@ -3812,6 +4063,18 @@ sub get_previous_attempt {
$lasthidden{$ign.'.'.$id} = 1;
}
}
+ if ($identifier ne '') {
+ my $id = join(',',@parts);
+ if (&Apache::lonnet::EXT("resource.$id.problemstatus",$symb,
+ $domain,$username,$usec,undef,$course) =~ /^no/) {
+ $hidestatus{$ign.'.'.$id} = 1;
+ }
+ }
+ } elsif ($data eq 'regrader') {
+ if (($identifier ne '') && (@parts)) {
+ my $id = join(',',@parts);
+ $regraded{$ign.'.'.$id} = 1;
+ }
}
} else {
if ($#parts == 0) {
@@ -3823,17 +4086,60 @@ sub get_previous_attempt {
}
$prevattempts.=&end_data_table_header_row();
if ($getattempt eq '') {
+ my (%solved,%resets,%probstatus);
+ if (($identifier ne '') && (keys(%regraded) > 0)) {
+ for ($version=1;$version<=$returnhash{'version'};$version++) {
+ foreach my $id (keys(%regraded)) {
+ if (($returnhash{$version.':'.$id.'.regrader'}) &&
+ ($returnhash{$version.':'.$id.'.tries'} eq '') &&
+ ($returnhash{$version.':'.$id.'.award'} eq '')) {
+ push(@{$resets{$id}},$version);
+ }
+ }
+ }
+ }
for ($version=1;$version<=$returnhash{'version'};$version++) {
- my @hidden;
+ my (@hidden,@unsolved);
if (%typeparts) {
foreach my $id (keys(%typeparts)) {
- if (($returnhash{$version.':'.$id.'.type'} eq 'anonsurvey') || ($returnhash{$version.':'.$id.'.type'} eq 'anonsurveycred')) {
+ if (($returnhash{$version.':'.$id.'.type'} eq 'anonsurvey') ||
+ ($returnhash{$version.':'.$id.'.type'} eq 'anonsurveycred')) {
push(@hidden,$id);
+ } elsif ($identifier ne '') {
+ unless (($returnhash{$version.':'.$id.'.type'} eq 'survey') ||
+ ($returnhash{$version.':'.$id.'.type'} eq 'surveycred') ||
+ ($hidestatus{$id})) {
+ next if ((ref($resets{$id}) eq 'ARRAY') && grep(/^\Q$version\E$/,@{$resets{$id}}));
+ if ($returnhash{$version.':'.$id.'.solved'} eq 'correct_by_student') {
+ push(@{$solved{$id}},$version);
+ } elsif (($returnhash{$version.':'.$id.'.solved'} ne '') &&
+ (ref($solved{$id}) eq 'ARRAY')) {
+ my $skip;
+ if (ref($resets{$id}) eq 'ARRAY') {
+ foreach my $reset (@{$resets{$id}}) {
+ if ($reset > $solved{$id}[-1]) {
+ $skip=1;
+ last;
+ }
+ }
+ }
+ unless ($skip) {
+ my ($ign,$partslist) = split(/\./,$id,2);
+ push(@unsolved,$partslist);
+ }
+ }
+ }
}
}
}
$prevattempts.=&start_data_table_row().
- ''.&mt('Transaction [_1]',$version).' | ';
+ ''.&mt('Transaction [_1]',$version);
+ if (@unsolved) {
+ $prevattempts .= '';
+ }
+ $prevattempts .= ' | ';
if (@hidden) {
foreach my $key (sort(keys(%lasthash))) {
next if ($key =~ /\.foilorder$/);
@@ -4320,23 +4626,20 @@ sub findallcourses {
###############################################
sub blockcheck {
- my ($setters,$activity,$uname,$udom,$url) = @_;
+ my ($setters,$activity,$uname,$udom,$url,$is_course) = @_;
- if (!defined($udom)) {
+ if (defined($udom) && defined($uname)) {
+ # If uname and udom are for a course, check for blocks in the course.
+ if (($is_course) || (&Apache::lonnet::is_course($udom,$uname))) {
+ my ($startblock,$endblock,$triggerblock) =
+ &get_blocks($setters,$activity,$udom,$uname,$url);
+ return ($startblock,$endblock,$triggerblock);
+ }
+ } else {
$udom = $env{'user.domain'};
- }
- if (!defined($uname)) {
$uname = $env{'user.name'};
}
- # If uname and udom are for a course, check for blocks in the course.
-
- if (&Apache::lonnet::is_course($udom,$uname)) {
- my ($startblock,$endblock,$triggerblock) =
- &get_blocks($setters,$activity,$udom,$uname,$url);
- return ($startblock,$endblock,$triggerblock);
- }
-
my $startblock = 0;
my $endblock = 0;
my $triggerblock = '';
@@ -4346,7 +4649,8 @@ sub blockcheck {
# boards, chat or groups, check for blocking in current course only.
if (($activity eq 'boards' || $activity eq 'chat' ||
- $activity eq 'groups') && ($env{'request.course.id'})) {
+ $activity eq 'groups' || $activity eq 'printout') &&
+ ($env{'request.course.id'})) {
foreach my $key (keys(%live_courses)) {
if ($key ne $env{'request.course.id'}) {
delete($live_courses{$key});
@@ -4610,12 +4914,12 @@ sub parse_block_record {
}
sub blocking_status {
- my ($activity,$uname,$udom,$url) = @_;
+ my ($activity,$uname,$udom,$url,$is_course) = @_;
my %setters;
# check for active blocking
my ($startblock,$endblock,$triggerblock) =
- &blockcheck(\%setters,$activity,$uname,$udom,$url);
+ &blockcheck(\%setters,$activity,$uname,$udom,$url,$is_course);
my $blocked = 0;
if ($startblock && $endblock) {
$blocked = 1;
@@ -4670,13 +4974,13 @@ END_BLOCK
###############################################
sub check_ip_acc {
- my ($acc)=@_;
+ my ($acc,$clientip)=@_;
&Apache::lonxml::debug("acc is $acc");
if (!defined($acc) || $acc =~ /^\s*$/ || $acc =~/^\s*no\s*$/i) {
return 1;
}
my $allowed=0;
- my $ip=$env{'request.host'} || $ENV{'REMOTE_ADDR'};
+ my $ip=$env{'request.host'} || $ENV{'REMOTE_ADDR'} || $clientip;
my $name;
foreach my $pattern (split(',',$acc)) {
@@ -6337,6 +6641,10 @@ span.LC_cusr_subheading {
font-size: 85%;
}
+span.LC_math-error {
+ border: solid 1px red; min-width: 1px;
+}
+
div.LC_docs_entry_move {
border: 1px solid #BBBBBB;
background: #DDDDDD;
@@ -6486,6 +6794,7 @@ div.LC_edit_problem_footer div,
div.LC_edit_problem_editxml_header,
div.LC_edit_problem_editxml_header div {
margin-top: 5px;
+ z-index: 100;
}
div.LC_edit_problem_header_title {
@@ -6503,7 +6812,12 @@ table.LC_edit_problem_header_title {
div.LC_edit_problem_discards {
float: left;
- padding-bottom: 5px;
+}
+
+div.LC_edit_actionbar {
+ margin: -5px 0px 0px 0px !important;
+ background-color: $sidebg;
+ height: 31px;
}
div.LC_edit_problem_saves {
@@ -6524,6 +6838,10 @@ div.LC_edit_problem_saves {
margin-left: 40px;
}
+#LC_edit_problem_codemirror div{
+ margin-left: 0px;
+}
+
img.stift {
border-width: 0;
vertical-align: middle;
@@ -6638,7 +6956,6 @@ fieldset > legend {
ol.LC_primary_menu {
margin: 0;
padding: 0;
- background-color: $pgbg_or_bgcolor;
}
ol#LC_PathBreadcrumbs {
@@ -6650,23 +6967,48 @@ ol.LC_primary_menu li {
vertical-align: middle;
text-align: left;
list-style: none;
+ position: relative;
float: left;
+ z-index: 100; /* will be displayed above codemirror and underneath the help-layer */
+ line-height: 1.5em;
}
-ol.LC_primary_menu li a {
+ol.LC_primary_menu li a,
+ol.LC_primary_menu li p {
display: block;
margin: 0;
padding: 0 5px 0 10px;
text-decoration: none;
}
-ol.LC_primary_menu li ul {
+ol.LC_primary_menu li p span.LC_primary_menu_innertitle {
+ display: inline-block;
+ width: 95%;
+ text-align: left;
+}
+
+ol.LC_primary_menu li p span.LC_primary_menu_innerarrow {
+ display: inline-block;
+ width: 5%;
+ float: right;
+ text-align: right;
+ font-size: 70%;
+}
+
+ol.LC_primary_menu ul {
display: none;
- width: 10em;
+ width: 15em;
background-color: $data_table_light;
+ position: absolute;
+ top: 100%;
}
-ol.LC_primary_menu li:hover ul, ol.LC_primary_menu li.hover ul {
+ol.LC_primary_menu ul ul {
+ left: 100%;
+ top: 0;
+}
+
+ol.LC_primary_menu li:hover > ul, ol.LC_primary_menu li.hover > ul {
display: block;
position: absolute;
margin: 0;
@@ -6675,15 +7017,21 @@ ol.LC_primary_menu li:hover ul, ol.LC_pr
}
ol.LC_primary_menu li:hover li, ol.LC_primary_menu li.hover li {
+/* First Submenu -> size should be smaller than the menu title of the whole menu */
font-size: 90%;
vertical-align: top;
float: none;
border-left: 1px solid black;
border-right: 1px solid black;
+/* A dark bottom border to visualize different menu options;
+overwritten in the create_submenu routine for the last border-bottom of the menu */
+ border-bottom: 1px solid $data_table_dark;
}
-ol.LC_primary_menu li:hover li a, ol.LC_primary_menu li.hover li a {
- background-color:$data_table_light;
+ol.LC_primary_menu li li p:hover {
+ color:$button_hover;
+ text-decoration:none;
+ background-color:$data_table_dark;
}
ol.LC_primary_menu li li a:hover {
@@ -6691,6 +7039,11 @@ ol.LC_primary_menu li li a:hover {
background-color:$data_table_dark;
}
+/* Font-size equal to the size of the predecessors*/
+ol.LC_primary_menu li:hover li li {
+ font-size: 100%;
+}
+
ol.LC_primary_menu li img {
vertical-align: bottom;
height: 1.1em;
@@ -7302,7 +7655,10 @@ sub headtag {
''.
&font_settings($args);
- my $inhibitprint = &print_suppression();
+ my $inhibitprint;
+ if ($args->{'print_suppress'}) {
+ $inhibitprint = &print_suppression();
+ }
if (!$args->{'frameset'}) {
$result .= &Apache::lonhtmlcommon::htmlareaheaders();
@@ -7428,7 +7784,7 @@ sub print_suppression {
}
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
- my $blocked = &blocking_status('printout',$cnum,$cdom);
+ my $blocked = &blocking_status('printout',$cnum,$cdom,undef,1);
if ($blocked) {
my $checkrole = "cm./$cdom/$cnum";
if ($env{'request.course.sec'} ne '') {
@@ -7661,10 +8017,12 @@ function set_wishlistlink(title, path) {
title = title.replace(/^LON-CAPA /,'');
}
title = encodeURIComponent(title);
+ title = title.replace("'","\\\'");
if (!path) {
path = location.pathname;
}
path = encodeURIComponent(path);
+ path = path.replace("'","\\\'");
Win = window.open('/adm/wishlist?mode=newLink&setTitle='+title+'&setPath='+path,
'wishlistNewLink','width=560,height=350,scrollbars=0');
}
@@ -7707,10 +8065,11 @@ var modalWindow = {
};
var openMyModal = function(source,width,height,scrolling,transparency,style)
{
+ source = source.replace("'","'");
modalWindow.windowId = "myModal";
modalWindow.width = width;
modalWindow.height = height;
- modalWindow.content = "