← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~raoul-snyman/openlp/bug-790382 into lp:openlp

 

Raoul Snyman has proposed merging lp:~raoul-snyman/openlp/bug-790382 into lp:openlp.

Requested reviews:
  OpenLP Core (openlp-core)
Related bugs:
  Bug #790382 in OpenLP: "Localize remote html interface"
  https://bugs.launchpad.net/openlp/+bug/790382

For more details, see:
https://code.launchpad.net/~raoul-snyman/openlp/bug-790382/+merge/63021

Added translation of the web remote interface by using a templating engine.

BEWARE: You need "Mako" installed!
-- 
https://code.launchpad.net/~raoul-snyman/openlp/bug-790382/+merge/63021
Your team OpenLP Core is requested to review the proposed merge of lp:~raoul-snyman/openlp/bug-790382 into lp:openlp.
=== modified file 'openlp/plugins/remotes/html/index.html'
--- openlp/plugins/remotes/html/index.html	2011-05-24 20:47:05 +0000
+++ openlp/plugins/remotes/html/index.html	2011-05-31 17:39:25 +0000
@@ -27,91 +27,109 @@
 -->
 <head>
   <meta charset="utf-8" />
-  <title>OpenLP 2.0 Remote</title>
+  <title>${app_title}</title>
   <link rel="stylesheet" href="/files/jquery.mobile.css" />
   <link rel="stylesheet" href="/files/openlp.css" />
   <script type="text/javascript" src="/files/jquery.js"></script>
   <script type="text/javascript" src="/files/openlp.js"></script>
   <script type="text/javascript" src="/files/jquery.mobile.js"></script>
+  <script type="text/javascript">
+  translationStrings = {
+    "go_live": "${go_live}",
+    "add_to_service": "${add_to_service}",
+    "no_results": "${no_results}",
+    "back": "${back}"
+  }
+  </script>
 </head>
 <body>
 <div data-role="page" id="home">
   <div data-role="header">
-    <h1>OpenLP 2.0 Remote</h1>
+    <h1>${app_title}</h1>
   </div>
   <div data-role="content">
     <div data-role="controlgroup">
-      <a href="#service-manager" data-role="button" data-icon="arrow-r" data-iconpos="right">Service Manager</a>
-      <a href="#slide-controller" data-role="button" data-icon="arrow-r" data-iconpos="right">Slide Controller</a>
-      <a href="#alerts" data-role="button" data-icon="arrow-r" data-iconpos="right">Alerts</a>
-      <a href="#search" data-role="button" data-icon="arrow-r" data-iconpos="right">Search</a>
+      <a href="#service-manager" data-role="button" data-icon="arrow-r" data-iconpos="right">${service_manager}</a>
+      <a href="#slide-controller" data-role="button" data-icon="arrow-r" data-iconpos="right">${slide_controller}</a>
+      <a href="#alerts" data-role="button" data-icon="arrow-r" data-iconpos="right">${alerts}</a>
+      <a href="#search" data-role="button" data-icon="arrow-r" data-iconpos="right">${search}</a>
     </div>
   </div>
 </div>
 <div data-role="page" id="service-manager">
   <div data-role="header">
-    <a href="#" data-rel="back" data-icon="arrow-l">Back</a>
-    <h1>Service Manager</h1>
-    <a href="#" id="service-refresh" data-role="button" data-icon="refresh">Refresh</a>
+    <a href="#" data-rel="back" data-icon="arrow-l">${back}</a>
+    <h1>${service_manager}</h1>
+    <a href="#" id="service-refresh" data-role="button" data-icon="refresh">${refresh}</a>
   </div>
   <div data-role="content">
     <ul data-role="listview" data-inset="true">
     </ul>
   </div>
   <div data-role="footer" data-theme="b" class="ui-bar">
-    <a href="#" id="service-blank" data-role="button" data-icon="blank">Blank</a>
-    <a href="#" id="service-unblank" data-role="button" data-icon="unblank">Show</a>
-    <a href="#" id="service-previous" data-role="button" data-icon="arrow-l">Prev</a>
-    <a href="#" id="service-next" data-role="button" data-icon="arrow-r" data-iconpos="right">Next</a>
+    <a href="#" id="service-blank" data-role="button" data-icon="blank">${blank}</a>
+    <a href="#" id="service-unblank" data-role="button" data-icon="unblank">${show}</a>
+    <a href="#" id="service-previous" data-role="button" data-icon="arrow-l">${prev}</a>
+    <a href="#" id="service-next" data-role="button" data-icon="arrow-r" data-iconpos="right">${next}</a>
   </div>
 </div>
 <div data-role="page" id="slide-controller">
   <div data-role="header">
-    <a href="#" data-rel="back" data-icon="arrow-l">Back</a>
-    <h1>Slide Controller</h1>
-    <a href="#" id="controller-refresh" data-role="button" data-icon="refresh">Refresh</a>
+    <a href="#" data-rel="back" data-icon="arrow-l">${back}</a>
+    <h1>${slide_controller}</h1>
+    <a href="#" id="controller-refresh" data-role="button" data-icon="refresh">${refresh}</a>
   </div>
   <div data-role="content">
     <ul data-role="listview" data-inset="true">
     </ul>
   </div>
   <div data-role="footer" data-theme="b" class="ui-bar">
-    <a href="#" id="controller-blank" data-role="button" data-icon="blank">Blank</a>
-    <a href="#" id="controller-unblank" data-role="button" data-icon="unblank">Show</a>
-    <a href="#" id="controller-previous" data-role="button" data-icon="arrow-l">Prev</a>
-    <a href="#" id="controller-next" data-role="button" data-icon="arrow-r" data-iconpos="right">Next</a>
+    <a href="#" id="controller-blank" data-role="button" data-icon="blank">${blank}</a>
+    <a href="#" id="controller-unblank" data-role="button" data-icon="unblank">${show}</a>
+    <a href="#" id="controller-previous" data-role="button" data-icon="arrow-l">${prev}</a>
+    <a href="#" id="controller-next" data-role="button" data-icon="arrow-r" data-iconpos="right">${next}</a>
   </div>
 </div>
 <div data-role="page" id="alerts">
   <div data-role="header">
-    <a href="#" data-rel="back" data-icon="arrow-l">Back</a>
-    <h1>Alerts</h1>
+    <a href="#" data-rel="back" data-icon="arrow-l">${back}</a>
+    <h1>${alerts}</h1>
   </div>
   <div data-role="content">
     <div data-role="fieldcontain">
-      <label for="alert-text">Text:</label>
+      <label for="alert-text">${text}:</label>
       <input type="text" name="alert-text" id="alert-text" value="" />
     </div>
-    <a href="#" id="alert-submit" data-role="button">Show Alert</a>
+    <a href="#" id="alert-submit" data-role="button">${show_alert}</a>
   </div>
 </div>
 <div data-role="page" id="search">
   <div data-role="header">
-    <a href="#" data-rel="back" data-icon="arrow-l">Back</a>
-    <h1>Search</h1>
+    <a href="#" data-rel="back" data-icon="arrow-l">${back}</a>
+    <h1>${search}</h1>
   </div>
   <div data-role="content">
     <div data-role="fieldcontain">
-      <label for="search-plugin">Search:</label>
+      <label for="search-plugin">${search}:</label>
       <select name="search-plugin" id="search-plugin" data-native-menu="false"></select>
     </div>
     <div data-role="fieldcontain">
-      <label for="search-text">Text:</label>
+      <label for="search-text">${text}:</label>
       <input type="search" name="search-text" id="search-text" value="" />
     </div>
-    <a href="#" id="search-submit" data-role="button">Search</a>
+    <a href="#" id="search-submit" data-role="button">${search}</a>
     <ul data-role="listview" data-inset="true">
   </div>
 </div>
+<div data-role="page" id="options">
+  <div data-role="header" data-position="inline" data-theme="b">
+    <h1>${options}</h1>
+  </div>
+  <div data-role="content">
+    <input type="hidden" id="selected-item" value="" />
+    <a href="#" id="go-live" data-role="button">${go_live}</a>       
+    <a href="#" id="add-to-service" data-role="button">${add_to_service}</a>    
+  </div>
+</div>
 </body>
 </html>

=== modified file 'openlp/plugins/remotes/html/openlp.js'
--- openlp/plugins/remotes/html/openlp.js	2011-05-24 20:47:05 +0000
+++ openlp/plugins/remotes/html/openlp.js	2011-05-31 17:39:25 +0000
@@ -47,7 +47,7 @@
         var select = $("#search-plugin");
         select.html("");
         $.each(data.results.items, function (idx, value) {
-          select.append("<option value='" + value + "'>" + value + "</option>");
+          select.append("<option value='" + value[0] + "'>" + value[1] + "</option>");
         });
         select.selectmenu("refresh");
       }
@@ -215,16 +215,12 @@
         var ul = $("#search > div[data-role=content] > ul[data-role=listview]");
         ul.html("");
         if (data.results.items.length == 0) {
-          var li = $("<li data-icon=\"false\">").text('No results');
+          var li = $("<li data-icon=\"false\">").text(translationStrings["no_results"]);
           ul.append(li);
         }
         else {
             $.each(data.results.items, function (idx, value) {
-              var item = $("<li>").text(value[1]);
-              var golive = $("<a href=\"#\">Go Live</a>").attr("value", value[0]).click(OpenLP.goLive);
-              var additem = $("<a href=\"#\">Add To Service</a>").attr("value", value[0]).click(OpenLP.addToService);
-              item.append($("<ul>").append($("<li>").append(golive)).append($("<li>").append(additem)));
-              ul.append(item);
+              ul.append($("<li>").append($("<a>").attr("href", "#options").attr("data-rel", "dialog").attr("data-transition", "pop").attr("value", value[0]).click(OpenLP.showOptions).text(value[1])));
             });
         }
         ul.listview("refresh");
@@ -232,20 +228,24 @@
     );
     return false;
   },
+  showOptions: function (event) {
+    var element = OpenLP.getElement(event);
+    console.log(element);
+    $("#selected-item").val(element.attr("value"));
+  },
   goLive: function (event) {
-    var item = OpenLP.getElement(event);
-    var id = item.attr("value");
+    var id = $("#selected-item").val();
     var text = JSON.stringify({"request": {"id": id}});
     $.getJSON(
       "/api/" + $("#search-plugin").val() + "/live",
-      {"data": text})
-    $.mobile.changePage("slide-controller");
+      {"data": text}
+    );
+    $.mobile.changePage("#slide-controller");
     return false;
   },
   addToService: function (event) {
-    var item = OpenLP.getElement(event);
-    var id = item.attr("value");
-    var text = JSON.stringify({"request": {"id": id}});
+    var id = $("#selected-item").val();
+    var text = JSON.stringify({"request": {"id": parseInt(id, 10)}});
     $.getJSON(
       "/api/" + $("#search-plugin").val() + "/add",
       {"data": text},
@@ -253,6 +253,7 @@
         history.back();
       }
     );
+    $("#options").dialog("close");
     return false;
   }
 }
@@ -274,6 +275,8 @@
 $("#alert-submit").live("click", OpenLP.showAlert);
 // Search
 $("#search-submit").live("click", OpenLP.search);
+$("#go-live").live("click", OpenLP.goLive);
+$("#add-to-service").live("click", OpenLP.addToService);
 // Poll the server twice a second to get any updates.
 OpenLP.getSearchablePlugins();
 $.ajaxSetup({ cache: false });

=== modified file 'openlp/plugins/remotes/html/stage.html'
--- openlp/plugins/remotes/html/stage.html	2011-05-24 20:47:05 +0000
+++ openlp/plugins/remotes/html/stage.html	2011-05-31 17:39:25 +0000
@@ -6,8 +6,8 @@
 # --------------------------------------------------------------------------- #
 # Copyright (c) 2008-2011 Raoul Snyman                                        #
 # Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael      #
-# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        #
-# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      #
+# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        #
+# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      #
 # Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode       #
 # Woldsund                                                                    #
 # --------------------------------------------------------------------------- #
@@ -27,12 +27,13 @@
 -->
 <head>
   <meta charset="utf-8" />
-  <title>OpenLP 2.0 Stage View</title>
+  <title>${stage_title}</title>
   <link rel="stylesheet" href="/files/stage.css" />
   <script type="text/javascript" src="/files/jquery.js"></script>
   <script type="text/javascript" src="/files/stage.js"></script>
 </head>
 <body>
+<input type="hidden" id="next-text" value="${next}" />
 <div id="right">
   <div id="clock"></div>
   <div id="notes"></div>

=== modified file 'openlp/plugins/remotes/html/stage.js'
--- openlp/plugins/remotes/html/stage.js	2011-05-24 20:47:05 +0000
+++ openlp/plugins/remotes/html/stage.js	2011-05-31 17:39:25 +0000
@@ -100,24 +100,24 @@
     $("#tag" + OpenLP.currentTags[OpenLP.currentSlide]).addClass("currenttag");
     var slide = OpenLP.currentSlides[OpenLP.currentSlide];
     var text = slide["text"];
-    text = text.replace(/\n/g, '<br />');
+    text = text.replace(/\n/g, "<br />");
     $("#currentslide").html(text);
     text = "";
     if (OpenLP.currentSlide < OpenLP.currentSlides.length - 1) {
       for (var idx = OpenLP.currentSlide + 1; idx < OpenLP.currentSlides.length; idx++) {
         if (OpenLP.currentTags[idx] != OpenLP.currentTags[idx - 1])
-            text = text + '<p class="nextslide">';
+            text = text + "<p class=\"nextslide\">";
         text = text + OpenLP.currentSlides[idx]["text"];
         if (OpenLP.currentTags[idx] != OpenLP.currentTags[idx - 1])
-            text = text + '</p>';
+            text = text + "</p>";
         else
-            text = text + '<br />';
+            text = text + "<br />";
       }
-      text = text.replace(/\n/g, '<br />');
+      text = text.replace(/\n/g, "<br />");
       $("#nextslide").html(text);
     }
     else {
-      text = '<p class="nextslide">Next: ' + OpenLP.nextSong + '</p>';
+      text = "<p class=\"nextslide\">" + $("#next-text").val() + ": " + OpenLP.nextSong + "</p>";
       $("#nextslide").html(text);
     }
   },

