Implement some more string functionality that will be needed for proper i18n...

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"
parent ab009122
- 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
......
......@@ -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>
......@@ -3323,6 +3333,21 @@ Child-elements:
</variablelist></para></listitem>
</varlistentry>
<varlistentry>
<term>&lt;i18n&gt;</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>&lt;set&gt;</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 &lt;set&gt; elements
......@@ -4224,6 +4249,16 @@ Child elements:
</variablelist></para></listitem>
</varlistentry>
<varlistentry>
<term>&lt;label&gt;</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>&lt;various html tags&gt;</term>
<listitem><para>Most basic html tags are allowed within the sections. Please keep manual formatting to a minimum, however.</para></listitem>
</varlistentry>
......
......@@ -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@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) {
......
......@@ -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);
......
......@@ -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@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;
}
......
......@@ -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@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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment