Index: /main/waeup.kofa/trunk/CHANGES.txt
===================================================================
--- /main/waeup.kofa/trunk/CHANGES.txt	(revision 13935)
+++ /main/waeup.kofa/trunk/CHANGES.txt	(revision 13936)
@@ -4,4 +4,6 @@
 1.4.2.dev0 (unreleased)
 =======================
+
+* Add file upload functionality to `EditScoresPage`.
 
 * Add `LecturerLandingPage` and `LecturerCourses` `ManageLink`
Index: /main/waeup.kofa/trunk/layout/static/css/base.css
===================================================================
--- /main/waeup.kofa/trunk/layout/static/css/base.css	(revision 13935)
+++ /main/waeup.kofa/trunk/layout/static/css/base.css	(revision 13936)
@@ -143,5 +143,4 @@
 input.btn {
     padding: 6px 12px;
-    margin-right: 4px;
 }
 
Index: /main/waeup.kofa/trunk/src/waeup/kofa/browser/templates/fileupload.pt
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/browser/templates/fileupload.pt	(revision 13935)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/browser/templates/fileupload.pt	(revision 13936)
@@ -21,5 +21,5 @@
 		<div class="input-group" tal:condition="not: viewlet/file_exists">
 			<div class="input-group-btn">
-				<div class="btn btn-default btn-file">
+				<div class="btn btn-default btn-file" i18n:translate="">
           Select new file&hellip;
           <input type="file" tal:attributes="name viewlet/input_name" />
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 13935)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 13936)
@@ -3087,4 +3087,5 @@
     grok.template('editscorespage')
     pnav = 1
+    doclink = DOCLINK + '/students/browser.html#batch-editing-scores-by-lecturers'
 
     def label(self):
@@ -3139,17 +3140,24 @@
             self.redirect(self.url(self.context))
             return
-        if not 'UPDATE' in form:
+        if not 'UPDATE_TABLE' in form and not 'UPDATE_FILE' in form:
             return
         error = ''
         if not editable_tickets:
             return
-        formvals = dict(zip(form['sids'], form['scores']))
-        if form['uploadfile']:
-            try:
-                formvals = self._extract_uploadfile(form['uploadfile'])
-            except:
+        if 'UPDATE_FILE' in form:
+            if form['uploadfile']:
+                try:
+                    formvals = self._extract_uploadfile(form['uploadfile'])
+                except:
+                    self.flash(
+                        _('Uploaded file contains illegal data. Ignored'),
+                        type="danger")
+                    return
+            else:
                 self.flash(
-                    _('Uploaded file contains illegal data. Ignored'),
-                    type="danger")
+                    _('No file provided.'), type="danger")
+                return
+        else:
+            formvals = dict(zip(form['sids'], form['scores']))
         for ticket in editable_tickets:
             score = ticket.score
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/editscorespage.pt
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/editscorespage.pt	(revision 13935)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/editscorespage.pt	(revision 13936)
@@ -1,8 +1,56 @@
+<p  i18n:domain="waeup.kofa" i18n:translate="edit_scores_info">
+  This page helps you to update your students' course results.
+  You can either update scores by importing a csv file
+  (press 'Help' for further information) or by
+  changing score values in the table below. Only scores of students
+  in state 'courses validated' and current academic session
+  can be modified.
+</p>
+
 <form  i18n:domain="waeup.kofa"  method="POST" enctype="multipart/form-data">
   <br />
+  <div class="input-group">
+    <div class="input-group-btn">
+      <div class="btn btn-default btn-file" i18n:translate="">
+        Select file&hellip;
+        <input type="file" name="uploadfile:file" />
+      </div>
+    </div>
+    <input type="text" class="form-control" readonly>
+    <div class="input-group-btn">
+      <input type="submit" name="UPDATE_FILE" i18n:translate=""
+             value="Update editable scores from csv file"
+             class="btn btn-primary" />
+      <button class="btn btn-warning" data-toggle="modal"
+              data-target="#myModal" i18n:translate="">
+        Help
+      </button>
+    </div>
+  </div>
+
+  <!-- Modal -->
+  <div class="modal fade" id="myModal" tabindex="-1" role="dialog"
+       aria-labelledby="myModalLabel" aria-hidden="true">
+    <div class="modal-dialog">
+      <div class="modal-content">
+        <div class="modal-header">
+          <button type="button" class="close" data-dismiss="modal"
+                  aria-hidden="true">&times;</button>
+          <h4 class="modal-title" id="myModalLabel" i18n:translate="">
+            Instructions for File Upload
+          </h4>
+        </div>
+        <div class="modal-body" i18n:translate="lecturer_help">
+          ...
+        </div>
+      </div><!-- /.modal-content -->
+    </div><!-- /.modal-dialog -->
+  </div><!-- /.modal -->
+
+  <br /><br />
 
   <table class="kofa-data-table dataTable">
     <thead>
