--- loncom/interface/lonmsgdisplay.pm 2012/10/02 16:42:07 1.161 +++ loncom/interface/lonmsgdisplay.pm 2016/02/26 21:44:39 1.183 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Routines for messaging display # -# $Id: lonmsgdisplay.pm,v 1.161 2012/10/02 16:42:07 bisitz Exp $ +# $Id: lonmsgdisplay.pm,v 1.183 2016/02/26 21:44:39 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -102,6 +102,8 @@ use HTML::TokeParser(); use Apache::Constants qw(:common); use Apache::loncommon(); use Apache::lonhtmlcommon(); +use Apache::longroup; +use Apache::lonnavmaps; use Apache::lontexconvert(); use HTML::Entities(); use Apache::lonlocal; @@ -120,21 +122,23 @@ my $startdis=''; sub folderlist { my ($folder,$msgstatus) = @_; - my %lt = &Apache::lonlocal::texthash( + my %html_lt = &Apache::lonlocal::texthash( actn => 'Action', fold => 'Folder', show => 'Show', status => 'Message Status', go => 'Go', + + ); + &html_escape(\%html_lt); + my %js_lt = &Apache::lonlocal::texthash( nnff => 'New Name for Folder', newn => 'New Name', - thfm => 'The folder may not be renamed', - fmnb => 'folder may not be renamed as it is a folder provided by the system.', - asth => 'as this name is already in use for a system-provided or user-defined folder.', - the => 'The', - tnfm => 'The new folder may not be named', + fmnb => 'Folder may not be renamed as it is a folder provided by the system.', + asth => 'Requested name already in use for a system-provided or user-defined folder.', ); + &js_escape(\%js_lt); # set se lastvisit for the new mail check in the toplevel menu &Apache::lonnet::appenv({'user.mailcheck.lastvisit'=>time}); @@ -182,16 +186,16 @@ function folder_choice(targetform,caller if (targetform.folderaction.options[targetform.folderaction.selectedIndex].value == 'rename') { for (var i=0; i<permfolders_keys.length; i++) { if (permfolders_keys[i] == targetform.folder.value) { - alert("$lt{'the'} '"+permfolders_vals[i]+"' $lt{'fmnb'}"); + alert("'"+permfolders_vals[i]+"' -- $js_lt{'fmnb'}"); return; } } - var foldername=prompt('$lt{'nnff'}','$lt{'newn'}'); + var foldername=prompt('$js_lt{'nnff'}','$js_lt{'newn'}'); if (foldername) { targetform.renamed.value=foldername; for (var i=0; i<allfolders.length; i++) { if (allfolders[i] == foldername) { - alert("$lt{'thfm'} '"+foldername+"' $lt{'asth'}"); + alert("'"+foldername+"' $js_lt{'asth'}"); return; } } @@ -207,7 +211,7 @@ function folder_choice(targetform,caller if (newname) { for (var i=0; i<allfolders.length; i++) { if (allfolders[i] == newname) { - alert("$lt{'tnfm'} '"+newname+"' $lt{'asth'}"); + alert("'"+newname+"' -- $js_lt{'asth'}"); return; } } @@ -222,34 +226,39 @@ function folder_choice(targetform,caller $output .= ' <form method="post" action="/adm/email" name="folderlist"> + <div class="LC_columnSection"><fieldset> + <legend>'.&mt('Folder Actions').'</legend> <table border="0" cellspacing="2" cellpadding="8"> <tr> - <td><b>'.$lt{'fold'}.'</b><br />'."\n". + <td><b>'.$html_lt{'fold'}.'</b><br />'."\n". &Apache::loncommon::select_form($folder,'folder',\%formhash).' </td> - <td><b>'.$lt{'show'}.'</b><br />'."\n". + <td><b>'.$html_lt{'show'}.'</b><br />'."\n". &Apache::loncommon::select_form($env{'form.interdis'},'interdis', \%show).' </td> - <td><b>'.$lt{'status'}.'</b><br />'."\n". + <td><b>'.$html_lt{'status'}.'</b><br />'."\n". &Apache::loncommon::select_form($msgstatus,'msgstatus',\%statushash).' </td> - <td><b>'.$lt{'actn'}.'</b><br />'."\n".' + <td style="padding-right: 40px;"> + <b>'.$html_lt{'actn'}.'</b><br />'."\n".' <span class="LC_nobreak">'. &Apache::loncommon::select_form('view','folderaction',\%actions). - ' <input type="button" value="'.$lt{'go'}. + ' <input type="button" value="'.$html_lt{'go'}. '" onclick="javascript:folder_choice(this.form,'."'change'".');" /> </span> </td> - <td><b>'.&mt('New Folder').'</b><br />'."\n".' + <td style="border-left: 1px solid;padding-left: 40px;"> + <b>'.&mt('New Folder').'</b><br />'."\n".' <span class="LC_nobreak"> <input type="text" size="15" name="newfolder" value="" /> - <input type="button" value="'.$lt{'go'}. + <input type="button" value="'.$html_lt{'go'}. '" onclick="javascript:folder_choice(this.form,'."'new'".');" /> </span> </td> </tr> </table> + </fieldset></div> '."\n". '<input type="hidden" name="sortedby" value="'.$env{'form.sortedby'}.'" />'. '<input type="hidden" name="renamed" value="" />'. @@ -261,8 +270,8 @@ sub get_permanent_folders { my %permfolders = &Apache::lonlocal::texthash('' => 'INBOX', 'trash' => 'TRASH', - 'critical' => 'Critical', - 'sent' => 'Sent Messages', + 'critical' => 'CRITICAL', + 'sent' => 'SENT MESSAGES', ); return %permfolders; } @@ -378,7 +387,7 @@ sub deletefolder { my ($folder)=@_; my %permfolders = &get_permanent_folders(); if (defined($permfolders{$folder})) { - return &mt('The folder "[_1]" may not be deleted.',$folder); + return &mt('The folder "[_1]" may not be deleted.',$permfolders{$folder}); } my %userfolders = &Apache::lonmsg::get_user_folders(); if (!defined($userfolders{$folder})) { @@ -543,7 +552,7 @@ sub discourse { $result .= '<fieldset id="LC_activeusers"><legend>' .$bcc_curr_hdr .'</legend>' - .'<form name="activeusers">'; + .'<form name="activeusers" action="">'; $result .= $tmptext.'</form></fieldset><br />'; if (ref($statushash) eq 'HASH') { $statushash->{'active'} = 1; @@ -564,7 +573,7 @@ sub discourse { $result .= '<fieldset id="LC_previoususers"><legend>' .$bcc_prev_hdr .'</legend>' - .'<form name="previoususers">'; + .'<form name="previoususers" action="">'; $result .= $tmptext.'</form></fieldset><br />'; if (ref($statushash) eq 'HASH') { $statushash->{'previous'} = 1; @@ -587,7 +596,7 @@ sub discourse { $result .= '<fieldset id="LC_futureusers"><legend>' .$bcc_future_hdr .'</legend>' - .'<form name="futureusers">'; + .'<form name="futureusers" action="">'; $result .= $tmptext.'</form></fieldset>'; if (ref($statushash) eq 'HASH') { $statushash->{'future'} = 1; @@ -662,7 +671,7 @@ sub disgroup { } $r->print('<fieldset>'. '<legend>'.$lt{$status}.'</legend>'. - '<form name="'.$formname.'">'. + '<form name="'.$formname.'" action="">'. '<span class="LC_nobreak">'. '<input type="button" value="'.&mt('Check All').'" '. 'onclick="javascript:toggleAll('."this.form,'check'".')" />'. @@ -766,14 +775,24 @@ sub groupmail_header { text=>"Groups", title=>$brtitle}); } - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"/adm/$cdom/$cnum/$group/smppg?$refarg", - text=>"Group: $description", - title=>"Go to group's home page"}, - {href=>"/adm/email?compose=group&group=". - "$env{'form.group'}&$refarg", - text=>"Send a Message in a Group", - title=>"Compose Group Message"},); + my $view_permission = + &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')); + my $navmap=Apache::lonnavmaps::navmap->new(); + my $grouppagelink = &Apache::longroup::get_group_link($cdom,$cnum,$group,$navmap,$view_permission,$refarg); + if ($grouppagelink) { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>$grouppagelink, + text=>"Group: $description", + title=>"Go to group's home page"},); + } else { + &Apache::lonhtmlcommon::add_breadcrumb + ({text=>"Group: $description",}); + } + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/email?compose=group&group=". + "$env{'form.group'}&$refarg", + text=>"Send a Message in a Group", + title=>"Compose Group Message"},); if ($action eq 'sending') { &Apache::lonhtmlcommon::add_breadcrumb ({text=>"Messages being sent.", @@ -811,7 +830,8 @@ sub discrit { .'<input type="hidden" name="confirm" value="true" />'; my %what=&Apache::lonnet::dump('critical'); my $result = ''; - foreach my $key (sort(keys(%what))) { + # Sort by date in descending order + foreach my $key (sort{$b <=> $a}(keys(%what))) { my %content=&Apache::lonmsg::unpackagemsg($what{$key}); next if ($content{'senderdomain'} eq ''); my $description; @@ -877,8 +897,9 @@ sub discrit { '<p class="LC_info">'. &mt('You have no critical messages.'). '</p>'. - '<a href="/adm/roles">'.&mt('Select a course').'</a><br />'. - '<a href="/adm/email">'.&mt('Communicate').'</a>'; + &Apache::lonhtmlcommon::actionbox( + ['<a href="/adm/roles">'.&mt('Select a course').'</a>', + '<a href="/adm/email">'.&mt('Communicate').'</a>']); } else { $r->print($header); } @@ -1020,6 +1041,13 @@ sub disall { &Apache::loncommon::store_settings('user','mail',\%saveable); &Apache::loncommon::restore_settings('user','mail',\%saveable); $folder ||= $env{'form.folder'}; + # Always show critical messages if present + my @what=&Apache::lonnet::dump('critical',$env{'user.domain'},$env{'user.name'}); + if ($what[0]) { + if (($what[0] ne 'con_lost') && ($what[0]!~/^error\:/)) { + $folder = 'critical'; + } + } $msgstatus ||= $env{'form.msgstatus'}; $env{'form.interdis'} ||= 20; @@ -1040,11 +1068,12 @@ sub disfolder { my %setters = (); my $numblocked = 0; my ($startblock,$endblock) = &Apache::loncommon::blockcheck(\%setters,'com'); - my %lt = &Apache::lonlocal::texthash( + my %js_lt = &Apache::lonlocal::texthash( sede => 'Select a destination folder to which the messages will be moved.', nome => 'No messages have been selected to apply this action to.', chec => 'Check the checkbox for at least one message.', ); + &js_escape(\%js_lt); my $jscript = &Apache::loncommon::check_uncheck_jscript(); $r->print(<<ENDDISHEADER); <script type="text/javascript"> @@ -1055,7 +1084,7 @@ sub disfolder { document.disall.markedaction.value = document.disall.checkedaction.options[document.disall.checkedaction.selectedIndex].value; if (document.disall.checkedaction.options[document.disall.checkedaction.selectedIndex].value == 'markedmove') { if (document.disall.movetofolder.options[document.disall.movetofolder.selectedIndex].value == "") { - alert("$lt{'sede'}"); + alert("$js_lt{'sede'}"); return; } } @@ -1072,7 +1101,7 @@ sub disfolder { } } if (checktotal == 0) { - alert("$lt{'nome'}\\n$lt{'chec'}"); + alert("$js_lt{'nome'}\\n$js_lt{'chec'}"); return; } document.disall.submit(); @@ -1201,7 +1230,7 @@ ENDDISHEADER foreach my $item ($localsenttime,$dis_name,$dis_domain,$shortsubj) { $r->print('<td>'.(($status eq 'new')?'<b>':''). '<a href="/adm/email?display='.$origID.$sqs.'">'. - $item.(($status eq 'new')?'</b>':'').'</a></td>'); + $item.'</a>'.(($status eq 'new')?'</b>':'').'</td>'); } # Description and Status my $showstatus; @@ -1232,17 +1261,17 @@ ENDDISHEADER # Bottom Functions - $r->print('<table border="0" cellspacing="2" cellpadding="8"> + $r->print(' +<div class="LC_columnSection"><fieldset> +<legend>'.&mt('Message Actions').'</legend> +<table border="0" cellspacing="2" cellpadding="8"> <tr> - <td> - <fieldset> - <legend>'.&mt('Select').'</legend> + <td><b>'.&mt('Select Messages').'</b><br /> <span class="LC_nobreak"> <input type="button" onclick="javascript:checkAll(document.disall.delmark)" value="'.&mt('Check All').'" />'."\n". ' <input type="button" onclick="javascript:uncheckAll(document.disall.delmark)" value="'.&mt('Uncheck All').'" />'."\n". '<input type="hidden" name="sortedby" value="'.$env{'form.sortedby'}.'" /> </span> - </fieldset> </td>'."\n". '<td><b>'.&mt('Action').'</b><br />'."\n". ' <select name="checkedaction">'."\n"); @@ -1251,7 +1280,7 @@ ENDDISHEADER $r->print(' <option value="markeddel">'.&mt('Delete').'</option>'."\n"); } if ($msgstatus ne 'read') { - $r->print(' <option value="markedread">'.&mt('Mark Read').'</option>."\n"'); + $r->print(' <option value="markedread">'.&mt('Mark Read').'</option>'."\n"); } if ($msgstatus ne 'unread') { $r->print(' <option value="markedunread">'.&mt('Mark Unread').'</option>'."\n"); @@ -1266,7 +1295,7 @@ ENDDISHEADER $r->print("\n".'</select></td>'."\n"); if (keys(%gotfolders) > 0) { - $r->print('<td><b>'.&mt('Destination folder').'<b><br />'); + $r->print('<td><b>'.&mt('Destination folder').'</b><br />'); my %userfolders; foreach my $key (keys(%gotfolders)) { $userfolders{$key} = $key; @@ -1275,10 +1304,12 @@ ENDDISHEADER $r->print(&Apache::loncommon::select_form('','movetofolder',\%userfolders). '</td>'); } - $r->print('<td>'. + $r->print('<td style="vertical-align:bottom;">'. '<input type="button" name="go" value="'.&mt('Go'). '" onclick="javascript:validate_checkedaction()"/></td>'."\n". - '</tr></table>'); + '</tr></table>'."\n". + '</fieldset></div>'."\n" + ); my $postedstartdis=$startdis+1; $r->print('<input type="hidden" name="folder" value="'.$folder.'" /><input type="hidden" name="startdis" value="'.$postedstartdis.'" /><input type="hidden" name="interdis" value="'.$env{'form.interdis'}.'" /><input type="hidden" name="msgstatus" value="'.$msgstatus.'" /><input type="hidden" name="markedaction" value="" /></form>'); if ($numblocked > 0) { @@ -1381,11 +1412,14 @@ sub compout { 'to' => 'To:', ); my %attachmax = ( - text => &mt('(128 KB max size)'), - num => 131072, + text => &mt('(1 MB max size)'), + num => 1048576, ); if (!$forwarding && !$multiforward) { - $attachrow = '<tr><td colspan="3"><b>'.$lt{'atta'}.'</b> '.$attachmax{'text'}.': <input type="file" name="attachment" /></td></tr>'; + $attachrow = '<tr><td colspan="3"><b>'.$lt{'atta'}.'</b> '.$attachmax{'text'} + .': <input type="file" name="attachment" class="flUpload" multiple />' + .'</td></tr>' + .'<input type="hidden" id="free_space" value="'.$attachmax{'num'}.'" />'; } if (&Apache::lonnet::allowed('srm',$env{'request.course.id'}) || &Apache::lonnet::allowed('srm',$env{'request.course.id'}. @@ -1657,8 +1691,8 @@ ENDREPSCRIPT $r->print(&additional_rec_row(\%lt)); $r->print('<tr><td colspan="2">'. &mt('Unless you choose otherwise:').'<ul><li>'. - &mt("The subject in each forwarded message will be <i>'Forwarding:'</i> followed by the original subject.").'</li><li>'. - &mt("The message itself will begin with a first line: <i>'Forwarded message from'</i> followed by the original sender's name.").'</li></ul></td></tr>'); + &mt("The subject in each forwarded message will be [_1]'Forwarding:'[_2] followed by the original subject.",'<i>','</i>').'</li><li>'. + &mt("The message itself will begin with a first line: [_1]'Forwarded message from'[_2] followed by the original sender's name.",'<i>','</i>').'</li></ul></td></tr>'); $func1='Forward'; # do not translate here! $dissub = &mt('Forwarding').': '; $subj_size = '10'; @@ -1733,7 +1767,7 @@ ENDBLOCK '</pre> </p> <p> -'.&mt('The messages will be assembled from all lines with the respective'."\n".'<tt>username:domain</tt>, and appended to the general message text.')); +'.&mt('The messages will be assembled from all lines with the respective [_1][_2]username:domain[_3], and appended to the general message text.','<br />','<tt>','</tt>')); $r->print(<<ENDUPLOAD); </p> <p> @@ -1887,7 +1921,7 @@ sub disfacetoface { $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'}, '%255b'.$user.'%253a'.$domain.'%255d'); - my $result='<div>'; + my $result=''; foreach my $key (sort(keys(%records))) { my %content=&Apache::lonmsg::unpackagemsg($records{$key}); next if ($content{'senderdomain'} eq ''); @@ -1919,8 +1953,7 @@ sub disfacetoface { } else { %content=&Apache::lonmsg::unpackagemsg($content{'message'}); $content{'message'} = - '<b>'.&mt('Subject').': '.$content{'subject'}.'</b><br -'. + '<b>'.&mt('Subject').': '.$content{'subject'}.'</b><br />'. $content{'message'}; } } else { @@ -1949,15 +1982,15 @@ $content{'sendername'}.':'. if ($result eq '') { my $lctype = &mt(lc(&Apache::loncommon::course_type())); if ($target ne 'tex') { - $r->print("<p><b>".&mt('No notes, face-to-face discussion records, critical messages, or broadcast messages in this [_1].',$lctype)."</b></p>"); + $r->print("<p><b>".&mt('No notes, face-to-face discussion records, critical messages or broadcast messages in this '.$lctype.'.')."</b></p>"); } else { - $r->print('\textbf{'.&mt('No notes, face-to-face discussion records, critical messages or broadcast messages in this [_1].',$lctype).'}\\\\'); + $r->print('\textbf{'.&mt('No notes, face-to-face discussion records, critical messages or broadcast messages in this '.$lctype.'.').'}\\\\'); } - } elsif ($target ne 'tex') { - $r->print($result.'</div>'); + } elsif ($target eq 'tex') { + $r->print(&Apache::lonxml::xmlparse($r,$target,$result)); } else { - $r->print(&Apache::lonxml::xmlparse($r, 'tex', $result)); - } + $r->print('<div>'.$result.'</div>'); + } } sub general_message { @@ -2129,19 +2162,22 @@ sub displaymessage { push(@functionlist,'<a href="/adm/email?markdel='.&escape($msgid).$sqs.'">' .&mt('Delete') .'</a>'); - push(@functionlist,'<a href="/adm/email?'.$sqs.'">' - .&mt('Back to Folder Display') - .'</a>'); + +# Prepare available navigation + my @navigationlist; if ($counter > 0){ - push(@functionlist,'<a href="/adm/email?display='.$messages[$counter-1]->[5].$sqs.'">' + push(@navigationlist,'<a href="/adm/email?display='.$messages[$counter-1]->[5].$sqs.'">' .&mt('Previous') .'</a>'); } if ($counter < $number_of_messages - 1){ - push(@functionlist,'<a href="/adm/email?display='.$messages[$counter+1]->[5].$sqs.'">' + push(@navigationlist,'<a href="/adm/email?display='.$messages[$counter+1]->[5].$sqs.'">' .&mt('Next') .'</a>'); } + push(@navigationlist,'<a href="/adm/email?'.$sqs.'">' + .&mt('Back to Folder Display') + .'</a>'); # Prepare available actions my $symb; @@ -2150,12 +2186,12 @@ sub displaymessage { } elsif (defined($content{'baseurl'})) { $symb=&Apache::lonnet::symbread($content{'baseurl'}); } - my @actionlist; + my @actionlist; if ($env{'user.adv'}) { if (&Apache::lonnet::allowed('vgr',$env{'request.course.id'})) { push(@actionlist,&Apache::loncommon::track_student_link( - &mt('View recent activity') + 'View recent activity' ,$content{'sendername'} ,$content{'senderdomain'} ,'check')); @@ -2178,7 +2214,7 @@ sub displaymessage { } } -# Print functionlist and actionlist in page header +# Print functionlist, navigationlist, and actionlist in page header my $functions='<div class="LC_columnSection">'; # Functionlist @@ -2188,10 +2224,18 @@ sub displaymessage { } $functions .= &Apache::lonhtmlcommon::end_funclist(); + # Navigationlist + $functions.=&Apache::lonhtmlcommon::start_funclist( + &mt('Navigation')); + foreach my $item (@navigationlist) { + $functions.=&Apache::lonhtmlcommon::add_item_funclist($item); + } + $functions .= &Apache::lonhtmlcommon::end_funclist(); + # Actionlist if (@actionlist) { - my $legendtext=&mt('Currently available actions (will open extra window)'); - $functions.=&Apache::lonhtmlcommon::start_funclist($legendtext); + $functions.=&Apache::lonhtmlcommon::start_funclist( + &mt('Currently available actions (will open extra window)')); foreach my $item (@actionlist) { $functions.=&Apache::lonhtmlcommon::add_item_funclist($item); } @@ -2638,6 +2682,8 @@ sub header { if ($baseurl) { $extra .= "<base href=\"".&Apache::lonnet::absolute_url()."/$baseurl\" />"; } + $extra .= '<script type="text/javascript" + src="/res/adm/includes/file_upload.js"></script>'; $r->print(&Apache::loncommon::start_page('Messages', $extra)); $r->print(&Apache::lonhtmlcommon::breadcrumbs @@ -2675,7 +2721,7 @@ sub storedcommentlisting { '^'.&escape(&escape($env{'form.showcommentbaseurl'}))); $r->print(&Apache::loncommon::start_page('Saved Comment Listing',undef, {'onlybody' => 1})); - if ((keys %msgs)[0]=~/^error\:/) { + if ((keys(%msgs))[0]=~/^error\:/) { $r->print(&mt('No saved comments yet.')); } else { my $found=0; @@ -2890,6 +2936,7 @@ sub sendoffmail { } my @recusers; my @recudoms; + my %permresults; foreach my $address (sort(keys(%toaddr))) { my ($recuname,$recdomain)=split(/\:/,$address); my $msgtxt = $savemsg; @@ -2906,7 +2953,8 @@ sub sendoffmail { $env{'form.sendbck'}, $env{'form.permanent'}, \$sentmessage{$address}, - $nosentstore,$recipid); + $nosentstore,$recipid, + $attachmenturl,\%permresults); } else { $r->print(&mt('Sending').' '.$recuname.':'.$recdomain.': '); @thismsg= @@ -2917,13 +2965,20 @@ sub sendoffmail { $env{'form.permanent'}, \$sentmessage{$address}, undef,undef,undef, - $nosentstore,$recipid); + $nosentstore,$recipid, + \%permresults); } $msg_status{$recuname.':'.$recdomain}=join(' ',@thismsg); if ($msg_status{$recuname.':'.$recdomain} =~ /(ok|con_delayed)/) { $numsent++; push(@recusers,$recuname); push(@recudoms,$recdomain); + if ($1 eq 'ok') { + $r->print('ok '); + } + if ($permresults{$recuname.':'.$recdomain}) { + $r->print(' (email) '); + } } $sendstatus.=' '.join(' ',@thismsg); }