00001
00002 """
00003 MoinMoin - Navigation Macro
00004
00005 @copyright: 2003 by Jürgen Hermann <jh@web.de>
00006 @license: GNU GPL, see COPYING for details.
00007 """
00008
00009 import re
00010 from MoinMoin import config
00011 from MoinMoin.Page import Page
00012
00013 Dependencies = ["namespace"]
00014
00015
00016
00017 def _getParent(pagename):
00018 """ Return parent of pagename.
00019 """
00020 pos = pagename.rfind('/')
00021 if pos >= 0:
00022 return pagename[:pos]
00023 return None
00024
00025
00026 def _getPages(request, filter_regex=None):
00027 """ Return a (filtered) list of pages names.
00028 """
00029 filter = None
00030 if filter_regex:
00031 filter = re.compile(filter_regex).match
00032 pages = request.rootpage.getPageList(filter=filter)
00033 pages.sort()
00034 return pages
00035
00036
00037 def _getLinks(request, pagename, filter_regex=None):
00038 """ Return pagename for up, first, prev, next, last; each can be None.
00039 """
00040 pos, size, first, prev, next, last = 0, 0, None, None, None, None
00041
00042 all_pages = _getPages(request, filter_regex)
00043 size = len(all_pages)
00044
00045 if all_pages:
00046 try:
00047 pos = all_pages.index(pagename)
00048 except ValueError:
00049
00050 pass
00051 else:
00052 if pos > 0:
00053 first = all_pages[0]
00054 prev = all_pages[pos-1]
00055 if pos+1 < len(all_pages):
00056 next = all_pages[pos+1]
00057 last = all_pages[-1]
00058
00059 return pos, size, (first, prev, next, last)
00060
00061
00062 class Navigation:
00063 """ Dispatcher class implementing the navigation schemes.
00064 """
00065
00066
00067 PROJECTION = 'action=print&media=projection'
00068
00069 def __init__(self, macro, args):
00070 """ Prepare common values used during processing.
00071 """
00072 self.macro = macro
00073 self.args = args.split(',')
00074 self._ = self.macro.request.getText
00075
00076 self.pagename = self.macro.formatter.page.page_name
00077 self.print_mode = self.macro.request.form.has_key('action') \
00078 and self.macro.request.form['action'][0] == 'print'
00079 self.media = self.macro.request.form.get('media', [None])[0]
00080 self.querystr = self.print_mode and self.PROJECTION or ''
00081
00082
00083 def dispatch(self):
00084 """ Return None if in plain print mode (no navigational
00085 elements in printouts), else the proper HTML code.
00086 """
00087 if self.print_mode and self.media != 'projection':
00088 return None
00089
00090 scheme = self.args[0] or '<default>'
00091 return getattr(self, 'do_'+scheme, self.badscheme)()
00092
00093
00094 def badscheme(self):
00095 """ Bad scheme argument.
00096 """
00097 _ = self._
00098 scheme = self.args[0]
00099 return (self.macro.formatter.sysmsg(1) +
00100 self.macro.formatter.text(
00101 _("Unsupported navigation scheme '%(scheme)s'!") %
00102 {'scheme': scheme}) +
00103 self.macro.formatter.sysmsg(0))
00104
00105
00106 def do_children(self):
00107 """ Navigate to subpages from a parent page.
00108 """
00109
00110 return self.do_siblings(root=self.pagename)
00111
00112
00113 def do_siblings(self, root=None):
00114 """ Navigate from a subpage to its siblings.
00115 """
00116 _ = self._
00117
00118 parent = root or _getParent(self.pagename)
00119 if not parent:
00120 return (self.macro.formatter.sysmsg(1) +
00121 self.macro.formatter.text(_('No parent page found!'))+
00122 self.macro.formatter.sysmsg(0))
00123
00124 try:
00125 depth = int(self.args[1])
00126 except (IndexError, TypeError, ValueError):
00127 depth = 0
00128
00129
00130 result = []
00131 children = _getPages(self.macro.request, '^%s/' % parent)
00132 for child in children:
00133
00134
00135 shortname = child[len(parent):]
00136
00137
00138 if depth and shortname.count('/') > depth:
00139 continue
00140
00141 if child == self.pagename:
00142
00143 result.append(self.macro.formatter.text(shortname))
00144 else:
00145
00146 result.append(Page(self.macro.request, child).link_to(self.macro.request, text=shortname, querystr=self.querystr))
00147 result.append(' ')
00148
00149 return ''.join(result)
00150
00151
00152 def do_slideshow(self, focus=None):
00153 """ Slideshow master page links.
00154
00155 If `focus` is set, it is the name of a slide page; these only
00156 get the mode toggle and edit links.
00157 """
00158 _ = self._
00159 curpage = focus or self.pagename
00160 result = []
00161
00162 if self.print_mode:
00163
00164 label = _('Wiki')
00165 toggle = ''
00166 result.append(Page(self.macro.request, curpage).link_to(self.macro.request, text=_('Edit'), querystr='action=edit'))
00167 result.append(' ')
00168 else:
00169
00170 label = _('Slideshow')
00171 toggle = self.PROJECTION
00172
00173
00174 result.append(Page(self.macro.request, curpage).link_to(self.macro.request, text=label, querystr=toggle))
00175
00176
00177 if focus is None:
00178 children = _getPages(self.macro.request, '^%s/' % self.pagename)
00179 if children:
00180
00181 result.append(' ')
00182 result.append(Page(self.macro.request, children[0]).link_to(self.macro.request, text=_('Start'), querystr=self.querystr))
00183
00184 return ''.join(result)
00185
00186
00187 def do_slides(self, root=None):
00188 """ Navigate within a slide show.
00189 """
00190 _ = self._
00191 parent = root or _getParent(self.pagename)
00192 if not parent:
00193 return (self.macro.formatter.sysmsg(1) +
00194 self.macro.formatter.text(_('No parent page found!')) +
00195 self.macro.formatter.sysmsg(0))
00196
00197
00198 result = []
00199 labels = ['^', '|<', '<<', '>>', '>|']
00200 filter_regex = '^%s/' % re.escape(parent)
00201 pos, size, links = _getLinks(self.macro.request, self.pagename, filter_regex)
00202 pos += 1
00203 links = zip(labels, (parent,) + links)
00204
00205
00206 for label, name in links:
00207 result.append(' ')
00208 if name:
00209
00210 result.append(Page(self.macro.request, name).link_to(self.macro.request, text=label, querystr=self.querystr))
00211 else:
00212
00213 result.append(self.macro.formatter.text(label))
00214 result.append(' ')
00215
00216
00217 if label == labels[2]:
00218 result.append(_('Slide %(pos)d of %(size)d') % {'pos': pos, 'size': size})
00219
00220 return self.do_slideshow(focus=self.pagename) + ''.join(result)
00221
00222
00223 def execute(macro, args):
00224
00225 navi = Navigation(macro, args or '').dispatch()
00226
00227 if navi:
00228
00229 return '<table class="navigation"><tr><td>%s</td></tr></table>' % navi
00230
00231
00232 return ''
00233