Index: SrvTxtUtils.py
===================================================================
--- SrvTxtUtils.py	(revision 514)
+++ SrvTxtUtils.py	(revision 528)
@@ -12,5 +12,5 @@
 
 
-srvTxtUtilsVersion = "1.4"
+srvTxtUtilsVersion = "1.4.1"
 
 def getInt(number, default=0):
@@ -38,5 +38,5 @@
             return s.decode('latin-1')
     else:
-        return s
+        return unicode(s)
 
 def utf8ify(s):
@@ -48,5 +48,5 @@
         return s
     else:
-        return s.encode('utf-8')
+        return unicode(s).encode('utf-8')
 
 def getText(node, recursive=0):
Index: css/docuviewer.css
===================================================================
--- css/docuviewer.css	(revision 526)
+++ css/docuviewer.css	(revision 528)
@@ -29,12 +29,12 @@
 }
 
-div.toc-thumbs .thumb {
+table.thumbs .thumb {
     padding: 3px;
 }
-div.toc-thumbs .thumbsel {
+table.thumbs .thumbsel {
     padding: 2px;
     border: 1px solid blue;
 }
-div.toc-thumbs .thumbcap {
+table.thumbs .thumbcap {
     color: black;
 }
Index: documentViewer.py
===================================================================
--- documentViewer.py	(revision 526)
+++ documentViewer.py	(revision 528)
@@ -124,4 +124,5 @@
     viewer_images = PageTemplateFile('zpt/viewer_images', globals())
     viewer_index = PageTemplateFile('zpt/viewer_index', globals())
+    viewer_thumbs = PageTemplateFile('zpt/viewer_thumbs', globals())
     # available layer types
     builtinLayers = {'text': ['dict','search','gis','annotator'],
@@ -462,4 +463,12 @@
         return pt(docinfo=docinfo)
 
+    def getAuthenticatedUser(self, anon=None):
+        """returns the authenticated user object or None. (ignores Zopes anonymous user)"""
+        user = getSecurityManager().getUser()
+        if user is not None and user.getUserName() != "Anonymous User":
+            return user
+        else:
+            return anon
+
     def isAccessible(self, docinfo):
         """returns if access to the resource is granted"""
@@ -472,15 +481,10 @@
         elif access is None or access in self.authgroups:
             # only local access -- only logged in users
-            user = getSecurityManager().getUser()
+            user = self.getAuthenticatedUser()
             logging.debug("documentViewer (accessOK) user=%s ip=%s"%(user,self.REQUEST.getClientAddr()))
-            if user is not None:
-                #print "user: ", user
-                return (user.getUserName() != "Anonymous User")
-            else:
-                return False
+            return (user is not None)
         
         logging.error("documentViewer (accessOK) unknown access type %s"%access)
         return False
-    
 
 
Index: zpt/common_template.zpt
===================================================================
--- zpt/common_template.zpt	(revision 527)
+++ zpt/common_template.zpt	(revision 528)
@@ -8,19 +8,22 @@
   <!-- block used for page header content area -->
   <metal:block metal:define-macro="head"
-    tal:define="docpath docinfo/textURLPath | nothing;
-               query here/REQUEST/query | nothing;
-               queryType here/REQUEST/queryType | nothing;
-               bib docinfo/bib | nothing; bibType docinfo/bibType | nothing;
-               formattedLabel python:here.metadataService.getBibFormattedLabel(bibdata=bib);">
+    tal:define="viewMode pageinfo/viewMode;
+                docpath docinfo/textURLPath | nothing;
+                bib docinfo/bib | nothing; bibType docinfo/bibType | nothing;
+                formattedLabel python:here.metadataService.getBibFormattedLabel(bibdata=bib);">
     <div tal:condition="not:formattedLabel">
-      <tal:block tal:condition="python:docinfo['creator'] or docinfo['title']"><i tal:content="docinfo/creator"/>,
-        <span tal:content="docinfo/title"/>, <span tal:content="docinfo/date"/>
+      <tal:block tal:condition="python:docinfo['creator'] or docinfo['title']">
+        <i tal:content="docinfo/creator" />,
+        <span tal:content="docinfo/title" />, <span tal:content="docinfo/date" />
       </tal:block>
       <span tal:condition="not:python:docinfo['creator'] or docinfo['title']"
-      tal:content="string:[no bibliographical information for this document (type ${bibType})]" />
+        tal:content="string:[no bibliographical information for this document (type ${bibType})]" />
     </div>
     <div tal:condition="formattedLabel" tal:content="structure formattedLabel" />
     <div class="doclinks">
-      <a tal:attributes="href python:here.getLink('viewMode','index')">Bibliographical information</a>
+      <a tal:condition="python:viewMode!='index'" tal:attributes="href python:here.getLink('viewMode','index')">Bibliographical
+        information</a>
+      <a tal:condition="python:viewMode!='text'" tal:attributes="href python:here.getLink('viewMode','text')">Page view</a>
+      <a tal:condition="python:viewMode!='thumbs'" tal:attributes="href python:here.getLink('viewMode','thumbs')">Thumbnail overview</a>
     </div>
   </metal:block>
@@ -35,16 +38,24 @@
               leftest python:test(flowLtr,first,last); rightest python:test(flowLtr,last,first);">
     <form class="autosubmit" tal:attributes="action viewerUrl">
-      <input type="hidden" tal:define="params python:here.getParams('pn', None)" tal:repeat="param params"
-        tal:attributes="name param; value python:params[param]" /> page <a tal:condition="leftest"
-        tal:attributes="href python:here.getLink('pn',leftest)">|&lt;</a> <span tal:condition="not:leftest">|&lt;</span> <a
-        tal:condition="left" tal:attributes="href python:here.getLink('pn',left)">&lt;</a> <span tal:condition="not:left">&lt;</span>
-      <input class="autosubmit" size="3" type="text" name="pn" tal:attributes="value pn" /> <span class="originalPage"
-        title="Original page number" tal:define="originalPage pageinfo/pageNumberOrig | nothing"
-        tal:condition="python:originalPage!=None"> (<span tal:replace="originalPage" /><span
-        tal:define="originalPageNorm pageinfo/pageNumberOrigNorm | nothing" tal:condition="python:originalPageNorm!=None"> [<span
-          tal:replace="originalPageNorm" />]</span>)
-      </span> <input type="submit" value="Go" /> of <span tal:replace="numPages" /> <a tal:condition="right"
-        tal:attributes="href python:here.getLink('pn',right)">&gt;</a> <span tal:condition="not:right">&gt;</span> <a
-        tal:condition="rightest" tal:attributes="href python:here.getLink('pn',rightest)">&gt;|</a> <span
+      <input type="hidden" tal:define="params python:here.getParams('pn', None)"
+        tal:repeat="param params" tal:attributes="name param; value python:params[param]" />
+      page <a tal:condition="leftest"
+        tal:attributes="href python:here.getLink('pn',leftest)">|&lt;</a> <span
+        tal:condition="not:leftest">|&lt;</span> <a tal:condition="left"
+        tal:attributes="href python:here.getLink('pn',left)">&lt;</a> <span
+        tal:condition="not:left">&lt;</span> <input class="autosubmit" size="3"
+        type="text" name="pn" tal:attributes="value pn" /> <span class="originalPage"
+        title="Original page number"
+        tal:define="originalPage pageinfo/pageNumberOrig | nothing"
+        tal:condition="python:originalPage!=None"> (<span
+        tal:replace="originalPage" /><span
+        tal:define="originalPageNorm pageinfo/pageNumberOrigNorm | nothing"
+        tal:condition="python:originalPageNorm!=None"> [<span
+          tal:replace="originalPageNorm" />]
+      </span>)
+      </span> <input type="submit" value="Go" /> of <span tal:replace="numPages" /> <a
+        tal:condition="right" tal:attributes="href python:here.getLink('pn',right)">&gt;</a>
+      <span tal:condition="not:right">&gt;</span> <a tal:condition="rightest"
+        tal:attributes="href python:here.getLink('pn',rightest)">&gt;|</a> <span
         tal:condition="not:rightest">&gt;|</span>
     </form>
@@ -52,15 +63,42 @@
   <!-- /ruler -->
 
-  <!-- toc ruler with previous/next toc page buttons -->
+  <!-- toc ruler (using getBatch) with previous/next toc page buttons -->
   <metal:block metal:define-macro="toc_ruler">
-    <form class="autosubmit" tal:attributes="action viewerUrl" tal:define="startParam startParam | string:start">
-      <input type="hidden" tal:define="params python:here.getParams(startParam, None)" tal:repeat="param params"
-        tal:attributes="name param; value python:params[param]" /> <a tal:condition="batch/prevStart"
-        tal:attributes="href python:here.getLink(startParam,batch['prevStart'])">&lt;</a> <span tal:condition="not:batch/prevStart">&lt;</span>
+    <form class="autosubmit" tal:attributes="action viewerUrl"
+      tal:define="startParam startParam | string:start">
+      <input type="hidden" tal:define="params python:here.getParams(startParam, None)"
+        tal:repeat="param params" tal:attributes="name param; value python:params[param]" />
+      <a tal:condition="batch/prevStart"
+        tal:attributes="href python:here.getLink(startParam,batch['prevStart'])">&lt;</a>
+      <span tal:condition="not:batch/prevStart">&lt;</span>
       <select class="autosubmit" tal:attributes="name startParam">
-        <option tal:repeat="grp batch/batches" tal:attributes="selected python:(start==grp['start']); value grp/start"
+        <option tal:repeat="grp batch/batches"
+          tal:attributes="selected python:(start==grp['start']); value grp/start"
           tal:content="string:${grp/start} - ${grp/end}" />
-      </select> <input type="submit" value="Go" /> <a tal:condition="batch/nextStart"
-        tal:attributes="href python:here.getLink(startParam,batch['nextStart'])">&gt;</a> <span tal:condition="not:batch/nextStart">&gt;</span>
+      </select>
+      <input type="submit" value="Go" /> <a tal:condition="batch/nextStart"
+        tal:attributes="href python:here.getLink(startParam,batch['nextStart'])">&gt;</a>
+      <span tal:condition="not:batch/nextStart">&gt;</span>
+    </form>
+  </metal:block>
+
+  <!-- toc ruler for thumbs (using getPageBatch) with previous/next toc page buttons -->
+  <metal:block metal:define-macro="toc_ruler_thumbs">
+    <form class="autosubmit" tal:attributes="action viewerUrl">
+      <input type="hidden" tal:define="params python:here.getParams('start',None)"
+        tal:repeat="param params" tal:attributes="name param; value python:params[param]" />
+      <a tal:condition="left" tal:attributes="href python:here.getLink('start',left)">&lt;</a>
+      <span tal:condition="not:left">&lt;</span>
+      <select class="autosubmit" name="start"
+        tal:define="ofs python:test(pageinfo['pageZero'],0,1)">
+        <tal:block>
+          <option tal:repeat="grp pageBatch/batches"
+            tal:attributes="selected python:start==grp['start']; value grp/start;"
+            tal:content="string:${grp/start} - ${grp/end}" />
+        </tal:block>
+      </select>
+      <input type="submit" value="Go" /> <a tal:condition="right"
+        tal:attributes="href python:here.getLink('start',right)">&gt;</a> <span
+        tal:condition="not:right">&gt;</span>
     </form>
   </metal:block>
@@ -69,6 +107,6 @@
   <metal:block metal:define-macro="toc_switcher">
     <ul class="switcher">
-      <li tal:attributes="class python:test(tocMode=='thumbs', 'sel', None)"><a
-        tal:attributes="href python:here.getLink('tocMode','thumbs')">Thumbnails</a>
+      <li tal:attributes="class python:test(tocMode=='thumbs', 'sel', None)">
+        <a tal:attributes="href python:here.getLink('tocMode','thumbs')">Thumbnails</a>
       </li>
       <li tal:attributes="class python:test(tocMode=='text', 'sel', None)"
@@ -78,14 +116,12 @@
       <li tal:attributes="class python:test(tocMode=='figures', 'sel', None)"
         tal:condition="python:docpath and docinfo.get('numFigureEntries', None)">
-        <a
-        tal:attributes="href python:here.getLink('tocMode','figures')">Figures</a>
+        <a tal:attributes="href python:here.getLink('tocMode','figures')">Figures</a>
       </li>
       <li tal:attributes="class python:test(tocMode=='concordance', 'sel', None)"
         tal:condition="python:docpath and docinfo.get('pageNumbers', None)">
-        <a
-        tal:attributes="href python:here.getLink('tocMode','concordance')">Concordance</a>
+        <a tal:attributes="href python:here.getLink('tocMode','concordance')">Concordance</a>
       </li>
-      <li tal:attributes="class python:test(tocMode=='none', 'sel', None)"><a
-        tal:attributes="href python:here.getLink('tocMode','none')">None</a>
+      <li tal:attributes="class python:test(tocMode=='none', 'sel', None)">
+        <a tal:attributes="href python:here.getLink('tocMode','none')">None</a>
       </li>
     </ul>
Index: zpt/layer_text_annotator.zpt
===================================================================
--- zpt/layer_text_annotator.zpt	(revision 527)
+++ zpt/layer_text_annotator.zpt	(revision 528)
@@ -24,12 +24,16 @@
   <script
     tal:attributes="src string:$rootUrl/template/annotator_files/lib/plugin/permissions.js"></script>
-  <script
-    tal:attributes="src string:$rootUrl/template/annotator_files/lib/plugin/annotateitpermissions.js"></script>
+  <!-- <script
+    tal:attributes="src string:$rootUrl/template/annotator_files/lib/plugin/annotateitpermissions.js"></script> -->
   <script tal:attributes="src string:$rootUrl/template/annotator_files/lib/plugin/auth.js"></script>
-  <script tal:attributes="src string:$rootUrl/template/annotator_files/lib/plugin/tags.js"></script>
+  <!-- <script tal:attributes="src string:$rootUrl/template/annotator_files/lib/plugin/tags.js"></script> -->
   <script
     tal:attributes="src string:$rootUrl/template/annotator_files/lib/plugin/unsupported.js"></script>
-  <script
-    tal:attributes="src string:$rootUrl/template/annotator_files/lib/plugin/filter.js"></script>
+  <!-- <script
+    tal:attributes="src string:$rootUrl/template/annotator_files/lib/plugin/filter.js"></script> -->
+
+  <script type="text/javascript" 
+    tal:define="annUrl python:'%s?url=%s&pn=%s'%(rootUrl,docinfo['url'],pageinfo['pn']); annUser python:here.getAuthenticatedUser(anon='anonymous');"
+    tal:content="structure string:var annotatorPageUrl='$annUrl'; var annotatorUser='$annUser';"></script>
 
   <script type="text/javascript">
@@ -38,11 +42,9 @@
                 // annotator
                 var elem = $('div.pageContent').get(0);
-                var uri = window.location.href.split(/#|\?/).shift();
+                var uri = annotatorPageUrl;
                 var devAnnotator = new Annotator(elem).addPlugin('Auth', {
-                    //tokenUrl: 'http://annotateit.org/api/token'
-                    tokenUrl : 'template/token?user=anonymous'
-                //autoFetch: false
+                    tokenUrl : 'template/token?user='+annotatorUser
                 }).addPlugin('Permissions', {
-                    user : 'anonymous',
+                    user : annotatorUser,
                     userString : function(user) {
                         if (user && user.name) {
@@ -58,7 +60,5 @@
                     }
                 }).addPlugin('Store', {
-                    //prefix : 'http://localhost:18080/AnnotationManager/annotator',
                     prefix: 'http://virtuoso.mpiwg-berlin.mpg.de:8080/AnnotationManager/annotator',
-                    //prefix: 'http://annotateit.org/api',
                     annotationData : {
                         'uri' : uri
@@ -67,5 +67,4 @@
                         'limit' : 20,
                         'uri' : uri
-                    //'uri': 'http://127.0.0.1:18080/ECHOdocuViewfullTest?pn=21&url=/mpiwg/online/permanent/library/163127KK'
                     }
                 });
@@ -90,7 +89,7 @@
   <metal:block metal:define-macro="options_box" tal:condition="python:'annotator' in viewLayers">
     <!-- BEGIN ANNOTATIONS -->
-    <div class="options">
+    <div class="options" tal:define="annUser python:here.getAuthenticatedUser(anon='anonymous')">
       <h4>Annotations</h4>
-      <div>nothing to be seen here...</div>
+      <div>You are user "<span tal:replace="annUser"/>"</div>
     </div>
     <!-- END ANNOTATIONS -->
Index: zpt/toc_thumbs.zpt
===================================================================
--- zpt/toc_thumbs.zpt	(revision 526)
+++ zpt/toc_thumbs.zpt	(revision 528)
@@ -19,22 +19,5 @@
     <div class="content">
       <div class="ruler">
-        <form class="autosubmit" tal:attributes="action viewerUrl">
-          <input type="hidden" tal:define="params python:here.getParams('start',None)"
-            tal:repeat="param params"
-            tal:attributes="name param; value python:params[param]" /> 
-          <a tal:condition="left" tal:attributes="href python:here.getLink('start',left)">&lt;</a>
-          <span tal:condition="not:left">&lt;</span>
-          <select class="autosubmit" name="start"
-            tal:define="ofs python:test(pageinfo['pageZero'],0,1)">
-            <tal:block >
-              <option tal:repeat="grp pageBatch/batches"
-                tal:attributes="selected python:start==grp['start']; value grp/start;"
-                tal:content="string:${grp/start} - ${grp/end}" />
-            </tal:block>
-          </select>
-          <input type="submit" value="Go" /> 
-          <a tal:condition="right" tal:attributes="href python:here.getLink('start',right)">&gt;</a>
-          <span tal:condition="not:right">&gt;</span>
-        </form>
+        <metal:block metal:use-macro="here/template/common_template/macros/toc_ruler_thumbs"/>
       </div>
 
Index: zpt/viewer_thumbs.zpt
===================================================================
--- zpt/viewer_thumbs.zpt	(revision 528)
+++ zpt/viewer_thumbs.zpt	(revision 528)
@@ -0,0 +1,116 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+  tal:define="docinfo options/docinfo; pageinfo options/pageinfo; viewMode pageinfo/viewMode;
+              viewerUrl docinfo/viewerUrl;
+              rootUrl here/getDocumentViewerURL;
+              numPages docinfo/numPages | nothing;">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title tal:content="python:docinfo.get('creator',' ') + ' - ' + docinfo.get('title',' ')" />
+<link rel="stylesheet" href="template/docuviewer_css" type="text/css" />
+<script type="text/javascript" tal:attributes="src string:$rootUrl/template/jquery_js"></script>
+<script type="text/javascript">
+    // <!--
+    $(document).ready(function() {
+        // autosubmit forms
+        $('form.autosubmit').find('.autosubmit').change(function() {
+            this.form.submit();
+        });
+        $('form.autosubmit input[type="submit"]').hide();
+    });
+// -->
+</script>
+</head>
+<body tal:condition="numPages">
+  <tal:block
+    tal:define="pn pageinfo/pn;
+                start pageinfo/start;
+                thumbRows python:int(request.get('thumbRows', 10));
+                thumbCols python:int(request.get('thumbCols', 12));
+                thumbSize python:int(request.get('thumbSize', 100));
+                flowLtr python:docinfo.get('pageFlow','ltr')!='rtl';
+                pageBatch python:here.getPageBatch(start=start, rows=thumbRows, cols=thumbCols, pageFlowLtr=flowLtr, maxIdx=numPages);
+                pageNumbers docinfo/pageNumbers | nothing;
+                left python:test(flowLtr,pageBatch['prevStart'],pageBatch['nextStart']);
+                right python:test(flowLtr,pageBatch['nextStart'],pageBatch['prevStart']);">
+    <div class="page-head">
+      <metal:block metal:use-macro="here/template/common_template/macros/head" />
+    </div>
+    <div class="page-body" tal:condition="python:here.isAccessible(docinfo)">
+      <!-- col-main: text page -->
+      <div class="col main">
+        <div class="ruler">
+          <metal:block
+            metal:use-macro="here/template/common_template/macros/toc_ruler_thumbs" />
+        </div>
+
+        <table class="thumbs">
+          <tr tal:repeat="row pageBatch/pages">
+            <td tal:repeat="thumb row"
+              tal:attributes="class python:here.getStyle(thumb['idx'],pn,'thumb')">
+              <a tal:define="idx thumb/idx" tal:condition="idx"
+                tal:attributes="href python:here.getLink(params={'pn':idx, 'viewMode':'images'})"> <img
+                tal:attributes="src python:test(docinfo['imageURL'],here.getScalerUrl(pn=idx,dw=thumbSize,dh=thumbSize,docinfo=docinfo),'images/pic');
+                                alt idx" /><br />
+                <span title="Scan number" tal:content="idx" /> <span
+                tal:condition="python:pageNumbers and pageNumbers.get(idx, False) and pageNumbers[idx]['no']"
+                title="Original page number"
+                tal:content="python:' (%s)'%(pageNumbers[idx]['no'])" />
+              </a>
+            </td>
+          </tr>
+        </table>
+
+        <div class="ruler">
+          <metal:block
+            metal:use-macro="here/template/common_template/macros/toc_ruler_thumbs" />
+        </div>
+
+      </div>
+      <!-- /col-main -->
+
+      <!-- right-side options -->
+      <div class="col buttons">
+        <!--"BEGIN TEXT DISPLAY"  -->
+        <div class="options">
+          <h4>Thumbnail display</h4>
+          <form tal:attributes="action viewerUrl" class="autosubmit">
+            <input type="hidden"
+              tal:define="params python:here.getParams(params={'thumbRows':None,'thumbCols':None,'thumbSize':None})"
+              tal:repeat="param params"
+              tal:attributes="name param; value python:params[param]" />
+            <ul>
+              <li>
+                Rows 
+                <select class="autosubmit" name="thumbRows" tal:define="rows python:[2,3,5,10,12,15,20,50,100]">
+                  <option tal:repeat="row rows" tal:attributes="selected python:thumbRows==row; value row" tal:content="row"/>
+                </select>
+              </li>
+              <li>
+                Columns 
+                <select class="autosubmit" name="thumbCols" tal:define="cols python:[2,3,5,10,12,15,20,50,100]">
+                  <option tal:repeat="col cols" tal:attributes="selected python:thumbCols==col; value col" tal:content="col"/>
+                </select>
+              </li>
+              <li>
+                Thumbnail size 
+                <select class="autosubmit" name="thumbSize" tal:define="sizes python:[100,150,200,300,500]">
+                  <option tal:repeat="size sizes" tal:attributes="selected python:thumbSize==size; value size" tal:content="size"/>
+                </select>
+              </li>
+            </ul>
+          </form>
+        </div>
+      </div>
+    </div>
+    <!-- page-body -->
+    <div class="page-body" tal:condition="python:not here.isAccessible(docinfo)">
+      <div class="errortext">Sorry, access to this document is restricted.</div>
+    </div>
+  </tal:block>
+</body>
+<body tal:condition="not:numPages">
+  <div class="errortext">Sorry, document doesn't exist.</div>
+</body>
+</html>
