Index: ajax.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/ajax.inc,v
retrieving revision 1.1.2.4
diff -u -p -r1.1.2.4 ajax.inc
--- ajax.inc	11 Oct 2007 20:47:49 -0000	1.1.2.4
+++ ajax.inc	18 Oct 2007 10:20:01 -0000
@@ -22,56 +22,61 @@
  *   Source string id.
  */
 function l10n_community_string_details($langcode = NULL, $sid = 0) {
-
-  // List of project releases, where this string is used.
-  $result = db_query('SELECT p.pid, p.title project_title, r.rid, r.title release_title, COUNT(l.lineno) as occurance_count FROM {l10n_community_project} p INNER JOIN {l10n_community_release} r ON p.pid = r.pid INNER JOIN {l10n_community_file} f ON r.rid = f.rid INNER JOIN {l10n_community_line} l ON f.fid = l.fid INNER JOIN {l10n_community_string} s ON l.sid = s.sid WHERE s.sid = %d GROUP BY r.rid ORDER by p.pid, r.rid', $sid);
-  
-  $list = array();
-  $output = array();
-  $previous_project = '';
-  while ($instance = db_fetch_object($result)) {
-    if ($instance->project_title != $previous_project) {
-      if (!empty($list)) {
-        $output[] = join(', ', $list);
-      }
-      $list = array('<em>'. $instance->project_title . ':</em> '. $instance->release_title .' ('. $instance->occurance_count .')');
-    }
-    else {
-      $list[] = $instance->release_title .' ('. $instance->occurance_count .')';
+  // Existing, "unresolved" suggestions.
+  if (isset($_GET[suggestion])) {
+    $suggestions = array();
+    $result = db_query("SELECT * FROM {l10n_community_translation} WHERE language = '%s' AND sid = %d AND is_active = 1 AND is_suggestion = 1", $langcode, $sid);
+    $perm = l10n_community_get_permission($langcode);
+    while ($suggestion = db_fetch_object($result)) {
+      
+      // This detail pane is only retrieved from JS, so we are free to output obtrusive JS here.
+      $approve_button = $perm == L10N_PERM_ALL ? '<img src="'. base_path() . drupal_get_path('module', 'l10n_community') .'/images/approve.png" class="action" title="'. t('Approve suggestion.') .'" onclick="return l10nCommunity.approveSuggestion('. $suggestion->tid .','. $suggestion->sid .');" /> ' : '';
+      
+      $copy_button = '<img src="'. base_path() . drupal_get_path('module', 'l10n_community') .'/images/edit.png" class="action" title="'. t('Edit suggestion.') .'" onclick="return l10nCommunity.copySuggestion('. $suggestion->sid .',\''. check_plain(str_replace(array("'", "\0"), array("\\'", "\O"), $suggestion->translation)) .'\');" /> ';
+      
+      // Plural versions are shown in a short form.
+      $translation = strpos($suggestion->translation, "\0") ? str_replace(chr(0), '; ', $suggestion->translation) : $suggestion->translation;
+      
+      $suggestions[] = $approve_button . $copy_button . $translation; 
     }
-    $previous_project = $instance->project_title; 
-  }
-  $output[] = join(', ', $list);
-  $usage_info = '<div style="float:right"><strong>'. t('Used in:') .'</strong>'. theme('item_list', $output) .'</div>';
+    $suggestion_info = count($suggestions) ? '<div><strong>'. t('Outstanding suggestions:') .'</strong>'. theme('item_list', $suggestions) .'</div>' : ''; 
   
-  // Information about translator and translation timestamp.
-  $translation_info = '';
-  $translation = db_fetch_object(db_query("SELECT translation, uid_entered, time_entered FROM {l10n_community_translation} WHERE language = '%s' AND sid = %d AND is_active = 1 AND is_suggestion = 0", $langcode, $sid));
-  if (!empty($translation->translation)) {
-    $account = user_load(array('uid' => $translation->uid_entered));
-    $translation_info = '<div>'. t('<strong>Translated by:</strong><br /> %username at %date', array('%username' => $account->name, '%date' => format_date($translation->time_entered))) .'</div>';
+    print $suggestion_info;
+    exit;
   }
-  
-  // Existing, "unresolved" suggestions.
-  $suggestions = array();
-  $result = db_query("SELECT * FROM {l10n_community_translation} WHERE language = '%s' AND sid = %d AND is_active = 1 AND is_suggestion = 1", $langcode, $sid);
-  $perm = l10n_community_get_permission($langcode);
-  while ($suggestion = db_fetch_object($result)) {
+  else {
+    // List of project releases, where this string is used.
+    $result = db_query('SELECT p.pid, p.title project_title, r.rid, r.title release_title, COUNT(l.lineno) as occurance_count FROM {l10n_community_project} p INNER JOIN {l10n_community_release} r ON p.pid = r.pid INNER JOIN {l10n_community_file} f ON r.rid = f.rid INNER JOIN {l10n_community_line} l ON f.fid = l.fid INNER JOIN {l10n_community_string} s ON l.sid = s.sid WHERE s.sid = %d GROUP BY r.rid ORDER by p.pid, r.rid', $sid);
     
-    // This detail pane is only retrieved from JS, so we are free to output obtrusive JS here.
-    $approve_button = $perm == L10N_PERM_ALL ? '<img src="'. base_path() . drupal_get_path('module', 'l10n_community') .'/images/approve.png" class="action" title="'. t('Approve suggestion.') .'" onclick="return l10nCommunity.approveSuggestion('. $suggestion->tid .','. $suggestion->sid .');" /> ' : '';
-    
-    $copy_button = '<img src="'. base_path() . drupal_get_path('module', 'l10n_community') .'/images/edit.png" class="action" title="'. t('Edit suggestion.') .'" onclick="return l10nCommunity.copySuggestion('. $suggestion->sid .',\''. check_plain(str_replace(array("'", "\0"), array("\\'", "\O"), $suggestion->translation)) .'\');" /> ';
+    $list = array();
+    $output = array();
+    $previous_project = '';
+    while ($instance = db_fetch_object($result)) {
+      if ($instance->project_title != $previous_project) {
+        if (!empty($list)) {
+          $output[] = join(', ', $list);
+        }
+        $list = array('<em>'. $instance->project_title . ':</em> '. $instance->release_title .' ('. $instance->occurance_count .')');
+      }
+      else {
+        $list[] = $instance->release_title .' ('. $instance->occurance_count .')';
+      }
+      $previous_project = $instance->project_title; 
+    }
+    $output[] = join(', ', $list);
+    $usage_info = '<div style="float:right"><strong>'. t('Used in:') .'</strong>'. theme('item_list', $output) .'</div>';
     
-    // Plural versions are shown in a short form.
-    $translation = strpos($suggestion->translation, "\0") ? str_replace(chr(0), '; ', $suggestion->translation) : $suggestion->translation;
+    // Information about translator and translation timestamp.
+    $translation_info = '';
+    $translation = db_fetch_object(db_query("SELECT translation, uid_entered, time_entered FROM {l10n_community_translation} WHERE language = '%s' AND sid = %d AND is_active = 1 AND is_suggestion = 0", $langcode, $sid));
+    if (!empty($translation->translation)) {
+      $account = user_load(array('uid' => $translation->uid_entered));
+      $translation_info = '<div>'. t('<strong>Translated by:</strong><br /> %username at %date', array('%username' => $account->name, '%date' => format_date($translation->time_entered))) .'</div>';
+    }
     
-    $suggestions[] = $approve_button . $copy_button . $translation; 
+    print $usage_info . $translation_info;
+    exit;
   }
-  $suggestion_info = count($suggestions) ? '<div><strong>'. t('Outstanding suggestions:') .'</strong>'. theme('item_list', $suggestions) .'</div>' : ''; 
-  
-  print $usage_info . $translation_info . $suggestion_info;
-  exit;
 }
 
 /**
Index: l10n_community.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/l10n_community.css,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 l10n_community.css
--- l10n_community.css	1 Oct 2007 19:58:48 -0000	1.1.2.2
+++ l10n_community.css	18 Oct 2007 10:29:32 -0000
@@ -26,10 +26,13 @@
   float: left;
 }
 .l10n-community-progress-untranslated {
-  background-color: #b93131;
+  background-color: #ddd;
 }
 .l10n-community-progress-has-suggestion {
-  background-color: #6a4970;
+  background-color: #ffff00;
+}
+#l10n-community-overview td.l10n-community-status-label {
+  text-align: left;
 }
 
 /* String search filtering form */
@@ -99,3 +102,32 @@ em.l10n-community-marker {
   background: none;
   padding: 0 0 0.2em 1em;
 }
+
+/* Phrases overview */
+#l10n-community-phrases td {
+  width: 50%;
+  border: 1px solid #D3E7F4;
+  vertical-align: top;
+}
+#l10n-community-phrases .icons {
+  width:25px;
+}
+#l10n-community-phrases .more {
+  display:none;
+}
+#l10n-community-phrases .toolbox img {
+  cursor: pointer;
+  float: left;
+  padding-right: 3px;
+}
+#l10n-community-phrases .has-suggestion {
+  background-image: url('images/suggestions.png');
+  width: 16px;
+  height: 16px;
+  display: block; 
+  margin-right: 0.3em;
+  float: left;
+}
+html.js #l10n-community-phrases .has-suggestion {
+  cursor: pointer;
+}
Index: l10n_community.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/l10n_community.js,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 l10n_community.js
--- l10n_community.js	1 Oct 2007 19:58:48 -0000	1.1.2.2
+++ l10n_community.js	18 Oct 2007 10:19:56 -0000
@@ -24,18 +24,10 @@ l10nCommunity.init = function() {
     $('#l10n-community-wrapper-' + parseInt(id.replace('-t', ''))).css('display', 'block');
   ;})
 
