[rkward-cvs] [rkward] /: Implement some more string functionality that will be needed for proper i18n of CLT plugins (but should also come in handy, elsewhere)

Thomas Friedrichsmeier thomas.friedrichsmeier at ruhr-uni-bochum.de
Fri Jan 30 20:04:40 UTC 2015


Git commit cec8e458eba3bd8d12b4eaddb31fcc6801ba9ccf by Thomas Friedrichsmeier.
Committed on 30/01/2015 at 20:03.
Pushed by tfry into branch 'master'.

Implement some more string functionality that will be needed for proper i18n of CLT plugins (but should also come in handy, elsewhere)
- <label>-element to insert element labels into .rkh pages
- <i18n>-element to define a translatable string property
- string properties gain modifier "quoted"

M  +3    -0    ChangeLog
M  +36   -1    doc/rkwardplugins/index.docbook
M  +6    -6    rkward/plugin/rkcomponentproperties.cpp
M  +10   -0    rkward/plugin/rkstandardcomponent.cpp
M  +49   -18   rkward/windows/rkhtmlwindow.cpp
M  +9    -2    rkward/windows/rkhtmlwindow.h

http://commits.kde.org/rkward/cec8e458eba3bd8d12b4eaddb31fcc6801ba9ccf

diff --git a/ChangeLog b/ChangeLog
index 8409cd7..ea4c697 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+- New element <i18n> for use in plugins' logic section: Provides a translatable string property
+- New element <label> for use in plugin help pages: Copies the label-attribute of the given element into the text
+- New string property modifier "quoted" to make it easier to quote dynamic strings inside plugins
 - Reworked distribution calculator plugins
 - Added power analysis plugin (already existed as separate plugin)
   - TODO: add automated tests
