VirtualBox

Changeset 71089 in vbox


Ignore:
Timestamp:
Feb 21, 2018 5:35:07 PM (7 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:6699 Listen to API errors for better user feedback

Location:
trunk/src/VBox/Frontends/VirtualBox/src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.cpp

    r70899 r71089  
    3838# include "CExtraDataChangedEvent.h"
    3939# include "CGuestMonitorChangedEvent.h"
    40 #include  "CGuestProcessRegisteredEvent.h"
     40# include "CGuestProcessIOEvent.h"
     41# include "CGuestProcessRegisteredEvent.h"
    4142# include "CGuestSessionRegisteredEvent.h"
     43# include "CGuestProcessStateChangedEvent.h"
     44# include "CGuestSessionStateChangedEvent.h"
    4245# include "CKeyboardLedsChangedEvent.h"
    4346# include "CMachineStateChangedEvent.h"
     
    450453        case KVBoxEventType_OnGuestSessionStateChanged:
    451454        {
    452             emit sigGuestSessionStatedChanged();
    453             break;
    454         }
    455         case KVBoxEventType_OnGuestProcessStateChanged:
     455            CGuestSessionStateChangedEvent cEvent(pEvent);
     456            emit sigGuestSessionStatedChanged(cEvent);
     457            break;
     458        }
    456459        case KVBoxEventType_OnGuestProcessInputNotify:
    457460        case KVBoxEventType_OnGuestProcessOutput:
    458461        {
    459             emit sigGuestProcessStateChanged();
    460             break;
    461         }
     462            break;
     463        }
     464        case KVBoxEventType_OnGuestProcessStateChanged:
     465        {
     466            CGuestProcessStateChangedEvent cEvent(pEvent);
     467            cEvent.GetError();
     468            emit sigGuestProcessStateChanged(cEvent);
     469            break;
     470        }
     471
    462472        case KVBoxEventType_OnGuestFileRegistered:
    463473        case KVBoxEventType_OnGuestFileStateChanged:
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.h

    r70899 r71089  
    3939class CEventListener;
    4040class CEventSource;
    41 
    42 
     41class CGuestProcessStateChangedEvent;
     42class CGuestSessionStateChangedEvent;
    4343
    4444/* Note: On a first look this may seems a little bit complicated.
     
    142142        void sigGuestProcessRegistered(CGuestProcess guestProcess);
    143143        void sigGuestProcessUnregistered(CGuestProcess guestProcess);
    144         void sigGuestSessionStatedChanged();
    145         void sigGuestProcessStateChanged();
     144        void sigGuestSessionStatedChanged(const CGuestSessionStateChangedEvent &cEvent);
     145        void sigGuestProcessStateChanged(const CGuestProcessStateChangedEvent &cEvent);
    146146    /** @} */
    147147
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/information/guestctrl/UIGuestControlConsole.cpp

    r71066 r71089  
    7676        startNextLine();
    7777    }
    78 }
     78 }
    7979
    8080void UIGuestControlConsole::keyPressEvent(QKeyEvent *pEvent)
     
    139139        default:
    140140        {
    141             if(pEvent->modifiers() == Qt::ControlModifier && pEvent->key() == Qt::Key_C)
     141            if (pEvent->modifiers() == Qt::ControlModifier && pEvent->key() == Qt::Key_C)
    142142            {
    143143                QPlainTextEdit::keyPressEvent(pEvent);
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/information/guestctrl/UIGuestControlInterface.cpp

    r71067 r71089  
    2121
    2222/* GUI includes: */
     23# include "UIErrorString.h"
    2324# include "UIGuestControlInterface.h"
    2425# include "VBoxGlobal.h"
     
    3839#define GCTLCMD_COMMON_OPT_SESSION_NAME     995 /**< The --sessionname option number. */
    3940#define GCTLCMD_COMMON_OPT_SESSION_ID       994 /**< The --sessionid option number. */
     41
     42#define RETURN_ERROR(strError)     \
     43    {                              \
     44    m_strStatus.append(strError);  \
     45    return false;                  \
     46    }
    4047
    4148#define GCTLCMD_COMMON_OPTION_DEFS() \
     
    95102    CommandData()
    96103        : m_bSessionIdGiven(false)
    97         , m_bSessionNameGiven(false){}
     104        , m_bSessionNameGiven(false)
     105        , m_bCreateParentDirectories(false){}
    98106    QString m_strUserName;
    99107    QString m_strPassword;
    100108    QString m_strExePath;
    101109    QString m_strSessionName;
     110    QString m_strDirectoryPath;
    102111    ULONG   m_uSessionId;
    103112    QString m_strDomain;
    104113    bool    m_bSessionIdGiven;
    105114    bool    m_bSessionNameGiven;
     115    /* Create the whole path during mkdir */
     116    bool    m_bCreateParentDirectories;
    106117    QVector<QString> m_arguments;
    107118    QVector<QString> m_environmentChanges;
     
    121132                "createsession                      [common-options]  [--sessionname <name>]\n"
    122133                "mkdir                           [common-options]\n"
    123                 "                                   [--path <path>]\n"
     134                "                                   [-P|--parents] [<guest directory>\n"
    124135                "                                   [--sessionid <id> |  [sessionname <name>]]\n"
    125136                )
     
    128139}
    129140
    130 bool UIGuestControlInterface::handleMkdir(int, char**)
    131 {
     141bool UIGuestControlInterface::handleMkdir(int argc , char** argv)
     142{
     143
     144    CommandData commandData;
     145
     146    static const RTGETOPTDEF s_aOptions[] =
     147    {
     148        GCTLCMD_COMMON_OPTION_DEFS()
     149        { "--sessionname",                  GCTLCMD_COMMON_OPT_SESSION_NAME,          RTGETOPT_REQ_STRING  },
     150        { "--sessionid",                    GCTLCMD_COMMON_OPT_SESSION_ID,            RTGETOPT_REQ_UINT32  },
     151        { "--parents",                      'P',                                      RTGETOPT_REQ_NOTHING  }
     152    };
     153
     154    int ch;
     155    bool pathFound = false;
     156    RTGETOPTUNION ValueUnion;
     157    RTGETOPTSTATE GetState;
     158    RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1 /* ignore 0th element (command) */, 0);
     159    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
     160    {
     161        switch (ch)
     162        {
     163            HANDLE_COMMON_OPTION_DEFS()
     164            case GCTLCMD_COMMON_OPT_SESSION_NAME:
     165                commandData.m_bSessionNameGiven = true;
     166                commandData.m_strSessionName  = ValueUnion.psz;
     167                break;
     168            case GCTLCMD_COMMON_OPT_SESSION_ID:
     169                commandData.m_bSessionIdGiven = true;
     170                commandData.m_uSessionId  = ValueUnion.i32;
     171                break;
     172            case 'P':
     173                commandData.m_bCreateParentDirectories  = true;
     174                break;
     175            case VINF_GETOPT_NOT_OPTION:
     176                if (!pathFound)
     177                {
     178                    commandData.m_strDirectoryPath = ValueUnion.psz;
     179                    pathFound = true;
     180                }
     181                /* Allow only a single NOT_OPTION */
     182                else
     183                    RETURN_ERROR(generateErrorString(ch, ValueUnion))
     184
     185                break;
     186            default:
     187                RETURN_ERROR(generateErrorString(ch, ValueUnion))
     188        }
     189    }
     190    if (commandData.m_strDirectoryPath.isEmpty())
     191        RETURN_ERROR(QString(m_strHelp).append("Syntax error! No path is given\n"));
     192
     193    CGuestSession guestSession;
     194    if (!findOrCreateSession(commandData, guestSession) || !guestSession.isOk())
     195        return false;
     196
     197
     198    //const QString &strErr = comProgressInstall.GetErrorInfo().GetText();
     199    QVector<KDirectoryCreateFlag> creationFlags;
     200    if (commandData.m_bCreateParentDirectories)
     201        creationFlags.push_back(KDirectoryCreateFlag_None);
     202    else
     203        creationFlags.push_back(KDirectoryCreateFlag_Parents);
     204
     205    guestSession.DirectoryCreate(commandData.m_strDirectoryPath, 0 /*ULONG aMode*/, creationFlags);
     206
     207    //startProcess(commandData, guestSession);
    132208    return true;
    133209}
     
    149225
    150226    CommandData commandData;
    151     //parseCommonOptions(argc, argv, commandData);
    152227
    153228    static const RTGETOPTDEF s_aOptions[] =
     
    186261                break;
    187262            default:
    188             {
    189                 emit sigOutputString(generateErrorString(ch, ValueUnion));
    190                 return false;
    191             }
     263                RETURN_ERROR(generateErrorString(ch, ValueUnion))
    192264        }
    193265    }
    194266    if (commandData.m_strExePath.isEmpty())
    195     {
    196         emit sigOutputString(QString(m_strHelp).append("Syntax error! No executable is given\n"));
    197         return false;
    198     }
    199 
     267        RETURN_ERROR(QString(m_strHelp).append("Syntax error! No executable is given\n"))
     268
     269    CGuestSession guestSession;
     270    if (!findOrCreateSession(commandData, guestSession) || !guestSession.isOk())
     271        return false;
     272    startProcess(commandData, guestSession);
     273    return true;
     274}
     275
     276bool UIGuestControlInterface::findOrCreateSession(const CommandData &commandData, CGuestSession &outGuestSession)
     277{
    200278    if (commandData.m_bSessionNameGiven && commandData.m_strSessionName.isEmpty())
    201     {
    202         emit sigOutputString(QString(m_strHelp).append("'Session Name' is not name valid\n"));
    203         return false;
    204     }
    205 
    206     CGuestSession guestSession;
     279        RETURN_ERROR(QString(m_strHelp).append("'Session Name' is not name valid\n"))
     280
    207281    /* Check if sessionname and sessionid are both supplied */
    208282    if (commandData.m_bSessionIdGiven && commandData.m_bSessionNameGiven)
    209     {
    210         emit sigOutputString(QString(m_strHelp).append("Both 'Session Name' and 'Session Id' are supplied\n"));
    211         return false;
    212     }
     283        RETURN_ERROR(QString(m_strHelp).append("Both 'Session Name' and 'Session Id' are supplied\n"))
     284
    213285    /* If sessionid is given then look for the session. if not found return without starting the process: */
    214286    else if (commandData.m_bSessionIdGiven && !commandData.m_bSessionNameGiven)
    215287    {
    216         if (!findSession(commandData.m_uSessionId, guestSession))
    217         {
    218             emit sigOutputString(QString(m_strHelp).append("No session with id %1 found.\n").arg(commandData.m_uSessionId));
    219             return false;
     288        if (!findSession(commandData.m_uSessionId, outGuestSession))
     289        {
     290            RETURN_ERROR(QString(m_strHelp).append("No session with id %1 found.\n").arg(commandData.m_uSessionId))
    220291        }
    221292    }
     
    223294    else if (!commandData.m_bSessionIdGiven && commandData.m_bSessionNameGiven)
    224295    {
    225         if (!findSession(commandData.m_strSessionName, guestSession))
    226         {
    227             if (!createSession(commandData, guestSession))
    228             {
    229                 emit sigOutputString(QString("Guest session could not be created"));
     296        if (!findSession(commandData.m_strSessionName, outGuestSession))
     297        {
     298            if (!createSession(commandData, outGuestSession))
    230299                return false;
    231             }
    232300        }
    233301    }
     
    235303    else
    236304    {
    237         if (!createSession(commandData, guestSession))
    238         {
    239             emit sigOutputString(QString("Guest session could not be created"));
     305        if (!createSession(commandData, outGuestSession))
    240306            return false;
    241         }
    242 
    243     }
    244     if (!guestSession.isOk())
    245         return false;
    246     startProcess(commandData, guestSession);
     307    }
    247308    return true;
    248309}
     
    277338                if (commandData.m_strSessionName.isEmpty())
    278339                {
    279                     emit sigOutputString(QString("'Session Name' is not name valid\n").append(m_strHelp));
    280                     return false;
     340                    RETURN_ERROR(QString("'Session Name' is not name valid\n").append(m_strHelp))
    281341                }
    282342                break;
     
    325385    QByteArray array = strCommand.toLocal8Bit();
    326386    RTGetOptArgvFromString(&argv, &argc, array.data(), RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, 0);
    327 
     387    m_strStatus.clear();
    328388    static const RTGETOPTDEF s_aOptions[] =
    329389    {
     
    351411                         (this->*(iterator.value()))(argc, argv);
    352412                         RTGetOptArgvFree(argv);
     413                         if (!m_strStatus.isEmpty())
     414                             emit sigOutputString(m_strStatus);
    353415                         return;
    354416                     }
     
    365427                 break;
    366428         }
    367      }
     429    }
     430    if (!m_strStatus.isEmpty())
     431        emit sigOutputString(m_strStatus);
    368432
    369433    RTGetOptArgvFree(argv);
     
    406470                                                          commandData.m_strDomain,
    407471                                                          commandData.m_strSessionName);
     472
    408473    if (!guestSession.isOk())
    409     {
    410         emit sigOutputString(QString("Guest session could not be created"));
    411         return false;
    412     }
     474        return false;
     475
    413476    /* Wait session to start: */
    414477    const ULONG waitTimeout = 2000;
    415478    KGuestSessionWaitResult waitResult = guestSession.WaitFor(KGuestSessionWaitForFlag_Start, waitTimeout);
    416479    if (waitResult != KGuestSessionWaitResult_Start)
    417     {
    418         emit sigOutputString("Guest Session has not started yet");
    419         return false;
    420     }
     480        return false;
     481
    421482    outSession = guestSession;
    422483    return true;
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/information/guestctrl/UIGuestControlInterface.h

    r71067 r71089  
    5656    typedef bool (UIGuestControlInterface::*HandleFuncPtr)(int, char**);
    5757
     58    /** findOrCreateSession parses command options and determines if an existing session
     59        to be returned or a new one to be created */
     60    bool findOrCreateSession(const CommandData &commandData, CGuestSession &guestSession);
    5861    bool findSession(const QString& strSessionName, CGuestSession& outSession);
    5962    bool findSession(ULONG strSessionId, CGuestSession& outSession);
     
    6265    void prepareSubCommandHandlers();
    6366    bool startProcess(const CommandData &commandData, CGuestSession &guestSession);
     67    bool createDirectory(const CommandData &commandData, CGuestSession &guestSession);
    6468
    6569    /* Handles the 'start' process command */
     
    7478    CGuest        m_comGuest;
    7579    const QString m_strHelp;
     80    QString  m_strStatus;
    7681    /* A map of function pointers to handleXXXX functions */
    7782    QMap<QString, HandleFuncPtr> m_subCommandHandlers;
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/information/guestctrl/UIGuestControlTreeItem.cpp

    r71059 r71089  
    2828# include "CGuest.h"
    2929# include "CEventSource.h"
     30# include "CGuestProcessStateChangedEvent.h"
     31# include "CGuestSessionStateChangedEvent.h"
    3032#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    3133
     
    250252}
    251253
    252 void UIGuestSessionTreeItem::sltGuestSessionUpdated()
    253 {
     254void UIGuestSessionTreeItem::sltGuestSessionUpdated(const CGuestSessionStateChangedEvent& cEvent)
     255{
     256    if (cEvent.isOk() && m_comGuestSession.isOk() && m_comGuestSession.GetStatus() == KGuestSessionStatus_Error)
     257    {
     258        CVirtualBoxErrorInfo cErrorInfo = cEvent.GetError();
     259        if (cErrorInfo.isOk() && cErrorInfo.GetResultCode() != S_OK)
     260        {
     261            emit sigGuestSessionErrorText(cErrorInfo.GetText());
     262        }
     263    }
    254264    setColumnText();
    255265    emit sigGuessSessionUpdated();
     
    271281        << QString("Process Status: %1").arg(processStatusString(guestProcess.GetStatus()));
    272282
    273     /*UIGuestProcessTreeItem *newItem = */new UIGuestProcessTreeItem(this, guestProcess, strList);
     283    UIGuestProcessTreeItem *newItem = new UIGuestProcessTreeItem(this, guestProcess, strList);
     284    connect(newItem, &UIGuestProcessTreeItem::sigGuestProcessErrorText,
     285            this, &UIGuestSessionTreeItem::sigGuestSessionErrorText);
     286}
     287
     288void UIGuestSessionTreeItem::errorString(QString strError)
     289{
     290    emit sigGuestSessionErrorText(strError);
    274291}
    275292
     
    342359}
    343360
    344 void UIGuestProcessTreeItem::sltGuestProcessUpdated()
    345 {
     361void UIGuestProcessTreeItem::sltGuestProcessUpdated(const CGuestProcessStateChangedEvent &cEvent)
     362{
     363    if (cEvent.isOk() && m_comGuestProcess.isOk() && m_comGuestProcess.GetStatus() == KProcessStatus_Error)
     364    {
     365        CVirtualBoxErrorInfo cErrorInfo = cEvent.GetError();
     366        if (cErrorInfo.isOk() && cErrorInfo.GetResultCode() != S_OK)
     367        {
     368            /* For some reason I am yet to find this emit is not working.
     369               Thus we are calling the parent's function directly: */
     370            //emit sigGuestProcessErrorText(cErrorInfo.GetText());
     371            UIGuestSessionTreeItem *sessionParent = dynamic_cast<UIGuestSessionTreeItem*>(QTreeWidgetItem::parent());
     372            if (sessionParent)
     373            {
     374                sessionParent->errorString(cErrorInfo.GetText().toStdString().c_str());
     375            }
     376        }
     377    }
    346378    setColumnText();
    347379}
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/information/guestctrl/UIGuestControlTreeItem.h

    r71065 r71089  
    2929/* Forward declarations: */
    3030class CEventSource;
     31class CGuestProcessStateChangedEvent;
     32class CGuestSessionStateChangedEvent;
    3133
    3234/** QITreeWidgetItem extension serving as a base class
     
    3739    Q_OBJECT;
    3840
    39 signals:
    40 
    41     void sigGuessSessionUpdated();
    42 
    4341public:
    44 
    4542
    4643    UIGuestControlTreeItem(QITreeWidget *pTreeWidget, const QStringList &strings = QStringList());
     
    7673    Q_OBJECT;
    7774
     75signals:
     76
     77    void sigGuessSessionUpdated();
     78    void sigGuestSessionErrorText(QString strError);
     79
    7880public:
    7981
     
    8284    virtual ~UIGuestSessionTreeItem();
    8385    const CGuestSession& guestSession() const;
     86    void errorString(QString strError);
    8487
    8588protected:
     
    9093private slots:
    9194
    92     void sltGuestSessionUpdated();
     95    void sltGuestSessionUpdated(const CGuestSessionStateChangedEvent& cEvent);
    9396    void sltGuestProcessRegistered(CGuestProcess guestProcess);
    9497    void sltGuestProcessUnregistered(CGuestProcess guestProcess);
     98
    9599
    96100private:
     
    112116    Q_OBJECT;
    113117
     118signals:
     119
     120    void sigGuestProcessErrorText(QString strError);
     121
    114122public:
    115123
     
    127135private slots:
    128136
    129     void sltGuestProcessUpdated();
     137    void sltGuestProcessUpdated(const CGuestProcessStateChangedEvent &cEvent);
    130138
    131139private:
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/information/guestctrl/UIInformationGuestSession.cpp

    r71059 r71089  
    378378    connect(sessionTreeItem, &UIGuestSessionTreeItem::sigGuessSessionUpdated,
    379379            this, &UIInformationGuestSession::sltTreeItemUpdated);
     380    connect(sessionTreeItem, &UIGuestSessionTreeItem::sigGuestSessionErrorText,
     381            this, &UIInformationGuestSession::sltGuestControlErrorText);
     382}
     383
     384void UIInformationGuestSession::sltGuestControlErrorText(QString strError)
     385{
     386    if (m_pConsole)
     387    {
     388        m_pConsole->putOutput(strError);
     389    }
    380390}
    381391
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/information/guestctrl/UIInformationGuestSession.h

    r71059 r71089  
    5757    void sltGuestSessionRegistered(CGuestSession guestSession);
    5858    void sltGuestSessionUnregistered(CGuestSession guestSession);
     59    void sltGuestControlErrorText(QString strError);
    5960
    6061    void sltTreeItemUpdated();
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette