--- loncom/interface/lonmsgdisplay.pm	2007/05/05 06:13:46	1.79
+++ loncom/interface/lonmsgdisplay.pm	2008/10/08 14:56:50	1.93
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Routines for messaging display
 #
-# $Id: lonmsgdisplay.pm,v 1.79 2007/05/05 06:13:46 albertel Exp $
+# $Id: lonmsgdisplay.pm,v 1.93 2008/10/08 14:56:50 bisitz Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -513,22 +513,34 @@ sub discourse {
     
     $result .= '<input type="hidden" name="sendmode" value="group" />'."\n";
 
-    $result .= &Apache::lonselstudent::render_student_list($current_members,
-							   "compemail",
-							   "current",
-							   \%defaultUsers,
-							   1,"selectedusers",1);
-
-    $result .= &Apache::lonselstudent::render_student_list($expired_members,
-							   "compemail",
-							   "expired",
-							   \%defaultUsers,
-							   1, "selectedusers",0);
-    $result .= &Apache::lonselstudent::render_student_list($future_members,
-							   "compemail",
-							   "future",
-							   \%defaultUsers,
-							   1, "selectedusers", 0);
+    my $tmptext;
+    if ($tmptext = &Apache::lonselstudent::render_student_list($current_members,
+                                                               "compemail",
+                                                               "current",
+                                                               \%defaultUsers,
+                                                               1,"selectedusers",1)
+       ) {
+       $result .= '<h2>'.&mt('Course members with current access').'</h2>';
+       $result .= $tmptext;
+    }
+    if ($tmptext = &Apache::lonselstudent::render_student_list($expired_members,
+                                                               "compemail",
+                                                               "expired",
+                                                               \%defaultUsers,
+                                                               1, "selectedusers",0)
+       ) {
+       $result .= '<h2>'.&mt('Course members with expired access').'</h2>';
+       $result .= $tmptext;
+    }
+    if ($tmptext = &Apache::lonselstudent::render_student_list($future_members,
+                                                               "compemail",
+                                                               "future",
+                                                               \%defaultUsers,
+                                                               1, "selectedusers", 0)
+       ) {
+       $result .= '<h2>'.&mt('Course members with future access').'</h2>';
+       $result .= $tmptext;
+    }
     return $result;
 }
 
