[education/rkward] rkward: Remove RKGlobals::rInterface() in favor of RInterface::instance(), and some static RInterface-functions for convenience.

Thomas Friedrichsmeier null at kde.org
Thu Apr 14 22:14:06 BST 2022


Git commit f79026e23d15e6d4f1252c3282ef67d128953b69 by Thomas Friedrichsmeier.
Committed on 12/04/2022 at 21:13.
Pushed by tfry into branch 'master'.

Remove RKGlobals::rInterface() in favor of RInterface::instance(), and some static RInterface-functions for convenience.

M  +2    -2    rkward/agents/rkeditobjectagent.cpp
M  +4    -4    rkward/agents/rkloadagent.cpp
M  +3    -3    rkward/agents/rkquitagent.cpp
M  +3    -3    rkward/agents/rksaveagent.cpp
M  +2    -2    rkward/core/rcontainerobject.cpp
M  +1    -1    rkward/core/renvironmentobject.cpp
M  +2    -2    rkward/core/rkrownames.cpp
M  +6    -6    rkward/core/rkvariable.cpp
M  +2    -2    rkward/core/robject.cpp
M  +7    -7    rkward/core/robjectlist.cpp
M  +5    -5    rkward/dataeditor/rkeditordataframe.cpp
M  +5    -5    rkward/dataeditor/rkvareditmodel.cpp
M  +2    -2    rkward/dialogs/rkerrordialog.cpp
M  +6    -6    rkward/dialogs/rkloadlibsdialog.cpp
M  +3    -3    rkward/dialogs/rksetupwizard.cpp
M  +3    -3    rkward/misc/rkoutputdirectory.cpp
M  +1    -1    rkward/misc/rkprogresscontrol.cpp
M  +2    -2    rkward/misc/rkxmlguipreviewarea.cpp
M  +4    -4    rkward/plugin/rkpreviewbox.cpp
M  +2    -2    rkward/plugin/rkstandardcomponentgui.cpp
M  +1    -1    rkward/rbackend/rcommandreceiver.cpp
M  +21   -10   rkward/rbackend/rkrinterface.cpp
M  +28   -23   rkward/rbackend/rkrinterface.h
M  +1    -1    rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
M  +3    -3    rkward/rkconsole.cpp
M  +0    -1    rkward/rkglobals.cpp
M  +0    -3    rkward/rkglobals.h
M  +9    -11   rkward/rkward.cpp
M  +3    -3    rkward/robjectviewer.cpp
M  +3    -3    rkward/scriptbackends/rkcomponentscripting.cpp
M  +1    -1    rkward/settings/rksettingsmodulegraphics.cpp
M  +1    -1    rkward/settings/rksettingsmoduleoutput.cpp
M  +7    -7    rkward/settings/rksettingsmoduler.cpp
M  +3    -3    rkward/windows/rcontrolwindow.cpp
M  +3    -3    rkward/windows/rkcommandeditorwindow.cpp
M  +1    -1    rkward/windows/rkfilebrowser.cpp
M  +2    -2    rkward/windows/rkhelpsearchwindow.cpp
M  +1    -1    rkward/windows/rkhtmlwindow.cpp
M  +1    -1    rkward/windows/rktoplevelwindowgui.cpp
M  +17   -17   rkward/windows/rkwindowcatcher.cpp
M  +2    -2    rkward/windows/rkworkplace.cpp
M  +2    -2    rkward/windows/robjectbrowser.cpp

https://invent.kde.org/education/rkward/commit/f79026e23d15e6d4f1252c3282ef67d128953b69

