![]() ![]() | ![]() |
- one of these days I'll take my own advice
1: # The LearningOnline Network 2: # Announce 3: # 4: # $Id: lonannounce.pm,v 1.57 2006/06/29 16:44:49 albertel Exp $ 5: # 6: # Copyright Michigan State University Board of Trustees 7: # 8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA). 9: # 10: # LON-CAPA is free software; you can redistribute it and/or modify 11: # it under the terms of the GNU General Public License as published by 12: # the Free Software Foundation; either version 2 of the License, or 13: # (at your option) any later version. 14: # 15: # LON-CAPA is distributed in the hope that it will be useful, 16: # but WITHOUT ANY WARRANTY; without even the implied warranty of 17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18: # GNU General Public License for more details. 19: # 20: # You should have received a copy of the GNU General Public License 21: # along with LON-CAPA; if not, write to the Free Software 22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23: # 24: # /home/httpd/html/adm/gpl.txt 25: # 26: # http://www.lon-capa.org/ 27: # 28: 29: package Apache::lonannounce; 30: 31: use strict; 32: use Apache::Constants qw(:common); 33: use Apache::loncommon; 34: use Apache::lonhtmlcommon(); 35: use Apache::lonlocal; 36: use Apache::lonnavmaps(); 37: use Apache::lonrss(); 38: use Apache::lonnet; 39: use HTML::Entities(); 40: 41: my %todayhash; 42: my %showedcheck; 43: 44: sub editfield { 45: my ($r,$start,$end,$text)=@_; 46: # Deal with date forms 47: my $startdateform = &Apache::lonhtmlcommon::date_setter('anno', 48: 'startdate', 49: $start); 50: my $enddateform = &Apache::lonhtmlcommon::date_setter('anno', 51: 'enddate', 52: $end); 53: my $help=&Apache::loncommon::help_open_menu('Calendar Add Announcement','Calendar_Add_Announcement',274,'Communication Tools'); 54: my %lt=&Apache::lonlocal::texthash('post' => 'Post Announcement', 55: 'start' => 'Starting date', 56: 'end' => 'Ending date', 57: 'incrss' => 'Include in course RSS newsfeed'); 58: 59: $r->print(<<ENDFORM); 60: $help 61: <form name="anno" method="post"> 62: <input type="hidden" value='' name="action" /> 63: <table><tr><td>$lt{'start'}:</td><td>$startdateform</td></tr> 64: <tr><td>$lt{'end'}:</td><td>$enddateform</td></tr></table> 65: <textarea name="msg" rows="4" cols="60">$text</textarea> 66: <br /> 67: <label><input type="checkbox" name="rsspost" /> $lt{'incrss'}</label> 68: <br /><input type="button" onClick="trysubmit()" value="$lt{'post'}" /><hr /> 69: ENDFORM 70: } 71: 72: sub readcalendar { 73: my $courseid=shift; 74: my $coursenum=$env{'course.'.$courseid.'.num'}; 75: my $coursedom=$env{'course.'.$courseid.'.domain'}; 76: my %thiscal=&Apache::lonnet::dump('calendar',$coursedom,$coursenum); 77: my %returnhash=(); 78: foreach my $item (keys(%thiscal)) { 79: unless (($item=~/^error\:/) || ($thiscal{$item}=~/^error\:/)) { 80: $returnhash{$courseid.'@'.$item}=$thiscal{$item}; 81: } 82: } 83: 84: my $can_see_hidden = $env{'request.role.adv'}; 85: my $navmap;# = Apache::lonnavmaps::navmap->new(); 86: my %resourcedata= 87: &Apache::lonnet::dump('resourcedata',$coursedom,$coursenum); 88: foreach my $thiskey (sort keys %resourcedata) { 89: if ($resourcedata{$thiskey.'.type'}=~/^date/) { 90: my ($course,$middle,$part,$name)= 91: ($thiskey=~/^(\w+)\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/); 92: my %data = ( 'section' => &mt('All Students')); 93: if ($middle=~/^\[(.*)\]\./) { 94: my $sec=$1; 95: # if we have a section don't show ones that aren't ours 96: if ($env{'request.course.sec'} && 97: $env{'request.course.sec'} ne $sec) { next; } 98: # if a student without a section don't show any section ones 99: if (!$env{'request.role.adv'} && 100: !$env{'request.course.sec'}) { next; } 101: $data{'section'}=&mt('Group/Section').': '.$1; 102: $middle=~s/^\[(.*)\]\.//; 103: } 104: $middle=~s/\.$//; 105: $data{'realm'}=&mt('All Resources'); 106: if ($middle eq '___(all)') { 107: if (!$can_see_hidden && !$navmap) { 108: next; 109: } 110: } elsif ($middle=~/^(.+)\_\_\_\(all\)$/) { 111: my $map_url=$1; 112: if (!$can_see_hidden && !$navmap) { 113: next; 114: } 115: if (!$can_see_hidden) { 116: my $res = $navmap->getResourceByUrl($map_url); 117: if ($res && $res->randomout()) { next; } 118: } 119: $data{'realm'}=&mt('Folder/Map'); 120: $data{'url'} = $map_url; 121: } elsif ($middle) { 122: if (!$can_see_hidden && !$navmap) { 123: next; 124: } 125: if (!$can_see_hidden) { 126: my $res = $navmap->getBySymb($middle); 127: if ($res && $res->randomout()) { next; } 128: } 129: $data{'realm'} = &mt('Resource'); 130: $data{'symb'} = $middle; 131: } 132: $data{'datetype'} = $name; 133: if ($name eq 'duedate') { 134: $data{'datetype'} = &mt('Due'); 135: # see if accidentally answerdate is before duedate 136: my $answerkey=$thiskey; 137: $answerkey=~s/duedate$/answerdate/; 138: if ($resourcedata{$thiskey}>$resourcedata{$answerkey}) { 139: $data{'datetype'} = &mt('Due and Answer Available'); 140: } 141: } 142: if ($name eq 'opendate' 143: || $name eq 'contentopen' ) { 144: $data{'datetype'}=&mt('Opening'); 145: } 146: if ($name eq 'contentclose') { 147: $data{'datetype'}=&mt('Closing'); 148: } 149: if ($name eq 'answerdate') { 150: # see if accidentally answerdate is before duedate 151: my $duekey=$thiskey; 152: $duekey=~s/answerdate$/duedate/; 153: if ($resourcedata{$duekey}>$resourcedata{$thiskey}) { 154: # forget it 155: next; 156: } 157: $data{'datetype'}=&mt('Answer Available'); 158: } 159: $returnhash{$courseid.'@'.$resourcedata{$thiskey}.'_'. 160: $resourcedata{$thiskey}}=\%data; 161: } 162: } 163: return %returnhash; 164: } 165: 166: sub emptycell { 167: return '<td class="LC_calendar_day_empty"> </td>'; 168: } 169: 170: sub normalcell { 171: my ($day,$month,$year,$items_ref)=@_; 172: my $output; 173: my @items=&order($items_ref); 174: foreach my $item (@items) { 175: if ($item) { 176: my ($courseid,$start,$end,$msg)=@$item; 177: my $internalflag= (ref($msg)) ? 1 : 0; 178: $msg = &display_msg($msg); 179: my $fullmsg=&mt('Calendar Announcement for ').$env{'course.'.$courseid.'.description'}. 180: '\n'.&Apache::lonlocal::locallocaltime($start); 181: if ($start!=$end) { 182: $fullmsg.=' - '.&Apache::lonlocal::locallocaltime($end); 183: } 184: $fullmsg.=':\n'.$msg; 185: $fullmsg=~s/[\n\r]/\\n/gs; 186: $fullmsg=&HTML::Entities::encode($fullmsg,'<>&"\''); 187: $fullmsg=~s/&/\\&/g; 188: my $short_msg = substr($msg,0,20).((length($msg) > 20)?'...':''); 189: if (defined($output)) { $output.='<br />'; } 190: if ($courseid eq $env{'request.course.id'}) { 191: if ((&Apache::lonnet::allowed('srm',$env{'request.course.id'})) 192: && (!$showedcheck{$start.'_'.$end}) 193: && ($env{'form.pickdate'} ne 'yes') 194: && (!$internalflag)) { 195: $output.='<input type="checkbox" name="remove_'.$start.'_'. 196: $end.'">'; 197: $showedcheck{$start.'_'.$end}=1; 198: } 199: } 200: $output.='<a href="javascript:alert('."'$fullmsg'".')">'. 201: $short_msg.'</a>'; 202: } 203: } 204: return '<td class="LC_calendar_day'. 205: ((($day eq $todayhash{'day'}) && 206: ($month eq $todayhash{'month'}) && 207: ($year eq $todayhash{'year'}))?'_current':''). 208: '" ><b>'.&picklink($day,$day,$month,$year).'</b><br />'.$output.'</td>'; 209: } 210: 211: sub plaincell { 212: my ($items_ref)=@_; 213: my $output; 214: my @items=&order($items_ref); 215: foreach my $item (@items) { 216: if (ref($item)) { 217: my ($courseid,$start,$end,$msg)=@$item; 218: my $fullmsg=&mt('Calendar Announcement for ').$env{'course.'.$courseid.'.description'}. 219: '\n'.&Apache::lonlocal::locallocaltime($start); 220: if ($start!=$end) { 221: $fullmsg.=' - '.&Apache::lonlocal::locallocaltime($end); 222: } 223: $msg = &display_msg($msg); 224: $fullmsg.=':\n'.$msg; 225: $fullmsg=~s/[\n\r]/\\n/gs; 226: $fullmsg=&HTML::Entities::encode($fullmsg,'<>&"\''); 227: $fullmsg=~s/&/\\&/g; 228: my $short_msg = substr($msg,0,80).((length($msg) > 80)?'...':''); 229: if (defined($output)) { $output.='<br />'; } 230: $output.='<a href="javascript:alert('."'$fullmsg'".')">'. 231: $short_msg.'</a>'; 232: } 233: } 234: return $output; 235: } 236: 237: sub listcell { 238: my ($items_ref)=@_; 239: my $output=''; 240: my @items=&order($items_ref); 241: foreach my $item (@items) { 242: if (ref($item)) { 243: my ($courseid,$start,$end,$msg)=@$item; 244: my $fullmsg=&Apache::lonlocal::locallocaltime($start); 245: if ($start!=$end) { 246: $fullmsg.=&mt(' to '). 247: &Apache::lonlocal::locallocaltime($end); 248: } 249: $fullmsg.=':<br /><b>'.&display_msg($msg).'</b>'; 250: $output.='<li>'.$fullmsg.'</li>'; 251: } 252: } 253: return $output; 254: } 255: 256: sub order { 257: my ($items)=@_; 258: return sort { 259: my ($astart,$aend)=$a->[1,2]; 260: my ($bstart,$bend)=$b->[1,2]; 261: if ($astart != $bstart) { 262: return $astart <=> $bstart; 263: } 264: return $aend <=> $bend; 265: } @$items; 266: } 267: 268: sub nextday { 269: my %th=@_; 270: $th{'day'}++; 271: return (&Apache::loncommon::maketime(%th),$th{'month'}); 272: } 273: 274: sub display_msg { 275: my ($msg) = @_; 276: 277: # if it's not a ref, it's an instructor provided message 278: return $msg if (!ref($msg)); 279: 280: my $output = $msg->{'datetype'}. ': '.$msg->{'realm'}; 281: if (exists($msg->{'url'})) { 282: $output .= ': '.&Apache::lonnet::gettitle($msg->{'url'}); 283: } 284: if (exists($msg->{'symb'})) { 285: $output .= ': '.&Apache::lonnet::gettitle($msg->{'symb'}); 286: } 287: $output .= ' ('.$msg->{'section'}.') '; 288: return $output; 289: } 290: 291: sub showday { 292: my ($tk,$mode,%allcal)=@_; 293: my %th=&Apache::loncommon::timehash($tk); 294: my ($nextday,$nextmonth)=&nextday(%th); 295: my @outp; 296: if ($mode) { 297: my $oneday=24*3600; 298: $tk-=$oneday; 299: $nextday+=$oneday; 300: } 301: foreach my $item (keys(%allcal)) { 302: my ($course,$startdate,$enddate)=($item=~/^(\w+)\@(\d+)\_(\d+)$/); 303: if (($startdate<$nextday) && ($enddate>=$tk)) { 304: push(@outp,[$course,$startdate,$enddate,$allcal{$item}]); 305: } 306: } 307: unless ($mode) { 308: return ($nextday,$nextmonth,&normalcell( 309: $th{'day'},$th{'month'},$th{'year'},\@outp)); 310: } elsif (@outp) { 311: if ($mode==1) { 312: return '<br />'.&plaincell(\@outp); 313: } else { 314: return '<ul>'.&listcell(\@outp).'</ul>'; 315: } 316: } else { 317: return ''; 318: } 319: } 320: 321: sub picklink { 322: my ($text,$day,$month,$year)=@_; 323: if ($env{'form.pickdate'} eq 'yes') { 324: return '<a href="javascript:dialin('.$day.','.$month.','.$year.')">'. 325: $text.'</a>'; 326: } else { 327: return $text; 328: } 329: } 330: 331: sub dialscript { 332: return (<<ENDDIA); 333: <script language="Javascript"> 334: function dialin(day,month,year) { 335: opener.document.$env{'form.formname'}.$env{'form.element'}\_year.value=year; 336: var slct=opener.document.$env{'form.formname'}.$env{'form.element'}\_month; 337: var i; 338: for (i=0;i<slct.length;i++) { 339: if (slct.options[i].value==month) { slct.selectedIndex=i; } 340: } 341: opener.document.$env{'form.formname'}.$env{'form.element'}\_day.value=day; 342: opener.$env{'form.element'}\_checkday(); 343: self.close(); 344: } 345: </script> 346: ENDDIA 347: } 348: # ----------------------------------------------------- Summarize all calendars 349: sub get_all_calendars { 350: my %allcal=(); 351: foreach my $course (sort(&Apache::loncommon::findallcourses())) { 352: %allcal=(%allcal,&readcalendar($course)); 353: } 354: return %allcal; 355: } 356: 357: sub output_ics_file { 358: my ($r)=@_; 359: # RFC 2445 wants CRLF 360: my $crlf="\015\012"; 361: # Header 362: $r->print("BEGIN:VCALENDAR$crlf"); 363: $r->print("VERSION:2.0$crlf"); 364: $r->print("PRODID:-//LONCAPA//LONCAPA Calendar Output//EN$crlf"); 365: my %allcal=&get_all_calendars(); 366: foreach my $event (keys(%allcal)) { 367: my ($courseid,$startdate,$enddate)=($event=~/^(\w+)\@(\d+)\_(\d+)$/); 368: my $uid=$event; 369: $uid=~s/[\W\_]/-/gs; 370: $uid.='@loncapa'; 371: my $summary=&display_msg($allcal{$event}); 372: $summary=~s/\s+/ /gs; 373: $summary=$env{'course.'.$courseid.'.description'}.': '.$summary; 374: $r->print("BEGIN:VEVENT$crlf"); 375: $r->print("DTSTART:".&Apache::loncommon::utc_string($startdate).$crlf); 376: $r->print("DTEND:".&Apache::loncommon::utc_string($enddate).$crlf); 377: $r->print("SUMMARY:$summary$crlf"); 378: $r->print("UID:$uid$crlf"); 379: $r->print("END:VEVENT$crlf"); 380: } 381: # Footer 382: $r->print("END:VCALENDAR$crlf"); 383: } 384: 385: sub handler { 386: my $r = shift; 387: if ($r->uri=~/\.(ics|ical)$/) { 388: &Apache::loncommon::content_type($r,'text/calendar'); 389: &output_ics_file($r); 390: return OK; 391: } 392: &Apache::loncommon::content_type($r,'text/html'); 393: $r->send_http_header; 394: return OK if $r->header_only; 395: 396: # ---------------------------------------------------------- Get time right now 397: my $today=time; 398: %todayhash=&Apache::loncommon::timehash($today); 399: # ----------------------------------------------------------------- Check marks 400: undef(%showedcheck); 401: # ---------------------------------------------------------- Get month and year 402: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, 403: ['month','year','pickdate','formname','element']); 404: # --------------------------------------------------- Decide what month to show 405: my $year=$todayhash{'year'}; 406: if ($env{'form.year'}) { $year=$env{'form.year'}; } 407: my $month=$todayhash{'month'}; 408: if ($env{'form.month'}) { $month=$env{'form.month'}; } 409: 410: # ---------------------------------------------- See if we are in pickdate mode 411: my $pickdatemode=($env{'form.pickdate'} eq 'yes'); 412: my $pickinfo='&pickdate=yes&formname='.$env{'form.formname'}. 413: '&element='.$env{'form.element'}; 414: # --------------------------------------------- Find out first day of the month 415: 416: my %firstday=&Apache::loncommon::timehash( 417: &Apache::loncommon::maketime( 'day' => 1, 'month'=> $month, 418: 'year' => $year, 'hours' => 0, 419: 'minutes' => 0, 'seconds' => 0, 420: 'dlsav' => -1 )); 421: my $weekday=$firstday{'weekday'}; 422: # ------------------------------------------------------------ Print the screen 423: my $js = <<ENDDOCUMENT; 424: <script type="text/javascript"> 425: 426: function trysubmit() { 427: document.anno.action.value="new"; 428: document.anno.submit(); 429: } 430: 431: function removesub() { 432: document.anno.action.value="del"; 433: document.anno.submit(); 434: } 435: </script> 436: ENDDOCUMENT 437: 438: if ($pickdatemode) { 439: # no big header in pickdate mode 440: $r->print(&Apache::loncommon::start_page("Pick a Date",$js, 441: {'only_body' => 1,}). 442: &dialscript(). 443: '<font size="1">'); 444: } else { 445: $r->print(&Apache::loncommon::start_page("Announcements and Calendar", 446: $js)); 447: } 448: # does this user have privileges to post, etc? 449: my $allowed=0; 450: if ($env{'request.course.id'}) { 451: $allowed=&Apache::lonnet::allowed('srm',$env{'request.course.id'}); 452: } 453: # does this user have privileges to post to servers? 454: my $serverpost=0; 455: if ($env{'request.role.domain'}) { 456: $serverpost=&Apache::lonnet::allowed('psa', 457: $env{'request.role.domain'}); 458: } else { 459: $serverpost=&Apache::lonnet::allowed('psa','/'); 460: } 461: # -------------------------------- BUT: do no fancy stuff when in pickdate mode 462: if ($pickdatemode) { 463: $serverpost=0; 464: $allowed=0; 465: } 466: # ------------------------------------------------------------ Process commands 467: if ($serverpost) { 468: if ($env{'form.serveraction'}) { 469: foreach my $key (keys(%env)) { 470: if ($key=~/^form\.postto\_(\w+)/) { 471: $r->print( 472: '<br />Posting '.$1.': '.&Apache::lonnet::postannounce 473: ($1,$env{'form.serverannnounce'})); 474: } 475: } 476: } 477: $r->print(<<SERVERANNOUNCE); 478: <form name="serveranno" method="post"> 479: <h3>Post Server Announcements</h3> 480: Post announcements to the system login and roles screen<br /> 481: <i>(leave blank to delete announcement)</i><br /> 482: <textarea name="serverannnounce" cols="60" rows="5"></textarea><br /> 483: Check machines:<br /> 484: SERVERANNOUNCE 485: # list servers 486: foreach my $host (sort(keys(%Apache::lonnet::hostname))) { 487: if (&Apache::lonnet::allowed('psa',$Apache::lonnet::hostdom{$host})) { 488: $r->print ('<br /><input type="checkbox" name="postto_'.$host.'" /> '. 489: $host.' <tt>'.$Apache::lonnet::hostname{$host}.'</tt> '. 490: '<a href="http://'.$Apache::lonnet::hostname{$host}. 491: '/announcement.txt" target="annowin">current</a>'); 492: } 493: } 494: $r->print( 495: '<br /><input type="submit" name="serveraction" value="Post"></form><hr />'); 496: } 497: if ($allowed) { 498: my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'}; 499: my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'}; 500: # ----------------------------------------------------- Store new submitted one 501: if ($env{'form.action'} eq 'new') { 502: my $startdate = 503: &Apache::lonhtmlcommon::get_date_from_form('startdate'); 504: my $enddate = 505: &Apache::lonhtmlcommon::get_date_from_form('enddate'); 506: unless ($startdate=~/^\d+$/) { $startdate=time; } 507: unless ($enddate=~/^\d+$/) { $enddate=$startdate+1; } 508: if ($startdate>$enddate) { 509: my $buffer=$startdate; 510: $startdate=$enddate; 511: $enddate=$buffer; 512: } 513: &Apache::lonnet::put('calendar',{ 514: $startdate.'_'.$enddate => 515: $env{'form.msg'} },$coursedom,$coursenum); 516: if ($env{'form.rsspost'}) { 517: &Apache::lonrss::addentry($coursenum,$coursedom,'Course_Announcements', 518: &mt('Event from [_1] to [_2]', 519: &Apache::lonlocal::locallocaltime($startdate), 520: &Apache::lonlocal::locallocaltime($enddate)), 521: $env{'form.msg'},'/adm/announcements','public'); 522: } 523: } 524: # ---------------------------------------------------------------- Remove items 525: if ($env{'form.action'} eq 'del') { 526: my @delwhich=(); 527: foreach my $key (keys(%env)) { 528: if ($key=~/^form\.remove\_(.+)$/) { 529: push(@delwhich,$1); 530: } 531: } 532: &Apache::lonnet::del('calendar',\@delwhich,$coursedom,$coursenum); 533: } 534: # -------------------------------------------------------- Form to post new one 535: my %tomorrowhash=%todayhash; 536: $tomorrowhash{'day'}++; 537: my $tomorrow=&Apache::loncommon::maketime(%tomorrowhash); 538: 539: &editfield($r,$today,$tomorrow,''); 540: } 541: # ----------------------------------------------------- Summarize all calendars 542: my %allcal=&get_all_calendars(); 543: # ------------------------------- Initialize table and forward backward buttons 544: my ($pm,$py,$fm,$fy)=($month-1,$year,$month+1,$year); 545: if ($pm<1) { ($pm,$py)=(12,$year-1); } 546: if ($fm>12){ ($fm,$fy)=(1,$year+1); } 547: 548: $r->print('<h1>'.('',&mt('January'),&mt('February'),&mt('March'), 549: &mt('April'),&mt('May'), 550: &mt('June'),&mt('July'),&mt('August'), 551: &mt('September'),&mt('October'), 552: &mt('November'),&mt('December'))[$month].' '. 553: $year.'</h1>'); 554: # Reached the end of times, give up 555: if (($year<1970) || ($year>2037)) { 556: $r->print('<h3>No calendar available for this date.</h3>'. 557: '<a href="/adm/announcements?month='.$todayhash{'month'}. 558: '&year='.$todayhash{'year'}.'">Current Month</a>'. 559: &Apache::loncommon::end_page()); 560: return OK; 561: } 562: 563: my $class = "LC_calendar"; 564: if ($env{'form.pickdate'} eq 'yes') { 565: $class .= " LC_calendar_pickdate"; 566: } 567: $r->print( 568: '<a href="/adm/announcements?month='.$pm.'&year='.$py. 569: ($pickdatemode?$pickinfo:'').'">'.&mt('Previous Month').'</a> '. 570: '<a href="/adm/announcements?month='.$fm.'&year='.$fy. 571: ($pickdatemode?$pickinfo:'').'">'.&mt('Next Month').'</a>'. 572: ' <a href="/adm/announcements?month='.$todayhash{'month'}. 573: '&year='.$todayhash{'year'}. 574: ($pickdatemode?$pickinfo:'').'">'.&mt('Current Month').'</a><p>'. 575: '<table class="'.$class.'" cols="7" rows="5"><tr> 576: <th>'.&mt('Sun').'</th> 577: <th>'.&mt('Mon').'</th> 578: <th>'.&mt('Tue').'</th> 579: <th>'.&mt('Wed').'</th> 580: <th>'.&mt('Thu').'</th> 581: <th>'.&mt('Fri').'</th> 582: <th>'.&mt('Sat').'</th></tr>'); 583: 584: my $tk=&Apache::loncommon::maketime(%firstday); 585: my $outp; 586: my $nm; 587: 588: # ---------------------------------------------------------------- Actual table 589: $r->print('<tr>'); 590: for (my $i=0;$i<$weekday;$i++) { $r->print(&emptycell); } 591: for (my $i=$weekday;$i<=6;$i++) { 592: ($tk,$nm,$outp)=&showday($tk,0,%allcal); 593: $r->print($outp); 594: } 595: $r->print('</tr>'); 596: 597: for (my $k=0;$k<=4;$k++) { 598: $r->print('<tr>'); 599: for (my $i=0;$i<=6;$i++) { 600: ($tk,$nm,$outp)=&showday($tk,0,%allcal); 601: if ($month!=$nm) { $outp=&emptycell; } 602: $r->print($outp); 603: } 604: $r->print('</tr>'); 605: } 606: # ------------------------------------------------------------------- End table 607: $r->print('</table>'); 608: # ----------------------------------------------------------------- Check marks 609: undef(%showedcheck); 610: # --------------------------------------------------------------- Remove button 611: if ($allowed) { $r->print('<input type="button" onClick="removesub()" value="Remove Checked Entries">'. 612: &Apache::loncommon::help_open_topic('Calendar_Remove_Announcement').'</form>'); } 613: $r->print('<p>'. 614: '<a href="/adm/announcements?month='.$pm.'&year='.$py. 615: ($pickdatemode?$pickinfo:'').'">'.&mt('Previous Month').'</a> '. 616: '<a href="/adm/announcements?month='.$fm.'&year='.$fy. 617: ($pickdatemode?$pickinfo:'').'">'.&mt('Next Month').'</a>'. 618: ' <a href="/adm/announcements?month='.$todayhash{'month'}. 619: '&year='.$todayhash{'year'}. 620: ($pickdatemode?$pickinfo:'').'">'.&mt('Current Month').'</a></p>'. 621: ($pickdatemode?'</font>':'').&Apache::loncommon::end_page()); 622: $r->print('<a href="/adm/announcements.ics">'.&mt('Download your Calendar as iCalendar File').'</a>'); 623: return OK; 624: } 625: 626: 1; 627: __END__