Git commit e6610f3390046207a18f33898ed57c8a94227ecf by Thomas Friedrichsmeier.
Committed on 15/05/2017 at 20:09.
Pushed by tfry into branch 'frameworks'.

EXPERIMENTAL: Remove the startup wrapper script, moving funcationality to the 
main executable, as needed.

Should address a number of quirks (esp. on Windows and Mac), hopefully without 
adding  worse bugs in their place.

M  +4    -0    ChangeLog
M  +0    -9    doc/rkward/man-rkward.1.docbook
M  +14   -24   rkward/CMakeLists.txt
M  +136  -26   rkward/main.cpp
M  +18   -0    rkward/misc/rkcommonfunctions.cpp
M  +2    -0    rkward/misc/rkcommonfunctions.h
M  +1    -1    rkward/org.kde.rkward.desktop
M  +0    -5    rkward/rbackend/rinterface.cpp
M  +13   -10   rkward/rbackend/rkfrontendtransmitter.cpp
M  +5    -7    rkward/rbackend/rkrbackendprotocol_backend.cpp
D  +0    -332  rkward/rkward_startup_wrapper.cpp

https://commits.kde.org/rkward/e6610f3390046207a18f33898ed57c8a94227ecf

diff --git a/ChangeLog b/ChangeLog
index 5276786f..fc4ff8b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+- Remove startup wrapper script (moving the still-needed functionality into 
the main executable)
+    TODO: This is still mostly EXPERIMENTAL, and only vaguely tested on Linux 
so far. It should help resolve a number of long standing quirks, though, such 
as command windows (on Windows), icons,
+          startup notification quirks, etc.
+    TODO: Clean up the Mac portions in CMakeLists.txt
 - Function argument hinting is less easily fooled by braces inside quotes
 - Preview status messages can now be closed
 - Show the message accompanying rk.show.files() or rk.edit.files() inside the 
main window, instead of a separate dialog
diff --git a/doc/rkward/man-rkward.1.docbook b/doc/rkward/man-rkward.1.docbook
index da46dfa9..03471efc 100644
--- a/doc/rkward/man-rkward.1.docbook
+++ b/doc/rkward/man-rkward.1.docbook
@@ -36,7 +36,6 @@
 <group choice="opt"><option>--evaluate</option> <replaceable> 
Rcode</replaceable></group>
 <group choice="opt"><option>--debug-level</option> <replaceable> 
level</replaceable></group>
 <group choice="opt"><option>--debug-flags</option> <replaceable> 
flags</replaceable></group>
-<arg><option>--debugger</option> 
<replaceable>debugger_command</replaceable><arg choice="opt">debugger_args<arg 
choice="opt"><option>--</option></arg></arg></arg>
 <group choice="opt"><option>--backend-debugger</option> <replaceable> 
debugger_command</replaceable></group>
 <group choice="opt"><option>--r-executable</option> <replaceable> 
path_to_executable</replaceable></group>
 <group choice="opt"><option>--reuse</option></group>
@@ -70,12 +69,6 @@
 <listitem><para>Allows to configure, which sections of code to debug. Flags 
are given as a binary number. Refer to the source files for documentation, as 
this really is an internal option.</para></listitem>
 </varlistentry>
 <varlistentry>
-<term><option>--debugger</option> <replaceable>command</replaceable> 
[<replaceable>arguments</replaceable> [<replaceable>--</replaceable>]]</term>
-<listitem><para>Run &rkward; through the specified debugger command. All 
arguments following this will be passed to the debugger command. To end 
debugger arguments (and add arguments to pass to &rkward;), use "--". 
<emphasis>NOTE:</emphasis> Only the frontend process will be debugged, using 
this option.</para>
-<para>Note that there are a number of pitfalls that may complicate setting up 
the debugger session as desired. Consider starting &rkward; with option 
\-\-debug-lebel 3, which will print the effective command line used to start 
the frontend (but not all relevant environment variables). As one hint, you 
will generally need to pass a separator argument with the debugger arguments, 
e.g. <command>rkward --debugger gdb --args</command>.
-Under Windows, the debugger command will <emphasis>not</emphasis> be connected 
to stdin. For interactive debugging, consider using a graphical 
debugger.</para></listitem>
-</varlistentry>
-<varlistentry>
 <term><option>--backend-debugger</option> 
<replaceable>command</replaceable></term>
 <listitem><para>Run the &rkward; backend through the specified debugger 
command. To add command line options to the debugger command, enclose them in 
single quotes ('') together with the command. <emphasis>NOTE:</emphasis> 
Debugger arguments will be split by spaces. If this is not appropriate, you 
will have to write your own wrapper script for invoking the debugger. Also, 
make sure to redirect all debugger output and/or input as appropriate. See the 
examples.</para></listitem>
 </varlistentry>
@@ -115,8 +108,6 @@ rkward --reuse file_a.R file_b.R
 
 # Run the rkward backend through valgrind
 rkward --backend-debugger 'valgrind --log-file=valgrind.log'.
-# Debug the frontend through gdb
-rkward --debugger 'gdb --args'
 </programlisting></para>
 </refsect1>
 
