[education/rkward] rkward/misc: Set QT_NO_CAST_FROM_ASCII in misc folder

Thomas Friedrichsmeier null at kde.org
Fri Apr 25 13:23:10 BST 2025


Git commit f57b5b574b1f6706060f67bece879f45349237ee by Thomas Friedrichsmeier.
Committed on 25/04/2025 at 12:19.
Pushed by tfry into branch 'master'.

Set QT_NO_CAST_FROM_ASCII in misc folder

M  +1    -0    rkward/misc/CMakeLists.txt
M  +13   -13   rkward/misc/celleditor.cpp
M  +11   -11   rkward/misc/getfilenamewidget.cpp
M  +23   -24   rkward/misc/rkcommonfunctions.cpp
M  +2    -2    rkward/misc/rkobjectlistview.cpp
M  +8    -8    rkward/misc/rkoutputdirectory.cpp
M  +2    -2    rkward/misc/rkparsedversion.cpp
M  +2    -2    rkward/misc/rkprogresscontrol.cpp
M  +7    -7    rkward/misc/rkrapimenu.cpp
M  +49   -49   rkward/misc/rkspecialactions.cpp
M  +1    -1    rkward/misc/rkstandardactions.cpp
M  +26   -26   rkward/misc/rkxmlguipreviewarea.cpp
M  +96   -89   rkward/misc/xmlhelper.cpp

https://invent.kde.org/education/rkward/-/commit/f57b5b574b1f6706060f67bece879f45349237ee

diff --git a/rkward/misc/CMakeLists.txt b/rkward/misc/CMakeLists.txt
index ff0da775d..8399a613c 100644
--- a/rkward/misc/CMakeLists.txt
+++ b/rkward/misc/CMakeLists.txt
@@ -40,3 +40,4 @@ SET(misc_STAT_SRCS
 
 ADD_LIBRARY(misc STATIC ${misc_STAT_SRCS})
 TARGET_LINK_LIBRARIES(misc Qt6::Widgets KF6::WidgetsAddons KF6::KIOWidgets Qt6::Xml Qt6::DBus KF6::ConfigCore KF6::Parts KF6::WindowSystem KF6::TextEditor KF6::Archive KF6::I18n)
+add_definitions(-DQT_NO_CAST_FROM_ASCII) # TODO remove, here, once enabled on top level
diff --git a/rkward/misc/celleditor.cpp b/rkward/misc/celleditor.cpp
index 38a526bdd..10ef78292 100644
--- a/rkward/misc/celleditor.cpp
+++ b/rkward/misc/celleditor.cpp
@@ -27,28 +27,28 @@ CellEditor::~CellEditor () {
 	RK_TRACE (EDITOR);
 }
 
-void CellEditor::setValueLabels (const RObject::ValueLabels& labels) {
-	RK_TRACE (EDITOR);
+void CellEditor::setValueLabels(const RObject::ValueLabels& labels) {
+	RK_TRACE(EDITOR);
 
-	if (labels.isEmpty ()) return;
+	if (labels.isEmpty()) return;
 
-// NOTE: not using a QComboBox, as we do not want it to pop up immediately
-	value_list = new QMenu (this);
-	value_list->setFont (font ());
-	value_list->setPalette (palette ());
-	value_list->setFocusProxy (this);
-	value_list->installEventFilter (this);	// somehow setting us as a focus proxy is not enough to continue to receive the key-presses
+	// NOTE: not using a QComboBox, as we do not want it to pop up immediately
+	value_list = new QMenu(this);
+	value_list->setFont(font());
+	value_list->setPalette(palette());
+	value_list->setFocusProxy(this);
+	value_list->installEventFilter(this);  // somehow setting us as a focus proxy is not enough to continue to receive the key-presses
 
 	const int limit = 64;
 	int i = 0;
-	for (RObject::ValueLabels::const_iterator it = labels.constBegin (); it != labels.constEnd (); ++it) {
+	for (RObject::ValueLabels::const_iterator it = labels.constBegin(); it != labels.constEnd(); ++it) {
 		if (++i >= limit) break;
-		value_list->addAction (it.key () + ": " + it.value ())->setData (it.key ());
+		value_list->addAction(it.key() + u": "_s + it.value())->setData(it.key());
 	}
 	if (i >= limit) {
-		value_list->addAction (i18n ("[Omitted %1 more factor levels]", labels.size () - limit))->setEnabled (false);
+		value_list->addAction(i18n("[Omitted %1 more factor levels]", labels.size() - limit))->setEnabled(false);
 	}
-	connect (value_list, &QMenu::triggered, this, &CellEditor::selectedFromList);
+	connect(value_list, &QMenu::triggered, this, &CellEditor::selectedFromList);
 
 	QTimer::singleShot(200, this, &CellEditor::showValueLabels);
 }
diff --git a/rkward/misc/getfilenamewidget.cpp b/rkward/misc/getfilenamewidget.cpp
index 6bdc862d8..8256e7b09 100644
--- a/rkward/misc/getfilenamewidget.cpp
+++ b/rkward/misc/getfilenamewidget.cpp
@@ -52,22 +52,22 @@ GetFileNameWidget::GetFileNameWidget (QWidget *parent, FileType mode, bool only_
 	edit->setMode (mode_flags);
 
 	QString append = initial;
-	if (initial.startsWith ('<')) {
-		storage_key = initial.section ('>', 0, 0).mid (1);
-		append = initial.section ('>', 1);
+	if (initial.startsWith(u'<')) {
+		storage_key = initial.section(u'>', 0, 0).mid(1);
+		append = initial.section(u'>', 1);
 	}
 	QUrl initial_url = RKRecentUrls::mostRecentUrl(storage_key).adjusted(QUrl::RemoveFilename);  // storage_key == QString () in the default case is intended
-	if (!append.isEmpty ()) {
-		if (initial_url.isLocalFile ()) {
-			initial_url = QUrl::fromUserInput (append, initial_url.toLocalFile (), QUrl::AssumeLocalFile);
+	if (!append.isEmpty()) {
+		if (initial_url.isLocalFile()) {
+			initial_url = QUrl::fromUserInput(append, initial_url.toLocalFile(), QUrl::AssumeLocalFile);
 		} else {
-			initial_url.setPath (initial_url.path () + '/' + append);
+			initial_url.setPath(initial_url.path() + u'/' + append);
 		}
-		initial_url = initial_url.adjusted (QUrl::NormalizePathSegments);
+		initial_url = initial_url.adjusted(QUrl::NormalizePathSegments);
 	}
-	if (initial_url.isLocalFile () || !only_local) {
-		if (!initial.isEmpty ()) edit->setUrl (initial_url);
-		else edit->setStartDir (initial_url);
+	if (initial_url.isLocalFile() || !only_local) {
+		if (!initial.isEmpty()) edit->setUrl(initial_url);
+		else edit->setStartDir(initial_url);
 	}
 
 	connect (edit, &KUrlRequester::textChanged, this, &GetFileNameWidget::locationEditChanged);
diff --git a/rkward/misc/rkcommonfunctions.cpp b/rkward/misc/rkcommonfunctions.cpp
index 95d156ee2..99cd560c3 100644
--- a/rkward/misc/rkcommonfunctions.cpp
+++ b/rkward/misc/rkcommonfunctions.cpp
@@ -124,7 +124,7 @@ namespace RKCommonFunctions {
 		for (int i=from; i <= line_end; ++i) {
 			QChar c = haystack.at (i);
 			if (c == quote_char) return i;
-			if (c == '\\') {
+			if (c == u'\\') {
 				++i;
 				continue;
 			}
@@ -141,14 +141,14 @@ namespace RKCommonFunctions {
 
 		for (int i=0; i <= line_end; ++i) {
 			QChar c = context_line.at (i);
-			if (c == '\'' || c == '\"' || c == '`') {
+			if (c == u'\'' || c == u'\"' || c == u'`') {
 				i = quoteEndPosition (c, context_line, i+1);
 				if (i < 0) break;
 				continue;
-			} else if (c.isLetterOrNumber () || c == '.' || c == '_') {
+			} else if (c.isLetterOrNumber () || c == u'.' || c == u'_') {
 				continue;
 			} else if (!strict) {
-				if (c == '$' || c == ':' || c == '[' || c == ']' || c == '@') continue;
+				if (c == u'$' || c == u':' || c == u'[' || c == u']' || c == u'@') continue;
 			}
 
 			// if we did not hit a continue, yet, that means we are on a potential symbol boundary
@@ -162,7 +162,7 @@ namespace RKCommonFunctions {
 
 	static QString findPathFromAppDir(const QStringList &candidates) {
 		for (int i = 0;  i < candidates.size(); ++i) {
-			QString candidate = QCoreApplication::applicationDirPath() + '/' + candidates[i] + '/';
+			QString candidate = QCoreApplication::applicationDirPath() + u'/' + candidates[i] + u'/';
 			if (QFile::exists(candidate)) return candidate;
 		}
 		return QString();
@@ -186,42 +186,41 @@ namespace RKCommonFunctions {
 					return rkward_data_dir;
 				}
 			}
-			rkward_data_dir = QLatin1String("");   // prevents checking again
-			RK_DEBUG(APP, DL_ERROR, "resource.ver not found. Data path(s): %s", qPrintable (QStandardPaths::standardLocations (QStandardPaths::AppDataLocation).join (':')));
+			rkward_data_dir = u""_s; // NOTE: not null. Prevents checking again
+			RK_DEBUG(APP, DL_ERROR, "resource.ver not found. Data path(s): %s", qPrintable (QStandardPaths::standardLocations (QStandardPaths::AppDataLocation).join(u':')));
 		}
 		return rkward_data_dir;
 	}
 
-	QString escape (const QString &in) {
+	QString escape(const QString &in) {
 		QString out;
 
-		for (int i = 0; i < in.size (); ++i) {
+		for (int i = 0; i < in.size(); ++i) {
 			QChar c = in[i];
-			if (c == '\\') out.append ("\\\\");
-			else if (c == '\n') out.append ("\\n");
-			else if (c == '\t') out.append ("\\t");
-			else if (c == '"') out.append ("\\\"");
-			else out.append (c);
+			if (c == u'\\') out.append(u"\\\\"_s);
+			else if (c == u'\n') out.append(u"\\n"_s);
+			else if (c == u'\t') out.append(u"\\t"_s);
+			else if (c == u'"') out.append(u"\\\""_s);
+			else out.append(c);
 		}
 
 		return out;
 	}
 
-	QString unescape (const QString &in) {
+	QString unescape(const QString &in) {
 		QString out;
-		out.reserve (in.size ());
+		out.reserve(in.size());
 
-		for (int i = 0; i < in.size (); ++i) {
+		for (int i = 0; i < in.size(); ++i) {
 			QChar c = in[i];
-			if (c == '\\') {
+			if (c == u'\\') {
 				++i;
-				if (i >= in.size ()) break;
-				c = in[i];
-				if (c == 'n') c = '\n';
-				else if (c == 't') c = '\t';
-				// NOTE: Quote (") and backslash (\) are escaped by the same symbol, i.e. c = in[i] is good enough
+				if (i >= in.size()) break;
+				if (c == u'n') c = u'\n';
+				else if (c == u't') c = u'\t';
+				else c = in[i]; // NOTE: Quote (") and backslash (\) are escaped by the same symbol, i.e. c = in[i] is good enough
 			}
-			out.append (c);
+			out.append(c);
 		}
 
 		return out;
diff --git a/rkward/misc/rkobjectlistview.cpp b/rkward/misc/rkobjectlistview.cpp
index d68962019..7336c6175 100644
--- a/rkward/misc/rkobjectlistview.cpp
+++ b/rkward/misc/rkobjectlistview.cpp
@@ -425,8 +425,8 @@ bool RKObjectListViewSettings::acceptRow (int source_row, const QModelIndex& sou
 	RK_ASSERT (object);
 
 	if (!persistent_settings[ShowObjectsHidden]) {
-		if (object->getShortName ().startsWith ('.')) return false;
-		if (object == reinterpret_cast<RObject*> (RObjectList::getObjectList ()->orphanNamespacesObject ())) return false;
+		if (object->getShortName().startsWith(u'.')) return false;
+		if (object == reinterpret_cast<RObject*>(RObjectList::getObjectList()->orphanNamespacesObject())) return false;
 	}
 
 	if (hide_functions && object->isType (RObject::Function)) return false;
diff --git a/rkward/misc/rkoutputdirectory.cpp b/rkward/misc/rkoutputdirectory.cpp
index c2377df1d..493abd649 100644
--- a/rkward/misc/rkoutputdirectory.cpp
+++ b/rkward/misc/rkoutputdirectory.cpp
@@ -37,11 +37,11 @@ void listDirectoryState(const QString& _dir, QString *list, const QString &prefi
 	for (int i = 0; i < entries.size(); ++i) {
 		const QFileInfo fi = entries[i];
 		if (fi.isDir()) {
-			listDirectoryState(fi.absolutePath(), list, prefix + '/' + fi.fileName());
+			listDirectoryState(fi.absolutePath(), list, prefix + u'/' + fi.fileName());
 		} else {
-			list->append(fi.fileName() + '\t');
-			list->append(fi.lastModified().toString(QStringLiteral("dd.hh.mm.ss.zzz")) + '\t');
-			list->append(QString::number(fi.size()) + '\n');
+			list->append(fi.fileName() + u'\t');
+			list->append(fi.lastModified().toString(QStringLiteral("dd.hh.mm.ss.zzz")) + u'\t');
+			list->append(QString::number(fi.size()) + u'\n');
 		}
 	}
 }
@@ -160,9 +160,9 @@ GenericRRequestResult RKOutputDirectory::exportZipInternal(const QString &dest)
 	RK_TRACE (APP);
 
 	// write to a temporary location, first, then - if successful - copy to final destination
-	QString tempname = dest + '~';
+	QString tempname = dest + u'~';
 	while (QFileInfo::exists(tempname)) {
-		tempname.append('~');
+		tempname.append(u'~');
 	}
 
 	KZip zip(tempname);
@@ -265,7 +265,7 @@ RKOutputDirectory* RKOutputDirectory::createOutputDirectoryInternal() {
 GenericRRequestResult RKOutputDirectory::activate(RCommandChain* chain) {
 	RK_TRACE (APP);
 
-	QString index_file = work_dir + "/index.html";
+	QString index_file = work_dir + u"/index.html"_s;
 	RInterface::issueCommand(new RCommand(QStringLiteral("rk.set.output.html.file(\"") + RKCommonFunctions::escape(index_file) + QStringLiteral("\")\n"), RCommand::App), chain);
 	if (!initialized) {
 		// when an output directory is first initialized, we don't want that to count as a "modification". Therefore, update the "saved hash" _after_ initialization
@@ -409,7 +409,7 @@ RKOutputDirectoryCallResult RKOutputDirectory::getCurrentOutput(RCommandChain* c
 	RKOutputDirectoryCallResult ret;
 	if (outputs.isEmpty()) {
 		if (RKSettingsModuleOutput::sharedDefaultOutput()) {
-			QString filename = RKSettingsModuleGeneral::filesPath() + "default.rko";
+			QString filename = RKSettingsModuleGeneral::filesPath() + u"default.rko"_s;
 			ret = get(filename, !QFileInfo::exists(filename), chain);
 			if (ret.dir()) {
 				ret.dir()->activate(chain);
diff --git a/rkward/misc/rkparsedversion.cpp b/rkward/misc/rkparsedversion.cpp
index b713de49e..187c698c8 100644
--- a/rkward/misc/rkparsedversion.cpp
+++ b/rkward/misc/rkparsedversion.cpp
@@ -23,7 +23,7 @@ RKParsedVersion::RKParsedVersion(const QString& version) {
 					else val = 0;
 				}
 				ret += val << (8 * i);
-				if ((pos < version.size ()) && (version[pos] == '.')) {
+				if ((pos < version.size ()) && (version[pos] == u'.')) {
 					opos = pos + 1;
 					break;
 				}
@@ -45,7 +45,7 @@ QString RKParsedVersion::toString() const {
 	for (int i = 3; i >= 0; --i) {
 		int ver_part = (version_numeric >> (i * 8)) & 0x000000FF;
 		ret.append(QString::number(ver_part));
-		if (i > 0) ret.append('.');
+		if (i > 0) ret.append(u'.');
 	}
 	if (ret.endsWith(QLatin1String(".0"))) ret.chop(2);	// HACK: Don't print more than three version parts, unless the fourth is non-zero
 	ret.append(version_suffix);
diff --git a/rkward/misc/rkprogresscontrol.cpp b/rkward/misc/rkprogresscontrol.cpp
index 6d31dc4ec..f0d932001 100644
--- a/rkward/misc/rkprogresscontrol.cpp
+++ b/rkward/misc/rkprogresscontrol.cpp
@@ -449,8 +449,8 @@ void RKInlineProgressControl::done() {
 		deleteLater();
 	} else {
 		message_widget->setMessageType(any_failed ? KMessageWidget::Error : KMessageWidget::Positive);
-		message_widget->setText(text + ' ' + (any_failed ? i18n("<b>An error occurred</b> (see below for details)") : i18n("<b>Done</b>")));
-		message_widget->setIcon(QIcon::fromTheme(any_failed ? "emblem-error" : "emblem-success"));
+		message_widget->setText(text + u' ' + (any_failed ? i18n("<b>An error occurred</b> (see below for details)") : i18n("<b>Done</b>")));
+		message_widget->setIcon(QIcon::fromTheme(any_failed ? u"emblem-error"_s : u"emblem-success"_s));
 		message_widget->animatedShow(); // to force an update of geometry
 		setCloseAction(i18n("Close"));
 	}
diff --git a/rkward/misc/rkrapimenu.cpp b/rkward/misc/rkrapimenu.cpp
index 248f2d1bd..92f7cc665 100644
--- a/rkward/misc/rkrapimenu.cpp
+++ b/rkward/misc/rkrapimenu.cpp
@@ -65,9 +65,9 @@ void RKRApiMenu::makeAction(QDomElement e, const QString &full_id, const QString
 		actionCollection()->addAction(full_id, a);
 		QObject::connect(a, &QAction::triggered, a, [full_id]() {
 			QString path;
-			auto segments = full_id.split(',');
+			auto segments = full_id.split(u',');
 			for (int i = 0; i < segments.size(); ++i) {
-				if (i) path += ',';
+				if (i) path += u',';
 				path += RObject::rQuote(segments[i]);
 			}
 
@@ -77,14 +77,14 @@ void RKRApiMenu::makeAction(QDomElement e, const QString &full_id, const QString
 				const auto props = w->globalContextProperties();
 				for (const auto [key,value] : props.asKeyValueRange()) {
 					if (key == QLatin1String("current_object") || key == QLatin1String("current_dataframe")) { // TODO: find cleaner solution than this special casing
-						args.append(key + '=' + value);
+						args.append(key + u'=' + value);
 					} else {
-						args.append(key + '=' + RObject::rQuote(value));
+						args.append(key + u'=' + RObject::rQuote(value));
 					}
 				}
 			}
 
-			RInterface::issueCommand(new RCommand("rk.menu()$item(" + path + ")$call(" + args.join(',') + ')', RCommand::App));
+			RInterface::issueCommand(new RCommand(u"rk.menu()$item("_s + path + u")$call("_s + args.join(u',') + u')', RCommand::App));
 		});
 	}
 	a->setText(label);
@@ -93,7 +93,7 @@ void RKRApiMenu::makeAction(QDomElement e, const QString &full_id, const QString
 
 void RKRApiMenu::makeXML(QDomElement e, const QVariantList &l, const QString &path, QStringList *actionlist) {
 	const auto id = getId(l);
-	const QString full_id = path.isEmpty() ? id : path + ',' + id;
+	const QString full_id = path.isEmpty() ? id : path + u',' + id;
 	const auto label = getLabel(l);
 	const auto callable = getCallable(l);
 
@@ -161,7 +161,7 @@ void RKRApiMenu::updateFromR(const QVariantList &_rep) {
 
 QAction *RKRApiMenu::actionByPath(const QStringList &path) {
 	commit(); // force commit before lookup
-	return action(path.join(','));
+	return action(path.join(u','));
 }
 
 void RKRApiMenu::enableAction(const QStringList &path, bool enable, bool show) {
diff --git a/rkward/misc/rkspecialactions.cpp b/rkward/misc/rkspecialactions.cpp
index 9a547021a..da5a02e29 100644
--- a/rkward/misc/rkspecialactions.cpp
+++ b/rkward/misc/rkspecialactions.cpp
@@ -163,108 +163,108 @@ void RKPasteSpecialDialog::updateState () {
 	ok_button->setEnabled((objectname == nullptr) || objectname->isOk());
 }
 
-QString RKPasteSpecialDialog::resultingText () {
-	RK_TRACE (MISC);
+QString RKPasteSpecialDialog::resultingText() {
+	RK_TRACE(MISC);
 
-	const int sep = separator_group->checkedId ();		// for easier typing
-	const int dim = dimensionality_group->checkedId ();
-	const bool reverse_h = reverse_h_box->isChecked () && (dim != DimSingleString);
-	const bool reverse_v = reverse_v_box->isChecked () && (dim >= DimMatrix);
-	const bool transpose = transpose_box->isChecked () && (dim >= DimMatrix);
+	const int sep = separator_group->checkedId();  // for easier typing
+	const int dim = dimensionality_group->checkedId();
+	const bool reverse_h = reverse_h_box->isChecked() && (dim != DimSingleString);
+	const bool reverse_v = reverse_v_box->isChecked() && (dim >= DimMatrix);
+	const bool transpose = transpose_box->isChecked() && (dim >= DimMatrix);
 	const bool names = names_box->isChecked() && (dim == DimDataFrame);
 	const bool rownames = rownames_box->isChecked() && (dim == DimDataFrame);
-	Quoting quot = (Quoting) quoting_group->checkedId();
+	Quoting quot = (Quoting)quoting_group->checkedId();
 
 	QString clip;
 
-	const QMimeData* data = QApplication::clipboard ()->mimeData ();
-	if ((dim != DimSingleString) && (sep == SepTab) && data->hasFormat (QStringLiteral("text/tab-separated-values"))) {
-		clip = QString::fromLocal8Bit (data->data (QStringLiteral("text/tab-separated-values")));
-	} else if ((dim != DimSingleString) && (sep == SepComma) && data->hasFormat (QStringLiteral("text/comma-separated-values"))) {
-		clip = QString::fromLocal8Bit (data->data (QStringLiteral("text/comma-separated-values")));
+	const QMimeData* data = QApplication::clipboard()->mimeData();
+	if ((dim != DimSingleString) && (sep == SepTab) && data->hasFormat(QStringLiteral("text/tab-separated-values"))) {
+		clip = QString::fromLocal8Bit(data->data(QStringLiteral("text/tab-separated-values")));
+	} else if ((dim != DimSingleString) && (sep == SepComma) && data->hasFormat(QStringLiteral("text/comma-separated-values"))) {
+		clip = QString::fromLocal8Bit(data->data(QStringLiteral("text/comma-separated-values")));
 	} else {
-		clip = data->text ();
+		clip = data->text();
 	}
 
 	if (dim == DimSingleString) return prepString(clip, quot);
 
 	QRegularExpression fieldsep;
-	if (sep == SepCustom) fieldsep.setPattern (separator_freefield->text ());
-	else if (sep == SepWhitespace) fieldsep.setPattern (QStringLiteral("\\s+"));
-	else if (sep == SepSpace) fieldsep.setPattern (QStringLiteral(" "));
-	else if (sep == SepTab) fieldsep.setPattern (QStringLiteral("\t"));
-	else if (sep == SepComma) fieldsep.setPattern (QStringLiteral("\\,"));
-	else RK_ASSERT (false);
-
-	RKTextMatrix matrix = RKTextMatrix::matrixFromSeparatedValues (clip, fieldsep);
+	if (sep == SepCustom) fieldsep.setPattern(separator_freefield->text());
+	else if (sep == SepWhitespace) fieldsep.setPattern(QStringLiteral("\\s+"));
+	else if (sep == SepSpace) fieldsep.setPattern(QStringLiteral(" "));
+	else if (sep == SepTab) fieldsep.setPattern(QStringLiteral("\t"));
+	else if (sep == SepComma) fieldsep.setPattern(QStringLiteral("\\,"));
+	else RK_ASSERT(false);
+
+	RKTextMatrix matrix = RKTextMatrix::matrixFromSeparatedValues(clip, fieldsep);
 	if (dim == DimVector) {
 		// transform list to single row matrix. This is wasteful on resources, but easy to code...
 		QStringList list;
-		for (int i = 0; i < matrix.numRows (); ++i) {
-			list += matrix.getRow (i);
+		for (int i = 0; i < matrix.numRows(); ++i) {
+			list += matrix.getRow(i);
 		}
-		matrix = RKTextMatrix::matrixFromSeparatedValues (list.join (QStringLiteral("\t")));
+		matrix = RKTextMatrix::matrixFromSeparatedValues(list.join(QStringLiteral("\t")));
 	}
 
-	if (reverse_h || reverse_v || transpose) matrix = matrix.transformed (reverse_h, reverse_v, transpose);
+	if (reverse_h || reverse_v || transpose) matrix = matrix.transformed(reverse_h, reverse_v, transpose);
 
 	QString ret;
-	if (dim == DimDataFrame) ret.append("data.frame(");
-	if (dim >= DimMatrix) ret.append ("cbind(\n");
-	else ret.append ("c(");	// DimVector
+	if (dim == DimDataFrame) ret.append(u"data.frame("_s);
+	if (dim >= DimMatrix) ret.append(u"cbind(\n"_s);
+	else ret.append(u"c("_s);  // DimVector
 
 	int startcol = rownames ? 1 : 0;
 	int startrow = names ? 1 : 0;
-	for (int i = startcol; i < matrix.numColumns (); ++i) {
+	for (int i = startcol; i < matrix.numColumns(); ++i) {
 		if (dim >= DimMatrix) {
-			if (i != startcol) ret.append ("),\n");
+			if (i != startcol) ret.append(u"),\n"_s);
 			if (names) {
-				ret.append(prepString(matrix.getText(0, i), QuoteAll) + "=c(");
+				ret.append(prepString(matrix.getText(0, i), QuoteAll) + u"=c("_s);
 			} else {
-				ret.append("c(");
+				ret.append(u"c("_s);
 			}
-		} else if (i != 0) ret.append (",");
+		} else if (i != 0) ret.append(u',');
 
-		for (int j = startrow; j < matrix.numRows (); ++j) {
-			if (j != startrow) ret.append (",");
+		for (int j = startrow; j < matrix.numRows(); ++j) {
+			if (j != startrow) ret.append(u',');
 			ret.append(prepString(matrix.getText(j, i), quot));
 		}
 	}
-	ret.append (")\n");
+	ret.append(u")\n"_s);
 	if (dim == DimDataFrame) {
-		ret.append(')');
+		ret.append(u')');
 		if (rownames) {
-			ret.append(", rownames=c(\n");
+			ret.append(u", rownames=c(\n"_s);
 			for (int row = startrow; row < matrix.numRows(); ++row) {
-				if (row != startrow) ret.append (",");
+				if (row != startrow) ret.append(u',');
 				ret.append(prepString(matrix.getText(row, 0), QuoteAll));
 			}
-			ret.append(")\n");
+			ret.append(u")\n"_s);
 		}
 	}
-	if (dim >= DimMatrix) ret.append (")\n");
+	if (dim >= DimMatrix) ret.append(u")\n"_s);
 
 	return (ret);
 }
 
 QString RKPasteSpecialDialog::prepString(const QString& src, const Quoting quot) const {
-//	RK_TRACE (MISC);
+	//	RK_TRACE (MISC);
 
-	if (quot == QuoteAll) return (RObject::rQuote (src));
-	if (src.isEmpty() && insert_nas_box->isChecked ()) return ("NA");
+	if (quot == QuoteAll) return (RObject::rQuote(src));
+	if (src.isEmpty() && insert_nas_box->isChecked()) return (u"NA"_s);
 	if (quot == QuoteNone) return (src);
-	RK_ASSERT (quot == QuoteAuto);
+	RK_ASSERT(quot == QuoteAuto);
 
 	bool numeric = false;
-	src.toDouble (&numeric);	// side-effect of setting numeric to true, if number conversion succeeds
-	if (!numeric) return (RObject::rQuote (src));
+	src.toDouble(&numeric);  // side-effect of setting numeric to true, if number conversion succeeds
+	if (!numeric) return (RObject::rQuote(src));
 	return src;
 }
 
 void RKPasteSpecialDialog::accept() {
 	RK_TRACE(MISC);
 	if (objectname) {
-		RCommand *command = new RCommand(objectname->currentFullName() + " <- " + resultingText(), RCommand::App | RCommand::ObjectListUpdate);
+		RCommand *command = new RCommand(objectname->currentFullName() + u" <- "_s + resultingText(), RCommand::App | RCommand::ObjectListUpdate);
 		connect(command->notifier(), &RCommandNotifier::commandFinished, [](RCommand *c) {
 			if (c->failed()) {
 				QString msg = c->fullOutput();
diff --git a/rkward/misc/rkstandardactions.cpp b/rkward/misc/rkstandardactions.cpp
index 5d1a557f2..25af40231 100644
--- a/rkward/misc/rkstandardactions.cpp
+++ b/rkward/misc/rkstandardactions.cpp
@@ -129,7 +129,7 @@ public Q_SLOTS:
 		QString symbol, package;
 		bool enabled = true;
 		provider->currentHelpContext (&symbol, &package);
-		QString searchtext = symbol + " " + package + " R";
+		QString searchtext = symbol + u' ' + package + u" R"_s;
 		actions->setSelectedText(searchtext);
 		menu->clear();
 
diff --git a/rkward/misc/rkxmlguipreviewarea.cpp b/rkward/misc/rkxmlguipreviewarea.cpp
index 3f2280c66..2db0c6f41 100644
--- a/rkward/misc/rkxmlguipreviewarea.cpp
+++ b/rkward/misc/rkxmlguipreviewarea.cpp
@@ -142,41 +142,41 @@ void RKXMLGUIPreviewArea::setWindow(RKMDIWindow* window) {
 	RKWorkplace::mainWorkplace()->setWindowNotManaged(window);
 }
 
-void RKXMLGUIPreviewArea::prepareMenu () {
-	RK_TRACE (PLUGIN);
+void RKXMLGUIPreviewArea::prepareMenu() {
+	RK_TRACE(PLUGIN);
 
 	// flatten menu, and try to purge irrelevant actions
-	menu->clear ();
-	QList<QAction*> entries = menubar->actions ();
-	for (int i = 0; i < entries.size (); ++i) {
-		QMenu *smenu = entries[i]->menu ();
-		if (!smenu) continue;    // Don't think it can happen...
-		if (entries[i]->objectName () == QLatin1String("settings")) continue;  // Skip settings menu, entirely
-
-		QList<QAction*> subentries = smenu->actions ();
-		QList<QAction*> entries_to_add;
+	menu->clear();
+	QList<QAction *> entries = menubar->actions();
+	for (int i = 0; i < entries.size(); ++i) {
+		QMenu *smenu = entries[i]->menu();
+		if (!smenu) continue;                                                 // Don't think it can happen...
+		if (entries[i]->objectName() == QLatin1String("settings")) continue;  // Skip settings menu, entirely
+
+		QList<QAction *> subentries = smenu->actions();
+		QList<QAction *> entries_to_add;
 		bool menu_empty = true;
-		for (int j = 0; j < subentries.size (); ++j) {
+		for (int j = 0; j < subentries.size(); ++j) {
 			QAction *act = subentries[j];
-			if (act->isVisible () && act->isEnabled()) {
-				entries_to_add.append (act);
-				if (!act->isSeparator ()) menu_empty = false;  // Copy separators, but purge menus with only separators in them.
+			if (act->isVisible() && act->isEnabled()) {
+				entries_to_add.append(act);
+				if (!act->isSeparator()) menu_empty = false;  // Copy separators, but purge menus with only separators in them.
 			}
 		}
 		if (menu_empty) continue;
 
-		QWidgetAction *act = new QWidgetAction (this);
-		QLabel *lab = new QLabel ("<b>" + entries[i]->text ().remove ('&') + "</b>");
-		lab->setAlignment (Qt::AlignCenter);
-		act->setDefaultWidget (lab);
-		menu->addAction (act);
+		QWidgetAction *act = new QWidgetAction(this);
+		QLabel *lab = new QLabel(u"<b>"_s + entries[i]->text().remove(u'&') + u"</b>"_s);
+		lab->setAlignment(Qt::AlignCenter);
+		act->setDefaultWidget(lab);
+		menu->addAction(act);
 
 		QMenu *where_to_add = menu;
-		if (entries_to_add.size () >= 8) {                     // if there are really many entries in the menu don't flatten it, keep it as a (shortened) submenu
-			where_to_add = menu->addMenu (entries[i]->text ());
+		if (entries_to_add.size() >= 8) {  // if there are really many entries in the menu don't flatten it, keep it as a (shortened) submenu
+			where_to_add = menu->addMenu(entries[i]->text());
 		}
-		for (int j = 0; j < entries_to_add.size (); ++j) {
-			where_to_add->addAction (entries_to_add[j]);
+		for (int j = 0; j < entries_to_add.size(); ++j) {
+			where_to_add->addAction(entries_to_add[j]);
 		}
 	}
 }
@@ -195,7 +195,7 @@ friend class RKPreviewManager;
 	off(i18nc("very short: Preview is turned off", "off"))
 	{
 		QFontMetrics fm(font());
-		em = fm.horizontalAdvance('w');
+		em = fm.horizontalAdvance(u'w');
 		auto l = new QVBoxLayout(this);
 		l->setContentsMargins(em,0,em,0);
 		lab = new QLabel();
@@ -270,7 +270,7 @@ RKPreviewManager::RKPreviewManager(QObject* parent) : QObject (parent), current_
 
 	update_pending = NoUpdatePending;
 	updating = false;
-	id = "0x" + QString::number((quint64) (quintptr) this, 16);
+	id = u"0x"_s + QString::number((quint64) (quintptr) this, 16);
 }
 
 RKPreviewManager::~RKPreviewManager () {
diff --git a/rkward/misc/xmlhelper.cpp b/rkward/misc/xmlhelper.cpp
index ecd9578f1..0181eb437 100644
--- a/rkward/misc/xmlhelper.cpp
+++ b/rkward/misc/xmlhelper.cpp
@@ -21,6 +21,8 @@ SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "../debug.h"
 
+using namespace Qt::Literals::StringLiterals;
+
 /* We want to allow undelcared entities in our XML files, importantly arbitrary HTML entities inside our .rkh files. Further, we want to
  * preserve them *non-replaced* in order to pass them along to the webegine for rendering.
  *
@@ -29,7 +31,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
  * i18nElementText(). */
 #define ENTITIYHACK "RKENTITY"
 class DummyEntityResolver : public QXmlStreamEntityResolver {
-	QString resolveUndeclaredEntity(const QString &name) override { return QString("<" ENTITIYHACK ">%1</" ENTITIYHACK ">").arg(name); }
+	QString resolveUndeclaredEntity(const QString &name) override { return QStringLiteral("<" ENTITIYHACK ">%1</" ENTITIYHACK ">").arg(name); }
 };
 
 XMLHelper::XMLHelper (const QString &filename, const RKMessageCatalog *default_catalog) {
@@ -43,54 +45,58 @@ XMLHelper::~XMLHelper () {
 	RK_TRACE (XML);
 }
 
-QDomElement XMLHelper::openXMLFile (int debug_level, bool with_includes, bool with_snippets) {
-	RK_TRACE (XML);
+QDomElement XMLHelper::openXMLFile(int debug_level, bool with_includes, bool with_snippets) {
+	RK_TRACE(XML);
 
 	int error_line, error_column;
 	QString error_message;
 	QDomDocument doc;
 
-	QFile f (filename);
+	QFile f(filename);
 	if (!f.open(QIODevice::ReadOnly)) displayError(nullptr, i18n("Could not open file %1 for reading", filename), debug_level, DL_ERROR);
 	QXmlStreamReader reader(&f);
 	DummyEntityResolver res;
 	reader.setEntityResolver(&res);
 	if (!doc.setContent(&reader, false, &error_message, &error_line, &error_column)) {
-		displayError(nullptr, i18n("Error parsing XML-file. Error-message was: '%1' in line '%2', column '%3'. Expect further errors to be reported below", error_message, error_line, error_column), debug_level, DL_ERROR);
-		return QDomElement ();
+		displayError(nullptr,
+		             i18n("Error parsing XML-file. Error-message was: '%1' in line '%2', column '%3'. Expect further errors to be reported below",
+		                  error_message, error_line, error_column),
+		             debug_level, DL_ERROR);
+		return QDomElement();
 	}
 	f.close();
 
-	QDomElement ret = doc.documentElement ();
-	if (ret.hasAttribute (QStringLiteral("po_id"))) {
-		QDir path = QFileInfo (filename).absoluteDir ();
-		catalog = RKMessageCatalog::getCatalog ("rkward__" + ret.attribute (QStringLiteral("po_id")), path.absoluteFilePath (getStringAttribute (ret, QStringLiteral("po_path"), QStringLiteral("po"), DL_INFO)));
+	QDomElement ret = doc.documentElement();
+	if (ret.hasAttribute(QStringLiteral("po_id"))) {
+		QDir path = QFileInfo(filename).absoluteDir();
+		catalog = RKMessageCatalog::getCatalog(u"rkward__"_s + ret.attribute(QStringLiteral("po_id")),
+		                                       path.absoluteFilePath(getStringAttribute(ret, QStringLiteral("po_path"), QStringLiteral("po"), DL_INFO)));
 	}
 	if (with_includes) {
-		XMLChildList includes = nodeListToChildList (doc.elementsByTagName (QStringLiteral("include")));
-		for (XMLChildList::const_iterator it = includes.constBegin (); it != includes.constEnd (); ++it) {
+		XMLChildList includes = nodeListToChildList(doc.elementsByTagName(QStringLiteral("include")));
+		for (XMLChildList::const_iterator it = includes.constBegin(); it != includes.constEnd(); ++it) {
 			// resolve the file to include
 			QDomElement el = *it;
 
-			QString inc_filename = getStringAttribute (el, QStringLiteral("file"), QString (), DL_ERROR);
-			QDir base = QFileInfo (filename).absoluteDir ();
-			inc_filename = base.filePath (inc_filename);
+			QString inc_filename = getStringAttribute(el, QStringLiteral("file"), QString(), DL_ERROR);
+			QDir base = QFileInfo(filename).absoluteDir();
+			inc_filename = base.filePath(inc_filename);
 
 			// import
-			XMLHelper inc_xml = XMLHelper (inc_filename);
-			QDomElement included = inc_xml.openXMLFile (debug_level, true, false);
+			XMLHelper inc_xml = XMLHelper(inc_filename);
+			QDomElement included = inc_xml.openXMLFile(debug_level, true, false);
+
+			if (!included.isNull()) {
+				QDomElement copied = doc.importNode(included, true).toElement();
 
-			if (!included.isNull ()) {
-				QDomElement copied = doc.importNode (included, true).toElement ();
-	
 				// insert everything within the document tag
-				replaceWithChildren (&el, copied);
+				replaceWithChildren(&el, copied);
 			}
 		}
 	}
 
 	if (with_snippets) {
-		return (resolveSnippets (ret));
+		return (resolveSnippets(ret));
 	}
 
 	return (ret);
@@ -119,38 +125,38 @@ XMLChildList XMLHelper::nodeListToChildList (const QDomNodeList &from) {
 	return ret;
 }
 
-QDomElement XMLHelper::resolveSnippets (QDomElement &from_doc) {
-	RK_TRACE (XML);
+QDomElement XMLHelper::resolveSnippets(QDomElement &from_doc) {
+	RK_TRACE(XML);
 
-	XMLChildList refs = nodeListToChildList (from_doc.elementsByTagName (QStringLiteral("insert")));
-	int ref_count = refs.count ();
+	XMLChildList refs = nodeListToChildList(from_doc.elementsByTagName(QStringLiteral("insert")));
+	int ref_count = refs.count();
 
-	if (!ref_count) {	// nothing to resolve
+	if (!ref_count) {  // nothing to resolve
 		return (from_doc);
 	}
 
-	QDomElement snippets_section = getChildElement (from_doc, QStringLiteral("snippets"), DL_ERROR);
-	XMLChildList snippets = getChildElements (snippets_section, QStringLiteral("snippet"), DL_ERROR);
+	QDomElement snippets_section = getChildElement(from_doc, QStringLiteral("snippets"), DL_ERROR);
+	XMLChildList snippets = getChildElements(snippets_section, QStringLiteral("snippet"), DL_ERROR);
 
-	for (XMLChildList::const_iterator it = refs.constBegin (); it != refs.constEnd (); ++it) {
+	for (XMLChildList::const_iterator it = refs.constBegin(); it != refs.constEnd(); ++it) {
 		QDomElement ref = *it;
-		QString id = getStringAttribute (ref, QStringLiteral("snippet"), QString (), DL_ERROR);
-		displayError (&ref, "resolving snippet '" + id + '\'', DL_DEBUG, DL_DEBUG);
+		QString id = getStringAttribute(ref, QStringLiteral("snippet"), QString(), DL_ERROR);
+		displayError(&ref, u"resolving snippet '"_s + id + u'\'', DL_DEBUG, DL_DEBUG);
 
 		// resolve the reference
 		QDomElement snippet;
-		for (XMLChildList::const_iterator it = snippets.constBegin(); it != snippets.constEnd (); ++it) {
-			if (getStringAttribute (*it, QStringLiteral("id"), QString (), DL_ERROR) == id) {
+		for (XMLChildList::const_iterator it = snippets.constBegin(); it != snippets.constEnd(); ++it) {
+			if (getStringAttribute(*it, QStringLiteral("id"), QString(), DL_ERROR) == id) {
 				snippet = *it;
 				break;
 			}
 		}
-		if (snippet.isNull ()) {
-			displayError (&ref, "no such snippet '" + id + '\'', DL_ERROR, DL_ERROR);
+		if (snippet.isNull()) {
+			displayError(&ref, u"no such snippet '"_s + id + u'\'', DL_ERROR, DL_ERROR);
 		}
 
 		// now insert it.
-		replaceWithChildren (&ref, snippet.cloneNode (true).toElement ());
+		replaceWithChildren(&ref, snippet.cloneNode(true).toElement());
 	}
 
 	return from_doc;
@@ -245,35 +251,35 @@ QString XMLHelper::getStringAttribute (const QDomElement &element, const QString
 	return (element.attribute (name));
 }
 
-QString XMLHelper::i18nStringAttribute (const QDomElement& element, const QString& name, const QString& def, int debug_level) {
-	RK_TRACE (XML);
-	if (!element.hasAttribute (name)) {
-		const QString no18nname = "noi18n_" + name;
-		if (element.hasAttribute (no18nname)) return element.attribute (no18nname);
-		displayError (&element, i18n ("'%1'-attribute not given. Assuming '%2'", name, def), debug_level);
+QString XMLHelper::i18nStringAttribute(const QDomElement& element, const QString& name, const QString& def, int debug_level) {
+	RK_TRACE(XML);
+	if (!element.hasAttribute(name)) {
+		const QString no18nname = u"noi18n_"_s + name;
+		if (element.hasAttribute(no18nname)) return element.attribute(no18nname);
+		displayError(&element, i18n("'%1'-attribute not given. Assuming '%2'", name, def), debug_level);
 		return def;
 	}
 
-	QString attr = element.attribute (name);
-	if (attr.isEmpty ()) return attr;	// Do not translate empty strings!
+	QString attr = element.attribute(name);
+	if (attr.isEmpty()) return attr;  // Do not translate empty strings!
 
-	const QString context = element.attribute (QStringLiteral("i18n_context"), QString ());
-	if (!context.isNull ()) return (catalog->translate (context, attr));
-	return (catalog->translate (attr));
+	const QString context = element.attribute(QStringLiteral("i18n_context"), QString());
+	if (!context.isNull()) return (catalog->translate(context, attr));
+	return (catalog->translate(attr));
 }
 
-int XMLHelper::getMultiChoiceAttribute (const QDomElement &element, const QString &name, const QString &values, int def, int debug_level) {
-	RK_TRACE (XML);
+int XMLHelper::getMultiChoiceAttribute(const QDomElement &element, const QString &name, const QString &values, int def, int debug_level) {
+	RK_TRACE(XML);
 
-	QStringList value_list = values.split (';');
+	QStringList value_list = values.split(u';');
+
+	QString plain_value = getStringAttribute(element, name, value_list[def], debug_level);
 
-	QString plain_value = getStringAttribute (element, name, value_list[def], debug_level);
-	
 	int index;
-	if ((index = value_list.indexOf (plain_value)) >= 0) {
+	if ((index = value_list.indexOf(plain_value)) >= 0) {
 		return (index);
 	} else {
-		displayError (&element, i18n ("Illegal attribute value. Allowed values are one of '%1', only.", values), debug_level, DL_ERROR);
+		displayError(&element, i18n("Illegal attribute value. Allowed values are one of '%1', only.", values), debug_level, DL_ERROR);
 		return def;
 	}
 }
@@ -325,23 +331,23 @@ bool XMLHelper::getBoolAttribute (const QDomElement &element, const QString &nam
 	return def;
 }
 
-QString translateChunk (const QString &chunk, const QString &context, bool add_paragraphs, const RKMessageCatalog *catalog) {
+QString translateChunk(const QString &chunk, const QString &context, bool add_paragraphs, const RKMessageCatalog *catalog) {
 	// if (!with_paragraphs), text should better not contain double newlines. We treat all the same, though, just as the message extraction script does.
-	QStringList paras = chunk.split (QStringLiteral("\n\n"));
+	QStringList paras = chunk.split(QStringLiteral("\n\n"));
 	QString ret;
 
-	for (int i = 0; i < paras.count (); ++i) {
-		QString para = paras[i].simplified ();
-		if (para.isEmpty ()) ret.append (QChar (' '));
+	for (int i = 0; i < paras.count(); ++i) {
+		QString para = paras[i].simplified();
+		if (para.isEmpty()) ret.append(u' ');
 		else {
-			if (!ret.isEmpty ()) ret.append ("\n");
+			if (!ret.isEmpty()) ret.append(u'\n');
 			// Oh, crap. Fix up after some differences between python message extraction and qt's.
-			para.replace (QLatin1String("<li> <"), QLatin1String("<li><"));
-			para.replace (QLatin1String("br> <"), QLatin1String("br><"));
-			para.replace (QLatin1String("> </li>"), QLatin1String("></li>"));
-			para.replace (QLatin1String("&"), QLatin1String("&"));
-			QString text = context.isNull () ? catalog->translate (para) : catalog->translate (context, para);
-			if (add_paragraphs) ret += "<p>" + text + "</p>";
+			para.replace(QLatin1String("<li> <"), u"<li><"_s);
+			para.replace(QLatin1String("br> <"), u"br><"_s);
+			para.replace(QLatin1String("> </li>"), u"></li>"_s);
+			para.replace(QLatin1String("&"), u"&"_s);
+			QString text = context.isNull() ? catalog->translate(para) : catalog->translate(context, para);
+			if (add_paragraphs) ret += u"<p>"_s + text + u"</p>"_s;
 			else ret += text;
 		}
 	}
@@ -349,44 +355,45 @@ QString translateChunk (const QString &chunk, const QString &context, bool add_p
 	return ret;
 }
 
-QString XMLHelper::i18nElementText (const QDomElement &element, bool with_paragraphs, int debug_level) const {
-	RK_TRACE (XML);
+QString XMLHelper::i18nElementText(const QDomElement &element, bool with_paragraphs, int debug_level) const {
+	RK_TRACE(XML);
 
-	if (element.isNull ()) {
-		displayError (&element, i18n ("Trying to retrieve contents of invalid element"), debug_level);
-		return QString ();
+	if (element.isNull()) {
+		displayError(&element, i18n("Trying to retrieve contents of invalid element"), debug_level);
+		return QString();
 	}
 
 	QString ret;
-	QString context = element.attribute (QStringLiteral("i18n_context"), QString ());
+	QString context = element.attribute(QStringLiteral("i18n_context"), QString());
 	QString buffer;
-	QTextStream stream (&buffer, QIODevice::WriteOnly);
-	for (QDomNode node = element.firstChild (); !node.isNull (); node = node.nextSibling ()) {
-		QDomElement e = node.toElement ();
-		if (!e.isNull ()) {
-			if (e.tagName () == QLatin1String ("ul") || e.tagName () == QLatin1String ("ol") || e.tagName () == QLatin1String ("li") || e.tagName () == QLatin1String ("p")) { // split translation units on these elements
+	QTextStream stream(&buffer, QIODevice::WriteOnly);
+	for (QDomNode node = element.firstChild(); !node.isNull(); node = node.nextSibling()) {
+		QDomElement e = node.toElement();
+		if (!e.isNull()) {
+			if (e.tagName() == QLatin1String("ul") || e.tagName() == QLatin1String("ol") || e.tagName() == QLatin1String("li") ||
+			    e.tagName() == QLatin1String("p")) {  // split translation units on these elements
 				// split before
-				ret.append (translateChunk (buffer, context, with_paragraphs, catalog));
-				buffer.clear ();
+				ret.append(translateChunk(buffer, context, with_paragraphs, catalog));
+				buffer.clear();
 
 				// serialize the tag with all its attributes but not the children.
-				e.cloneNode (false).save (stream, 0);   // will write: <TAG[ attributes]/>
-				buffer = buffer.left (buffer.lastIndexOf ('/')) + QChar ('>');
-				buffer.append (i18nElementText (e, false, debug_level));
-				buffer.append ("</" + e.tagName () + QChar ('>'));
+				e.cloneNode(false).save(stream, 0);  // will write: <TAG[ attributes]/>
+				buffer = buffer.left(buffer.lastIndexOf(u'/')) + u'>';
+				buffer.append(i18nElementText(e, false, debug_level));
+				buffer.append(u"</"_s + e.tagName() + u'>');
 
 				// split after
-				ret.append (buffer);
-				buffer.clear ();
+				ret.append(buffer);
+				buffer.clear();
 				continue;
 			} else if (e.tagName() == QLatin1String(ENTITIYHACK)) {
-				ret.append(QChar('&') + e.text() + QChar(';'));
+				ret.append(u'&' + e.text() + u';');
 				continue;
 			}
 		}
-		node.save (stream, 0);
+		node.save(stream, 0);
 	}
-	ret.append (translateChunk (buffer, context, with_paragraphs, catalog));
+	ret.append(translateChunk(buffer, context, with_paragraphs, catalog));
 
 	return ret;
 }


More information about the rkward-tracker mailing list