-  $('#l10n-community-translate-form .toolbox').each(function(){
-    
-    // Add expand button to the toolbox.
-    $(this).append($(document.createElement('IMG')).attr('src', imagePath + 'expand.png').attr('class', 'expand').attr('title', Drupal.settings.l10n_expand_help).click(function() {
-      var id = $(this).parent().parent().attr('id').replace('l10n-community-editor-', '');
-      // Reveal textareas where the translation is done (if those were hidden).
-      $('#l10n-community-wrapper-' + id).css('display', 'block');
-    ;}));
-    
+  $('#l10n-community-phrases .toolbox').each(function(){
     // Add a lookup button to invoke server side callback.
     $(this).append($(document.createElement('IMG')).attr('src', imagePath + 'lookup.png').attr('class', 'lookup').attr('title', Drupal.settings.l10n_lookup_help).click(function() {
-      var sid = $(this).parent().parent().attr('id').replace('l10n-community-editor-', '');
+      var sid = $(this).parent().parent().parent().attr('id').replace('l10n-community-editor-', '');
       // Ajax GET request to retrieve more details about this string.
       $.ajax({
         type: "GET",
@@ -51,6 +43,23 @@ l10nCommunity.init = function() {
       });
     ;}));
   });
+  
+  $('#l10n-community-phrases .has-suggestion').click(function() {
+    var sid = $(this).parent().prev().parent().attr('id').replace('l10n-community-editor-', '');
+    // Ajax GET request to retrieve more details about this string.
+    $.ajax({
+      type: "GET",
+      url: Drupal.settings.l10n_details_callback + sid + '?suggestion',
+      success: function (data) {
+        // First empty, then load the data we get into the info pane.
+        $('#l10n-community-editor-' + sid + ' .suggestion-pane').css('display', 'block').empty().append(data);
+      },
+      error: function (xmlhttp) {
+        // Being an internal/system error, this is not translatable.
+        alert('An HTTP error '+ xmlhttp.status +' occured.\n'+ uri);
+      }
+    });
+  });
 }
 
 /**
Index: pages.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/pages.inc,v
retrieving revision 1.1.2.4
diff -u -p -r1.1.2.4 pages.inc
--- pages.inc	11 Oct 2007 20:47:49 -0000	1.1.2.4
+++ pages.inc	18 Oct 2007 10:28:21 -0000
@@ -6,6 +6,11 @@
  *   Overview and translation editing pages for localization community.
  */
 
+/**
+ * Number of items to be displayd by the filter.
+ */
+define('L10N_PAGE_LIMIT', 20);
+
 // = Overview screens ==========================================================
 
 /**
@@ -35,27 +40,20 @@ function l10n_community_overview_languag
     $perm = l10n_community_get_permission($langcode);
     $table[] = array_merge(
       array(
-        array('data' => "<strong>$language</strong> ($langcode)", 'class' => 'rowhead'),
-        l(t('Projects'), 'translate/languages/'. $langcode, array('title' => t('Go to the project list.'))),
-        ($perm == L10N_PERM_NONE ? t('n/a') : l(t('Import'), 'translate/languages/'. $langcode . '/import')),
+        array('data' => l("$language ($langcode)", 'translate/languages/'. $langcode, array('title' => t('Go to the project list.'))), 'class' => 'rowhead'),
       ),
-      count($groups) ? (isset($groups[$langcode]) ? l(t('Group'), 'node/'. $groups[$langcode]->nid, array('title' => t('Go to the group homepage.'))) : t('n/a')) : array(),
-      isset($string_counts[$langcode]) ? theme('l10n_community_progress_columns', $num_source, $string_counts[$langcode][0], $string_counts[$langcode][1]) : theme('l10n_community_progress_columns', $num_source, 0, 0)
+      isset($string_counts[$langcode]) ? theme('l10n_community_progress_columns', $num_source, $string_counts[$langcode][0], $string_counts[$langcode][1]) : theme('l10n_community_progress_columns', $num_source, 0, 0),
+      array(
+        ($perm == L10N_PERM_NONE ? t('n/a') : l(t('Import'), 'translate/languages/'. $langcode . '/import')),
+      )
     );
   }
   $header = array(
     array('data' => t('Language'), 'class' => 'rowhead'),
-    t('Projects'),
-    t('Import'),
-    t('Group'),
     t('Overall status'),
-    t('Translated'),
-    t('Has suggestion'),
-    t('Untranslated')
+    '', // No header for the status bar label.
+    t('Options')
   );
-  if (!count($groups)) {
-    unset($header[3]);
-  }
 
   return theme('table', $header, $table, array('id' => 'l10n-community-overview'));
 }
@@ -81,11 +79,12 @@ function l10n_community_overview_project
       list($sum, $translated, $suggested) = $string_counts[$project->pid];
       $table[] = array_merge(
         array(
-          array('data' => $project->title, 'class' => 'rowhead'), 
-          l(t('Languages'), 'translate/projects/'. $uri), 
-          l(t('Export'), 'translate/projects/'. $uri .'/export'),
+          array('data' => l($project->title, 'translate/projects/'. $uri), 'class' => 'rowhead'), 
         ), 
-        theme('l10n_community_progress_columns', $sum, $translated, $suggested)
+        theme('l10n_community_progress_columns', $sum, $translated, $suggested),
+        array(
+          l(t('Export'), 'translate/projects/'. $uri .'/export')
+        )
       );
     }
   }
@@ -93,12 +92,9 @@ function l10n_community_overview_project
     'table',
     array(
       array('data' => t('Project'), 'class' => 'rowhead'),
-      t('Languages'),
-      t('Export template'),
       t('Overall status'),
-      t('Translated'),
-      t('Has suggestion'),
-      t('Untranslated')
+      '', // No header for the status bar label.
+      t('Options')
     ),
     $table,
     array('id' => 'l10n-community-overview')
@@ -134,11 +130,15 @@ function l10n_community_status_projects(
       list($sum, $translated, $suggested) = $string_counts[$project->pid];
       $table[] = array_merge(
         array(
-          array('data' => l($project->title, 'translate/languages/'. $langcode .'/' . $uri), 'class' => 'rowhead'),
-          ($perm != L10N_PERM_NONE ? l(t('Import'), 'translate/languages/'. $langcode . '/'. $uri .'/import') : t('n/a')),
-          l(t('Export'), 'translate/languages/'. $langcode . '/'. $uri .'/export')
+          array('data' => l($project->title, 'translate/languages/'. $langcode .'/' . $uri), 'class' => 'rowhead')
         ),
-        theme('l10n_community_progress_columns', $sum, $translated, $suggested)
+        theme('l10n_community_progress_columns', $sum, $translated, $suggested),
+        array(
+          theme('links', array(
+            $perm != L10N_PERM_NONE ? array('title' => t('Import'), 'href' => 'translate/languages/'. $langcode . '/'. $uri .'/import') : array(),
+            array('title' => t('Export'), 'href' => 'translate/languages/'. $langcode . '/'. $uri .'/export')
+          ))
+        )
       );
     }
   }
@@ -146,12 +146,9 @@ function l10n_community_status_projects(
     'table',
     array(
       array('data' => t('Project'), 'class' => 'rowhead'),
-      t('Import'),
-      t('Export'),
       t('Overall status'),
-      t('Translated'),
-      t('Has suggestion'),
-      t('Untranslated')
+      '', // No header for the status bar label.
+      t('Options')
     ),
     $table,
     array('id' => 'l10n-community-overview')
@@ -188,10 +185,14 @@ function l10n_community_status_languages
     $table[] = array_merge(
       array(
         array('data' => l("<strong>$language</strong> ($langcode)", 'translate/projects/'. $uri . '/'. $langcode, array(), NULL, NULL, FALSE, TRUE), 'class' => 'rowhead'),
-        ($perm != L10N_PERM_NONE) ? l(t('Import'), 'translate/projects/'. $uri . '/'. $langcode .'/import') : t('n/a'),
-        l(t('Export'), 'translate/projects/'. $uri . '/'. $langcode .'/export'),
       ),
-      theme('l10n_community_progress_columns', $num_source, $string_counts[$langcode][0], $string_counts[$langcode][1])
+      theme('l10n_community_progress_columns', $num_source, $string_counts[$langcode][0], $string_counts[$langcode][1]),
+      array(
+        theme('links', array(
+          $perm != L10N_PERM_NONE ? array('title' => t('Import'), 'href' => 'translate/projects/'. $uri . '/'. $langcode .'/import') : array(), 
+          array('title' => t('Export'), 'href' => 'translate/projects/'. $uri . '/'. $langcode .'/export')
+        ))
+      )
     );
   }
 
@@ -199,12 +200,9 @@ function l10n_community_status_languages
     'table',
     array(
       array('data' => t('Language'), 'class' => 'rowhead'),
-      t('Import'),
-      t('Export'),
       t('Overall status'),
-      t('Translated'),
-      t('Has suggestions'),
-      t('Untranslated')
+      '', // No header for the status bar label.
+      t('Options')
     ),
     $table,
     array('id' => 'l10n-community-overview')
@@ -236,20 +234,20 @@ function l10n_community_translate_page($
   // Retrieve values stored from the form changes (in case of submit).
   list ($status, $release, $search) = l10n_community_filter_build();
   
-  $strings = l10n_community_get_strings($project, $languages[$langcode]->locale, $status, $release, $search, 10);
+  $strings = l10n_community_get_strings($project, $languages[$langcode]->locale, $status, $release, $search, L10N_PAGE_LIMIT);
   if (!count($strings)) {
     drupal_set_message(t('No strings found with this filter. Try adjusting the filter options.'), 'error');
   }
   elseif ($perm == L10N_PERM_NONE) {
     // For users without permission to translate or suggest, display the view.
     drupal_set_title(t('@language %project translations', array('%project' => $project->title, '@language' => $languages[$langcode]->name)));
-    $output .= drupal_get_form('l10n_community_translate_view', $strings, $languages[$langcode], $uri);
+    $output .= l10n_community_translate_view($strings, $languages[$langcode], $uri);
   }
   else {
     // For users with some permission, display the form.
     drupal_add_js(drupal_get_path('module', 'l10n_community') .'/l10n_community.js');
     drupal_set_title(t('Translate %project to @language', array('%project' => $project->title, '@language' => $languages[$langcode]->name)));
-    $output .= drupal_get_form('l10n_community_translate_form', $strings, $languages[$langcode], $uri, $perm);
+    $output .= l10n_community_translate_view($strings, $languages[$langcode], $uri); //TODO: send $perm
   }
   return $output;
 }
@@ -340,37 +338,25 @@ function l10n_community_filter_build() {
  *   Project URI.
  */
 function l10n_community_translate_view($strings = array(), $language = NULL, $uri = NULL) {
-  $pager = theme('pager', NULL, 10, 0);
+  $pager = theme('pager', NULL, L10N_PAGE_LIMIT, 0);
   
-  $form = array(
-    '#tree' => TRUE
-  );
-  $form['pager_top'] = array(
-    '#value' => $pager,
-  );
+  $table = array();
   foreach ($strings as $string) {
-    // Include a fieldset for each source string. Although sid is not globally
-    // unique, it is unique if we already limit to one language, which
-    // fits here. So we can use that for form item identification.
-    $form[$string->sid] = array(
-      '#type' => 'fieldset',
-    );
+    $source = '<span class="toolbox"></span> ';
     $is_plural = strpos($string->value, "\0");
     if ($is_plural) {
       // Multiple source strings if we deal with plurals.
-      $source = theme('item_list', array_map('l10n_community_format_text', explode(chr(0), $string->value)), '');
+      $source .= theme('item_list', array_map('l10n_community_format_text', explode(chr(0), $string->value)), '');
     }
     else {
       // Single source string otherwise.
-      $source = l10n_community_format_text($string->value);
+      $source .= l10n_community_format_text($string->value);
     }
-    $form[$string->sid]['source'] = array(
-      '#type' => 'markup',
-      '#value' => $source,
-    );
+    $source .= '<div class="info-pane"></div> ';
+    
     if (!empty($string->translation)) {
       if ($is_plural) {
-        $translations = explode(chr(0), $string->translation);
+        $translations = explode(chr(0), l10n_community_format_text($string->translation));
         // Fill in any missing items, so it is shown that not all items are done.
         if (count($translations) < $language->plurals) {
           $translations = array_merge($translations, array_fill(0, count($translations) - $language->plurals, '')); 
@@ -378,18 +364,46 @@ function l10n_community_translate_view($
         $translation = theme('item_list', $translations);
       }
       else {
-        $translation = $string->translation;
+        $translation = l10n_community_format_text($string->translation);
       }
-      $form[$string->sid]['translation'] = array(
-        '#type' => 'markup',
-        '#value' => '<div class="translation">'. $translation .'</div>',
-      );
+      $action = l(t('Edit'), '');
+    }
+    else {
+      $translation = '';
+      $action = l(t('Translate'), '');
     }
+    
+    if($string->has_suggestion) {
+      $translation = theme('l10n_community_has_suggestion') . $translation .'<div class="suggestion-pane"></div>';
+    }
+    
+    $rows[] = array('data' => array($source, $translation, $action), 'id' => 'l10n-community-editor-'. $string->sid);
   }
-  $form['pager_bottom'] = array(
-    '#value' => $pager,
+  $header = array(
+    t('English text (source)'),
+    t('@language text (translation)', array('@language' => $language->name)),
+    t('Action'),
   );
-  return $form;
+
+  // Add all strings for copy-pasting and some helpers.
+  drupal_add_js(
+    array(
+      'l10n_strings'          => $js_strings,
+
+      'l10n_image_path'       => base_path() . drupal_get_path('module', 'l10n_community') . '/images/',
+
+      'l10n_expand_help'      => t('Show the translation editing field.'),
+      'l10n_lookup_help'      => t('Show detailed information about this string.'),
+      'l10n_approve_error'    => t('There was an error approving this suggestion. You might not have permission or the suggestion id was invalid.'),
+      'l10n_approve_confirm'  => t('Suggestion approved.'),
+
+      'l10n_details_callback' => url('translate/details/'. $language->locale .'/'),
+      'l10n_approve_callback' => url('translate/approve/'),
+    ),
+    'setting'
+  );
+
+  return $pager . theme('table', $header, $rows, array('id' => 'l10n-community-phrases')) . $pager;
 }
 
 // = Translation editor ========================================================
@@ -416,7 +430,7 @@ function l10n_community_translate_form($
     '#tree' => TRUE
   );
   $form['pager'] = array(
-    '#value' => theme('pager', NULL, 10, 0)
+    '#value' => theme('pager', NULL, L10N_PAGE_LIMIT, 0)
   );
   // Keep language code and URI in form for further reference.
   $form['langcode'] = array(
@@ -682,8 +696,8 @@ function l10n_community_format_text($str
 function theme_l10n_community_progress_columns($sum, $translated, $has_suggestion) {
   // Compute numbers, percentages and provide alternate text titles.
   $status = array(
-    'translated'     => array((int) $translated, round($translated / $sum * 100, 2), t('!percent translated')),
-    'has-suggestion' => array((int) $has_suggestion, round($has_suggestion / $sum * 100, 2),  t('!percent has suggestion')),
+    'translated'     => array((int) $translated, round($translated / $sum * 100), t('!percent translated')),
+    'has-suggestion' => array((int) $has_suggestion, round($has_suggestion / $sum * 100),  t('!percent has suggestion')),
     'untranslated'   => array($sum - $translated - $has_suggestion, 0, t('!percent untranslated')),
   );
   $status['untranslated'][1] = 100 - $status['has-suggestion'][1] - $status['translated'][1];
@@ -697,11 +711,13 @@ function theme_l10n_community_progress_c
   }
   $bar .= '</div>';
   
+  $bar_label = '<strong>'. t('@translated% translated', array('@translated' => $status['translated'][1])) .'</strong>';
+  $bar_label .= $status['has-suggestion'][0] ? ', '. t('@count suggested', array('@count' => $status['has-suggestion'][0])) : '';
+  $bar_label .= $status['untranslated'][0] ? ', '. t('@count untranslated', array('@count' => $status['untranslated'][0])) : '';
+  
   return array(
     $bar,
-    $status['translated'][0] .' ('. $status['translated'][1] .'%)',
-    $status['has-suggestion'][0],
-    $status['untranslated'][0]
+    array('data' => '('. $bar_label .')', 'class' => 'l10n-community-status-label')
   );
 }
 
@@ -715,3 +731,7 @@ function theme_l10n_community_copy_butto
   $title = t('Copy value to edit field.');
   return ' <span title="'. $title .'" id="l10n-community-copy-'. $sid .'" class="l10n-community-copy"></span>';
 }
+
+function theme_l10n_community_has_suggestion() {
+  return '<span class="has-suggestion"></span>';
+}
\ No newline at end of file