=== modified file 'openlp/plugins/remotes/lib/httpserver.py'
--- openlp/plugins/remotes/lib/httpserver.py	2011-05-28 09:53:37 +0000
+++ openlp/plugins/remotes/lib/httpserver.py	2011-05-31 17:39:25 +0000
@@ -115,7 +115,6 @@
 import os
 import urlparse
 import re
-from pprint import pformat
 
 try:
     import json
@@ -123,10 +122,11 @@
     import simplejson as json
 
 from PyQt4 import QtCore, QtNetwork
+from mako.template import Template
 
-from openlp.core.lib import Receiver, PluginStatus
+from openlp.core.lib import Receiver, PluginStatus, StringContent
 from openlp.core.ui import HideMode
-from openlp.core.utils import AppLocation
+from openlp.core.utils import AppLocation, translate
 
 log = logging.getLogger(__name__)
 
@@ -261,6 +261,7 @@
             self.ready_read)
         QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'disconnected()'),
             self.disconnected)
+        self.translate()
 
     def _get_service_items(self):
         service_items = []
@@ -280,6 +281,31 @@
             })
         return service_items
 
+    def translate(self):
+        """
+        Translate various strings in the mobile app.
+        """
+        self.template_vars = {
+            'app_title': translate('RemotePlugin.Mobile', 'OpenLP 2.0 Remote'),
+            'stage_title': translate('RemotePlugin.Mobile', 'OpenLP 2.0 Stage View'),
+            'service_manager': translate('RemotePlugin.Mobile', 'Service Manager'),
+            'slide_controller': translate('RemotePlugin.Mobile', 'Slide Controller'),
+            'alerts': translate('RemotePlugin.Mobile', 'Alerts'),
+            'search': translate('RemotePlugin.Mobile', 'Search'),
+            'back': translate('RemotePlugin.Mobile', 'Back'),
+            'refresh': translate('RemotePlugin.Mobile', 'Refresh'),
+            'blank': translate('RemotePlugin.Mobile', 'Blank'),
+            'show': translate('RemotePlugin.Mobile', 'Show'),
+            'prev': translate('RemotePlugin.Mobile', 'Prev'),
+            'next': translate('RemotePlugin.Mobile', 'Next'),
+            'text': translate('RemotePlugin.Mobile', 'Text'),
+            'show_alert': translate('RemotePlugin.Mobile', 'Show Alert'),
+            'go_live': translate('RemotePlugin.Mobile', 'Go Live'),
+            'add_to_service': translate('RemotePlugin.Mobile', 'Add To Service'),
+            'no_results': translate('RemotePlugin.Mobile', 'No Results'),
+            'options': translate('RemotePlugin.Mobile', 'Options')
+        }
+
     def ready_read(self):
         """
         Data has been sent from the client. Respond to it
@@ -327,8 +353,11 @@
         if not path.startswith(self.parent.html_dir):
             return HttpResponse(code=u'404 Not Found')
         ext = os.path.splitext(filename)[1]
+        html = None
         if ext == u'.html':
             mimetype = u'text/html'
+            variables = self.template_vars
+            html = Template(filename=path, input_encoding=u'utf-8', output_encoding=u'utf-8').render(**variables)
         elif ext == u'.css':
             mimetype = u'text/css'
         elif ext == u'.js':
@@ -343,9 +372,12 @@
             mimetype = u'text/plain'
         file_handle = None
         try:
-            file_handle = open(path, u'rb')
-            log.debug(u'Opened %s' % path)
-            content = file_handle.read()
+            if html:
+                content = html
+            else:
+                file_handle = open(path, u'rb')
+                log.debug(u'Opened %s' % path)
+                content = file_handle.read()
         except IOError:
             log.exception(u'Failed to open %s' % path)
             return HttpResponse(code=u'404 Not Found')
@@ -460,7 +492,8 @@
             for plugin in self.parent.plugin.pluginManager.plugins:
                 if plugin.status == PluginStatus.Active and \
                     plugin.mediaItem and plugin.mediaItem.hasSearch:
-                    searches.append(plugin.name)
+                    searches.append([plugin.name, unicode(
+                        plugin.textStrings[StringContent.Name][u'plural'])])
             return HttpResponse(
                 json.dumps({u'results': {u'items': searches}}),
                 {u'Content-Type': u'application/json'})
@@ -476,7 +509,7 @@
         plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
         if plugin.status == PluginStatus.Active and \
             plugin.mediaItem and plugin.mediaItem.hasSearch:
-            results =plugin.mediaItem.search(text)
+            results = plugin.mediaItem.search(text)
         else:
             results = []
         return HttpResponse(


Follow ups