[rkward-cvs] SF.net SVN: rkward-code:[4976] trunk/rkward/rkward

tfry at users.sf.net tfry at users.sf.net
Wed Oct 29 10:07:10 UTC 2014


Revision: 4976
          http://sourceforge.net/p/rkward/code/4976
Author:   tfry
Date:     2014-10-29 10:07:09 +0000 (Wed, 29 Oct 2014)
Log Message:
-----------
Add i18n-capability to .js backend.
 - No message extraction, yet.
 - Not added to UI logic scripting, yet.

Modified Paths:
--------------
    trunk/rkward/rkward/misc/rkmessagecatalog.cpp
    trunk/rkward/rkward/misc/rkmessagecatalog.h
    trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
    trunk/rkward/rkward/scriptbackends/CMakeLists.txt
    trunk/rkward/rkward/scriptbackends/common.js
    trunk/rkward/rkward/scriptbackends/qtscriptbackend.cpp
    trunk/rkward/rkward/scriptbackends/qtscriptbackend.h

Added Paths:
-----------
    trunk/rkward/rkward/scriptbackends/qtscripti18n.cpp
    trunk/rkward/rkward/scriptbackends/qtscripti18n.h

Modified: trunk/rkward/rkward/misc/rkmessagecatalog.cpp
===================================================================
--- trunk/rkward/rkward/misc/rkmessagecatalog.cpp	2014-10-29 10:05:06 UTC (rev 4975)
+++ trunk/rkward/rkward/misc/rkmessagecatalog.cpp	2014-10-29 10:07:09 UTC (rev 4976)
@@ -53,12 +53,31 @@
 	return QString::fromUtf8 (trans);
 }
 
+QString RKMessageCatalog::translate (const QString &msgctxt, const QString &msgid_singular, const QString &msgid_plural, unsigned long int count) const {
+	RK_TRACE (MISC);
+
+	QByteArray key = (msgctxt + GETTEXT_CONTEXT_GLUE + msgid_singular).toUtf8 ();
+	QByteArray pkey = msgid_plural.toUtf8 ();
+	const char *trans = dngettext (catalog_name, key, pkey, count);
+	if ((trans == key) || (trans == pkey)) {
+		if (count == 1) return msgid_singular.arg (count);
+		return msgid_plural.arg (count);
+	}
+	return QString::fromUtf8 (trans).arg (count);
+}
+
 QString RKMessageCatalog::translate (const QString &msgid) const {
 	RK_TRACE (MISC);
 
 	return QString::fromUtf8 (dgettext (catalog_name, msgid.toUtf8 ()));
 }
 
