File:
[LON-CAPA] /
loncom /
interface /
lonmenu.pm
Revision
1.131:
download - view:
text,
annotated -
select for diffs
Tue Nov 30 19:08:18 2004 UTC (19 years, 7 months ago) by
raeburn
Branches:
MAIN
CVS tags:
HEAD
Fix bugs #3640, 3631, 3630, 3628. Menu buttons eliminated when viewing directories in iCSTR in remoteless mode. Directory position and selection now directly below top menu bar. Directory location larger font, headings for directory options (remoteless only) smaller font. Certain directory actions directed to top, (to escape frame), to avoid nesting frames.
1: # The LearningOnline Network with CAPA
2: # Routines to control the menu
3: #
4: # $Id: lonmenu.pm,v 1.131 2004/11/30 19:08:18 raeburn 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: # There are two parameters controlling the action of this module:
30: #
31: # browser.interface - if this is 'textual', it overrides the second parameter
32: # and goes to screen reader PDA mode
33: #
34: # environment.remote - if this is 'on', the routines controll the remote
35: # control, otherwise they render the main window controls; ignored it
36: # browser.interface is 'textual'
37: #
38:
39: package Apache::lonmenu;
40:
41: use strict;
42: use Apache::lonnet();
43: use Apache::Constants qw(:common);
44: use Apache::lonhtmlcommon();
45: use Apache::loncommon();
46: use Apache::lonenc();
47: use Apache::lonlocal;
48:
49: use vars qw(@desklines $readdesk);
50:
51:
52: my @inlineremote;
53: my $font;
54: my $tabbg;
55: my $pgbg;
56:
57: # ================================================================ Little texts
58:
59: sub initlittle {
60: return &Apache::lonlocal::texthash('ret' => 'Return to Last Location',
61: 'nav' => 'Navigate Contents',
62: 'main' => 'Main Menu',
63: 'launch' => 'Launch Remote Control');
64: }
65:
66: # ============================= This gets called at the top of the body section
67:
68: sub menubuttons {
69: my $forcereg=shift;
70: my $target =shift;
71: my $registration=shift;
72: my $titletable=shift;
73: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
74: ['inhibitmenu']);
75: if ($ENV{'form.inhibitmenu'} eq 'yes') { return ''; }
76:
77: my $navmaps='';
78: my $reloadlink='';
79: my $escurl=&Apache::lonnet::escape(&Apache::lonenc::check_encrypt($ENV{'request.noversionuri'}));
80: my $escsymb=&Apache::lonnet::escape(&Apache::lonenc::check_encrypt($ENV{'request.symb'}));
81: if ($ENV{'browser.interface'} eq 'textual') {
82: # Textual display only
83: my %lt=&initlittle();
84: $pgbg='#FFFFFF';
85: $tabbg='#FFFFFF';
86: $font='#000000';
87: if ($ENV{'request.course.id'}) {
88: $navmaps=(<<ENDNAV);
89: <a href="/adm/navmaps?postdata=$escurl&postsymb=$escsymb" target="_top">$lt{'nav'}</a>
90: ENDNAV
91: if (($ENV{'request.noversionuri'}=~/^\/adm\//) &&
92: ($ENV{'request.noversionuri'}!~/^\/adm\/wrapper\//) &&
93: ($ENV{'request.noversionuri'}!~/^\/adm\/.*\/(smppg|bulletinboard|aboutme)(\?|$)/)) {
94: my $escreload=&Apache::lonnet::escape('return:');
95: $reloadlink=(<<ENDRELOAD);
96: <a href="/adm/flip?postdata=$escreload" target="_top"><font color="$font">$lt{'ret'}</font></a>
97: ENDRELOAD
98: }
99: }
100: my $form=&serverform();
101: my $utility=&utilityfunctions();
102: my $output=(<<ENDMAINMENU);
103: <script type="text/javascript">
104: // BEGIN LON-CAPA Internal
105: $utility
106: </script>
107: <a href="/adm/menu" target="_top">$lt{'main'}</a>
108: $reloadlink $navmaps<br />
109: <script type="text/javascript">
110: // END LON-CAPA Internal
111: </script>
112: $form
113: ENDMAINMENU
114: if ($registration) { $output.=&innerregister($forcereg,$target); }
115: return $output."<hr />";
116: } elsif ($ENV{'environment.remote'} eq 'off') {
117: # Remote Control is switched off
118: # figure out colors
119: my %lt=&initlittle();
120: my $function='student';
121: if ($ENV{'request.role'}=~/^(cc|in|ta|ep)/) {
122: $function='coordinator';
123: }
124: if ($ENV{'request.role'}=~/^(su|dc|ad|li)/) {
125: $function='admin';
126: }
127: if (($ENV{'request.role'}=~/^(au|ca)/) ||
128: ($ENV{'request.noversionuri'}=~/^(\/priv|\~)/)) {
129: $function='author';
130: }
131: my $domain=&Apache::loncommon::determinedomain();
132: $pgbg=&Apache::loncommon::designparm($function.'.pgbg',$domain);
133: $tabbg=&Apache::loncommon::designparm($function.'.tabbg',$domain);
134: $font=&Apache::loncommon::designparm($function.'.font',$domain);
135: my $link=&Apache::loncommon::designparm($function.'.link',$domain);
136: my $alink=&Apache::loncommon::designparm($function.'.alink',$domain);
137: my $vlink=&Apache::loncommon::designparm($function.'.vlink',$domain);
138: my $sidebg=&Apache::loncommon::designparm($function.'.sidebg',$domain);
139: # Do we have a NAV link?
140: if ($ENV{'request.course.id'}) {
141: $navmaps=(<<ENDNAV);
142: <td bgcolor="$tabbg">
143: <a href="javascript:gonav('/adm/navmaps?postdata=$escurl&postsymb=$escsymb')"><font color="$font">$lt{'nav'}</font></a></td>
144: ENDNAV
145: if (($ENV{'request.noversionuri'}=~/^\/adm\//) &&
146: ($ENV{'request.noversionuri'}!~/^\/adm\/wrapper\//) &&
147: ($ENV{'request.noversionuri'}!~/^\/adm\/.*\/(smppg|bulletinboard|aboutme)(\?|$)/)) {
148: my $escreload=&Apache::lonnet::escape('return:');
149: $reloadlink=(<<ENDRELOAD);
150: <td bgcolor="$tabbg">
151: <a href="/adm/flip?postdata=$escreload" target="_top"><font color="$font">$lt{'ret'}</font></a></td>
152: ENDRELOAD
153: }
154: }
155: my $reg='';
156: if ($registration) {
157: $reg=&innerregister($forcereg,$target,$titletable);
158: }
159: my $form=&serverform();
160: my $utility=&utilityfunctions();
161: return (<<ENDINLINEMENU);
162: <script type="text/javascript">
163: // BEGIN LON-CAPA Internal
164: $utility
165: </script>
166: <font face="Arial,Helvetica,sans-serif"><table bgcolor="$pgbg" width="100%" border="0" cellpadding="1" cellspacing="1">
167: <tr>
168: <td bgcolor="$tabbg">
169: <a href="/adm/menu" target="_top"><font color="$font">$lt{'main'}</font></a>
170: </td>
171: $reloadlink
172: $navmaps
173: <td bgcolor="$tabbg">
174: <a href="/adm/remote?action=launch&url=$escurl" target="_top">
175: <font color="$font">$lt{'launch'}</font></a></td>
176: <td bgcolor="$tabbg">
177: <img align="right" src="/adm/lonIcons/minilogo.gif" />
178: <b>LON-CAPA</b></td>
179: $form
180: </tr>
181: </table>
182: </font>
183: <script type="text/javascript">
184: // END LON-CAPA Internal
185: </script>
186: $reg
187: ENDINLINEMENU
188: } else {
189: return '';
190: }
191: }
192:
193: # ====================================== This gets called in the header section
194:
195: sub registerurl {
196: my $forcereg=shift;
197: my $target = shift;
198: my $result = '';
199: if ($ENV{'request.noversionuri'} eq '/res/adm/pages/menu.html') { return ''; }
200: my $force_title='';
201: if ($ENV{'request.state'} eq 'construct') {
202: $force_title=&Apache::lonxml::display_title();
203: }
204: if ($target eq 'edit') {
205: $result .="<script type=\"text/javascript\">\n".
206: "if (typeof swmenu != 'undefined') {swmenu.currentURL=null;}\n".
207: &Apache::loncommon::browser_and_searcher_javascript().
208: "\n</script>\n";
209: }
210: if (($ENV{'browser.interface'} eq 'textual') ||
211: ($ENV{'environment.remote'} eq 'off') ||
212: ((($ENV{'request.publicaccess'}) ||
213: (!&Apache::lonnet::is_on_map(
214: &Apache::lonnet::unescape($ENV{'request.noversionuri'})))) &&
215: (!$forcereg))) {
216: return $result.
217: '<script type="text/javascript">function LONCAPAreg(){;} function LONCAPAstale(){}</script>'.$force_title;
218: }
219: # Graphical display after login only
220: if ($Apache::lonxml::registered && !$forcereg) { return ''; }
221: if ($target ne 'edit') {
222: $result.=&innerregister($forcereg,$target);
223: }
224: return $result.$force_title;
225: }
226:
227: # =========== This gets called in order to register a URL, both with the Remote
228: # =========== and in the body of the document
229:
230: sub innerregister {
231: my $forcereg=shift;
232: my $target = shift;
233: my $titletable = shift;
234: my $result = '';
235: my ($uname,$thisdisfn);
236: my $const_space = ($ENV{'request.state'} eq 'construct');
237: my $is_const_dir = 0;
238:
239: if ($ENV{'request.noversionuri'} eq '/res/adm/pages/menu.html') { return ''; }
240:
241: $Apache::lonxml::registered=1;
242:
243: my $textinter=($ENV{'browser.interface'} eq 'textual');
244: my $noremote=($ENV{'environment.remote'} eq 'off');
245:
246: my $textual=($textinter || $noremote);
247:
248: @inlineremote=();
249: undef @inlineremote;
250:
251: my $reopen=&Apache::lonmenu::reopenmenu();
252:
253: my $newmail='';
254: if ($noremote) {
255: $newmail='<font face="Arial,Helvetica,sans-serif"><table bgcolor="'.$pgbg.'" border="0" cellspacing="1" cellpadding="1" width="100%"><tr><td bgcolor="'.$tabbg.'">';
256: }
257: if (($textual) && ($ENV{'request.symb'}) && ($ENV{'request.course.id'})) {
258: my ($mapurl,$rid,$resurl)=&Apache::lonnet::decode_symb($ENV{'request.symb'});
259: $newmail.=$ENV{'course.'.$ENV{'request.course.id'}.'.description'};
260: my $maptitle=&Apache::lonnet::gettitle($mapurl);
261: my $restitle=&Apache::lonnet::gettitle($resurl);
262: if ($maptitle) {
263: $newmail.=', '.$maptitle;
264: }
265: if ($restitle) {
266: $newmail.=': '.$restitle;
267: }
268: $newmail.=' ';
269: }
270: if (&Apache::lonmsg::newmail()) {
271: $newmail=($textual?
272: '<b><a href="/adm/communicate" target="_top">You have new messages</a></b><br />':
273: 'swmenu.setstatus("you have","messages");');
274: }
275: if ($ENV{'request.state'} eq 'construct') {
276: $newmail = $titletable;
277: }
278: if ($noremote) {
279: $newmail.='</td></tr></table></font>';
280: }
281: my $timesync=($textual?'':'swmenu.syncclock(1000*'.time.');');
282: my $tablestart=($noremote?'<font face="Arial,Helvetica,sans-serif"><table bgcolor="'.$pgbg.'" border="0" cellspacing="1" cellpadding="1" width="100%">':'').($textinter?'<br /><a href="#content">'.&mt('Skip to Content').'</a><br />':'');
283: my $tableend=($noremote?'</table></font>':'').($textinter?'<a name="content" />':'');
284: # =============================================================================
285: # ============================ This is for URLs that actually can be registered
286: if (($ENV{'request.noversionuri'}!~/^\/(res\/)*adm\//) || ($forcereg)) {
287: # -- This applies to homework problems for users with grading privileges
288: my $crs='/'.$ENV{'request.course.id'};
289: if ($ENV{'request.course.sec'}) {
290: $crs.='_'.$ENV{'request.course.sec'};
291: }
292: $crs=~s/\_/\//g;
293:
294: my $hwkadd='';
295: if ($ENV{'request.filename'}=~/\.(problem|exam|quiz|assess|survey|form)$/) {
296: if (&Apache::lonnet::allowed('vgr',$crs)) {
297: $hwkadd.=&switch('','',7,1,'subm.gif','view sub-[_1]','missions[_1]',
298: "gocmd('/adm/grades','submission')",
299: 'View user submissions for this assessment resource');
300: }
301: if (&Apache::lonnet::allowed('mgr',$crs)) {
302: $hwkadd.=&switch('','',7,2,'pgrd.gif','problem[_1]','grades[_3]',
303: "gocmd('/adm/grades','gradingmenu')",
304: 'Modify user grades for this assessment resource');
305: }
306: }
307: if (&Apache::lonnet::allowed('opa',$crs)) {
308: $hwkadd.=&switch('','',7,3,'pparm.gif','problem[_2]','parms[_2]',
309: "gocmd('/adm/parmset','set')",
310: 'Modify deadlines, etc, for this resource');
311: }
312: # -- End Homework
313: ###
314: ### Determine whether or not to display the 'cstr' button for this
315: ### resource
316: ###
317: my $editbutton = '';
318: if ($ENV{'user.author'}) {
319: if ($ENV{'request.role'}=~/^(ca|au)/) {
320: # Set defaults for authors
321: my ($top,$bottom) = ('con-','struct');
322: my $action = "go('/priv/".$ENV{'user.name'}."');";
323: my $cadom = $ENV{'request.role.domain'};
324: my $caname = $ENV{'user.name'};
325: my $desc = "Enter my resource construction space";
326: # Set defaults for co-authors
327: if ($ENV{'request.role'} =~ /^ca/) {
328: ($cadom,$caname)=($ENV{'request.role'}=~/(\w+)\/(\w+)$/);
329: ($top,$bottom) = ('co con-','struct');
330: $action = "go('/priv/".$caname."');";
331: $desc = "Enter construction space as co-author";
332: }
333: # Check that we are on the correct machine
334: my $home = &Apache::lonnet::homeserver($caname,$cadom);
335: my $allowed=0;
336: my @ids=&Apache::lonnet::current_machine_ids();
337: foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
338: if (!$allowed) {
339: $editbutton=&switch('','',6,1,$top,,$bottom,$action,$desc);
340: }
341: }
342: ##
343: ## Determine if user can edit url.
344: ##
345: my $cfile='';
346: my $cfuname='';
347: my $cfudom='';
348: if ($ENV{'request.filename'}) {
349: my $file=&Apache::lonnet::declutter($ENV{'request.filename'});
350: $file=~s/^(\w+)\/(\w+)/\/priv\/$2/;
351: # Check that the user has permission to edit this resource
352: ($cfuname,$cfudom)=&Apache::loncacc::constructaccess($file,$1);
353: if (defined($cfudom)) {
354: my $home=&Apache::lonnet::homeserver($cfuname,$cfudom);
355: my $allowed=0;
356: my @ids=&Apache::lonnet::current_machine_ids();
357: foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
358: if ($allowed) {
359: $cfile=$file;
360: }
361: }
362: }
363: # Finally, turn the button on or off
364: if ($cfile && !$const_space) {
365: $editbutton=&switch
366: ('','',6,1,'cstr.gif','edit[_1]','resource[_2]',
367: "go('".$cfile."');","Edit this resource");
368: } elsif ($editbutton eq '') {
369: $editbutton=&clear(6,1);
370: }
371: }
372: ###
373: ###
374: # Prepare the rest of the buttons
375: my $menuitems;
376: if ($const_space) {
377: my ($uname,$thisdisfn) =
378: ($ENV{'request.filename'}=~m|^/home/([^/]+)/public_html/(.*)|);
379: my $currdir = '/priv/'.$uname.'/'.$thisdisfn;
380: if ($currdir =~ m-/$-) {
381: $is_const_dir = 1;
382: } else {
383: $currdir =~ s#[^/]+$##;
384: $menuitems=(<<ENDMENUITEMS);
385: s&6&1&list.gif&list[_1]&dir[_1]&golist('$currdir')&List current directory
386: s&6&2&rtrv.gif&retrieve[_1]&version[_1]&gocstr('/adm/retrieve','/~$uname/$thisdisfn')&Retrieve old version
387: s&6&3&pub.gif&publish[_1]&resource[_1]&gocstr('/adm/publish','/~$uname/$thisdisfn')&Publish this resource
388: s&7&1&del.gif&delete[_1]&resource[_2]&gocstr('/adm/cfile?action=delete','/~$uname/$thisdisfn')&Delete this resource
389: s&7&2&prt.gif&prepare[_1]&printout[_1]&gopost('/adm/printout','/~$uname/$thisdisfn')&Prepare a printable document
390: ENDMENUITEMS
391: }
392: } else {
393: $menuitems=(<<ENDMENUITEMS);
394: c&3&1
395: s&2&1&back.gif&backward[_1]&&gopost('/adm/flip','back:'+currentURL)&Go to the previous resource in the course sequence&1
396: s&2&3&forw.gif&forward[_1]&&gopost('/adm/flip','forward:'+currentURL)&Go to the next resource in the course sequence&3
397: c&6&3
398: c&8&1
399: c&8&2
400: s&8&3&prt.gif&prepare[_1]&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document
401: s&9&1&sbkm.gif&set[_1]&bookmark[_2]&set_bookmark()&Set a bookmark for this resource&2
402: s&9&3&anot.gif&anno-[_1]&tations[_1]&annotate()&Make notes and annotations about this resource&2
403: ENDMENUITEMS
404: unless ($ENV{'request.noversionuri'}=~/\/(bulletinboard|smppg|navmaps|syllabus|aboutme)(\?|$)/) {
405: $menuitems.=(<<ENDREALRES);
406: s&6&3&catalog.gif&catalog[_1]&info[_1]&catalog_info()&Show catalog information
407: s&8&1&eval.gif&evaluate[_1]&this[_1]&gopost('/adm/evaluate',currentURL,1)&Provide my evaluation of this resource
408: s&8&2&fdbk.gif&feedback[_1]&discuss[_1]&gopost('/adm/feedback',currentURL,1)&Provide feedback messages or contribute to the course discussion about this resource
409: ENDREALRES
410: }
411: }
412: my $buttons='';
413: foreach (split(/\n/,$menuitems)) {
414: my ($command,@rest)=split(/\&/,$_);
415: if ($command eq 's') {
416: $buttons.=&switch('','',@rest);
417: } else {
418: $buttons.=&clear(@rest);
419: }
420: }
421: if ($textual) {
422: # Registered, textual output
423: my $inlinebuttons='';
424:
425: if ($ENV{'browser.interface'} eq 'textual') {
426: $inlinebuttons=
427: join('',map { (defined($_)?$_:'') } @inlineremote);
428: } else {
429: $inlinebuttons=(<<ENDINLINE);
430: <tr><td>$inlineremote[21]</td><td> </td><td>$inlineremote[23]</td></tr>
431: <tr><td>$inlineremote[61]</td><td>$inlineremote[62]</td><td>$inlineremote[63]</td></tr>
432: <tr><td>$inlineremote[71]</td><td>$inlineremote[72]</td><td>$inlineremote[73]</td></tr>
433: <tr><td>$inlineremote[81]</td><td>$inlineremote[82]</td><td>$inlineremote[83]</td></tr>
434: <tr><td>$inlineremote[91]</td><td>$inlineremote[92]</td><td>$inlineremote[93]</td></tr>
435: ENDINLINE
436: }
437: if ($const_space && $is_const_dir) {
438: $inlinebuttons = '';
439: }
440: $result =(<<ENDREGTEXT);
441: <script type="text/javascript">
442: // BEGIN LON-CAPA Internal
443: </script>
444: $timesync
445: $newmail
446: $tablestart
447: $inlinebuttons
448: $tableend
449: <script type="text/javascript">
450: // END LON-CAPA Internal
451: </script>
452:
453: ENDREGTEXT
454: # Registered, graphical output
455: } else {
456: my $requri=(split(/\?/,$ENV{'request.noversionuri'}))[0];
457: $requri=&Apache::lonenc::check_encrypt(&Apache::lonnet::unescape($requri));
458: my $cursymb=&Apache::lonenc::check_encrypt($ENV{'request.symb'});
459: my $navstatus=&get_nav_status();
460: $result = (<<ENDREGTHIS);
461:
462: <script type="text/javascript">
463: // BEGIN LON-CAPA Internal
464: var swmenu=null;
465:
466: function LONCAPAreg() {
467: swmenu=$reopen;
468: swmenu.clearTimeout(swmenu.menucltim);
469: $timesync
470: $newmail
471: $buttons
472: swmenu.currentURL="$requri";
473: swmenu.reloadURL=swmenu.currentURL+window.location.search;
474: swmenu.currentSymb="$cursymb";
475: swmenu.reloadSymb="$cursymb";
476: swmenu.currentStale=0;
477: $navstatus
478: $hwkadd
479: $editbutton
480: }
481:
482: function LONCAPAstale() {
483: swmenu=$reopen
484: swmenu.currentStale=1;
485: if (swmenu.reloadURL!='' && swmenu.reloadURL!= null) {
486: swmenu.switchbutton
487: (3,1,'reload.gif','return','location','go(reloadURL)','Return to the last known location in the course sequence');
488: }
489: swmenu.clearbut(7,1);
490: swmenu.clearbut(7,2);
491: swmenu.clearbut(7,3);
492: swmenu.menucltim=swmenu.setTimeout(
493: 'clearbut(2,1);clearbut(2,3);clearbut(8,1);clearbut(8,2);clearbut(8,3);'+
494: 'clearbut(9,1);clearbut(9,3);clearbut(6,3);clearbut(6,1)',
495: 2000);
496: }
497:
498: // END LON-CAPA Internal
499: </script>
500: ENDREGTHIS
501: }
502: # =============================================================================
503: } else {
504: # ========================================== This can or will not be registered
505: if ($textual) {
506: # Not registered, textual
507: $result= (<<ENDDONOTREGTEXT);
508: ENDDONOTREGTEXT
509: } else {
510: # Not registered, graphical
511: $result = (<<ENDDONOTREGTHIS);
512:
513: <script type="text/javascript">
514: // BEGIN LON-CAPA Internal
515: var swmenu=null;
516:
517: function LONCAPAreg() {
518: swmenu=$reopen
519: $timesync
520: swmenu.currentStale=1;
521: swmenu.clearbut(2,1);
522: swmenu.clearbut(2,3);
523: swmenu.clearbut(8,1);
524: swmenu.clearbut(8,2);
525: swmenu.clearbut(8,3);
526: if (swmenu.currentURL) {
527: swmenu.switchbutton
528: (3,1,'reload.gif','return','location','go(currentURL)');
529: } else {
530: swmenu.clearbut(3,1);
531: }
532: }
533:
534: function LONCAPAstale() {
535: }
536:
537: // END LON-CAPA Internal
538: </script>
539: ENDDONOTREGTHIS
540: }
541: # =============================================================================
542: }
543: return $result;
544: }
545:
546: sub loadevents() {
547: if ($ENV{'request.noversionuri'} eq '/res/adm/pages/menu.html') { return ''; }
548: return 'LONCAPAreg();';
549: }
550:
551: sub unloadevents() {
552: if ($ENV{'request.noversionuri'} eq '/res/adm/pages/menu.html') { return ''; }
553: return 'LONCAPAstale();';
554: }
555:
556: # ============================================================= Start up remote
557:
558: sub startupremote {
559: my ($lowerurl)=@_;
560: if (($ENV{'browser.interface'} eq 'textual') ||
561: ($ENV{'environment.remote'} eq 'off')) {
562: return ('<meta HTTP-EQUIV="Refresh" CONTENT="0.5; url='.$lowerurl.'" />');
563: }
564: #
565: # The Remote actually gets launched!
566: #
567: my $configmenu=&rawconfig();
568: my $esclowerurl=&Apache::lonnet::escape($lowerurl);
569: my $message=&mt('"Waiting for Remote Control window to load: "+[_1]','waited');
570: return(<<ENDREMOTESTARTUP);
571: <script type="text/javascript">
572: var timestart;
573: function wheelswitch() {
574: if (typeof(document.wheel) != 'undefined') {
575: if (typeof(document.wheel.spin) != 'undefined') {
576: var date=new Date();
577: var waited=Math.round(30-((date.getTime()-timestart)/1000));
578: document.wheel.spin.value=$message;
579: }
580: }
581: if (window.status=='|') {
582: window.status='/';
583: } else {
584: if (window.status=='/') {
585: window.status='-';
586: } else {
587: if (window.status=='-') {
588: window.status='\\\\';
589: } else {
590: if (window.status=='\\\\') { window.status='|'; }
591: }
592: }
593: }
594: }
595:
596: // ---------------------------------------------------------- The wait function
597: var canceltim;
598: function wait() {
599: if ((menuloaded==1) || (tim==1)) {
600: window.status='Done.';
601: if (tim==0) {
602: clearTimeout(canceltim);
603: $configmenu
604: window.location='$lowerurl';
605: } else {
606: window.location='/adm/remote?action=collapse&url=$esclowerurl';
607: }
608: } else {
609: wheelswitch();
610: setTimeout('wait();',200);
611: }
612: }
613:
614: function main() {
615: canceltim=setTimeout('tim=1;',30000);
616: window.status='-';
617: var date=new Date();
618: timestart=date.getTime();
619: wait();
620: }
621:
622: </script>
623: ENDREMOTESTARTUP
624: }
625:
626: sub setflags() {
627: return(<<ENDSETFLAGS);
628: <script type="text/javascript">
629: menuloaded=0;
630: tim=0;
631: </script>
632: ENDSETFLAGS
633: }
634:
635: sub maincall() {
636: if (($ENV{'browser.interface'} eq 'textual') ||
637: ($ENV{'environment.remote'} eq 'off')) { return ''; }
638: return(<<ENDMAINCALL);
639: <script type="text/javascript">
640: main();
641: </script>
642: ENDMAINCALL
643: }
644:
645: sub load_remote_msg {
646: my ($lowerurl)=@_;
647:
648: if (($ENV{'browser.interface'} eq 'textual') ||
649: ($ENV{'environment.remote'} eq 'off')) { return ''; }
650:
651: my $esclowerurl=&Apache::lonnet::escape($lowerurl);
652: my $link=&mt('<a href="[_1]">Continue</a> on in Inline Menu mode',
653: "/adm/remote?action=collapse?url=$esclowerurl");
654: return(<<ENDREMOTEFORM);
655: <p>
656: <form name="wheel">
657: <input name="spin" type="text" size="60" />
658: </form>
659: </p>
660: <p>$link</p>
661: ENDREMOTEFORM
662: }
663: # ================================================================= Reopen menu
664:
665: sub reopenmenu {
666: if (($ENV{'browser.interface'} eq 'textual') ||
667: ($ENV{'environment.remote'} eq 'off')) { return ''; }
668: my $menuname='LCmenu'.$Apache::lonnet::perlvar{'lonHostID'};
669: my $nothing = &Apache::lonhtmlcommon::javascript_nothing();
670: return('window.open('.$nothing.',"'.$menuname.'","",false);');
671: }
672:
673: # =============================================================== Open the menu
674:
675: sub open {
676: my $returnval='';
677: if (($ENV{'browser.interface'} eq 'textual') ||
678: ($ENV{'environment.remote'} eq 'off')) {
679: return '<script type="text/javascript">self.name="loncapaclient";</script>';
680: }
681: my $menuname='LCmenu'.$Apache::lonnet::perlvar{'lonHostID'};
682: unless (shift eq 'unix') {
683: # resizing does not work on linux because of virtual desktop sizes
684: $returnval.=(<<ENDRESIZE);
685: if (window.screen) {
686: self.resizeTo(screen.availWidth-215,screen.availHeight-55);
687: self.moveTo(190,15);
688: }
689: ENDRESIZE
690: }
691: $returnval.=(<<ENDOPEN);
692: window.status='Opening LON-CAPA Remote Control';
693: var menu=window.open("/res/adm/pages/menu.html","$menuname",
694: "height=350,width=150,scrollbars=no,menubar=no,top=5,left=5,screenX=5,screenY=5");
695: self.name='loncapaclient';
696: ENDOPEN
697: return '<script type="text/javascript">'.$returnval.'</script>';
698: }
699:
700:
701: # ================================================================== Raw Config
702:
703: sub clear {
704: my ($row,$col)=@_;
705: unless (($ENV{'browser.interface'} eq 'textual') ||
706: ($ENV{'environment.remote'} eq 'off')) {
707: return "\n".qq(window.status+='.';swmenu.clearbut($row,$col););
708: } else {
709: $inlineremote[10*$row+$col]='';
710: return '';
711: }
712: }
713:
714: # ============================================ Switch a button or create a link
715: # Switch acts on the javascript that is executed when a button is clicked.
716: # The javascript is usually similar to "go('/adm/roles')" or "cstrgo(..)".
717:
718: sub switch {
719: my ($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$nobreak)=@_;
720: $act=~s/\$uname/$uname/g;
721: $act=~s/\$udom/$udom/g;
722: $top=&mt($top);
723: $bot=&mt($bot);
724: $desc=&mt($desc);
725: $img=&mt($img);
726: unless (($ENV{'browser.interface'} eq 'textual') ||
727: ($ENV{'environment.remote'} eq 'off')) {
728: # Remote
729: return "\n".
730: qq(window.status+='.';swmenu.switchbutton($row,$col,"$img","$top","$bot","$act","$desc"););
731: } elsif ($ENV{'browser.interface'} eq 'textual') {
732: # Accessibility
733: if ($nobreak==2) { return ''; }
734: my $text=$top.' '.$bot;
735: $text=~s/\s*\-\s*//gs;
736: if ($nobreak) {
737: $inlineremote[10*$row+$col]=
738: '<a href="javascript:'.$act.';">'.$text.'</a>';
739: } else {
740: $inlineremote[10*$row+$col]="\n<br />".
741: $desc.' <a href="javascript:'.$act.';">'.$text.'</a>';
742: }
743: } else {
744: # Inline Remote
745: if ($nobreak==2) { return ''; }
746: my $text=$top.' '.$bot;
747: $text=~s/\s*\-\s*//gs;
748:
749: my $lonhttpdPort=$Apache::lonnet::perlvar{'lonhttpdPort'};
750: if (!defined($lonhttpdPort)) { $lonhttpdPort='8080'; }
751: my $pic=
752: '<img border="0" alt="'.$text.'" src="http://'.$ENV{'HTTP_HOST'}.
753: ':'.$lonhttpdPort.'/res/adm/pages/'.$img.'" align="'.
754: ($nobreak==3?'right':'left').'" />';
755: if (($ENV{'browser.interface'} eq 'textual') || ($ENV{'browser.interface'} eq 'faketextual')) {
756: # Accessibility
757: if ($nobreak==3) {
758: $inlineremote[10*$row+$col]="\n".
759: '<td width="40%" align="right"><font color="'.$font.'" size="+1">'.$text.
760: '</font></td><td width="10%" align="right" bgcolor="'.$tabbg.'">'.
761: '<a href="javascript:'.$act.';">'.$pic.'</a></td></tr>';
762: } elsif ($nobreak) {
763: $inlineremote[10*$row+$col]="\n<tr>".
764: '<td width="10%" align="left" bgcolor="'.$tabbg.'">'.
765: '<a href="javascript:'.$act.';">'.$pic.
766: '</a></td><td width="40%" align="left"><font color="'.$font.'" size="+1">'.$text.'</font></td>';
767: } else {
768: $inlineremote[10*$row+$col]="\n<tr>".
769: '<td width="10%" align="left" bgcolor="'.$tabbg.'">'.
770: '<a href="javascript:'.$act.';">'.$pic.
771: '</a></td><td colspan="3"><font color="'.$font.'">'.$desc.
772: '</font></td></tr>';
773: }
774: } else {
775: # Inline Menu
776: $inlineremote[10*$row+$col]=
777: '<a href="javascript:'.$act.';">'.$pic.
778: '</a><font color="'.$font.'" size="2">'.$desc.
779: '</font>';
780: }
781: }
782: return '';
783: }
784:
785: sub secondlevel {
786: my $output='';
787: my
788: ($uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc)=@_;
789: if ($prt eq 'any') {
790: $output.=switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc);
791: } elsif ($prt=~/^r(\w+)/) {
792: if ($rol eq $1) {
793: $output.=switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc);
794: }
795: }
796: return $output;
797: }
798:
799: sub openmenu {
800: my $menuname='LCmenu'.$Apache::lonnet::perlvar{'lonHostID'};
801: if (($ENV{'browser.interface'} eq 'textual') ||
802: ($ENV{'environment.remote'} eq 'off')) { return ''; }
803: my $nothing = &Apache::lonhtmlcommon::javascript_nothing();
804: return "window.open(".$nothing.",'".$menuname."');";
805: }
806:
807: sub inlinemenu {
808: @inlineremote=();
809: undef @inlineremote;
810: &rawconfig(1);
811: return join('',map { (defined($_)?$_:'') } @inlineremote);
812: }
813:
814: sub rawconfig {
815: my $textualoverride=shift;
816: my $output='';
817: unless (($ENV{'browser.interface'} eq 'textual') ||
818: ($ENV{'environment.remote'} eq 'off')) {
819: $output.=
820: "window.status='Opening Remote Control';var swmenu=".&openmenu().
821: "\nwindow.status='Configuring Remote Control ';";
822: } else {
823: unless ($textualoverride) { return ''; }
824: }
825: my $uname=$ENV{'user.name'};
826: my $udom=$ENV{'user.domain'};
827: my $adv=$ENV{'user.adv'};
828: my $author=$ENV{'user.author'};
829: my $crs='';
830: if ($ENV{'request.course.id'}) {
831: $crs='/'.$ENV{'request.course.id'};
832: if ($ENV{'request.course.sec'}) {
833: $crs.='_'.$ENV{'request.course.sec'};
834: }
835: $crs=~s/\_/\//g;
836: }
837: my $pub=($ENV{'request.state'} eq 'published');
838: my $con=($ENV{'request.state'} eq 'construct');
839: my $rol=$ENV{'request.role'};
840: my $requested_domain = $ENV{'request.role.domain'};
841: foreach (@desklines) {
842: my ($row,$col,$pro,$prt,$img,$top,$bot,$act,$desc)=split(/\:/,$_);
843: $prt=~s/\$uname/$uname/g;
844: $prt=~s/\$udom/$udom/g;
845: $prt=~s/\$crs/$crs/g;
846: $prt=~s/\$requested_domain/$requested_domain/g;
847: if ($pro eq 'clear') {
848: $output.=&clear($row,$col);
849: } elsif ($pro eq 'any') {
850: $output.=&secondlevel(
851: $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc);
852: } elsif ($pro eq 'smp') {
853: unless ($adv) {
854: $output.=&secondlevel(
855: $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc);
856: }
857: } elsif ($pro eq 'adv') {
858: if ($adv) {
859: $output.=&secondlevel(
860: $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc);
861: }
862: } elsif (($pro=~/^p(\w+)/) && ($prt)) {
863: if (&Apache::lonnet::allowed($1,$prt)) {
864: $output.=switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc);
865: }
866: } elsif ($pro eq 'course') {
867: if ($ENV{'request.course.fn'}) {
868: $output.=switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc);
869: }
870: } elsif ($pro =~ /^courseenv_(.*)$/) {
871: my $key = $1;
872: if ($ENV{'course.'.$ENV{'request.course.id'}.'.'.$key}) {
873: $output.=switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc);
874: }
875: } elsif ($pro =~ /^course_(.*)$/) {
876: # Check for permissions inside of a course
877: if (($ENV{'request.course.id'}) &&
878: (&Apache::lonnet::allowed($1,$ENV{'request.course.id'}.
879: ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))
880: )) {
881: $output.=switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc);
882: }
883: } elsif ($pro eq 'author') {
884: if ($author) {
885: if ((($prt eq 'rca') && ($ENV{'request.role'}=~/^ca/)) ||
886: (($prt eq 'rau') && ($ENV{'request.role'}=~/^au/))) {
887: # Check that we are on the correct machine
888: my $cadom=$requested_domain;
889: my $caname=$ENV{'user.name'};
890: if ($prt eq 'rca') {
891: ($cadom,$caname)=
892: ($ENV{'request.role'}=~/(\w+)\/(\w+)$/);
893: }
894: $act =~ s/\$caname/$caname/g;
895: my $home = &Apache::lonnet::homeserver($caname,$cadom);
896: my $allowed=0;
897: my @ids=&Apache::lonnet::current_machine_ids();
898: foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
899: if ($allowed) {
900: $output.=switch($caname,$cadom,
901: $row,$col,$img,$top,$bot,$act,$desc);
902: }
903: }
904: }
905: }
906: }
907: unless (($ENV{'browser.interface'} eq 'textual') ||
908: ($ENV{'environment.remote'} eq 'off')) {
909: $output.="\nwindow.status='Synchronizing Time';swmenu.syncclock(1000*".time.");\nwindow.status='Remote Control Configured.';";
910: if (&Apache::lonmsg::newmail()) {
911: $output.='swmenu.setstatus("you have","messages");';
912: }
913: }
914:
915: return $output;
916: }
917:
918: # ======================================================================= Close
919:
920: sub close {
921: if (($ENV{'browser.interface'} eq 'textual') ||
922: ($ENV{'environment.remote'} eq 'off')) { return ''; }
923: my $menuname='LCmenu'.$Apache::lonnet::perlvar{'lonHostID'};
924: return(<<ENDCLOSE);
925: <script type="text/javascript">
926: window.status='Accessing Remote Control';
927: menu=window.open("/adm/rat/empty.html","$menuname",
928: "height=350,width=150,scrollbars=no,menubar=no");
929: window.status='Disabling Remote Control';
930: menu.active=0;
931: menu.autologout=0;
932: window.status='Closing Remote Control';
933: menu.close();
934: window.status='Done.';
935: </script>
936: ENDCLOSE
937: }
938:
939: # ====================================================================== Footer
940:
941: sub footer {
942:
943: }
944:
945: sub nav_control_js {
946: my $nav=($ENV{'environment.remotenavmap'} eq 'on');
947: return (<<NAVCONTROL);
948: var w_loncapanav_flag="$nav";
949:
950:
951: function gonav(url) {
952: if (w_loncapanav_flag != 1) {
953: gopost(url,'');
954: } else {
955: navwindow=window.open(url,
956: "loncapanav","height=600,width=400,scrollbars=1");
957: }
958: }
959: NAVCONTROL
960: }
961:
962: sub utilityfunctions {
963: unless (($ENV{'browser.interface'} eq 'textual') ||
964: ($ENV{'environment.remote'} eq 'off')) { return ''; }
965: my $currenturl=&Apache::lonenc::check_encrypt($ENV{'request.noversionuri'});
966:
967: my $currentsymb=&Apache::lonenc::check_encrypt($ENV{'request.symb'});
968: my $nav_control=&nav_control_js();
969: return (<<ENDUTILITY)
970:
971: var currentURL="$currenturl";
972: var reloadURL="$currenturl";
973: var currentSymb="$currentsymb";
974:
975: $nav_control
976:
977: function go(url) {
978: if (url!='' && url!= null) {
979: currentURL = null;
980: currentSymb= null;
981: window.location.href=url;
982: }
983: }
984:
985: function gopost(url,postdata) {
986: if (url!='') {
987: this.document.server.action=url;
988: this.document.server.postdata.value=postdata;
989: this.document.server.command.value='';
990: this.document.server.url.value='';
991: this.document.server.symb.value='';
992: this.document.server.submit();
993: }
994: }
995:
996: function gocmd(url,cmd) {
997: if (url!='') {
998: this.document.server.action=url;
999: this.document.server.postdata.value='';
1000: this.document.server.command.value=cmd;
1001: this.document.server.url.value=currentURL;
1002: this.document.server.symb.value=currentSymb;
1003: this.document.server.submit();
1004: }
1005: }
1006:
1007: function gocstr(url,filename) {
1008: if (url == '/adm/cfile?action=delete') {
1009: this.document.cstrdelete.filename.value = filename
1010: this.document.cstrdelete.submit();
1011: return;
1012: }
1013: if (url !='') {
1014: this.document.constspace.filename.value = filename;
1015: this.document.constspace.action = url;
1016: this.document.constspace.submit();
1017: }
1018: }
1019:
1020: function golist(url) {
1021: if (url!='' && url!= null) {
1022: currentURL = null;
1023: currentSymb= null;
1024: top.location.href=url;
1025: }
1026: }
1027:
1028:
1029:
1030: function catalog_info() {
1031: loncatinfo=window.open(window.location.pathname+'.meta',"LONcatInfo",'height=320,width=280,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
1032: }
1033:
1034: function chat_win() {
1035: lonchat=window.open('/res/adm/pages/chatroom.html',"LONchat",'height=320,width=280,resizable=yes,location=no,menubar=no,toolbar=no');
1036: }
1037: ENDUTILITY
1038: }
1039:
1040: sub serverform {
1041: return(<<ENDSERVERFORM);
1042:
1043: <form name="server" action="/adm/logout" method="post" target="_top">
1044: <input type="hidden" name="postdata" value="none" />
1045: <input type="hidden" name="command" value="none" />
1046: <input type="hidden" name="url" value="none" />
1047: <input type="hidden" name="symb" value="none" />
1048: </form>
1049: ENDSERVERFORM
1050: }
1051:
1052: sub constspaceform {
1053: return(<<ENDCONSTSPACEFORM);
1054: <form name="constspace" action="/adm/logout" method="post" target="_top">
1055: <input type="hidden" name="filename" value="" />
1056: </form>
1057: <form name="cstrdelete" action="/adm/cfile" method="post" target="_top">
1058: <input type="hidden" name="action" value="delete" />
1059: <input type="hidden" name="filename" value="" />
1060: </form>
1061: ENDCONSTSPACEFORM
1062: }
1063:
1064:
1065: sub get_nav_status {
1066: my $navstatus="swmenu.w_loncapanav_flag=";
1067: if ($ENV{'environment.remotenavmap'} eq 'on') {
1068: $navstatus.="1";
1069: } else {
1070: $navstatus.="-1";
1071: }
1072: return $navstatus;
1073: }
1074:
1075: # ================================================ Handler when called directly
1076:
1077:
1078: sub handler {
1079: my $r = shift;
1080: &Apache::loncommon::content_type($r,'text/html');
1081: $r->send_http_header;
1082: return OK if $r->header_only;
1083:
1084: my $form;
1085: if ($ENV{'environment.remote'} ne 'off' &&
1086: $ENV{'browser.interface'} ne 'textual') {
1087: $form=&serverform();
1088: }
1089: my $bodytag=&Apache::loncommon::bodytag('Main Menu');
1090: my $function='student';
1091: if ($ENV{'request.role'}=~/^(cc|in|ta|ep)/) {
1092: $function='coordinator';
1093: }
1094: if ($ENV{'request.role'}=~/^(su|dc|ad|li)/) {
1095: $function='admin';
1096: }
1097: if (($ENV{'request.role'}=~/^(au|ca)/) ||
1098: ($ENV{'request.noversionuri'}=~/^(\/priv|\~)/)) {
1099: $function='author';
1100: }
1101: my $domain=&Apache::loncommon::determinedomain();
1102: $pgbg=&Apache::loncommon::designparm($function.'.pgbg',$domain);
1103: $tabbg=&Apache::loncommon::designparm($function.'.tabbg',$domain);
1104: $font=&Apache::loncommon::designparm($function.'.font',$domain);
1105: # ---- Print the screen, pretent to be in text mode to generate text-based menu
1106: unless ($ENV{'browser.interface'} eq 'textual') {
1107: $ENV{'browser.interface'}='faketextual';
1108: $ENV{'environment.remote'}='off';
1109: }
1110: $r->print(<<ENDHEADER);
1111: <html><head>
1112: <title>LON-CAPA Main Menu</title>
1113: </head>
1114: $bodytag
1115: ENDHEADER
1116: $r->print('<table>'.&inlinemenu().'</table>'.$form);
1117: $r->print('</body></html>');
1118: return OK;
1119: }
1120:
1121: # ================================================================ Main Program
1122:
1123: BEGIN {
1124: if (! defined($readdesk)) {
1125: {
1126: my $tabfile = $Apache::lonnet::perlvar{'lonTabDir'}.'/mydesk.tab';
1127: if ( CORE::open( my $config,"<$tabfile") ) {
1128: while (my $configline=<$config>) {
1129: $configline=(split(/\#/,$configline))[0];
1130: $configline=~s/^\s+//;
1131: chomp($configline);
1132: if ($configline) {
1133: $desklines[$#desklines+1]=$configline;
1134: }
1135: }
1136: CORE::close($config);
1137: }
1138: }
1139: $readdesk='done';
1140: }
1141: }
1142:
1143: 1;
1144: __END__
1145:
1146:
1147:
1148:
1149:
1150:
1151:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>