修改VirtualBox GUI以使用kchmviewer(如果可用) [英] Modifying VirtualBox GUI to use kchmviewer if available

查看:207
本文介绍了修改VirtualBox GUI以使用kchmviewer(如果可用)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:我想指出,我没有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
}

说明:在运行时检查, kchmviewer 在操作系统中可用,如果是,请将 USE_KCHMVIEWER 设置为1(true),否则设置为0 >

2。)



我想将上述代码放入VirtualBox代码库中, c $ c> VBOX_OSE 在以下情况下:



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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