diff --git a/doc/rkwardplugins/index.docbook b/doc/rkwardplugins/index.docbook
index 4da8d3d..2c298c6 100644
--- a/doc/rkwardplugins/index.docbook
+++ b/doc/rkwardplugins/index.docbook
@@ -2530,7 +2530,17 @@ local({
 <variablelist>
 <varlistentry>
 <term>String properties</term>
-<listitem><para>The most simple type of property, used to simply hold a piece of text. It does not provide any modifiers. If you attempt to fetch modified values from the JS template, it will return the usual value, and a warning will be written to the terminal you're running rkward from.</para></listitem>
+<listitem><para>The most simple type of property, used to simply hold a piece of text. Modifiers:
+	<variablelist>
+	<varlistentry>
+	<term>No modifier ("")</term>
+	<listitem><para>The string as defined / set.</para></listitem>
+	</varlistentry>
+	<varlistentry>
+	<term>quoted</term>
+	<listitem><para>The string in quoted form (suitable for passing to R as character).</para></listitem>
+	</varlistentry>
+	</variablelist></para></listitem>
 </varlistentry>
 <varlistentry>
 <term>Boolean properties</term>
@@ -3324,6 +3334,21 @@ Child-elements:
 </varlistentry>
 
 <varlistentry>
+<term><i18n></term>
+<listitem><para>Creates a new (string) property that is supposed to be provide an i18n'ed label. Attributes:
+	<variablelist>
+	<varlistentry>
+	<term><parameter>id</parameter></term>
+	<listitem><para>The ID of the new property (required)</para></listitem>
+	</varlistentry>
+	<varlistentry>
+	<term><parameter>label</parameter></term>
+	<listitem><para>The label. This will be translated. (required)</para></listitem>
+	</varlistentry>
+	</variablelist></para></listitem>
+</varlistentry>
+
+<varlistentry>
 <term><set></term>
 <listitem><para>Set a property to a fixed value (of course, if you additionally connect the property to some other property, the value does not remain fixed). For instance, if you embed a plugin, but want to hide some of its elements, you might set the visibility property of those elements to false. Useful esp. for embedded/embedding plugins. Note: If there are several <set> elements
 for a single <parameter>id</parameter>, the latest one to be defined takes precendence. This will sometimes be useful to rely on when using <include>d parts.
@@ -4224,6 +4249,16 @@ Child elements:
 	</variablelist></para></listitem>
 </varlistentry>
 <varlistentry>
+<term><label></term>
+<listitem><para>Inserts the value of a UI label. Can be used in any of the sections described above.
+	<variablelist>
+	<varlistentry>
+	<term>id</term>
+	<listitem><para>The id of the element in the plugin, of which to copy the <replaceable>label</replaceable>-attribute.</para></listitem>
+	</varlistentry>
+	</variablelist></para></listitem>
+</varlistentry>
+<varlistentry>
 <term><various html tags></term>
 <listitem><para>Most basic html tags are allowed within the sections. Please keep manual formatting to a minimum, however.</para></listitem>
 </varlistentry>
diff --git a/rkward/plugin/rkcomponentproperties.cpp b/rkward/plugin/rkcomponentproperties.cpp
index 5807e76..4f10ba7 100644
--- a/rkward/plugin/rkcomponentproperties.cpp
+++ b/rkward/plugin/rkcomponentproperties.cpp
@@ -2,7 +2,7 @@
                           rkcomponentproperties  -  description
                              -------------------
     begin                : Fri Nov 25 2005
-    copyright            : (C) 2005, 2006, 2007, 2008, 2009, 2011, 2012, 2014 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2007, 2008, 2009, 2011, 2012, 2014, 2015 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -113,11 +113,11 @@ RKComponentPropertyBase::~RKComponentPropertyBase () {
 
 QVariant RKComponentPropertyBase::value (const QString &modifier) {
 	RK_TRACE (PLUGIN);
-	if (!modifier.isEmpty ()) {
-		warnModifierNotRecognized (modifier);
-		return QString ();
-	}
-	return _value;
+	if (modifier.isEmpty ()) return _value;
+	if (modifier == "quoted") return RObject::rQuote (_value);
+	// else
+	warnModifierNotRecognized (modifier);
+	return QString ();
 }
 
 bool RKComponentPropertyBase::setValue (const QString &string) {
diff --git a/rkward/plugin/rkstandardcomponent.cpp b/rkward/plugin/rkstandardcomponent.cpp
index 5f48925..41120ad 100644
--- a/rkward/plugin/rkstandardcomponent.cpp
+++ b/rkward/plugin/rkstandardcomponent.cpp
@@ -740,6 +740,16 @@ void RKComponentBuilder::parseLogic (const QDomElement &element, XMLHelper &xml,
 		initial_values.insert (xml.getStringAttribute (*it, "id", "#noid#", DL_WARNING), xml.getStringAttribute (*it, "to", "false", DL_WARNING));
 	}
 
+	// i18n'ed strings
+	children = xml.getChildElements (element, "i18n", DL_INFO);
+	for (it = children.constBegin (); it != children.constEnd (); ++it) {
+		QString id = xml.getStringAttribute (*it, "id", "#noid#", DL_WARNING);
+		RKComponentPropertyBase *prop = new RKComponentPropertyBase (component (), false);
+		component ()->addChild (id, prop);
+		prop->setInternal (true);
+		initial_values.insert (id, xml.i18nStringAttribute (*it, "label", QString (), DL_WARNING));
+	}
+
 	// find convert elements
 	QMap<RKComponentPropertyBase*, QStringList> switch_convert_sources;
 	children = xml.getChildElements (element, "convert", DL_INFO);
diff --git a/rkward/windows/rkhtmlwindow.cpp b/rkward/windows/rkhtmlwindow.cpp
index cea48e0..84d2ece 100644
--- a/rkward/windows/rkhtmlwindow.cpp
+++ b/rkward/windows/rkhtmlwindow.cpp
@@ -2,7 +2,7 @@
                           rkhtmlwindow  -  description
                              -------------------
     begin                : Wed Oct 12 2005
-    copyright            : (C) 2005-2014 by Thomas Friedrichsmeier
+    copyright            : (C) 2005-2015 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -508,6 +508,7 @@ bool RKHTMLWindow::renderRKHelp (const KUrl &url) {
 		chandle = componentPathToHandle (url.path ());
 		if (!chandle) return false;
 	}
+
 	XMLHelper component_xml (for_component ? chandle->getFilename () : QString (), for_component ? chandle->messageCatalog () : 0);
 	QString help_file_name;
 	QDomElement element;
@@ -536,6 +537,12 @@ bool RKHTMLWindow::renderRKHelp (const KUrl &url) {
 	QDomElement help_doc_element = help_xml.openXMLFile (DL_ERROR);
 	if (help_doc_element.isNull () && (!for_component)) return false;
 
+	HTMLRendererState state;
+	state.component_xml = &component_xml;
+	state.help_xml = &help_xml;
+	state.component_doc_element = component_doc_element;
+	state.help_doc_element = help_doc_element;
+
 	// initialize output, and set title
 	beginWritingHTML (url);
 	QString page_title (i18n ("No Title"));
@@ -572,13 +579,13 @@ bool RKHTMLWindow::renderRKHelp (const KUrl &url) {
 	element = help_xml.getChildElement (help_doc_element, "summary", DL_INFO);
 	if (!element.isNull ()) {
 		writeHTML (startSection ("summary", i18n ("Summary"), QString (), &anchors, &anchornames));
-		writeHTML (renderHelpFragment (element, &help_xml));
+		writeHTML (renderHelpFragment (element, state));
 	}
 
 	element = help_xml.getChildElement (help_doc_element, "usage", DL_INFO);
 	if (!element.isNull ()) {
 		writeHTML (startSection ("usage", i18n ("Usage"), QString (), &anchors, &anchornames));
-		writeHTML (renderHelpFragment (element, &help_xml));
+		writeHTML (renderHelpFragment (element, state));
 	}
 
 	XMLChildList section_elements = help_xml.getChildElements (help_doc_element, "section", DL_INFO);
@@ -587,7 +594,7 @@ bool RKHTMLWindow::renderRKHelp (const KUrl &url) {
 		QString shorttitle = help_xml.i18nStringAttribute (*it, "shorttitle", QString (), DL_DEBUG);
 		QString id = help_xml.getStringAttribute (*it, "id", QString (), DL_WARNING);
 		writeHTML (startSection (id, title, shorttitle, &anchors, &anchornames));
-		writeHTML (renderHelpFragment (*it, &help_xml));
+		writeHTML (renderHelpFragment (*it, state));
 	}
 
 	// the section "settings" is the most complicated, as the labels of the individual GUI items has to be fetched from the component description. Of course it is only meaningful for component help, and not rendered for top level help pages.
@@ -600,19 +607,13 @@ bool RKHTMLWindow::renderRKHelp (const KUrl &url) {
 				if ((*it).tagName () == "setting") {
 					QString id = help_xml.getStringAttribute (*it, "id", QString (), DL_WARNING);
 					QString title = help_xml.i18nStringAttribute (*it, "title", QString (), DL_INFO);
-					if (title.isEmpty ()) {
-						QDomElement source_element = component_xml.findElementWithAttribute (component_doc_element, "id", id, true, DL_WARNING);
-						if (source_element.isNull ()) RK_DEBUG (PLUGIN, DL_ERROR, "No such UI element: %s", qPrintable (id));
-						title = component_xml.i18nStringAttribute (source_element, "label", i18n ("Unnamed GUI element"), DL_WARNING);
-					}
+					if (title.isEmpty ()) title = resolveLabel (id, state);
 					writeHTML ("<h4>" + title + "</h4>");
-					writeHTML (renderHelpFragment (*it, &help_xml));
+					writeHTML (renderHelpFragment (*it, state));
 				} else if ((*it).tagName () == "caption") {
 					QString id = help_xml.getStringAttribute (*it, "id", QString (), DL_WARNING);
 					QString title = help_xml.i18nStringAttribute (*it, "title", QString (), DL_INFO);
-					QDomElement source_element = component_xml.findElementWithAttribute (component_doc_element, "id", id, true, DL_WARNING);
-					if (source_element.isNull ()) RK_DEBUG (PLUGIN, DL_ERROR, "No such UI element: %s", qPrintable (id));
-					title = component_xml.i18nStringAttribute (source_element, "label", title, DL_WARNING);
+					if (title.isEmpty ()) title = resolveLabel (id, state);
 					writeHTML ("<h3>" + title + "</h3>");
 				} else {
 					help_xml.displayError (&(*it), "Tag not allowed, here", DL_WARNING);
@@ -625,14 +626,14 @@ bool RKHTMLWindow::renderRKHelp (const KUrl &url) {
 	element = help_xml.getChildElement (help_doc_element, "related", DL_INFO);
 	if (!element.isNull ()) {
 		writeHTML (startSection ("related", i18n ("Related functions and pages"), QString (), &anchors, &anchornames));
-		writeHTML (renderHelpFragment (element, &help_xml));
+		writeHTML (renderHelpFragment (element, state));
 	}
 
 	// "technical" section
 	element = help_xml.getChildElement (help_doc_element, "technical", DL_INFO);
 	if (!element.isNull ()) {
 		writeHTML (startSection ("technical", i18n ("Technical details"), QString (), &anchors, &anchornames));
-		writeHTML (renderHelpFragment (element, &help_xml));
+		writeHTML (renderHelpFragment (element, state));
 	}
 
 	if (for_component) {
@@ -680,12 +681,22 @@ bool RKHTMLWindow::renderRKHelp (const KUrl &url) {
 	return (true);
 }
 
-QString RKHTMLWindow::renderHelpFragment (QDomElement &fragment, const XMLHelper *xml) {
+QString RKHTMLWindow::resolveLabel (const QString& id, const RKHTMLWindow::HTMLRendererState& state) const {
 	RK_TRACE (APP);
 
-	QString text = xml->i18nElementText (fragment, true, DL_WARNING);
+	QDomElement source_element = state.component_xml->findElementWithAttribute (state.component_doc_element, "id", id, true, DL_WARNING);
+	if (source_element.isNull ()) {
+		RK_DEBUG (PLUGIN, DL_ERROR, "No such UI element: %s", qPrintable (id));
+	}
+	return (state.component_xml->i18nStringAttribute (source_element, "label", i18n ("Unnamed GUI element"), DL_WARNING));
+}
+
+QString RKHTMLWindow::renderHelpFragment (QDomElement &fragment, const HTMLRendererState &state) {
+	RK_TRACE (APP);
 
-	// Can't resolve links based on the already parsed dom-tree, because they can be inside string to be translated.
+	QString text = state.help_xml->i18nElementText (fragment, true, DL_WARNING);
+
+	// Can't resolve links and references based on the already parsed dom-tree, because they can be inside string to be translated.
 	// I.e. resolving links before doing i18n will cause i18n-lookup to fail
 	int pos = 0;
 	int npos;
@@ -713,6 +724,26 @@ QString RKHTMLWindow::renderHelpFragment (QDomElement &fragment, const XMLHelper
 	}
 	ret += text.mid (pos);
 
+	if (state.component_xml) {
+		text = ret;
+		ret.clear ();
+		pos = 0;
+		while ((npos = text.indexOf ("<label ", pos)) >= 0) {
+			ret += text.mid (pos, npos - pos);
+
+			QString id;
+			int id_start = text.indexOf ("id=\"", npos + 6);
+			if (id_start >= 0) {
+				id_start += 4;
+				int id_end = text.indexOf ("\"", id_start);
+				id = text.mid (id_start, id_end - id_start);
+				pos = text.indexOf ("/>", id_end) + 2;
+			}
+			ret += resolveLabel (id, state);
+		}
+		ret += text.mid (pos);
+	}
+
 	RK_DEBUG (APP, DL_DEBUG, "%s", qPrintable (ret));
 	return ret;
 }
diff --git a/rkward/windows/rkhtmlwindow.h b/rkward/windows/rkhtmlwindow.h
index 35e8697..d78ffa3 100644
--- a/rkward/windows/rkhtmlwindow.h
+++ b/rkward/windows/rkhtmlwindow.h
@@ -2,7 +2,7 @@
                           rkhtmlwindow  -  description
                              -------------------
     begin                : Wed Oct 12 2005
-    copyright            : (C) 2005, 2006, 2007, 2009, 2011, 2014 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2007, 2009, 2011, 2014, 2015 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -137,7 +137,14 @@ private:
 
 	// for dealing with rkward://[page|component]-pages
 	bool renderRKHelp (const KUrl &url);
-	QString renderHelpFragment (QDomElement &fragment, const XMLHelper *xml);
+	struct HTMLRendererState {
+		XMLHelper *help_xml;
+		XMLHelper *component_xml;
+		QDomElement help_doc_element;
+		QDomElement component_doc_element;
+	};
+	QString renderHelpFragment (QDomElement &fragment, const HTMLRendererState &state);
+	QString resolveLabel (const QString &id, const HTMLRendererState &state) const;
 	QString prepareHelpLink (const QString &href, const QString &text);
 	QString componentPathToId (QString path);
 	RKComponentHandle *componentPathToHandle (QString path);


------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
rkward-cvs mailing list
rkward-cvs at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rkward-cvs


More information about the rkward-tracker mailing list