]> git.mjollnir.org Git - moodle.git/commitdiff
Manual grading
authorgustav_delius <gustav_delius>
Fri, 7 Apr 2006 16:00:29 +0000 (16:00 +0000)
committergustav_delius <gustav_delius>
Fri, 7 Apr 2006 16:00:29 +0000 (16:00 +0000)
lang/en_utf8/quiz.php
lib/questionlib.php
mod/quiz/comment.php [new file with mode: 0644]
mod/quiz/locallib.php
mod/quiz/report/grading/report.php
mod/quiz/review.php
mod/quiz/reviewquestion.php
question/comment.html [new file with mode: 0644]
question/type/question.html
question/type/questiontype.php
theme/standard/styles_layout.css

index 9f31bb092aa92cd9207f4b8446397e6b2f6d6e8c..d4e2f3f49e55fe28bb4731312865db2262384847 100644 (file)
@@ -82,6 +82,8 @@ $string['choosefile'] = 'Choose a file';
 $string['close'] = 'Close window';
 $string['closepreview'] = 'Close preview';
 $string['closereview'] = 'Close review';
+$string['comment'] = 'Comment';
+$string['commentorgrade'] = 'Make comment or override grade';
 $string['completedon'] = 'Completed on';
 $string['confirmclose'] = 'You are about to close this attempt. Once you close the attempt you will no longer be able to change your answers.';
 $string['confirmserverdelete'] = 'Are you sure you want to remove the server <b>$a</b> from the list?';
@@ -159,9 +161,10 @@ $string['event1'] = 'Autosave';
 $string['event2'] = 'Save';
 $string['event3'] = 'Grade';
 $string['event5'] = 'Validate';
-$string['event6'] = 'Close';
+$string['event6'] = 'Close&amp;Grade';
 $string['event7'] = 'Submit';
 $string['event8'] = 'Close';
+$string['event9'] = 'Manual Grade';
 $string['examview'] = 'Examview';
 $string['existingcategory1'] = 'a literal from an already existing set of literals that are also used by other questions in this category';
 $string['existingcategory2'] = 'a file from an already existing set of files that are also used by other questions in this category';