diff --git a/rkward/agents/rkeditobjectagent.cpp b/rkward/agents/rkeditobjectagent.cpp
index 4b933a58..784aae19 100644
--- a/rkward/agents/rkeditobjectagent.cpp
+++ b/rkward/agents/rkeditobjectagent.cpp
@@ -23,12 +23,12 @@ RKEditObjectAgent::RKEditObjectAgent (const QStringList &object_names, RCommandC
 	RKEditObjectAgent::object_names = object_names;
 
 	// first issue an empty command to trigger an update of the object list
-	RKGlobals::rInterface ()->issueCommand (new RCommand (QString (), RCommand::EmptyCommand | RCommand::ObjectListUpdate, QString (), this), chain);
+	RInterface::issueCommand (new RCommand (QString (), RCommand::EmptyCommand | RCommand::ObjectListUpdate, QString (), this), chain);
 
 	// now add another empty command to find out, when the update is complete
 	RCommand *command = new RCommand (QString (), RCommand::EmptyCommand, QString (), this);
 	done_command_id = command->id ();
-	RKGlobals::rInterface ()->issueCommand (command, chain);
+	RInterface::issueCommand (command, chain);
 }
 
 RKEditObjectAgent::~RKEditObjectAgent () {
diff --git a/rkward/agents/rkloadagent.cpp b/rkward/agents/rkloadagent.cpp
index 592c97de..91bdb11a 100644
--- a/rkward/agents/rkloadagent.cpp
+++ b/rkward/agents/rkloadagent.cpp
@@ -54,11 +54,11 @@ RKLoadAgent::RKLoadAgent (const QUrl &url, bool merge) {
 	
 	if (!merge) {
 		command = new RCommand ("remove (list=ls (all.names=TRUE))", RCommand::App | RCommand::ObjectListUpdate);
-		RKGlobals::rInterface ()->issueCommand (command);
+		RInterface::issueCommand (command);
 	}
 
 	command = new RCommand ("load (\"" + filename + "\")", RCommand::App | RCommand::ObjectListUpdate, QString (), this, WORKSPACE_LOAD_COMMAND);
-	RKGlobals::rInterface ()->issueCommand (command);
+	RInterface::issueCommand (command);
 
 	RKWorkplace::mainWorkplace ()->setWorkspaceURL (url);
 }
@@ -78,11 +78,11 @@ void RKLoadAgent::rCommandDone (RCommand *command) {
 			RKWorkplace::mainWorkplace ()->restoreWorkplace (0, _merge);
 			if (RKSettingsModuleGeneral::cdToWorkspaceOnLoad ()) {
 				if (RKWorkplace::mainWorkplace ()->workspaceURL ().isLocalFile ()) {
-					RKGlobals::rInterface ()->issueCommand ("setwd (" + RObject::rQuote (RKWorkplace::mainWorkplace ()->workspaceURL ().adjusted (QUrl::RemoveFilename).path ()) + ')', RCommand::App);
+					RInterface::issueCommand ("setwd (" + RObject::rQuote (RKWorkplace::mainWorkplace ()->workspaceURL ().adjusted (QUrl::RemoveFilename).path ()) + ')', RCommand::App);
 				}
 			}
 		}
-		RKGlobals::rInterface()->issueCommand(QString(), RCommand::EmptyCommand | RCommand::App, QString(), this, WORKSPACE_LOAD_COMPLETE_COMMAND);
+		RInterface::issueCommand(QString(), RCommand::EmptyCommand | RCommand::App, QString(), this, WORKSPACE_LOAD_COMPLETE_COMMAND);
 		RKWardMainWindow::getMain ()->setCaption (QString ());	// trigger update of caption
 	} else if (command->getFlags () == WORKSPACE_LOAD_COMPLETE_COMMAND) {
 		RKWardMainWindow::getMain ()->slotSetStatusReady ();
diff --git a/rkward/agents/rkquitagent.cpp b/rkward/agents/rkquitagent.cpp
index 348a4bc2..c7d01a13 100644
--- a/rkward/agents/rkquitagent.cpp
+++ b/rkward/agents/rkquitagent.cpp
@@ -32,17 +32,17 @@ RKQuitAgent::RKQuitAgent (QObject *parent) : QObject (parent) {
 	cancel_dialog->addRCommand (command, true);
 	connect (cancel_dialog, &RKProgressControl::cancelled, this, &RKQuitAgent::doQuitNow);
 
-	if (RKGlobals::rInterface ()->backendIsDead ()) {	// nothing to loose
+	if (RInterface::instance()->backendIsDead()) {	// nothing to loose
 		QTimer::singleShot (0, this, SLOT (doQuitNow()));
 		return;
-	} else if (RKGlobals::rInterface ()->backendIsIdle ()) {
+	} else if (RInterface::instance()->backendIsIdle()) {
 		// there should be no problem while quitting. If there is, show the dialog after 300 msec
 		QTimer::singleShot (300, this, SLOT (showWaitDialog()));
 	} else {
 		showWaitDialog ();
 	}
 
-	RKGlobals::rInterface ()->issueCommand (command);
+	RInterface::issueCommand (command);
 }
 
 RKQuitAgent::~RKQuitAgent () {
diff --git a/rkward/agents/rksaveagent.cpp b/rkward/agents/rksaveagent.cpp
index 622240f0..b84b23ab 100644
--- a/rkward/agents/rksaveagent.cpp
+++ b/rkward/agents/rksaveagent.cpp
@@ -76,7 +76,7 @@ bool RKSaveAgent::saveWorkspace(const QUrl& _url) {
 	if (url.isEmpty()) return saveWorkspaceAs();
 
 	RKWorkplace::mainWorkplace()->flushAllData();
-	auto save_chain = RKGlobals::rInterface()->startChain(0);
+	auto save_chain = RInterface::startChain(0);
 
 	RKWorkplace::mainWorkplace()->saveWorkplace(url, save_chain);
 	auto command = new RCommand("save.image(" + RObject::rQuote(url.toLocalFile()) + ')', RCommand::App);
@@ -84,9 +84,9 @@ bool RKSaveAgent::saveWorkspace(const QUrl& _url) {
 	control.addRCommand(command, true);
 	bool success = false;
 	QObject::connect(command->notifier(), &RCommandNotifier::commandFinished, [&success, command]() { success = command->succeeded(); });  // clazy:exclude=lambda-in-connect (-> doModal(), below)
-	RKGlobals::rInterface()->issueCommand(command, save_chain);
+	RInterface::issueCommand(command, save_chain);
 	control.doModal(false);
-	RKGlobals::rInterface()->closeChain(save_chain);
+	RInterface::closeChain(save_chain);
 
 	if (!success) KMessageBox::error(RKWardMainWindow::getMain(), i18n("Save failed"), i18n("An error occurred while trying to save the workspace. You data was <b>not</b> saved."));
 	RKWorkplace::mainWorkplace()->setWorkspaceURL(url, true);
diff --git a/rkward/core/rcontainerobject.cpp b/rkward/core/rcontainerobject.cpp
index e8691d69..fc444348 100644
--- a/rkward/core/rcontainerobject.cpp
+++ b/rkward/core/rcontainerobject.cpp
@@ -318,7 +318,7 @@ void RContainerObject::renameChild (RObject *object, const QString &new_name) {
 	}
 
 	RCommand *command = new RCommand (renameChildCommand (object, new_name), RCommand::App | RCommand::Sync);
-	RKGlobals::rInterface ()->issueCommand (command, 0);
+	RInterface::issueCommand (command, 0);
 
 	object->name = new_name;
 }
@@ -350,7 +350,7 @@ void RContainerObject::removeChild (RObject *object, bool removed_in_workspace)
 		}
 
 		RCommand *command = new RCommand (removeChildCommand (object), RCommand::App | RCommand::Sync | RCommand::ObjectListUpdate);
-		RKGlobals::rInterface ()->issueCommand (command, 0);
+		RInterface::issueCommand (command, 0);
 	}
 
 	removeChildNoDelete (object);
diff --git a/rkward/core/renvironmentobject.cpp b/rkward/core/renvironmentobject.cpp
index c8df2dca..8860097c 100644
--- a/rkward/core/renvironmentobject.cpp
+++ b/rkward/core/renvironmentobject.cpp
@@ -105,7 +105,7 @@ void REnvironmentObject::updateFromR (RCommandChain *chain) {
 	if (type & PackageEnv) options.append (", namespacename=" + rQuote (packageName ()));
 
 	RCommand *command = new RCommand (".rk.get.structure (" + getFullName (DefaultObjectNameOptions) + ", " + rQuote (getShortName ()) + options + ')', RCommand::App | RCommand::Sync | RCommand::GetStructuredData, QString (), this, ROBJECT_UDPATE_STRUCTURE_COMMAND);
-	RKGlobals::rInterface ()->issueCommand (command, chain);
+	RInterface::issueCommand (command, chain);
 
 	type |= Updating;
 }
diff --git a/rkward/core/rkrownames.cpp b/rkward/core/rkrownames.cpp
index 577a206d..d4fffba3 100644
--- a/rkward/core/rkrownames.cpp
+++ b/rkward/core/rkrownames.cpp
@@ -62,7 +62,7 @@ void RKRowNames::writeData (int from_row, int to_row, RCommandChain *chain) {
 	RK_TRACE (OBJECTS);
 
 	if (isSequential ()) {
-		RKGlobals::rInterface ()->issueCommand (getFullName (DefaultObjectNameOptions) + " <- NULL", RCommand::App | RCommand::Sync, QString (), 0,0, chain);
+		RInterface::issueCommand (getFullName (DefaultObjectNameOptions) + " <- NULL", RCommand::App | RCommand::Sync, QString (), 0,0, chain);
 	} else {
 		// unfortunately, we always need to write the whole data, as row.names<- does not support indexing.
 		QString data_string = "c (";
@@ -74,7 +74,7 @@ void RKRowNames::writeData (int from_row, int to_row, RCommandChain *chain) {
 			}
 		}
 		data_string.append (")");
-		RKGlobals::rInterface ()->issueCommand (getFullName (DefaultObjectNameOptions) + " <- " + data_string, RCommand::App | RCommand::Sync, QString (), 0, 0, chain);
+		RInterface::issueCommand (getFullName (DefaultObjectNameOptions) + " <- " + data_string, RCommand::App | RCommand::Sync, QString (), 0, 0, chain);
 	}
 
 	ChangeSet *set = new ChangeSet;
diff --git a/rkward/core/rkvariable.cpp b/rkward/core/rkvariable.cpp
index 470ac331..d9776303 100644
--- a/rkward/core/rkvariable.cpp
+++ b/rkward/core/rkvariable.cpp
@@ -85,7 +85,7 @@ void RKVariable::setVarType (RObject::RDataType new_type, bool sync) {
 			else if (new_type == RObject::DataLogical) command += "as.logical";
 			else if (new_type == RObject::DataFactor) command += "as.factor";
 			command += ')';
-			RKGlobals::rInterface ()->issueCommand (command, RCommand::App | RCommand::Sync, QString ());
+			RInterface::issueCommand (command, RCommand::App | RCommand::Sync, QString ());
 			if (new_type == RObject::DataFactor) updateValueLabels ();	// as.factor resets the "levels"-attribute!
 
 			syncDataToR ();
@@ -286,7 +286,7 @@ void RKVariable::updateDataFromR (RCommandChain *chain) {
 	RK_TRACE (OBJECTS);
 	if (!data) return;
 
-	RKGlobals::rInterface ()->issueCommand (".rk.get.vector.data (" + getFullName () + ')', RCommand::App | RCommand::Sync | RCommand::GetStructuredData, QString (), this, GET_DATA_COMMAND, chain);
+	RInterface::issueCommand (".rk.get.vector.data (" + getFullName () + ')', RCommand::App | RCommand::Sync | RCommand::GetStructuredData, QString (), this, GET_DATA_COMMAND, chain);
 }
 
 void RKVariable::lockSyncing (bool lock) {
@@ -364,7 +364,7 @@ void RKVariable::writeInvalidFields (QList<int> rows, RCommandChain *chain) {
 		if (!values.isEmpty ()) values.append (",");
 	}
 
-	RKGlobals::rInterface ()->issueCommand (".rk.set.invalid.fields (" + getFullName () + ", " + set + values + clear + ')', RCommand::App | RCommand::Sync, QString (), 0,0, chain);
+	RInterface::issueCommand (".rk.set.invalid.fields (" + getFullName () + ", " + set + values + clear + ')', RCommand::App | RCommand::Sync, QString (), 0,0, chain);
 
 	if (data->previously_valid != data->invalid_fields.isEmpty ()) {
 		data->previously_valid = data->invalid_fields.isEmpty ();
@@ -380,7 +380,7 @@ void RKVariable::writeData (int from_row, int to_row, RCommandChain *chain) {
 
 	// TODO: try to sync in correct storage mode
 	if (from_row == to_row) {
-		RKGlobals::rInterface ()->issueCommand (getFullName () + '[' + QString::number (from_row+1) + "] <- " + getRText (from_row), RCommand::App | RCommand::Sync, QString (), 0,0, chain);
+		RInterface::issueCommand (getFullName () + '[' + QString::number (from_row+1) + "] <- " + getRText (from_row), RCommand::App | RCommand::Sync, QString (), 0,0, chain);
 		if (data->cell_states[from_row] & RKVarEditData::UnsyncedInvalidState) changed_invalids.append (from_row);
 	} else {
 		QString data_string = "c (";
@@ -393,7 +393,7 @@ void RKVariable::writeData (int from_row, int to_row, RCommandChain *chain) {
 			if (data->cell_states[row] & RKVarEditData::UnsyncedInvalidState) changed_invalids.append (row);
 		}
 		data_string.append (")");
-		RKGlobals::rInterface ()->issueCommand (getFullName () + '[' + QString::number (from_row + 1) + ':' + QString::number (to_row + 1) + "] <- " + data_string, RCommand::App | RCommand::Sync, QString (), 0,0, chain);
+		RInterface::issueCommand (getFullName () + '[' + QString::number (from_row + 1) + ':' + QString::number (to_row + 1) + "] <- " + data_string, RCommand::App | RCommand::Sync, QString (), 0,0, chain);
 	}
 
 	if (!changed_invalids.isEmpty ()) writeInvalidFields (changed_invalids, chain);
@@ -758,7 +758,7 @@ void RKVariable::writeValueLabels (RCommandChain *chain) const {
 		level_string = "NULL";
 	}
 
-	RKGlobals::rInterface ()->issueCommand (".rk.set.levels (" + getFullName () + ", " + level_string + ')', RCommand::App | RCommand::Sync, QString (), 0, 0, chain);
+	RInterface::issueCommand (".rk.set.levels (" + getFullName () + ", " + level_string + ')', RCommand::App | RCommand::Sync, QString (), 0, 0, chain);
 }
 
 QString RKVariable::getValueLabelString () const {
diff --git a/rkward/core/robject.cpp b/rkward/core/robject.cpp
index 2e6caae7..c440afae 100644
--- a/rkward/core/robject.cpp
+++ b/rkward/core/robject.cpp
@@ -203,7 +203,7 @@ void RObject::writeMetaData (RCommandChain *chain) {
 	}
 
 	RCommand *command = new RCommand (".rk.set.meta (" + getFullName () + ", " + map_string + ')', RCommand::App | RCommand::Sync);
-	RKGlobals::rInterface ()->issueCommand (command, chain);
+	RInterface::issueCommand (command, chain);
 }
 
 void RObject::updateFromR (RCommandChain *chain) {
@@ -220,7 +220,7 @@ void RObject::updateFromR (RCommandChain *chain) {
 // This is the less common branch, but we do call .rk.get.structure on sub-object, e.g. when fetching more levels in the Workspace Browser, or when calling rk.sync(), explicitly
 		command = new RCommand (".rk.get.structure (" + getFullName () + ", " + rQuote (getShortName ()) + ')', RCommand::App | RCommand::Sync | RCommand::GetStructuredData, QString (), this, ROBJECT_UDPATE_STRUCTURE_COMMAND);
 	}
-	RKGlobals::rInterface ()->issueCommand (command, chain);
+	RInterface::issueCommand (command, chain);
 
 	type |= Updating;	// will be cleared, implicitly, when the new structure gets set
 }
diff --git a/rkward/core/robjectlist.cpp b/rkward/core/robjectlist.cpp
index 04ae4429..d7ac47a7 100644
--- a/rkward/core/robjectlist.cpp
+++ b/rkward/core/robjectlist.cpp
@@ -86,7 +86,7 @@ QStringList RObjectList::detachPackages (const QStringList &packages, RCommandCh
 		RCommand *command = new RCommand ("detach (" + rQuote (remove[i]) + ')', RCommand::App | RCommand::ObjectListUpdate);
 
 		if (control) control->addRCommand (command);
-		RKGlobals::rInterface()->issueCommand (command, chain);
+		RInterface::issueCommand (command, chain);
 	}
 
 	return reject;
@@ -103,10 +103,10 @@ void RObjectList::updateFromR (RCommandChain *chain) {
 	}
 
 	emit updateStarted();
-	update_chain = RKGlobals::rInterface ()->startChain (chain);
+	update_chain = RInterface::startChain (chain);
 
 	RCommand *command = new RCommand ("list (search (), loadedNamespaces ())", RCommand::App | RCommand::Sync | RCommand::GetStructuredData, QString (), this, ROBJECTLIST_UPDATE_ENVIRONMENTS_COMMAND);
-	RKGlobals::rInterface ()->issueCommand (command, update_chain);
+	RInterface::issueCommand (command, update_chain);
 }
 
 void RObjectList::updateFromR (RCommandChain *chain, const QStringList &current_searchpath, const QStringList &current_namespaces) {
@@ -121,12 +121,12 @@ void RObjectList::updateFromR (RCommandChain *chain, const QStringList &current_
 	}
 
 	emit updateStarted();
-	update_chain = RKGlobals::rInterface ()->startChain (chain);
+	update_chain = RInterface::startChain (chain);
 
 	updateEnvironments (current_searchpath, false);
 	updateNamespaces (current_namespaces);
 
-	RKGlobals::rInterface ()->issueCommand (QString (), RCommand::App | RCommand::Sync | RCommand::EmptyCommand, QString (), this, ROBJECTLIST_UPDATE_COMPLETE_COMMAND, update_chain);
+	RInterface::issueCommand (QString (), RCommand::App | RCommand::Sync | RCommand::EmptyCommand, QString (), this, ROBJECTLIST_UPDATE_COMPLETE_COMMAND, update_chain);
 }
 
 void RObjectList::rCommandDone (RCommand *command) {
@@ -143,10 +143,10 @@ void RObjectList::rCommandDone (RCommand *command) {
 		updateEnvironments (new_environments, true);
 		updateNamespaces (data[1]->stringVector ());
 
-		RKGlobals::rInterface ()->issueCommand (QString (), RCommand::App | RCommand::Sync | RCommand::EmptyCommand, QString (), this, ROBJECTLIST_UPDATE_COMPLETE_COMMAND, update_chain);
+		RInterface::issueCommand (QString (), RCommand::App | RCommand::Sync | RCommand::EmptyCommand, QString (), this, ROBJECTLIST_UPDATE_COMPLETE_COMMAND, update_chain);
 	} else if (command->getFlags () == ROBJECTLIST_UPDATE_COMPLETE_COMMAND) {
 		RK_ASSERT (update_chain);
-		RKGlobals::rInterface ()->closeChain (update_chain);
+		RInterface::closeChain (update_chain);
 		update_chain = 0;
 	
 		RK_DEBUG (OBJECTS, DL_DEBUG, "object list update complete");
diff --git a/rkward/dataeditor/rkeditordataframe.cpp b/rkward/dataeditor/rkeditordataframe.cpp
index 16700901..8bd9a356 100644
--- a/rkward/dataeditor/rkeditordataframe.cpp
+++ b/rkward/dataeditor/rkeditordataframe.cpp
@@ -61,7 +61,7 @@ RKEditorDataFrame::RKEditorDataFrame (const QString& new_object_name, QWidget* p
 	initTable (model, object);
 	connect (model, &RKVarEditDataFrameModel::modelObjectDestroyed, this, &RKEditorDataFrame::deleteLater);
 
-	RKGlobals::rInterface ()->closeChain (open_chain);
+	RInterface::closeChain (open_chain);
 }
 
 void RKEditorDataFrame::commonInit () {
@@ -71,12 +71,12 @@ void RKEditorDataFrame::commonInit () {
 	getPart ()->insertChildClient (this);
 	initializeActivationSignals ();
 
-	open_chain = RKGlobals::rInterface ()->startChain (0);
+	open_chain = RInterface::startChain (0);
 }
 
 RKEditorDataFrame::~RKEditorDataFrame () {
 	RK_TRACE (EDITOR);
-	if (open_chain) RKGlobals::rInterface()->closeChain(open_chain);
+	if (open_chain) RInterface::closeChain(open_chain);
 }
 
 void RKEditorDataFrame::detachModel () {
@@ -99,14 +99,14 @@ void RKEditorDataFrame::waitForLoad () {
 	enableEditing (false);
 
 	RCommand *command = new RCommand (QString (), RCommand::EmptyCommand | RCommand::Sync | RCommand::GetStringVector, QString (), this, LOAD_COMPLETE_COMMAND);
-	RKGlobals::rInterface ()->issueCommand (command, open_chain);
+	RInterface::issueCommand (command, open_chain);
 }
 
 void RKEditorDataFrame::rCommandDone (RCommand *command) {
 	RK_TRACE (EDITOR);
 
 	if (command->getFlags () == LOAD_COMPLETE_COMMAND) {
-		RKGlobals::rInterface ()->closeChain (open_chain);
+		RInterface::closeChain (open_chain);
 		open_chain = 0;
 
 		enableEditing (true);
diff --git a/rkward/dataeditor/rkvareditmodel.cpp b/rkward/dataeditor/rkvareditmodel.cpp
index a2a40a1f..942e188a 100644
--- a/rkward/dataeditor/rkvareditmodel.cpp
+++ b/rkward/dataeditor/rkvareditmodel.cpp
@@ -849,7 +849,7 @@ bool RKVarEditDataFrameModel::insertColumns (int column, int count, const QModel
 		RK_ASSERT (obj->isVariable ());
 //		addObject (col, obj);	// the object will be added via RKModificationTracker::addObject -> this::childAdded. That will also take care of calling beginInsertColumns()/endInsertColumns()
 	
-		RKGlobals::rInterface ()->issueCommand (new RCommand (".rk.data.frame.insert.column (" + dataframe->getFullName () + ", \"" + obj->getShortName () + "\", " + QString::number (col+1-var_col_offset) + ")", RCommand::App | RCommand::Sync));
+		RInterface::issueCommand (new RCommand (".rk.data.frame.insert.column (" + dataframe->getFullName () + ", \"" + obj->getShortName () + "\", " + QString::number (col+1-var_col_offset) + ")", RCommand::App | RCommand::Sync));
 	}
 
 	return true;
@@ -881,7 +881,7 @@ void RKVarEditDataFrameModel::doInsertRowsInBackend (int row, int count) {
 
 	// TODO: most of the time we're only adding one row at a time, still we should have a function to add multiple rows at once.
 	for (int i = row; i < row + count; ++i) {
-		RKGlobals::rInterface ()->issueCommand (new RCommand (".rk.data.frame.insert.row (" + dataframe->getFullName () + ", " + QString::number (i+1) + ')', RCommand::App | RCommand::Sync));
+		RInterface::issueCommand (new RCommand (".rk.data.frame.insert.row (" + dataframe->getFullName () + ", " + QString::number (i+1) + ')', RCommand::App | RCommand::Sync));
 	}
 }
 
@@ -889,7 +889,7 @@ void RKVarEditDataFrameModel::doRemoveRowsInBackend (int row, int count) {
 	RK_TRACE (EDITOR);
 
 	for (int i = row + count - 1; i >= row; --i) {
-		RKGlobals::rInterface ()->issueCommand (new RCommand (".rk.data.frame.delete.row (" + dataframe->getFullName () + ", " + QString::number (i+1) + ')', RCommand::App | RCommand::Sync));
+		RInterface::issueCommand (new RCommand (".rk.data.frame.delete.row (" + dataframe->getFullName () + ", " + QString::number (i+1) + ')', RCommand::App | RCommand::Sync));
 	}
 }
 
@@ -964,7 +964,7 @@ void RKVarEditDataFrameModel::pushTable (RCommandChain *sync_chain) {
 	command.append (")");
 
 	// push all children
-	RKGlobals::rInterface ()->issueCommand (new RCommand (command, RCommand::Sync), sync_chain);
+	RInterface::issueCommand (new RCommand (command, RCommand::Sync), sync_chain);
 	for (int col=0; col < objects.size (); ++col) {
 		objects[col]->restore (sync_chain);
 	}
@@ -972,7 +972,7 @@ void RKVarEditDataFrameModel::pushTable (RCommandChain *sync_chain) {
 	// now store the meta-data
 	dataframe->writeMetaData (sync_chain);
 
-	RKGlobals::rInterface ()->issueCommand (new RCommand (QString (), RCommand::Sync | RCommand::EmptyCommand | RCommand::ObjectListUpdate), sync_chain);
+	RInterface::issueCommand (new RCommand (QString (), RCommand::Sync | RCommand::EmptyCommand | RCommand::ObjectListUpdate), sync_chain);
 }
 
 void RKVarEditDataFrameModel::restoreObject (RObject* object, RCommandChain* chain) {
diff --git a/rkward/dialogs/rkerrordialog.cpp b/rkward/dialogs/rkerrordialog.cpp
index 918de894..5a874be7 100644
--- a/rkward/dialogs/rkerrordialog.cpp
+++ b/rkward/dialogs/rkerrordialog.cpp
@@ -140,11 +140,11 @@ void RKErrorDialog::reportBug (QWidget* parent_widget, const QString& message_in
 
 	report_template.append ("\n---Session Info---\n");
 	bool ok = false;
-	if (!RKGlobals::rInterface ()->backendIsDead ()) {
+	if (!RInterface::instance()->backendIsDead ()) {
 		RCommand *command = new RCommand ("rk.sessionInfo()", RCommand::App);
 		RKProgressControl *control = new RKProgressControl (parent_widget, i18n ("Please stand by while gathering some information on your setup.\nIn case the backend has died or hung up, you may want to press 'Cancel' to skip this step."), i18n ("Gathering setup information"), RKProgressControl::CancellableNoProgress);
 		control->addRCommand (command, true);
-		RKGlobals::rInterface ()->issueCommand (command);
+		RInterface::issueCommand(command);
 		ok = control->doModal (false);
 		// NOTE: command is already deleted at this point
 		report_template.append (control->fullCommandOutput ());
diff --git a/rkward/dialogs/rkloadlibsdialog.cpp b/rkward/dialogs/rkloadlibsdialog.cpp
index 34024aae..9f835696 100644
--- a/rkward/dialogs/rkloadlibsdialog.cpp
+++ b/rkward/dialogs/rkloadlibsdialog.cpp
@@ -73,7 +73,7 @@ RKLoadLibsDialog::RKLoadLibsDialog (QWidget *parent, RCommandChain *chain, bool
 		library_locations = command->stringVector();
 		emit libraryLocationsChanged(library_locations);
 	});
-	RKGlobals::rInterface()->issueCommand(command, chain);
+	RInterface::issueCommand(command, chain);
 }
 
 RKLoadLibsDialog::~RKLoadLibsDialog () {
@@ -479,7 +479,7 @@ void LoadUnloadWidget::updateInstalledPackages () {
 		installed_view->setSortingEnabled (true);
 		installed_view->sortItems (0, Qt::AscendingOrder);
 	});
-	RKGlobals::rInterface ()->issueCommand(command, parent->chain);
+	RInterface::issueCommand(command, parent->chain);
 
 	command = new RCommand(".packages()", RCommand::App | RCommand::Sync | RCommand::GetStringVector);
 	connect(command->notifier(), &RCommandNotifier::commandFinished, this, [this](RCommand *command) {
@@ -498,7 +498,7 @@ void LoadUnloadWidget::updateInstalledPackages () {
 		loaded_view->sortItems (0, Qt::AscendingOrder);
 		updateCurrentList ();
 	});
-	RKGlobals::rInterface()->issueCommand(command, parent->chain);
+	RInterface::issueCommand(command, parent->chain);
 }
 
 void LoadUnloadWidget::loadButtonClicked () {
@@ -572,7 +572,7 @@ void LoadUnloadWidget::doLoadUnload () {
 		if (!prev_packages.contains (loaded->text (0))) {
 			RCommand *command = new RCommand ("library (\"" + loaded->text (0) + "\")", RCommand::App | RCommand::ObjectListUpdate);
 			control->addRCommand (command);
-			RKGlobals::rInterface ()->issueCommand (command, parent->chain);
+			RInterface::issueCommand (command, parent->chain);
 		}
 	}
 	
@@ -594,7 +594,7 @@ void LoadUnloadWidget::doLoadUnload () {
 	connect(command->notifier(), &RCommandNotifier::commandFinished, this, [this](RCommand *) {
 		emit loadUnloadDone();
 	});
-	RKGlobals::rInterface()->issueCommand(command, parent->chain);
+	RInterface::issueCommand(command, parent->chain);
 
 	control->doNonModal(true);
 }
@@ -935,7 +935,7 @@ void RKRPackageInstallationStatus::initialize (RCommandChain *chain) {
 	connect (command->notifier (), &RCommandNotifier::commandFinished, this, &RKRPackageInstallationStatus::statusCommandFinished);
 	RKProgressControl *control = new RKProgressControl (this, i18n ("<p>Please stand by while searching for installed and available packages.</p><p><strong>Note:</strong> This requires a working internet connection, and may take some time, esp. if one or more repositories are temporarily unavailable.</p>"), i18n ("Searching for packages"), RKProgressControl::CancellableProgress | RKProgressControl::AutoCancelCommands);
 	control->addRCommand (command, true);
-	RKGlobals::rInterface ()->issueCommand (command, chain);
+	RInterface::issueCommand (command, chain);
 	control->doModal (true);
 }
 
diff --git a/rkward/dialogs/rksetupwizard.cpp b/rkward/dialogs/rksetupwizard.cpp
index 22442b6c..fd4b0303 100644
--- a/rkward/dialogs/rksetupwizard.cpp
+++ b/rkward/dialogs/rksetupwizard.cpp
@@ -200,8 +200,8 @@ RKSetupWizard::RKSetupWizard(QWidget* parent, InvokationReason reason, const QLi
 
 void RKSetupWizard::setupWizardPhase2() {
 	// Wait for R Interface, then enable dialog
-	if (!RKGlobals::rInterface()->backendIsIdle()) {
-		if (RKGlobals::rInterface()->backendIsDead()) {
+	if (!RInterface::instance()->backendIsIdle()) {
+		if (RInterface::instance()->backendIsDead()) {
 			waiting_to_start_label->setText(i18n("<b>R backend has crashed. Click \"Cancel\" to exit setup assistant.</b>"));
 		} else {
 			QTimer::singleShot(100, this, &RKSetupWizard::setupWizardPhase2);
@@ -332,7 +332,7 @@ void RKSetupWizard::fullInteractiveCheck(InvokationReason reason, const QList<RK
 		}
 #endif
 		for(int i = 0; i < wizard->r_commands_to_run.size(); ++i) {
-			RKGlobals::rInterface()->issueCommand(wizard->r_commands_to_run[i], RCommand::App);
+			RInterface::issueCommand(wizard->r_commands_to_run[i], RCommand::App);
 		}
 	}
 
diff --git a/rkward/misc/rkoutputdirectory.cpp b/rkward/misc/rkoutputdirectory.cpp
index 563d58d0..e7973ecf 100644
--- a/rkward/misc/rkoutputdirectory.cpp
+++ b/rkward/misc/rkoutputdirectory.cpp
@@ -274,12 +274,12 @@ GenericRRequestResult RKOutputDirectory::activate(RCommandChain* chain) {
 	RK_TRACE (APP);
 
 	QString index_file = work_dir + "/index.html";
-	RKGlobals::rInterface()->issueCommand(QStringLiteral("rk.set.output.html.file(\"") + RKCommonFunctions::escape(index_file) + QStringLiteral("\")\n"), RCommand::App, QString(), 0, 0, chain);
+	RInterface::issueCommand(QStringLiteral("rk.set.output.html.file(\"") + RKCommonFunctions::escape(index_file) + QStringLiteral("\")\n"), RCommand::App, QString(), 0, 0, 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
 		RCommand *command = new RCommand(QString(), RCommand::App | RCommand::Sync | RCommand::EmptyCommand);
 		connect(command->notifier(), &RCommandNotifier::commandFinished, this, &RKOutputDirectory::updateSavedHash);
-		RKGlobals::rInterface()->issueCommand(command, chain);
+		RInterface::issueCommand(command, chain);
 		initialized = true;
 	}
 
@@ -524,7 +524,7 @@ RKOutputDirectoryCallResult RKOutputDirectory::get(const QString &_filename, boo
 			dir->save_filename = filename;
 			// this is a bit cumbersome. TODO: create a dedicated function to init an output.
 			RCommand *command = new RCommand(QStringLiteral("local({o <- rk.output(); n <- rk.output(\"") + RKCommonFunctions::escape(filename) + QStringLiteral("\"); n$activate(); n$save(); try(o$activate(), silent=TRUE); o$save() })\n"), RCommand::App);
-			RKGlobals::rInterface()->issueCommand(command, chain);
+			RInterface::issueCommand(command, chain);
 		} else {
 			if (!(file_exists || dir)) return GenericRRequestResult::makeError(i18n("File '%1' does not exist.", filename));
 
diff --git a/rkward/misc/rkprogresscontrol.cpp b/rkward/misc/rkprogresscontrol.cpp
index f0c5ec15..85cc4985 100644
--- a/rkward/misc/rkprogresscontrol.cpp
+++ b/rkward/misc/rkprogresscontrol.cpp
@@ -162,7 +162,7 @@ void RKProgressControl::dialogDestroyed () {
 		is_done = true;
 		if (mode & AutoCancelCommands) {
 			for (RCommandList::const_iterator it = outstanding_commands.cbegin (); it != outstanding_commands.cend (); ++it) {
-				RKGlobals::rInterface ()->cancelCommand (*it);
+				RInterface::instance()->cancelCommand(*it);
 			}
 		}
 		emit cancelled();
diff --git a/rkward/misc/rkxmlguipreviewarea.cpp b/rkward/misc/rkxmlguipreviewarea.cpp
index 58508aa1..3d9eb7e3 100644
--- a/rkward/misc/rkxmlguipreviewarea.cpp
+++ b/rkward/misc/rkxmlguipreviewarea.cpp
@@ -196,9 +196,9 @@ void RKPreviewManager::setCommand (RCommand* command) {
 	// Send an empty dummy command first. This is to sync up with any commands that should have been run _before_ the preview (e.g. to set up the preview area, so that status labels can be shown)
 	RCommand *dummy = new RCommand (QString (), RCommand::App | RCommand::Sync | RCommand::EmptyCommand);
 	connect(dummy->notifier(), &RCommandNotifier::commandFinished, this, [this]() { setStatusMessage(shortStatusLabel()); });
-	RKGlobals::rInterface ()->issueCommand (dummy);
+	RInterface::issueCommand (dummy);
 
-	RKGlobals::rInterface ()->issueCommand (command);
+	RInterface::issueCommand (command);
 	setStatusMessage (shortStatusLabel ());
 }
 
diff --git a/rkward/plugin/rkpreviewbox.cpp b/rkward/plugin/rkpreviewbox.cpp
index 1a96a760..c76a394d 100644
--- a/rkward/plugin/rkpreviewbox.cpp
+++ b/rkward/plugin/rkpreviewbox.cpp
@@ -70,7 +70,7 @@ RKPreviewBox::RKPreviewBox (const QDomElement &element, RKComponent *parent_comp
 			uicomp->addDockedPreview (state, toggle_preview_box->text (), manager->previewId ());
 
 			if (preview_mode == OutputPreview) {
-				RKGlobals::rInterface ()->issueCommand ("local ({\n"
+				RInterface::issueCommand ("local ({\n"
 				    "outfile <- tempfile (fileext='.html')\n"
 				    "rk.assign.preview.data(" + idprop + ", list (filename=outfile, on.delete=function (id) {\n"
 				    "	rk.flush.output (outfile, ask=FALSE)\n"
@@ -81,7 +81,7 @@ RKPreviewBox::RKPreviewBox (const QDomElement &element, RKComponent *parent_comp
 				    "})\n" + placement_command + "rk.show.html(rk.get.preview.data (" + idprop + ")$filename)" + placement_end, RCommand::Plugin | RCommand::Sync);
 			} else {
 				// For all others, create an empty data.frame as dummy. Even for custom docked previews it has the effect of initializing the preview area with _something_.
-				RKGlobals::rInterface ()->issueCommand ("local ({\nrk.assign.preview.data(" + idprop + ", data.frame ())\n})\n" + placement_command + "rk.edit(rkward::.rk.variables$.rk.preview.data[[" + idprop + "]])" + placement_end, RCommand::Plugin | RCommand::Sync);
+				RInterface::issueCommand ("local ({\nrk.assign.preview.data(" + idprop + ", data.frame ())\n})\n" + placement_command + "rk.edit(rkward::.rk.variables$.rk.preview.data[[" + idprop + "]])" + placement_end, RCommand::Plugin | RCommand::Sync);
 			}
 
 			// A bit of a hack: For now, in wizards, docked previews are always active, and control boxes are meaningless.
@@ -181,7 +181,7 @@ void RKPreviewBox::tryPreviewNow () {
 
 	RCommand *command;
 	if (preview_mode == PlotPreview) {
-		RKGlobals::rInterface ()->issueCommand (placement_command + ".rk.startPreviewDevice (" + idprop + ')' + placement_end, RCommand::Plugin | RCommand::Sync, QString ());
+		RInterface::issueCommand (placement_command + ".rk.startPreviewDevice (" + idprop + ')' + placement_end, RCommand::Plugin | RCommand::Sync, QString ());
 		// creating window generates warnings, sometimes. Don't make those part of the warnings shown for the preview -> separate command for the actual plot.
 		command = new RCommand ("local({\n" + code_property->preview () + "})\n", RCommand::Plugin | RCommand::Sync);
 	} else if (preview_mode == DataPreview) {
@@ -209,7 +209,7 @@ void RKPreviewBox::killPreview (bool cleanup) {
 		QString command;
 		if (preview_mode == PlotPreview) command = ".rk.killPreviewDevice (" + idprop + ")\n";
 		command += "rk.discard.preview.data (" + idprop + ')';
-		RKGlobals::rInterface ()->issueCommand (command, RCommand::Plugin | RCommand::Sync);
+		RInterface::issueCommand (command, RCommand::Plugin | RCommand::Sync);
 	}
 	if (placement != DockedPreview) {
 		RKMDIWindow *window =  RKWorkplace::mainWorkplace ()->getNamedWindow (manager->previewId ());
diff --git a/rkward/plugin/rkstandardcomponentgui.cpp b/rkward/plugin/rkstandardcomponentgui.cpp
index b47a970c..ac3e0a32 100644
--- a/rkward/plugin/rkstandardcomponentgui.cpp
+++ b/rkward/plugin/rkstandardcomponentgui.cpp
@@ -309,7 +309,7 @@ void RKStandardComponentGUI::ok () {
 	command.append (code_property->calculate ());
 	command.append (code_property->printout ());
 	command.append ("})\n");
-	RKGlobals::rInterface ()->issueCommand (new RCommand (command, RCommand::Plugin | RCommand::CCOutput | RCommand::ObjectListUpdate), component->commandChain ());
+	RInterface::issueCommand (new RCommand (command, RCommand::Plugin | RCommand::CCOutput | RCommand::ObjectListUpdate), component->commandChain ());
 
 	// re-run link
 	// This should be run in a separate command, in case the above command bails out with an error. Even in that case, the re-run link should be printed.
@@ -323,7 +323,7 @@ void RKStandardComponentGUI::ok () {
 	}
 	// separator line
 	command.append (".rk.make.hr()\n");
-	RKGlobals::rInterface ()->issueCommand (new RCommand (command, RCommand::Plugin | RCommand::ObjectListUpdate | RCommand::Silent), component->commandChain ());
+	RInterface::issueCommand (new RCommand (command, RCommand::Plugin | RCommand::ObjectListUpdate | RCommand::Silent), component->commandChain ());
 
 	if (auto_close_box->isChecked ()) cancel ();
 }
diff --git a/rkward/rbackend/rcommandreceiver.cpp b/rkward/rbackend/rcommandreceiver.cpp
index 0a5149c5..32c2673d 100644
--- a/rkward/rbackend/rcommandreceiver.cpp
+++ b/rkward/rbackend/rcommandreceiver.cpp
@@ -29,7 +29,7 @@ void RCommandReceiver::cancelOutstandingCommands () {
 	RK_TRACE (RBACKEND);
 
 	for (RCommandList::const_iterator it = outstanding_commands.constBegin (); it != outstanding_commands.constEnd (); ++it) {
-		RKGlobals::rInterface()->cancelCommand (*it);
+		RInterface::instance()->cancelCommand(*it);
 	}
 }
 
diff --git a/rkward/rbackend/rkrinterface.cpp b/rkward/rbackend/rkrinterface.cpp
index 56681b0e..106b2bcc 100644
--- a/rkward/rbackend/rkrinterface.cpp
+++ b/rkward/rbackend/rkrinterface.cpp
@@ -68,6 +68,13 @@ SPDX-License-Identifier: GPL-2.0-or-later
 // statics
 double RInterface::na_real;
 int RInterface::na_int;
+RInterface *RInterface::_instance = nullptr;
+
+void RInterface::create() {
+	RK_TRACE (RBACKEND);
+	RK_ASSERT(_instance == nullptr);
+	_instance = new RInterface();
+}
 
 RInterface::RInterface () {
 	RK_TRACE (RBACKEND);
@@ -84,7 +91,7 @@ RInterface::RInterface () {
 
 	// create a fake init command
 	RCommand *fake = new RCommand (i18n ("R Startup"), RCommand::App | RCommand::Sync | RCommand::ObjectListUpdate, i18n ("R Startup"), this, STARTUP_PHASE2_COMPLETE);
-	issueCommand (fake);
+	_issueCommand(fake);
 
 	new RKSessionVars (this);
 	new RKDebugHandler (this);
@@ -93,9 +100,9 @@ RInterface::RInterface () {
 
 	/////// Further initialization commands, which do not necessarily have to run before everything else can be queued, here. ///////
 	// NOTE: will receive the list as a call plain generic request from the backend ("updateInstalledPackagesList")
-	issueCommand (".rk.get.installed.packages()", RCommand::App | RCommand::Sync);
+	_issueCommand(new RCommand(".rk.get.installed.packages()", RCommand::App | RCommand::Sync));
 
-	issueCommand (new RCommand (QString (), RCommand::App | RCommand::Sync | RCommand::EmptyCommand, QString (), this, RSTARTUP_COMPLETE));
+	_issueCommand(new RCommand(QString(), RCommand::App | RCommand::Sync | RCommand::EmptyCommand, QString(), this, RSTARTUP_COMPLETE));
 }
 
 void RInterface::issueCommand (const QString &command, int type, const QString &rk_equiv, RCommandReceiver *receiver, int flags, RCommandChain *chain) {
@@ -480,7 +487,11 @@ void RInterface::flushOutput (bool forced) {
 	}
 }
 
-void RInterface::issueCommand (RCommand *command, RCommandChain *chain) { 
+void RInterface::issueCommand (RCommand *command, RCommandChain *chain) {
+	instance()->_issueCommand(command, chain);
+}
+
+void RInterface::_issueCommand(RCommand *command, RCommandChain *chain) { 
 	RK_TRACE (RBACKEND);
 
 	if (command->command ().isEmpty ()) command->_type |= RCommand::EmptyCommand;
@@ -492,17 +503,17 @@ void RInterface::issueCommand (RCommand *command, RCommandChain *chain) {
 	tryNextCommand ();
 }
 
-RCommandChain *RInterface::startChain (RCommandChain *parent) {
+RCommandChain *RInterface::startChain(RCommandChain *parent) {
 	RK_TRACE (RBACKEND);
 
-	return RCommandStack::startChain (parent);
+	return RCommandStack::startChain(parent);
 };
 
-void RInterface::closeChain (RCommandChain *chain) {
-	RK_TRACE (RBACKEND);
+void RInterface::closeChain(RCommandChain *chain) {
+	RK_TRACE(RBACKEND);
 
-	RCommandStack::closeChain (chain);
-	tryNextCommand ();
+	RCommandStack::closeChain(chain);
+	instance()->tryNextCommand();
 };
 
 void RInterface::cancelAll () {
diff --git a/rkward/rbackend/rkrinterface.h b/rkward/rbackend/rkrinterface.h
index 02a3061c..a1b48371 100644
--- a/rkward/rbackend/rkrinterface.h
+++ b/rkward/rbackend/rkrinterface.h
@@ -34,20 +34,21 @@ class RBackendRequest;
 class RInterface : public QObject, public RCommandReceiver {
 	Q_OBJECT
 public:
-/** constructor */
-	RInterface();
+	static void create();
 /** destructor */
 	~RInterface();
 
+	static RInterface* instance() { return _instance; };
+
 /** issues the given command in the given chain */
-	void issueCommand (RCommand *command, RCommandChain *chain=0);
-/** convenience function to create a new command and issue it. See documentation on RCommand::RCommand () and RInterface::issueCommand () */
-	void issueCommand (const QString &command, int type = 0, const QString &rk_equiv = QString (), RCommandReceiver *receiver=0, int flags=0, RCommandChain *chain=0);
+	static void issueCommand(RCommand *command, RCommandChain *chain=0);
+/** convenience function to create a new command and issue it. See documentation on RCommand::RCommand() and RInterface::issueCommand() */
+	static void issueCommand(const QString &command, int type = 0, const QString &rk_equiv = QString(), RCommandReceiver *receiver=0, int flags=0, RCommandChain *chain=0);
 
 /** opens a new command chain. Returns a pointer to the new chain. If you specify a parent, the new chain will be a sub-chain of that chain. */
-	RCommandChain *startChain (RCommandChain *parent=0);
+	static RCommandChain *startChain(RCommandChain *parent=0);
 /** closes the command chain. The chain (and even its parent, if it is already closed) may be deleted right afterwards! */
-	void closeChain (RCommandChain *chain);
+	static void closeChain(RCommandChain *chain);
 
 /** Ensures that the given command will not be executed, or, if it is already running, interrupts it. Note that commands marked RCommand::Sync can
 not be interrupted. */
@@ -133,6 +134,10 @@ friend class RCommand;
 protected:
 	void handleRequest (RBackendRequest *request);
 	void rCommandDone (RCommand *command) override;
+	static RInterface *_instance;
+	void _issueCommand(RCommand *command, RCommandChain *chain=0);
+/** constructor */
+	RInterface();
 signals:
 	void backendWorkdirChanged();
 /** Note: status is actually RInterface::RStatus */
@@ -159,7 +164,7 @@ code:
 #include "rkglobals.h"
 #include "rbackend/rinterface.h"
 
-RKGlobals::rInterface ()->issueCommand ("print (\"hello world!\")", RCommand::User);
+RInterface::issueCommand ("print (\"hello world!\")", RCommand::User);
 \endcode
 
 You will note, that actually there are two RInterface::issueCommand functions, this one is obviously the one taking a QString and several further
@@ -199,7 +204,7 @@ private:
 
 
 void MyReceiver::someFunction () {
-	RKGlobals::rInterface ()->issueCommand ("print (1+1)", RCommand::App, QString (), this);
+	RInterface::issueCommand ("print (1+1)", RCommand::App, QString (), this);
 }
 
 void MyReceiver::rCommandDone (RCommand *command) {
@@ -232,7 +237,7 @@ To illustrate the option of using "FLAGS", here is a reduced example of how RKVa
 void RKVariable::updateFromR () {
 	//...
 	RCommand *command = new RCommand ("length (" + getFullName () + ")", RCommand::App | RCommand::Sync | RCommand::GetIntVector, QString (), this, UPDATE_DIM_COMMAND);
-	RKGlobals::rInterface ()->issueCommand (command, RKGlobals::rObjectList()->getUpdateCommandChain ());
+	RInterface::issueCommand (command, RKGlobals::rObjectList()->getUpdateCommandChain ());
 }
 
 void RKVariable::rCommandDone (RCommand *command) {
@@ -240,7 +245,7 @@ void RKVariable::rCommandDone (RCommand *command) {
 	if (command->getFlags () == UPDATE_DIM_COMMAND) {
 		// ...
 		RCommand *ncommand = new RCommand ("class (" + getFullName () + ")", RCommand::App | RCommand::Sync | RCommand::GetStringVector, QString (), this, UPDATE_CLASS_COMMAND);
-		RKGlobals::rInterface ()->issueCommand (ncommand, RKGlobals::rObjectList()->getUpdateCommandChain ());
+		RInterface::issueCommand (ncommand, RKGlobals::rObjectList()->getUpdateCommandChain ());
 	} else if (command->getFlags () == UPDATE_CLASS_COMMAND) {
 		//...
 	}
@@ -306,17 +311,17 @@ To cope with this, it is sometimes desirable to keep closer control over the ord
 The way to do this is to use RCommandChain. Basically, when you want commands to be executed in a sequence being sure that no other commands intervene, you do this:
 
 \code
-	RCommandChain *chain = RKGlobals::rInterface ()->startChain ();
+	RCommandChain *chain = RInterface::startChain ();
 
 	// create first command
-	RKGlobals::rInterface ()->issueCommand (first_command, chain);
+	RInterface::issueCommand (first_command, chain);
 
 	// wait for command to return, potentially allows further calls to RInterface::issueCommand () from other places in the code
 
 	// create second command
-	RKGlobals::rInterface ()->issueCommand (second_command, chain);
+	RInterface::issueCommand (second_command, chain);
 
-	RKGlobals::rInterface ()->closeChain (chain);
+	RInterface::closeChain (chain);
 \endcode
 
 Now the point is that you place both of your commands in a dedicated "chain", telling RKWard that those two commands will have to be run in direct succession. If between the first and the second command, another section of the code issues a different command, this command will never be run until all commands in the chain have been run and the chain has been marked as closed.
@@ -324,12 +329,12 @@ Now the point is that you place both of your commands in a dedicated "chain", te
 To illustrate, consider this series of events:
 
 \code
-1) RCommandChain *chain = RKGlobals::rInterface ()->startChain ();
-2) RKGlobals::rInterface ()->issueCommand (first_command, chain);
-3) RKGlobals::rInterface ()->issueCommand (some_command);
-4) RKGlobals::rInterface ()->issueCommand (second_command, chain);
-5) RKGlobals::rInterface ()->issueCommand (some_command2);
-6) RKGlobals::rInterface ()->closeChain (chain);
+1) RCommandChain *chain = RInterface::startChain ();
+2) RInterface::issueCommand (first_command, chain);
+3) RInterface::issueCommand (some_command);
+4) RInterface::issueCommand (second_command, chain);
+5) RInterface::issueCommand (some_command2);
+6) RInterface::closeChain (chain);
 \endcode
 
 Now let's assume for a second, the R backend has been busy doing other stuff and has not executed any of the commands so far, then the execution stack will now look like this:
@@ -345,7 +350,7 @@ Now let's assume for a second, the R backend has been busy doing other stuff and
 So the order of execution will be guaranteed to be first_command, second_command, some_command, some_command2, although they were issued ina different order. You can also open sub chains, using
 
 \code
-RCommandChain *sub_chain = RKGlobals::rInterface ()->startChain (parent_chain);
+RCommandChain *sub_chain = RInterface::startChain (parent_chain);
 \endcode
 
 Remember to close chains when you placed all the commands you needed to. If you don't close the chain, RKWard will continue to wait for new commands in that chain, and never proceed with commands outside of the chain.
@@ -364,7 +369,7 @@ This is typically used in plugins: When you specify this modifier, the plain tex
 These are special modifiers helpful when transferring data from R to RKWard (used primarily in the editor classes and in conjunction with RCommand::Sync): They tell the backend to try to fetch the result as an array of int, char*, or double, respectively. For instance, if you know object "myobject" is an integer vector, you may get the data using
 
 \code
-RKGlobals::rInterface ()->issueCommand ("myobject", RCommand::Sync | RCommand::GetIntVector, QString (), this);
+RInterface::issueCommand ("myobject", RCommand::Sync | RCommand::GetIntVector, QString (), this);
 \endcode
 
 Assuming the data can in fact be converted to a vector of integers, you can then access the data using these members in RCommand:
diff --git a/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp b/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
index 2bccc371..b8d3eaa3 100644
--- a/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
+++ b/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
@@ -192,7 +192,7 @@ void RKGraphicsDevice::checkSize() {
 	if(!view) return;
 	if (view->size () != area.size ()) {
 		if(view->size().isEmpty()) return;
-		RKGlobals::rInterface()->issueCommand(new RCommand ("rkward:::RK.resize(" + QString::number(devices.key(this) + 1) + ',' + QString::number(id) + ')', RCommand::PriorityCommand));
+		RInterface::issueCommand(new RCommand ("rkward:::RK.resize(" + QString::number(devices.key(this) + 1) + ',' + QString::number(id) + ')', RCommand::PriorityCommand));
 	}
 }
 
diff --git a/rkward/rkconsole.cpp b/rkward/rkconsole.cpp
index 96b4c823..f2d3aae6 100644
--- a/rkward/rkconsole.cpp
+++ b/rkward/rkconsole.cpp
@@ -487,7 +487,7 @@ void RKConsole::submitCommand () {
 	doc->insertLine (doc->lines (), QString ());
 	if (!command.isEmpty ()) {
 		current_command = new RCommand (command, RCommand::User | RCommand::Console, QString (), this);
-		RKGlobals::rInterface ()->issueCommand (current_command);
+		RInterface::issueCommand (current_command);
 		interrupt_command_action->setEnabled (true);
 	} else {
 		showPrompt ();
@@ -801,7 +801,7 @@ void RKConsole::resetConsole () {
 
 	input_buffer.clear ();
 	if (current_command) {
-		RKGlobals::rInterface ()->cancelCommand (current_command);
+		RInterface::instance()->cancelCommand(current_command);
 	} else {
 		prefix = nprefix;
 		incomplete_command.clear ();
@@ -880,7 +880,7 @@ void RKConsole::pipeUserCommand (const QString &command) {
 		RKConsole::mainConsole ()->pipeCommandThroughConsoleLocal (command);
 	} else {
 		RCommand *cmd = new RCommand (command, RCommand::User);
-		RKGlobals::rInterface ()->issueCommand (cmd);
+		RInterface::issueCommand (cmd);
 	}
 }
 
diff --git a/rkward/rkglobals.cpp b/rkward/rkglobals.cpp
index 9dc18ab7..d6e5feff 100644
--- a/rkward/rkglobals.cpp
+++ b/rkward/rkglobals.cpp
@@ -8,7 +8,6 @@ SPDX-License-Identifier: GPL-2.0-or-later
 
 #include <qstring.h>
 
-RInterface *RKGlobals::rinter;
 RKModificationTracker *RKGlobals::mtracker;
 QVariantMap RKGlobals::startup_options;
 
diff --git a/rkward/rkglobals.h b/rkward/rkglobals.h
index 1b69fa70..fa0e6a31 100644
--- a/rkward/rkglobals.h
+++ b/rkward/rkglobals.h
@@ -26,8 +26,6 @@ TODO: move the static members to the respective classes instead. There's no poin
 */
 class RKGlobals{
 public:
-/// static pointer to the RInterface
-	static RInterface *rInterface () { return rinter; };
 /// static pointer to the RKModificationTracker
 	static RKModificationTracker *tracker () { return mtracker; };
 
@@ -39,7 +37,6 @@ public:
 	static QVariantMap startup_options;
 private:
 	friend class RKWardMainWindow;
-	static RInterface *rinter;
 	static RKModificationTracker *mtracker;
 };
 
diff --git a/rkward/rkward.cpp b/rkward/rkward.cpp
index f181d36f..7ac65e0b 100644
--- a/rkward/rkward.cpp
+++ b/rkward/rkward.cpp
@@ -118,7 +118,6 @@ RKWardMainWindow::RKWardMainWindow () : KParts::MainWindow ((QWidget *)0, (Qt::W
 	rkward_mainwin = this;
 	katepluginintegration = nullptr;
 	active_ui_buddy = nullptr;
-	RKGlobals::rinter = nullptr;
 	RKCommonFunctions::getRKWardDataDir(); // call this before any forking, in order to avoid potential race conditions during initialization of data dir
 	RKSettings::settings_tracker = new RKSettingsTracker (this);
 
@@ -185,7 +184,7 @@ RKWardMainWindow::~RKWardMainWindow() {
 	delete RKConsole::mainConsole ();
 	delete RKHelpSearchWindow::mainHelpSearch ();
 	delete RKGlobals::tracker ();
-	delete RKGlobals::rInterface ();
+	delete RInterface::instance();
 	delete RControlWindow::getControl ();
 	factory ()->removeClient (RKComponentMap::getMap ());
 	delete RKComponentMap::getMap ();
@@ -244,7 +243,7 @@ void RKWardMainWindow::doPostInit () {
 
 	QString cd_to = RKSettingsModuleGeneral::initialWorkingDirectory ();
 	if (!cd_to.isEmpty ()) {
-		RKGlobals::rInterface ()->issueCommand ("setwd (" + RObject::rQuote (cd_to) + ")\n", RCommand::App);
+		RInterface::issueCommand ("setwd (" + RObject::rQuote (cd_to) + ")\n", RCommand::App);
 		QDir::setCurrent (cd_to);
 	}
 
@@ -277,7 +276,7 @@ void RKWardMainWindow::doPostInit () {
 	// up to this point, no "real" save-worthy stuff can be pending in the backend. So mark this point as "clean".
 	RCommand *command = new RCommand (QString (), RCommand::EmptyCommand | RCommand::Sync | RCommand::App);
 	connect (command->notifier (), &RCommandNotifier::commandFinished, this, &RKWardMainWindow::setWorkspaceUnmodified);
-	RKGlobals::rInterface ()->issueCommand (command);
+	RInterface::issueCommand (command);
 
 	if (!evaluate_code.isEmpty ()) RKConsole::pipeUserCommand (evaluate_code);
 	RKDBusAPI *dbus = new RKDBusAPI (this);
@@ -285,7 +284,7 @@ void RKWardMainWindow::doPostInit () {
 	// around on the bus in this case.
 
 	updateCWD ();
-	connect (RKGlobals::rInterface (), &RInterface::backendWorkdirChanged, this, &RKWardMainWindow::updateCWD);
+	connect (RInterface::instance(), &RInterface::backendWorkdirChanged, this, &RKWardMainWindow::updateCWD);
 	setCaption (QString ());	// our version of setCaption takes care of creating a correct caption, so we do not need to provide it here
 }
 
@@ -367,7 +366,6 @@ void RKWardMainWindow::initPlugins (const QStringList &automatically_added) {
 
 void RKWardMainWindow::startR () {
 	RK_TRACE (APP);
-	RK_ASSERT (!RKGlobals::rInterface ());
 
 	// make sure our general purpose files directory exists
 	QString packages_path = RKSettingsModuleGeneral::filesPath() + "/.rkward_packages";
@@ -392,8 +390,8 @@ void RKWardMainWindow::startR () {
 		}
 	}
 
-	RKGlobals::rinter = new RInterface ();
-	connect(RKGlobals::rInterface(), &RInterface::backendStatusChanged, this, &RKWardMainWindow::setRStatus);
+	RInterface::create();
+	connect(RInterface::instance(), &RInterface::backendStatusChanged, this, &RKWardMainWindow::setRStatus);
 	new RObjectList ();
 
 	RObjectBrowser::mainBrowser ()->unlock ();
@@ -405,9 +403,9 @@ void RKWardMainWindow::slotConfigure () {
 }
 
 void RKWardMainWindow::slotCancelAllCommands () {
-	RK_TRACE (APP);
-	RK_ASSERT (RKGlobals::rInterface ());
-	RKGlobals::rInterface ()->cancelAll ();
+	RK_TRACE(APP);
+	RK_ASSERT(RInterface::instance());
+	RInterface::instance()->cancelAll();
 }
 
 void RKWardMainWindow::configureCarbonCopy () {
diff --git a/rkward/robjectviewer.cpp b/rkward/robjectviewer.cpp
index d43e1683..44ac6102 100644
--- a/rkward/robjectviewer.cpp
+++ b/rkward/robjectviewer.cpp
@@ -267,7 +267,7 @@ void RObjectSummaryWidget::update () {
 	RObjectViewerWidget::update ();
 
 	RCommand *command = new RCommand ("print(summary(" + _object->getFullName () + "))", RCommand::App, QString (), this);
-	RKGlobals::rInterface ()->issueCommand (command, 0);
+	RInterface::issueCommand (command, 0);
 }
 
 ////////////////// print widget /////////////////
@@ -289,7 +289,7 @@ void RObjectPrintWidget::update () {
 	                                  "\ton.exit(options(width=rk.temp.width.save))\n"
 	                                  "\tprint(" + _object->getFullName () + ")\n"
 	                                  "})", RCommand::App, QString (), this);
-	RKGlobals::rInterface ()->issueCommand (command, 0);
+	RInterface::issueCommand (command, 0);
 }
 
 ////////////////// structure widget /////////////////
@@ -305,6 +305,6 @@ void RObjectStructureWidget::update () {
 	RObjectViewerWidget::update ();
 
 	RCommand *command = new RCommand ("str(" + _object->getFullName () + ')', RCommand::App, QString (), this);
-	RKGlobals::rInterface ()->issueCommand (command, 0);
+	RInterface::issueCommand (command, 0);
 }
 
diff --git a/rkward/scriptbackends/rkcomponentscripting.cpp b/rkward/scriptbackends/rkcomponentscripting.cpp
index 0ae49a65..d51ae268 100644
--- a/rkward/scriptbackends/rkcomponentscripting.cpp
+++ b/rkward/scriptbackends/rkcomponentscripting.cpp
@@ -37,7 +37,7 @@ RKComponentScriptingProxy::~RKComponentScriptingProxy () {
 	RK_TRACE (PHP);
 
 	for (int i = 0; i < outstanding_commands.size (); ++i) {
-		RKGlobals::rInterface ()->cancelCommand (outstanding_commands[i].command);
+		RInterface::instance()->cancelCommand(outstanding_commands[i].command);
 	}
 }
 
@@ -140,7 +140,7 @@ QVariant RKComponentScriptingProxy::doRCommand (const QString& command, const QS
 	for (int i = 0; i < outstanding_commands.size (); ++i) {
 		const OutstandingCommand &oc = outstanding_commands[i];
 		if (oc.callback == callback) {
-			if (RKGlobals::rInterface ()->softCancelCommand (oc.command)) {
+			if (RInterface::instance()->softCancelCommand(oc.command)) {
 				outstanding_commands.removeAt (i);
 				--i;
 				continue;
@@ -154,7 +154,7 @@ QVariant RKComponentScriptingProxy::doRCommand (const QString& command, const QS
 	com.callback = callback;
 	outstanding_commands.append (com);
 
-	RKGlobals::rInterface ()->issueCommand (com.command);
+	RInterface::issueCommand (com.command);
 	return (QVariant (com.command->id ()));
 }
 
diff --git a/rkward/settings/rksettingsmodulegraphics.cpp b/rkward/settings/rksettingsmodulegraphics.cpp
index 91d2d364..a8a45c96 100644
--- a/rkward/settings/rksettingsmodulegraphics.cpp
+++ b/rkward/settings/rksettingsmodulegraphics.cpp
@@ -170,7 +170,7 @@ void RKSettingsModuleGraphics::applyChanges () {
 
 	QStringList commands = makeRRunTimeOptionCommands ();
 	for (QStringList::const_iterator it = commands.cbegin (); it != commands.cend (); ++it) {
-		RKGlobals::rInterface ()->issueCommand (*it, RCommand::App, QString (), 0, 0, commandChain ());
+		RInterface::issueCommand (*it, RCommand::App, QString (), 0, 0, commandChain ());
 	}
 }
 
diff --git a/rkward/settings/rksettingsmoduleoutput.cpp b/rkward/settings/rksettingsmoduleoutput.cpp
index b02dbce4..c073809a 100644
--- a/rkward/settings/rksettingsmoduleoutput.cpp
+++ b/rkward/settings/rksettingsmoduleoutput.cpp
@@ -199,7 +199,7 @@ void RKSettingsModuleOutput::applyChanges () {
 
 	QStringList commands = makeRRunTimeOptionCommands ();
 	for (QStringList::const_iterator it = commands.cbegin (); it != commands.cend (); ++it) {
-		RKGlobals::rInterface ()->issueCommand (*it, RCommand::App, QString (), 0, 0, commandChain ());
+		RInterface::issueCommand (*it, RCommand::App, QString (), 0, 0, commandChain ());
 	}
 
 	cc_settings->applyChanges ();
diff --git a/rkward/settings/rksettingsmoduler.cpp b/rkward/settings/rksettingsmoduler.cpp
index ac328b19..934b4708 100755
--- a/rkward/settings/rksettingsmoduler.cpp
+++ b/rkward/settings/rksettingsmoduler.cpp
@@ -195,7 +195,7 @@ void RKSettingsModuleR::applyChanges () {
 // apply run time options in R
 	QStringList commands = makeRRunTimeOptionCommands ();
 	for (QStringList::const_iterator it = commands.cbegin (); it != commands.cend (); ++it) {
-		RKGlobals::rInterface ()->issueCommand (*it, RCommand::App, QString (), 0, 0, commandChain ());
+		RInterface::issueCommand (*it, RCommand::App, QString (), 0, 0, commandChain ());
 	}
 }
 
@@ -366,7 +366,7 @@ void RKSettingsModuleRPackages::addLibraryLocation (const QString& new_loc, RCom
 	if (!libraryLocations ().contains (new_loc)) liblocs.get().prepend (new_loc);
 
 	// update the backend in any case. User might have changed liblocs, there.
-	RKGlobals::rInterface ()->issueCommand (".libPaths (unique (c (" + RObject::rQuote (new_loc) + ", .libPaths ())))", RCommand::App | RCommand::Sync, QString (), 0, 0, chain);
+	RInterface::issueCommand (".libPaths (unique (c (" + RObject::rQuote (new_loc) + ", .libPaths ())))", RCommand::App | RCommand::Sync, QString (), 0, 0, chain);
 }
 
 QStringList expandLibLocs (const QStringList &in) {
@@ -449,7 +449,7 @@ void RKSettingsModuleRPackages::selectCRANMirror () {
 
 	RKProgressControl* control = new RKProgressControl (this, title, title, RKProgressControl::CancellableProgress);
 	control->addRCommand (command, true);
-	RKGlobals::rInterface ()->issueCommand (command, commandChain ());
+	RInterface::issueCommand (command, commandChain ());
 	control->doModal (true);
 }
 
@@ -544,7 +544,7 @@ void RKSettingsModuleRPackages::applyChanges () {
 // apply options in R
 	QStringList commands = makeRRunTimeOptionCommands ();
 	for (QStringList::const_iterator it = commands.cbegin (); it != commands.cend (); ++it) {
-		RKGlobals::rInterface ()->issueCommand (*it, RCommand::App, QString (), 0, 0, commandChain ());
+		RInterface::issueCommand (*it, RCommand::App, QString (), 0, 0, commandChain ());
 	}
 }
 
@@ -597,14 +597,14 @@ void RKSettingsModuleRPackages::validateSettingsInteractive (QList<RKSetupWizard
 			                                        "to work (if they are compatible with this version of R)."), [legacy_libloc](RKSetupWizard*) {
 									liblocs.get().removeAll(legacy_libloc);
 									QString new_loc = legacy_libloc + '-' + RKSessionVars::RVersion (true);
-									RKGlobals::rInterface ()->issueCommand (QString ("file.rename(%1, %2)\n").arg(RObject::rQuote(legacy_libloc), RObject::rQuote (new_loc)), RCommand::App);
+									RInterface::issueCommand (QString ("file.rename(%1, %2)\n").arg(RObject::rQuote(legacy_libloc), RObject::rQuote (new_loc)), RCommand::App);
 									liblocs.get().prepend (legacy_libloc + QStringLiteral ("-%v"));
-									RKGlobals::rInterface ()->issueCommand (libLocsCommand(), RCommand::App);
+									RInterface::issueCommand (libLocsCommand(), RCommand::App);
 								});
 			item->addOption(i18nc("verb", "Remove"), i18n("Remove this location from the configuration (it will not be deleted on disk). You will have to "
 			                                        "re-install any packages that you want to keep."), [legacy_libloc](RKSetupWizard*) {
 									liblocs.get().removeAll(legacy_libloc);
-									RKGlobals::rInterface ()->issueCommand (libLocsCommand(), RCommand::App);
+									RInterface::issueCommand (libLocsCommand(), RCommand::App);
 								});
 			item->addOption(i18nc("verb", "Keep"), i18n("Keep this location (do not change anything)"), [](RKSetupWizard*) {});
 
diff --git a/rkward/windows/rcontrolwindow.cpp b/rkward/windows/rcontrolwindow.cpp
index 2241ddc7..12926061 100644
--- a/rkward/windows/rcontrolwindow.cpp
+++ b/rkward/windows/rcontrolwindow.cpp
@@ -112,7 +112,7 @@ void RControlWindow::cancelButtonClicked () {
 		RCommand* command = coc->toCommand ();
 		if (command) {
 			if (!(command->type () & RCommand::Sync)) {
-				RKGlobals::rInterface ()->cancelCommand (command);
+				RInterface::instance()->cancelCommand(command);
 			} else {
 				some_not_cancelable = true;
 			}
@@ -128,11 +128,11 @@ void RControlWindow::pauseButtonClicked () {
 	RK_TRACE (APP);
 
 	if (paused) {
-		RKGlobals::rInterface ()->pauseProcessing (false);
+		RInterface::instance()->pauseProcessing(false);
 		pause_button->setText (i18n ("Pause execution"));
 		paused = false;
 	} else {
-		RKGlobals::rInterface ()->pauseProcessing (true);
+		RInterface::instance()->pauseProcessing(true);
 		pause_button->setText (i18n ("Resume execution"));
 		paused = true;
 	}
diff --git a/rkward/windows/rkcommandeditorwindow.cpp b/rkward/windows/rkcommandeditorwindow.cpp
index dec9eb41..49f2a33e 100644
--- a/rkward/windows/rkcommandeditorwindow.cpp
+++ b/rkward/windows/rkcommandeditorwindow.cpp
@@ -566,7 +566,7 @@ void RKCommandEditorWindow::discardPreview () {
 	if (preview_dir) {
 		preview->wrapperWidget ()->hide ();
 		preview_manager->setPreviewDisabled ();
-		RKGlobals::rInterface ()->issueCommand (QString (".rk.killPreviewDevice(%1)\nrk.discard.preview.data (%1)").arg (RObject::rQuote(preview_manager->previewId ())), RCommand::App | RCommand::Sync);
+		RInterface::issueCommand (QString (".rk.killPreviewDevice(%1)\nrk.discard.preview.data (%1)").arg (RObject::rQuote(preview_manager->previewId ())), RCommand::App | RCommand::Sync);
 		delete preview_dir;
 		preview_dir = 0;
 		delete preview_input_file;
@@ -864,7 +864,7 @@ void RKCommandEditorWindow::doRenderPreview () {
 
 	if (mode != GraphPreview && !preview->findChild<RKMDIWindow*>()) {
 		// (lazily) initialize the preview window with _something_, as an RKMDIWindow is needed to display messages (important, if there is an error during the first preview)
-		RKGlobals::rInterface()->issueCommand (".rk.with.window.hints (rk.show.html(" + RObject::rQuote (output_file) + "), \"\", " + RObject::rQuote (preview_manager->previewId ()) + ", style=\"preview\")", RCommand::App | RCommand::Sync);
+		RInterface::issueCommand (".rk.with.window.hints (rk.show.html(" + RObject::rQuote (output_file) + "), \"\", " + RObject::rQuote (preview_manager->previewId ()) + ", style=\"preview\")", RCommand::App | RCommand::Sync);
 	}
 
 	RK_ASSERT (preview_input_file->open (QIODevice::WriteOnly));
@@ -1250,7 +1250,7 @@ void RKCommandHighlighter::copyLinesToOutput (KTextEditor::View *view, Highlight
 	// highlight and submit
 	QString highlighted = commandToHTML (doc->text (sel), mode);
 	if (!highlighted.isEmpty ()) {
-		RKGlobals::rInterface ()->issueCommand (".rk.cat.output (" + RObject::rQuote (highlighted) + ")\n", RCommand::App | RCommand::Silent);
+		RInterface::issueCommand (".rk.cat.output (" + RObject::rQuote (highlighted) + ")\n", RCommand::App | RCommand::Silent);
 	}
 }
 
diff --git a/rkward/windows/rkfilebrowser.cpp b/rkward/windows/rkfilebrowser.cpp
index 18549e2a..19eb64de 100644
--- a/rkward/windows/rkfilebrowser.cpp
+++ b/rkward/windows/rkfilebrowser.cpp
@@ -132,7 +132,7 @@ RKFileBrowserWidget::RKFileBrowserWidget (QWidget *parent) : QWidget (parent) {
 	connect (urlbox, &KUrlComboBox::urlActivated, this, &RKFileBrowserWidget::urlChangedInCombo);
 
 	connect (dir, &KDirOperator::fileSelected, this, &RKFileBrowserWidget::fileActivated);
-	connect (RKGlobals::rInterface (), &RInterface::backendWorkdirChanged, this, &RKFileBrowserWidget::syncToWD);
+	connect (RInterface::instance(), &RInterface::backendWorkdirChanged, this, &RKFileBrowserWidget::syncToWD);
 
 	setURL (QUrl::fromLocalFile (QDir::currentPath ()));
 }
diff --git a/rkward/windows/rkhelpsearchwindow.cpp b/rkward/windows/rkhelpsearchwindow.cpp
index 861592fa..410ba229 100644
--- a/rkward/windows/rkhelpsearchwindow.cpp
+++ b/rkward/windows/rkhelpsearchwindow.cpp
@@ -158,7 +158,7 @@ void RKHelpSearchWindow::getFunctionHelp (const QString &function_name, const QS
 	command.append (")");
 	if (type == "vignette") command.append (")");
 
-	RKGlobals::rInterface ()->issueCommand (command, RCommand::App | RCommand::GetStringVector, i18n ("Find HTML help for %1", function_name), this, GET_HELP);
+	RInterface::issueCommand (command, RCommand::App | RCommand::GetStringVector, i18n ("Find HTML help for %1", function_name), this, GET_HELP);
 }
 
 void RKHelpSearchWindow::slotFindButtonClicked () {
@@ -191,7 +191,7 @@ void RKHelpSearchWindow::slotFindButtonClicked () {
 
 	QString s = ".rk.get.search.results (" + RObject::rQuote (field->currentText ()) + ", agrep=" + agrep + ", ignore.case=" + ignoreCase + package + ", fields=" + fields + ')';
 	
-	RKGlobals::rInterface ()->issueCommand (s, RCommand::App | RCommand::Sync | RCommand::GetStringVector, QString (), this, HELP_SEARCH, 0);
+	RInterface::issueCommand (s, RCommand::App | RCommand::Sync | RCommand::GetStringVector, QString (), this, HELP_SEARCH, 0);
 	setEnabled (false);
 	field->addItem (field->currentText ());
 }
diff --git a/rkward/windows/rkhtmlwindow.cpp b/rkward/windows/rkhtmlwindow.cpp
index 1474b660..89138975 100644
--- a/rkward/windows/rkhtmlwindow.cpp
+++ b/rkward/windows/rkhtmlwindow.cpp
@@ -857,7 +857,7 @@ void RKHTMLWindow::flushOutput () {
 		RKProgressControl *status = new RKProgressControl (this, i18n ("Flushing output"), i18n ("Flushing output"), RKProgressControl::CancellableNoProgress);
 		status->addRCommand (c, true);
 		status->doNonModal (true);
-		RKGlobals::rInterface ()->issueCommand (c);
+		RInterface::issueCommand (c);
 	}
 }
 
diff --git a/rkward/windows/rktoplevelwindowgui.cpp b/rkward/windows/rktoplevelwindowgui.cpp
index b1962227..e597796b 100644
--- a/rkward/windows/rktoplevelwindowgui.cpp
+++ b/rkward/windows/rktoplevelwindowgui.cpp
@@ -166,7 +166,7 @@ void RKTopLevelWindowGUI::configureToolbars () {
 void RKTopLevelWindowGUI::invokeRHelp () {
 	RK_TRACE (APP);
 
-	RKGlobals::rInterface ()->issueCommand ("help.start ()", RCommand::App);
+	RInterface::issueCommand ("help.start ()", RCommand::App);
 	RKWardMainWindow::getMain ()->topLevelWidget ()->raise ();
 }
 
diff --git a/rkward/windows/rkwindowcatcher.cpp b/rkward/windows/rkwindowcatcher.cpp
index ad89b917..41eb6b50 100644
--- a/rkward/windows/rkwindowcatcher.cpp
+++ b/rkward/windows/rkwindowcatcher.cpp
@@ -371,7 +371,7 @@ void RKCaughtX11Window::commonClose(bool in_destructor) {
 	if (!(close_attempted || killed_in_r)) {
 		RCommand* c = new RCommand("dev.off (" + QString::number(device_number) + ')', RCommand::App, i18n("Shutting down device number %1", device_number));
 		if (!in_destructor) setStatusMessage(status, c);
-		RKGlobals::rInterface()->issueCommand(c);
+		RInterface::issueCommand(c);
 		close_attempted = true;
 	} else {
 		if (in_destructor) return;
@@ -408,7 +408,7 @@ void RKCaughtX11Window::forceClose() {
 bool RKCaughtX11Window::close(CloseWindowMode ask_save) {
 	RK_TRACE(MISC);
 
-	if (killed_in_r || RKGlobals::rInterface()->backendIsDead()) {
+	if (killed_in_r || RInterface::instance()->backendIsDead()) {
 		return RKMDIWindow::close(ask_save);
 	}
 
@@ -475,7 +475,7 @@ void RKCaughtX11Window::fixedSizeToggled () {
 
 	if (embedded && !embedding_complete) {
 		embedding_complete = true;
-		RKGlobals::rInterface ()->issueCommand ("assign ('devembedded', TRUE, rkward:::.rk.variables)", RCommand::App | RCommand::Sync | RCommand::PriorityCommand);
+		RInterface::issueCommand ("assign ('devembedded', TRUE, rkward:::.rk.variables)", RCommand::App | RCommand::Sync | RCommand::PriorityCommand);
 	}
 }
 
@@ -552,13 +552,13 @@ void RKCaughtX11Window::setFixedSizeManual () {
 void RKCaughtX11Window::activateDevice () {
 	RK_TRACE (MISC);
 
-	RKGlobals::rInterface ()->issueCommand ("dev.set (" + QString::number (device_number) + ')', RCommand::App, i18n ("Activate graphics device number %1", device_number), error_dialog);
+	RInterface::issueCommand ("dev.set (" + QString::number (device_number) + ')', RCommand::App, i18n ("Activate graphics device number %1", device_number), error_dialog);
 }
 
 void RKCaughtX11Window::copyDeviceToOutput () {
 	RK_TRACE (MISC);
 
-	RKGlobals::rInterface ()->issueCommand ("dev.set (" + QString::number (device_number) + ")\ndev.copy (device=rk.graph.on)\nrk.graph.off ()", RCommand::App | RCommand::CCOutput, i18n ("Copy contents of graphics device number %1 to output", device_number), error_dialog);
+	RInterface::issueCommand ("dev.set (" + QString::number (device_number) + ")\ndev.copy (device=rk.graph.on)\nrk.graph.off ()", RCommand::App | RCommand::CCOutput, i18n ("Copy contents of graphics device number %1 to output", device_number), error_dialog);
 }
 
 void RKCaughtX11Window::printDevice () {
@@ -566,7 +566,7 @@ void RKCaughtX11Window::printDevice () {
 
 	QString printer_device;
 	if (RKSettingsModuleGraphics::kdePrintingEnabled ()) printer_device = "rk.printer.device";
-	RKGlobals::rInterface ()->issueCommand ("dev.set (" + QString::number (device_number) + ")\ndev.print (" + printer_device + ')', RCommand::App, i18n ("Print contents of graphics device number %1", device_number), error_dialog);
+	RInterface::issueCommand ("dev.set (" + QString::number (device_number) + ")\ndev.print (" + printer_device + ')', RCommand::App, i18n ("Print contents of graphics device number %1", device_number), error_dialog);
 }
 
 void RKCaughtX11Window::copyDeviceToRObject () {
@@ -598,7 +598,7 @@ void RKCaughtX11Window::copyDeviceToRObject () {
 
 		QString name = chooser->currentFullName ();
 
-		RKGlobals::rInterface ()->issueCommand ("dev.set (" + QString::number (device_number) + ")\n" + name + " <- recordPlot ()", RCommand::App | RCommand::ObjectListUpdate, i18n ("Save contents of graphics device number %1 to object '%2'", device_number, name), error_dialog);
+		RInterface::issueCommand ("dev.set (" + QString::number (device_number) + ")\n" + name + " <- recordPlot ()", RCommand::App | RCommand::ObjectListUpdate, i18n ("Save contents of graphics device number %1 to object '%2'", device_number, name), error_dialog);
 	}
 
 	delete dialog;
@@ -607,7 +607,7 @@ void RKCaughtX11Window::copyDeviceToRObject () {
 void RKCaughtX11Window::duplicateDevice () {
 	RK_TRACE (MISC);
 
-	RKGlobals::rInterface ()->issueCommand ("rk.duplicate.device (" + QString::number (device_number) + ')', RCommand::App, i18n ("Duplicate graphics device number %1", device_number), error_dialog);
+	RInterface::issueCommand ("rk.duplicate.device (" + QString::number (device_number) + ')', RCommand::App, i18n ("Duplicate graphics device number %1", device_number), error_dialog);
 }
 
 void RKCaughtX11Window::nextPlot () {
@@ -615,7 +615,7 @@ void RKCaughtX11Window::nextPlot () {
 
 	RCommand* c = new RCommand ("rk.next.plot (" + QString::number (device_number) + ')', RCommand::App, i18n ("Load next plot in device number %1", device_number), error_dialog);
 	setStatusMessage (i18n ("Loading plot from history"), c);
-	RKGlobals::rInterface ()->issueCommand (c);
+	RInterface::issueCommand (c);
 }
 
 void RKCaughtX11Window::previousPlot () {
@@ -623,7 +623,7 @@ void RKCaughtX11Window::previousPlot () {
 
 	RCommand* c = new RCommand ("rk.previous.plot (" + QString::number (device_number) + ')', RCommand::App, i18n ("Load previous plot in device number %1", device_number), error_dialog);
 	setStatusMessage (i18n ("Loading plot from history"), c);
-	RKGlobals::rInterface ()->issueCommand (c);
+	RInterface::issueCommand (c);
 }
 
 void RKCaughtX11Window::firstPlot () {
@@ -631,7 +631,7 @@ void RKCaughtX11Window::firstPlot () {
 
 	RCommand* c = new RCommand ("rk.first.plot (" + QString::number (device_number) + ')', RCommand::App, i18n ("Load first plot in device number %1", device_number), error_dialog);
 	setStatusMessage (i18n ("Loading plot from history"), c);
-	RKGlobals::rInterface ()->issueCommand (c);
+	RInterface::issueCommand (c);
 }
 
 void RKCaughtX11Window::lastPlot () {
@@ -639,7 +639,7 @@ void RKCaughtX11Window::lastPlot () {
 
 	RCommand* c = new RCommand ("rk.last.plot (" + QString::number (device_number) + ')', RCommand::App, i18n ("Load last plot in device number %1", device_number), error_dialog);
 	setStatusMessage (i18n ("Loading plot from history"), c);
-	RKGlobals::rInterface ()->issueCommand (c);
+	RInterface::issueCommand (c);
 }
 
 void RKCaughtX11Window::gotoPlot (int index) {
@@ -647,19 +647,19 @@ void RKCaughtX11Window::gotoPlot (int index) {
 
 	RCommand* c = new RCommand ("rk.goto.plot (" + QString::number (device_number) + ", " + QString::number (index+1) + ')', RCommand::App, i18n ("Load plot %1 in device number %2", index, device_number), error_dialog);
 	setStatusMessage (i18n ("Loading plot from history"), c);
-	RKGlobals::rInterface ()->issueCommand (c);
+	RInterface::issueCommand (c);
 }
 
 void RKCaughtX11Window::forceAppendCurrentPlot () {
 	RK_TRACE (MISC);
 
-	RKGlobals::rInterface ()->issueCommand ("rk.force.append.plot (" + QString::number (device_number) + ')', RCommand::App, i18n ("Append this plot to history (device number %1)", device_number), error_dialog);
+	RInterface::issueCommand ("rk.force.append.plot (" + QString::number (device_number) + ')', RCommand::App, i18n ("Append this plot to history (device number %1)", device_number), error_dialog);
 }
 
 void RKCaughtX11Window::removeCurrentPlot () {
 	RK_TRACE (MISC);
 
-	RKGlobals::rInterface ()->issueCommand ("rk.removethis.plot (" + QString::number (device_number) + ')', RCommand::App, i18n ("Remove current plot from history (device number %1)", device_number), error_dialog);
+	RInterface::issueCommand ("rk.removethis.plot (" + QString::number (device_number) + ')', RCommand::App, i18n ("Remove current plot from history (device number %1)", device_number), error_dialog);
 }
 
 void RKCaughtX11Window::clearHistory () {
@@ -667,13 +667,13 @@ void RKCaughtX11Window::clearHistory () {
 
 	if (KMessageBox::warningContinueCancel (this, i18n ("This will clear the plot history for all device windows, not just this one. If this is not your intent, press cancel, below.")) != KMessageBox::Continue) return;
 
-	RKGlobals::rInterface ()->issueCommand ("rk.clear.plot.history ()", RCommand::App, i18n ("Clear plot history"), error_dialog);
+	RInterface::issueCommand ("rk.clear.plot.history ()", RCommand::App, i18n ("Clear plot history"), error_dialog);
 }
 
 void RKCaughtX11Window::showPlotInfo () {
 	RK_TRACE (MISC);
 
-	RKGlobals::rInterface ()->issueCommand ("rk.show.plot.info (" + QString::number (device_number) + ')', RCommand::App, i18n ("Plot properties (device number %1)", device_number), error_dialog);
+	RInterface::issueCommand ("rk.show.plot.info (" + QString::number (device_number) + ')', RCommand::App, i18n ("Plot properties (device number %1)", device_number), error_dialog);
 }
 
 void RKCaughtX11Window::updateHistoryActions (int history_length, int position, const QStringList &labels) {
diff --git a/rkward/windows/rkworkplace.cpp b/rkward/windows/rkworkplace.cpp
index 734fc647..bcb98558 100644
--- a/rkward/windows/rkworkplace.cpp
+++ b/rkward/windows/rkworkplace.cpp
@@ -967,7 +967,7 @@ void RKWorkplace::saveWorkplace(const QUrl& for_url, RCommandChain *chain) {
 
 	QString file_param;
 	if (!for_url.isEmpty()) file_param = QString("file=") + RObject::rQuote(for_url.toLocalFile() + QStringLiteral(".rkworkplace")) + QStringLiteral(", ");
-	RKGlobals::rInterface()->issueCommand("rk.save.workplace(" + file_param + "description=" + RObject::rQuote (makeWorkplaceDescription().join ("\n")) + ')', RCommand::App, i18n ("Save Workplace layout"), 0, 0, chain);
+	RInterface::issueCommand("rk.save.workplace(" + file_param + "description=" + RObject::rQuote (makeWorkplaceDescription().join ("\n")) + ')', RCommand::App, i18n ("Save Workplace layout"), 0, 0, chain);
 }
 
 void RKWorkplace::restoreWorkplace (RCommandChain *chain, bool merge) {
@@ -976,7 +976,7 @@ void RKWorkplace::restoreWorkplace (RCommandChain *chain, bool merge) {
 
 	QString no_close_windows;
 	if (merge) no_close_windows = "close.windows = FALSE";
-	RKGlobals::rInterface ()->issueCommand ("rk.restore.workplace(" + no_close_windows + ')', RCommand::App, i18n ("Restore Workplace layout"), 0, 0, chain);
+	RInterface::issueCommand ("rk.restore.workplace(" + no_close_windows + ')', RCommand::App, i18n ("Restore Workplace layout"), 0, 0, chain);
 }
 
 void RKWorkplace::restoreWorkplace (const QStringList &description) {
diff --git a/rkward/windows/robjectbrowser.cpp b/rkward/windows/robjectbrowser.cpp
index 1f1632fb..7b640126 100644
--- a/rkward/windows/robjectbrowser.cpp
+++ b/rkward/windows/robjectbrowser.cpp
@@ -183,7 +183,7 @@ void RObjectBrowserInternal::popupCopy () {
 	if (ok) {
 		QString valid = RObjectList::getGlobalEnv ()->validizeName (name);
 		if (valid != name) KMessageBox::sorry (this, i18n ("The name you specified was already in use or not valid. Renamed to %1", valid), i18n ("Invalid Name"));
-		RKGlobals::rInterface ()->issueCommand (RObject::rQuote (valid) + " <- " + object->getFullName (), RCommand::App | RCommand::ObjectListUpdate);
+		RInterface::issueCommand (RObject::rQuote (valid) + " <- " + object->getFullName (), RCommand::App | RCommand::ObjectListUpdate);
 	}
 }
 
@@ -195,7 +195,7 @@ void RObjectBrowserInternal::popupCopyToGlobalEnv () {
 
 	QString valid = RObjectList::getGlobalEnv ()->validizeName (name);
 	if (valid != name) KMessageBox::sorry (this, i18n ("An object named '%1' already exists in the GlobalEnv. Created the copy as '%2' instead.", name, valid), i18n ("Name already in use"));
-	RKGlobals::rInterface ()->issueCommand (RObject::rQuote (valid) + " <- " + object->getFullName (), RCommand::App | RCommand::ObjectListUpdate);
+	RInterface::issueCommand (RObject::rQuote (valid) + " <- " + object->getFullName (), RCommand::App | RCommand::ObjectListUpdate);
 }
 
 void RObjectBrowserInternal::popupView () {



More information about the rkward-tracker mailing list