diff --git a/i18n_string/i18n_string.module b/i18n_string/i18n_string.module
index 9c232c0..9ef8b17 100644
--- a/i18n_string/i18n_string.module
+++ b/i18n_string/i18n_string.module
@@ -152,6 +152,15 @@ function i18n_string_menu_alter(&$items) {
'file' => 'i18n_string.pages.inc',
'file path' => drupal_get_path('module', 'i18n_string'),
);
+ $items['admin/config/regional/translate/translate'] = array(
+ 'title' => 'Translate',
+ 'weight' => 10,
+ 'type' => MENU_LOCAL_TASK,
+ 'page callback' => 'i18n_string_locale_translate_seek_screen',
+ 'access arguments' => array('translate interface'),
+ 'file' => 'i18n_string.pages.inc',
+ 'file path' => drupal_get_path('module', 'i18n_string'),
+ );
}
/**
diff --git a/i18n_string/i18n_string.pages.inc b/i18n_string/i18n_string.pages.inc
index 4d0da59..ec6afbf 100644
--- a/i18n_string/i18n_string.pages.inc
+++ b/i18n_string/i18n_string.pages.inc
@@ -443,3 +443,143 @@ function _i18n_string_translate_format_help($format_id) {
}
return $output;
}
+
+/**
+ * String search & translate screen.
+ *
+ * Almost exactly the same as the core locale module's implementation, but
+ * taking i18n_string_source_language into account for the languages column.
+ */
+function i18n_string_locale_translate_seek_screen() {
+ // Add CSS.
+ drupal_add_css(drupal_get_path('module', 'locale') . '/locale.css');
+
+ $elements = drupal_get_form('locale_translation_filter_form');
+ $output = drupal_render($elements);
+ $output .= _i18n_string_locale_translate_seek();
+ return $output;
+}
+
+/**
+ * Perform a string search and display results in a table
+ */
+function _i18n_string_locale_translate_seek() {
+ $output = '';
+
+ // We have at least one criterion to match
+ if (!($query = _locale_translate_seek_query())) {
+ $query = array(
+ 'translation' => 'all',
+ 'group' => 'all',
+ 'language' => 'all',
+ 'string' => '',
+ );
+ }
+
+ $sql_query = db_select('locales_source', 's');
+
+ $limit_language = NULL;
+ if ($query['language'] != 'en' && $query['language'] != 'all') {
+ $sql_query->leftJoin('locales_target', 't', "t.lid = s.lid AND t.language = :langcode", array(':langcode' => $query['language']));
+ $limit_language = $query['language'];
+ }
+ else {
+ $sql_query->leftJoin('locales_target', 't', 't.lid = s.lid');
+ }
+
+ $sql_query->fields('s', array('source', 'location', 'context', 'lid', 'textgroup'));
+ $sql_query->fields('t', array('translation', 'language'));
+
+ // Compute LIKE section.
+ switch ($query['translation']) {
+ case 'translated':
+ $sql_query->condition('t.translation', '%' . db_like($query['string']) . '%', 'LIKE');
+ $sql_query->orderBy('t.translation', 'DESC');
+ break;
+ case 'untranslated':
+ $sql_query->condition(db_and()
+ ->condition('s.source', '%' . db_like($query['string']) . '%', 'LIKE')
+ ->isNull('t.translation')
+ );
+ $sql_query->orderBy('s.source');
+ break;
+ case 'all' :
+ default:
+ $condition = db_or()
+ ->condition('s.source', '%' . db_like($query['string']) . '%', 'LIKE');
+ if ($query['language'] != 'en') {
+ // Only search in translations if the language is not forced to English.
+ $condition->condition('t.translation', '%' . db_like($query['string']) . '%', 'LIKE');
+ }
+ $sql_query->condition($condition);
+ break;
+ }
+
+ // Add a condition on the text group.
+ if (!empty($query['group']) && $query['group'] != 'all') {
+ $sql_query->condition('s.textgroup', $query['group']);
+ }
+
+ $sql_query = $sql_query->extend('PagerDefault')->limit(50);
+ $locales = $sql_query->execute();
+
+ $groups = module_invoke_all('locale', 'groups');
+ $header = array(t('Text group'), t('String'), t('Context'), ($limit_language) ? t('Language') : t('Languages'), array('data' => t('Operations'), 'colspan' => '2'));
+
+ $strings = array();
+ foreach ($locales as $locale) {
+ if (!isset($strings[$locale->lid])) {
+ $strings[$locale->lid] = array(
+ 'group' => $locale->textgroup,
+ 'languages' => array(),
+ 'location' => $locale->location,
+ 'source' => $locale->source,
+ 'context' => $locale->context,
+ );
+ }
+ if (isset($locale->language)) {
+ $strings[$locale->lid]['languages'][$locale->language] = $locale->translation;
+ }
+ }
+
+ $rows = array();
+ foreach ($strings as $lid => $string) {
+ $rows[] = array(
+ $groups[$string['group']],
+ array('data' => check_plain(truncate_utf8($string['source'], 150, FALSE, TRUE)) . '
' . $string['location'] . ''),
+ $string['context'],
+ array('data' => _i18n_string_locale_translate_language_list($string, $limit_language), 'align' => 'center'),
+ array('data' => l(t('edit'), "admin/config/regional/translate/edit/$lid", array('query' => drupal_get_destination())), 'class' => array('nowrap')),
+ array('data' => l(t('delete'), "admin/config/regional/translate/delete/$lid", array('query' => drupal_get_destination())), 'class' => array('nowrap')),
+ );
+ }
+
+ $output .= theme('table', array('header' => $header, 'rows' => $rows, 'empty' => t('No strings available.')));
+ $output .= theme('pager');
+
+ return $output;
+}
+
+/**
+ * List languages in search result table.
+ */
+function _i18n_string_locale_translate_language_list($string, $limit_language) {
+ // Add CSS.
+ drupal_add_css(drupal_get_path('module', 'locale') . '/locale.css');
+
+ // Include both translated and not yet translated target languages in the
+ // list. The source language is English for built-in strings and the default
+ // language for other strings.
+ $languages = language_list();
+ $default = language_default();
+ $omit = $string['group'] == 'default' ? 'en' : variable_get('i18n_string_source_language', $default->language);
+ unset($languages[$omit]);
+ $output = '';
+ foreach ($languages as $langcode => $language) {
+ if (!$limit_language || $limit_language == $langcode) {
+ $output .= (!empty($string['languages'][$langcode])) ? $langcode . ' ' : "$langcode ";
+ }
+ }
+
+ return $output;
+}