1: # The LearningOnline Network with CAPA
2: # Routines to control the menu
3: #
4: # $Id: lonmenu.pm,v 1.314 2010/02/24 17:38:52 droeschl 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 is one parameter controlling the action of this module:
30: #
31: # environment.remote - if this is 'on', the routines controll the remote
32: # control, otherwise they render the main window controls;
33:
34: =head1 NAME
35:
36: Apache::lonmenu
37:
38: =head1 SYNOPSIS
39:
40: Coordinates the response to clicking an image.
41:
42: This is part of the LearningOnline Network with CAPA project
43: described at http://www.lon-capa.org.
44:
45: =head1 GLOBAL VARIABLES
46:
47: =over
48:
49: =item @desklines
50:
51: Each element of this array contains a line of mydesk.tab that doesn't start with
52: cat, prim or scnd.
53: It gets filled in the BEGIN block of this module.
54:
55: =item %category_names
56:
57: The keys of this hash are the abbreviations used in mydesk.tab in those lines that
58: start with cat, the values are strings representing titles.
59: It gets filled in the BEGIN block of this module.
60:
61: =item %category_members
62:
63: TODO
64:
65: =item %category_positions
66:
67: The keys of this hash are the abbreviations used in mydesk.tab in those lines that
68: start with cat, its values are position vectors (column, row).
69: It gets filled in the BEGIN block of this module.
70:
71: =item $readdesk
72:
73: Indicates that mydesk.tab has been read.
74: It is set to 'done' in the BEGIN block of this module.
75:
76: =item @primary_menu
77:
78: The elements of this array reference arrays that are made up of the components
79: of those lines of mydesk.tab that start with prim.
80: It is used by primary_menu() to generate the corresponding menu.
81: It gets filled in the BEGIN block of this module.
82:
83: =item @secondary_menu
84:
85: The elements of this array reference arrays that are made up of the components
86: of those lines of mydesk.tab that start with scnd.
87: It is used by secondary_menu() to generate the corresponding menu.
88: It gets filled in the BEGIN block of this module.
89:
90: =back
91:
92: =head1 SUBROUTINES
93:
94: =over
95:
96: =item prep_menuitems(\@menuitem)
97:
98: This routine wraps a menuitem in proper HTML. It is used by primary_menu() and
99: secondary_menu().
100:
101: =item primary_menu()
102:
103: This routine evaluates @primary_menu and returns XHTML for the menu
104: that contains following links: About, Message, Roles, Help, Logout
105: @primary_menu is filled within the BEGIN block of this module with
106: entries from mydesk.tab
107:
108: =item secondary_menu()
109:
110: Same as primary_menu() but operates on @secondary_menu.
111:
112: =item DEPRECATED: initlittle()
113:
114: This routine returns a translated hash for the menu items in the top inline
115: menu row
116:
117: =item menubuttons()
118:
119: This gets called at the top of the body section
120:
121: =item show_return_link()
122:
123: =item registerurl()
124:
125: This gets called in the header section
126:
127: =item innerregister()
128:
129: This gets called in order to register a URL, both with the Remote
130: and in the body of the document
131:
132: =item loadevents()
133:
134: =item unloadevents()
135:
136: =item startupremote()
137:
138: =item setflags()
139:
140: =item maincall()
141:
142: =item load_remote_msg()
143:
144: =item get_menu_name()
145:
146: =item reopenmenu()
147:
148: =item open()
149:
150: Open the menu
151:
152: =item clear()
153:
154: =item switch()
155:
156: Switch a button or create a link
157: Switch acts on the javascript that is executed when a button is clicked.
158: The javascript is usually similar to "go('/adm/roles')" or "cstrgo(..)".
159:
160: =item secondlevel()
161:
162: =item openmenu()
163:
164: =item inlinemenu()
165:
166: =item rawconfig()
167:
168: =item close()
169:
170: =item footer()
171:
172: =item utilityfunctions()
173:
174: =item serverform()
175:
176: =item constspaceform()
177:
178: =item get_nav_status()
179:
180: =item hidden_button_check()
181:
182: =item roles_selector()
183:
184: =item jump_to_role()
185:
186: =back
187:
188: =cut
189:
190: package Apache::lonmenu;
191:
192: use strict;
193: use Apache::lonnet;
194: use Apache::lonhtmlcommon();
195: use Apache::loncommon();
196: use Apache::lonenc();
197: use Apache::lonlocal;
198: use LONCAPA qw(:DEFAULT :match);
199: use HTML::Entities();
200:
201: use vars qw(@desklines %category_names %category_members %category_positions
202: $readdesk @primary_menu @secondary_menu);
203:
204: my @inlineremote;
205:
206: sub prep_menuitem {
207: my ($menuitem) = @_;
208: return '' unless(ref($menuitem) eq 'ARRAY');
209: my $link;
210: if ($$menuitem[1]) { # graphical Link
211: $link = "<img class=\"LC_noBorder\""
212: . " src=\"" . &Apache::loncommon::lonhttpdurl($$menuitem[1]) . "\""
213: . " alt=\"" . &mt($$menuitem[2]) . "\" />";
214: } else { # textual Link
215: $link = &mt($$menuitem[3]);
216: }
217: if($$menuitem[4] eq 'newmsg'){ #special style for New Messages
218: return '<li><a href="'.$$menuitem[0].'"><span class="LC_new_message">'.$link.'</span></a></li>';
219: }
220: return '<li><a href="'.$$menuitem[0].'">'.$link.'</a></li>';
221: }
222:
223: # primary_menu() evaluates @primary_menu and returns XHTML for the menu
224: # that contains following links:
225: # About, Message, Roles, Help, Logout
226: # @primary_menu is filled within the BEGIN block of this module with
227: # entries from mydesk.tab
228: sub primary_menu {
229: my $menu;
230: # each element of @primary contains following array:
231: # (link url, icon path, alt text, link text, condition)
232: foreach my $menuitem (@primary_menu) {
233: # evaluate conditions
234: next if ref($menuitem) ne 'ARRAY'; #
235: next if $$menuitem[4] eq 'nonewmsg' # show links depending on
236: && &Apache::lonmsg::mynewmail(); # whether a new msg
237: next if $$menuitem[4] eq 'newmsg' # arrived or not
238: && !&Apache::lonmsg::mynewmail(); #
239: next if $$menuitem[4] !~ /public/ ##we've a public user,
240: && $env{'user.name'} eq 'public' ##who should not see all
241: && $env{'user.domain'} eq 'public'; ##links
242: next if $$menuitem[4] eq 'onlypublic'# hide links which are
243: && $env{'user.name'} ne 'public' # only visible to public
244: && $env{'user.domain'} ne 'public'; # users
245: next if $$menuitem[4] eq 'roles' ##show links depending on
246: && &Apache::loncommon::show_course(); ##term 'Courses' or
247: next if $$menuitem[4] eq 'courses' ##'Roles' wanted
248: && !&Apache::loncommon::show_course(); ##
249:
250:
251: if ($$menuitem[3] eq 'Help') { # special treatment for helplink
252: $menu .= '<li>'.&Apache::loncommon::top_nav_help('Help').'</li>';
253: } else {
254: my @items = @{$menuitem};
255: $items[0] = 'javascript:'.$menuitem->[0].';';
256: $menu .= &prep_menuitem(\@items);
257: }
258: }
259:
260: return "<ol class=\"LC_primary_menu LC_right\">$menu</ol>";
261: }
262:
263:
264: sub secondary_menu {
265: my $menu;
266:
267: my $crstype = &Apache::loncommon::course_type();
268: my $canedit = &Apache::lonnet::allowed('mdc', $env{'request.course.id'});
269: my $canviewgrps = &Apache::lonnet::allowed('vcg', $env{'request.course.id'}
270: . ($env{'request.course.sec'} ? "/$env{'request.course.sec'}"
271: : ''));
272: my $showlink = &show_return_link();
273: my %groups = &Apache::lonnet::get_active_groups(
274: $env{'user.domain'}, $env{'user.name'},
275: $env{'course.' . $env{'request.course.id'} . '.domain'},
276: $env{'course.' . $env{'request.course.id'} . '.num'});
277: foreach my $menuitem (@secondary_menu) {
278: # evaluate conditions
279: next if ref($menuitem) ne 'ARRAY';
280: next if $$menuitem[4] ne 'always'
281: && !$env{'request.course.id'};
282: next if $$menuitem[4] eq 'showreturn'
283: && !$showlink
284: && !($env{'request.state'} eq 'construct');
285: next if $$menuitem[4] =~ /^mdc/
286: && !$canedit;
287: next if $$menuitem[4] eq 'mdcCourse'
288: && $crstype eq 'Community';
289: next if $$menuitem[4] eq 'mdcCommunity'
290: && $crstype ne 'Community';
291: next if $$menuitem[4] =~ /^remotenav/
292: && $env{'environment.remotenavmap'} ne 'on';
293: next if $$menuitem[4] =~ /noremotenav/
294: && $env{'environment.remotenavmap'} eq 'on';
295: next if $$menuitem[4] =~ /^(no|)remotenav$/
296: && $crstype eq 'Community';
297: next if $$menuitem[4] =~ /^(no|)remotenavCommunity$/
298: && $crstype ne 'Community';
299: next if $$menuitem[4] =~ /showgroups$/
300: && !$canviewgrps
301: && !%groups;
302:
303: if ($$menuitem[3] eq 'Roles' && $env{'request.course.id'}) {
304: # special treatment for role selector
305: my $roles_selector = &roles_selector(
306: $env{'course.' . $env{'request.course.id'} . '.domain'},
307: $env{'course.' . $env{'request.course.id'} . '.num'} );
308:
309: $menu .= $roles_selector ? "<li>$roles_selector</li>"
310: : '';
311: } elsif ($env{'environment.remotenavmap'} eq 'on') {
312: # open link using javascript when remote navmap is activated
313: my @items = @{$menuitem};
314: if ($menuitem->[4] eq 'remotenav') {
315: $items[0] = "javascript:gonav('$menuitem->[0]');";
316: } else {
317: $items[0] = "javascript:go('$menuitem->[0]');";
318: }
319: $menu .= &prep_menuitem(\@items);
320: } else {
321: $menu .= &prep_menuitem(\@$menuitem);
322: }
323: }
324: if ($menu =~ /\[url\].*\[symb\]/) {
325: my $escurl = &escape( &Apache::lonenc::check_encrypt(
326: $env{'request.noversionuri'}));
327:
328: my $escsymb = &escape( &Apache::lonenc::check_encrypt(
329: $env{'request.symb'}));
330:
331: if ( $env{'request.state'} eq 'construct'
332: and ( $env{'request.noversionuri'} eq ''
333: || !defined($env{'request.noversionuri'})))
334: {
335: ($escurl = $env{'request.filename'}) =~
336: s{^/home/([^/]+)/public_html/(.*)$}{/priv/$1/$2};
337:
338: $escurl = &escape($escurl);
339: }
340: $menu =~ s/\[url\]/$escurl/g;
341: $menu =~ s/\[symb\]/$escsymb/g;
342: }
343:
344: return "<ul id=\"LC_secondary_menu\">$menu</ul>";
345: }
346:
347:
348: #
349: # This routine returns a translated hash for the menu items in the top inline menu row
350: # Probably should be in mydesk.tab
351:
352: #SD this sub is deprecated - don't use it
353: sub initlittle {
354: return &Apache::lonlocal::texthash('ret' => 'Return to Last Location',
355: 'nav' => 'Course Contents',
356: 'main' => 'Main Menu',
357: 'roles' => (&Apache::loncommon::show_course()?
358: 'Courses':'Roles'),
359: 'other' => 'Other Roles',
360: 'docs' => 'Course Editor',
361: 'exit' => 'Logout',
362: 'login' => 'Log In',
363: 'launch' => 'Launch Remote Control',
364: 'groups' => 'Groups',
365: 'gdoc' => 'Community Documents',
366: );
367: }
368:
369: #SD this sub is deprecated - don't use it
370: #SD functionality is covered by new loncommon::bodytag and primary_menu(), secondary_menu()
371: sub menubuttons {
372: my $forcereg=shift;
373: my $titletable=shift;
374: #
375: # Early-out for pages that should not have a menu, triggered by query string "inhibitmenu=yes"
376: #
377: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
378: ['inhibitmenu']);
379: if (($env{'form.inhibitmenu'} eq 'yes') ||
380: ($ENV{'REQUEST_URI'} eq '/adm/logout')) { return ''; }
381:
382: if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
383:
384: my %lt=&initlittle();
385: my $navmaps='';
386: my $reloadlink='';
387: my $docs='';
388: my $groups='';
389: my $roles='<a href="/adm/roles" target="_top">'.$lt{'roles'}.'</a>';
390: my $role_selector;
391: my $showgroups=0;
392: my ($cnum,$cdom);
393: #
394: # if the URL is hidden, symbs and the non-versioned version of the URL would be encrypted
395: #
396: my $escurl=&escape(&Apache::lonenc::check_encrypt($env{'request.noversionuri'}));
397: my $escsymb=&escape(&Apache::lonenc::check_encrypt($env{'request.symb'}));
398:
399: my $logo=&Apache::loncommon::lonhttpdurl("/adm/lonIcons/minilogo.gif");
400: $logo = '<a href="/adm/about.html"><img src="'.
401: $logo.'" alt="LON-CAPA Logo" class="LC_noBorder" /></a>';
402:
403: if ($env{'request.state'} eq 'construct') {
404: #
405: # We are in construction space
406: #
407: if (($env{'request.noversionuri'} eq '') || (!defined($env{'request.noversionuri'}))) {
408: my $returnurl = $env{'request.filename'};
409: $returnurl =~ s:^/home/([^/]+)/public_html/(.*)$:/priv/$1/$2:;
410: $escurl = &escape($returnurl);
411: }
412: }
413: if ($env{'request.course.id'}) {
414: #
415: # We are in a course
416: #
417: $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
418: $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
419: my %coursegroups;
420: my $viewgrps_permission =
421: &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
422: if (!$viewgrps_permission) {
423: %coursegroups = &Apache::lonnet::get_active_groups($env{'user.domain'},$env{'user.name'},$cdom,$cnum);
424: }
425: if ((keys(%coursegroups) > 0) || ($viewgrps_permission)) {
426: $showgroups = 1;
427: }
428: $role_selector = &roles_selector($cdom,$cnum);
429: if ($role_selector) {
430: $roles = '<span class="LC_nobreak">'.$role_selector.' <a href="/adm/roles" target="_top">'.$lt{'other'}.'</a></span>';
431: }
432: }
433:
434: if ($env{'environment.remote'} eq 'off') {
435: # Remote Control is switched off
436: # figure out colors
437: my %lt=&initlittle();
438:
439: my $domain=&Apache::loncommon::determinedomain();
440: my $function=&Apache::loncommon::get_users_function();
441: my $link=&Apache::loncommon::designparm($function.'.link',$domain);
442: my $alink=&Apache::loncommon::designparm($function.'.alink',$domain);
443: my $vlink=&Apache::loncommon::designparm($function.'.vlink',$domain);
444: my $sidebg=&Apache::loncommon::designparm($function.'.sidebg',$domain);
445:
446: if ($env{'user.name'} eq 'public' && $env{'user.domain'} eq 'public') {
447: return (<<ENDINLINEMENU);
448: <ol class="LC_primary_menu LC_right">
449: <li>$logo</li>
450: <li><a href="/adm/roles" target="_top">$lt{'login'}</a></li>
451: </ol>
452: <hr />
453: ENDINLINEMENU
454: }
455: $roles = '<a href="/adm/roles" target="_top">'.$lt{'roles'}.'</a>';
456: # Do we have a NAV link?
457: if ($env{'request.course.id'}) {
458: my $link='/adm/navmaps?postdata='.$escurl.'&postsymb='.
459: $escsymb;
460: if ($env{'environment.remotenavmap'} eq 'on') {
461: $link="javascript:gonav('".$link."')";
462: }
463: $navmaps=(<<ENDNAV);
464: <li><a href="$link" target="_top">$lt{'nav'}</a></li>
465: ENDNAV
466: my $is_community =
467: (&Apache::loncommon::course_type() eq 'Community');
468: if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) {
469: my $text = ($is_community) ? $lt{'gdoc'} : $lt{'docs'};
470: $docs=(<<ENDDOCS);
471: <li><a href="/adm/coursedocs" target="_top">$text</a></li>
472: ENDDOCS
473: }
474: if ($showgroups) {
475: $groups =(<<ENDGROUPS);
476: <li><a href="/adm/coursegroups" target="_top">$lt{'groups'}</a></li>
477: ENDGROUPS
478: }
479: if (&show_return_link()) {
480: my $escreload=&escape('return:');
481: $reloadlink=(<<ENDRELOAD);
482: <li><a href="/adm/flip?postdata=$escreload" target="_top">$lt{'ret'}</a></li>
483: ENDRELOAD
484: }
485: if ($role_selector) {
486: #$roles = '<td>'.$role_selector.'</td><td><a href="/adm/roles" target="_top">'.$lt{'other'}.'</a></td>';
487: $role_selector = '<li>'.$role_selector.'</li>';
488: }
489: }
490: if (($env{'request.state'} eq 'construct') && ($env{'request.course.id'})) {
491: my $escreload=&escape('return:');
492: $reloadlink=(<<ENDCRELOAD);
493: <li><a href="/adm/flip?postdata=$escreload" target="_top">$lt{'ret'}</a></li>
494: ENDCRELOAD
495: }
496: my $reg = $forcereg ? &innerregister($forcereg,$titletable) : '';
497: my $form = &serverform();
498: my $utility = &utilityfunctions();
499:
500: #Prepare the message link that indicates the arrival of new mail
501: my $messagelink = &Apache::lonmsg::mynewmail() ? "Message (new)" : "Message";
502: $messagelink = '<a href="javascript:go(\'/adm/communicate\');">'
503: . mt($messagelink) .'</a>';
504:
505: my $helplink = &Apache::loncommon::top_nav_help('Help');
506: return (<<ENDINLINEMENU);
507: <script type="text/javascript">
508: // <![CDATA[
509: // BEGIN LON-CAPA Internal
510: $utility
511: // ]]>
512: </script>
513: <ol class="LC_primary_menu LC_right">
514: <li>$logo</li>
515: <li>$messagelink</li>
516: <li>$roles</li>
517: <li>$helplink</li>
518: <li><a href="/adm/logout" target="_top">$lt{'exit'}</a></li>
519: </ol>
520: <ul id="LC_secondary_menu">
521: <li><a href="/adm/menu" target="_top">$lt{'main'}</a></li>
522: $reloadlink
523: $navmaps
524: $docs
525: $groups
526: $role_selector
527: </ul>
528: $form
529: <script type="text/javascript">
530: // END LON-CAPA Internal
531: </script>
532: $reg
533: ENDINLINEMENU
534: } else {
535: return '';
536: }
537: }
538:
539: sub show_return_link {
540: return (($env{'request.noversionuri'}=~m{^/(res|public)/} &&
541: $env{'request.symb'} eq '')
542: ||
543: ($env{'request.noversionuri'}=~ m{^/cgi-bin/printout.pl})
544: ||
545: (($env{'request.noversionuri'}=~/^\/adm\//) &&
546: ($env{'request.noversionuri'}!~/^\/adm\/wrapper\//) &&
547: ($env{'request.noversionuri'}!~
548: m[^/adm/.*/(smppg|bulletinboard|aboutme)($|\?)])
549: ));
550: }
551:
552:
553: sub registerurl {
554: my ($forcereg) = @_;
555: my $result = '';
556: if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
557: my $force_title='';
558: if ($env{'request.state'} eq 'construct') {
559: $force_title=&Apache::lonxml::display_title();
560: }
561: if (($env{'environment.remote'} eq 'off') ||
562: ((($env{'request.publicaccess'}) ||
563: (!&Apache::lonnet::is_on_map(
564: &unescape($env{'request.noversionuri'})))) &&
565: (!$forcereg))) {
566: return
567: $result
568: .'<script type="text/javascript">'."\n"
569: .'// <![CDATA['."\n"
570: .'function LONCAPAreg(){;} function LONCAPAstale(){}'."\n"
571: .'// ]]>'."\n"
572: .'</script>'
573: .$force_title;
574: }
575: # Graphical display after login only
576: if ($env{'request.registered'} && !$forcereg) { return ''; }
577: $result.=&innerregister($forcereg);
578: return $result.$force_title;
579: }
580:
581: sub innerregister {
582: my ($forcereg,$titletable,$bread_crumbs) = @_;
583: my $result = '';
584: my ($uname,$thisdisfn);
585: my $const_space = ($env{'request.state'} eq 'construct');
586: my $is_const_dir = 0;
587:
588: if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
589:
590: $env{'request.registered'} = 1;
591:
592: my $noremote = ($env{'environment.remote'} eq 'off');
593:
594: undef(@inlineremote);
595:
596: my $reopen=&Apache::lonmenu::reopenmenu();
597:
598: my $newmail='';
599:
600: if (&Apache::lonmsg::newmail() && !$noremote) {
601: # We have new mail and remote is up
602: $newmail= 'swmenu.setstatus("you have","messages");';
603: }
604:
605: my ($breadcrumb,$separator);
606: if ($noremote
607: && ($env{'request.symb'})
608: && ($env{'request.course.id'})) {
609:
610: my ($mapurl,$rid,$resurl) = &Apache::lonnet::decode_symb(&Apache::lonnet::symbread());
611: my $coursetitle = $env{'course.'.$env{'request.course.id'}.'.description'};
612:
613: my $maptitle = &Apache::lonnet::gettitle($mapurl);
614: my $restitle = &Apache::lonnet::gettitle(&Apache::lonnet::symbread());
615: my $contentstext;
616: if ($env{'course.'.$env{'request.course.id'}.'.type'} eq 'Community') {
617: $contentstext = &mt('Community Contents');
618: } else {
619: $contentstext = &mt('Course Contents');
620: }
621: my @crumbs = ({text => $contentstext,
622: href => "Javascript:gonav('/adm/navmaps')"});
623:
624: if ($mapurl ne $env{'course.'.$env{'request.course.id'}.'.url'}) {
625: push(@crumbs, {text => '...',
626: no_mt => 1});
627: }
628:
629: push @crumbs, {text => $maptitle, no_mt => 1} if ($maptitle
630: && $maptitle ne 'default.sequence'
631: && $maptitle ne $coursetitle);
632:
633: push @crumbs, {text => $restitle, no_mt => 1} if $restitle;
634:
635: &Apache::lonhtmlcommon::clear_breadcrumbs();
636: &Apache::lonhtmlcommon::add_breadcrumb(@crumbs);
637: #$breadcrumb .= &Apache::lonhtmlcommon::breadcrumbs(undef,undef,0);
638: unless (($env{'request.state'} eq 'edit') || ($newmail) ||
639: ($env{'request.state'} eq 'construct') ||
640: ($env{'form.register'})) {
641: $separator = &Apache::loncommon::head_subbox();
642: }
643: #
644: }
645: if ($env{'request.state'} eq 'construct') {
646: $newmail = $titletable;
647: }
648: my $timesync = ( $noremote ? '' : 'swmenu.syncclock(1000*'.time.');' );
649: my $tablestart = ( $noremote ? '<table id="LC_menubuttons">' : '');
650: my $tableend = ( $noremote ? '</table>' : '');
651: # =============================================================================
652: # ============================ This is for URLs that actually can be registered
653: if (($env{'request.noversionuri'}!~m{^/(res/)*adm/}) || ($forcereg)) {
654: # -- This applies to homework problems for users with grading privileges
655: my $crs='/'.$env{'request.course.id'};
656: if ($env{'request.course.sec'}) {
657: $crs.='_'.$env{'request.course.sec'};
658: }
659: $crs=~s/\_/\//g;
660:
661: my $hwkadd='';
662: if ($env{'request.symb'} ne '' &&
663: $env{'request.filename'}=~/\.(problem|exam|quiz|assess|survey|form|task)$/) {
664: if (&Apache::lonnet::allowed('mgr',$crs)) {
665: $hwkadd.=&switch('','',7,2,'pgrd.gif','problem[_1]','grades[_4]',
666: "gocmd('/adm/grades','gradingmenu')",
667: 'Modify user grades for this assessment resource');
668: } elsif (&Apache::lonnet::allowed('vgr',$crs)) {
669: $hwkadd.=&switch('','',7,2,'subm.gif','view sub-[_1]','missions[_1]',
670: "gocmd('/adm/grades','submission')",
671: 'View user submissions for this assessment resource');
672: }
673: }
674: if ($env{'request.symb'} ne '' &&
675: &Apache::lonnet::allowed('opa',$crs)) {
676: $hwkadd.=&switch('','',7,3,'pparm.gif','problem[_2]','parms[_2]',
677: "gocmd('/adm/parmset','set')",
678: 'Modify parameter settings for this resource');
679: }
680: # -- End Homework
681: ###
682: ### Determine whether or not to display the 'cstr' button for this
683: ### resource
684: ###
685: my $editbutton = '';
686: my $noeditbutton = 1;
687: my ($cnum,$cdom);
688: if ($env{'request.course.id'}) {
689: $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
690: $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
691: }
692: if ($env{'user.author'}) {
693: if ($env{'request.role'}=~/^(aa|ca|au)/) {
694: #
695: # We have the role of an author
696: #
697: # Set defaults for authors
698: my ($top,$bottom) = ('con-','struct');
699: my $action = "go('/priv/".$env{'user.name'}."');";
700: my $cadom = $env{'request.role.domain'};
701: my $caname = $env{'user.name'};
702: my $desc = "Enter my construction space";
703: # Set defaults for co-authors
704: if ($env{'request.role'} =~ /^ca/) {
705: ($cadom,$caname)=($env{'request.role'}=~/($match_domain)\/($match_username)$/);
706: ($top,$bottom) = ('co con-','struct');
707: $action = "go('/priv/".$caname."');";
708: $desc = "Enter construction space as co-author";
709: } elsif ($env{'request.role'} =~ /^aa/) {
710: ($cadom,$caname)=($env{'request.role'}=~/($match_domain)\/($match_username)$/);
711: ($top,$bottom) = ('co con-','struct');
712: $action = "go('/priv/".$caname."');";
713: $desc = "Enter construction space as assistant co-author";
714: }
715: # Check that we are on the correct machine
716: my $home = &Apache::lonnet::homeserver($caname,$cadom);
717: my $allowed=0;
718: my @ids=&Apache::lonnet::current_machine_ids();
719: foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
720: if (!$allowed) {
721: $editbutton=&switch('','',6,1,$top,,$bottom,$action,$desc);
722: $noeditbutton = 0;
723: }
724: }
725: #
726: # We are an author for some stuff, but currently do not have the role of author.
727: # Figure out if we have authoring privileges for the resource we are looking at.
728: # This should maybe become a privilege check in lonnet
729: #
730: ##
731: ## Determine if user can edit url.
732: ##
733: my $cfile='';
734: my $cfuname='';
735: my $cfudom='';
736: my $uploaded;
737: if ($env{'request.filename'}) {
738: my $file=&Apache::lonnet::declutter($env{'request.filename'});
739: if (defined($cnum) && defined($cdom)) {
740: $uploaded = &is_course_upload($file,$cnum,$cdom);
741: }
742: if (!$uploaded) {
743: $file=~s/^($match_domain)\/($match_username)/\/priv\/$2/;
744: # Check that the user has permission to edit this resource
745: ($cfuname,$cfudom)=&Apache::loncacc::constructaccess($file,$1);
746: if (defined($cfudom)) {
747: my $home=&Apache::lonnet::homeserver($cfuname,$cfudom);
748: my $allowed=0;
749: my @ids=&Apache::lonnet::current_machine_ids();
750: foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
751: if ($allowed) {
752: $cfile=$file;
753: }
754: }
755: }
756: }
757: # Finally, turn the button on or off
758: if ($cfile && !$const_space) {
759: my $nocrsedit;
760: # Suppress display where CC has switched to student role.
761: if ($env{'request.course.id'}) {
762: unless(&Apache::lonnet::allowed('mdc',
763: $env{'request.course.id'})) {
764: $nocrsedit = 1;
765: }
766: }
767: if ($nocrsedit) {
768: $editbutton=&clear(6,1);
769: } else {
770: $editbutton=&switch
771: ('','',6,1,'pcstr.gif','edit[_1]','resource[_2]',
772: "go('".$cfile."');","Edit this resource");
773: $noeditbutton = 0;
774: }
775: } elsif ($editbutton eq '') {
776: $editbutton=&clear(6,1);
777: }
778: }
779: if (($noeditbutton) && ($env{'request.filename'})) {
780: if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) {
781: my $file=&Apache::lonnet::declutter($env{'request.filename'});
782: if (defined($cnum) && defined($cdom)) {
783: if (&is_course_upload($file,$cnum,$cdom)) {
784: my $cfile = &edit_course_upload($file,$cnum,$cdom);
785: if ($cfile) {
786: $editbutton=&switch
787: ('','',6,1,'pcstr.gif','edit[_1]',
788: 'resource[_2]',"go('".$cfile."');",
789: 'Edit this resource');
790: }
791: }
792: }
793: }
794: }
795: ###
796: ###
797: # Prepare the rest of the buttons
798: my $menuitems;
799: if ($const_space) {
800: #
801: # We are in construction space
802: #
803: my ($uname,$thisdisfn) =
804: ($env{'request.filename'}=~m|^/home/([^/]+)/public_html/(.*)|);
805: my $currdir = '/priv/'.$uname.'/'.$thisdisfn;
806: if ($currdir =~ m-/$-) {
807: $is_const_dir = 1;
808: } else {
809: $currdir =~ s|[^/]+$||;
810: my $cleandisfn = &Apache::loncommon::escape_single($thisdisfn);
811: my $esc_currdir = &Apache::loncommon::escape_single($currdir);
812: #
813: # Probably should be in mydesk.tab
814: #
815: $menuitems=(<<ENDMENUITEMS);
816: s&6&1&list.gif&list[_1]&dir[_1]&golist('$esc_currdir')&List current directory
817: s&6&2&rtrv.gif&retrieve[_1]&version[_1]&gocstr('/adm/retrieve','/~$uname/$cleandisfn')&Retrieve old version
818: s&6&3&pub.gif&publish[_1]&resource[_3]&gocstr('/adm/publish','/~$uname/$cleandisfn')&Publish this resource
819: s&7&1&del.gif&delete[_1]&resource[_2]&gocstr('/adm/cfile?action=delete','/~$uname/$cleandisfn')&Delete this resource
820: s&7&2&prt.gif&prepare[_1]&printout[_1]&gocstr('/adm/printout','/~$uname/$cleandisfn')&Prepare a printable document
821: ENDMENUITEMS
822: }
823: if ($noremote) {
824: if (ref($bread_crumbs) eq 'ARRAY') {
825: &Apache::lonhtmlcommon::clear_breadcrumbs();
826: foreach my $crumb (@{$bread_crumbs}){
827: &Apache::lonhtmlcommon::add_breadcrumb($crumb);
828: }
829: }
830: }
831: } elsif ( defined($env{'request.course.id'}) &&
832: $env{'request.symb'} ne '' ) {
833: #
834: # We are in a course and looking at a registred URL
835: # Should probably be in mydesk.tab
836: #
837: $menuitems=(<<ENDMENUITEMS);
838: c&3&1
839: s&2&1&back.gif&backward[_1]&&gopost('/adm/flip','back:'+currentURL)&Go to the previous resource in the course sequence&&1
840: s&2&3&forw.gif&forward[_1]&&gopost('/adm/flip','forward:'+currentURL)&Go to the next resource in the course sequence&&3
841: c&6&3
842: c&8&1
843: c&8&2
844: s&8&3&prt.gif&prepare[_1]&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document
845: s&9&1&sbkm.gif&set[_1]&bookmark[_2]&set_bookmark()&Set a bookmark for this resource&&1
846: ENDMENUITEMS
847:
848: my $currentURL = &Apache::loncommon::get_symb();
849: my ($symb_old,$symb_old_enc) = &Apache::loncommon::clean_symb($currentURL);
850: my $annotation = &Apache::loncommon::get_annotation($symb_old,$symb_old_enc);
851: $menuitems.="s&9&3&";
852: if(length($annotation) > 0){
853: $menuitems.="anot2.gif";
854: }else{
855: $menuitems.="anot.gif";
856: }
857: $menuitems.="&anno-[_1]&tations[_1]&annotate()&";
858: $menuitems.="Make notes and annotations about this resource&&1\n";
859:
860: unless ($noremote) {
861: my $showreqcrs = &check_for_rcrs();
862: if ($showreqcrs) {
863: $menuitems.="s&8&1&rcrs.gif&request[_1]&course[_16]".
864: "&go('/adm/requestcourse')&Course requests\n";
865: }
866: }
867: unless ($env{'request.noversionuri'}=~/\/(bulletinboard|smppg|navmaps|syllabus|aboutme)(\?|$)/) {
868: if ((!$env{'request.enc'}) && ($env{'request.noversionuri'} !~ m{^/adm/wrapper/ext/})) {
869: $menuitems.=(<<ENDREALRES);
870: s&6&3&catalog.gif&catalog[_2]&info[_1]&catalog_info()&Show Metadata
871: ENDREALRES
872: }
873: $menuitems.=(<<ENDREALRES);
874: s&8&1&eval.gif&evaluate[_1]&this[_1]&gopost('/adm/evaluate',currentURL,1)&Provide my evaluation of this resource
875: 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
876: ENDREALRES
877: }
878: }
879: if ($env{'request.uri'} =~ /^\/res/) {
880: $menuitems .= (<<ENDMENUITEMS);
881: s&8&3&prt.gif&prepare[_1]&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document
882: ENDMENUITEMS
883: }
884: my $buttons='';
885: foreach (split(/\n/,$menuitems)) {
886: my ($command,@rest)=split(/\&/,$_);
887: my $idx=10*$rest[0]+$rest[1];
888: if (&hidden_button_check() eq 'yes') {
889: if ($idx == 21 ||$idx == 23) {
890: $buttons.=&switch('','',@rest);
891: } else {
892: $buttons.=&clear(@rest);
893: }
894: } else {
895: if ($command eq 's') {
896: $buttons.=&switch('','',@rest);
897: } else {
898: $buttons.=&clear(@rest);
899: }
900: }
901: }
902:
903: if ($noremote) {
904: my $addremote=0;
905: foreach (@inlineremote) { if ($_ ne '') { $addremote=1; last;} }
906: my $inlinebuttons='';
907: if ($addremote) {
908:
909: Apache::lonhtmlcommon::clear_breadcrumb_tools();
910:
911: Apache::lonhtmlcommon::add_breadcrumb_tool(
912: 'navigation', @inlineremote[21,23]);
913:
914: if(hidden_button_check() ne 'yes') {
915: Apache::lonhtmlcommon::add_breadcrumb_tool(
916: 'tools', @inlineremote[93,91,81,82,83]);
917:
918: #publish button in construction space
919: if ($env{'request.state'} eq 'construct'){
920: Apache::lonhtmlcommon::add_breadcrumb_tool(
921: 'advtools', @inlineremote[63]);
922: }else{
923: Apache::lonhtmlcommon::add_breadcrumb_tool(
924: 'tools', @inlineremote[63]);
925: }
926:
927:
928: Apache::lonhtmlcommon::add_breadcrumb_tool(
929: 'advtools', @inlineremote[61,71,72,73,92]);
930: }
931:
932: # # Registered, textual output
933: # if ( $env{'environment.icons'} eq 'iconsonly' ) {
934: # $inlinebuttons = (<<ENDARROWSINLINE);
935: #<tr><td>
936: #$inlineremote[21] $inlineremote[23]
937: #ENDARROWSINLINE
938: # if ( &hidden_button_check() ne 'yes' ) {
939: # $inlinebuttons .= (<<ENDINLINEICONS);
940: #$inlineremote[61] $inlineremote[63]
941: #$inlineremote[71] $inlineremote[72] $inlineremote[73]
942: #$inlineremote[81] $inlineremote[82] $inlineremote[83]
943: #$inlineremote[91] $inlineremote[92] $inlineremote[93]</td></tr>
944: #ENDINLINEICONS
945: # }
946: # } else { # not iconsonly
947: # if ( $inlineremote[21] ne '' || $inlineremote[23] ne '' ) {
948: # $inlinebuttons = (<<ENDFIRSTLINE);
949: #<tr><td>$inlineremote[21]</td><td> </td><td>$inlineremote[23]</td></tr>
950: #ENDFIRSTLINE
951: # }
952: # if ( &hidden_button_check() ne 'yes' ) {
953: # foreach my $row ( 6 .. 9 ) {
954: # if ( $inlineremote[ ${row} . '1' ] ne ''
955: # || $inlineremote[ $row . '2' ] ne ''
956: # || $inlineremote[ $row . '3' ] ne '' )
957: # {
958: # $inlinebuttons .= <<"ENDLINE";
959: #<tr><td>$inlineremote["${row}1"]</td><td>$inlineremote["${row}2"]</td><td>$inlineremote["${row}3"]</td></tr>
960: #ENDLINE
961: # }
962: # }
963: # }
964: # }
965: }
966: $breadcrumb = &Apache::lonhtmlcommon::breadcrumbs(undef,undef,0);
967: $result =(<<ENDREGTEXT);
968: <script type="text/javascript">
969: // BEGIN LON-CAPA Internal
970: </script>
971: $timesync
972: $breadcrumb
973: <!-- $tablestart -->
974: <!-- $inlinebuttons -->
975: <!-- $tableend -->
976: $newmail
977: <!-- $separator -->
978: <script type="text/javascript">
979: // END LON-CAPA Internal
980: </script>
981:
982: ENDREGTEXT
983: # Registered, graphical output
984: } else {
985: my $requri=&Apache::lonnet::clutter(&Apache::lonnet::fixversion((split(/\?/,$env{'request.noversionuri'}))[0]));
986: $requri=&Apache::lonenc::check_encrypt(&unescape($requri));
987: my $cursymb=&Apache::lonenc::check_encrypt($env{'request.symb'});
988: my $navstatus=&get_nav_status();
989: my $clearcstr;
990:
991: if ($env{'user.adv'}) { $clearcstr='clearbut(6,1)'; }
992: $result = (<<ENDREGTHIS);
993:
994: <script type="text/javascript">
995: // <![CDATA[
996: // BEGIN LON-CAPA Internal
997: var swmenu=null;
998:
999: function LONCAPAreg() {
1000: swmenu=$reopen;
1001: swmenu.clearTimeout(swmenu.menucltim);
1002: $timesync
1003: $newmail
1004: $buttons
1005: swmenu.currentURL="$requri";
1006: swmenu.reloadURL=swmenu.currentURL+window.location.search;
1007: swmenu.currentSymb="$cursymb";
1008: swmenu.reloadSymb="$cursymb";
1009: swmenu.currentStale=0;
1010: $navstatus
1011: $hwkadd
1012: $editbutton
1013: }
1014:
1015: function LONCAPAstale() {
1016: swmenu=$reopen
1017: swmenu.currentStale=1;
1018: if (swmenu.reloadURL!='' && swmenu.reloadURL!= null) {
1019: swmenu.switchbutton
1020: (3,1,'reload.gif','return','location','go(reloadURL)','Return to the last known location in the course sequence');
1021: }
1022: swmenu.clearbut(7,2);
1023: swmenu.clearbut(7,3);
1024: swmenu.menucltim=swmenu.setTimeout(
1025: 'clearbut(2,1);clearbut(2,3);clearbut(8,1);clearbut(8,2);clearbut(8,3);'+
1026: 'clearbut(9,1);clearbut(9,3);clearbut(6,3);$clearcstr',
1027: 2000);
1028: }
1029:
1030: // END LON-CAPA Internal
1031: // ]]>
1032: </script>
1033: ENDREGTHIS
1034: }
1035: # =============================================================================
1036: } else {
1037: # ========================================== This can or will not be registered
1038: if ($noremote) {
1039: # Not registered
1040: $result= (<<ENDDONOTREGTEXT);
1041: ENDDONOTREGTEXT
1042: } else {
1043: # Not registered, graphical
1044: $result = (<<ENDDONOTREGTHIS);
1045:
1046: <script type="text/javascript">
1047: // <![CDATA[
1048: // BEGIN LON-CAPA Internal
1049: var swmenu=null;
1050:
1051: function LONCAPAreg() {
1052: swmenu=$reopen
1053: $timesync
1054: swmenu.currentStale=1;
1055: swmenu.clearbut(2,1);
1056: swmenu.clearbut(2,3);
1057: swmenu.clearbut(8,1);
1058: swmenu.clearbut(8,2);
1059: swmenu.clearbut(8,3);
1060: if (swmenu.currentURL) {
1061: swmenu.switchbutton
1062: (3,1,'reload.gif','return','location','go(currentURL)');
1063: } else {
1064: swmenu.clearbut(3,1);
1065: }
1066: }
1067:
1068: function LONCAPAstale() {
1069: }
1070:
1071: // END LON-CAPA Internal
1072: // ]]>
1073: </script>
1074: ENDDONOTREGTHIS
1075: }
1076: # =============================================================================
1077: }
1078: return $result;
1079: }
1080:
1081: sub is_course_upload {
1082: my ($file,$cnum,$cdom) = @_;
1083: my $uploadpath = &LONCAPA::propath($cdom,$cnum);
1084: $uploadpath =~ s{^\/}{};
1085: if (($file =~ m{^\Q$uploadpath\E/userfiles/docs/}) ||
1086: ($file =~ m{^userfiles/\Q$cdom\E/\Q$cnum\E/docs/})) {
1087: return 1;
1088: }
1089: return;
1090: }
1091:
1092: sub edit_course_upload {
1093: my ($file,$cnum,$cdom) = @_;
1094: my $cfile;
1095: if ($file =~/\.(htm|html|css|js|txt)$/) {
1096: my $ext = $1;
1097: my $url = &Apache::lonnet::hreflocation('',$file);
1098: my $home = &Apache::lonnet::homeserver($cnum,$cdom);
1099: my @ids=&Apache::lonnet::current_machine_ids();
1100: my $dest;
1101: if ($home && grep(/^\Q$home\E$/,@ids)) {
1102: $dest = $url.'?forceedit=1';
1103: } else {
1104: unless (&Apache::lonnet::get_locks()) {
1105: $dest = '/adm/switchserver?otherserver='.
1106: $home.'&role='.$env{'request.role'}.
1107: '&url='.$url.'&forceedit=1';
1108: }
1109: }
1110: if ($dest) {
1111: $cfile = &HTML::Entities::encode($dest,'"<>&');
1112: }
1113: }
1114: return $cfile;
1115: }
1116:
1117: sub loadevents() {
1118: if ($env{'request.state'} eq 'construct' ||
1119: $env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
1120: return 'LONCAPAreg();';
1121: }
1122:
1123: sub unloadevents() {
1124: if ($env{'request.state'} eq 'construct' ||
1125: $env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
1126: return 'LONCAPAstale();';
1127: }
1128:
1129:
1130: sub startupremote {
1131: my ($lowerurl)=@_;
1132: if ($env{'environment.remote'} eq 'off') {
1133: return ('<meta HTTP-EQUIV="Refresh" CONTENT="0.5; url='.$lowerurl.'" />');
1134: }
1135: #
1136: # The Remote actually gets launched!
1137: #
1138: my $configmenu=&rawconfig();
1139: my $esclowerurl=&escape($lowerurl);
1140: my $message=&mt('"Waiting for Remote Control window to load: "+[_1]','waited');
1141: return(<<ENDREMOTESTARTUP);
1142: <script type="text/javascript">
1143: // <![CDATA[
1144: var timestart;
1145: function wheelswitch() {
1146: if (typeof(document.wheel) != 'undefined') {
1147: if (typeof(document.wheel.spin) != 'undefined') {
1148: var date=new Date();
1149: var waited=Math.round(30-((date.getTime()-timestart)/1000));
1150: document.wheel.spin.value=$message;
1151: }
1152: }
1153: if (window.status=='|') {
1154: window.status='/';
1155: } else {
1156: if (window.status=='/') {
1157: window.status='-';
1158: } else {
1159: if (window.status=='-') {
1160: window.status='\\\\';
1161: } else {
1162: if (window.status=='\\\\') { window.status='|'; }
1163: }
1164: }
1165: }
1166: }
1167:
1168: // ---------------------------------------------------------- The wait function
1169: var canceltim;
1170: function wait() {
1171: if ((menuloaded==1) || (tim==1)) {
1172: window.status='Done.';
1173: if (tim==0) {
1174: clearTimeout(canceltim);
1175: $configmenu
1176: window.location='$lowerurl';
1177: } else {
1178: window.location='/adm/remote?action=collapse&url=$esclowerurl';
1179: }
1180: } else {
1181: wheelswitch();
1182: setTimeout('wait();',200);
1183: }
1184: }
1185:
1186: function main() {
1187: canceltim=setTimeout('tim=1;',30000);
1188: window.status='-';
1189: var date=new Date();
1190: timestart=date.getTime();
1191: wait();
1192: }
1193:
1194: // ]]>
1195: </script>
1196: ENDREMOTESTARTUP
1197: }
1198:
1199: sub setflags() {
1200: return(<<ENDSETFLAGS);
1201: <script type="text/javascript">
1202: // <![CDATA[
1203: menuloaded=0;
1204: tim=0;
1205: // ]]>
1206: </script>
1207: ENDSETFLAGS
1208: }
1209:
1210: sub maincall() {
1211: if ($env{'environment.remote'} eq 'off') { return ''; }
1212: return(<<ENDMAINCALL);
1213: <script type="text/javascript">
1214: // <![CDATA[
1215: main();
1216: // ]]>
1217: </script>
1218: ENDMAINCALL
1219: }
1220:
1221: sub load_remote_msg {
1222: my ($lowerurl)=@_;
1223:
1224: if ($env{'environment.remote'} eq 'off') { return ''; }
1225:
1226: my $esclowerurl=&escape($lowerurl);
1227: my $link=&mt('[_1]Continue[_2] on in Inline Menu mode'
1228: ,'<a href="/adm/remote?action=collapse&url='.$esclowerurl.'">'
1229: ,'</a>');
1230: return(<<ENDREMOTEFORM);
1231: <p>
1232: <form name="wheel">
1233: <input name="spin" type="text" size="60" />
1234: </form>
1235: </p>
1236: <p>$link</p>
1237: ENDREMOTEFORM
1238: }
1239:
1240: sub get_menu_name {
1241: my $hostid = $Apache::lonnet::perlvar{'lonHostID'};
1242: $hostid =~ s/\W//g;
1243: return 'LCmenu'.$hostid;
1244: }
1245:
1246:
1247: sub reopenmenu {
1248: if ($env{'environment.remote'} eq 'off') { return ''; }
1249: my $menuname = &get_menu_name();
1250: my $nothing = &Apache::lonhtmlcommon::javascript_nothing();
1251: return('window.open('.$nothing.',"'.$menuname.'","",false);');
1252: }
1253:
1254:
1255: sub open {
1256: my $returnval='';
1257: if ($env{'environment.remote'} eq 'off') {
1258: return
1259: '<script type="text/javascript">'."\n"
1260: .'// <![CDATA['."\n"
1261: .'self.name="loncapaclient";'."\n"
1262: .'// ]]>'."\n"
1263: .'</script>';
1264: }
1265: my $menuname = &get_menu_name();
1266:
1267: # unless (shift eq 'unix') {
1268: # resizing does not work on linux because of virtual desktop sizes
1269: # $returnval.=(<<ENDRESIZE);
1270: #if (window.screen) {
1271: # self.resizeTo(screen.availWidth-215,screen.availHeight-55);
1272: # self.moveTo(190,15);
1273: #}
1274: #ENDRESIZE
1275: # }
1276: $returnval=(<<ENDOPEN);
1277: // <![CDATA[
1278: window.status='Opening LON-CAPA Remote Control';
1279: var menu=window.open("/res/adm/pages/menu.html?inhibitmenu=yes","$menuname",
1280: "height=375,width=150,scrollbars=no,menubar=no,top=5,left=5,screenX=5,screenY=5");
1281: self.name='loncapaclient';
1282: // ]]>
1283: ENDOPEN
1284: return '<script type="text/javascript">'.$returnval.'</script>';
1285: }
1286:
1287:
1288: # ================================================================== Raw Config
1289:
1290: sub clear {
1291: my ($row,$col)=@_;
1292: unless ($env{'environment.remote'} eq 'off') {
1293: if (($row<1) || ($row>13)) { return ''; }
1294: return "\n".qq(window.status+='.';swmenu.clearbut($row,$col););
1295: } else {
1296: $inlineremote[10*$row+$col]='';
1297: return '';
1298: }
1299: }
1300:
1301: # ============================================ Switch a button or create a link
1302: # Switch acts on the javascript that is executed when a button is clicked.
1303: # The javascript is usually similar to "go('/adm/roles')" or "cstrgo(..)".
1304:
1305: sub switch {
1306: my ($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat,$nobreak)=@_;
1307: $act=~s/\$uname/$uname/g;
1308: $act=~s/\$udom/$udom/g;
1309: $top=&mt($top);
1310: $bot=&mt($bot);
1311: $desc=&mt($desc);
1312: if (($env{'environment.remote'} ne 'off') || ($env{'environment.icons'} eq 'classic')) {
1313: $img=&mt($img);
1314: }
1315: my $idx=10*$row+$col;
1316: $category_members{$cat}.=':'.$idx;
1317:
1318: unless ($env{'environment.remote'} eq 'off') {
1319: if (($row<1) || ($row>13)) { return ''; }
1320: # Remote
1321: return "\n".
1322: qq(window.status+='.';swmenu.switchbutton($row,$col,"$img","$top","$bot","$act","$desc"););
1323: } else {
1324: # Inline Remote
1325: if ($env{'environment.icons'} ne 'classic') {
1326: $img=~s/\.gif$/\.png/;
1327: }
1328: if ($nobreak==2) { return ''; }
1329: my $text=$top.' '.$bot;
1330: $text=~s/\s*\-\s*//gs;
1331:
1332: my $pic=
1333: '<img alt="'.$text.'" src="'.
1334: &Apache::loncommon::lonhttpdurl('/res/adm/pages/'.$img).
1335: '" align="'.($nobreak==3?'right':'left').'" class="LC_icon" />';
1336: if ($env{'browser.interface'} eq 'faketextual') {
1337: # Main Menu
1338: if ($nobreak==3) {
1339: $inlineremote[$idx]="\n".
1340: '<td class="LC_menubuttons_text" align="right">'.$text.
1341: '</td><td align="left">'.
1342: '<a href="javascript:'.$act.';">'.$pic.'</a></td></tr>';
1343: } elsif ($nobreak) {
1344: $inlineremote[$idx]="\n<tr>".
1345: '<td align="left">'.
1346: '<a href="javascript:'.$act.';">'.$pic.'</a></td>
1347: <td class="LC_menubuttons_text" align="left"><a class="LC_menubuttons_link" href="javascript:'.$act.';"><span class="LC_menubuttons_inline_text">'.$text.'</span></a></td>';
1348: } else {
1349: $inlineremote[$idx]="\n<tr>".
1350: '<td align="left">'.
1351: '<a href="javascript:'.$act.';">'.$pic.
1352: '</a></td><td class="LC_menubuttons_text" colspan="3">'.
1353: '<a class="LC_menubuttons_link" href="javascript:'.$act.';"><span class="LC_menubuttons_inline_text">'.$desc.'</span></a></td></tr>';
1354: }
1355: } else {
1356: # Inline Menu
1357: if ($env{'environment.icons'} eq 'iconsonly') {
1358: $inlineremote[$idx]='<a title="'.$desc.'" href="javascript:'.$act.';">'.$pic.'</a>';
1359: } else {
1360: $inlineremote[$idx]=
1361: '<a title="'.$desc.'" class="LC_menubuttons_link" href="javascript:'.$act.';">'.$pic.
1362: '<span class="LC_menubuttons_inline_text">'.$desc.'</span></a>';
1363: }
1364: }
1365: }
1366: return '';
1367: }
1368:
1369: sub secondlevel {
1370: my $output='';
1371: my
1372: ($uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat)=@_;
1373: if ($prt eq 'any') {
1374: $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1375: } elsif ($prt=~/^r(\w+)/) {
1376: if ($rol eq $1) {
1377: $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1378: }
1379: }
1380: return $output;
1381: }
1382:
1383: sub openmenu {
1384: my $menuname = &get_menu_name();
1385: if ($env{'environment.remote'} eq 'off') { return ''; }
1386: my $nothing = &Apache::lonhtmlcommon::javascript_nothing();
1387: return "window.open(".$nothing.",'".$menuname."');";
1388: }
1389:
1390: sub inlinemenu {
1391: undef(@inlineremote);
1392: undef(%category_members);
1393: # calling rawconfig with "1" will evaluate mydesk.tab, even if there is no active remote control
1394: &rawconfig(1);
1395: my $output='<table><tr>';
1396: for (my $col=1; $col<=2; $col++) {
1397: $output.='<td class="LC_mainmenu_col_fieldset">';
1398: for (my $row=1; $row<=8; $row++) {
1399: foreach my $cat (keys(%category_members)) {
1400: if ($category_positions{$cat} ne "$col,$row") { next; }
1401: #$output.='<table><tr><td colspan="4" class="LC_menubuttons_category">'.&mt($category_names{$cat}).'</td></tr>';
1402: $output.='<div class="LC_Box LC_400Box">';
1403: $output.='<h3 class="LC_hcell">'.&mt($category_names{$cat}).'</h3>';
1404: $output.='<table>';
1405: my %active=();
1406: foreach my $menu_item (split(/\:/,$category_members{$cat})) {
1407: if ($inlineremote[$menu_item]) {
1408: $active{$menu_item}=1;
1409: }
1410: }
1411: foreach my $item (sort(keys(%active))) {
1412: $output.=$inlineremote[$item];
1413: }
1414: $output.='</table>';
1415: $output.='</div>';
1416: }
1417: }
1418: $output.="</td>";
1419: }
1420: $output.="</tr></table>";
1421: return $output;
1422: }
1423:
1424: sub rawconfig {
1425: #
1426: # This evaluates mydesk.tab
1427: # Need to add more positions and more privileges to deal with all
1428: # menu items.
1429: #
1430: my $textualoverride=shift;
1431: my $output='';
1432: unless ($env{'environment.remote'} eq 'off') {
1433: $output.=
1434: "window.status='Opening Remote Control';var swmenu=".&openmenu().
1435: "\nwindow.status='Configuring Remote Control ';";
1436: } else {
1437: unless ($textualoverride) { return ''; }
1438: }
1439: my $uname=$env{'user.name'};
1440: my $udom=$env{'user.domain'};
1441: my $adv=$env{'user.adv'};
1442: my $show_course=&Apache::loncommon::show_course();
1443: my $author=$env{'user.author'};
1444: my $crs='';
1445: my $crstype='';
1446: if ($env{'request.course.id'}) {
1447: $crs='/'.$env{'request.course.id'};
1448: if ($env{'request.course.sec'}) {
1449: $crs.='_'.$env{'request.course.sec'};
1450: }
1451: $crs=~s/\_/\//g;
1452: $crstype = &Apache::loncommon::course_type();
1453: }
1454: my $pub=($env{'request.state'} eq 'published');
1455: my $con=($env{'request.state'} eq 'construct');
1456: my $rol=$env{'request.role'};
1457: my $requested_domain = $env{'request.role.domain'};
1458: foreach my $line (@desklines) {
1459: my ($row,$col,$pro,$prt,$img,$top,$bot,$act,$desc,$cat)=split(/\:/,$line);
1460: $prt=~s/\$uname/$uname/g;
1461: $prt=~s/\$udom/$udom/g;
1462: if ($prt =~ /\$crs/) {
1463: next unless ($env{'request.course.id'});
1464: next if ($crstype eq 'Community');
1465: $prt=~s/\$crs/$crs/g;
1466: } elsif ($prt =~ /\$cmty/) {
1467: next unless ($env{'request.course.id'});
1468: next if ($crstype ne 'Community');
1469: $prt=~s/\$cmty/$crs/g;
1470: }
1471: $prt=~s/\$requested_domain/$requested_domain/g;
1472: if ($category_names{$cat}!~/\w/) { $cat='oth'; }
1473: if ($pro eq 'clear') {
1474: $output.=&clear($row,$col);
1475: } elsif ($pro eq 'any') {
1476: $output.=&secondlevel(
1477: $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
1478: } elsif ($pro eq 'smp') {
1479: unless ($adv) {
1480: $output.=&secondlevel(
1481: $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
1482: }
1483: } elsif ($pro eq 'adv') {
1484: if ($adv) {
1485: $output.=&secondlevel(
1486: $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
1487: }
1488: } elsif ($pro eq 'shc') {
1489: if ($show_course) {
1490: $output.=&secondlevel(
1491: $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
1492: }
1493: } elsif ($pro eq 'nsc') {
1494: if (!$show_course) {
1495: $output.=&secondlevel(
1496: $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
1497: }
1498: } elsif (($pro=~/^p(\w+)/) && ($prt)) {
1499: my $priv = $1;
1500: if ($priv =~ /^mdc(Course|Community)/) {
1501: if ($crstype eq $1) {
1502: $priv = 'mdc';
1503: } else {
1504: next;
1505: }
1506: }
1507: if (&Apache::lonnet::allowed($priv,$prt)) {
1508: $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1509: }
1510: } elsif ($pro eq 'course') {
1511: if (($env{'request.course.fn'}) && ($crstype ne 'Community')) {
1512: $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1513: }
1514: } elsif ($pro eq 'community') {
1515: if (($env{'request.course.fn'}) && ($crstype eq 'Community')) {
1516: $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1517: }
1518: } elsif ($pro =~ /^courseenv_(.*)$/) {
1519: my $key = $1;
1520: if ($crstype ne 'Community') {
1521: my $coursepref = $env{'course.'.$env{'request.course.id'}.'.'.$key};
1522: if ($key eq 'canuse_pdfforms') {
1523: if ($env{'request.course.id'} && $coursepref eq '') {
1524: my %domdefs = &Apache::lonnet::get_domain_defaults($env{'course.'.$env{'request.course.id'}.'.domain'});
1525: $coursepref = $domdefs{'canuse_pdfforms'};
1526: }
1527: }
1528: if ($coursepref) {
1529: $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1530: }
1531: }
1532: } elsif ($pro =~ /^communityenv_(.*)$/) {
1533: my $key = $1;
1534: if ($crstype eq 'Community') {
1535: my $coursepref = $env{'course.'.$env{'request.course.id'}.'.'.$key};
1536: if ($key eq 'canuse_pdfforms') {
1537: if ($env{'request.course.id'} && $coursepref eq '') {
1538: my %domdefs = &Apache::lonnet::get_domain_defaults($env{'course.'.$env{'request.course.id'}.'.domain'});
1539: $coursepref = $domdefs{'canuse_pdfforms'};
1540: }
1541: }
1542: if ($coursepref) {
1543: $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1544: }
1545: }
1546: } elsif ($pro =~ /^course_(.*)$/) {
1547: # Check for permissions inside of a course
1548: if (($env{'request.course.id'}) && ($crstype ne 'Community') &&
1549: (&Apache::lonnet::allowed($1,$env{'request.course.id'}.
1550: ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))
1551: )) {
1552: $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1553: }
1554: } elsif ($pro =~ /^community_(.*)$/) {
1555: # Check for permissions inside of a community
1556: if (($env{'request.course.id'}) && ($crstype eq 'Community') &&
1557: (&Apache::lonnet::allowed($1,$env{'request.course.id'}.
1558: ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))
1559: )) {
1560: $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1561: }
1562: } elsif ($pro eq 'author') {
1563: if ($author) {
1564: if ((($prt eq 'rca') && ($env{'request.role'}=~/^ca/)) ||
1565: (($prt eq 'raa') && ($env{'request.role'}=~/^aa/)) ||
1566: (($prt eq 'rau') && ($env{'request.role'}=~/^au/))) {
1567: # Check that we are on the correct machine
1568: my $cadom=$requested_domain;
1569: my $caname=$env{'user.name'};
1570: if (($prt eq 'rca') || ($prt eq 'raa')) {
1571: ($cadom,$caname)=
1572: ($env{'request.role'}=~/($match_domain)\/($match_username)$/);
1573: }
1574: $act =~ s/\$caname/$caname/g;
1575: my $home = &Apache::lonnet::homeserver($caname,$cadom);
1576: my $allowed=0;
1577: my @ids=&Apache::lonnet::current_machine_ids();
1578: foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
1579: if ($allowed) {
1580: $output.=&switch($caname,$cadom,
1581: $row,$col,$img,$top,$bot,$act,$desc,$cat);
1582: }
1583: }
1584: }
1585: } elsif ($pro eq 'tools') {
1586: my @tools = ('aboutme','blog','portfolio');
1587: if (grep(/^\Q$prt\E$/,@tools)) {
1588: if (!&Apache::lonnet::usertools_access($env{'user.name'},
1589: $env{'user.domain'},
1590: $prt,undef,'tools')) {
1591: $output.=&clear($row,$col);
1592: next;
1593: }
1594: } elsif (($prt eq 'reqcrsnsc') || ($prt eq 'reqcrsshc')) {
1595: if (($prt eq 'reqcrsnsc') && ($show_course)) {
1596: next;
1597: }
1598: if (($prt eq 'reqcrsshc') && (!$show_course)) {
1599: next;
1600: }
1601: my $showreqcrs = &check_for_rcrs();
1602: if (!$showreqcrs) {
1603: $output.=&clear($row,$col);
1604: next;
1605: }
1606: }
1607: $prt='any';
1608: $output.=&secondlevel(
1609: $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
1610: }
1611: }
1612: unless ($env{'environment.remote'} eq 'off') {
1613: $output.="\nwindow.status='Synchronizing Time';swmenu.syncclock(1000*".time.");\nwindow.status='Remote Control Configured.';";
1614: if (&Apache::lonmsg::newmail()) {
1615: $output.='swmenu.setstatus("you have","messages");';
1616: }
1617: }
1618:
1619: return $output;
1620: }
1621:
1622: sub check_for_rcrs {
1623: my $showreqcrs = 0;
1624: my @reqtypes = ('official','unofficial','community');
1625: foreach my $type (@reqtypes) {
1626: if (&Apache::lonnet::usertools_access($env{'user.name'},
1627: $env{'user.domain'},
1628: $type,undef,'requestcourses')) {
1629: $showreqcrs = 1;
1630: last;
1631: }
1632: }
1633: if (!$showreqcrs) {
1634: foreach my $type (@reqtypes) {
1635: if ($env{'environment.reqcrsotherdom.'.$type} ne '') {
1636: $showreqcrs = 1;
1637: last;
1638: }
1639: }
1640: }
1641: return $showreqcrs;
1642: }
1643:
1644: # ======================================================================= Close
1645:
1646: sub close {
1647: if ($env{'environment.remote'} eq 'off') { return ''; }
1648: my $menuname = &get_menu_name();
1649: return(<<ENDCLOSE);
1650: <script type="text/javascript">
1651: // <![CDATA[
1652: window.status='Accessing Remote Control';
1653: menu=window.open("/adm/rat/empty.html","$menuname",
1654: "height=350,width=150,scrollbars=no,menubar=no");
1655: window.status='Disabling Remote Control';
1656: menu.active=0;
1657: menu.autologout=0;
1658: window.status='Closing Remote Control';
1659: menu.close();
1660: window.status='Done.';
1661: // ]]>
1662: </script>
1663: ENDCLOSE
1664: }
1665:
1666: # ====================================================================== Footer
1667:
1668: sub footer {
1669:
1670: }
1671:
1672: sub nav_control_js {
1673: my $nav=($env{'environment.remotenavmap'} eq 'on');
1674: return (<<NAVCONTROL);
1675: var w_loncapanav_flag="$nav";
1676:
1677:
1678: function gonav(url) {
1679: if (w_loncapanav_flag != 1) {
1680: gopost(url,'');
1681: } else {
1682: navwindow=window.open(url,
1683: "loncapanav","height=600,width=400,scrollbars=1");
1684: }
1685: }
1686: NAVCONTROL
1687: }
1688:
1689: sub dc_popup_js {
1690: my %lt = &Apache::lonlocal::texthash(
1691: more => '(More ...)',
1692: less => '(Less ...)',
1693: );
1694: return <<"END";
1695:
1696: function showCourseID() {
1697: document.getElementById('dccid').style.display='block';
1698: document.getElementById('dccid').style.textAlign='left';
1699: document.getElementById('dccid').style.textFace='normal';
1700: document.getElementById('dccidtext').innerHTML ='<a href="javascript:hideCourseID();">$lt{'less'}</a>';
1701: return;
1702: }
1703:
1704: function hideCourseID() {
1705: document.getElementById('dccid').style.display='none';
1706: document.getElementById('dccidtext').innerHTML ='<a href="javascript:showCourseID()">$lt{'more'}</a>';
1707: return;
1708: }
1709:
1710: END
1711:
1712: }
1713:
1714: sub utilityfunctions {
1715: my $caller = shift;
1716: unless ($env{'environment.remote'} eq 'off' ||
1717: $caller eq '/adm/menu') {
1718: return ''; }
1719:
1720: my $currenturl=&Apache::lonnet::clutter(&Apache::lonnet::fixversion((split(/\?/,$env{'request.noversionuri'}))[0]));
1721: if ($currenturl =~ m{^/adm/wrapper/ext/}) {
1722: if ($env{'request.external.querystring'}) {
1723: $currenturl .= ($currenturl=~/\?/)?'&':'?'.$env{'request.external.querystring'};
1724: }
1725: }
1726: $currenturl=&Apache::lonenc::check_encrypt(&unescape($currenturl));
1727:
1728: my $currentsymb=&Apache::lonenc::check_encrypt($env{'request.symb'});
1729: my $nav_control=&nav_control_js();
1730:
1731: my $dc_popup_cid;
1732: if ($env{'user.adv'} && exists($env{'user.role.dc./'.
1733: $env{'course.'.$env{'request.course.id'}.
1734: '.domain'}.'/'})) {
1735: $dc_popup_cid = &dc_popup_js();
1736: }
1737:
1738: my $start_page_annotate =
1739: &Apache::loncommon::start_page('Annotator',undef,
1740: {'only_body' => 1,
1741: 'js_ready' => 1,
1742: 'bgcolor' => '#BBBBBB',
1743: 'add_entries' => {
1744: 'onload' => 'javascript:document.goannotate.submit();'}});
1745:
1746: my $end_page_annotate =
1747: &Apache::loncommon::end_page({'js_ready' => 1});
1748:
1749: my $start_page_bookmark =
1750: &Apache::loncommon::start_page('Bookmarks',undef,
1751: {'only_body' => 1,
1752: 'js_ready' => 1,
1753: 'bgcolor' => '#BBBBBB',});
1754:
1755: my $end_page_bookmark =
1756: &Apache::loncommon::end_page({'js_ready' => 1});
1757:
1758: return (<<ENDUTILITY)
1759:
1760: var currentURL="$currenturl";
1761: var reloadURL="$currenturl";
1762: var currentSymb="$currentsymb";
1763:
1764: $nav_control
1765: $dc_popup_cid
1766:
1767: function go(url) {
1768: if (url!='' && url!= null) {
1769: currentURL = null;
1770: currentSymb= null;
1771: window.location.href=url;
1772: }
1773: }
1774:
1775: function gotop(url) {
1776: if (url!='' && url!= null) {
1777: top.location.href = url;
1778: }
1779: }
1780:
1781: function gopost(url,postdata) {
1782: if (url!='') {
1783: this.document.server.action=url;
1784: this.document.server.postdata.value=postdata;
1785: this.document.server.command.value='';
1786: this.document.server.url.value='';
1787: this.document.server.symb.value='';
1788: this.document.server.submit();
1789: }
1790: }
1791:
1792: function gocmd(url,cmd) {
1793: if (url!='') {
1794: this.document.server.action=url;
1795: this.document.server.postdata.value='';
1796: this.document.server.command.value=cmd;
1797: this.document.server.url.value=currentURL;
1798: this.document.server.symb.value=currentSymb;
1799: this.document.server.submit();
1800: }
1801: }
1802:
1803: function gocstr(url,filename) {
1804: if (url == '/adm/cfile?action=delete') {
1805: this.document.cstrdelete.filename.value = filename
1806: this.document.cstrdelete.submit();
1807: return;
1808: }
1809: if (url == '/adm/printout') {
1810: this.document.cstrprint.postdata.value = filename
1811: this.document.cstrprint.curseed.value = 0;
1812: this.document.cstrprint.problemtype.value = 0;
1813: if (this.document.lonhomework) {
1814: if ((this.document.lonhomework.rndseed) && (this.document.lonhomework.rndseed.value != null) && (this.document.lonhomework.rndseed.value != '')) {
1815: this.document.cstrprint.curseed.value = this.document.lonhomework.rndseed.value
1816: }
1817: if (this.document.lonhomework.problemtype) {
1818: if (this.document.lonhomework.problemtype.value) {
1819: this.document.cstrprint.problemtype.value =
1820: this.document.lonhomework.problemtype.value;
1821: } else if (this.document.lonhomework.problemtype.options) {
1822: for (var i=0; i<this.document.lonhomework.problemtype.options.length; i++) {
1823: if (this.document.lonhomework.problemtype.options[i].selected) {
1824: if (this.document.lonhomework.problemtype.options[i].value != null && this.document.lonhomework.problemtype.options[i].value != '') {
1825: this.document.cstrprint.problemtype.value = this.document.lonhomework.problemtype.options[i].value
1826: }
1827: }
1828: }
1829: }
1830: }
1831: }
1832: this.document.cstrprint.submit();
1833: return;
1834: }
1835: if (url !='') {
1836: this.document.constspace.filename.value = filename;
1837: this.document.constspace.action = url;
1838: this.document.constspace.submit();
1839: }
1840: }
1841:
1842: function golist(url) {
1843: if (url!='' && url!= null) {
1844: currentURL = null;
1845: currentSymb= null;
1846: top.location.href=url;
1847: }
1848: }
1849:
1850:
1851:
1852: function catalog_info() {
1853: loncatinfo=window.open(window.location.pathname+'.meta',"LONcatInfo",'height=320,width=280,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
1854: }
1855:
1856: function chat_win() {
1857: lonchat=window.open('/res/adm/pages/chatroom.html',"LONchat",'height=320,width=480,resizable=yes,location=no,menubar=no,toolbar=no');
1858: }
1859:
1860: function group_chat(group) {
1861: var url = '/adm/groupchat?group='+group;
1862: var winName = 'LONchat_'+group;
1863: grpchat=window.open(url,winName,'height=320,width=280,resizable=yes,location=no,menubar=no,toolbar=no');
1864: }
1865:
1866: function edit_bookmarks() {
1867: go('');
1868: w_BookmarkPal_flag=1;
1869: bookmarkpal=window.open("/adm/bookmarks",
1870: "BookmarkPal", "width=400,height=505,scrollbars=0");
1871: }
1872:
1873: function annotate() {
1874: w_Annotator_flag=1;
1875: annotator=window.open('','Annotator','width=365,height=265,scrollbars=0');
1876: annotator.document.write(
1877: '$start_page_annotate'
1878: +"<form name='goannotate' target='Annotator' method='post' "
1879: +"action='/adm/annotations'>"
1880: +"<input type='hidden' name='symbnew' value='"+currentSymb+"' />"
1881: +"<\\/form>"
1882: +'$end_page_annotate');
1883: annotator.document.close();
1884: }
1885:
1886: function set_bookmark() {
1887: go('');
1888: clienttitle=document.title;
1889: clienthref=location.pathname;
1890: w_bmquery_flag=1;
1891: bmquery=window.open('','bmquery','width=365,height=165,scrollbars=0');
1892: bmquery.document.write(
1893: '$start_page_bookmark'
1894: +'<center><form method="post"'
1895: +' name="newlink" action="/adm/bookmarks" target="bmquery" '
1896: +'> <table width="340" height="150" '
1897: +'bgcolor="#FFFFFF" align="center"><tr><td>Link Name:<br /><input '
1898: +'type="text" name="title" size="45" value="'+clienttitle+'" />'
1899: +'<br />Address:<br /><input type="text" name="address" size="45" '
1900: +'value="'+clienthref+'" /><br /><center><input type="submit" '
1901: +'value="Save" /> <input type="button" value="Close" '
1902: +'onclick="javascript:window.close();" /></center></td>'
1903: +'</tr></table></form></center>'
1904: +'$end_page_bookmark' );
1905: bmquery.document.close();
1906: }
1907:
1908: ENDUTILITY
1909: }
1910:
1911: sub serverform {
1912: return(<<ENDSERVERFORM);
1913: <form name="server" action="/adm/logout" method="post" target="_top">
1914: <input type="hidden" name="postdata" value="none" />
1915: <input type="hidden" name="command" value="none" />
1916: <input type="hidden" name="url" value="none" />
1917: <input type="hidden" name="symb" value="none" />
1918: </form>
1919: ENDSERVERFORM
1920: }
1921:
1922: sub constspaceform {
1923: return(<<ENDCONSTSPACEFORM);
1924: <form name="constspace" action="/adm/logout" method="post" target="_top">
1925: <input type="hidden" name="filename" value="" />
1926: </form>
1927: <form name="cstrdelete" action="/adm/cfile" method="post" target="_top">
1928: <input type="hidden" name="action" value="delete" />
1929: <input type="hidden" name="filename" value="" />
1930: </form>
1931: <form name="cstrprint" action="/adm/printout" target="_parent" method="post">
1932: <input type="hidden" name="postdata" value="" />
1933: <input type="hidden" name="curseed" value="" />
1934: <input type="hidden" name="problemtype" value="" />
1935: </form>
1936:
1937: ENDCONSTSPACEFORM
1938: }
1939:
1940:
1941: sub get_nav_status {
1942: my $navstatus="swmenu.w_loncapanav_flag=";
1943: if ($env{'environment.remotenavmap'} eq 'on') {
1944: $navstatus.="1";
1945: } else {
1946: $navstatus.="-1";
1947: }
1948: return $navstatus;
1949: }
1950:
1951: sub hidden_button_check {
1952: my $hidden;
1953: if ($env{'request.course.id'} eq '') {
1954: return;
1955: }
1956: if ($env{'request.role.adv'}) {
1957: return;
1958: }
1959: my $buttonshide = &Apache::lonnet::EXT('resource.0.buttonshide');
1960: return $buttonshide;
1961: }
1962:
1963: sub roles_selector {
1964: my ($cdom,$cnum) = @_;
1965: my $crstype = &Apache::loncommon::course_type();
1966: my $now = time;
1967: my (%courseroles,%seccount);
1968: my $is_cc;
1969: my $role_selector;
1970: my $ccrole;
1971: if ($crstype eq 'Community') {
1972: $ccrole = 'co';
1973: } else {
1974: $ccrole = 'cc';
1975: }
1976: if ($env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum}) {
1977: my ($start,$end) = split(/\./,$env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum});
1978:
1979: if ((($start) && ($start<0)) ||
1980: (($end) && ($end<$now)) ||
1981: (($start) && ($now<$start))) {
1982: $is_cc = 0;
1983: } else {
1984: $is_cc = 1;
1985: }
1986: }
1987: if ($is_cc) {
1988: &get_all_courseroles($cdom,$cnum,\%courseroles,\%seccount);
1989: } else {
1990: my %gotnosection;
1991: foreach my $item (keys(%env)) {
1992: if ($item =~ m-^user\.role\.([^.]+)\./\Q$cdom\E/\Q$cnum\E/?(\w*)$-) {
1993: my $role = $1;
1994: my $sec = $2;
1995: next if ($role eq 'gr');
1996: my ($start,$end) = split(/\./,$env{$item});
1997: next if (($start && $start > $now) || ($end && $end < $now));
1998: if ($sec eq '') {
1999: if (!$gotnosection{$role}) {
2000: $seccount{$role} ++;
2001: $gotnosection{$role} = 1;
2002: }
2003: }
2004: if (ref($courseroles{$role}) eq 'ARRAY') {
2005: if ($sec ne '') {
2006: if (!grep(/^\Q$sec\E$/,@{$courseroles{$role}})) {
2007: push(@{$courseroles{$role}},$sec);
2008: $seccount{$role} ++;
2009: }
2010: }
2011: } else {
2012: @{$courseroles{$role}} = ();
2013: if ($sec ne '') {
2014: $seccount{$role} ++;
2015: push(@{$courseroles{$role}},$sec);
2016: }
2017: }
2018: }
2019: }
2020: }
2021: my $switchtext;
2022: if ($crstype eq 'Community') {
2023: $switchtext = &mt('Switch community role to...')
2024: } else {
2025: $switchtext = &mt('Switch course role to...')
2026: }
2027: my @roles_order = ($ccrole,'in','ta','ep','ad','st');
2028: if (keys(%courseroles) > 1) {
2029: $role_selector = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles);
2030: $role_selector .= '<form name="rolechooser" method="post" action="/adm/roles">
2031: <select name="switchrole" onchange="javascript:adhocRole('."'switchrole'".')">';
2032: $role_selector .= '<option value="">'.$switchtext.'</option>';
2033: foreach my $role (@roles_order) {
2034: if (defined($courseroles{$role})) {
2035: $role_selector .= "\n".'<option value="'.$role.'">'.&Apache::lonnet::plaintext($role,$crstype).'</option>';
2036: }
2037: }
2038: foreach my $role (sort(keys(%courseroles))) {
2039: if ($role =~ /^cr/) {
2040: $role_selector .= "\n".'<option value="'.$role.'">'.&Apache::lonnet::plaintext($role).'</option>';
2041: }
2042: }
2043: $role_selector .= '</select>'."\n".
2044: '<input type="hidden" name="destinationurl" value="'.
2045: &HTML::Entities::encode($ENV{'REQUEST_URI'}).'" />'."\n".
2046: '<input type="hidden" name="gotorole" value="1" />'."\n".
2047: '<input type="hidden" name="selectrole" value="" />'."\n".
2048: '<input type="hidden" name="switch" value="1" />'."\n".
2049: '</form>';
2050: }
2051: return $role_selector;
2052: }
2053:
2054: sub get_all_courseroles {
2055: my ($cdom,$cnum,$courseroles,$seccount) = @_;
2056: unless ((ref($courseroles) eq 'HASH') && (ref($seccount) eq 'HASH')) {
2057: return;
2058: }
2059: my ($result,$cached) =
2060: &Apache::lonnet::is_cached_new('getcourseroles',$cdom.'_'.$cnum);
2061: if (defined($cached)) {
2062: if (ref($result) eq 'HASH') {
2063: if ((ref($result->{'roles'}) eq 'HASH') &&
2064: (ref($result->{'seccount'}) eq 'HASH')) {
2065: %{$courseroles} = %{$result->{'roles'}};
2066: %{$seccount} = %{$result->{'seccount'}};
2067: return;
2068: }
2069: }
2070: }
2071: my %gotnosection;
2072: my %adv_roles =
2073: &Apache::lonnet::get_course_adv_roles($env{'request.course.id'},1);
2074: foreach my $role (keys(%adv_roles)) {
2075: my ($urole,$usec) = split(/:/,$role);
2076: if (!$gotnosection{$urole}) {
2077: $seccount->{$urole} ++;
2078: $gotnosection{$urole} = 1;
2079: }
2080: if (ref($courseroles->{$urole}) eq 'ARRAY') {
2081: if ($usec ne '') {
2082: if (!grep(/^Q$usec\E$/,@{$courseroles->{$urole}})) {
2083: push(@{$courseroles->{$urole}},$usec);
2084: $seccount->{$urole} ++;
2085: }
2086: }
2087: } else {
2088: @{$courseroles->{$urole}} = ();
2089: if ($usec ne '') {
2090: $seccount->{$urole} ++;
2091: push(@{$courseroles->{$urole}},$usec);
2092: }
2093: }
2094: }
2095: my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum,['st']);
2096: @{$courseroles->{'st'}} = ();
2097: if (keys(%sections_count) > 0) {
2098: push(@{$courseroles->{'st'}},keys(%sections_count));
2099: $seccount->{'st'} = scalar(keys(%sections_count));
2100: }
2101: my $rolehash = {
2102: 'roles' => $courseroles,
2103: 'seccount' => $seccount,
2104: };
2105: &Apache::lonnet::do_cache_new('getcourseroles',$cdom.'_'.$cnum,$rolehash);
2106: return;
2107: }
2108:
2109: sub jump_to_role {
2110: my ($cdom,$cnum,$seccount,$courseroles) = @_;
2111: my %lt = &Apache::lonlocal::texthash(
2112: this => 'This role has section(s) associated with it.',
2113: ente => 'Enter a specific section.',
2114: orlb => 'Enter a specific section, or leave blank for no section.',
2115: avai => 'Available sections are:',
2116: youe => 'You entered an invalid section choice:',
2117: plst => 'Please try again',
2118: );
2119: my $js;
2120: if (ref($courseroles) eq 'HASH') {
2121: $js = ' var secpick = new Array("'.$lt{'ente'}.'","'.$lt{'orlb'}.'");'."\n".
2122: ' var numsec = new Array();'."\n".
2123: ' var rolesections = new Array();'."\n".
2124: ' var rolenames = new Array();'."\n".
2125: ' var roleseclist = new Array();'."\n";
2126: my @items = keys(%{$courseroles});
2127: for (my $i=0; $i<@items; $i++) {
2128: $js .= ' rolenames['.$i.'] = "'.$items[$i].'";'."\n";
2129: my ($secs,$secstr);
2130: if (ref($courseroles->{$items[$i]}) eq 'ARRAY') {
2131: my @sections = sort { $a <=> $b } @{$courseroles->{$items[$i]}};
2132: $secs = join('","',@sections);
2133: $secstr = join(', ',@sections);
2134: }
2135: $js .= ' rolesections['.$i.'] = new Array("'.$secs.'");'."\n".
2136: ' roleseclist['.$i.'] = "'.$secstr.'";'."\n".
2137: ' numsec['.$i.'] = "'.$seccount->{$items[$i]}.'";'."\n";
2138: }
2139: }
2140: return <<"END";
2141: <script type="text/javascript">
2142: //<![CDATA[
2143: function adhocRole(roleitem) {
2144: $js
2145: var newrole = document.rolechooser.elements[roleitem].options[document.rolechooser.elements[roleitem].selectedIndex].value;
2146: if (newrole == '') {
2147: return;
2148: }
2149: var fullrole = newrole+'./$cdom/$cnum';
2150: var selidx = '';
2151: for (var i=0; i<rolenames.length; i++) {
2152: if (rolenames[i] == newrole) {
2153: selidx = i;
2154: }
2155: }
2156: var secok = 1;
2157: var secchoice = '';
2158: if (selidx >= 0) {
2159: if (numsec[selidx] > 1) {
2160: secok = 0;
2161: var numrolesec = rolesections[selidx].length;
2162: var msgidx = numsec[selidx] - numrolesec;
2163: secchoice = prompt("$lt{'this'}\\n"+secpick[msgidx]+"\\n$lt{'avai'} "+roleseclist[selidx],"");
2164: if (secchoice == '') {
2165: if (msgidx > 0) {
2166: secok = 1;
2167: }
2168: } else {
2169: for (var j=0; j<rolesections[selidx].length; j++) {
2170: if (rolesections[selidx][j] == secchoice) {
2171: secok = 1;
2172: }
2173: }
2174: }
2175: } else {
2176: if (rolesections[selidx].length == 1) {
2177: secchoice = rolesections[selidx][0];
2178: }
2179: }
2180: }
2181: if (secok == 1) {
2182: if (secchoice != '') {
2183: fullrole += '/'+secchoice;
2184: }
2185: } else {
2186: document.rolechooser.elements[roleitem].selectedIndex = 0;
2187: if (secchoice != null) {
2188: alert("$lt{'youe'} \\""+secchoice+"\\".\\n $lt{'plst'}");
2189: }
2190: return;
2191: }
2192: if (fullrole == "$env{'request.role'}") {
2193: return;
2194: }
2195: itemid = retrieveIndex('gotorole');
2196: if (itemid != -1) {
2197: document.rolechooser.elements[itemid].name = fullrole;
2198: }
2199: document.rolechooser.elements[roleitem].options[document.rolechooser.elements[roleitem].selectedIndex].value = fullrole;
2200: document.rolechooser.selectrole.value = '1';
2201: document.rolechooser.submit();
2202: return;
2203: }
2204:
2205: function retrieveIndex(item) {
2206: for (var i=0;i<document.rolechooser.elements.length;i++) {
2207: if (document.rolechooser.elements[i].name == item) {
2208: return i;
2209: }
2210: }
2211: return -1;
2212: }
2213: // ]]>
2214: </script>
2215: END
2216: }
2217:
2218:
2219: # ================================================================ Main Program
2220:
2221: BEGIN {
2222: if (! defined($readdesk)) {
2223: {
2224: my $tabfile = $Apache::lonnet::perlvar{'lonTabDir'}.'/mydesk.tab';
2225: if ( CORE::open( my $config,"<$tabfile") ) {
2226: while (my $configline=<$config>) {
2227: $configline=(split(/\#/,$configline))[0];
2228: $configline=~s/^\s+//;
2229: chomp($configline);
2230: if ($configline=~/^cat\:/) {
2231: my @entries=split(/\:/,$configline);
2232: $category_positions{$entries[2]}=$entries[1];
2233: $category_names{$entries[2]}=$entries[3];
2234: } elsif ($configline=~/^prim\:/) {
2235: my @entries = (split(/\:/, $configline))[1..5];
2236: push @primary_menu, \@entries;
2237: } elsif ($configline=~/^scnd\:/) {
2238: my @entries = (split(/\:/, $configline))[1..5];
2239: push @secondary_menu, \@entries;
2240: } elsif ($configline) {
2241: push(@desklines,$configline);
2242: }
2243: }
2244: CORE::close($config);
2245: }
2246: }
2247: $readdesk='done';
2248: }
2249: }
2250:
2251: 1;
2252: __END__
2253:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>