+QString RKMessageCatalog::translate (const QString &msgid_singular, const QString &msgid_plural, unsigned long int count) const {
+	RK_TRACE (MISC);
+
+	return QString::fromUtf8 (dngettext (catalog_name, msgid_singular.toUtf8 (), msgid_plural.toUtf8 (), count)).arg (count);
+}
+
 // static
 RKMessageCatalog* RKMessageCatalog::getCatalog (const QString& name, const QString& pathhint) {
 	RK_TRACE (MISC);

Modified: trunk/rkward/rkward/misc/rkmessagecatalog.h
===================================================================
--- trunk/rkward/rkward/misc/rkmessagecatalog.h	2014-10-29 10:05:06 UTC (rev 4975)
+++ trunk/rkward/rkward/misc/rkmessagecatalog.h	2014-10-29 10:07:09 UTC (rev 4976)
@@ -30,8 +30,10 @@
  */
 class RKMessageCatalog {
 public:
+	QString translate (const QString &msgid) const;
 	QString translate (const QString &msgctxt, const QString &msgid) const;
-	QString translate (const QString &msgid) const;
+	QString translate (const QString &msgid_singular, const QString &msgid_plural, unsigned long int count) const;
+	QString translate (const QString &msgctxt, const QString &msgid_singular, const QString &msgid_plural, unsigned long int count) const;
 
 /** Get the catalog identified by name. This could be an already open catalog, or a new one. In the latter case, the catalog is expected at pathhint. In the former case, pathhint is ignored. This function is guaranteed to return a non-null RKMessageCatalog, although that does not imply the catalog could actually be loaded. */
 	static RKMessageCatalog *getCatalog (const QString &name, const QString &pathhint);

Modified: trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponent.cpp	2014-10-29 10:05:06 UTC (rev 4975)
+++ trunk/rkward/rkward/plugin/rkstandardcomponent.cpp	2014-10-29 10:07:09 UTC (rev 4976)
@@ -104,7 +104,7 @@
 	if (element.hasAttribute ("file")) {
 		QString dummy = QFileInfo (filename).path() + '/' + xml->getStringAttribute (element, "file", "code.js", DL_WARNING);
 
-		backend = new QtScriptBackend (dummy);
+		backend = new QtScriptBackend (dummy, xml->messageCatalog ());
 	} else {
 		SimpleBackend *back = new SimpleBackend ();
 		back->setPreprocessTemplate (xml->getStringAttribute (element, "preprocess", QString::null, DL_INFO));

Modified: trunk/rkward/rkward/scriptbackends/CMakeLists.txt
===================================================================
--- trunk/rkward/rkward/scriptbackends/CMakeLists.txt	2014-10-29 10:05:06 UTC (rev 4975)
+++ trunk/rkward/rkward/scriptbackends/CMakeLists.txt	2014-10-29 10:07:09 UTC (rev 4976)
@@ -7,6 +7,7 @@
    scriptbackend.cpp
    simplebackend.cpp
    qtscriptbackend.cpp
+   qtscripti18n.cpp
    rkcomponentscripting.cpp
    )
 

Modified: trunk/rkward/rkward/scriptbackends/common.js
===================================================================
--- trunk/rkward/rkward/scriptbackends/common.js	2014-10-29 10:05:06 UTC (rev 4975)
+++ trunk/rkward/rkward/scriptbackends/common.js	2014-10-29 10:07:09 UTC (rev 4976)
@@ -28,20 +28,6 @@
 	return ("\"" + text.replace (/\"/g, "\\\"") + "\"");
 }
 
-/** Yet unused: Dummies for i18n(), for later backwards-compatibility of plugins. */
-i18n = function (string) {
-	return string;
-}
-i18np = function (string) {
-	return string;
-}
-i18nc = function (comment, string) {
-	return string;
-}
-i18ncp = function (comment, string) {
-	return string;
-}
-
 makeHeaderCode = function (title, parameters) {
 	echo ("rk.header(" + quote (title));
 	if (parameters.length) {

Modified: trunk/rkward/rkward/scriptbackends/qtscriptbackend.cpp
===================================================================
--- trunk/rkward/rkward/scriptbackends/qtscriptbackend.cpp	2014-10-29 10:05:06 UTC (rev 4975)
+++ trunk/rkward/rkward/scriptbackends/qtscriptbackend.cpp	2014-10-29 10:07:09 UTC (rev 4976)
@@ -23,14 +23,16 @@
 #include "kmessagebox.h"
 
 #include "../misc/rkcommonfunctions.h"
+#include "qtscripti18n.h"
 
 #include "../debug.h"
 
-QtScriptBackend::QtScriptBackend (const QString &filename) : ScriptBackend () {
+QtScriptBackend::QtScriptBackend (const QString &filename, const RKMessageCatalog *catalog) : ScriptBackend () {
 	RK_TRACE (PHP);
 
 	script_thread = 0;
 	QtScriptBackend::filename = filename;
+	QtScriptBackend::catalog = catalog;
 	dead = false;
 	busy = true;
 }
@@ -53,7 +55,7 @@
 	QDir files_path (RKCommonFunctions::getRKWardDataDir () + "phpfiles/");
 	QString common_js (files_path.absoluteFilePath ("common.js"));
 
-	script_thread = new QtScriptBackendThread (common_js, filename, this);
+	script_thread = new QtScriptBackendThread (common_js, filename, this, catalog);
 	connect (script_thread, SIGNAL (error(const QString&)), this, SLOT (threadError(const QString&)));
 	connect (script_thread, SIGNAL (commandDone(const QString&)), this, SLOT (commandDone(const QString&)));
 	connect (script_thread, SIGNAL (needData(const QString&, const int)), this, SLOT (needData(const QString&, const int)));
@@ -141,13 +143,14 @@
 
 #include <kurl.h>
 
-QtScriptBackendThread::QtScriptBackendThread (const QString &commonfile, const QString &scriptfile, QtScriptBackend *parent) : QThread (parent) {
+QtScriptBackendThread::QtScriptBackendThread (const QString &commonfile, const QString &scriptfile, QtScriptBackend *parent, const RKMessageCatalog *catalog) : QThread (parent) {
 	RK_TRACE (PHP);
 
 	_commonfile = commonfile;
 	_scriptfile = scriptfile;
 	killed = false;
 	sleeping = false;
+	QtScriptBackendThread::catalog = catalog;
 }
 
 QtScriptBackendThread::~QtScriptBackendThread () {
@@ -268,6 +271,8 @@
 
 	QScriptValue backend_object = engine.newQObject (this);
 	engine.globalObject ().setProperty ("_RK_backend", backend_object);
+	RKMessageCatalogObject::addI18nToScriptEngine (&engine, catalog);
+	if (scriptError ()) return;
 
 	if (!includeFile (_commonfile)) return;
 	if (!includeFile (_scriptfile)) return;

Modified: trunk/rkward/rkward/scriptbackends/qtscriptbackend.h
===================================================================
--- trunk/rkward/rkward/scriptbackends/qtscriptbackend.h	2014-10-29 10:05:06 UTC (rev 4975)
+++ trunk/rkward/rkward/scriptbackends/qtscriptbackend.h	2014-10-29 10:07:09 UTC (rev 4976)
@@ -21,6 +21,7 @@
 #include "scriptbackend.h"
 
 class QtScriptBackendThread;
+class RKMessageCatalog;
 
 /** This class allows to use QtScript as a scripting backend in RKWard.
 
@@ -30,7 +31,7 @@
 class QtScriptBackend : public ScriptBackend {
 	Q_OBJECT
 public:
-	QtScriptBackend (const QString &filename);
+	QtScriptBackend (const QString &filename, const RKMessageCatalog *catalog);
 
 	~QtScriptBackend ();
 
@@ -49,6 +50,7 @@
 private:
 	void tryNextFunction ();
 	QtScriptBackendThread *script_thread;
+	const RKMessageCatalog *catalog;
 
 	bool dead;
 
@@ -62,7 +64,7 @@
 class QtScriptBackendThread : public QThread {
 	Q_OBJECT
 public:
-	QtScriptBackendThread (const QString &commonfile, const QString &scriptfile, QtScriptBackend *parent);
+	QtScriptBackendThread (const QString &commonfile, const QString &scriptfile, QtScriptBackend *parent, const RKMessageCatalog *catalog);
 	~QtScriptBackendThread ();
 
 	void setCommand (const QString &command);
@@ -92,6 +94,7 @@
 	QString _scriptfile;
 
 	QScriptEngine engine;
+	const RKMessageCatalog *catalog;
 
 	bool killed;
 

Added: trunk/rkward/rkward/scriptbackends/qtscripti18n.cpp
===================================================================
--- trunk/rkward/rkward/scriptbackends/qtscripti18n.cpp	                        (rev 0)
+++ trunk/rkward/rkward/scriptbackends/qtscripti18n.cpp	2014-10-29 10:07:09 UTC (rev 4976)
@@ -0,0 +1,48 @@
+/***************************************************************************
+                          qtscripti18n  -  description
+                             -------------------
+    begin                : Wed Oct 29 2014
+    copyright            : (C) 2014 by Thomas Friedrichsmeier
+    email                : tfry at users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/ 
+
+#include "qtscripti18n.h"
+
+#include <QScriptEngine>
+
+#include "../debug.h"
+
+void RKMessageCatalogObject::addI18nToScriptEngine (QScriptEngine* engine, const RKMessageCatalog* catalog) {
+	QScriptValue handle = engine->newQObject (new RKMessageCatalogObject (catalog, engine));
+	engine->globalObject ().setProperty ("_i18n", handle);
+
+	const int n_funs = 4;
+	// NOTE that we exploit the fact that these are ordered by number of arguments from 1 to 4, below.
+	QLatin1String funs [n_funs] = { 
+		QLatin1String ("i18n(msgid)"), 
+		QLatin1String ("i18nc(msgctxt, msgid)"), 
+		QLatin1String ("i18np(msgid, msgid_plural, count)"), 
+		QLatin1String ("i18ncp(msgctxt, msgid, msgid_plural, count)")
+	};
+	QString eval;
+	for (int i = 0; i < n_funs; ++i) {
+		eval += QLatin1String ("function ") + funs[i] + QLatin1String ("{ ret = _i18n.") + funs[i] + ";\n"
+		      + QLatin1String ("argn=") + ((i < 2) ? QLatin1String ("1") : QLatin1String ("2")) + ";\n"
+		      + QLatin1String ("for (i=") + QString::number (i+1) + QLatin1String ("; i<arguments.length; i++) ")
+			  + QLatin1String ("ret = ret.replace(new RegExp(\"%\"+argn++, 'g'), arguments[i]);\n")
+			  + QLatin1String ("return(ret); }\n");
+	}
+	RK_DEBUG (PHP, DL_DEBUG, "Evaluating i18n glue code:\n%s", qPrintable (eval));
+	engine->evaluate (eval);
+}
+
+#include "qtscripti18n.moc"

Added: trunk/rkward/rkward/scriptbackends/qtscripti18n.h
===================================================================
--- trunk/rkward/rkward/scriptbackends/qtscripti18n.h	                        (rev 0)
+++ trunk/rkward/rkward/scriptbackends/qtscripti18n.h	2014-10-29 10:07:09 UTC (rev 4976)
@@ -0,0 +1,51 @@
+/***************************************************************************
+                          qtscripti18n  -  description
+                             -------------------
+    begin                : Wed Oct 29 2014
+    copyright            : (C) 2014 by Thomas Friedrichsmeier
+    email                : tfry at users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/ 
+
+#ifndef QTSCRIPTI18N_H
+#define QTSCRIPTI18N_H
+
+#include "../misc/rkmessagecatalog.h"
+
+class QScriptEngine;
+/** A QObject wrapper around RKMessageCatalog. Meant for use in RKComponentScripting and QtScriptBackend */
+class RKMessageCatalogObject : public QObject {
+	Q_OBJECT
+public:
+	RKMessageCatalogObject (const RKMessageCatalog *_catalog, QObject *parent) : QObject (parent), catalog (_catalog) {};
+	virtual ~RKMessageCatalogObject () {};
+
+	Q_INVOKABLE QString i18n (const QString &msgid) const {
+		return (catalog->translate (msgid));
+	};
+	Q_INVOKABLE QString i18nc (const QString &msgctxt, const QString &msgid) const {
+		return (catalog->translate (msgctxt, msgid));
+	};
+	Q_INVOKABLE QString i18np (const QString &msgid_singular, const QString &msgid_plural, unsigned long int count) const {
+		return (catalog->translate (msgid_singular, msgid_plural, count));
+	};
+	Q_INVOKABLE QString i18ncp (const QString &msgctxt, const QString &msgid_singular, const QString &msgid_plural, unsigned long int count) const {
+		return (catalog->translate (msgctxt, msgid_singular, msgid_plural, count).arg (count));
+	};
+/** Add an RKMessageCatalog, and the required glue code to the given QScriptEngine. */
+	static void addI18nToScriptEngine (QScriptEngine *engine, const RKMessageCatalog *catalog);
+private:
+	const RKMessageCatalog *catalog;
+};
+
+
+
+#endif





More information about the rkward-tracker mailing list