openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #09603
[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:
Jonathan Corwin (j-corwin)
Tim Bentley (trb143)
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/63027
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/63027
Your team OpenLP Core is subscribed to branch 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 18:24:33 +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/json2.js' (properties changed: +x to -x)
=== 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 18:24:33 +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,15 @@
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,19 +231,23 @@
);
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 id = $("#selected-item").val();
var text = JSON.stringify({"request": {"id": id}});
$.getJSON(
"/api/" + $("#search-plugin").val() + "/add",
@@ -253,6 +256,7 @@
history.back();
}
);
+ $("#options").dialog("close");
return false;
}
}
@@ -274,6 +278,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 18:24:33 +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 18:24:33 +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 18:24:33 +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