index 1c8ee86728a21284d6d3aedc3dfdfd69fcbdc3c3..c8d27c5bdee92e0e827c2c7b20dca542562d23e3 100644 (file)
@@ -685,8 +685,7 @@ function save_question_session(&$question, &$state) {
     $state->answer = isset($state->responses['']) ? $state->responses[''] : '';
 
     // Save the state
-    if (isset($state->update)) { // this ->update field is only used by the 
-        // regrading function to force the old state record to be overwritten
+    if (isset($state->update)) { // this forces the old state record to be overwritten
         update_record('question_states', $state);
     } else {
         if (!$state->id = insert_record('question_states', $state)) {
@@ -694,30 +693,30 @@ function save_question_session(&$question, &$state) {
             unset($state->answer);
             return false;
         }
+    }
 
-        // this is the most recent state
-        if (!record_exists('question_sessions', 'attemptid',
-         $state->attempt, 'questionid', $question->id)) {
-            $new->attemptid = $state->attempt;
-            $new->questionid = $question->id;
-            $new->newest = $state->id;
-            $new->sumpenalty = $state->sumpenalty;
-            if (!insert_record('question_sessions', $new)) {
-                error('Could not insert entry in question_sessions');
-            }
-        } else {
-            set_field('question_sessions', 'newest', $state->id, 'attemptid',
-             $state->attempt, 'questionid', $question->id);
+    // create or update the session
+    if (!record_exists('question_sessions', 'attemptid',
+     $state->attempt, 'questionid', $question->id)) {
+        $new->attemptid = $state->attempt;
+        $new->questionid = $question->id;
+        $new->newest = $state->id;
+        $new->sumpenalty = $state->sumpenalty;
+        if (!insert_record('question_sessions', $new)) {
+            error('Could not insert entry in question_sessions');
         }
-        if (question_state_is_graded($state)) {
-            // this is also the most recent graded state
-            if ($newest = get_record('question_sessions', 'attemptid',
-             $state->attempt, 'questionid', $question->id)) {
-                $newest->newgraded = $state->id;
-                $newest->sumpenalty = $state->sumpenalty;
-                $newest->comment = $state->comment;
-                update_record('question_sessions', $newest);
-            }
+    } else {
+        set_field('question_sessions', 'newest', $state->id, 'attemptid',
+         $state->attempt, 'questionid', $question->id);
+    }
+    if (question_state_is_graded($state)) {
+        // this is also the most recent graded state
+        if ($newest = get_record('question_sessions', 'attemptid',
+         $state->attempt, 'questionid', $question->id)) {
+            $newest->newgraded = $state->id;
+            $newest->sumpenalty = $state->sumpenalty;
+            $newest->comment = $state->comment;
+            update_record('question_sessions', $newest);
         }
     }
 
@@ -752,7 +751,9 @@ function question_state_is_graded($state) {
 * @param object $state
 */
 function question_state_is_closed($state) {
-    return ($state->event == QUESTION_EVENTCLOSE or $state->event == QUESTION_EVENTCLOSEANDGRADE);
+    return ($state->event == QUESTION_EVENTCLOSE
+        or $state->event == QUESTION_EVENTCLOSEANDGRADE
+        or $state->event == QUESTION_EVENTMANUALGRADE);
 }
 
 
@@ -1166,6 +1167,59 @@ function get_question_image($question, $courseid) {
     }
     return $img;
 }
+
+function question_print_comment_box($question, $state, $attempt, $url) {
+    global $CFG;
+    if ($usehtmleditor = can_use_richtext_editor()) {
+        use_html_editor('comment');
+    }
+    $grade = round($state->last_graded->grade, 3);
+    echo '<form method="post" action="'.$url.'">';
+    include($CFG->dirroot.'/question/comment.html');
+    echo '<input type="hidden" name="attempt" value="'.$attempt->uniqueid.'" />';
+    echo '<input type="hidden" name="question" value="'.$question->id.'" />';
+    echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
+    echo '</form>';
+}
+
+function question_process_comment($question, &$state, &$attempt, $comment, $grade) {
+
+    // Update the comment and save it in the database
+    $state->comment = $comment;
+    if (!set_field('question_sessions', 'comment', $comment, 'attemptid', $attempt->uniqueid, 'questionid', $question->id)) {
+        error("Cannot save comment");
+    }
+
+    // If the teacher has changed the grade then update the attempt and the state
+    // The modified attempt is stored to the database, the state not yet but the
+    // $state->changed flag is set 
+    if (abs($state->last_graded->grade - $grade) > 0.002) {
+        // the teacher has changed the grade
+        $attempt->sumgrades = $attempt->sumgrades - $state->last_graded->grade + $grade;
+        $attempt->timemodified = time();
+        if (!update_record('quiz_attempts', $attempt)) {
+            error('Failed to save the current quiz attempt!');
+        }
+
+        $state->raw_grade = $grade;
+        $state->grade = $grade;
+        $state->penalty = 0;
+        $state->timestamp = time();
+        // We need to indicate that the state has changed in order for it to be saved
+        $state->changed = 1;
+        // We want to update existing state (rather than creating new one) if it
+        // was itself created by a manual grading event
+        $state->update = ($state->event == QUESTION_EVENTMANUALGRADE) ? 1 : 0;
+        $state->event = QUESTION_EVENTMANUALGRADE;
+
+        // Update the last graded state (don't simplify!)
+        unset($state->last_graded);
+        $state->last_graded = clone($state);
+        unset($state->last_graded->changed);
+    }
+
+}
+
 /**
 * Construct name prefixes for question form element names
 *
diff --git a/mod/quiz/comment.php b/mod/quiz/comment.php
new file mode 100644 (file)
index 0000000..7fbd831
--- /dev/null
@@ -0,0 +1,87 @@
+<?php  // $Id$
+/**
+* This page prints a review of a particular question attempt
+*
+* @version $Id$
+* @author Martin Dougiamas and many others. This has recently been completely
+*         rewritten by Alex Smith, Julian Sedding and Gustav Delius as part of
+*         the Serving Mathematics project
+*         {@link http://maths.york.ac.uk/serving_maths}
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package quiz
+*/
+
+    require_once('../../config.php');
+    require_once('locallib.php');
+
+    $attemptid =required_param('attempt', PARAM_INT); // attempt id
+    $questionid =required_param('question', PARAM_INT); // question id
+
+    if (! $attempt = get_record('quiz_attempts', 'uniqueid', $attemptid)) {
+        error('No such attempt ID exists');
+    }
+    if (! $quiz = get_record('quiz', 'id', $attempt->quiz)) {
+        error('Course module is incorrect');
+    }
+    if (! $course = get_record('course', 'id', $quiz->course)) {
+        error('Course is misconfigured');
+    }
+
+    // Teachers are only allowed to comment and grade on closed attempts
+    if (!($attempt->timefinish > 0)) {
+        error('Attempt has not closed yet');
+    }
+
+    require_login($course->id);
+
+    if (!isteacher($course->id)) {
+        error('This page is for teachers only');
+    }
+
+    // Load question
+    if (! $question = get_record('question', 'id', $questionid)) {
+        error('Question for this session is missing');
+    }
+    $question->maxgrade = get_field('quiz_question_instances', 'grade', 'quiz', $quiz->id, 'question', $question->id);
+    // Some of the questions code is optimised to work with several questions
+    // at once so it wants the question to be in an array. 
+    $key = $question->id;
+    $questions[$key] = &$question;
+    // Add additional questiontype specific information to the question objects.
+    if (!get_question_options($questions)) {
+        error("Unable to load questiontype specific question information");
+    }
+
+    // Load state
+    $states = get_question_states($questions, $quiz, $attempt);
+    // The $states array is indexed by question id but because we are dealing
+    // with only one question there is only one entry in this array
+    $state = &$states[$question->id];
+
+    print_header();
+    print_heading(format_string($question->name));
+    
+    //add_to_log($course->id, 'quiz', 'review', "review.php?id=$cm->id&amp;attempt=$attempt->id", "$quiz->id", "$cm->id");
+
+    if ($data = data_submitted() and confirm_sesskey()) {
+        // the following will update the state and attempt
+        question_process_comment($question, $state, $attempt, $data->comment, $data->grade);
+        // If the state has changed save it and update the quiz grade
+        if ($state->changed) {
+            save_question_session($question, $state);
+            quiz_save_best_grade($quiz);
+        }
+
+        notify(print_string('changessaved'));
+        echo '<input type="button" onclick="window.close()" value="' .
+         get_string('closewindow') . "\" />";
+         
+        print_footer();
+        exit;
+    }
+
+    question_print_comment_box($question, $state, $attempt, $CFG->wwwroot.'/mod/quiz/comment.php');
+
+    print_footer();
+
+?>
index 742b09d113be6b6602a5078b0ede089ac01d4953..85ede1d000aaa06bfe4ecc891c6e119accfcb14d 100644 (file)
@@ -509,8 +509,11 @@ function quiz_get_renderoptions($reviewoptions, $state) {
 /**
 * Determine review options
 */
-function quiz_get_reviewoptions($cmoptions, $attempt, $isteacher=false) {
+function quiz_get_reviewoptions($quiz, $attempt, $isteacher=false) {
     $options->readonly = true;
+    // Provide the links to the question review and comment script
+    $options->questionreviewlink = '/mod/quiz/reviewquestion.php';
+
     if ($isteacher and !$attempt->preview) {
         // The teacher should be shown everything except during preview when the teachers
         // wants to see just what the students see
@@ -519,27 +522,32 @@ function quiz_get_reviewoptions($cmoptions, $attempt, $isteacher=false) {
         $options->feedback = true;
         $options->correct_responses = true;
         $options->solutions = false;
+        // Show a link to the comment box only for closed attempts
+        if ($attempt->timefinish) {
+            $options->questioncommentlink = '/mod/quiz/comment.php';
+        }
         return $options;
     }
     if ((time() - $attempt->timefinish) < 120) {
-        $options->responses = ($cmoptions->review & QUIZ_REVIEW_IMMEDIATELY & QUIZ_REVIEW_RESPONSES) ? 1 : 0;
-        $options->scores = ($cmoptions->review & QUIZ_REVIEW_IMMEDIATELY & QUIZ_REVIEW_SCORES) ? 1 : 0;
-        $options->feedback = ($cmoptions->review & QUIZ_REVIEW_IMMEDIATELY & QUIZ_REVIEW_FEEDBACK) ? 1 : 0;
-        $options->correct_responses = ($cmoptions->review & QUIZ_REVIEW_IMMEDIATELY & QUIZ_REVIEW_ANSWERS) ? 1 : 0;
-        $options->solutions = ($cmoptions->review & QUIZ_REVIEW_IMMEDIATELY & QUIZ_REVIEW_SOLUTIONS) ? 1 : 0;
-    } else if (!$cmoptions->timeclose or time() < $cmoptions->timeclose) {
-        $options->responses = ($cmoptions->review & QUIZ_REVIEW_OPEN & QUIZ_REVIEW_RESPONSES) ? 1 : 0;
-        $options->scores = ($cmoptions->review & QUIZ_REVIEW_OPEN & QUIZ_REVIEW_SCORES) ? 1 : 0;
-        $options->feedback = ($cmoptions->review & QUIZ_REVIEW_OPEN & QUIZ_REVIEW_FEEDBACK) ? 1 : 0;
-        $options->correct_responses = ($cmoptions->review & QUIZ_REVIEW_OPEN & QUIZ_REVIEW_ANSWERS) ? 1 : 0;
-        $options->solutions = ($cmoptions->review & QUIZ_REVIEW_OPEN & QUIZ_REVIEW_SOLUTIONS) ? 1 : 0;
+        $options->responses = ($quiz->review & QUIZ_REVIEW_IMMEDIATELY & QUIZ_REVIEW_RESPONSES) ? 1 : 0;
+        $options->scores = ($quiz->review & QUIZ_REVIEW_IMMEDIATELY & QUIZ_REVIEW_SCORES) ? 1 : 0;
+        $options->feedback = ($quiz->review & QUIZ_REVIEW_IMMEDIATELY & QUIZ_REVIEW_FEEDBACK) ? 1 : 0;
+        $options->correct_responses = ($quiz->review & QUIZ_REVIEW_IMMEDIATELY & QUIZ_REVIEW_ANSWERS) ? 1 : 0;
+        $options->solutions = ($quiz->review & QUIZ_REVIEW_IMMEDIATELY & QUIZ_REVIEW_SOLUTIONS) ? 1 : 0;
+    } else if (!$quiz->timeclose or time() < $quiz->timeclose) {
+        $options->responses = ($quiz->review & QUIZ_REVIEW_OPEN & QUIZ_REVIEW_RESPONSES) ? 1 : 0;
+        $options->scores = ($quiz->review & QUIZ_REVIEW_OPEN & QUIZ_REVIEW_SCORES) ? 1 : 0;
+        $options->feedback = ($quiz->review & QUIZ_REVIEW_OPEN & QUIZ_REVIEW_FEEDBACK) ? 1 : 0;
+        $options->correct_responses = ($quiz->review & QUIZ_REVIEW_OPEN & QUIZ_REVIEW_ANSWERS) ? 1 : 0;
+        $options->solutions = ($quiz->review & QUIZ_REVIEW_OPEN & QUIZ_REVIEW_SOLUTIONS) ? 1 : 0;
     } else {
-        $options->responses = ($cmoptions->review & QUIZ_REVIEW_CLOSED & QUIZ_REVIEW_RESPONSES) ? 1 : 0;
-        $options->scores = ($cmoptions->review & QUIZ_REVIEW_CLOSED & QUIZ_REVIEW_SCORES) ? 1 : 0;
-        $options->feedback = ($cmoptions->review & QUIZ_REVIEW_CLOSED & QUIZ_REVIEW_FEEDBACK) ? 1 : 0;
-        $options->correct_responses = ($cmoptions->review & QUIZ_REVIEW_CLOSED & QUIZ_REVIEW_ANSWERS) ? 1 : 0;
-        $options->solutions = ($cmoptions->review & QUIZ_REVIEW_CLOSED & QUIZ_REVIEW_SOLUTIONS) ? 1 : 0;
+        $options->responses = ($quiz->review & QUIZ_REVIEW_CLOSED & QUIZ_REVIEW_RESPONSES) ? 1 : 0;
+        $options->scores = ($quiz->review & QUIZ_REVIEW_CLOSED & QUIZ_REVIEW_SCORES) ? 1 : 0;
+        $options->feedback = ($quiz->review & QUIZ_REVIEW_CLOSED & QUIZ_REVIEW_FEEDBACK) ? 1 : 0;
+        $options->correct_responses = ($quiz->review & QUIZ_REVIEW_CLOSED & QUIZ_REVIEW_ANSWERS) ? 1 : 0;
+        $options->solutions = ($quiz->review & QUIZ_REVIEW_CLOSED & QUIZ_REVIEW_SOLUTIONS) ? 1 : 0;
     }
+
     return $options;
 }
 
index 0042d74fcdc249e3a182f1900ece7a989f0d9f12..a6157ce077427805bed9928f51515c17351746bf 100644 (file)
@@ -113,26 +113,14 @@ class quiz_report extends quiz_default_report {
                 // with only one question there is only one entry in this array
                 $state = &$states[$question->id];
 
-                // this is the new response from the teacher
-                $state->responses = $response;
-
-                // Process the teacher responses
-                $QTYPES[$question->qtype]->process_teacher_responses($question, $state, $quiz);
-
-                // We need to indicate that the state has changed in order for it to be saved
-                $state->changed = 1;
-                // We want to update existing state (rather than creating new one) if it
-                // was itself created by a manual grading event
-                $state->update = ($state->event == QUESTION_EVENTMANUALGRADE) ? 1 : 0;
-                // Go ahead and save
-                save_question_session($question, $state);
-
-                if ($attempt->sumgrades != $sumgrades) {
-                    set_field('quiz_attempts', 'sumgrades', $sumgrades, 'id', $attempt->id);
-                }
+                // the following will update the state and attempt
+                question_process_comment($question, $state, $attempt, $response['comment'], $response['grade']);
 
-                // update user's grade
-                quiz_save_best_grade($quiz, $attempt->userid);
+                // If the state has changed save it and update the quiz grade
+                if ($state->changed) {
+                    save_question_session($question, $state);
+                    quiz_save_best_grade($quiz);
+                }
             }
             notify(get_string('changessaved', 'quiz'));
 
index 723a1dfd63e63eced3d40af5ed3c249d107ad35b..ac4e6bf8807122873d94c0d19130ba49642b8eed 100644 (file)
         $options = quiz_get_reviewoptions($quiz, $attempt, $isteacher);
         $options->validation = QUESTION_EVENTVALIDATE === $states[$i]->event;
         $options->history = ($isteacher and !$attempt->preview) ? 'all' : 'graded';
-        // Provide the links to the question review script
-        $options->questionreviewlink = '/mod/quiz/reviewquestion.php';
         // Print the question
         if ($i > 0) {
             echo "<br />\n";
index 8b6e20e37b3d878b292f5750bca8f70cb037ed9a..0eefb6e37f03b17ce95fd3d2cb83148b5cb21e45 100644 (file)
 /// Print heading
     print_heading(format_string($question->name));
 
-    $instance = get_record('quiz_question_instances', 'quiz', $quiz->id, 'question', $question->id);
-    $question->instance = $instance->id;
-    $question->maxgrade = $instance->grade;
-    $question->name_prefix = 'r';
-    $QTYPES[$question->qtype]->get_question_options($question);
+    $question->maxgrade = get_field('quiz_question_instances', 'grade', 'quiz', $quiz->id, 'question', $question->id);
+    // Some of the questions code is optimised to work with several questions
+    // at once so it wants the question to be in an array. 
+    $key = $question->id;
+    $questions[$key] = &$question;
+    // Add additional questiontype specific information to the question objects.
+    if (!get_question_options($questions)) {
+        error("Unable to load questiontype specific question information");
+    }
 
+    $session = get_record('question_sessions', 'attemptid', $attempt->uniqueid, 'questionid', $question->id);
+    $state->sumpenalty = $session->sumpenalty;
+    $state->comment = $session->comment;
     restore_question_state($question, $state);
     $state->last_graded = $state;
 
     $options = quiz_get_reviewoptions($quiz, $attempt, $isteacher);
     $options->validation = ($state->event == QUESTION_EVENTVALIDATE);
     $options->history = ($isteacher and !$attempt->preview) ? 'all' : 'graded';
-    // Provide the links to this question review script
-    $options->questionreviewlink = '/mod/quiz/reviewquestion.php';
 
 /// Print infobox
     $table->align  = array("right", "left");
diff --git a/question/comment.html b/question/comment.html
new file mode 100644 (file)
index 0000000..d3210b3
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+/* This template determines the overall layout of a question. It is included by the 
+ * print_question() method.
+ */
+?>
+<table class="que comment">
+  <tr valign="top">
+    <td>
+      <b><?php print_string('comment', 'quiz'); ?>: </b>
+    </td>
+    <td>
+      <?php
+        print_textarea($usehtmleditor, 15, 60, 630, 300, 'comment', $state->comment);
+      ?>
+    </td>
+  </tr>
+  <tr valign="top">
+    <td>
+      <b><?php print_string('grade', 'quiz'); ?>: </b>
+    </td>
+    <td>
+      <input type="text" name="grade" size="2" value="<?php echo $grade; ?>" />/<?php echo $question->maxgrade; ?>
+    </td>
+  </tr>
+</table>
+<input type="submit" name="submit" value="<?php print_string('save', 'quiz'); ?>" />
\ No newline at end of file
index ee1dad4c589d547981c800f035b4164131c2e5d2..93b7bbe56423c45951517e14d1790da4d74210a3 100644 (file)
@@ -8,8 +8,8 @@
     <span class="no"><?php echo $number; ?></span>
     <?php if ($editlink) { ?>
       <span class="edit"><?php echo $editlink; ?></span>
-    <?php } ?>
-    <?php if ($grade) { ?>
+    <?php }
+    if ($grade) { ?>
       <div class="grade">
         <?php echo get_string('marks', 'quiz').': '.$grade; ?>
       </div>
   <div class="grading">
     <?php $this->print_question_grading_details($question, $state, $cmoptions, $options); ?>
   </div>
-  <?php if ($history) { ?>
+  <?php if ($comment) { ?>
+       <div class="comment">
+         <?php
+        echo get_string('comment', 'quiz').': ';
+        echo $comment;
+      ?>
+    </div>
+  <?php }
+  echo $commentlink;
+  if ($history) { ?>
        <div class="history">
          <?php
         print_string('history', 'quiz');
index 6e3b4c04dbbdd960f088b8970940fda5e6ffc9ef..a50ff8a99451ef098db24fbfa1c5fd0013aabf50 100644 (file)
@@ -473,6 +473,14 @@ class default_questiontype {
             }
             $grade .= $question->maxgrade;
         }
+        
+        $comment = $state->comment;
+        $commentlink = '';
+        if (isset($options->questioncommentlink)) {
+            $strcomment = get_string('commentorgrade', 'quiz');
+            $commentlink = '<div class="commentlink">'.link_to_popup_window ($options->questioncommentlink.'?attempt='.$state->attempt.'&amp;question='.$question->id,
+                             'commentquestion', $strcomment, 450, 650, $strcomment, 'none', true).'</div>';
+        }
 
         $history = $this->history($question, $state, $number, $cmoptions, $options);
 
@@ -503,11 +511,9 @@ class default_questiontype {
                     get_string('response', 'quiz'),
                     get_string('time'),
                     get_string('score', 'quiz'),
-                    get_string('penalty', 'quiz'),
+                    //get_string('penalty', 'quiz'),
                     get_string('grade', 'quiz'),
                 );
-                $table->align = array ('center', 'center', 'left', 'left', 'left', 'left', 'left');
-                $table->size = array ('', '', '', '', '', '', '');
                 $table->width = '100%';
                 foreach ($states as $st) {
                     $st->responses[''] = $st->answer;
@@ -530,7 +536,7 @@ class default_questiontype {
                         $b.$this->response_summary($question, $st).$be,
                         $b.userdate($st->timestamp, get_string('timestr', 'quiz')).$be,
                         $b.round($st->raw_grade, $cmoptions->decimalpoints).$be,
-                        $b.round($st->penalty, $cmoptions->decimalpoints).$be,
+                        //$b.round($st->penalty, $cmoptions->decimalpoints).$be,
                         $b.round($st->grade, $cmoptions->decimalpoints).$be
                     );
                 }
index 600934080e4c46482bfd8607125fbbcc5a0c8768..9bfa29fcc53e9aa952c787f7a14f293bd53bcb23 100644 (file)
@@ -1177,7 +1177,9 @@ body#message-messages {
        padding: 0 0 0.3em 0.3em;
   border: 1px solid;
 }      
-.que .grading, 
+.que .grading,
+.que .comment,
+.que .commentlink,
 .que .history {
        float: right;
        margin: 5px;