If you used Qt to develop your cross-platform application, then the QDesktopServices::openUrl() method would do the job. It is of course cross-platform, like everything in Qt.
Since you're already using wxWidgets, using Qt just to open a file is obviously an overkill. And since wxWidgets is mostly GUI stuff, it probably doesn't have anything like that, although I can't be sure as I've never used it myself.
Still, if you want to do it in a cross-platform way, here is what Qt does for Windows:
quintptr returnValue = (quintptr)ShellExecute(0, 0,
(wchar_t*)filePath.utf16(), 0, 0, SW_SHOWNORMAL);
// ShellExecute returns a value greater than 32 if successful
return (returnValue > 32);
Here, filePath.utf16() is the Unicode null-terminated file path.
Here is the relevant part for X11/Unix:
if (launch(url, QLatin1String("xdg-open")))
return true;
if (X11->desktopEnvironment == DE_GNOME
&& launch(url, QLatin1String("gnome-open"))) {
return true;
} else {
if (X11->desktopEnvironment == DE_KDE
&& launch(url, QLatin1String("kfmclient exec")))
return true;
}
if (launch(url, QLatin1String("firefox")))
return true;
if (launch(url, QLatin1String("mozilla")))
return true;
if (launch(url, QLatin1String("netscape")))
return true;
if (launch(url, QLatin1String("opera")))
return true;
return false;
Here, the launch() function basically starts the indicated application, passing it the URL to open. Not just the file path, like in Windows, but the complete URL like file:///home/user/tmp/file.doc
. Not sure that it matters, though. It also percent-encodes all non-ASCII characters in the URL before passing it to the program. Not sure if it matters for all the programs that the openDocument() tries. I have tested it with xdg-open
, and it doesn't care if it's percent-encoded or not.
Here is the part that detects desktop environment and sets X11->desktopEnvironment
accordingly:
X11->desktopEnvironment = DE_UNKNOWN;
Atom type;
int format;
unsigned long length, after;
uchar *data = 0;
int rc;
do {
if (!qgetenv("KDE_FULL_SESSION").isEmpty()) {
X11->desktopEnvironment = DE_KDE;
break;
}
if (qgetenv("DESKTOP_SESSION") == "gnome") {
X11->desktopEnvironment = DE_GNOME;
break;
}
// GNOME_DESKTOP_SESSION_ID is deprecated for some reason, but still check it
if (!qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) {
X11->desktopEnvironment = DE_GNOME;
break;
}
rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(_DT_SAVE_MODE),
0, 2, False, XA_STRING, &type, &format, &length,
&after, &data);
if (rc == Success && length) {
if (!strcmp(reinterpret_cast<char *>(data), "xfce4")) {
// Pretend that xfce4 is gnome, as it uses the same libraries.
// The detection above is stolen from xdg-open.
X11->desktopEnvironment = DE_GNOME;
break;
}
// We got the property but it wasn't xfce4. Free data before it gets overwritten.
XFree(data);
data = 0;
}
} while(0);
Wow, that was something. And I have removed the parts that detects other environments because they aren't used in openDocument().
And lastly, here is the glorious Mac version of the openDocument():
// LSOpen does not work in this case, use QProcess open instead.
return QProcess::startDetached(QLatin1String("open"), QStringList() << file.toLocalFile());
Really? That's it? Wow, there must be something to the Mac platform after all. Here, QProcess::startDetached() just starts a new process, passing the file path as an argument. It is largely equivalent to the system() call, but doesn't wait for the process to terminate. Not sure if that matters, and I have no idea how to do it on Mac without using QProcess, as I've never even seen a Mac.
system()
command? That's the quickest way I can think of to go cross-platform, but I assume it doesn't do exactly what you want, if you're asking this question. – Andreas