修改VirtualBox GUI以使用kchmviewer(如果可用) [英] Modifying VirtualBox GUI to use kchmviewer if available
问题描述
注意:我想指出,我没有C / C ++知识,但我知道 bash
解决方案对语言的具体解释。非常感谢。
为了更清楚起见,我将我的问题分为两个不同的部分:
1。)
我试图让以下代码工作:
if(system(which kchmviewer> / dev / null)== 0)
{
//which kchmviewerexit code 0
#define USE_KCHMVIEWER 1
}
else
{
//which kchmviewer退出代码1
#define USE_KCHMVIEWER 0
}
说明:在运行时检查, 我想将上述代码放入VirtualBox代码库中, c $ c> VBOX_OSE kchmviewer
在操作系统中可用,如果是,请将
在以下情况下: USE_KCHMVIEWER
设置为1(true),否则设置为0 >
2。)
a。) :: sltShowHelpHelpDialog(),包含 #ifndef VBOX_OSE
的行将替换为 #ifdef USE_KCHMVIEWER
;
b。)在 UIMessageCenter :: sltShowUserManual()
,包含#ifndef在<$ c中,将替换为
,包含#ifdef USE_KCHMVIEWER
;
c。) $ c> VBoxGlobal :: helpFile()的行如果定义VBOX_OSE
将替换为#if! USE_KCHMVIEWER
。
//文件:VirtualBox-5.0.6 / src / VBox / Frontends / VirtualBox /src/globals/UIMessageCenter.cpp
void UIMessageCenter :: sltShowHelpHelpDialog()
{
#ifndef VBOX_OSE
/ *对于非OSE版本,我们只需打开它:* /
sltShowUserManual(vboxGlobal()。helpFile());
#else / * #ifndef VBOX_OSE * /
/ *对于OSE版本,我们必须检查它是否存在:* /
QString strUserManualFileName1 = vboxGlobal()。helpFile
QString strShortFileName = QFileInfo(strUserManualFileName1).fileName();
QString strUserManualFileName2 = QDir(vboxGlobal()。homeFolder())。absoluteFilePath(strShortFileName);
/ *显示用户手册是否已经存在:* /
if(QFile :: exists(strUserManualFileName1))
sltShowUserManual(strUserManualFileName1);
else if(QFile :: exists(strUserManualFileName2))
sltShowUserManual(strUserManualFileName2);
/ *如果下载程序已经运行:* /
else if(UIDownloaderUserManual :: current())
{
/ *只显示网络访问管理器:* /
gNetworkManager-> show();
}
/ * Else建议下载用户手册:* /
else if(cannotFindUserManual(strUserManualFileName1))
{
/ *创建用户手册下载器:* /
UIDownloaderUserManual * pDl = UIDownloaderUserManual :: create();
/ *下载完成后=>显示用户手册:* /
connect(pD1,SIGNAL(sigDownloadFinished(const QString&)),this,SLOT(sltShowUserManual(const QString&
/ *开始下载:* /
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
}
//文件:VirtualBox-5.0.6 / src / VBox / Frontends / VirtualBox / src / globals / VBoxGlobal.cpp
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)
#如果定义VBOX_OSE
const QString name =UserManual;
const QString suffix =pdf;
#else
const QString name =VirtualBox;
const QString suffix =chm;
#endif
#endif
/ *文档位于哪里? * /
char szDocsPath [RTPATH_MAX];
int rc = RTPathAppDocs(szDocsPath,sizeof(szDocsPath));
AssertRC(rc);
/ *确保语言是两个字母代码。
*注意:如果languageId()返回一个空字符串lang.name()将
*返回C这是一个有效的语言代码。 * /
QLocale lang(VBoxGlobal :: languageId());
/ *构造路径和文件名* /
QString manual = QString(%1 /%2_%3.%4)arg(szDocsPath)
。 arg(name)
.arg(lang.name())
.arg(suffix);
/ *检查具有该名称的帮助文件是否存在* /
QFileInfo fi(manual);
if(fi.exists())
return manual;
/ *回退到标准* /
manual = QString(%1 /%2.%4)arg(szDocsPath)
.arg(name)
.arg(suffix);
return manual;
}
底部
如何实现这一点? 我的操作系统是 Trisquel 7.0 (GNU / Linux)。
感谢您的建议。
strong> PS :详情请参阅论坛主题。
PPS :由于我还不知道如何仅重建源代码的特定部分,请尝试解决方案很可能需要我重新编译整个应用程序,然后才能检查它是否工作。这可能需要一个小时或更长时间,请耐心等待。
更新:重新提出问题以反映我的发现。这一次我想尽可能具体。
您最后一个论坛帖子与系统(which kchmviewer)
几乎是正确的。你只需要在上面的
上面的
QString名称,后缀 c>,并跳过
const QString
在 {}
块中。但是,它是一个仅适用于Linux的解决方案,因为其中
在Windows上不起作用。
Qt你可以使用 QProcess
来检查的退出代码,如果这样的命令退出:
QString name =UserManual;
QString suffix =pdf;
if(QProcess :: execute(which kchmviewer)== 0)
{
//which kchmviewerexit code 0
name =VirtualBox ;
suffix =chm;
}
这是为你的函数 helpFile但是你可以尝试通过
直接启动
kchmviewer
> QProcess:code>。
< :
sltShowUserManual()
中的startDetached()。如果失败, startDetached()
的返回值为 false
。在这种情况下,您可以使用 pdf
进入默认行为。 Note: I would like to point out that I have no C/C++ knowledge, but I know bash
so please try to provide functional solutions over language specific explanations. Thanks for that.
For better clarity, I'm going to separate my question into two distinct sections:
1.)
I'm trying to make the following code work:
if (system("which kchmviewer > /dev/null") == 0)
{
// "which kchmviewer" exit code 0
#define USE_KCHMVIEWER 1
}
else
{
// "which kchmviewer" exit code 1
#define USE_KCHMVIEWER 0
}
Explanation: Check, at runtime, whether kchmviewer
is available in the operating system, and if yes, set USE_KCHMVIEWER
to "1" (true), otherwise "0" (false).
2.)
I would like to place the above code into the VirtualBox codebase, then use it instead of VBOX_OSE
in the following cases:
a.) in UIMessageCenter::sltShowHelpHelpDialog()
, line containing #ifndef VBOX_OSE
will be replaced with #ifdef USE_KCHMVIEWER
;
b.) in UIMessageCenter::sltShowUserManual()
, line containing # ifndef VBOX_OSE
will be replaced with # ifdef USE_KCHMVIEWER
;
c.) in VBoxGlobal::helpFile()
, line containing # if defined VBOX_OSE
will be replaced with # if !defined USE_KCHMVIEWER
.
// File: VirtualBox-5.0.6/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp
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
}
// File: VirtualBox-5.0.6/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
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;
}
Bottom line
How to achieve this? My operating system is Trisquel 7.0 (GNU/Linux).
Thank you for the advice.
P.S.: More details can be found in this forum thread.
P.P.S.: As I don't know yet how to rebuild only specific parts of the source code, trying your solution will most likely require from me to recompile the whole application before I can check whether it works or not. This may take an hour or more so please be patient.
UPDATE: Rephrased the question to reflect my findings. This time I'm trying to be as specific as possible.
Your last forum post with system("which kchmviewer")
is almost correct. You only need the declaration QString name, suffix;
above the if
and skip const QString
in the {}
blocks. However, it is a solution only for Linux, since which
does not work on Windows.
Since your project uses Qt you can use QProcess
to check the exit code of the which
command if such command exits:
QString name = "UserManual";
QString suffix = "pdf";
if (QProcess::execute("which kchmviewer") == 0)
{
// "which kchmviewer" exit code 0
name = "VirtualBox";
suffix = "chm";
}
That is for your function helpFile()
.
However you can try directly launch kchmviewer
by QProcess::startDetached()
in sltShowUserManual()
. The return value of startDetached()
is false
if it fails. In that case you can go to default behavior using pdf
.
这篇关于修改VirtualBox GUI以使用kchmviewer(如果可用)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!