diff --git a/rkward/CMakeLists.txt b/rkward/CMakeLists.txt
index 1d7b4d1a..037d0ba9 100755
--- a/rkward/CMakeLists.txt
+++ b/rkward/CMakeLists.txt
@@ -40,8 +40,18 @@ SET(RKWard_Sources
 GET_DIRECTORY_PROPERTY(R_SHAREDLIBDIR DIRECTORY rbackend LINK_DIRECTORIES)
 LINK_DIRECTORIES(${R_SHAREDLIBDIR})
 
-add_executable(rkward.frontend ${RKWard_Sources})
-SET_TARGET_PROPERTIES(rkward.frontend PROPERTIES
+GET_DIRECTORY_PROPERTY(R_EXECUTABLE DIRECTORY rbackend DEFINITION R_EXECUTABLE)
+ADD_CUSTOM_COMMAND (OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/rkward.ico"
+                       COMMAND cmake -E copy 
"${CMAKE_CURRENT_SOURCE_DIR}/icons/app-icon/rkward.ico"
+                       "${CMAKE_CURRENT_BINARY_DIR}/rkward.ico")
+
+add_executable(rkward ${RKWard_Sources} rkward_windows_icon.rc rkward.ico)
+# NOTE: These definitions are needed for the wrapper, only.
+# We should switch with to target_compile_definitions once we require CMAKE 
2.6+
+add_definitions (-DR_EXECUTABLE="${R_EXECUTABLE}")
+add_definitions (-DINSTALL_PATH="${CMAKE_INSTALL_PREFIX}")
+add_definitions (-DR_LIBS="${R_LIBDIR}")
+SET_TARGET_PROPERTIES(rkward PROPERTIES
         MACOSX_BUNDLE_BUNDLE_NAME "RKWard")
 
 IF(Q_WS_MAC)
@@ -53,31 +63,12 @@ IF(Q_WS_MAC)
                @ONLY)
 ENDIF(Q_WS_MAC)
 
-TARGET_LINK_LIBRARIES(rkward.frontend windows ${RKWARD_ADDLIBS} agents dialogs 
plugin settings dataeditor core scriptbackends rbackend misc KF5::WindowSystem 
Qt5::Widgets KF5::XmlGui ${LibIntl_LIBRARIES})
+TARGET_LINK_LIBRARIES(rkward windows ${RKWARD_ADDLIBS} agents dialogs plugin 
settings dataeditor core scriptbackends rbackend misc KF5::WindowSystem 
Qt5::Widgets KF5::XmlGui ${LibIntl_LIBRARIES})
 IF(KF5Crash_FOUND)
-       TARGET_LINK_LIBRARIES(rkward.frontend KF5::Crash)
+       TARGET_LINK_LIBRARIES(rkward KF5::Crash)
        SET_SOURCE_FILES_PROPERTIES(main.cpp PROPERTIES COMPILE_DEFINITIONS 
WITH_KCRASH=1)
 ENDIF(KF5Crash_FOUND)
 
-# wrapper executable
-GET_DIRECTORY_PROPERTY(R_EXECUTABLE DIRECTORY rbackend DEFINITION R_EXECUTABLE)
-IF (WIN32)
-       SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
-ENDIF (WIN32)
-ADD_CUSTOM_COMMAND (OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/rkward.ico"
-                       COMMAND cmake -E copy 
"${CMAKE_CURRENT_SOURCE_DIR}/icons/app-icon/rkward.ico"
-                       "${CMAKE_CURRENT_BINARY_DIR}/rkward.ico")
-ADD_EXECUTABLE (rkward rkward_startup_wrapper.cpp rkward_windows_icon.rc 
rkward.ico)
-# NOTE: These definitions are needed for the wrapper, only.
-# We should switch with to target_compile_definitions once we require CMAKE 
2.6+
-add_definitions (-DR_EXECUTABLE="${R_EXECUTABLE}")
-add_definitions (-DINSTALL_PATH="${CMAKE_INSTALL_PREFIX}")
-add_definitions (-DR_LIBS="${R_LIBDIR}")
-add_definitions 
(-DRKWARD_FRONTEND_LOCATION="${CMAKE_INSTALL_PREFIX}/${RKWARD_FRONTEND_LOCATION}")
-TARGET_LINK_LIBRARIES(rkward Qt5::Gui Qt5::Core Qt5::DBus Qt5::Widgets)
-
-ADD_DEPENDENCIES(rkward.frontend rkward)
-
 ########### install files ###############
 
 INSTALL(DIRECTORY plugins/ pages DESTINATION ${DATA_INSTALL_DIR}/rkward
@@ -92,7 +83,6 @@ IF(Q_WS_MAC)
        INSTALL(FILES ${CMAKE_SOURCE_DIR}/rkward/icons/app-icon/rkward.icns 
DESTINATION ${BUNDLE_INSTALL_DIR}/${CPACK_BUNDLE_NAME}.app/Contents/Resources)
        INSTALL(FILES ${RKWARD_INFOPLIST_FILE} DESTINATION 
${BUNDLE_INSTALL_DIR}/${CPACK_BUNDLE_NAME}.app/Contents)
 ELSE(Q_WS_MAC)
-       INSTALL(TARGETS rkward.frontend DESTINATION ${LIBEXEC_INSTALL_DIR})
        INSTALL(TARGETS rkward DESTINATION ${BIN_INSTALL_DIR})
 ENDIF(Q_WS_MAC)
 
diff --git a/rkward/main.cpp b/rkward/main.cpp
index 782a9e85..487d8c08 100644
--- a/rkward/main.cpp
+++ b/rkward/main.cpp
@@ -66,6 +66,9 @@
 #include <QApplication>
 #include <QUrl>
 #include <QCommandLineParser>
+#include <QtDBus>
+#include <QSettings>
+#include <QMessageBox>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -74,6 +77,8 @@
 #include "rkglobals.h"
 #include "settings/rksettingsmoduledebug.h"
 #include "windows/rkdebugmessagewindow.h"
+#include "misc/rkdbusapi.h"
+#include "misc/rkcommonfunctions.h"
 
 #ifdef Q_OS_WIN
        // these are needed for the exit hack.
@@ -84,6 +89,28 @@
 
 #include "version.h"
 
+#ifndef R_EXECUTABLE
+#      define R_EXECUTABLE ""
+#endif
+
+#ifdef Q_OS_WIN
+#      define PATH_VAR_SEP ';'
+#else
+#      define PATH_VAR_SEP ':'
+#endif
+
+QString findExeAtPath (const QString appname, const QString &path) {
+       QDir dir (path);
+       dir.makeAbsolute ();
+       if (QFileInfo (dir.filePath (appname)).isExecutable ()) return 
dir.filePath (appname);
+#ifdef Q_OS_WIN
+       if (QFileInfo (dir.filePath (appname + ".exe")).isExecutable ()) return 
dir.filePath (appname + ".exe");
+       if (QFileInfo (dir.filePath (appname + ".com")).isExecutable ()) return 
dir.filePath (appname + ".com");
+       if (QFileInfo (dir.filePath (appname + ".bat")).isExecutable ()) return 
dir.filePath (appname + ".bat");
+#endif
+       return QString ();
+}
+
 int RK_Debug_Level = 0;
 int RK_Debug_Flags = DEBUG_ALL;
 int RK_Debug_CommandStep = 0;
@@ -119,21 +146,12 @@ void RKDebug (int flags, int level, const char *fmt, ...) 
{
        }
 }
 
-QString decodeArgument (const QString &input) {
-       return (QUrl::fromPercentEncoding (input.toUtf8()));
-}
-
 int main (int argc, char *argv[]) {
-       // before initializing the commandline args, remove the ".bin" from 
"rkward.bin".
-       // This is so it prints "Usage rkward..." instead of "Usage 
rkward.bin...", etc.
-       // it seems safest to keep a copy, since the shell still owns argv
-       char **argv_copy = new char*[argc];
-       argv_copy[0] = qstrdup (QString (argv[0]).remove (".frontend").replace 
(".exe", ".bat").toLocal8Bit ());
-       for (int i = 1; i < argc; ++i) {
-               argv_copy[i] = argv[i];
-       }
+       // TODO: This is a _temporary_ hack! --> Problems with output not 
updating on Windows Live Image. See 
https://mail.kde.org/pipermail/rkward-devel/2016-September/004660.html .
+#warning Remove me!
+       qputenv ("KDIRWATCH_METHOD", QByteArray ("Stat"));
 
-       QApplication app (argc, argv_copy);
+       QApplication app (argc, argv);
 #ifdef WITH_KCRASH
        KCrash::setDrKonqiEnabled (true);
 #endif
@@ -174,7 +192,6 @@ int main (int argc, char *argv[]) {
        parser.addOption (QCommandLineOption ("evaluate", i18n ("After starting 
(and after loading the specified workspace, if applicable), evaluate the given 
R code."), "Rcode", QString ()));
        parser.addOption (QCommandLineOption ("debug-level", i18n ("Verbosity 
of debug messages (0-5)"), "level", "2"));
        parser.addOption (QCommandLineOption ("debug-flags", i18n ("Mask for 
components to debug (see debug.h)"), "flags", QString::number (DEBUG_ALL)));
-       parser.addOption (QCommandLineOption ("debugger", i18n ("Debugger for 
the frontend. Specify last, or add '--' after all debugger arguments"), 
"command and arguments", QString ()));
        parser.addOption (QCommandLineOption ("backend-debugger", i18n 
("Debugger for the backend. (Enclose any debugger arguments in single quotes 
('') together with the command. Make sure to re-direct stdout!)"), "command", 
QString ()));
        parser.addOption (QCommandLineOption ("r-executable", i18n ("Use 
specified R installation, instead of the one configured at compile time (note: 
rkward R library must be installed to that installation of R)"), "command", 
QString ()));
        parser.addOption (QCommandLineOption ("reuse", i18n ("Reuse a running 
RKWard instance (if available). If a running instance is reused, only the file 
arguments will be interpreted, all other options will be ignored.")));
@@ -185,30 +202,124 @@ int main (int argc, char *argv[]) {
        parser.process (app);
        aboutData.processCommandLine (&parser);
 
+       // Set up debugging
        RK_Debug_Level = DL_FATAL - QString (parser.value 
("debug-level")).toInt ();
        RK_Debug_Flags = QString (parser.value ("debug-flags")).toInt ();
-       if (!parser.value ("debugger").isEmpty ()) {
-               RK_DEBUG (DEBUG_ALL, DL_ERROR, "--debugger option should have 
been handled by wrapper script. Ignoring.");
+       RKSettingsModuleDebug::debug_file = new QTemporaryFile (QDir::tempPath 
() + "/rkward.frontend");
+       RKSettingsModuleDebug::debug_file->setAutoRemove (false);
+       if (RKSettingsModuleDebug::debug_file->open ()) {
+               RK_DEBUG (APP, DL_INFO, "Full debug output is at %s", 
qPrintable (RKSettingsModuleDebug::debug_file->fileName ()));
+               qInstallMessageHandler (RKDebugMessageOutput);
        }
 
+       // handle positional (file) arguments, first
        QStringList url_args = parser.positionalArguments ();
        if (!url_args.isEmpty ()) {
                for (int i = 0; i < url_args.size (); ++i) {
-                       url_args[i] = decodeArgument (url_args[i]);
+                       url_args[i] = QUrl::fromUserInput (url_args[i], 
QDir::currentPath (), QUrl::AssumeLocalFile).toString ();
                }
                RKGlobals::startup_options["initial_urls"] = url_args;
                RKGlobals::startup_options["warn_external"] = !parser.isSet 
("nowarn-external");
        }
-       RKGlobals::startup_options["evaluate"] = decodeArgument (parser.value 
("evaluate"));
-       RKGlobals::startup_options["backend-debugger"] = decodeArgument 
(parser.value ("backend-debugger"));
+       RKGlobals::startup_options["evaluate"] = parser.value ("evaluate");
+       RKGlobals::startup_options["backend-debugger"] = parser.value 
("backend-debugger");
 
-       // install message handler *after* the componentData has been 
initialized
-       RKSettingsModuleDebug::debug_file = new QTemporaryFile (QDir::tempPath 
() + "/rkward.frontend");
-       RKSettingsModuleDebug::debug_file->setAutoRemove (false);
-       if (RKSettingsModuleDebug::debug_file->open ()) {
-               RK_DEBUG (APP, DL_INFO, "Full debug output is at %s", 
qPrintable (RKSettingsModuleDebug::debug_file->fileName ()));
-               qInstallMessageHandler (RKDebugMessageOutput);
+       // Handle --reuse option, by placing a dbus-call to existing RKWard 
process (if any) and exiting
+       if (parser.isSet ("reuse")) {
+               if (!QDBusConnection::sessionBus ().isConnected ()) {
+                       RK_DEBUG (DEBUG_ALL, DL_WARNING, "Could not connect to 
session dbus");
+               } else {
+                       QDBusInterface iface (RKDBUS_SERVICENAME, "/", "", 
QDBusConnection::sessionBus ());
+                       if (iface.isValid ()) {
+                               QDBusReply<void> reply = iface.call 
("openAnyUrl", url_args, !parser.isSet ("nowarn-external"));
+                               if (!reply.isValid ()) {
+                                       RK_DEBUG (DEBUG_ALL, DL_ERROR, "Error 
while placing dbus call: %s", qPrintable (reply.error ().message ()));
+                                       return 1;
+                               }
+                               return 0;
+                       }
+               }
+       }
+
+// MacOS may need some path adjustments, first
+#ifdef Q_OS_MAC
+       QString oldpath = qgetenv ("PATH");
+       if (!oldpath.contains (INSTALL_PATH)) {
+               //ensure that PATH is set to include what we deliver with the 
bundle
+               qputenv ("PATH", QString ("%1/bin:%1/sbin:%2").arg 
(INSTALL_PATH).arg (oldpath).toLocal8Bit ());
+               if (debug_level > 3) qDebug ("Adjusting system path to %s", 
qPrintable (qgetenv ("PATH")));
+       }
+       // ensure that RKWard finds its own packages
+       qputenv ("R_LIBS", R_LIBS);
+       QProcess::execute ("launchctl", QStringList () << "load" << "-w" << 
INSTALL_PATH "/Library/LaunchAgents/org.freedesktop.dbus-session.plist");
+#endif
+
+       // Locate KDE and RKWard installations
+       QString marker_exe_name ("qtpaths");    // Simply some file that should 
exist in the bin dir of a KDE installation on both Unix and Windows
+       QString marker_exe = findExeAtPath (marker_exe_name, QDir::currentPath 
());
+       if (marker_exe.isNull ()) marker_exe = findExeAtPath (marker_exe_name, 
app.applicationDirPath ());
+       if (marker_exe.isNull ()) marker_exe = findExeAtPath (marker_exe_name, 
QDir (app.applicationDirPath ()).filePath ("KDE/bin"));
+       QStringList syspath = QString (qgetenv ("PATH")).split (PATH_VAR_SEP);
+       if (marker_exe.isNull ()) {
+               for (int i = 0; i < syspath.size (); ++i) {
+                       marker_exe = findExeAtPath (marker_exe_name, 
syspath[i]);
+                       if (!marker_exe.isNull ()) break;
+               }
+       }
+
+       if (marker_exe.isNull ()) {
+               QMessageBox::critical (0, "Could not find KDE installation", 
"The KDE installation could not be found (" + marker_exe_name + "). When moving 
/ copying RKWard, make sure to copy the whole application folder, or create a 
shorcut / link, instead.");
+               exit (1);
+       }
+
+       QDir kde_dir (QFileInfo (marker_exe).absolutePath ());
+       kde_dir.makeAbsolute ();
+       QString kde_dir_safe_path = 
RKCommonFunctions::windowsShellScriptSafeCommand (kde_dir.path ());
+       if (syspath.indexOf (kde_dir.path ()) < 0) {
+               RK_DEBUG (DEBUG_ALL, DL_INFO, "Adding %s to the system path", 
qPrintable (kde_dir_safe_path));
+               qputenv ("PATH", QString (kde_dir_safe_path + PATH_VAR_SEP + 
qgetenv ("PATH")).toLocal8Bit ());
+       }
+
+       // Look for R:
+       //- command line parameter
+       //- Specified in cfg file next to rkward executable
+       //- compile-time default
+       QString r_exe = parser.value ("r-executable");
+       if (!r_exe.isNull ()) {
+               if (!QFileInfo (r_exe).isExecutable ()) {
+                       QMessageBox::critical (0, "Specified R executable does 
not exist", QString ("The R executable specified on the command line (%1) does 
not exist or is not executable.").arg (r_exe));
+                       exit (1);
+               }
+               RK_DEBUG (APP, DL_DEBUG, "Using R specified on command line");
+       } else {
+               QDir frontend_path = app.applicationDirPath ();
+               QFileInfo rkward_ini_file (frontend_path.absoluteFilePath 
("rkward.ini"));
+               if (rkward_ini_file.isReadable ()) {
+                       QSettings rkward_ini (rkward_ini_file.absoluteFilePath 
(), QSettings::IniFormat);
+                       r_exe = rkward_ini.value ("R executable").toString ();
+                       if (!r_exe.isNull ()) {
+                               if (QDir::isRelativePath (r_exe)) {
+                                       r_exe = frontend_path.absoluteFilePath 
(r_exe);
+                               }
+                               if (!QFileInfo (r_exe).isExecutable ()) {
+                                       QMessageBox::critical (0, "Specified R 
executable does not exist", QString ("The R executable specified in the 
rkward.ini file (%1) does not exist or is not executable.").arg 
(rkward_ini_file.absoluteFilePath ()));
+                                       exit (1);
+                               }
+                       }
+                       RK_DEBUG (APP, DL_DEBUG, "Using R as configured in 
config file %s", qPrintable (rkward_ini_file.absoluteFilePath ()));
+               }
+               if (r_exe.isNull ()) {
+                       r_exe = R_EXECUTABLE;
+                       if (!QFileInfo (r_exe).isExecutable ()) {
+                               QMessageBox::critical (0, "Specified R 
executable does not exist", QString ("The R executable specified at compile 
time (%1) does not exist or is not executable. Probably the installation of R 
has moved. You can use the command line parameter '--r-executable 
<i>PATH_TO_R</i>', or supply an rkward.ini file to specify the new 
location.").arg (r_exe));
+                               exit (1);
+                       }
+                       RK_DEBUG (APP, DL_DEBUG, "Using R as configured at 
compile time");
+               }
        }
+       // TODO: Store somewhere else
+       qputenv ("R_BINARY", r_exe.toLocal8Bit ());
+
 
        if (app.isSessionRestored ()) {
                RESTORE(RKWardMainWindow);      // well, whatever this is 
supposed to do -> TODO
@@ -227,7 +338,6 @@ int main (int argc, char *argv[]) {
 
        qInstallMessageHandler (0);
        RKSettingsModuleDebug::debug_file->close ();
-       delete argv_copy;
 
        return status;
 }
diff --git a/rkward/misc/rkcommonfunctions.cpp 
b/rkward/misc/rkcommonfunctions.cpp
index 77e296f1..431014f7 100644
--- a/rkward/misc/rkcommonfunctions.cpp
+++ b/rkward/misc/rkcommonfunctions.cpp
@@ -222,4 +222,22 @@ namespace RKCommonFunctions {
                return (i18n ("<p><em>Note:</em> This setting does not take 
effect until you restart RKWard.</p>"));
        }
 
+#ifdef Q_OS_WIN
+#      include <windows.h>
+#      include <QTemporaryFile>
+#endif
+       QString windowsShellScriptSafeCommand (const QString &orig) {
+#ifdef Q_OS_WIN
+               // credits to 
http://erasmusjam.wordpress.com/2012/10/01/get-8-3-windows-short-path-names-in-a-qt-application/
+               QByteArray input (sizeof (wchar_t) * (orig.size()+1), '\0');
+               // wchar_t input[orig.size()+1]; -- No: MSVC (2013) does not 
support variable length arrays. Oh dear...
+               orig.toWCharArray ((wchar_t*) input.data ());
+               long length = GetShortPathName ((wchar_t*) input.data (), NULL, 
0);
+               QByteArray output (sizeof (wchar_t) * (length), '\0');
+               GetShortPathName ((wchar_t*) input.data (), (wchar_t*) 
output.data (), length);
+               return QString::fromWCharArray ((wchar_t*) output.data (), 
length-1);
+#else
+               return orig;
+#endif
+       }
 }      // namespace
diff --git a/rkward/misc/rkcommonfunctions.h b/rkward/misc/rkcommonfunctions.h
index 23511cae..34683fc9 100644
--- a/rkward/misc/rkcommonfunctions.h
+++ b/rkward/misc/rkcommonfunctions.h
@@ -59,6 +59,8 @@ namespace RKCommonFunctions {
 /** simultaneously sets tool tips and what's this tips on up to three QWidgets 
*/
        void setTips (const QString tip, QWidget *first, QWidget *second=0, 
QWidget *third=0);
        QString noteSettingsTakesEffectAfterRestart ();
+/** Passing commands as part of arguments to windows shell scripts will fail 
miserably for paths with spaces or special characters. Transform to short path 
names for safety. No-op on sane platforms.*/
+       QString windowsShellScriptSafeCommand (const QString &orig);
 };
 
 #endif
diff --git a/rkward/org.kde.rkward.desktop b/rkward/org.kde.rkward.desktop
index de75e66d..adb468eb 100755
--- a/rkward/org.kde.rkward.desktop
+++ b/rkward/org.kde.rkward.desktop
@@ -50,7 +50,7 @@ Comment[uk]=Графічний інтерфейс проекту R
 Comment[x-test]=xxGUI for the R-projectxx
 Icon=rkward
 X-DBUS-ServiceName=org.kde.rkward
-Exec=sh -c "STARTUP_ID_COPY=\\${DESKTOP_STARTUP_ID} rkward -qwindowtitle '%c'"
+Exec=rkward -qwindowtitle '%c'
 Terminal=false
 Type=Application
 X-DocPath=rkward/index.html
diff --git a/rkward/rbackend/rinterface.cpp b/rkward/rbackend/rinterface.cpp
index b058576e..37c812c9 100644
--- a/rkward/rbackend/rinterface.cpp
+++ b/rkward/rbackend/rinterface.cpp
@@ -77,11 +77,6 @@ int RInterface::na_int;
 RInterface::RInterface () {
        RK_TRACE (RBACKEND);
 
-       // If R_HOME is not set, most certainly the user called the binary 
without the wrapper script
-       if (!getenv ("R_HOME")) {
-               RK_DEBUG (RBACKEND, DL_ERROR, "No R_HOME environment variable 
set. RKWard will quit in a moment. Always start rkward in the default way 
unless you know what you're doing.");
-       }
-
        new RCommandStackModel (this);
        RCommandStack::regular_stack = new RCommandStack ();
        startup_phase2_error = false;
diff --git a/rkward/rbackend/rkfrontendtransmitter.cpp 
b/rkward/rbackend/rkfrontendtransmitter.cpp
index e8eeb5db..2f62e860 100644
--- a/rkward/rbackend/rkfrontendtransmitter.cpp
+++ b/rkward/rbackend/rkfrontendtransmitter.cpp
@@ -95,10 +95,11 @@ void RKFrontendTransmitter::run () {
 
        QStringList args;
        args.append ("--debug-level=" + QString::number (RK_Debug_Level));
-       args.append ("--server-name=" + server->fullServerName ());
-       args.append ("--rkd-server-name=" + rkd_transmitter->serverName ());
-       args.append ("--data-dir=" + RKSettingsModuleGeneral::filesPath ());
-       args.append ("--locale-dir=" + localeDir ());
+       // NOTE: QProcess quotes its arguments, *but* properly passing all 
spaces and quotes through the R CMD wrapper, seems near(?) impossible on 
Windows. Instead, we use percent encoding, internally.
+       args.append ("--server-name=" + server->fullServerName ().toUtf8 
().toPercentEncoding ());
+       args.append ("--rkd-server-name=" + rkd_transmitter->serverName 
().toUtf8 ().toPercentEncoding ());
+       args.append ("--data-dir=" + RKSettingsModuleGeneral::filesPath 
().toUtf8 ().toPercentEncoding ());
+       args.append ("--locale-dir=" + localeDir ().toUtf8 ().toPercentEncoding 
());
        connect (backend, static_cast<void (QProcess::*)(int, 
QProcess::ExitStatus)>(&QProcess::finished), this, 
&RKFrontendTransmitter::backendExit);
        QString backend_executable = findBackendAtPath 
(QCoreApplication::applicationDirPath ());
        if (backend_executable.isEmpty ()) backend_executable = 
findBackendAtPath (QCoreApplication::applicationDirPath () + "/rbackend");      
// for running directly from the build-dir
@@ -107,14 +108,16 @@ void RKFrontendTransmitter::run () {
 #endif
        if (backend_executable.isEmpty ()) handleTransmissionError (i18n ("The 
backend executable could not be found. This is likely to be a problem with your 
installation."));
        QString debugger = 
RKGlobals::startup_options["backend-debugger"].toString ();
+       args.prepend (RKCommonFunctions::windowsShellScriptSafeCommand 
(backend_executable));
+       args.prepend ("CMD");
        if (!debugger.isEmpty ()) {
-               args.prepend (backend_executable);
-               QStringList l = debugger.split (' ');
-               args = l.mid (1) + args;
-               backend->start (l.first (), args, QIODevice::ReadOnly);
-       } else {
-               backend->start (backend_executable, args, QIODevice::ReadOnly);
+               args = debugger.split (' ') + args;
        }
+for (int i = 0; i < args.size (); ++i) {
+qDebug ("%s", qPrintable (args[i]));
+}
+qDebug ("%s", qPrintable (qgetenv ("R_BINARY")));
+       backend->start (qgetenv ("R_BINARY"), args, QIODevice::ReadOnly);
 
        if (!backend->waitForStarted ()) {
                handleTransmissionError (i18n ("The backend executable could 
not be started. Error message was: %1", backend->errorString ()));
diff --git a/rkward/rbackend/rkrbackendprotocol_backend.cpp 
b/rkward/rbackend/rkrbackendprotocol_backend.cpp
index cbce78f8..84a87884 100644
--- a/rkward/rbackend/rkrbackendprotocol_backend.cpp
+++ b/rkward/rbackend/rkrbackendprotocol_backend.cpp
@@ -33,6 +33,7 @@
 #include <QUuid>               // mis-used as a random-string generator
 #include <QTemporaryFile>
 #include <QDir>
+#include <QUrl>
 
        void RK_setupGettext (const char*);
        int RK_Debug_Level = 2;
@@ -83,16 +84,13 @@
                        if (args[i].startsWith ("--debug-level")) {
                                RK_Debug_Level = args[i].section ('=', 1).toInt 
();
                        } else if (args[i].startsWith ("--server-name")) {
-                               servername = args[i].section ('=', 1);
+                               servername = QUrl::fromPercentEncoding 
(args[i].section ('=', 1).toUtf8 ());
                        } else if (args[i].startsWith ("--data-dir")) {
-#ifdef __GNUC__
-#      warning What about paths with spaces?!
-#endif
-                               data_dir = args[i].section ('=', 1);
+                               data_dir = QUrl::fromPercentEncoding 
(args[i].section ('=', 1).toUtf8 ());
                        } else if (args[i].startsWith ("--locale-dir")) {
-                               locale_dir = args[i].section ('=', 1);
+                               locale_dir = QUrl::fromPercentEncoding 
(args[i].section ('=', 1).toUtf8 ());
                        } else if (args[i].startsWith ("--rkd-server-name")) {
-                               rkd_server_name = args[i].section ('=', 1);
+                               rkd_server_name = QUrl::fromPercentEncoding 
(args[i].section ('=', 1).toUtf8 ());
                        } else {
                                printf ("unknown argument %s", qPrintable 
(args[i]));
                        }
diff --git a/rkward/rkward_startup_wrapper.cpp 
b/rkward/rkward_startup_wrapper.cpp
deleted file mode 100755
index b6f8f2a8..00000000
--- a/rkward/rkward_startup_wrapper.cpp
+++ /dev/null
@@ -1,332 +0,0 @@
-/***************************************************************************
-                          rkward_startup_wrapper  -  description
-                             -------------------
-    begin                : Sun Mar 10 2013
-    copyright            : (C) 2013, 2014, 2015 by Thomas Friedrichsmeier
-    email                : [email protected]
- ***************************************************************************/
-
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- ***************************************************************************/
-
-/** This simple helper executable is responsible for reading basic 
configuration
- * settings, checking for some services and starting RKWard. These things used
- * to be done using a script, and there was nothing wrong with that, in 
principle.
- * However, the binary allows more flexibility, and more consistency across
- * platforms. */
-
-#include <QApplication>
-#include <QMessageBox>
-#include <QDir>
-#include <QProcess>
-#include <QSettings>
-#include <QUrl>
-#include <QFile>
-#include <QtDBus>
-#include "misc/rkdbusapi.h"
-
-#ifndef RKWARD_FRONTEND_LOCATION
-#      define RKWARD_FRONTEND_LOCATION ""
-#endif
-
-#ifndef R_EXECUTABLE
-#      define R_EXECUTABLE ""
-#endif
-
-QString findExeAtPath (const QString appname, const QString &path) {
-       QDir dir (path);
-       dir.makeAbsolute ();
-       if (QFileInfo (dir.filePath (appname)).isExecutable ()) return 
dir.filePath (appname);
-#ifdef Q_OS_WIN
-       if (QFileInfo (dir.filePath (appname + ".exe")).isExecutable ()) return 
dir.filePath (appname + ".exe");
-       if (QFileInfo (dir.filePath (appname + ".com")).isExecutable ()) return 
dir.filePath (appname + ".com");
-       if (QFileInfo (dir.filePath (appname + ".bat")).isExecutable ()) return 
dir.filePath (appname + ".bat");
-#endif
-       return QString ();
-}
-
-QString findRKWardAtPath (const QString &path) {
-       return findExeAtPath ("rkward.frontend", path);
-}
-
-#ifdef Q_OS_WIN
-#include <windows.h>
-#include <QTemporaryFile>
-#endif
-QString quoteCommand (const QString &orig) {
-#ifdef Q_OS_WIN
-// Get short path name as a safe way to pass all sort of commands on the 
Windows shell
-// credits to 
http://erasmusjam.wordpress.com/2012/10/01/get-8-3-windows-short-path-names-in-a-qt-application/
-       QByteArray input (sizeof (wchar_t) * (orig.size()+1), '\0');
-       // wchar_t input[orig.size()+1]; -- No: MSVC (2013) does not support 
variable length arrays. Oh dear...
-       orig.toWCharArray ((wchar_t*) input.data ());
-       long length = GetShortPathName ((wchar_t*) input.data (), NULL, 0);
-       QByteArray output (sizeof (wchar_t) * (length), '\0');
-       GetShortPathName ((wchar_t*) input.data (), (wchar_t*) output.data (), 
length);
-       return QString::fromWCharArray ((wchar_t*) output.data (), length-1);
-#else
-       return orig;
-#endif
-}
-
-#ifndef Q_OS_WIN
-// see 
http://blog.qt.digia.com/blog/2006/03/16/starting-interactive-processes-with-qprocess/
-// Need an interactive process e.g. for running through gdb
-#      include <unistd.h>
-class InteractiveProcess : public QProcess {
-    static int stdinClone;
-public:
-    InteractiveProcess (QObject *parent = 0) : QProcess (parent) {
-        if (stdinClone == -1) stdinClone = ::dup (fileno(stdin));
-    }
-protected:
-    void setupChildProcess () override {
-        ::dup2 (stdinClone, fileno(stdin));
-    }
-};
-int InteractiveProcess::stdinClone = -1;
-#else
-// no easy solution for Windows. But ain't Windows the world of graphical 
debuggers, anyway...
-#      define InteractiveProcess QProcess
-#endif
-
-#ifdef Q_OS_WIN
-#      define PATH_VAR_SEP ';'
-#else
-#      define PATH_VAR_SEP ':'
-#endif
-
-int main (int argc, char *argv[]) {
-       QApplication app (argc, argv);
-       QStringList args = app.arguments ();
-       if (!args.isEmpty ()) args.pop_front ();        // The command itself
-       qputenv ("DESKTOP_STARTUP_ID", qgetenv ("STARTUP_ID_COPY"));    // for 
startup notifications (set via org.kde.rkward.desktop)
-       qputenv ("STARTUP_ID_COPY", "");
-
-       // Parse arguments that need handling in the wrapper
-       bool usage = false;
-       QStringList debugger_args;
-       QStringList file_args;
-       bool reuse = false;
-       bool warn_external = true;
-       QString r_exe_arg;
-       int debug_level = 2;
-
-       for (int i=0; i < args.size (); ++i) {
-               if (args[i] == "--debugger") {
-                       args.removeAt (i);
-                       while (i < args.size ()) {
-                               QString arg = args.takeAt (i);
-                               if (arg == "--") break;
-                               debugger_args.append (arg);
-                       }
-                       if (debugger_args.isEmpty ()) usage = true;
-               } else if (args[i] == "--r-executable") {
-                       if ((i+1) < args.size ()) {
-                               r_exe_arg = args.takeAt (i + 1);
-                       } else usage = true;
-                       args.removeAt (i);
-                       --i;
-               } else if (args[i] == "--debug-level") {
-                       if ((i+1) < args.size ()) {
-                               debug_level = args[i+1].toInt ();
-                       }
-               } else if (args[i] == "--reuse") {
-                       reuse = true;
-               } else if (args[i] == "--nowarn-external") {
-                       warn_external = false;
-               } else if (args[i].startsWith ("--")) {
-                       // all RKWard and KDE options (other than --reuse) are 
of the for --option <value>. So skip over the <value>
-                       i++;
-               } else {
-                       QUrl url = QUrl::fromUserInput (args[i], 
QDir::currentPath (), QUrl::AssumeLocalFile);
-                       file_args.append (url.toString ());
-               }
-       }
-
-       if (reuse) {
-               if (!QDBusConnection::sessionBus ().isConnected ()) {
-                       if (debug_level > 2) qDebug ("Could not connect to 
session dbus");
-               } else {
-                       QDBusInterface iface (RKDBUS_SERVICENAME, "/", "", 
QDBusConnection::sessionBus ());
-                       if (iface.isValid ()) {
-                               QDBusReply<void> reply = iface.call 
("openAnyUrl", file_args, warn_external);
-                               if (!reply.isValid ()) {
-                                       if (debug_level > 2) qDebug ("Error 
while placing dbus call: %s", qPrintable (reply.error ().message ()));
-                                       return 1;
-                               }
-                               return 0;
-                       }
-               }
-       }
-
-       // MacOS may need some path adjustments, first
-#ifdef Q_OS_MAC
-       QString oldpath = qgetenv ("PATH");
-       if (!oldpath.contains (INSTALL_PATH)) {
-               //ensure that PATH is set to include what we deliver with the 
bundle
-               qputenv ("PATH", QString ("%1/bin:%1/sbin:%2").arg 
(INSTALL_PATH).arg (oldpath).toLocal8Bit ());
-               if (debug_level > 3) qDebug ("Adjusting system path to %s", 
qPrintable (qgetenv ("PATH")));
-       }
-       // ensure that RKWard finds its own packages
-       qputenv ("R_LIBS", R_LIBS);
-       QProcess::execute ("launchctl", QStringList () << "load" << "-w" << 
INSTALL_PATH "/Library/LaunchAgents/org.freedesktop.dbus-session.plist");
-#endif
-
-       // Locate KDE and RKWard installations
-       QString marker_exe_name ("qtpaths");    // Simply some file that should 
exist in the bin dir of a KDE installation on both Unix and Windows
-       QString marker_exe = findExeAtPath (marker_exe_name, QDir::currentPath 
());
-       if (marker_exe.isNull ()) marker_exe = findExeAtPath (marker_exe_name, 
app.applicationDirPath ());
-       if (marker_exe.isNull ()) marker_exe = findExeAtPath (marker_exe_name, 
QDir (app.applicationDirPath ()).filePath ("KDE/bin"));
-       QStringList syspath = QString (qgetenv ("PATH")).split (PATH_VAR_SEP);
-       if (marker_exe.isNull ()) {
-               for (int i = 0; i < syspath.size (); ++i) {
-                       marker_exe = findExeAtPath (marker_exe_name, 
syspath[i]);
-                       if (!marker_exe.isNull ()) break;
-               }
-       }
-
-       if (marker_exe.isNull ()) {
-               QMessageBox::critical (0, "Could not find KDE installation", 
"The KDE installation could not be found (" + marker_exe_name + "). When moving 
/ copying RKWard, make sure to copy the whole application folder, or create a 
shorcut / link, instead.");
-               exit (1);
-       }
-
-       QDir kde_dir (QFileInfo (marker_exe).absolutePath ());
-       kde_dir.makeAbsolute ();
-       QString kde_dir_safe_path = quoteCommand (kde_dir.path ());
-       if (syspath.indexOf (kde_dir.path ()) < 0) {
-               if (debug_level > 3) qDebug ("Adding %s to the system path", 
qPrintable (kde_dir_safe_path));
-               qputenv ("PATH", QString (kde_dir_safe_path + PATH_VAR_SEP + 
qgetenv ("PATH")).toLocal8Bit ());
-       }
-
-       QString rkward_frontend_exe = findRKWardAtPath (app.applicationDirPath 
());     // this is for running directly from a build tree
-#ifdef Q_OS_MAC
-       if (rkward_frontend_exe.isNull ()) rkward_frontend_exe = 
findRKWardAtPath (app.applicationDirPath () + 
"/rkward.frontend.app/Contents/MacOS");  // this is for running directly from a 
build tree
-#endif
-       if (rkward_frontend_exe.isNull ()) rkward_frontend_exe = 
findRKWardAtPath (RKWARD_FRONTEND_LOCATION);
-       if (rkward_frontend_exe.isNull ()) rkward_frontend_exe = 
findRKWardAtPath (kde_dir.absoluteFilePath ("bin"));
-       if (rkward_frontend_exe.isNull ()) rkward_frontend_exe = 
findRKWardAtPath (kde_dir.absoluteFilePath ("../lib/libexec"));
-       for (int i = 0; i < syspath.size (); ++i) {
-               if (!rkward_frontend_exe.isNull ()) break;
-               rkward_frontend_exe = findRKWardAtPath (syspath[i]);
-       }
-
-       if (rkward_frontend_exe.isNull ()) {
-               QMessageBox::critical (0, "RKWard frontend binary missing", 
"RKWard frontend binary could not be found. When moving / copying RKWard, make 
sure to copy the whole application folder, or create a shorcut / link, 
instead.");
-               exit (1);
-       }
-
-       if (usage) {
-               QProcess::execute (rkward_frontend_exe, QStringList ("--help"));
-               exit (1);
-       }
-
-#ifdef Q_OS_WIN
-       // Explicit initialization of KDE, in case Windows 7 asks for admin 
privileges
-       // KF5 TODO: _is_ there a kdeinit5.exe on Windows? Do we have to add 
some dependency? Do we still need this?
-       QString kdeinit5_exe = findExeAtPath ("kdeinit5", kde_dir.path ());
-       if (kdeinit5_exe.isNull ()) {
-               kdeinit5_exe = findExeAtPath ("kdeinit5", QFileInfo 
(rkward_frontend_exe).absolutePath ());
-       }
-       if (!kdeinit5_exe.isNull ()) QProcess::execute (kdeinit5_exe, 
QStringList ());
-#endif
-
-       // Look for R:
-       //- command line parameter
-       //- Specified in cfg file next to rkward executable
-       //- compile-time default
-       QString r_exe = r_exe_arg;
-       if (!r_exe.isNull ()) {
-               if (!QFileInfo (r_exe).isExecutable ()) {
-                       QMessageBox::critical (0, "Specified R executable does 
not exist", QString ("The R executable specified on the command line (%1) does 
not exist or is not executable.").arg (r_exe));
-                       exit (1);
-               }
-               if (debug_level > 3) qDebug ("Using R specified on command 
line");
-       } else {
-               QFileInfo frontend_info (rkward_frontend_exe);
-               QDir frontend_path = frontend_info.absoluteDir ();
-               QFileInfo rkward_ini_file (frontend_path.absoluteFilePath 
("rkward.ini"));
-               if (rkward_ini_file.isReadable ()) {
-                       QSettings rkward_ini (rkward_ini_file.absoluteFilePath 
(), QSettings::IniFormat);
-                       r_exe = rkward_ini.value ("R executable").toString ();
-                       if (!r_exe.isNull ()) {
-                               if (QDir::isRelativePath (r_exe)) {
-                                       r_exe = frontend_path.absoluteFilePath 
(r_exe);
-                               }
-                               if (!QFileInfo (r_exe).isExecutable ()) {
-                                       QMessageBox::critical (0, "Specified R 
executable does not exist", QString ("The R executable specified in the 
rkward.ini file (%1) does not exist or is not executable.").arg 
(rkward_ini_file.absoluteFilePath ()));
-                                       exit (1);
-                               }
-                       }
-                       if (debug_level > 3) qDebug ("Using R as configured in 
config file %s", qPrintable (rkward_ini_file.absoluteFilePath ()));
-               }
-               if (r_exe.isNull ()) {
-                       r_exe = R_EXECUTABLE;
-                       if (!QFileInfo (r_exe).isExecutable ()) {
-                               QMessageBox::critical (0, "Specified R 
executable does not exist", QString ("The R executable specified at compile 
time (%1) does not exist or is not executable. Probably the installation of R 
has moved. You can use the command line parameter '--r-executable 
<i>PATH_TO_R</i>', or supply an rkward.ini file to specify the new 
location.").arg (r_exe));
-                               exit (1);
-                       }
-                       if (debug_level > 3) qDebug ("Using R as configured at 
compile time");
-               }
-       }
-
-       // TODO: This is a _temporary_ hack!
-#warning Remove me!
-       qputenv ("KDIRWATCH_METHOD", QByteArray ("Stat"));
-
-       qputenv ("R_BINARY", r_exe.toLocal8Bit ());
-       QStringList call_args ("CMD");
-       call_args.append (debugger_args);
-       call_args.append (quoteCommand (rkward_frontend_exe));
-
-       if (!args.isEmpty ()) {
-               // NOTE: QProcess quotes its arguments, *but* properly passing 
all spaces and quotes through the R CMD wrapper, seems near(?) impossible on 
Windows. Instead, we use percent encoding, internally.
-               for (int i = 0; i < args.size (); ++i) {
-                       call_args.append (QString::fromUtf8 
(QUrl::toPercentEncoding (args[i], QByteArray (), " \"")));
-               }
-       }
-
-       if (debug_level > 2) qDebug ("Starting frontend: %s %s", qPrintable 
(r_exe), qPrintable (call_args.join (" ")));
-
-       InteractiveProcess proc;
-#ifdef Q_OS_WIN
-       if (debugger_args.isEmpty ()) {
-               // start _without_ opening an annoying console window
-               QTemporaryFile *vbsf = new QTemporaryFile (QDir::tempPath () + 
"/rkwardlaunchXXXXXX.vbs");
-               vbsf->setAutoRemove (false);
-               if (vbsf->open ()) {
-                       QTextStream vbs (vbsf);
-                       vbs << "Dim WinScriptHost\r\nSet WinScriptHost = 
CreateObject(\"WScript.Shell\")\r\nWinScriptHost.Run \"" << quoteCommand 
(r_exe);
-                       for (int i = 0;  i < call_args.length (); ++i) {
-                               vbs << " " << call_args[i];
-                       }
-                       vbs << "\", 0\r\nSet WinScriptHost = Nothing\r\n";
-                       vbsf->close ();
-                       QString filename = vbsf->fileName ();
-                       delete (vbsf);  // somehow, if creating vbsf on the 
stack, we cannot launch it, because "file is in use by another process", 
despite we have closed it.
-                       proc.start ("WScript.exe", QStringList (filename));
-                       bool ok = proc.waitForFinished (-1);
-                       if (proc.exitCode () || !ok) {
-                               QMessageBox::critical (0, "Error starting 
RKWard", QString ("Starting RKWard failed with error \"%1\"").arg 
(proc.errorString ()));
-                       }
-                       QFile (filename).remove ();
-                       return (0);
-               }
-       }
-       // if that did not work or not on windows:
-#endif
-       proc.setProcessChannelMode (QProcess::ForwardedChannels);
-       proc.start (quoteCommand (r_exe), call_args);
-       bool ok = proc.waitForFinished (-1);
-       if (proc.exitCode () || !ok) {
-               QMessageBox::critical (0, "Error starting RKWard", QString 
("Starting RKWard failed with error \"%1\"").arg (proc.errorString ()));
-       }
-
-       return (0);
-}

Reply via email to