-  	<tr>
+    <tr>
       <th i18n:translate="">Matric No.</th>
       <th i18n:translate="">Student Id</th>
@@ -12,5 +60,5 @@
       <th i18n:translate="">Level</th>
       <th i18n:translate="">Score</th>
-  	</tr>
+    </tr>
     </thead>
     <tbody>
@@ -18,12 +66,12 @@
       <td tal:content="ticket/student/matric_number">MATRIC_NUMBER</td>
       <td tal:content="ticket/student/student_id">STUDENT ID</td>
-  	  <td tal:content="ticket/student/display_fullname">FULLNAME</td>
+      <td tal:content="ticket/student/display_fullname">FULLNAME</td>
       <td tal:content="ticket/student/translated_state">STATE</td>
       <td tal:content="ticket/student/certcode">CERTCODE</td>
       <td tal:content="ticket/level">LEVEL</td>
 
-  	  <td tal:condition="ticket/editable_by_lecturer" style="width: 65px;">
+      <td tal:condition="ticket/editable_by_lecturer" style="width: 65px;">
           <input type="text" name="scores:list" class="form-control"
-  	             tal:attributes="value ticket/score" />
+                 tal:attributes="value ticket/score" />
           <input type="hidden" name="sids:list"
                  tal:attributes="value ticket/student/student_id" />
@@ -31,28 +79,10 @@
       <td tal:condition="not: ticket/editable_by_lecturer"
           tal:content="ticket/score">SCORE</td>
-  	</tr>
-
-      <tr>
-        <td i18n:translate="">
-          Set scores from CSV file:
-        </td>
-        <td>
-          <div class="input-group half">
-            <div class="input-group-btn">
-              <div class="btn btn-default btn-file">
-                Select&hellip;
-                <input type="file" name="uploadfile:file" />
-              </div>
-            </div>
-            <input type="text" class="form-control" readonly />
-          </div>
-        </td>
-      </tr>
-
+     </tr>
     </tbody>
   </table>
 
-  <input type="submit" name="UPDATE"
-         value="Update scores" class="btn btn-primary"
+  <input type="submit" name="UPDATE_TABLE" i18n:translate=""
+         value="Update scores from table" class="btn btn-primary"
          />
 </form>
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 13935)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 13936)
@@ -4055,5 +4055,5 @@
         self.login_as_lecturer()
         self.browser.open(self.edit_scores_url)
-        self.browser.getLink("Download editable tickets").click()
+        self.browser.getLink("Download csv file").click()
         self.assertEqual(self.browser.headers['Status'], '200 Ok')
         self.assertEqual(self.browser.headers['Content-Type'],
@@ -4072,5 +4072,5 @@
         upload_file = StringIO(UPLOAD_CSV_TEMPLATE % '65')
         upload_ctrl.add_file(upload_file, 'text/csv', 'myscores.csv')
-        self.browser.getControl("Update scores").click()
+        self.browser.getControl("Update editable scores from").click()
         # value changed
         self.assertEqual(
@@ -4120,5 +4120,5 @@
             upload_ctrl = self.browser.getControl(name='uploadfile:file')
             upload_ctrl.add_file(StringIO(content), mimetype, name)
-            self.browser.getControl("Update scores").click()
+            self.browser.getControl("Update editable scores").click()
             self.assertEqual(
                 self.student['studycourse']['100']['COURSE1'].score, 55)
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/viewlets.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/viewlets.py	(revision 13935)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/viewlets.py	(revision 13936)
@@ -869,5 +869,5 @@
     grok.require('waeup.editScores')
     icon = 'actionicon_down.png'
-    text = _('Download editable tickets')
+    text = _('Download csv file (editable scores only)')
     target = 'download_scores'
     grok.order(1)