@@ -555,7 +567,7 @@ sub disgroup {
                       'recipients to select.');
         return $result;
     } else {
-        $result = &mt('Select message recipients from the group members listed below.<br />');  
+        $result = &mt('Select message recipients from the group members listed below.').'<br />';  
         my %Sortby = (
                          active   => {},
                          previous => {},
@@ -721,23 +733,34 @@ sub groupmail_sent {
 
 sub discrit {
     my $r=shift;
-    my $header = '<h1><font color="red">'.&mt('Critical Messages').'</font></h1>'.
-        '<form action="/adm/email" method="POST">'.
-        '<input type="hidden" name="confirm" value="true" />';
+    my $header = '<h1>'.&mt('Critical Messages').'</h1>'
+                .'<div class="LC_warning">'
+                .&mt('Access to other pages will be prevented until you have moved all critical messages to your inbox.')
+                .'</div><br />'
+                .'<form action="/adm/email" method="POST">'
+                .'<input type="hidden" name="confirm" value="true" />';
     my %what=&Apache::lonnet::dump('critical');
     my $result = '';
     foreach my $key (sort(keys(%what))) {
         my %content=&Apache::lonmsg::unpackagemsg($what{$key});
         next if ($content{'senderdomain'} eq '');
-        $result.='<hr />'.&mt('From').': <b>'.
-&Apache::loncommon::aboutmewrapper(
- &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).'</b> ('.
-$content{'sendername'}.':'.
-            $content{'senderdomain'}.') '.$content{'time'}.
-            '<br />'.&mt('Subject').': '.$content{'subject'}.
-            '<br /><pre>'.
-              &Apache::lontexconvert::msgtexconverted($content{'message'}).
-            '</pre><small>';
+        $result .= &Apache::lonhtmlcommon::start_pick_box()
+                  .&Apache::lonhtmlcommon::row_title(&mt('From'),undef,'LC_oddrow_value')
+                  .'<b>'.&Apache::loncommon::aboutmewrapper(
+                   &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).'</b>'
+                  .' ('.$content{'sendername'}.':'.$content{'senderdomain'}.')'
+                  .&Apache::lonhtmlcommon::row_closure(1)
+                  .&Apache::lonhtmlcommon::row_title(&mt('Date'),undef,'LC_evenrow_value')
+                  .$content{'time'}
+                  .&Apache::lonhtmlcommon::row_closure(1)
+                  .&Apache::lonhtmlcommon::row_title(&mt('Subject'),undef,'LC_oddrow_value')
+                  .$content{'subject'}
+                  .&Apache::lonhtmlcommon::row_closure(1)
+                  .&Apache::lonhtmlcommon::row_title(&mt('Message'),undef,'LC_evenrow_value')
+                  .'<pre>'.&Apache::lontexconvert::msgtexconverted($content{'message'}).'</pre>'
+                  .&Apache::lonhtmlcommon::row_closure()
+                  .&Apache::lonhtmlcommon::row_title('',undef,'LC_oddrow_value')
+                  .'<div class="LC_warning">';
         my ($rec_button,$reprec_button);
         $rec_button = &mt('Move to Inbox');
         if (!$content{'noreplies'}) {
@@ -752,12 +775,17 @@ $content{'sendername'}.':'.
         } else {
             $result .= &mt('Access to other pages will be prevented until you have moved the message to your inbox.'); 
         }
-        $result .= '</small><br />'.
-            '<input type="submit" name="rec_'.$key.'" value="'.$rec_button.'" />';
+        $result .= '</div>'
+                  .&Apache::lonhtmlcommon::row_closure(1)
+                  .&Apache::lonhtmlcommon::row_title('',undef,'LC_evenrow_value')
+                  .'<input type="submit" name="rec_'.$key.'" value="'.$rec_button.'" />';
         if (!$content{'noreplies'}) {
-            $result .= '<input type="submit" name="reprec_'.$key.'" '.
-                  'value="'.$reprec_button.'" />';
+            $result .= '<input type="submit" name="reprec_'.$key.'" '
+                      .'value="'.$reprec_button.'" />'
         }
+        $result .= &Apache::lonhtmlcommon::row_closure(1)
+                  .&Apache::lonhtmlcommon::end_pick_box()
+                  .'<br />';
     }
     # Check to see if there were any messages.
     if ($result eq '') {
@@ -892,8 +920,7 @@ sub get_course_desc {
 
 sub disall {
     my ($r,$folder,$msgstatus)=@_;
-    my %saveable = ('folder'    => 'scalar',
-		    'msgstatus' => 'scalar',
+    my %saveable = ('msgstatus' => 'scalar',
 		    'sortedby'  => 'scalar',
 		    'interdis'  => 'scalar',
 		    );
@@ -930,16 +957,6 @@ sub disfolder {
 <script type="text/javascript">
     $jscript
 
-    function checkfoldermove() {
-        if (document.disall.checkedaction.options[document.disall.checkedaction.selectedIndex].value == 'markedmove') {
-            if (document.disall.movetofolder.options[document.disall.movetofolder.selectedIndex].value == "") {
-                alert("$lt{'sede'}");
-                return;
-            }
-        }
-        return; 
-    }
-
     function validate_checkedaction() {
         document.disall.markedaction.value = document.disall.checkedaction.options[document.disall.checkedaction.selectedIndex].value;
         if (document.disall.checkedaction.options[document.disall.checkedaction.selectedIndex].value == 'markedmove') {
@@ -1111,7 +1128,7 @@ ENDDISHEADER
   '<input type="button" onclick="javascript:uncheckAll(document.disall.delmark)" value="'.&mt('Uncheck All').'" />'."\n".
   '<input type="hidden" name="sortedby" value="'.$env{'form.sortedby'}.'" /></td><td>&nbsp;</td>'."\n".
   '<td align="center"><b>'.&mt('Action').'</b><br />'."\n".
-  '  <select name="checkedaction" onchange="javascript:checkfoldermove()">'."\n");
+  '  <select name="checkedaction">'."\n");
 
     if ($folder ne 'trash') {
         $r->print('    <option value="markeddel">'.&mt('Delete').'</option>'."\n");
@@ -1205,8 +1222,9 @@ sub compout {
         &printheader($r,'/adm/email?compose=multiforward',
              'Forwarding Multiple Messages');
         if ($multiforward > 1) {
-            $r->print(&mt('Each of the <b>[quant,_1,message]</b> you checked
-will be forwarded to the recipient(s) you select below.',$multiforward).'<br />');
+            $r->print(&mt('Each of the <b>[quant,_1,message]</b> you checked'
+                         .' will be forwarded to the recipient(s) you select below.',$multiforward)
+                    .'<br />');
         } else {
             $r->print(&mt('The message you checked will be forwarded to the recipient(s) you select below.').'<br />');
         }
@@ -1220,6 +1238,7 @@ will be forwarded to the recipient(s) yo
     my $dissub='';
     my $dismsg='';
     my $disbase='';
+    my $attachrow;
     my $func=&mt('Send New');
     my %lt=&Apache::lonlocal::texthash('us'  => 'Username',
 				       'do'  => 'Domain',
@@ -1234,7 +1253,15 @@ will be forwarded to the recipient(s) yo
                                        'gmt' => 'General message text',
                                        'tff' => 'The file format for the uploaded portion of the message is',
                                        'uas' => 'Upload and Send',
+                                       'atta' => 'Attachment',
                                       );
+    my %attachmax = (
+                     text => &mt('(128 KB max size)'),
+                     num  => 131072,
+                    );
+    if (!$forwarding && !$multiforward) {
+        $attachrow = '<br />'.$lt{'atta'}.' '.$attachmax{'text'}.': <input type="file" name="attachment" />';
+    }
     if (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
 	|| &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
 				    '/'.$env{'request.course.sec'})) {
@@ -1428,7 +1455,10 @@ $latexHelp.
 </table>
 $latexHelp
 <textarea name="message" id="message" cols="80" rows="15" wrap="hard">$dismsg
-</textarea></p><br />
+</textarea>
+$attachrow
+</p>
+<br />
 $dispcrit
 $disbase
 ENDCOMP
@@ -1515,9 +1545,10 @@ ENDREP
 sub additional_rec_row {
     my ($lt) = @_;
     my $cc = &mt('Cc:');
-    my $bcc = &mt('Bcc:'); 
+    my $bcc = &mt('Bcc:');
+    my $exmpl = &mt('username:domain,username:domain,...'); 
     my $output = <<"ENDADD";
-<tr><td>$lt->{'ad'} :<br /><tt>username:domain,username:domain, ...
+<tr><td>$lt->{'ad'} :<br /><tt>($exmpl)
 </tt></td><td>&nbsp;<span class="LC_nobreak">$cc 
 <input type="text" size="50" name="additionalrec_cc" /></span><br />
 <span class="LC_nobreak">$bcc <input type="text" size="50" name="additionalrec_bcc" /></span></td></tr>
@@ -2065,7 +2096,6 @@ sub displaymessage {
     my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
     my %content=&Apache::lonmsg::unpackagemsg($message{$msgid});
     my $counter=0;
-    $r->print('<pre>');
     my $escmsgid=&escape($msgid);
     foreach (@messages) {
 	if ($_->[5] eq $escmsgid){
@@ -2073,7 +2103,22 @@ sub displaymessage {
 	}
 	$counter++;
     }
-    $r->print('</pre>');
+
+    my $see_anonymous;
+    my $from_student = 0;
+    if ($env{'request.course.id'} eq $content{'courseid'}) {
+	my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+	my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+	my $username = $content{'sendername'}.':'.$content{'senderdomain'};
+	my %classlist_entry =
+	    &Apache::lonnet::get('classlist',[$username],$cdom,$cnum);
+	if (exists($classlist_entry{$username})) {
+	    $from_student = 1;
+	    $see_anonymous = &Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
+	}
+    }
+
+
     my $number_of_messages = scalar(@messages); #subtract 1 for last index
 # start output
     &printheader($r,'/adm/email?display='.&escape($msgid),'Display a Message','',$content{'baseurl'});
@@ -2108,17 +2153,33 @@ sub displaymessage {
         $symb=&Apache::lonnet::symbread($content{'baseurl'});
     }
     if ($env{'user.adv'}) {
-	$r->print('<table border="2" width="100%"><tr bgcolor="#FFAAAA"><td>'.&mt('Currently available actions (will open extra window)').':</td>');
+        my $actionlist='';
 	if (&Apache::lonnet::allowed('vgr',$env{'request.course.id'})) {
-		$r->print('<td><b>'.&Apache::loncommon::track_student_link(&mt('View recent activity'),$content{'sendername'},$content{'senderdomain'},'check').'</b></td>');
-	    }
+		$actionlist.='<td><b>'
+                            .&Apache::loncommon::track_student_link(
+                                 &mt('View recent activity'),$content{'sendername'},$content{'senderdomain'},'check')
+                            .'</b></td>';
+	}
 	if (&Apache::lonnet::allowed('opa',$env{'request.course.id'}) && $symb) {
-	    $r->print('<td><b>'.&Apache::loncommon::pprmlink(&mt('Set/Change parameters'),$content{'sendername'},$content{'senderdomain'},$symb,'check').'</b></td>');
+	    $actionlist.='<td><b>'
+                        .&Apache::loncommon::pprmlink(
+                             &mt('Set/Change parameters'),$content{'sendername'},$content{'senderdomain'},$symb,'check')
+                        .'</b></td>';
 	}
 	if (&Apache::lonnet::allowed('mgr',$env{'request.course.id'}) && $symb) {
-	    $r->print('<td><b>'.&Apache::loncommon::pgrdlink(&mt('Set/Change grades'),$content{'sendername'},$content{'senderdomain'},$symb,'check').'</b></td>');
-	}
-	$r->print('</tr></table>');
+	    $actionlist.='<td><b>'
+                       .&Apache::loncommon::pgrdlink(
+                            &mt('Set/Change grades'),$content{'sendername'},$content{'senderdomain'},$symb,'check')
+                       .'</b></td>';
+	}
+        if ($actionlist) {
+            $r->print('<table border="2" width="100%">'
+                     .'<tr bgcolor="#FFAAAA"><td>'
+                     .&mt('Currently available actions (will open extra window):')
+                     .'</td>'
+                     .$actionlist
+                     .'</tr></table>');
+        }
     }
     my ($tolist,$cclist);
     my (@recipients,@ccs);
@@ -2147,47 +2208,87 @@ sub displaymessage {
     if (defined($content{'baseurl'})) {
         $baseurl = &Apache::lonenc::check_encrypt($content{'baseurl'});
     }
-    $r->print(&Apache::loncommon::student_image_tag($content{'senderdomain'},$content{'sendername'}));
-    $r->print('<br /><b>'.&mt('Subject').':</b> '.$content{'subject'});
+    if ($from_student && $see_anonymous ) {
+	$r->print(&Apache::loncommon::student_image_tag($content{'senderdomain'},$content{'sendername'}));
+    }
+
+    # Display LON-CAPA Message (Start)
+    # Subject
+    $r->print('<br />'
+             .&Apache::lonhtmlcommon::start_pick_box()
+             .&Apache::lonhtmlcommon::row_title(&mt('Subject'))
+             .$content{'subject'}
+             .&Apache::lonhtmlcommon::row_closure()
+    );
     if ($folder eq 'sent') {
-        $r->print('<br /><b>'.&mt('To').':</b> '.$tolist);
+        # To
+        $r->print(&Apache::lonhtmlcommon::row_title(&mt('To'))
+                 .$tolist
+                 .&Apache::lonhtmlcommon::row_closure()
+        );
         if ($content{'replytoaddr'}) {
             my ($replytoname,$replytodom) = split(/:/,$content{'replytoaddr'});
             if ($replytoname ne '' && $replytodom ne '') {
-                $r->print('<br /><b>'.&mt('Reply To').':</b> '.
-                          $replytoname.' '.&mt('at').' '.$replytodom);
+                $r->print(&Apache::lonhtmlcommon::row_title(&mt('Reply To'))
+                         .&mt('[_1] at [_2]',$replytoname,$replytodom)
+                         .&Apache::lonhtmlcommon::row_closure()
+                );
             }
         }
     } else {
-        $r->print('<br /><b>'.&mt('From').':</b> '.
-	      &Apache::loncommon::aboutmewrapper(
-						 &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),
-						 $content{'sendername'},$content{'senderdomain'}));
+        # From, Reply
+        $r->print(&Apache::lonhtmlcommon::row_title(&mt('From'))
+                 .&Apache::loncommon::aboutmewrapper(
+                     &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),
+                                                 $content{'sendername'},$content{'senderdomain'})
+        );
         if ($content{'noreplies'}) {
-            $r->print(' ('.&mt('No replies to sender').')'); 
+            $r->print(' ('.&mt('No replies to sender').')'
+                     .&Apache::lonhtmlcommon::row_closure()
+            ); 
         } else {
             if ($content{'replytoaddr'}) {
                 my ($replytoname,$replytodom) = split(/:/,$content{'replytoaddr'});
                 if ($replytoname ne '' && $replytodom ne '') {
-                    $r->print('<br /><b>'.&mt('Reply To').':</b> '.
-                              $replytoname.' '.&mt('at').' '.$replytodom);
+                    $r->print(&Apache::lonhtmlcommon::row_closure()
+                             .&Apache::lonhtmlcommon::row_title(&mt('Reply To'))
+                             .&mt('[_1] at [_2]',$replytoname,$replytodom)
+                             .&Apache::lonhtmlcommon::row_closure()
+                    );
+                } else {
+                    $r->print(&Apache::lonhtmlcommon::row_closure());
                 }
             } else {
-                $r->print(' ('.$content{'sendername'}.' '&mt('at').' '.
-                          $content{'senderdomain'}.') ');
+                $r->print(' ('.&mt('[_1] at [_2]',$content{'sendername'},$content{'senderdomain'}).') '
+                         .&Apache::lonhtmlcommon::row_closure()
+                );
             }
             if ($cclist) {
-                $r->print('<br /><b>'.&mt('Cc').':</b> '.$cclist);
+                $r->print(&Apache::lonhtmlcommon::row_title(&mt('Cc'))
+                         .$cclist
+                         .&Apache::lonhtmlcommon::row_closure()
+                    );
+
             }
-        } 
+        }
     }
+
+    # Course
     if ($content{'courseid'}) {
-        $r->print('<br /><b>'.&mt($crstype).':</b> '.$courseinfo{'description'});
+        $r->print(&Apache::lonhtmlcommon::row_title(&mt($crstype))
+                 .$courseinfo{'description'}
+        );
         if ($content{'coursesec'}) {
             $r->print(' ('.&mt('Section').': '.$content{'coursesec'}.')');
         }
+        $r->print(&Apache::lonhtmlcommon::row_closure());
     }
-    $r->print('<br /><b>'.&mt('Time').':</b> '.$content{'time'});
+    $r->print(&Apache::lonhtmlcommon::row_title(&mt('Time'))
+             .$content{'time'}
+             .&Apache::lonhtmlcommon::row_closure()
+    );
+
+    # Refers to
     if ($baseurl) {
         if (defined($content{'courseid'}) && defined($env{'request.course.id'})) {
             if ($content{'courseid'} eq $env{'request.course.id'}) {
@@ -2205,7 +2306,10 @@ sub displaymessage {
                 if ($encrypturl =~ /^yes$/i && !$env{'request.role.adv'}) {
                     $showurl = $baseurl;
                 }
-                $r->print('<br /><b>'.&mt('Refers to').':</b> <a href="'.$showurl.$symblink.'">'.$restitle.'</a>');
+                $r->print(&Apache::lonhtmlcommon::row_title(&mt('Refers to'))
+                         .'<a href="'.$showurl.$symblink.'">'.$restitle.'</a>'
+                         .&Apache::lonhtmlcommon::row_closure()
+                );
                 $refers_to = 1;
             }
         }
@@ -2218,25 +2322,41 @@ sub displaymessage {
                                                         $content{'courseid'});
                         if ($unencurl ne '') {
                             if (&Apache::lonnet::allowed('bre',$unencurl)) {
-                                $r->print('<br /><b>'.&mt('Refers to').
-                                          ':</b> <a href="'.$unencurl.'">'.
-                                          $restitle.'</a>');
+                                $r->print(&Apache::lonhtmlcommon::row_title(&mt('Refers to'))
+                                         .'<a href="'.$unencurl.'">'.$restitle.'</a>'
+                                         .&Apache::lonhtmlcommon::row_closure()
+                                );
                             }
                         }
                     }
                 }
             } else {
                 if (&Apache::lonnet::allowed('bre',$baseurl)) {
-                    $r->print('<br /><b>'.&mt('Refers to').
-                              ':</b> <a href="'.$baseurl.
-                              '">'.$restitle.'</a>');
+                    $r->print(&Apache::lonhtmlcommon::row_title(&mt('Refers to'))
+                             .'<a href="'.$baseurl.'">'.$restitle.'</a>'
+                             .&Apache::lonhtmlcommon::row_closure()
+                    );
+
                 }
             }
         }
     }
-    $r->print('<p><pre>'.
-	      &Apache::lontexconvert::msgtexconverted($content{'message'},1).
-	      '</pre><hr />'.&displayresource(%content).'</p>');
+
+    # Message
+    $r->print(&Apache::lonhtmlcommon::row_title(&mt('Message'))
+             .'<pre>'
+	     .&Apache::lontexconvert::msgtexconverted($content{'message'},1)
+	     .'</pre>'
+    );
+    if (&displayresource(%content)) {
+        $r->print(&Apache::lonhtmlcommon::row_closure()
+                 .&Apache::lonhtmlcommon::row_title(&mt('Resource Details'))
+                 .&displayresource(%content)
+        );
+    } 
+    $r->print(&Apache::lonhtmlcommon::row_closure(1).
+              &Apache::lonhtmlcommon::end_pick_box());
+    # Display LON-CAPA Message (End)
     return;
 }
 
@@ -2381,6 +2501,8 @@ sub sendoffmail {
     my %msg_status;
     my $numsent = 0;
     my $nosentstore = 1;
+    my $attachmenturl;
+    my $now = time;
     my ($cdom,$cnum,$group);
     if (exists($env{'form.group'})) {
         $group = $env{'form.group'};
@@ -2403,10 +2525,13 @@ sub sendoffmail {
 	if ($env{'form.forwid'}) {
 	    my $msgid=$env{'form.forwid'};
 	    my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
-	    %content=&Apache::lonmsg::unpackagemsg($message{$msgid},1);
+	    %content=&Apache::lonmsg::unpackagemsg($message{$msgid},1,1);
 	    &statuschange($msgid,'forwarded',$folder);
-	    $env{'form.message'}.="\n\n-- Forwarded message --\n\n".
-		$content{'message'};
+            if ($content{'attachmenturl'} ne '') {
+                $attachmenturl = $content{'attachmenturl'};
+            }
+	    $env{'form.message'} .= "\n\n-- Forwarded message --\n\n".
+		                    $content{'message'};
 	}
 	if ($env{'form.replyid'}) {
 	    my $msgid=$env{'form.replyid'};
@@ -2505,7 +2630,18 @@ sub sendoffmail {
                                        $env{'user.domain'},\%reciphash);
         if ($recipstatus ne 'ok') {
             &Apache::lonnet::logthis('Failed to store Bcc and Cc recipients for '.$env{'user.name'}.':'.$env{'user.domain'});
-        }  
+        }
+        if ($env{'form.attachment'}) {
+            if (length($env{'form.attachment'})<131072) {
+                $attachmenturl=&Apache::lonnet::userfileupload('attachment',undef,'feedback/'.$now);
+            } else {
+                $r->print('<p><span class="LC_warning">'.&mt('Attachment not included - exceeded permitted length').'</span><br /></p>');
+            }
+        } elsif ($env{'form.multiforward'}) {
+            if ($env{'form.attachmenturl'} ne '') {
+                $attachmenturl = $env{'form.attachmenturl'};
+            }
+        }
         my @recusers;
         my @recudoms;
 	foreach my $address (sort(keys(%toaddr))) {
@@ -2531,7 +2667,7 @@ sub sendoffmail {
 		    &Apache::lonmsg::user_normal_msg($recuname,$recdomain,
 						     $msgsubj,$msgtxt,
 						     $content{'citation'},
-						     undef,undef,
+						     undef,$attachmenturl,
 						     $env{'form.permanent'},
 						     \$sentmessage{$address},
                                                      undef,undef,undef,
@@ -2564,7 +2700,7 @@ sub sendoffmail {
                 $specialresult = 
                     &Apache::lonmsg::user_normal_msg_raw($cnum,$cdom,
                         $subj_prefix.' '.$course_str,$savemsg,undef,undef,
-                        undef,undef,undef,\$specialmsgid,undef,undef,undef,
+                        $attachmenturl,undef,undef,\$specialmsgid,undef,undef,undef,
                         undef,undef,1);
                 $specialmsgid = &unescape($specialmsgid);
                 if ($specialresult eq 'ok') {
@@ -2581,7 +2717,7 @@ sub sendoffmail {
 							    $pid);
                             &Apache::lonmsg::user_normal_msg_raw($cnum,$cdom,
                                 $subj_prefix.' ['.$recipient.']',$msgsubj,
-                                undef,undef,undef,undef,$usermsgid,undef,
+                                undef,undef,$attachmenturl,undef,$usermsgid,undef,
                                 undef,$specialmsgid,undef,undef,undef,1);
                         }
                     }
@@ -2589,7 +2725,7 @@ sub sendoffmail {
                         &Apache::lonmsg::process_sent_mail($msgsubj,
                            $subj_prefix,$numsent,$stamp,$msgname,$msgdom,
                            $msgcount,$context,$pid,$savemsg,\@recusers,
-                           \@recudoms);
+                           \@recudoms,undef,$attachmenturl);
                     }
                 } else {
                     &Apache::lonnet::logthis('Failed to create record of critical, broadcast or archived message in '.$env{'course.'.$env{'request.course.id'}.'.num'}.' '&mt('at').' '.$env{'course.'.$env{'request.course.id'}.'.domain'}.' - no msgid generated');
@@ -2601,7 +2737,7 @@ sub sendoffmail {
                 &Apache::lonmsg::process_sent_mail($msgsubj,$subj_prefix,
                        $numsent,$stamp,$env{'user.name'},
                        $env{'user.domain'},$msgcount,$context,
-                       $$,$savemsg,\@recusers,\@recudoms);
+                       $$,$savemsg,\@recusers,\@recudoms,undef,$attachmenturl);
             }
         }
         if (!$env{'form.multiforward'}) { 
@@ -2618,7 +2754,7 @@ sub sendoffmail {
 	        }
             } else {
 	        $r->print('<p><span class="LC_error">'.&mt('Could not deliver message').'</span> '.
-		          &mt('Please use the browser "Back" button and correct the recipient addresses '."($sendstatus)").'</p>');
+		          &mt('Please use the browser "Back" button and correct the recipient addresses ([_1]).',$sendstatus).'</p>');
             }
         }
     }
@@ -2853,7 +2989,7 @@ sub handler {
             foreach my $item (@to_forward) {
                 my $msgid=&unescape($item);
                 my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
-                my %content=&Apache::lonmsg::unpackagemsg($message{$msgid},1);
+                my %content=&Apache::lonmsg::unpackagemsg($message{$msgid},1,1);
                 if ($env{'form.showorigsubj'}) {
                     $env{'form.subject'} = $fixed_subj.$content{'subject'};
                 } else {
@@ -2867,8 +3003,10 @@ sub handler {
                         &Apache::loncommon::plainname($uname,$udom).' ('.
                                            $uname.':'.$udom.')';
                 }
-                $env{'form.message'} .= "\n\n-- Forwarded message --\n\n".
-                                        $content{'message'};
+                $env{'form.message'}.="\n\n-- Forwarded message --\n\n".
+                                      $content{'message'};
+                $env{'form.attachmenturl'} = $content{'attachmenturl'};
+                $env{'form.multiforwid'} = $item;
                 $fwdcount ++;
                 $r->print($fwdcount.': '); 
                 $sendresult{$msgid} = &sendoffmail($r,$folder);