Modifying GUI to use kchmviewer if available
Posted: 14. Oct 2015, 11:17
When accessing the documentation, the OSE version opens UserManual.pdf in whatever is the default PDF viewer in the system (e.g. Evince) while the official version opens VirtualBox.chm in an older (GPLv2) version of kchmviewer, that comes bundled in the package. Since my build contains documentation in both PDF and CHM formats (but no kchmviewer), I would like to adapt VirtualBox's code to check whether kchmviewer is installed (e.g. using "which kchmviewer"), and if not, fall back to UserManual.pdf. Currently I have no C++ skills and would be grateful if the developers would show me how to properly do this.
Here's the relevant code snippet from VirtualBox-5.0.6/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp:
…and also VBoxGlobal.cpp:
Thank you in advance.
EDIT: I added the missing piece of code that I previously overlooked.
EDIT 2: Also added code from VBoxGlobal.cpp that defines the filename. I guess this is the part that I have to change.
Here's the relevant code snippet from VirtualBox-5.0.6/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp:
Code: Select all
void UIMessageCenter::sltShowHelpHelpDialog()
{
#ifndef VBOX_OSE
/* For non-OSE version we just open it: */
sltShowUserManual(vboxGlobal().helpFile());
#else /* #ifndef VBOX_OSE */
/* For OSE version we have to check if it present first: */
QString strUserManualFileName1 = vboxGlobal().helpFile();
QString strShortFileName = QFileInfo(strUserManualFileName1).fileName();
QString strUserManualFileName2 = QDir(vboxGlobal().homeFolder()).absoluteFilePath(strShortFileName);
/* Show if user manual already present: */
if (QFile::exists(strUserManualFileName1))
sltShowUserManual(strUserManualFileName1);
else if (QFile::exists(strUserManualFileName2))
sltShowUserManual(strUserManualFileName2);
/* If downloader is running already: */
else if (UIDownloaderUserManual::current())
{
/* Just show network access manager: */
gNetworkManager->show();
}
/* Else propose to download user manual: */
else if (cannotFindUserManual(strUserManualFileName1))
{
/* Create User Manual downloader: */
UIDownloaderUserManual *pDl = UIDownloaderUserManual::create();
/* After downloading finished => show User Manual: */
connect(pDl, SIGNAL(sigDownloadFinished(const QString&)), this, SLOT(sltShowUserManual(const QString&)));
/* Start downloading: */
pDl->start();
}
#endif /* #ifdef VBOX_OSE */
}
…
void UIMessageCenter::sltShowUserManual(const QString &strLocation)
{
#if defined (Q_WS_WIN32)
HtmlHelp(GetDesktopWindow(), strLocation.utf16(), HH_DISPLAY_TOPIC, NULL);
#elif defined (Q_WS_X11)
# ifndef VBOX_OSE
char szViewerPath[RTPATH_MAX];
int rc;
rc = RTPathAppPrivateArch(szViewerPath, sizeof(szViewerPath));
AssertRC(rc);
QProcess::startDetached(QString(szViewerPath) + "/kchmviewer", QStringList(strLocation));
# else /* #ifndef VBOX_OSE */
vboxGlobal().openURL("file://" + strLocation);
# endif /* #ifdef VBOX_OSE */
#elif defined (Q_WS_MAC)
vboxGlobal().openURL("file://" + strLocation);
#endif
}
Code: Select all
QString VBoxGlobal::helpFile() const
{
#if defined (Q_WS_WIN32)
const QString name = "VirtualBox";
const QString suffix = "chm";
#elif defined (Q_WS_MAC)
const QString name = "UserManual";
const QString suffix = "pdf";
#elif defined (Q_WS_X11)
# if defined VBOX_OSE
const QString name = "UserManual";
const QString suffix = "pdf";
# else
const QString name = "VirtualBox";
const QString suffix = "chm";
# endif
#endif
/* Where are the docs located? */
char szDocsPath[RTPATH_MAX];
int rc = RTPathAppDocs (szDocsPath, sizeof (szDocsPath));
AssertRC (rc);
/* Make sure that the language is in two letter code.
* Note: if languageId() returns an empty string lang.name() will
* return "C" which is an valid language code. */
QLocale lang (VBoxGlobal::languageId());
/* Construct the path and the filename */
QString manual = QString ("%1/%2_%3.%4").arg (szDocsPath)
.arg (name)
.arg (lang.name())
.arg (suffix);
/* Check if a help file with that name exists */
QFileInfo fi (manual);
if (fi.exists())
return manual;
/* Fall back to the standard */
manual = QString ("%1/%2.%4").arg (szDocsPath)
.arg (name)
.arg (suffix);
return manual;
}
EDIT: I added the missing piece of code that I previously overlooked.
EDIT 2: Also added code from VBoxGlobal.cpp that defines the filename. I guess this is the part that I have to change.