VirtualBox

Changeset 71937 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Apr 20, 2018 12:08:03 PM (7 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:9049: Full and huge cleanup for UIPortForwardingTable classes and move them to VBoxGlobal library.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r71924 r71937  
    558558        src/widgets/UIEmptyFilePathSelector.h \
    559559        src/widgets/UILineTextEdit.h \
    560         src/widgets/UIPortForwardingTable.h \
    561560        src/widgets/UISlidingWidget.h \
    562561        src/widgets/UITabBar.h \
     
    693692        src/widgets/UIPopupStack.h \
    694693        src/widgets/UIPopupStackViewport.h \
     694        src/widgets/UIPortForwardingTable.h \
    695695        src/widgets/UIProgressDialog.h \
    696696        src/widgets/UISpecialControls.h \
     
    788788        src/widgets/UIPopupStack.h \
    789789        src/widgets/UIPopupStackViewport.h \
     790        src/widgets/UIPortForwardingTable.h \
    790791        src/widgets/UIProgressDialog.h \
    791792        src/widgets/UISpecialControls.h \
     
    840841        src/widgets/UIMenuToolBar.cpp \
    841842        src/widgets/UIMiniToolBar.cpp \
    842         src/widgets/UIPortForwardingTable.cpp \
    843843        src/widgets/UITabBar.cpp \
    844844        src/wizards/importappliance/UIWizardImportApp.cpp
     
    862862        src/widgets/UIFilmContainer.cpp \
    863863        src/widgets/UIHotKeyEditor.cpp \
     864        src/widgets/UIPortForwardingTable.cpp \
    864865        src/widgets/UIProgressDialog.cpp
    865866
     
    902903        src/widgets/UIFilmContainer.cpp \
    903904        src/widgets/UIHotKeyEditor.cpp \
     905        src/widgets/UIPortForwardingTable.cpp \
    904906        src/widgets/UIProgressDialog.cpp
    905907
     
    10511053        src/widgets/UIEmptyFilePathSelector.cpp \
    10521054        src/widgets/UILineTextEdit.cpp \
    1053         src/widgets/UIPortForwardingTable.cpp \
    10541055        src/widgets/UISlidingWidget.cpp \
    10551056        src/widgets/UITabBar.cpp \
     
    12261227        src/widgets/UIPopupStack.cpp \
    12271228        src/widgets/UIPopupStackViewport.cpp \
     1229        src/widgets/UIPortForwardingTable.cpp \
    12281230        src/widgets/UIProgressDialog.cpp \
    12291231        src/widgets/UISpecialControls.cpp \
     
    13471349        src/widgets/UIPopupStack.cpp \
    13481350        src/widgets/UIPopupStackViewport.cpp \
     1351        src/widgets/UIPortForwardingTable.cpp \
    13491352        src/widgets/UIProgressDialog.cpp \
    13501353        src/widgets/UISpecialControls.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIPortForwardingTable.cpp

    r71027 r71937  
    55
    66/*
    7  * Copyright (C) 2010-2017 Oracle Corporation
     7 * Copyright (C) 2010-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2121
    2222/* Qt includes: */
     23# include <QAction>
     24# include <QComboBox>
    2325# include <QHBoxLayout>
     26# include <QHeaderView>
     27# include <QItemEditorFactory>
     28# include <QLineEdit>
    2429# include <QMenu>
    25 # include <QAction>
    26 # include <QHeaderView>
     30# include <QSpinBox>
    2731# include <QStyledItemDelegate>
    28 # include <QItemEditorFactory>
    29 # include <QComboBox>
    30 # include <QLineEdit>
    31 # include <QSpinBox>
    3232
    3333/* GUI includes: */
     34# include "QITableView.h"
    3435# include "UIDesktopWidgetWatchdog.h"
    35 # include "UIPortForwardingTable.h"
    36 # include "UIMessageCenter.h"
    3736# include "UIConverter.h"
    3837# include "UIIconPool.h"
     38# include "UIMessageCenter.h"
     39# include "UIPortForwardingTable.h"
    3940# include "UIToolBar.h"
    40 # include "QITableView.h"
    4141
    4242/* Other VBox includes: */
     
    4747/* External includes: */
    4848#include <math.h>
    49 
    50 
    51 #if 0 /* Decided to not use it for now. */
    52 /* IPv4 validator: */
    53 class IPv4Validator : public QValidator
    54 {
    55     Q_OBJECT;
    56 
    57 public:
    58 
    59     /* Constructor/destructor: */
    60     IPv4Validator(QObject *pParent) : QValidator(pParent) {}
    61     ~IPv4Validator() {}
    62 
    63     /* Handler: Validation stuff: */
    64     QValidator::State validate(QString &strInput, int& /*iPos*/) const
    65     {
    66         QString strStringToValidate(strInput);
    67         strStringToValidate.remove(' ');
    68         QString strDot("\\.");
    69         QString strDigits("(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)");
    70         QRegExp intRegExp(QString("^(%1?(%2(%1?(%2(%1?(%2%1?)?)?)?)?)?)?$").arg(strDigits).arg(strDot));
    71         RTNETADDRIPV4 Network, Mask;
    72         if (strStringToValidate == "..." || RTCidrStrToIPv4(strStringToValidate.toLatin1().constData(), &Network, &Mask) == VINF_SUCCESS)
    73             return QValidator::Acceptable;
    74         else if (intRegExp.indexIn(strStringToValidate) != -1)
    75             return QValidator::Intermediate;
    76         else
    77             return QValidator::Invalid;
    78     }
    79 };
    80 
    81 /* IPv6 validator: */
    82 class IPv6Validator : public QValidator
    83 {
    84     Q_OBJECT;
    85 
    86 public:
    87 
    88     /* Constructor/destructor: */
    89     IPv6Validator(QObject *pParent) : QValidator(pParent) {}
    90     ~IPv6Validator() {}
    91 
    92     /* Handler: Validation stuff: */
    93     QValidator::State validate(QString &strInput, int& /*iPos*/) const
    94     {
    95         QString strStringToValidate(strInput);
    96         strStringToValidate.remove(' ');
    97         QString strDigits("([0-9a-fA-F]{0,4})");
    98         QRegExp intRegExp(QString("^%1(:%1(:%1(:%1(:%1(:%1(:%1(:%1)?)?)?)?)?)?)?$").arg(strDigits));
    99         if (intRegExp.indexIn(strStringToValidate) != -1)
    100             return QValidator::Acceptable;
    101         else
    102             return QValidator::Invalid;
    103     }
    104 };
    105 #endif /* Decided to not use it for now. */
    10649
    10750
     
    11962
    12063
    121 /* Name editor: */
     64/** QLineEdit extension used as name editor. */
    12265class NameEditor : public QLineEdit
    12366{
     
    12770public:
    12871
    129     /* Constructor: */
     72    /** Constructs name editor passing @a pParent to the base-class. */
    13073    NameEditor(QWidget *pParent = 0) : QLineEdit(pParent)
    13174    {
     
    13780private:
    13881
    139     /* API: Name stuff: */
    140     void setName(NameData name)
    141     {
    142         setText(name);
    143     }
    144 
    145     /* API: Name stuff: */
     82    /** Defines the @a strName. */
     83    void setName(NameData strName)
     84    {
     85        setText(strName);
     86    }
     87
     88    /** Returns the name. */
    14689    NameData name() const
    14790    {
     
    15194
    15295
    153 /* Protocol editor: */
     96/** QComboBox extension used as protocol editor. */
    15497class ProtocolEditor : public QComboBox
    15598{
     
    159102public:
    160103
    161     /* Constructor: */
     104    /** Constructs protocol editor passing @a pParent to the base-class. */
    162105    ProtocolEditor(QWidget *pParent = 0) : QComboBox(pParent)
    163106    {
     
    168111private:
    169112
    170     /* API: Protocol stuff: */
    171     void setProtocol(KNATProtocol p)
     113    /** Defines the @a enmProtocol. */
     114    void setProtocol(KNATProtocol enmProtocol)
    172115    {
    173116        for (int i = 0; i < count(); ++i)
    174117        {
    175             if (itemData(i).value<KNATProtocol>() == p)
     118            if (itemData(i).value<KNATProtocol>() == enmProtocol)
    176119            {
    177120                setCurrentIndex(i);
     
    181124    }
    182125
    183     /* API: Protocol stuff: */
     126    /** Returns the protocol. */
    184127    KNATProtocol protocol() const
    185128    {
     
    189132
    190133
    191 /* IPv4 editor: */
     134/** QLineEdit extension used as IPv4 editor. */
    192135class IPv4Editor : public QLineEdit
    193136{
     
    197140public:
    198141
    199     /* Constructor: */
     142    /** Constructs IPv4-editor passing @a pParent to the base-class. */
    200143    IPv4Editor(QWidget *pParent = 0) : QLineEdit(pParent)
    201144    {
     
    208151private:
    209152
    210     /* API: IP stuff: */
    211     void setIp(IpData ip)
    212     {
    213         setText(ip);
    214     }
    215 
    216     /* API: IP stuff: */
     153    /** Defines the @a strIp. */
     154    void setIp(IpData strIp)
     155    {
     156        setText(strIp);
     157    }
     158
     159    /** Returns the ip. */
    217160    IpData ip() const
    218161    {
     
    222165
    223166
    224 /* IPv6 editor: */
     167/** QLineEdit extension used as IPv6 editor. */
    225168class IPv6Editor : public QLineEdit
    226169{
     
    230173public:
    231174
    232     /* Constructor: */
     175    /** Constructs IPv6-editor passing @a pParent to the base-class. */
    233176    IPv6Editor(QWidget *pParent = 0) : QLineEdit(pParent)
    234177    {
     
    241184private:
    242185
    243     /* API: IP stuff: */
    244     void setIp(IpData ip)
    245     {
    246         setText(ip);
    247     }
    248 
    249     /* API: IP stuff: */
     186    /** Defines the @a strIp. */
     187    void setIp(IpData strIp)
     188    {
     189        setText(strIp);
     190    }
     191
     192    /** Returns the ip. */
    250193    IpData ip() const
    251194    {
     
    255198
    256199
    257 /* Port editor: */
     200/** QSpinBox extension used as Port editor. */
    258201class PortEditor : public QSpinBox
    259202{
     
    263206public:
    264207
    265     /* Constructor: */
     208    /** Constructs Port-editor passing @a pParent to the base-class. */
    266209    PortEditor(QWidget *pParent = 0) : QSpinBox(pParent)
    267210    {
     
    272215private:
    273216
    274     /* API: Port stuff: */
     217    /** Defines the @a port. */
    275218    void setPort(PortData port)
    276219    {
     
    278221    }
    279222
    280     /* API: Port stuff: */
     223    /** Returns the port. */
    281224    PortData port() const
    282225    {
     
    309252    /** Constructs table cell passing @a pParent to the base-class.
    310253      * @param  strIp  Brings the IP address. */
    311     UIPortForwardingCell(QITableViewRow *pParent, const IpData &strIP)
     254    UIPortForwardingCell(QITableViewRow *pParent, const IpData &strIp)
    312255        : QITableViewCell(pParent)
    313         , m_strText(strIP)
     256        , m_strText(strIp)
    314257    {}
    315258
    316259    /** Constructs table cell passing @a pParent to the base-class.
    317       * @param  uHostPort  Brings the port. */
    318     UIPortForwardingCell(QITableViewRow *pParent, PortData uPort)
     260      * @param  port  Brings the port. */
     261    UIPortForwardingCell(QITableViewRow *pParent, PortData port)
    319262        : QITableViewCell(pParent)
    320         , m_strText(QString::number(uPort.value()))
     263        , m_strText(QString::number(port.value()))
    321264    {}
    322265
     
    327270
    328271    /** Holds the cell text. */
    329     QString m_strText;
     272    QString  m_strText;
    330273};
    331274
     
    342285      * @param  enmProtocol  Brings the rule protocol type.
    343286      * @param  strHostIp    Brings the rule host IP address.
    344       * @param  uHostPort    Brings the rule host port.
     287      * @param  hostPort     Brings the rule host port.
    345288      * @param  strGuestIp   Brings the rule guest IP address.
    346       * @param  uGuestPort   Brings the rule guest port. */
     289      * @param  guestPort    Brings the rule guest port. */
    347290    UIPortForwardingRow(QITableView *pParent,
    348291                        const NameData &strName, KNATProtocol enmProtocol,
    349                         const IpData &strHostIp, PortData uHostPort,
    350                         const IpData &strGuestIp, PortData uGuestPort)
     292                        const IpData &strHostIp, PortData hostPort,
     293                        const IpData &strGuestIp, PortData guestPort)
    351294        : QITableViewRow(pParent)
    352295        , m_strName(strName), m_enmProtocol(enmProtocol)
    353         , m_strHostIp(strHostIp), m_uHostPort(uHostPort)
    354         , m_strGuestIp(strGuestIp), m_uGuestPort(uGuestPort)
     296        , m_strHostIp(strHostIp), m_hostPort(hostPort)
     297        , m_strGuestIp(strGuestIp), m_guestPort(guestPort)
    355298    {
    356299        /* Create cells: */
     
    396339
    397340    /** Returns the rule host port. */
    398     PortData hostPort() const { return m_uHostPort; }
     341    PortData hostPort() const { return m_hostPort; }
    399342    /** Defines the rule host port. */
    400     void setHostPort(PortData uHostPort)
    401     {
    402         m_uHostPort = uHostPort;
     343    void setHostPort(PortData hostPort)
     344    {
     345        m_hostPort = hostPort;
    403346        delete m_cells[UIPortForwardingDataType_HostPort];
    404         m_cells[UIPortForwardingDataType_HostPort] = new UIPortForwardingCell(this, m_uHostPort);
     347        m_cells[UIPortForwardingDataType_HostPort] = new UIPortForwardingCell(this, m_hostPort);
    405348    }
    406349
     
    416359
    417360    /** Returns the rule guest port. */
    418     PortData guestPort() const { return m_uGuestPort; }
     361    PortData guestPort() const { return m_guestPort; }
    419362    /** Defines the rule guest port. */
    420     void setGuestPort(PortData uGuestPort)
    421     {
    422         m_uGuestPort = uGuestPort;
     363    void setGuestPort(PortData guestPort)
     364    {
     365        m_guestPort = guestPort;
    423366        delete m_cells[UIPortForwardingDataType_GuestPort];
    424         m_cells[UIPortForwardingDataType_GuestPort] = new UIPortForwardingCell(this, m_uGuestPort);
     367        m_cells[UIPortForwardingDataType_GuestPort] = new UIPortForwardingCell(this, m_guestPort);
    425368    }
    426369
     
    453396        m_cells[UIPortForwardingDataType_Protocol] = new UIPortForwardingCell(this, m_enmProtocol);
    454397        m_cells[UIPortForwardingDataType_HostIp] = new UIPortForwardingCell(this, m_strHostIp);
    455         m_cells[UIPortForwardingDataType_HostPort] = new UIPortForwardingCell(this, m_uHostPort);
     398        m_cells[UIPortForwardingDataType_HostPort] = new UIPortForwardingCell(this, m_hostPort);
    456399        m_cells[UIPortForwardingDataType_GuestIp] = new UIPortForwardingCell(this, m_strGuestIp);
    457         m_cells[UIPortForwardingDataType_GuestPort] = new UIPortForwardingCell(this, m_uGuestPort);
     400        m_cells[UIPortForwardingDataType_GuestPort] = new UIPortForwardingCell(this, m_guestPort);
    458401    }
    459402
     
    473416    IpData m_strHostIp;
    474417    /** Holds the rule host port. */
    475     PortData m_uHostPort;
     418    PortData m_hostPort;
    476419    /** Holds the rule guest IP address. */
    477420    IpData m_strGuestIp;
    478421    /** Holds the rule guest port. */
    479     PortData m_uGuestPort;
     422    PortData m_guestPort;
    480423
    481424    /** Holds the cell instances. */
     
    484427
    485428
    486 /* Port forwarding data model: */
     429/** QAbstractTableModel subclass used as port forwarding data model. */
    487430class UIPortForwardingModel : public QAbstractTableModel
    488431{
     
    502445    QITableViewRow *childItem(int iIndex) const;
    503446
    504     /* API: Rule stuff: */
     447    /** Returns the list of port forwarding rules. */
    505448    const UIPortForwardingDataList rules() const;
     449    /** Adds empty port forwarding rule for certain @a index. */
    506450    void addRule(const QModelIndex &index);
    507     void delRule(const QModelIndex &index);
    508 
    509     /* API: Index flag stuff: */
     451    /** Removes port forwarding rule with certain @a index. */
     452    void removeRule(const QModelIndex &index);
     453
     454    /** Returns flags for item with certain @a index. */
    510455    Qt::ItemFlags flags(const QModelIndex &index) const;
    511456
    512     /* API: Index row-count stuff: */
     457    /** Returns row count of certain @a parent. */
    513458    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    514459
    515     /* API: Index column-count stuff: */
     460    /** Returns column count of certain @a parent. */
    516461    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    517462
    518     /* API: Header data stuff: */
    519     QVariant headerData(int iSection, Qt::Orientation orientation, int iRole) const;
    520 
    521     /* API: Index data stuff: */
     463    /** Returns header data.
     464      * @param  iSection        Brings the number of section we aquire data for.
     465      * @param  enmOrientation  Brings the orientation of header we aquire data for.
     466      * @param  iRole           Brings the role we aquire data for. */
     467    QVariant headerData(int iSection, Qt::Orientation enmOrientation, int iRole) const;
     468
     469    /** Defines the @a iRole data for item with @a index as @a value. */
     470    bool setData(const QModelIndex &index, const QVariant &value, int iRole = Qt::EditRole);
     471    /** Returns the @a iRole data for item with @a index. */
    522472    QVariant data(const QModelIndex &index, int iRole) const;
    523     bool setData(const QModelIndex &index, const QVariant &value, int iRole = Qt::EditRole);
    524473
    525474private:
     
    528477    QITableView *parentTable() const;
    529478
    530     /* Variable: Data stuff: */
     479    /** Holds the port forwarding row list. */
    531480    QList<UIPortForwardingRow*> m_dataList;
    532481};
     
    556505*********************************************************************************************************************************/
    557506
    558 UIPortForwardingModel::UIPortForwardingModel(QITableView *pParent, const UIPortForwardingDataList &rules /* = UIPortForwardingDataList() */)
     507UIPortForwardingModel::UIPortForwardingModel(QITableView *pParent,
     508                                             const UIPortForwardingDataList &rules /* = UIPortForwardingDataList() */)
    559509    : QAbstractTableModel(pParent)
    560510{
     
    623573}
    624574
    625 void UIPortForwardingModel::delRule(const QModelIndex &index)
     575void UIPortForwardingModel::removeRule(const QModelIndex &index)
    626576{
    627577    if (!index.isValid())
     
    642592}
    643593
    644 int UIPortForwardingModel::rowCount(const QModelIndex&) const
     594int UIPortForwardingModel::rowCount(const QModelIndex &) const
    645595{
    646596    return m_dataList.size();
    647597}
    648598
    649 int UIPortForwardingModel::columnCount(const QModelIndex&) const
     599int UIPortForwardingModel::columnCount(const QModelIndex &) const
    650600{
    651601    return UIPortForwardingDataType_Max;
    652602}
    653603
    654 QVariant UIPortForwardingModel::headerData(int iSection, Qt::Orientation orientation, int iRole) const
     604QVariant UIPortForwardingModel::headerData(int iSection, Qt::Orientation enmOrientation, int iRole) const
    655605{
    656606    /* Display role for horizontal header: */
    657     if (iRole == Qt::DisplayRole && orientation == Qt::Horizontal)
     607    if (iRole == Qt::DisplayRole && enmOrientation == Qt::Horizontal)
    658608    {
    659609        /* Switch for different columns: */
     
    671621    /* Return wrong value: */
    672622    return QVariant();
     623}
     624
     625bool UIPortForwardingModel::setData(const QModelIndex &index, const QVariant &value, int iRole /* = Qt::EditRole */)
     626{
     627    /* Check index validness: */
     628    if (!index.isValid() || iRole != Qt::EditRole)
     629        return false;
     630    /* Switch for different columns: */
     631    switch (index.column())
     632    {
     633        case UIPortForwardingDataType_Name:
     634            m_dataList[index.row()]->setName(value.value<NameData>());
     635            emit dataChanged(index, index);
     636            return true;
     637        case UIPortForwardingDataType_Protocol:
     638            m_dataList[index.row()]->setProtocol(value.value<KNATProtocol>());
     639            emit dataChanged(index, index);
     640            return true;
     641        case UIPortForwardingDataType_HostIp:
     642            m_dataList[index.row()]->setHostIp(value.value<IpData>());
     643            emit dataChanged(index, index);
     644            return true;
     645        case UIPortForwardingDataType_HostPort:
     646            m_dataList[index.row()]->setHostPort(value.value<PortData>());
     647            emit dataChanged(index, index);
     648            return true;
     649        case UIPortForwardingDataType_GuestIp:
     650            m_dataList[index.row()]->setGuestIp(value.value<IpData>());
     651            emit dataChanged(index, index);
     652            return true;
     653        case UIPortForwardingDataType_GuestPort:
     654            m_dataList[index.row()]->setGuestPort(value.value<PortData>());
     655            emit dataChanged(index, index);
     656            return true;
     657        default: return false;
     658    }
     659    /* not reached! */
    673660}
    674661
     
    745732}
    746733
    747 bool UIPortForwardingModel::setData(const QModelIndex &index, const QVariant &value, int iRole /* = Qt::EditRole */)
    748 {
    749     /* Check index validness: */
    750     if (!index.isValid() || iRole != Qt::EditRole)
    751         return false;
    752     /* Switch for different columns: */
    753     switch (index.column())
    754     {
    755         case UIPortForwardingDataType_Name:
    756             m_dataList[index.row()]->setName(value.value<NameData>());
    757             emit dataChanged(index, index);
    758             return true;
    759         case UIPortForwardingDataType_Protocol:
    760             m_dataList[index.row()]->setProtocol(value.value<KNATProtocol>());
    761             emit dataChanged(index, index);
    762             return true;
    763         case UIPortForwardingDataType_HostIp:
    764             m_dataList[index.row()]->setHostIp(value.value<IpData>());
    765             emit dataChanged(index, index);
    766             return true;
    767         case UIPortForwardingDataType_HostPort:
    768             m_dataList[index.row()]->setHostPort(value.value<PortData>());
    769             emit dataChanged(index, index);
    770             return true;
    771         case UIPortForwardingDataType_GuestIp:
    772             m_dataList[index.row()]->setGuestIp(value.value<IpData>());
    773             emit dataChanged(index, index);
    774             return true;
    775         case UIPortForwardingDataType_GuestPort:
    776             m_dataList[index.row()]->setGuestPort(value.value<PortData>());
    777             emit dataChanged(index, index);
    778             return true;
    779         default: return false;
    780     }
    781     /* not reached! */
    782 }
    783 
    784734QITableView *UIPortForwardingModel::parentTable() const
    785735{
     
    810760
    811761UIPortForwardingTable::UIPortForwardingTable(const UIPortForwardingDataList &rules, bool fIPv6, bool fAllowEmptyGuestIPs)
    812     : m_fAllowEmptyGuestIPs(fAllowEmptyGuestIPs)
    813     , m_fIsTableDataChanged(false)
     762    : m_rules(rules)
     763    , m_fIPv6(fIPv6)
     764    , m_fAllowEmptyGuestIPs(fAllowEmptyGuestIPs)
     765    , m_fTableDataChanged(false)
     766    , m_pLayout(0)
    814767    , m_pTableView(0)
    815768    , m_pToolBar(0)
    816     , m_pModel(0)
    817     , m_pAddAction(0)
    818     , m_pCopyAction(0)
    819     , m_pDelAction(0)
    820 {
    821     /* Create layout: */
    822     QHBoxLayout *pMainLayout = new QHBoxLayout(this);
    823     {
    824         /* Configure layout: */
    825 #ifdef VBOX_WS_MAC
    826         /* On macOS we can do a bit of smoothness: */
    827         pMainLayout->setContentsMargins(0, 0, 0, 0);
    828         pMainLayout->setSpacing(3);
    829 #else
    830         pMainLayout->setSpacing(qApp->style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing) / 3);
    831 #endif
    832         /* Create table: */
    833         m_pTableView = new UIPortForwardingView;
    834         {
    835             /* Configure table: */
    836             m_pTableView->setTabKeyNavigation(false);
    837             m_pTableView->verticalHeader()->hide();
    838             m_pTableView->verticalHeader()->setDefaultSectionSize((int)(m_pTableView->verticalHeader()->minimumSectionSize() * 1.33));
    839             m_pTableView->setSelectionMode(QAbstractItemView::SingleSelection);
    840             m_pTableView->setContextMenuPolicy(Qt::CustomContextMenu);
    841             m_pTableView->installEventFilter(this);
    842         }
    843         /* Create model: */
    844         m_pModel = new UIPortForwardingModel(m_pTableView, rules);
    845         {
    846             /* Configure model: */
    847             connect(m_pModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(sltTableDataChanged()));
    848             connect(m_pModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), this, SLOT(sltTableDataChanged()));
    849             connect(m_pModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), this, SLOT(sltTableDataChanged()));
    850             /* Configure table (after model is configured): */
    851             m_pTableView->setModel(m_pModel);
    852             connect(m_pTableView, SIGNAL(sigCurrentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(sltCurrentChanged()));
    853             connect(m_pTableView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(sltShowTableContexMenu(const QPoint &)));
    854         }
    855         /* Create toolbar: */
    856         m_pToolBar = new UIToolBar;
    857         {
    858             /* Determine icon metric: */
    859             const QStyle *pStyle = QApplication::style();
    860             const int iIconMetric = pStyle->pixelMetric(QStyle::PM_SmallIconSize);
    861             /* Configure toolbar: */
    862             m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric));
    863             m_pToolBar->setOrientation(Qt::Vertical);
    864             /* Create 'add' action: */
    865             m_pAddAction = new QAction(this);
    866             {
    867                 /* Configure 'add' action: */
    868                 m_pAddAction->setShortcut(QKeySequence("Ins"));
    869                 m_pAddAction->setIcon(UIIconPool::iconSet(":/controller_add_16px.png", ":/controller_add_disabled_16px.png"));
    870                 connect(m_pAddAction, SIGNAL(triggered(bool)), this, SLOT(sltAddRule()));
    871                 m_pToolBar->addAction(m_pAddAction);
    872             }
    873             /* Create 'copy' action: */
    874             m_pCopyAction = new QAction(this);
    875             {
    876                 /* Configure 'add' action: */
    877                 m_pCopyAction->setIcon(UIIconPool::iconSet(":/controller_add_16px.png", ":/controller_add_disabled_16px.png"));
    878                 connect(m_pCopyAction, SIGNAL(triggered(bool)), this, SLOT(sltCopyRule()));
    879             }
    880             /* Create 'del' action: */
    881             m_pDelAction = new QAction(this);
    882             {
    883                 /* Configure 'del' action: */
    884                 m_pDelAction->setShortcut(QKeySequence("Del"));
    885                 m_pDelAction->setIcon(UIIconPool::iconSet(":/controller_remove_16px.png", ":/controller_remove_disabled_16px.png"));
    886                 connect(m_pDelAction, SIGNAL(triggered(bool)), this, SLOT(sltDelRule()));
    887                 m_pToolBar->addAction(m_pDelAction);
    888             }
    889         }
    890         /* Add widgets into layout: */
    891         pMainLayout->addWidget(m_pTableView);
    892         pMainLayout->addWidget(m_pToolBar);
    893     }
    894 
    895     /* We do have abstract item delegate: */
    896     QAbstractItemDelegate *pAbstractItemDelegate = m_pTableView->itemDelegate();
    897     if (pAbstractItemDelegate)
    898     {
    899         /* But do we have styled item delegate? */
    900         QStyledItemDelegate *pStyledItemDelegate = qobject_cast<QStyledItemDelegate*>(pAbstractItemDelegate);
    901         if (pStyledItemDelegate)
    902         {
    903             /* Create new item editor factory: */
    904             QItemEditorFactory *pNewItemEditorFactory = new QItemEditorFactory;
    905             {
    906                 /* Register NameEditor as the NameData editor: */
    907                 int iNameId = qRegisterMetaType<NameData>();
    908                 QStandardItemEditorCreator<NameEditor> *pNameEditorItemCreator = new QStandardItemEditorCreator<NameEditor>();
    909                 pNewItemEditorFactory->registerEditor((QVariant::Type)iNameId, pNameEditorItemCreator);
    910 
    911                 /* Register ProtocolEditor as the KNATProtocol editor: */
    912                 int iProtocolId = qRegisterMetaType<KNATProtocol>();
    913                 QStandardItemEditorCreator<ProtocolEditor> *pProtocolEditorItemCreator = new QStandardItemEditorCreator<ProtocolEditor>();
    914                 pNewItemEditorFactory->registerEditor((QVariant::Type)iProtocolId, pProtocolEditorItemCreator);
    915 
    916                 /* Register IPv4Editor/IPv6Editor as the IpData editor: */
    917                 int iIpId = qRegisterMetaType<IpData>();
    918                 if (!fIPv6)
    919                 {
    920                     QStandardItemEditorCreator<IPv4Editor> *pIPv4EditorItemCreator = new QStandardItemEditorCreator<IPv4Editor>();
    921                     pNewItemEditorFactory->registerEditor((QVariant::Type)iIpId, pIPv4EditorItemCreator);
    922                 }
    923                 else
    924                 {
    925                     QStandardItemEditorCreator<IPv6Editor> *pIPv6EditorItemCreator = new QStandardItemEditorCreator<IPv6Editor>();
    926                     pNewItemEditorFactory->registerEditor((QVariant::Type)iIpId, pIPv6EditorItemCreator);
    927                 }
    928 
    929                 /* Register PortEditor as the PortData editor: */
    930                 int iPortId = qRegisterMetaType<PortData>();
    931                 QStandardItemEditorCreator<PortEditor> *pPortEditorItemCreator = new QStandardItemEditorCreator<PortEditor>();
    932                 pNewItemEditorFactory->registerEditor((QVariant::Type)iPortId, pPortEditorItemCreator);
    933 
    934                 /* Set newly created item editor factory for table delegate: */
    935                 pStyledItemDelegate->setItemEditorFactory(pNewItemEditorFactory);
    936             }
    937         }
    938     }
    939 
    940     /* Retranslate dialog: */
    941     retranslateUi();
    942 
    943     /* Limit the minimum size to 33% of screen size: */
    944     setMinimumSize(gpDesktop->screenGeometry(this).size() / 3);
     769    , m_pTableModel(0)
     770    , m_pActionAdd(0)
     771    , m_pActionCopy(0)
     772    , m_pActionRemove(0)
     773{
     774    /* Prepare: */
     775    prepare();
    945776}
    946777
    947778const UIPortForwardingDataList UIPortForwardingTable::rules() const
    948779{
    949     return m_pModel->rules();
     780    return m_pTableModel->rules();
    950781}
    951782
     
    955786    QList<NameData> names;
    956787    QList<UIPortForwardingDataUnique> rules;
    957     for (int i = 0; i < m_pModel->rowCount(); ++i)
     788    for (int i = 0; i < m_pTableModel->rowCount(); ++i)
    958789    {
    959790        /* Some of variables: */
    960         const NameData name = m_pModel->data(m_pModel->index(i, UIPortForwardingDataType_Name), Qt::EditRole).value<NameData>();
    961         const KNATProtocol protocol = m_pModel->data(m_pModel->index(i, UIPortForwardingDataType_Protocol), Qt::EditRole).value<KNATProtocol>();
    962         const PortData hostPort = m_pModel->data(m_pModel->index(i, UIPortForwardingDataType_HostPort), Qt::EditRole).value<PortData>().value();
    963         const PortData guestPort = m_pModel->data(m_pModel->index(i, UIPortForwardingDataType_GuestPort), Qt::EditRole).value<PortData>().value();
    964         const IpData hostIp = m_pModel->data(m_pModel->index(i, UIPortForwardingDataType_HostIp), Qt::EditRole).value<IpData>();
    965         const IpData guestIp = m_pModel->data(m_pModel->index(i, UIPortForwardingDataType_GuestIp), Qt::EditRole).value<IpData>();
     791        const NameData strName = m_pTableModel->data(m_pTableModel->index(i, UIPortForwardingDataType_Name), Qt::EditRole).value<NameData>();
     792        const KNATProtocol enmProtocol = m_pTableModel->data(m_pTableModel->index(i, UIPortForwardingDataType_Protocol), Qt::EditRole).value<KNATProtocol>();
     793        const PortData hostPort = m_pTableModel->data(m_pTableModel->index(i, UIPortForwardingDataType_HostPort), Qt::EditRole).value<PortData>().value();
     794        const PortData guestPort = m_pTableModel->data(m_pTableModel->index(i, UIPortForwardingDataType_GuestPort), Qt::EditRole).value<PortData>().value();
     795        const IpData strHostIp = m_pTableModel->data(m_pTableModel->index(i, UIPortForwardingDataType_HostIp), Qt::EditRole).value<IpData>();
     796        const IpData strGuestIp = m_pTableModel->data(m_pTableModel->index(i, UIPortForwardingDataType_GuestIp), Qt::EditRole).value<IpData>();
    966797
    967798        /* If at least one port is 'zero': */
     
    969800            return msgCenter().warnAboutIncorrectPort(window());
    970801        /* If at least one address is incorrect: */
    971         if (!(   hostIp.trimmed().isEmpty()
    972               || RTNetIsIPv4AddrStr(hostIp.toUtf8().constData())
    973               || RTNetIsIPv6AddrStr(hostIp.toUtf8().constData())
    974               || RTNetStrIsIPv4AddrAny(hostIp.toUtf8().constData())
    975               || RTNetStrIsIPv6AddrAny(hostIp.toUtf8().constData())))
     802        if (!(   strHostIp.trimmed().isEmpty()
     803              || RTNetIsIPv4AddrStr(strHostIp.toUtf8().constData())
     804              || RTNetIsIPv6AddrStr(strHostIp.toUtf8().constData())
     805              || RTNetStrIsIPv4AddrAny(strHostIp.toUtf8().constData())
     806              || RTNetStrIsIPv6AddrAny(strHostIp.toUtf8().constData())))
    976807            return msgCenter().warnAboutIncorrectAddress(window());
    977         if (!(   guestIp.trimmed().isEmpty()
    978               || RTNetIsIPv4AddrStr(guestIp.toUtf8().constData())
    979               || RTNetIsIPv6AddrStr(guestIp.toUtf8().constData())
    980               || RTNetStrIsIPv4AddrAny(guestIp.toUtf8().constData())
    981               || RTNetStrIsIPv6AddrAny(guestIp.toUtf8().constData())))
     808        if (!(   strGuestIp.trimmed().isEmpty()
     809              || RTNetIsIPv4AddrStr(strGuestIp.toUtf8().constData())
     810              || RTNetIsIPv6AddrStr(strGuestIp.toUtf8().constData())
     811              || RTNetStrIsIPv4AddrAny(strGuestIp.toUtf8().constData())
     812              || RTNetStrIsIPv6AddrAny(strGuestIp.toUtf8().constData())))
    982813            return msgCenter().warnAboutIncorrectAddress(window());
    983814        /* If empty guest address is not allowed: */
    984815        if (   !m_fAllowEmptyGuestIPs
    985             && guestIp.isEmpty())
     816            && strGuestIp.isEmpty())
    986817            return msgCenter().warnAboutEmptyGuestAddress(window());
    987818
    988819        /* Make sure non of the names were previosly used: */
    989         if (!names.contains(name))
    990             names << name;
     820        if (!names.contains(strName))
     821            names << strName;
    991822        else
    992823            return msgCenter().warnAboutNameShouldBeUnique(window());
    993824
    994825        /* Make sure non of the rules were previosly used: */
    995         UIPortForwardingDataUnique rule(protocol, hostPort, hostIp);
     826        UIPortForwardingDataUnique rule(enmProtocol, hostPort, strHostIp);
    996827        if (!rules.contains(rule))
    997828            rules << rule;
     
    1006837{
    1007838    m_pTableView->makeSureEditorDataCommitted();
    1008 }
    1009 
    1010 void UIPortForwardingTable::sltAddRule()
    1011 {
    1012     m_pModel->addRule(QModelIndex());
    1013     m_pTableView->setFocus();
    1014     m_pTableView->setCurrentIndex(m_pModel->index(m_pModel->rowCount() - 1, 0));
    1015     sltCurrentChanged();
    1016     sltAdjustTable();
    1017 }
    1018 
    1019 void UIPortForwardingTable::sltCopyRule()
    1020 {
    1021     m_pModel->addRule(m_pTableView->currentIndex());
    1022     m_pTableView->setFocus();
    1023     m_pTableView->setCurrentIndex(m_pModel->index(m_pModel->rowCount() - 1, 0));
    1024     sltCurrentChanged();
    1025     sltAdjustTable();
    1026 }
    1027 
    1028 void UIPortForwardingTable::sltDelRule()
    1029 {
    1030     m_pModel->delRule(m_pTableView->currentIndex());
    1031     m_pTableView->setFocus();
    1032     sltCurrentChanged();
    1033     sltAdjustTable();
    1034 }
    1035 
    1036 void UIPortForwardingTable::sltCurrentChanged()
    1037 {
    1038     bool fTableFocused = m_pTableView->hasFocus();
    1039     bool fTableChildFocused = m_pTableView->findChildren<QWidget*>().contains(QApplication::focusWidget());
    1040     bool fTableOrChildFocused = fTableFocused || fTableChildFocused;
    1041     m_pCopyAction->setEnabled(m_pTableView->currentIndex().isValid() && fTableOrChildFocused);
    1042     m_pDelAction->setEnabled(m_pTableView->currentIndex().isValid() && fTableOrChildFocused);
    1043 }
    1044 
    1045 void UIPortForwardingTable::sltShowTableContexMenu(const QPoint &pos)
    1046 {
    1047     /* Prepare context menu: */
    1048     QMenu menu(m_pTableView);
    1049     /* If some index is currently selected: */
    1050     if (m_pTableView->indexAt(pos).isValid())
    1051     {
    1052         menu.addAction(m_pCopyAction);
    1053         menu.addAction(m_pDelAction);
    1054     }
    1055     /* If no valid index selected: */
    1056     else
    1057     {
    1058         menu.addAction(m_pAddAction);
    1059     }
    1060     menu.exec(m_pTableView->viewport()->mapToGlobal(pos));
    1061 }
    1062 
    1063 void UIPortForwardingTable::sltAdjustTable()
    1064 {
    1065     m_pTableView->horizontalHeader()->setStretchLastSection(false);
    1066     /* If table is NOT empty: */
    1067     if (m_pModel->rowCount())
    1068     {
    1069         /* Resize table to contents size-hint and emit a spare place for first column: */
    1070         m_pTableView->resizeColumnsToContents();
    1071         uint uFullWidth = m_pTableView->viewport()->width();
    1072         for (uint u = 1; u < UIPortForwardingDataType_Max; ++u)
    1073             uFullWidth -= m_pTableView->horizontalHeader()->sectionSize(u);
    1074         m_pTableView->horizontalHeader()->resizeSection(UIPortForwardingDataType_Name, uFullWidth);
    1075     }
    1076     /* If table is empty: */
    1077     else
    1078     {
    1079         /* Resize table columns to be equal in size: */
    1080         uint uFullWidth = m_pTableView->viewport()->width();
    1081         for (uint u = 0; u < UIPortForwardingDataType_Max; ++u)
    1082             m_pTableView->horizontalHeader()->resizeSection(u, uFullWidth / UIPortForwardingDataType_Max);
    1083     }
    1084     m_pTableView->horizontalHeader()->setStretchLastSection(true);
    1085 }
    1086 
    1087 void UIPortForwardingTable::retranslateUi()
    1088 {
    1089     /* Table translations: */
    1090     m_pTableView->setWhatsThis(tr("Contains a list of port forwarding rules."));
    1091 
    1092     /* Set action's text: */
    1093     m_pAddAction->setText(tr("Add New Rule"));
    1094     m_pCopyAction->setText(tr("Copy Selected Rule"));
    1095     m_pDelAction->setText(tr("Remove Selected Rule"));
    1096 
    1097     m_pAddAction->setWhatsThis(tr("Adds new port forwarding rule."));
    1098     m_pCopyAction->setWhatsThis(tr("Copies selected port forwarding rule."));
    1099     m_pDelAction->setWhatsThis(tr("Removes selected port forwarding rule."));
    1100 
    1101     m_pAddAction->setToolTip(m_pAddAction->whatsThis());
    1102     m_pCopyAction->setToolTip(m_pCopyAction->whatsThis());
    1103     m_pDelAction->setToolTip(m_pDelAction->whatsThis());
    1104839}
    1105840
     
    1134869}
    1135870
     871void UIPortForwardingTable::retranslateUi()
     872{
     873    /* Table translations: */
     874    m_pTableView->setWhatsThis(tr("Contains a list of port forwarding rules."));
     875
     876    /* Set action's text: */
     877    m_pActionAdd->setText(tr("Add New Rule"));
     878    m_pActionCopy->setText(tr("Copy Selected Rule"));
     879    m_pActionRemove->setText(tr("Remove Selected Rule"));
     880
     881    m_pActionAdd->setWhatsThis(tr("Adds new port forwarding rule."));
     882    m_pActionCopy->setWhatsThis(tr("Copies selected port forwarding rule."));
     883    m_pActionRemove->setWhatsThis(tr("Removes selected port forwarding rule."));
     884
     885    m_pActionAdd->setToolTip(m_pActionAdd->whatsThis());
     886    m_pActionCopy->setToolTip(m_pActionCopy->whatsThis());
     887    m_pActionRemove->setToolTip(m_pActionRemove->whatsThis());
     888}
     889
     890void UIPortForwardingTable::sltAddRule()
     891{
     892    m_pTableModel->addRule(QModelIndex());
     893    m_pTableView->setFocus();
     894    m_pTableView->setCurrentIndex(m_pTableModel->index(m_pTableModel->rowCount() - 1, 0));
     895    sltCurrentChanged();
     896    sltAdjustTable();
     897}
     898
     899void UIPortForwardingTable::sltCopyRule()
     900{
     901    m_pTableModel->addRule(m_pTableView->currentIndex());
     902    m_pTableView->setFocus();
     903    m_pTableView->setCurrentIndex(m_pTableModel->index(m_pTableModel->rowCount() - 1, 0));
     904    sltCurrentChanged();
     905    sltAdjustTable();
     906}
     907
     908void UIPortForwardingTable::sltRemoveRule()
     909{
     910    m_pTableModel->removeRule(m_pTableView->currentIndex());
     911    m_pTableView->setFocus();
     912    sltCurrentChanged();
     913    sltAdjustTable();
     914}
     915
     916void UIPortForwardingTable::sltCurrentChanged()
     917{
     918    bool fTableFocused = m_pTableView->hasFocus();
     919    bool fTableChildFocused = m_pTableView->findChildren<QWidget*>().contains(QApplication::focusWidget());
     920    bool fTableOrChildFocused = fTableFocused || fTableChildFocused;
     921    m_pActionCopy->setEnabled(m_pTableView->currentIndex().isValid() && fTableOrChildFocused);
     922    m_pActionRemove->setEnabled(m_pTableView->currentIndex().isValid() && fTableOrChildFocused);
     923}
     924
     925void UIPortForwardingTable::sltShowTableContexMenu(const QPoint &pos)
     926{
     927    /* Prepare context menu: */
     928    QMenu menu(m_pTableView);
     929    /* If some index is currently selected: */
     930    if (m_pTableView->indexAt(pos).isValid())
     931    {
     932        menu.addAction(m_pActionCopy);
     933        menu.addAction(m_pActionRemove);
     934    }
     935    /* If no valid index selected: */
     936    else
     937    {
     938        menu.addAction(m_pActionAdd);
     939    }
     940    menu.exec(m_pTableView->viewport()->mapToGlobal(pos));
     941}
     942
     943void UIPortForwardingTable::sltAdjustTable()
     944{
     945    m_pTableView->horizontalHeader()->setStretchLastSection(false);
     946    /* If table is NOT empty: */
     947    if (m_pTableModel->rowCount())
     948    {
     949        /* Resize table to contents size-hint and emit a spare place for first column: */
     950        m_pTableView->resizeColumnsToContents();
     951        uint uFullWidth = m_pTableView->viewport()->width();
     952        for (uint u = 1; u < UIPortForwardingDataType_Max; ++u)
     953            uFullWidth -= m_pTableView->horizontalHeader()->sectionSize(u);
     954        m_pTableView->horizontalHeader()->resizeSection(UIPortForwardingDataType_Name, uFullWidth);
     955    }
     956    /* If table is empty: */
     957    else
     958    {
     959        /* Resize table columns to be equal in size: */
     960        uint uFullWidth = m_pTableView->viewport()->width();
     961        for (uint u = 0; u < UIPortForwardingDataType_Max; ++u)
     962            m_pTableView->horizontalHeader()->resizeSection(u, uFullWidth / UIPortForwardingDataType_Max);
     963    }
     964    m_pTableView->horizontalHeader()->setStretchLastSection(true);
     965}
     966
     967void UIPortForwardingTable::prepare()
     968{
     969    /* Prepare layout: */
     970    prepareLayout();
     971
     972    /* Apply language settings: */
     973    retranslateUi();
     974
     975    /* Limit the minimum size to 33% of screen size: */
     976    setMinimumSize(gpDesktop->screenGeometry(this).size() / 3);
     977}
     978
     979void UIPortForwardingTable::prepareLayout()
     980{
     981    /* Create layout: */
     982    m_pLayout = new QHBoxLayout(this);
     983    if (m_pLayout)
     984    {
     985        /* Configure layout: */
     986#ifdef VBOX_WS_MAC
     987        /* On macOS we can do a bit of smoothness: */
     988        m_pLayout->setContentsMargins(0, 0, 0, 0);
     989        m_pLayout->setSpacing(3);
     990#else
     991        m_pLayout->setSpacing(qApp->style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing) / 3);
     992#endif
     993
     994        /* Prepare table-view: */
     995        prepareTableView();
     996
     997        /* Prepare toolbar: */
     998        prepareToolbar();
     999    }
     1000}
     1001
     1002void UIPortForwardingTable::prepareTableView()
     1003{
     1004    /* Create table-view: */
     1005    m_pTableView = new UIPortForwardingView;
     1006    if (m_pTableView)
     1007    {
     1008        /* Configure table-view: */
     1009        m_pTableView->setTabKeyNavigation(false);
     1010        m_pTableView->verticalHeader()->hide();
     1011        m_pTableView->verticalHeader()->setDefaultSectionSize((int)(m_pTableView->verticalHeader()->minimumSectionSize() * 1.33));
     1012        m_pTableView->setSelectionMode(QAbstractItemView::SingleSelection);
     1013        m_pTableView->setContextMenuPolicy(Qt::CustomContextMenu);
     1014        m_pTableView->installEventFilter(this);
     1015
     1016        /* Prepare model: */
     1017        prepareTableModel();
     1018
     1019        /* Finish configure table-view (after model is configured): */
     1020        m_pTableView->setModel(m_pTableModel);
     1021        connect(m_pTableView, SIGNAL(sigCurrentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(sltCurrentChanged()));
     1022        connect(m_pTableView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(sltShowTableContexMenu(const QPoint &)));
     1023
     1024        /* Prepare delegates: */
     1025        prepareTableDelegates();
     1026
     1027        /* Add into layout: */
     1028        m_pLayout->addWidget(m_pTableView);
     1029    }
     1030}
     1031
     1032void UIPortForwardingTable::prepareTableModel()
     1033{
     1034    /* Create table-model: */
     1035    m_pTableModel = new UIPortForwardingModel(m_pTableView, m_rules);
     1036    if (m_pTableModel)
     1037    {
     1038        /* Configure table-model: */
     1039        connect(m_pTableModel, &UIPortForwardingModel::dataChanged,
     1040                this, &UIPortForwardingTable::sltTableDataChanged);
     1041        connect(m_pTableModel, &UIPortForwardingModel::rowsInserted,
     1042                this, &UIPortForwardingTable::sltTableDataChanged);
     1043        connect(m_pTableModel, &UIPortForwardingModel::rowsRemoved,
     1044                this, &UIPortForwardingTable::sltTableDataChanged);
     1045    }
     1046}
     1047
     1048void UIPortForwardingTable::prepareTableDelegates()
     1049{
     1050    /* We certainly have abstract item delegate: */
     1051    QAbstractItemDelegate *pAbstractItemDelegate = m_pTableView->itemDelegate();
     1052    if (pAbstractItemDelegate)
     1053    {
     1054        /* But is this also styled item delegate? */
     1055        QStyledItemDelegate *pStyledItemDelegate = qobject_cast<QStyledItemDelegate*>(pAbstractItemDelegate);
     1056        if (pStyledItemDelegate)
     1057        {
     1058            /* Create new item editor factory: */
     1059            QItemEditorFactory *pNewItemEditorFactory = new QItemEditorFactory;
     1060            if (pNewItemEditorFactory)
     1061            {
     1062                /* Register NameEditor as the NameData editor: */
     1063                int iNameId = qRegisterMetaType<NameData>();
     1064                QStandardItemEditorCreator<NameEditor> *pNameEditorItemCreator = new QStandardItemEditorCreator<NameEditor>();
     1065                pNewItemEditorFactory->registerEditor((QVariant::Type)iNameId, pNameEditorItemCreator);
     1066
     1067                /* Register ProtocolEditor as the KNATProtocol editor: */
     1068                int iProtocolId = qRegisterMetaType<KNATProtocol>();
     1069                QStandardItemEditorCreator<ProtocolEditor> *pProtocolEditorItemCreator = new QStandardItemEditorCreator<ProtocolEditor>();
     1070                pNewItemEditorFactory->registerEditor((QVariant::Type)iProtocolId, pProtocolEditorItemCreator);
     1071
     1072                /* Register IPv4Editor/IPv6Editor as the IpData editor: */
     1073                int iIpId = qRegisterMetaType<IpData>();
     1074                if (!m_fIPv6)
     1075                {
     1076                    QStandardItemEditorCreator<IPv4Editor> *pIPv4EditorItemCreator = new QStandardItemEditorCreator<IPv4Editor>();
     1077                    pNewItemEditorFactory->registerEditor((QVariant::Type)iIpId, pIPv4EditorItemCreator);
     1078                }
     1079                else
     1080                {
     1081                    QStandardItemEditorCreator<IPv6Editor> *pIPv6EditorItemCreator = new QStandardItemEditorCreator<IPv6Editor>();
     1082                    pNewItemEditorFactory->registerEditor((QVariant::Type)iIpId, pIPv6EditorItemCreator);
     1083                }
     1084
     1085                /* Register PortEditor as the PortData editor: */
     1086                int iPortId = qRegisterMetaType<PortData>();
     1087                QStandardItemEditorCreator<PortEditor> *pPortEditorItemCreator = new QStandardItemEditorCreator<PortEditor>();
     1088                pNewItemEditorFactory->registerEditor((QVariant::Type)iPortId, pPortEditorItemCreator);
     1089
     1090                /* Set newly created item editor factory for table delegate: */
     1091                pStyledItemDelegate->setItemEditorFactory(pNewItemEditorFactory);
     1092            }
     1093        }
     1094    }
     1095}
     1096
     1097void UIPortForwardingTable::prepareToolbar()
     1098{
     1099    /* Create toolbar: */
     1100    m_pToolBar = new UIToolBar;
     1101    if (m_pToolBar)
     1102    {
     1103        /* Determine icon metric: */
     1104        const QStyle *pStyle = QApplication::style();
     1105        const int iIconMetric = pStyle->pixelMetric(QStyle::PM_SmallIconSize);
     1106
     1107        /* Configure toolbar: */
     1108        m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric));
     1109        m_pToolBar->setOrientation(Qt::Vertical);
     1110
     1111        /* Create 'Add' action: */
     1112        m_pActionAdd = new QAction(this);
     1113        if (m_pActionAdd)
     1114        {
     1115            /* Configure action: */
     1116            m_pActionAdd->setShortcut(QKeySequence("Ins"));
     1117            m_pActionAdd->setIcon(UIIconPool::iconSet(":/controller_add_16px.png", ":/controller_add_disabled_16px.png"));
     1118            connect(m_pActionAdd, SIGNAL(triggered(bool)), this, SLOT(sltAddRule()));
     1119            m_pToolBar->addAction(m_pActionAdd);
     1120        }
     1121
     1122        /* Create 'Copy' action: */
     1123        m_pActionCopy = new QAction(this);
     1124        if (m_pActionCopy)
     1125        {
     1126            /* Configure action: */
     1127            m_pActionCopy->setIcon(UIIconPool::iconSet(":/controller_add_16px.png", ":/controller_add_disabled_16px.png"));
     1128            connect(m_pActionCopy, SIGNAL(triggered(bool)), this, SLOT(sltCopyRule()));
     1129        }
     1130
     1131        /* Create 'Remove' action: */
     1132        m_pActionRemove = new QAction(this);
     1133        if (m_pActionRemove)
     1134        {
     1135            /* Configure action: */
     1136            m_pActionRemove->setShortcut(QKeySequence("Del"));
     1137            m_pActionRemove->setIcon(UIIconPool::iconSet(":/controller_remove_16px.png", ":/controller_remove_disabled_16px.png"));
     1138            connect(m_pActionRemove, SIGNAL(triggered(bool)), this, SLOT(sltRemoveRule()));
     1139            m_pToolBar->addAction(m_pActionRemove);
     1140        }
     1141
     1142        /* Add into layout: */
     1143        m_pLayout->addWidget(m_pToolBar);
     1144    }
     1145}
     1146
     1147
    11361148#include "UIPortForwardingTable.moc"
    1137 
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIPortForwardingTable.h

    r71027 r71937  
    55
    66/*
    7  * Copyright (C) 2010-2017 Oracle Corporation
     7 * Copyright (C) 2010-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1616 */
    1717
    18 #ifndef __UIPortForwardingTable_h__
    19 #define __UIPortForwardingTable_h__
     18#ifndef ___UIPortForwardingTable_h___
     19#define ___UIPortForwardingTable_h___
    2020
    2121/* Qt includes: */
     22#include <QString>
    2223#include <QWidget>
    2324
    2425/* GUI includes: */
    2526#include "QIWithRetranslateUI.h"
     27#include "UILibraryDefs.h"
    2628
    2729/* COM includes: */
     
    2931
    3032/* Forward declarations: */
     33class QAction;
     34class QHBoxLayout;
     35class QIDialogButtonBox;
    3136class QITableView;
     37class UIPortForwardingModel;
    3238class UIToolBar;
    33 class QIDialogButtonBox;
    34 class UIPortForwardingModel;
    35 
    36 /* Name data: */
     39
     40
     41/** QString subclass used to distinguish name data from simple QString. */
    3742class NameData : public QString
    3843{
    3944public:
    4045
     46    /** Constructs null name data. */
    4147    NameData() : QString() {}
     48    /** Constructs name data passing @a strName to the base-class. */
    4249    NameData(const QString &strName) : QString(strName) {}
    4350};
    4451Q_DECLARE_METATYPE(NameData);
    4552
    46 /* Ip data: */
     53
     54/** QString subclass used to distinguish IP data from simple QString. */
    4755class IpData : public QString
    4856{
    4957public:
    5058
     59    /** Constructs null IP data. */
    5160    IpData() : QString() {}
    52     IpData(const QString &strIP) : QString(strIP) {}
     61    /** Constructs name data passing @a strIp to the base-class. */
     62    IpData(const QString &strIp) : QString(strIp) {}
    5363};
    5464Q_DECLARE_METATYPE(IpData);
    5565
    56 /* Port data: */
     66
     67/** Wrapper for ushort used to distinguish port data from simple ushort. */
    5768class PortData
    5869{
    5970public:
    6071
     72    /** Constructs null port data. */
    6173    PortData() : m_uValue(0) {}
     74    /** Constructs port data based on @a uValue. */
    6275    PortData(ushort uValue) : m_uValue(uValue) {}
     76    /** Constructs port data based on @a other port data value. */
    6377    PortData(const PortData &other) : m_uValue(other.value()) {}
    64     bool operator==(const PortData &other) const { return m_uValue == other.m_uValue; }
     78
     79    /** Returns whether this port data is equal to @a another. */
     80    bool operator==(const PortData &another) const { return m_uValue == another.m_uValue; }
     81
     82    /** Returns serialized port data value. */
    6583    ushort value() const { return m_uValue; }
    6684
    6785private:
    6886
     87    /** Holds the port data value. */
    6988    ushort m_uValue;
    7089};
    7190Q_DECLARE_METATYPE(PortData);
    7291
    73 /** Port Forwarding Rule data structure. */
     92
     93/** Port Forwarding Rule structure. */
    7494struct UIDataPortForwardingRule
    7595{
     
    137157};
    138158
    139 /* Port forwarding data, unique part: */
     159/** Port Forwarding Data list. */
     160typedef QList<UIDataPortForwardingRule> UIPortForwardingDataList;
     161
     162
     163/** Unique part of port forwarding data. */
    140164struct UIPortForwardingDataUnique
    141165{
     166    /** Constructs unique port forwarding data based on
     167      * @a enmProtocol, @a uHostPort and @a uHostPort. */
    142168    UIPortForwardingDataUnique(KNATProtocol enmProtocol,
    143169                               PortData uHostPort,
     
    145171        : protocol(enmProtocol)
    146172        , hostPort(uHostPort)
    147         , hostIp(strHostIp) {}
    148     bool operator==(const UIPortForwardingDataUnique &other)
     173        , hostIp(strHostIp)
     174    {}
     175
     176    /** Returns whether this port data is equal to @a another. */
     177    bool operator==(const UIPortForwardingDataUnique &another)
    149178    {
    150         return    protocol == other.protocol
    151                && hostPort == other.hostPort
    152                && (   hostIp.isEmpty()    || other.hostIp.isEmpty()
    153                    || hostIp == "0.0.0.0" || other.hostIp == "0.0.0.0"
    154                    || hostIp              == other.hostIp);
     179        return    protocol == another.protocol
     180               && hostPort == another.hostPort
     181               && (   hostIp.isEmpty()    || another.hostIp.isEmpty()
     182                   || hostIp == "0.0.0.0" || another.hostIp == "0.0.0.0"
     183                   || hostIp              == another.hostIp);
    155184    }
     185
     186    /** Holds the port forwarding data protocol type. */
    156187    KNATProtocol protocol;
     188    /** Holds the port forwarding data host port. */
    157189    PortData hostPort;
     190    /** Holds the port forwarding data host IP. */
    158191    IpData hostIp;
    159192};
    160193
    161 /* Port forwarding data list: */
    162 typedef QList<UIDataPortForwardingRule> UIPortForwardingDataList;
    163 
    164 /* Port forwarding dialog: */
    165 class UIPortForwardingTable : public QIWithRetranslateUI<QWidget>
     194
     195/** QWidget subclass representig Port Forwarding table. */
     196class SHARED_LIBRARY_STUFF UIPortForwardingTable : public QIWithRetranslateUI<QWidget>
    166197{
    167198    Q_OBJECT;
     
    169200public:
    170201
    171     /* Constructor: */
     202    /** Constructs Port Forwarding table.
     203      * @param  rules                Brings the current list of Port Forwarding rules.
     204      * @param  fIPv6                Brings whether this table contains IPv6 rules, not IPv4.
     205      * @param  fAllowEmptyGuestIPs  Brings whether this table allows empty guest IPs. */
    172206    UIPortForwardingTable(const UIPortForwardingDataList &rules, bool fIPv6, bool fAllowEmptyGuestIPs);
    173207
    174     /* API: Rules stuff: */
     208    /** Returns the list of port forwarding rules. */
    175209    const UIPortForwardingDataList rules() const;
     210
     211    /** Validates the table. */
    176212    bool validate() const;
    177213
    178214    /** Returns whether the table data was changed. */
    179     bool isChanged() const { return m_fIsTableDataChanged; }
     215    bool isChanged() const { return m_fTableDataChanged; }
    180216
    181217    /** Makes sure current editor data committed. */
    182218    void makeSureEditorDataCommitted();
    183219
     220protected:
     221
     222    /** Preprocesses any Qt @a pEvent for passed @a pObject. */
     223    virtual bool eventFilter(QObject *pObject, QEvent *pEvent) /* override */;
     224
     225    /** Handles translation event. */
     226    virtual void retranslateUi() /* override */;
     227
    184228private slots:
    185229
    186     /* Handlers: Table operation stuff: */
     230    /** Adds the rule. */
    187231    void sltAddRule();
     232    /** Copies the rule. */
    188233    void sltCopyRule();
    189     void sltDelRule();
     234    /** Removes the rule. */
     235    void sltRemoveRule();
    190236
    191237    /** Marks table data as changed. */
    192     void sltTableDataChanged() { m_fIsTableDataChanged = true; }
    193 
    194     /* Handlers: Table stuff: */
     238    void sltTableDataChanged() { m_fTableDataChanged = true; }
     239
     240    /** Handles current item change. */
    195241    void sltCurrentChanged();
     242    /** Handles request to show context-menu in certain @a position. */
    196243    void sltShowTableContexMenu(const QPoint &position);
     244    /** Adjusts table column sizes. */
    197245    void sltAdjustTable();
    198246
    199247private:
    200248
    201     /* Handler: Translation stuff: */
    202     void retranslateUi();
    203 
    204     /* Handlers: Event-processing stuff: */
    205     bool eventFilter(QObject *pObject, QEvent *pEvent);
    206 
    207     /* Flags: */
    208     bool m_fAllowEmptyGuestIPs;
    209 
    210     /** Holds whether the table data was changed. */
    211     bool m_fIsTableDataChanged;
    212 
    213     /* Widgets: */
     249    /** Prepares all. */
     250    void prepare();
     251    /** Prepares layout. */
     252    void prepareLayout();
     253    /** Prepares table-view. */
     254    void prepareTableView();
     255    /** Prepares table-model. */
     256    void prepareTableModel();
     257    /** Prepares table-delegates. */
     258    void prepareTableDelegates();
     259    /** Prepares toolbar. */
     260    void prepareToolbar();
     261
     262    /** Holds the _initial_ list of Port Forwarding rules. */
     263    const UIPortForwardingDataList &m_rules;
     264
     265    /** Holds whether this table contains IPv6 rules, not IPv4. */
     266    bool  m_fIPv6               : 1;
     267    /** Holds whether this table allows empty guest IPs. */
     268    bool  m_fAllowEmptyGuestIPs : 1;
     269    /** Holds whether this table data was changed. */
     270    bool  m_fTableDataChanged   : 1;
     271
     272    /** Holds the layout instance. */
     273    QHBoxLayout *m_pLayout;
     274    /** Holds the table-view instance. */
    214275    QITableView *m_pTableView;
    215     UIToolBar *m_pToolBar;
    216 
    217     /* Model: */
    218     UIPortForwardingModel *m_pModel;
    219 
    220     /* Actions: */
    221     QAction *m_pAddAction;
    222     QAction *m_pCopyAction;
    223     QAction *m_pDelAction;
    224 };
    225 
    226 #endif // __UIPortForwardingTable_h__
     276    /** Holds the tool-bar instance. */
     277    UIToolBar   *m_pToolBar;
     278
     279    /** Holds the table-model instance. */
     280    UIPortForwardingModel *m_pTableModel;
     281
     282    /** Holds the Add action instance. */
     283    QAction *m_pActionAdd;
     284    /** Holds the Copy action instance. */
     285    QAction *m_pActionCopy;
     286    /** Holds the Remove action instance. */
     287    QAction *m_pActionRemove;
     288};
     289
     290
     291#endif /* !___UIPortForwardingTable_h___ */
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