VirtualBox

Changeset 48533 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
Sep 19, 2013 2:04:10 PM (11 years ago)
Author:
vboxsync
Message:

FE/Qt: Moving port-forwarding table into separate widget for reusing.

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

Legend:

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

    r48496 r48533  
    386386        src/widgets/UIPopupStack.h \
    387387        src/widgets/UIPopupStackViewport.h \
     388        src/widgets/UIPortForwardingTable.h \
    388389        src/widgets/UIProgressDialog.h \
    389390        src/widgets/UISpacerWidgets.h \
     
    458459        src/selector/UIVMDesktop.cpp \
    459460        src/settings/UISettingsDialogSpecific.cpp \
    460         src/settings/machine/UIMachineSettingsPortForwardingDlg.cpp \
    461461        src/settings/machine/UIMachineSettingsStorage.cpp \
    462462        src/settings/machine/UIMachineSettingsUSB.cpp \
    463463        src/widgets/UIHotKeyEditor.cpp \
     464        src/widgets/UIPortForwardingTable.cpp \
    464465        src/wizards/importappliance/UIWizardImportApp.cpp
    465466
     
    640641        src/widgets/UIPopupStack.cpp \
    641642        src/widgets/UIPopupStackViewport.cpp \
     643        src/widgets/UIPortForwardingTable.cpp \
    642644        src/widgets/UIProgressDialog.cpp \
    643645        src/widgets/UISpecialControls.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsPortForwardingDlg.cpp

    r45047 r48533  
    77
    88/*
    9  * Copyright (C) 2010-2012 Oracle Corporation
     9 * Copyright (C) 2010-2013 Oracle Corporation
    1010 *
    1111 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1919
    2020/* Qt includes: */
    21 #include <QHBoxLayout>
    22 #include <QMenu>
    23 #include <QAction>
    24 #include <QHeaderView>
     21#include <QVBoxLayout>
    2522#include <QPushButton>
    26 #include <QStyledItemDelegate>
    27 #include <QItemEditorFactory>
    28 #include <QComboBox>
    29 #include <QLineEdit>
    30 #include <QSpinBox>
    31 #include <QTimer>
    3223
    3324/* GUI includes: */
    3425#include "UIMachineSettingsPortForwardingDlg.h"
    35 #include "UIMessageCenter.h"
    36 #include "UIToolBar.h"
    37 #include "QITableView.h"
     26#include "UIIconPool.h"
    3827#include "QIDialogButtonBox.h"
    39 #include "UIIconPool.h"
    40 #include "UIConverter.h"
    4128
    42 /* Other VBox includes: */
    43 #include <iprt/cidr.h>
    44 
    45 /* External includes: */
    46 #include <math.h>
    47 
    48 /* IP validator: */
    49 class IPValidator : public QValidator
     29UIMachineSettingsPortForwardingDlg::UIMachineSettingsPortForwardingDlg(QWidget *pParent,
     30                                                                       const UIPortForwardingDataList &rules)
     31    : QIWithRetranslateUI<QIDialog>(pParent)
     32    , m_pTable(0)
     33    , m_pButtonBox(0)
    5034{
    51     Q_OBJECT;
    52 
    53 public:
    54 
    55     IPValidator(QObject *pParent) : QValidator(pParent) {}
    56     ~IPValidator() {}
    57 
    58     QValidator::State validate(QString &strInput, int & /* iPos */) const
    59     {
    60         QString strStringToValidate(strInput);
    61         strStringToValidate.remove(' ');
    62         QString strDot("\\.");
    63         QString strDigits("(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)");
    64         QRegExp intRegExp(QString("^(%1?(%2(%1?(%2(%1?(%2%1?)?)?)?)?)?)?$").arg(strDigits).arg(strDot));
    65         RTNETADDRIPV4 Network, Mask;
    66         if (strStringToValidate == "..." || RTCidrStrToIPv4(strStringToValidate.toLatin1().constData(), &Network, &Mask) == VINF_SUCCESS)
    67             return QValidator::Acceptable;
    68         else if (intRegExp.indexIn(strStringToValidate) != -1)
    69             return QValidator::Intermediate;
    70         else
    71             return QValidator::Invalid;
    72     }
    73 };
    74 
    75 /* Name editor: */
    76 class NameEditor : public QLineEdit
    77 {
    78     Q_OBJECT;
    79     Q_PROPERTY(NameData name READ name WRITE setName USER true);
    80 
    81 public:
    82 
    83     NameEditor(QWidget *pParent = 0) : QLineEdit(pParent)
    84     {
    85         setFrame(false);
    86         setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    87         setValidator(new QRegExpValidator(QRegExp("[^,]*"), this));
    88     }
    89 
    90 private:
    91 
    92     void setName(NameData name)
    93     {
    94         setText(name);
    95     }
    96 
    97     NameData name() const
    98     {
    99         return text();
    100     }
    101 };
    102 
    103 /* Protocol editor: */
    104 class ProtocolEditor : public QComboBox
    105 {
    106     Q_OBJECT;
    107     Q_PROPERTY(KNATProtocol protocol READ protocol WRITE setProtocol USER true);
    108 
    109 public:
    110 
    111     ProtocolEditor(QWidget *pParent = 0) : QComboBox(pParent)
    112     {
    113         addItem(gpConverter->toString(KNATProtocol_UDP), QVariant::fromValue(KNATProtocol_UDP));
    114         addItem(gpConverter->toString(KNATProtocol_TCP), QVariant::fromValue(KNATProtocol_TCP));
    115     }
    116 
    117 private:
    118 
    119     void setProtocol(KNATProtocol p)
    120     {
    121         for (int i = 0; i < count(); ++i)
    122         {
    123             if (itemData(i).value<KNATProtocol>() == p)
    124             {
    125                 setCurrentIndex(i);
    126                 break;
    127             }
    128         }
    129     }
    130 
    131     KNATProtocol protocol() const
    132     {
    133         return itemData(currentIndex()).value<KNATProtocol>();
    134     }
    135 };
    136 
    137 /* IP editor: */
    138 class IPEditor : public QLineEdit
    139 {
    140     Q_OBJECT;
    141     Q_PROPERTY(IpData ip READ ip WRITE setIp USER true);
    142 
    143 public:
    144 
    145     IPEditor(QWidget *pParent = 0) : QLineEdit(pParent)
    146     {
    147         setFrame(false);
    148         setAlignment(Qt::AlignCenter);
    149         setValidator(new IPValidator(this));
    150         setInputMask("000.000.000.000");
    151     }
    152 
    153 private:
    154 
    155     void setIp(IpData ip)
    156     {
    157         setText(ip);
    158     }
    159 
    160     IpData ip() const
    161     {
    162         return text() == "..." ? QString() : text();
    163     }
    164 };
    165 
    166 /* Port editor: */
    167 class PortEditor : public QSpinBox
    168 {
    169     Q_OBJECT;
    170     Q_PROPERTY(PortData port READ port WRITE setPort USER true);
    171 
    172 public:
    173 
    174     PortEditor(QWidget *pParent = 0) : QSpinBox(pParent)
    175     {
    176         setFrame(false);
    177         setRange(0, (1 << (8 * sizeof(ushort))) - 1);
    178     }
    179 
    180 private:
    181 
    182     void setPort(PortData port)
    183     {
    184         setValue(port.value());
    185     }
    186 
    187     PortData port() const
    188     {
    189         return value();
    190     }
    191 };
    192 
    193 /* Port forwarding data model: */
    194 class UIPortForwardingModel : public QAbstractTableModel
    195 {
    196     Q_OBJECT;
    197 
    198 public:
    199 
    200     /* Column names: */
    201     enum UIPortForwardingDataType
    202     {
    203         UIPortForwardingDataType_Name,
    204         UIPortForwardingDataType_Protocol,
    205         UIPortForwardingDataType_HostIp,
    206         UIPortForwardingDataType_HostPort,
    207         UIPortForwardingDataType_GuestIp,
    208         UIPortForwardingDataType_GuestPort,
    209         UIPortForwardingDataType_Max
    210     };
    211 
    212     /* Port forwarding model constructor: */
    213     UIPortForwardingModel(QObject *pParent = 0, const UIPortForwardingDataList &rules = UIPortForwardingDataList())
    214         : QAbstractTableModel(pParent), m_dataList(rules) {}
    215     /* Port forwarding model destructor: */
    216     ~UIPortForwardingModel() {}
    217 
    218     /* The list of chosen rules: */
    219     const UIPortForwardingDataList& rules() const
    220     {
    221         return m_dataList;
    222     }
    223 
    224     /* Flags for model indexes: */
    225     Qt::ItemFlags flags(const QModelIndex &index) const
    226     {
    227         /* Check index validness: */
    228         if (!index.isValid())
    229             return Qt::NoItemFlags;
    230         /* All columns have similar flags: */
    231         return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
    232     }
    233 
    234     /* Row count getter: */
    235     int rowCount(const QModelIndex & parent = QModelIndex()) const
    236     {
    237         Q_UNUSED(parent);
    238         return m_dataList.size();
    239     }
    240 
    241     /* Column count getter: */
    242     int columnCount(const QModelIndex & parent = QModelIndex()) const
    243     {
    244         Q_UNUSED(parent);
    245         return UIPortForwardingDataType_Max;
    246     }
    247 
    248     /* Get header data: */
    249     QVariant headerData(int iSection, Qt::Orientation orientation, int iRole) const
    250     {
    251         /* Display role for horizontal header: */
    252         if (iRole == Qt::DisplayRole && orientation == Qt::Horizontal)
    253         {
    254             /* Switch for different columns: */
    255             switch (iSection)
    256             {
    257                 case UIPortForwardingDataType_Name: return tr("Name");
    258                 case UIPortForwardingDataType_Protocol: return tr("Protocol");
    259                 case UIPortForwardingDataType_HostIp: return tr("Host IP");
    260                 case UIPortForwardingDataType_HostPort: return tr("Host Port");
    261                 case UIPortForwardingDataType_GuestIp: return tr("Guest IP");
    262                 case UIPortForwardingDataType_GuestPort: return tr("Guest Port");
    263                 default: break;
    264             }
    265         }
    266         /* Return wrong value: */
    267         return QVariant();
    268     }
    269 
    270     /* Get index data: */
    271     QVariant data(const QModelIndex &index, int iRole) const
    272     {
    273         /* Check index validness: */
    274         if (!index.isValid())
    275             return QVariant();
    276         /* Switch for different roles: */
    277         switch (iRole)
    278         {
    279             /* Display role: */
    280             case Qt::DisplayRole:
    281             {
    282                 /* Switch for different columns: */
    283                 switch (index.column())
    284                 {
    285                     case UIPortForwardingDataType_Name: return m_dataList[index.row()].name;
    286                     case UIPortForwardingDataType_Protocol: return gpConverter->toString(m_dataList[index.row()].protocol);
    287                     case UIPortForwardingDataType_HostIp: return m_dataList[index.row()].hostIp;
    288                     case UIPortForwardingDataType_HostPort: return m_dataList[index.row()].hostPort.value();
    289                     case UIPortForwardingDataType_GuestIp: return m_dataList[index.row()].guestIp;
    290                     case UIPortForwardingDataType_GuestPort: return m_dataList[index.row()].guestPort.value();
    291                     default: return QVariant();
    292                 }
    293             }
    294             /* Edit role: */
    295             case Qt::EditRole:
    296             {
    297                 /* Switch for different columns: */
    298                 switch (index.column())
    299                 {
    300                     case UIPortForwardingDataType_Name: return QVariant::fromValue(m_dataList[index.row()].name);
    301                     case UIPortForwardingDataType_Protocol: return QVariant::fromValue(m_dataList[index.row()].protocol);
    302                     case UIPortForwardingDataType_HostIp: return QVariant::fromValue(m_dataList[index.row()].hostIp);
    303                     case UIPortForwardingDataType_HostPort: return QVariant::fromValue(m_dataList[index.row()].hostPort);
    304                     case UIPortForwardingDataType_GuestIp: return QVariant::fromValue(m_dataList[index.row()].guestIp);
    305                     case UIPortForwardingDataType_GuestPort: return QVariant::fromValue(m_dataList[index.row()].guestPort);
    306                     default: return QVariant();
    307                 }
    308             }
    309             /* Alignment role: */
    310             case Qt::TextAlignmentRole:
    311             {
    312                 /* Switch for different columns: */
    313                 switch (index.column())
    314                 {
    315                     case UIPortForwardingDataType_Name:
    316                     case UIPortForwardingDataType_Protocol:
    317                     case UIPortForwardingDataType_HostPort:
    318                     case UIPortForwardingDataType_GuestPort:
    319                         return (int)(Qt::AlignLeft | Qt::AlignVCenter);
    320                     case UIPortForwardingDataType_HostIp:
    321                     case UIPortForwardingDataType_GuestIp:
    322                         return Qt::AlignCenter;
    323                     default: return QVariant();
    324                 }
    325             }
    326             case Qt::SizeHintRole:
    327             {
    328                 /* Switch for different columns: */
    329                 switch (index.column())
    330                 {
    331                     case UIPortForwardingDataType_HostIp:
    332                     case UIPortForwardingDataType_GuestIp:
    333                         return QSize(QApplication::fontMetrics().width(" 888.888.888.888 "), QApplication::fontMetrics().height());
    334                     default: return QVariant();
    335                 }
    336             }
    337             default: break;
    338         }
    339         /* Return wrong value: */
    340         return QVariant();
    341     }
    342 
    343     /* Set index data: */
    344     bool setData(const QModelIndex &index, const QVariant &value, int iRole = Qt::EditRole)
    345     {
    346         /* Check index validness: */
    347         if (!index.isValid() || iRole != Qt::EditRole)
    348             return false;
    349         /* Switch for different columns: */
    350         switch (index.column())
    351         {
    352             case UIPortForwardingDataType_Name:
    353                 m_dataList[index.row()].name = value.value<NameData>();
    354                 emit dataChanged(index, index);
    355                 return true;
    356             case UIPortForwardingDataType_Protocol:
    357                 m_dataList[index.row()].protocol = value.value<KNATProtocol>();
    358                 emit dataChanged(index, index);
    359                 return true;
    360             case UIPortForwardingDataType_HostIp:
    361                 m_dataList[index.row()].hostIp = value.value<IpData>();
    362                 emit dataChanged(index, index);
    363                 return true;
    364             case UIPortForwardingDataType_HostPort:
    365                 m_dataList[index.row()].hostPort = value.value<PortData>();
    366                 emit dataChanged(index, index);
    367                 return true;
    368             case UIPortForwardingDataType_GuestIp:
    369                 m_dataList[index.row()].guestIp = value.value<IpData>();
    370                 emit dataChanged(index, index);
    371                 return true;
    372             case UIPortForwardingDataType_GuestPort:
    373                 m_dataList[index.row()].guestPort = value.value<PortData>();
    374                 emit dataChanged(index, index);
    375                 return true;
    376             default: return false;
    377         }
    378         /* Return false value: */
    379         return false;
    380     }
    381 
    382     /* Add/Copy rule: */
    383     void addRule(const QModelIndex &index)
    384     {
    385         beginInsertRows(QModelIndex(), m_dataList.size(), m_dataList.size());
    386         /* Search for existing "Rule [NUMBER]" record: */
    387         uint uMaxIndex = 0;
    388         QString strTemplate("Rule %1");
    389         QRegExp regExp(strTemplate.arg("(\\d+)"));
    390         for (int i = 0; i < m_dataList.size(); ++i)
    391             if (regExp.indexIn(m_dataList[i].name) > -1)
    392                 uMaxIndex = regExp.cap(1).toUInt() > uMaxIndex ? regExp.cap(1).toUInt() : uMaxIndex;
    393         /* If index is valid => copy data: */
    394         if (index.isValid())
    395             m_dataList << UIPortForwardingData(strTemplate.arg(++uMaxIndex), m_dataList[index.row()].protocol,
    396                                                m_dataList[index.row()].hostIp, m_dataList[index.row()].hostPort,
    397                                                m_dataList[index.row()].guestIp, m_dataList[index.row()].guestPort);
    398         /* If index is NOT valid => use default values: */
    399         else
    400             m_dataList << UIPortForwardingData(strTemplate.arg(++uMaxIndex), KNATProtocol_TCP,
    401                                                QString(""), 0, QString(""), 0);
    402         endInsertRows();
    403     }
    404 
    405     /* Delete rule: */
    406     void delRule(const QModelIndex &index)
    407     {
    408         if (!index.isValid())
    409             return;
    410         beginRemoveRows(QModelIndex(), index.row(), index.row());
    411         m_dataList.removeAt(index.row());
    412         endRemoveRows();
    413     }
    414 
    415 private:
    416 
    417     /* Data container: */
    418     UIPortForwardingDataList m_dataList;
    419 };
    420 
    421 /* Port forwarding dialog constructor: */
    422 UIMachineSettingsPortForwardingDlg::UIMachineSettingsPortForwardingDlg(QWidget *pParent,
    423                                                                  const UIPortForwardingDataList &rules)
    424     : QIWithRetranslateUI<QIDialog>(pParent)
    425     , fIsTableDataChanged(false)
    426     , m_pTableView(0)
    427     , m_pToolBar(0)
    428     , m_pButtonBox(0)
    429     , m_pModel(0)
    430     , m_pAddAction(0)
    431     , m_pCopyAction(0)
    432     , m_pDelAction(0)
    433 {
    434 #ifdef Q_WS_MAC
    435     setWindowFlags(Qt::Sheet);
    436 #endif /* Q_WS_MAC */
    437 
    43835    /* Set dialog icon: */
    43936    setWindowIcon(UIIconPool::iconSetFull(QSize(32, 32), QSize(16, 16), ":/nw_32px.png", ":/nw_16px.png"));
    44037
    441     /* Create table: */
    442     m_pTableView = new QITableView(this);
    443     m_pTableView->setTabKeyNavigation(false);
    444     m_pTableView->verticalHeader()->hide();
    445     m_pTableView->verticalHeader()->setDefaultSectionSize((int)(m_pTableView->verticalHeader()->minimumSectionSize() * 1.33));
    446     m_pTableView->setSelectionMode(QAbstractItemView::SingleSelection);
    447     m_pTableView->setContextMenuPolicy(Qt::CustomContextMenu);
    448     m_pTableView->installEventFilter(this);
    449     connect(m_pTableView, SIGNAL(sigCurrentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(sltCurrentChanged()));
    450     connect(m_pTableView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(sltShowTableContexMenu(const QPoint &)));
    451 
    452     /* Create actions: */
    453     m_pAddAction = new QAction(this);
    454     m_pCopyAction = new QAction(this);
    455     m_pDelAction = new QAction(this);
    456     m_pAddAction->setShortcut(QKeySequence("Ins"));
    457     m_pDelAction->setShortcut(QKeySequence("Del"));
    458     m_pAddAction->setIcon(UIIconPool::iconSet(":/controller_add_16px.png", ":/controller_add_disabled_16px.png"));
    459     m_pCopyAction->setIcon(UIIconPool::iconSet(":/controller_add_16px.png", ":/controller_add_disabled_16px.png"));
    460     m_pDelAction->setIcon(UIIconPool::iconSet(":/controller_remove_16px.png", ":/controller_remove_disabled_16px.png"));
    461     connect(m_pAddAction, SIGNAL(triggered(bool)), this, SLOT(sltAddRule()));
    462     connect(m_pCopyAction, SIGNAL(triggered(bool)), this, SLOT(sltCopyRule()));
    463     connect(m_pDelAction, SIGNAL(triggered(bool)), this, SLOT(sltDelRule()));
    464 
    465     /* Create toolbar: */
    466     m_pToolBar = new UIToolBar(this);
    467     m_pToolBar->setIconSize(QSize(16, 16));
    468     m_pToolBar->setOrientation(Qt::Vertical);
    469     m_pToolBar->addAction(m_pAddAction);
    470     m_pToolBar->addAction(m_pDelAction);
    471 
    472     /* Create table & toolbar layout: */
    473     QHBoxLayout *pTableAndToolbarLayout = new QHBoxLayout;
    474     pTableAndToolbarLayout->setSpacing(1);
    475     pTableAndToolbarLayout->addWidget(m_pTableView);
    476     pTableAndToolbarLayout->addWidget(m_pToolBar);
    477 
    478     /* Create buttonbox: */
    479     m_pButtonBox = new QIDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
    480     connect(m_pButtonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept()));
    481     connect(m_pButtonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject()));
    482 
    483     /* Create main layout: */
    484     QVBoxLayout *pMainLayout = new QVBoxLayout;
    485     this->setLayout(pMainLayout);
    486     pMainLayout->addLayout(pTableAndToolbarLayout);
    487     pMainLayout->addWidget(m_pButtonBox);
    488 
    489     /* Create model: */
    490     m_pModel = new UIPortForwardingModel(this, rules);
    491     connect(m_pModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(sltTableDataChanged()));
    492     connect(m_pModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(sltTableDataChanged()));
    493     connect(m_pModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(sltTableDataChanged()));
    494     m_pTableView->setModel(m_pModel);
    495 
    496     /* Register delegates editors: */
    497     if (QAbstractItemDelegate *pAbstractItemDelegate = m_pTableView->itemDelegate())
     38    /* Create layout: */
     39    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
    49840    {
    499         if (QStyledItemDelegate *pStyledItemDelegate = qobject_cast<QStyledItemDelegate*>(pAbstractItemDelegate))
     41        /* Create table: */
     42        m_pTable = new UIPortForwardingTable(rules);
     43        /* Create button-box: */
     44        m_pButtonBox = new QIDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);
    50045        {
    501             /* Create new item editor factory: */
    502             QItemEditorFactory *pNewItemEditorFactory = new QItemEditorFactory;
    503 
    504             /* Register name type: */
    505             int iNameId = qRegisterMetaType<NameData>();
    506             /* Register name editor: */
    507             QStandardItemEditorCreator<NameEditor> *pNameEditorItemCreator = new QStandardItemEditorCreator<NameEditor>();
    508             /* Link name type & editor: */
    509             pNewItemEditorFactory->registerEditor((QVariant::Type)iNameId, pNameEditorItemCreator);
    510 
    511             /* Register protocol type: */
    512             int iProtocolId = qRegisterMetaType<KNATProtocol>();
    513             /* Register protocol editor: */
    514             QStandardItemEditorCreator<ProtocolEditor> *pProtocolEditorItemCreator = new QStandardItemEditorCreator<ProtocolEditor>();
    515             /* Link protocol type & editor: */
    516             pNewItemEditorFactory->registerEditor((QVariant::Type)iProtocolId, pProtocolEditorItemCreator);
    517 
    518             /* Register ip type: */
    519             int iIpId = qRegisterMetaType<IpData>();
    520             /* Register ip editor: */
    521             QStandardItemEditorCreator<IPEditor> *pIpEditorItemCreator = new QStandardItemEditorCreator<IPEditor>();
    522             /* Link ip type & editor: */
    523             pNewItemEditorFactory->registerEditor((QVariant::Type)iIpId, pIpEditorItemCreator);
    524 
    525             /* Register port type: */
    526             int iPortId = qRegisterMetaType<PortData>();
    527             /* Register port editor: */
    528             QStandardItemEditorCreator<PortEditor> *pPortEditorItemCreator = new QStandardItemEditorCreator<PortEditor>();
    529             /* Link port type & editor: */
    530             pNewItemEditorFactory->registerEditor((QVariant::Type)iPortId, pPortEditorItemCreator);
    531 
    532             /* Set newly created item editor factory for table delegate: */
    533             pStyledItemDelegate->setItemEditorFactory(pNewItemEditorFactory);
     46            /* Configure button-box: */
     47            connect(m_pButtonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept()));
     48            connect(m_pButtonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject()));
    53449        }
     50        /* Add widgets into layout: */
     51        pMainLayout->addWidget(m_pTable);
     52        pMainLayout->addWidget(m_pButtonBox);
    53553    }
    53654
    53755    /* Retranslate dialog: */
    53856    retranslateUi();
    539 
    540     /* Minimum Size: */
    541     setMinimumSize(600, 300);
    542 }
    543 
    544 /* Port forwarding dialog destructor: */
    545 UIMachineSettingsPortForwardingDlg::~UIMachineSettingsPortForwardingDlg()
    546 {
    54757}
    54858
    54959const UIPortForwardingDataList& UIMachineSettingsPortForwardingDlg::rules() const
    55060{
    551     return m_pModel->rules();
    552 }
    553 
    554 /* Add rule slot: */
    555 void UIMachineSettingsPortForwardingDlg::sltAddRule()
    556 {
    557     m_pModel->addRule(QModelIndex());
    558     m_pTableView->setFocus();
    559     m_pTableView->setCurrentIndex(m_pModel->index(m_pModel->rowCount() - 1, 0));
    560     sltCurrentChanged();
    561     sltAdjustTable();
    562 }
    563 
    564 /* Copy rule slot: */
    565 void UIMachineSettingsPortForwardingDlg::sltCopyRule()
    566 {
    567     m_pModel->addRule(m_pTableView->currentIndex());
    568     m_pTableView->setFocus();
    569     m_pTableView->setCurrentIndex(m_pModel->index(m_pModel->rowCount() - 1, 0));
    570     sltCurrentChanged();
    571     sltAdjustTable();
    572 }
    573 
    574 /* Del rule slot: */
    575 void UIMachineSettingsPortForwardingDlg::sltDelRule()
    576 {
    577     m_pModel->delRule(m_pTableView->currentIndex());
    578     m_pTableView->setFocus();
    579     sltCurrentChanged();
    580     sltAdjustTable();
    581 }
    582 
    583 /* Table data change handler: */
    584 void UIMachineSettingsPortForwardingDlg::sltTableDataChanged()
    585 {
    586     fIsTableDataChanged = true;
    587 }
    588 
    589 /* Table index-change handler: */
    590 void UIMachineSettingsPortForwardingDlg::sltCurrentChanged()
    591 {
    592     bool fTableFocused = m_pTableView->hasFocus();
    593     bool fTableChildrenFocused = m_pTableView->findChildren<QWidget*>().contains(QApplication::focusWidget());
    594     bool fTableOrChildrenFocused = fTableFocused || fTableChildrenFocused;
    595     m_pCopyAction->setEnabled(m_pTableView->currentIndex().isValid() && fTableOrChildrenFocused);
    596     m_pDelAction->setEnabled(m_pTableView->currentIndex().isValid() && fTableOrChildrenFocused);
    597 }
    598 
    599 /* Table context-menu handler: */
    600 void UIMachineSettingsPortForwardingDlg::sltShowTableContexMenu(const QPoint &pos)
    601 {
    602     /* Prepare context menu: */
    603     QMenu menu(m_pTableView);
    604     /* If some index is currently selected: */
    605     if (m_pTableView->indexAt(pos).isValid())
    606     {
    607         menu.addAction(m_pCopyAction);
    608         menu.addAction(m_pDelAction);
    609     }
    610     /* If no valid index selected: */
    611     else
    612     {
    613         menu.addAction(m_pAddAction);
    614     }
    615     menu.exec(m_pTableView->viewport()->mapToGlobal(pos));
    616 }
    617 
    618 /* Adjusts table column's sizes: */
    619 void UIMachineSettingsPortForwardingDlg::sltAdjustTable()
    620 {
    621     m_pTableView->horizontalHeader()->setStretchLastSection(false);
    622     /* If table is NOT empty: */
    623     if (m_pModel->rowCount())
    624     {
    625         /* Resize table to contents size-hint and emit a spare place for first column: */
    626         m_pTableView->resizeColumnsToContents();
    627         uint uFullWidth = m_pTableView->viewport()->width();
    628         for (uint u = 1; u < UIPortForwardingModel::UIPortForwardingDataType_Max; ++u)
    629             uFullWidth -= m_pTableView->horizontalHeader()->sectionSize(u);
    630         m_pTableView->horizontalHeader()->resizeSection(UIPortForwardingModel::UIPortForwardingDataType_Name, uFullWidth);
    631     }
    632     /* If table is empty: */
    633     else
    634     {
    635         /* Resize table columns to be equal in size: */
    636         uint uFullWidth = m_pTableView->viewport()->width();
    637         for (uint u = 0; u < UIPortForwardingModel::UIPortForwardingDataType_Max; ++u)
    638             m_pTableView->horizontalHeader()->resizeSection(u, uFullWidth / UIPortForwardingModel::UIPortForwardingDataType_Max);
    639     }
    640     m_pTableView->horizontalHeader()->setStretchLastSection(true);
     61    return m_pTable->rules();
    64162}
    64263
     
    64465{
    64566    /* Validate table: */
    646     for (int i = 0; i < m_pModel->rowCount(); ++i)
    647     {
    648         if (m_pModel->data(m_pModel->index(i, UIPortForwardingModel::UIPortForwardingDataType_HostPort), Qt::EditRole).value<PortData>().value() == 0 ||
    649             m_pModel->data(m_pModel->index(i, UIPortForwardingModel::UIPortForwardingDataType_GuestPort), Qt::EditRole).value<PortData>().value() == 0)
    650         {
    651             msgCenter().warnAboutIncorrectPort(this);
    652             return;
    653         }
    654     }
    655     /* Base class accept() slot: */
     67    bool fPassed = m_pTable->validate();
     68    if (!fPassed)
     69        return;
     70    /* Call to base-class: */
    65671    QIWithRetranslateUI<QIDialog>::accept();
    65772}
     
    65974void UIMachineSettingsPortForwardingDlg::reject()
    66075{
    661     /* Check if table data was changed: */
    662     if (fIsTableDataChanged && !msgCenter().confirmCancelingPortForwardingDialog(this))
     76    /* Discard table: */
     77    bool fPassed = m_pTable->discard();
     78    if (!fPassed)
    66379        return;
    664     /* Base class reject() slot: */
     80    /* Call to base-class: */
    66581    QIWithRetranslateUI<QIDialog>::reject();
    66682}
    66783
    668 /* UI Retranslation slot: */
    66984void UIMachineSettingsPortForwardingDlg::retranslateUi()
    67085{
    67186    /* Set window title: */
    67287    setWindowTitle(tr("Port Forwarding Rules"));
    673 
    674     /* Table translations: */
    675     m_pTableView->setWhatsThis(tr("This table contains a list of port forwarding rules."));
    676 
    677     /* Set action's text: */
    678     m_pAddAction->setText(tr("Insert new rule"));
    679     m_pCopyAction->setText(tr("Copy selected rule"));
    680     m_pDelAction->setText(tr("Delete selected rule"));
    681     m_pAddAction->setWhatsThis(tr("This button adds new port forwarding rule."));
    682     m_pDelAction->setWhatsThis(tr("This button deletes selected port forwarding rule."));
    683     m_pAddAction->setToolTip(QString("%1 (%2)").arg(m_pAddAction->text()).arg(m_pAddAction->shortcut().toString()));
    684     m_pDelAction->setToolTip(QString("%1 (%2)").arg(m_pDelAction->text()).arg(m_pDelAction->shortcut().toString()));
    68588}
    68689
    687 /* Extended event-handler: */
    688 bool UIMachineSettingsPortForwardingDlg::eventFilter(QObject *pObj, QEvent *pEvent)
    689 {
    690     /* Process table: */
    691     if (pObj == m_pTableView)
    692     {
    693         /* Switch for different event-types: */
    694         switch (pEvent->type())
    695         {
    696             case QEvent::FocusIn:
    697             case QEvent::FocusOut:
    698                 /* Update actions: */
    699                 sltCurrentChanged();
    700                 break;
    701             case QEvent::Show:
    702             case QEvent::Resize:
    703             {
    704                 /* Instant table adjusting: */
    705                 sltAdjustTable();
    706                 /* Delayed table adjusting: */
    707                 QTimer::singleShot(0, this, SLOT(sltAdjustTable()));
    708                 break;
    709             }
    710             default:
    711                 break;
    712         }
    713     }
    714     /* Continue with base-class processing: */
    715     return QIWithRetranslateUI<QIDialog>::eventFilter(pObj, pEvent);
    716 }
    717 
    718 #include "UIMachineSettingsPortForwardingDlg.moc"
    719 
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsPortForwardingDlg.h

    r44529 r48533  
    66
    77/*
    8  * Copyright (C) 2010-2012 Oracle Corporation
     8 * Copyright (C) 2010-2013 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2020#define __UIMachineSettingsPortForwardingDlg_h__
    2121
    22 /* GUI includes */
     22/* GUI includes: */
    2323#include "QIWithRetranslateUI.h"
    2424#include "QIDialog.h"
    25 
    26 /* COM includes: */
    27 #include "COMEnums.h"
     25#include "UIPortForwardingTable.h"
    2826
    2927/* Forward declarations: */
    30 class QITableView;
    31 class UIToolBar;
    3228class QIDialogButtonBox;
    33 class UIPortForwardingModel;
    3429
    35 /* Name data: */
    36 class NameData : public QString
    37 {
    38 public:
    39 
    40     NameData() : QString() {}
    41     NameData(const QString &ruleName) : QString(ruleName) {}
    42 };
    43 Q_DECLARE_METATYPE(NameData);
    44 
    45 /* Ip data: */
    46 class IpData : public QString
    47 {
    48 public:
    49 
    50     IpData() : QString() {}
    51     IpData(const QString &ipAddress) : QString(ipAddress) {}
    52 };
    53 Q_DECLARE_METATYPE(IpData);
    54 
    55 /* Port data: */
    56 class PortData
    57 {
    58 public:
    59 
    60     PortData() : m_uValue(0) {}
    61     PortData(ushort uValue) : m_uValue(uValue) {}
    62     PortData(const PortData &other) : m_uValue(other.value()) {}
    63     bool operator==(const PortData &other) { return m_uValue == other.m_uValue; }
    64     ushort value() const { return m_uValue; }
    65 
    66 private:
    67 
    68     ushort m_uValue;
    69 };
    70 Q_DECLARE_METATYPE(PortData);
    71 
    72 /* Port forwarding data: */
    73 struct UIPortForwardingData
    74 {
    75     UIPortForwardingData(const NameData &strName, KNATProtocol eProtocol,
    76                          const IpData &strHostIp, PortData uHostPort,
    77                          const IpData &strGuestIp, PortData uGuestPort)
    78         : name(strName), protocol(eProtocol)
    79         , hostIp(strHostIp), hostPort(uHostPort)
    80         , guestIp(strGuestIp), guestPort(uGuestPort) {}
    81     bool operator==(const UIPortForwardingData &other)
    82     {
    83         return name == other.name &&
    84                protocol == other.protocol &&
    85                hostIp == other.hostIp &&
    86                hostPort == other.hostPort &&
    87                guestIp == other.guestIp &&
    88                guestPort == other.guestPort;
    89     }
    90     NameData name;
    91     KNATProtocol protocol;
    92     IpData hostIp;
    93     PortData hostPort;
    94     IpData guestIp;
    95     PortData guestPort;
    96 };
    97 
    98 /* Port forwarding data list: */
    99 typedef QList<UIPortForwardingData> UIPortForwardingDataList;
    100 
    101 /* Port forwarding dialog: */
     30/* Machine settings / Network page / NAT attachment / Port forwarding dialog: */
    10231class UIMachineSettingsPortForwardingDlg : public QIWithRetranslateUI<QIDialog>
    10332{
     
    10635public:
    10736
    108     /* Port forwarding dialog constructor: */
    109     UIMachineSettingsPortForwardingDlg(QWidget *pParent = 0,
    110                                     const UIPortForwardingDataList &rules = UIPortForwardingDataList());
    111     /* Port forwarding dialog destructor: */
    112     ~UIMachineSettingsPortForwardingDlg();
     37    /* Constructor/destructor: */
     38    UIMachineSettingsPortForwardingDlg(QWidget *pParent,
     39                                       const UIPortForwardingDataList &rules = UIPortForwardingDataList());
    11340
    114     /* The list of chosen rules: */
     41    /* API: Rules stuff: */
    11542    const UIPortForwardingDataList& rules() const;
    11643
    11744private slots:
    11845
    119     /* Action's slots: */
    120     void sltAddRule();
    121     void sltCopyRule();
    122     void sltDelRule();
    123 
    124     /* Table slots: */
    125     void sltTableDataChanged();
    126     void sltCurrentChanged();
    127     void sltShowTableContexMenu(const QPoint &position);
    128     void sltAdjustTable();
    129 
    130     /* Dialog slots: */
     46    /* Handlers: Dialog stuff: */
    13147    void accept();
    13248    void reject();
     
    13450private:
    13551
    136     /* UI Translator: */
     52    /* Handler: Translation stuff: */
    13753    void retranslateUi();
    13854
    139     /* Event filter: */
    140     bool eventFilter(QObject *pObj, QEvent *pEvent);
    141 
    142     /* Flags: */
    143     bool fIsTableDataChanged;
    144 
    14555    /* Widgets: */
    146     QITableView *m_pTableView;
    147     UIToolBar *m_pToolBar;
     56    UIPortForwardingTable *m_pTable;
    14857    QIDialogButtonBox *m_pButtonBox;
    149 
    150     /* Model: */
    151     UIPortForwardingModel *m_pModel;
    152 
    153     /* Actions: */
    154     QAction *m_pAddAction;
    155     QAction *m_pCopyAction;
    156     QAction *m_pDelAction;
    15758};
    15859
    15960#endif // __UIMachineSettingsPortForwardingDlg_h__
    160 
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIPortForwardingTable.cpp

    r48528 r48533  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UIMachineSettingsPortForwardingDlg class implementation
     5 * UIPortForwardingTable class implementation
    66 */
    77
    88/*
    9  * Copyright (C) 2010-2012 Oracle Corporation
     9 * Copyright (C) 2010-2013 Oracle Corporation
    1010 *
    1111 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2323#include <QAction>
    2424#include <QHeaderView>
    25 #include <QPushButton>
    2625#include <QStyledItemDelegate>
    2726#include <QItemEditorFactory>
     
    2928#include <QLineEdit>
    3029#include <QSpinBox>
    31 #include <QTimer>
    3230
    3331/* GUI includes: */
    34 #include "UIMachineSettingsPortForwardingDlg.h"
     32#include "UIPortForwardingTable.h"
    3533#include "UIMessageCenter.h"
     34#include "UIConverter.h"
     35#include "UIIconPool.h"
    3636#include "UIToolBar.h"
    3737#include "QITableView.h"
    38 #include "QIDialogButtonBox.h"
    39 #include "UIIconPool.h"
    40 #include "UIConverter.h"
    4138
    4239/* Other VBox includes: */
     
    5350public:
    5451
     52    /* Constructor/destructor: */
    5553    IPValidator(QObject *pParent) : QValidator(pParent) {}
    5654    ~IPValidator() {}
    5755
    58     QValidator::State validate(QString &strInput, int & /* iPos */) const
     56    /* Handler: Validation stuff: */
     57    QValidator::State validate(QString &strInput, int& /*iPos*/) const
    5958    {
    6059        QString strStringToValidate(strInput);
     
    8180public:
    8281
     82    /* Constructor: */
    8383    NameEditor(QWidget *pParent = 0) : QLineEdit(pParent)
    8484    {
     
    9090private:
    9191
     92    /* API: Name stuff: */
    9293    void setName(NameData name)
    9394    {
     
    9596    }
    9697
     98    /* API: Name stuff: */
    9799    NameData name() const
    98100    {
     
    109111public:
    110112
     113    /* Constructor: */
    111114    ProtocolEditor(QWidget *pParent = 0) : QComboBox(pParent)
    112115    {
     
    117120private:
    118121
     122    /* API: Protocol stuff: */
    119123    void setProtocol(KNATProtocol p)
    120124    {
     
    129133    }
    130134
     135    /* API: Protocol stuff: */
    131136    KNATProtocol protocol() const
    132137    {
     
    143148public:
    144149
     150    /* Constructor: */
    145151    IPEditor(QWidget *pParent = 0) : QLineEdit(pParent)
    146152    {
     
    153159private:
    154160
     161    /* API: IP stuff: */
    155162    void setIp(IpData ip)
    156163    {
     
    158165    }
    159166
     167    /* API: IP stuff: */
    160168    IpData ip() const
    161169    {
     
    172180public:
    173181
     182    /* Constructor: */
    174183    PortEditor(QWidget *pParent = 0) : QSpinBox(pParent)
    175184    {
     
    180189private:
    181190
     191    /* API: Port stuff: */
    182192    void setPort(PortData port)
    183193    {
     
    185195    }
    186196
     197    /* API: Port stuff: */
    187198    PortData port() const
    188199    {
     
    198209public:
    199210
    200     /* Column names: */
     211    /* Enum: Column names: */
    201212    enum UIPortForwardingDataType
    202213    {
     
    210221    };
    211222
    212     /* Port forwarding model constructor: */
     223    /* Constructor: */
    213224    UIPortForwardingModel(QObject *pParent = 0, const UIPortForwardingDataList &rules = UIPortForwardingDataList())
    214         : QAbstractTableModel(pParent), m_dataList(rules) {}
    215     /* Port forwarding model destructor: */
    216     ~UIPortForwardingModel() {}
    217 
    218     /* The list of chosen rules: */
    219     const UIPortForwardingDataList& rules() const
    220     {
    221         return m_dataList;
    222     }
    223 
    224     /* Flags for model indexes: */
    225     Qt::ItemFlags flags(const QModelIndex &index) const
    226     {
    227         /* Check index validness: */
    228         if (!index.isValid())
    229             return Qt::NoItemFlags;
    230         /* All columns have similar flags: */
    231         return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
    232     }
    233 
    234     /* Row count getter: */
    235     int rowCount(const QModelIndex & parent = QModelIndex()) const
    236     {
    237         Q_UNUSED(parent);
    238         return m_dataList.size();
    239     }
    240 
    241     /* Column count getter: */
    242     int columnCount(const QModelIndex & parent = QModelIndex()) const
    243     {
    244         Q_UNUSED(parent);
    245         return UIPortForwardingDataType_Max;
    246     }
    247 
    248     /* Get header data: */
    249     QVariant headerData(int iSection, Qt::Orientation orientation, int iRole) const
    250     {
    251         /* Display role for horizontal header: */
    252         if (iRole == Qt::DisplayRole && orientation == Qt::Horizontal)
    253         {
    254             /* Switch for different columns: */
    255             switch (iSection)
    256             {
    257                 case UIPortForwardingDataType_Name: return tr("Name");
    258                 case UIPortForwardingDataType_Protocol: return tr("Protocol");
    259                 case UIPortForwardingDataType_HostIp: return tr("Host IP");
    260                 case UIPortForwardingDataType_HostPort: return tr("Host Port");
    261                 case UIPortForwardingDataType_GuestIp: return tr("Guest IP");
    262                 case UIPortForwardingDataType_GuestPort: return tr("Guest Port");
    263                 default: break;
    264             }
    265         }
    266         /* Return wrong value: */
    267         return QVariant();
    268     }
    269 
    270     /* Get index data: */
    271     QVariant data(const QModelIndex &index, int iRole) const
    272     {
    273         /* Check index validness: */
    274         if (!index.isValid())
    275             return QVariant();
    276         /* Switch for different roles: */
    277         switch (iRole)
    278         {
    279             /* Display role: */
    280             case Qt::DisplayRole:
    281             {
    282                 /* Switch for different columns: */
    283                 switch (index.column())
    284                 {
    285                     case UIPortForwardingDataType_Name: return m_dataList[index.row()].name;
    286                     case UIPortForwardingDataType_Protocol: return gpConverter->toString(m_dataList[index.row()].protocol);
    287                     case UIPortForwardingDataType_HostIp: return m_dataList[index.row()].hostIp;
    288                     case UIPortForwardingDataType_HostPort: return m_dataList[index.row()].hostPort.value();
    289                     case UIPortForwardingDataType_GuestIp: return m_dataList[index.row()].guestIp;
    290                     case UIPortForwardingDataType_GuestPort: return m_dataList[index.row()].guestPort.value();
    291                     default: return QVariant();
    292                 }
    293             }
    294             /* Edit role: */
    295             case Qt::EditRole:
    296             {
    297                 /* Switch for different columns: */
    298                 switch (index.column())
    299                 {
    300                     case UIPortForwardingDataType_Name: return QVariant::fromValue(m_dataList[index.row()].name);
    301                     case UIPortForwardingDataType_Protocol: return QVariant::fromValue(m_dataList[index.row()].protocol);
    302                     case UIPortForwardingDataType_HostIp: return QVariant::fromValue(m_dataList[index.row()].hostIp);
    303                     case UIPortForwardingDataType_HostPort: return QVariant::fromValue(m_dataList[index.row()].hostPort);
    304                     case UIPortForwardingDataType_GuestIp: return QVariant::fromValue(m_dataList[index.row()].guestIp);
    305                     case UIPortForwardingDataType_GuestPort: return QVariant::fromValue(m_dataList[index.row()].guestPort);
    306                     default: return QVariant();
    307                 }
    308             }
    309             /* Alignment role: */
    310             case Qt::TextAlignmentRole:
    311             {
    312                 /* Switch for different columns: */
    313                 switch (index.column())
    314                 {
    315                     case UIPortForwardingDataType_Name:
    316                     case UIPortForwardingDataType_Protocol:
    317                     case UIPortForwardingDataType_HostPort:
    318                     case UIPortForwardingDataType_GuestPort:
    319                         return (int)(Qt::AlignLeft | Qt::AlignVCenter);
    320                     case UIPortForwardingDataType_HostIp:
    321                     case UIPortForwardingDataType_GuestIp:
    322                         return Qt::AlignCenter;
    323                     default: return QVariant();
    324                 }
    325             }
    326             case Qt::SizeHintRole:
    327             {
    328                 /* Switch for different columns: */
    329                 switch (index.column())
    330                 {
    331                     case UIPortForwardingDataType_HostIp:
    332                     case UIPortForwardingDataType_GuestIp:
    333                         return QSize(QApplication::fontMetrics().width(" 888.888.888.888 "), QApplication::fontMetrics().height());
    334                     default: return QVariant();
    335                 }
    336             }
    337             default: break;
    338         }
    339         /* Return wrong value: */
    340         return QVariant();
    341     }
    342 
    343     /* Set index data: */
    344     bool setData(const QModelIndex &index, const QVariant &value, int iRole = Qt::EditRole)
    345     {
    346         /* Check index validness: */
    347         if (!index.isValid() || iRole != Qt::EditRole)
    348             return false;
    349         /* Switch for different columns: */
    350         switch (index.column())
    351         {
    352             case UIPortForwardingDataType_Name:
    353                 m_dataList[index.row()].name = value.value<NameData>();
    354                 emit dataChanged(index, index);
    355                 return true;
    356             case UIPortForwardingDataType_Protocol:
    357                 m_dataList[index.row()].protocol = value.value<KNATProtocol>();
    358                 emit dataChanged(index, index);
    359                 return true;
    360             case UIPortForwardingDataType_HostIp:
    361                 m_dataList[index.row()].hostIp = value.value<IpData>();
    362                 emit dataChanged(index, index);
    363                 return true;
    364             case UIPortForwardingDataType_HostPort:
    365                 m_dataList[index.row()].hostPort = value.value<PortData>();
    366                 emit dataChanged(index, index);
    367                 return true;
    368             case UIPortForwardingDataType_GuestIp:
    369                 m_dataList[index.row()].guestIp = value.value<IpData>();
    370                 emit dataChanged(index, index);
    371                 return true;
    372             case UIPortForwardingDataType_GuestPort:
    373                 m_dataList[index.row()].guestPort = value.value<PortData>();
    374                 emit dataChanged(index, index);
    375                 return true;
    376             default: return false;
    377         }
    378         /* Return false value: */
    379         return false;
    380     }
    381 
    382     /* Add/Copy rule: */
    383     void addRule(const QModelIndex &index)
    384     {
    385         beginInsertRows(QModelIndex(), m_dataList.size(), m_dataList.size());
    386         /* Search for existing "Rule [NUMBER]" record: */
    387         uint uMaxIndex = 0;
    388         QString strTemplate("Rule %1");
    389         QRegExp regExp(strTemplate.arg("(\\d+)"));
    390         for (int i = 0; i < m_dataList.size(); ++i)
    391             if (regExp.indexIn(m_dataList[i].name) > -1)
    392                 uMaxIndex = regExp.cap(1).toUInt() > uMaxIndex ? regExp.cap(1).toUInt() : uMaxIndex;
    393         /* If index is valid => copy data: */
    394         if (index.isValid())
    395             m_dataList << UIPortForwardingData(strTemplate.arg(++uMaxIndex), m_dataList[index.row()].protocol,
    396                                                m_dataList[index.row()].hostIp, m_dataList[index.row()].hostPort,
    397                                                m_dataList[index.row()].guestIp, m_dataList[index.row()].guestPort);
    398         /* If index is NOT valid => use default values: */
    399         else
    400             m_dataList << UIPortForwardingData(strTemplate.arg(++uMaxIndex), KNATProtocol_TCP,
    401                                                QString(""), 0, QString(""), 0);
    402         endInsertRows();
    403     }
    404 
    405     /* Delete rule: */
    406     void delRule(const QModelIndex &index)
    407     {
    408         if (!index.isValid())
    409             return;
    410         beginRemoveRows(QModelIndex(), index.row(), index.row());
    411         m_dataList.removeAt(index.row());
    412         endRemoveRows();
    413     }
     225        : QAbstractTableModel(pParent)
     226        , m_dataList(rules) {}
     227
     228    /* API: Rule stuff: */
     229    const UIPortForwardingDataList& rules() const { return m_dataList; }
     230    void addRule(const QModelIndex &index);
     231    void delRule(const QModelIndex &index);
     232
     233    /* API: Index flag stuff: */
     234    Qt::ItemFlags flags(const QModelIndex &index) const;
     235
     236    /* API: Index row-count stuff: */
     237    int rowCount(const QModelIndex &parent = QModelIndex()) const;
     238
     239    /* API: Index column-count stuff: */
     240    int columnCount(const QModelIndex &parent = QModelIndex()) const;
     241
     242    /* API: Header data stuff: */
     243    QVariant headerData(int iSection, Qt::Orientation orientation, int iRole) const;
     244
     245    /* API: Index data stuff: */
     246    QVariant data(const QModelIndex &index, int iRole) const;
     247    bool setData(const QModelIndex &index, const QVariant &value, int iRole = Qt::EditRole);
    414248
    415249private:
    416250
    417     /* Data container: */
     251    /* Variable: Data stuff: */
    418252    UIPortForwardingDataList m_dataList;
    419253};
    420254
    421 /* Port forwarding dialog constructor: */
    422 UIMachineSettingsPortForwardingDlg::UIMachineSettingsPortForwardingDlg(QWidget *pParent,
    423                                                                  const UIPortForwardingDataList &rules)
    424     : QIWithRetranslateUI<QIDialog>(pParent)
    425     , fIsTableDataChanged(false)
     255void UIPortForwardingModel::addRule(const QModelIndex &index)
     256{
     257    beginInsertRows(QModelIndex(), m_dataList.size(), m_dataList.size());
     258    /* Search for existing "Rule [NUMBER]" record: */
     259    uint uMaxIndex = 0;
     260    QString strTemplate("Rule %1");
     261    QRegExp regExp(strTemplate.arg("(\\d+)"));
     262    for (int i = 0; i < m_dataList.size(); ++i)
     263        if (regExp.indexIn(m_dataList[i].name) > -1)
     264            uMaxIndex = regExp.cap(1).toUInt() > uMaxIndex ? regExp.cap(1).toUInt() : uMaxIndex;
     265    /* If index is valid => copy data: */
     266    if (index.isValid())
     267        m_dataList << UIPortForwardingData(strTemplate.arg(++uMaxIndex), m_dataList[index.row()].protocol,
     268                                           m_dataList[index.row()].hostIp, m_dataList[index.row()].hostPort,
     269                                           m_dataList[index.row()].guestIp, m_dataList[index.row()].guestPort);
     270    /* If index is NOT valid => use default values: */
     271    else
     272        m_dataList << UIPortForwardingData(strTemplate.arg(++uMaxIndex), KNATProtocol_TCP,
     273                                           QString(""), 0, QString(""), 0);
     274    endInsertRows();
     275}
     276
     277void UIPortForwardingModel::delRule(const QModelIndex &index)
     278{
     279    if (!index.isValid())
     280        return;
     281    beginRemoveRows(QModelIndex(), index.row(), index.row());
     282    m_dataList.removeAt(index.row());
     283    endRemoveRows();
     284}
     285
     286Qt::ItemFlags UIPortForwardingModel::flags(const QModelIndex &index) const
     287{
     288    /* Check index validness: */
     289    if (!index.isValid())
     290        return Qt::NoItemFlags;
     291    /* All columns have similar flags: */
     292    return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
     293}
     294
     295int UIPortForwardingModel::rowCount(const QModelIndex&) const
     296{
     297    return m_dataList.size();
     298}
     299
     300int UIPortForwardingModel::columnCount(const QModelIndex&) const
     301{
     302    return UIPortForwardingDataType_Max;
     303}
     304
     305QVariant UIPortForwardingModel::headerData(int iSection, Qt::Orientation orientation, int iRole) const
     306{
     307    /* Display role for horizontal header: */
     308    if (iRole == Qt::DisplayRole && orientation == Qt::Horizontal)
     309    {
     310        /* Switch for different columns: */
     311        switch (iSection)
     312        {
     313            case UIPortForwardingDataType_Name: return tr("Name");
     314            case UIPortForwardingDataType_Protocol: return tr("Protocol");
     315            case UIPortForwardingDataType_HostIp: return tr("Host IP");
     316            case UIPortForwardingDataType_HostPort: return tr("Host Port");
     317            case UIPortForwardingDataType_GuestIp: return tr("Guest IP");
     318            case UIPortForwardingDataType_GuestPort: return tr("Guest Port");
     319            default: break;
     320        }
     321    }
     322    /* Return wrong value: */
     323    return QVariant();
     324}
     325
     326QVariant UIPortForwardingModel::data(const QModelIndex &index, int iRole) const
     327{
     328    /* Check index validness: */
     329    if (!index.isValid())
     330        return QVariant();
     331    /* Switch for different roles: */
     332    switch (iRole)
     333    {
     334        /* Display role: */
     335        case Qt::DisplayRole:
     336        {
     337            /* Switch for different columns: */
     338            switch (index.column())
     339            {
     340                case UIPortForwardingDataType_Name: return m_dataList[index.row()].name;
     341                case UIPortForwardingDataType_Protocol: return gpConverter->toString(m_dataList[index.row()].protocol);
     342                case UIPortForwardingDataType_HostIp: return m_dataList[index.row()].hostIp;
     343                case UIPortForwardingDataType_HostPort: return m_dataList[index.row()].hostPort.value();
     344                case UIPortForwardingDataType_GuestIp: return m_dataList[index.row()].guestIp;
     345                case UIPortForwardingDataType_GuestPort: return m_dataList[index.row()].guestPort.value();
     346                default: return QVariant();
     347            }
     348        }
     349        /* Edit role: */
     350        case Qt::EditRole:
     351        {
     352            /* Switch for different columns: */
     353            switch (index.column())
     354            {
     355                case UIPortForwardingDataType_Name: return QVariant::fromValue(m_dataList[index.row()].name);
     356                case UIPortForwardingDataType_Protocol: return QVariant::fromValue(m_dataList[index.row()].protocol);
     357                case UIPortForwardingDataType_HostIp: return QVariant::fromValue(m_dataList[index.row()].hostIp);
     358                case UIPortForwardingDataType_HostPort: return QVariant::fromValue(m_dataList[index.row()].hostPort);
     359                case UIPortForwardingDataType_GuestIp: return QVariant::fromValue(m_dataList[index.row()].guestIp);
     360                case UIPortForwardingDataType_GuestPort: return QVariant::fromValue(m_dataList[index.row()].guestPort);
     361                default: return QVariant();
     362            }
     363        }
     364        /* Alignment role: */
     365        case Qt::TextAlignmentRole:
     366        {
     367            /* Switch for different columns: */
     368            switch (index.column())
     369            {
     370                case UIPortForwardingDataType_Name:
     371                case UIPortForwardingDataType_Protocol:
     372                case UIPortForwardingDataType_HostPort:
     373                case UIPortForwardingDataType_GuestPort:
     374                    return (int)(Qt::AlignLeft | Qt::AlignVCenter);
     375                case UIPortForwardingDataType_HostIp:
     376                case UIPortForwardingDataType_GuestIp:
     377                    return Qt::AlignCenter;
     378                default: return QVariant();
     379            }
     380        }
     381        case Qt::SizeHintRole:
     382        {
     383            /* Switch for different columns: */
     384            switch (index.column())
     385            {
     386                case UIPortForwardingDataType_HostIp:
     387                case UIPortForwardingDataType_GuestIp:
     388                    return QSize(QApplication::fontMetrics().width(" 888.888.888.888 "), QApplication::fontMetrics().height());
     389                default: return QVariant();
     390            }
     391        }
     392        default: break;
     393    }
     394    /* Return wrong value: */
     395    return QVariant();
     396}
     397
     398bool UIPortForwardingModel::setData(const QModelIndex &index, const QVariant &value, int iRole /*= Qt::EditRole*/)
     399{
     400    /* Check index validness: */
     401    if (!index.isValid() || iRole != Qt::EditRole)
     402        return false;
     403    /* Switch for different columns: */
     404    switch (index.column())
     405    {
     406        case UIPortForwardingDataType_Name:
     407            m_dataList[index.row()].name = value.value<NameData>();
     408            emit dataChanged(index, index);
     409            return true;
     410        case UIPortForwardingDataType_Protocol:
     411            m_dataList[index.row()].protocol = value.value<KNATProtocol>();
     412            emit dataChanged(index, index);
     413            return true;
     414        case UIPortForwardingDataType_HostIp:
     415            m_dataList[index.row()].hostIp = value.value<IpData>();
     416            emit dataChanged(index, index);
     417            return true;
     418        case UIPortForwardingDataType_HostPort:
     419            m_dataList[index.row()].hostPort = value.value<PortData>();
     420            emit dataChanged(index, index);
     421            return true;
     422        case UIPortForwardingDataType_GuestIp:
     423            m_dataList[index.row()].guestIp = value.value<IpData>();
     424            emit dataChanged(index, index);
     425            return true;
     426        case UIPortForwardingDataType_GuestPort:
     427            m_dataList[index.row()].guestPort = value.value<PortData>();
     428            emit dataChanged(index, index);
     429            return true;
     430        default: return false;
     431    }
     432    /* Return false value: */
     433    return false;
     434}
     435
     436
     437UIPortForwardingTable::UIPortForwardingTable(const UIPortForwardingDataList &rules)
     438    : m_fIsTableDataChanged(false)
    426439    , m_pTableView(0)
    427440    , m_pToolBar(0)
    428     , m_pButtonBox(0)
    429441    , m_pModel(0)
    430442    , m_pAddAction(0)
     
    432444    , m_pDelAction(0)
    433445{
    434 #ifdef Q_WS_MAC
    435     setWindowFlags(Qt::Sheet);
    436 #endif /* Q_WS_MAC */
    437 
    438     /* Set dialog icon: */
    439     setWindowIcon(UIIconPool::iconSetFull(QSize(32, 32), QSize(16, 16), ":/nw_32px.png", ":/nw_16px.png"));
    440 
    441     /* Create table: */
    442     m_pTableView = new QITableView(this);
    443     m_pTableView->setTabKeyNavigation(false);
    444     m_pTableView->verticalHeader()->hide();
    445     m_pTableView->verticalHeader()->setDefaultSectionSize((int)(m_pTableView->verticalHeader()->minimumSectionSize() * 1.33));
    446     m_pTableView->setSelectionMode(QAbstractItemView::SingleSelection);
    447     m_pTableView->setContextMenuPolicy(Qt::CustomContextMenu);
    448     m_pTableView->installEventFilter(this);
    449     connect(m_pTableView, SIGNAL(sigCurrentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(sltCurrentChanged()));
    450     connect(m_pTableView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(sltShowTableContexMenu(const QPoint &)));
    451 
    452     /* Create actions: */
    453     m_pAddAction = new QAction(this);
    454     m_pCopyAction = new QAction(this);
    455     m_pDelAction = new QAction(this);
    456     m_pAddAction->setShortcut(QKeySequence("Ins"));
    457     m_pDelAction->setShortcut(QKeySequence("Del"));
    458     m_pAddAction->setIcon(UIIconPool::iconSet(":/controller_add_16px.png", ":/controller_add_disabled_16px.png"));
    459     m_pCopyAction->setIcon(UIIconPool::iconSet(":/controller_add_16px.png", ":/controller_add_disabled_16px.png"));
    460     m_pDelAction->setIcon(UIIconPool::iconSet(":/controller_remove_16px.png", ":/controller_remove_disabled_16px.png"));
    461     connect(m_pAddAction, SIGNAL(triggered(bool)), this, SLOT(sltAddRule()));
    462     connect(m_pCopyAction, SIGNAL(triggered(bool)), this, SLOT(sltCopyRule()));
    463     connect(m_pDelAction, SIGNAL(triggered(bool)), this, SLOT(sltDelRule()));
    464 
    465     /* Create toolbar: */
    466     m_pToolBar = new UIToolBar(this);
    467     m_pToolBar->setIconSize(QSize(16, 16));
    468     m_pToolBar->setOrientation(Qt::Vertical);
    469     m_pToolBar->addAction(m_pAddAction);
    470     m_pToolBar->addAction(m_pDelAction);
    471 
    472     /* Create table & toolbar layout: */
    473     QHBoxLayout *pTableAndToolbarLayout = new QHBoxLayout;
    474     pTableAndToolbarLayout->setSpacing(1);
    475     pTableAndToolbarLayout->addWidget(m_pTableView);
    476     pTableAndToolbarLayout->addWidget(m_pToolBar);
    477 
    478     /* Create buttonbox: */
    479     m_pButtonBox = new QIDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
    480     connect(m_pButtonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept()));
    481     connect(m_pButtonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject()));
    482 
    483     /* Create main layout: */
    484     QVBoxLayout *pMainLayout = new QVBoxLayout;
    485     this->setLayout(pMainLayout);
    486     pMainLayout->addLayout(pTableAndToolbarLayout);
    487     pMainLayout->addWidget(m_pButtonBox);
    488 
    489     /* Create model: */
    490     m_pModel = new UIPortForwardingModel(this, rules);
    491     connect(m_pModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(sltTableDataChanged()));
    492     connect(m_pModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(sltTableDataChanged()));
    493     connect(m_pModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(sltTableDataChanged()));
    494     m_pTableView->setModel(m_pModel);
     446    /* Create layout: */
     447    QHBoxLayout *pMainLayout = new QHBoxLayout(this);
     448    {
     449        /* Configure layout: */
     450        pMainLayout->setMargin(0);
     451        pMainLayout->setSpacing(3);
     452        /* Create model: */
     453        m_pModel = new UIPortForwardingModel(this, rules);
     454        {
     455            /* Configure model: */
     456            connect(m_pModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(sltTableDataChanged()));
     457            connect(m_pModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), this, SLOT(sltTableDataChanged()));
     458            connect(m_pModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), this, SLOT(sltTableDataChanged()));
     459        }
     460        /* Create table: */
     461        m_pTableView = new QITableView;
     462        {
     463            /* Configure table: */
     464            m_pTableView->setModel(m_pModel);
     465            m_pTableView->setTabKeyNavigation(false);
     466            m_pTableView->verticalHeader()->hide();
     467            m_pTableView->verticalHeader()->setDefaultSectionSize((int)(m_pTableView->verticalHeader()->minimumSectionSize() * 1.33));
     468            m_pTableView->setSelectionMode(QAbstractItemView::SingleSelection);
     469            m_pTableView->setContextMenuPolicy(Qt::CustomContextMenu);
     470            m_pTableView->installEventFilter(this);
     471            connect(m_pTableView, SIGNAL(sigCurrentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(sltCurrentChanged()));
     472            connect(m_pTableView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(sltShowTableContexMenu(const QPoint &)));
     473        }
     474        /* Create toolbar: */
     475        m_pToolBar = new UIToolBar;
     476        {
     477            /* Configure toolbar: */
     478            m_pToolBar->setIconSize(QSize(16, 16));
     479            m_pToolBar->setOrientation(Qt::Vertical);
     480            /* Create 'add' action: */
     481            m_pAddAction = new QAction(this);
     482            {
     483                /* Configure 'add' action: */
     484                m_pAddAction->setShortcut(QKeySequence("Ins"));
     485                m_pAddAction->setIcon(UIIconPool::iconSet(":/controller_add_16px.png", ":/controller_add_disabled_16px.png"));
     486                connect(m_pAddAction, SIGNAL(triggered(bool)), this, SLOT(sltAddRule()));
     487                m_pToolBar->addAction(m_pAddAction);
     488            }
     489            /* Create 'copy' action: */
     490            m_pCopyAction = new QAction(this);
     491            {
     492                /* Configure 'add' action: */
     493                m_pCopyAction->setIcon(UIIconPool::iconSet(":/controller_add_16px.png", ":/controller_add_disabled_16px.png"));
     494                connect(m_pCopyAction, SIGNAL(triggered(bool)), this, SLOT(sltCopyRule()));
     495            }
     496            /* Create 'del' action: */
     497            m_pDelAction = new QAction(this);
     498            {
     499                /* Configure 'del' action: */
     500                m_pDelAction->setShortcut(QKeySequence("Del"));
     501                m_pDelAction->setIcon(UIIconPool::iconSet(":/controller_remove_16px.png", ":/controller_remove_disabled_16px.png"));
     502                connect(m_pDelAction, SIGNAL(triggered(bool)), this, SLOT(sltDelRule()));
     503                m_pToolBar->addAction(m_pDelAction);
     504            }
     505        }
     506        /* Add widgets into layout: */
     507        pMainLayout->addWidget(m_pTableView);
     508        pMainLayout->addWidget(m_pToolBar);
     509    }
    495510
    496511    /* Register delegates editors: */
     
    539554
    540555    /* Minimum Size: */
    541     setMinimumSize(600, 300);
    542 }
    543 
    544 /* Port forwarding dialog destructor: */
    545 UIMachineSettingsPortForwardingDlg::~UIMachineSettingsPortForwardingDlg()
    546 {
    547 }
    548 
    549 const UIPortForwardingDataList& UIMachineSettingsPortForwardingDlg::rules() const
     556    setMinimumSize(600, 250);
     557}
     558
     559const UIPortForwardingDataList& UIPortForwardingTable::rules() const
    550560{
    551561    return m_pModel->rules();
    552562}
    553563
    554 /* Add rule slot: */
    555 void UIMachineSettingsPortForwardingDlg::sltAddRule()
     564bool UIPortForwardingTable::validate() const
     565{
     566    /* Validate table: */
     567    for (int i = 0; i < m_pModel->rowCount(); ++i)
     568    {
     569        /* If at aleast one port is 'zero': */
     570        if (m_pModel->data(m_pModel->index(i, UIPortForwardingModel::UIPortForwardingDataType_HostPort), Qt::EditRole).value<PortData>().value() == 0 ||
     571            m_pModel->data(m_pModel->index(i, UIPortForwardingModel::UIPortForwardingDataType_GuestPort), Qt::EditRole).value<PortData>().value() == 0)
     572        {
     573            msgCenter().warnAboutIncorrectPort(window());
     574            return false;
     575        }
     576    }
     577    /* True by default: */
     578    return true;
     579}
     580
     581bool UIPortForwardingTable::discard() const
     582{
     583    /* Check if table data was changed and user do not want to loose it: */
     584    if (m_fIsTableDataChanged && !msgCenter().confirmCancelingPortForwardingDialog(window()))
     585        return false;
     586    /* True by default: */
     587    return true;
     588}
     589
     590void UIPortForwardingTable::sltAddRule()
    556591{
    557592    m_pModel->addRule(QModelIndex());
     
    562597}
    563598
    564 /* Copy rule slot: */
    565 void UIMachineSettingsPortForwardingDlg::sltCopyRule()
     599void UIPortForwardingTable::sltCopyRule()
    566600{
    567601    m_pModel->addRule(m_pTableView->currentIndex());
     
    572606}
    573607
    574 /* Del rule slot: */
    575 void UIMachineSettingsPortForwardingDlg::sltDelRule()
     608void UIPortForwardingTable::sltDelRule()
    576609{
    577610    m_pModel->delRule(m_pTableView->currentIndex());
     
    581614}
    582615
    583 /* Table data change handler: */
    584 void UIMachineSettingsPortForwardingDlg::sltTableDataChanged()
    585 {
    586     fIsTableDataChanged = true;
    587 }
    588 
    589 /* Table index-change handler: */
    590 void UIMachineSettingsPortForwardingDlg::sltCurrentChanged()
     616void UIPortForwardingTable::sltTableDataChanged()
     617{
     618    m_fIsTableDataChanged = true;
     619}
     620
     621void UIPortForwardingTable::sltCurrentChanged()
    591622{
    592623    bool fTableFocused = m_pTableView->hasFocus();
    593     bool fTableChildrenFocused = m_pTableView->findChildren<QWidget*>().contains(QApplication::focusWidget());
    594     bool fTableOrChildrenFocused = fTableFocused || fTableChildrenFocused;
    595     m_pCopyAction->setEnabled(m_pTableView->currentIndex().isValid() && fTableOrChildrenFocused);
    596     m_pDelAction->setEnabled(m_pTableView->currentIndex().isValid() && fTableOrChildrenFocused);
    597 }
    598 
    599 /* Table context-menu handler: */
    600 void UIMachineSettingsPortForwardingDlg::sltShowTableContexMenu(const QPoint &pos)
     624    bool fTableChildFocused = m_pTableView->findChildren<QWidget*>().contains(QApplication::focusWidget());
     625    bool fTableOrChildFocused = fTableFocused || fTableChildFocused;
     626    m_pCopyAction->setEnabled(m_pTableView->currentIndex().isValid() && fTableOrChildFocused);
     627    m_pDelAction->setEnabled(m_pTableView->currentIndex().isValid() && fTableOrChildFocused);
     628}
     629
     630void UIPortForwardingTable::sltShowTableContexMenu(const QPoint &pos)
    601631{
    602632    /* Prepare context menu: */
     
    616646}
    617647
    618 /* Adjusts table column's sizes: */
    619 void UIMachineSettingsPortForwardingDlg::sltAdjustTable()
     648void UIPortForwardingTable::sltAdjustTable()
    620649{
    621650    m_pTableView->horizontalHeader()->setStretchLastSection(false);
     
    641670}
    642671
    643 void UIMachineSettingsPortForwardingDlg::accept()
    644 {
    645     /* Validate table: */
    646     for (int i = 0; i < m_pModel->rowCount(); ++i)
    647     {
    648         if (m_pModel->data(m_pModel->index(i, UIPortForwardingModel::UIPortForwardingDataType_HostPort), Qt::EditRole).value<PortData>().value() == 0 ||
    649             m_pModel->data(m_pModel->index(i, UIPortForwardingModel::UIPortForwardingDataType_GuestPort), Qt::EditRole).value<PortData>().value() == 0)
    650         {
    651             msgCenter().warnAboutIncorrectPort(this);
    652             return;
    653         }
    654     }
    655     /* Base class accept() slot: */
    656     QIWithRetranslateUI<QIDialog>::accept();
    657 }
    658 
    659 void UIMachineSettingsPortForwardingDlg::reject()
    660 {
    661     /* Check if table data was changed: */
    662     if (fIsTableDataChanged && !msgCenter().confirmCancelingPortForwardingDialog(this))
    663         return;
    664     /* Base class reject() slot: */
    665     QIWithRetranslateUI<QIDialog>::reject();
    666 }
    667 
    668 /* UI Retranslation slot: */
    669 void UIMachineSettingsPortForwardingDlg::retranslateUi()
    670 {
    671     /* Set window title: */
    672     setWindowTitle(tr("Port Forwarding Rules"));
    673 
     672void UIPortForwardingTable::retranslateUi()
     673{
    674674    /* Table translations: */
    675     m_pTableView->setWhatsThis(tr("This table contains a list of port forwarding rules."));
     675    m_pTableView->setToolTip(QApplication::translate("UIMachineSettingsPortForwardingDlg", "This table contains a list of port forwarding rules."));
    676676
    677677    /* Set action's text: */
    678     m_pAddAction->setText(tr("Insert new rule"));
    679     m_pCopyAction->setText(tr("Copy selected rule"));
    680     m_pDelAction->setText(tr("Delete selected rule"));
    681     m_pAddAction->setWhatsThis(tr("This button adds new port forwarding rule."));
    682     m_pDelAction->setWhatsThis(tr("This button deletes selected port forwarding rule."));
     678    m_pAddAction->setText(QApplication::translate("UIMachineSettingsPortForwardingDlg", "Insert new rule"));
     679    m_pCopyAction->setText(QApplication::translate("UIMachineSettingsPortForwardingDlg", "Copy selected rule"));
     680    m_pDelAction->setText(QApplication::translate("UIMachineSettingsPortForwardingDlg", "Delete selected rule"));
     681    m_pAddAction->setWhatsThis(QApplication::translate("UIMachineSettingsPortForwardingDlg", "This button adds new port forwarding rule."));
     682    m_pDelAction->setWhatsThis(QApplication::translate("UIMachineSettingsPortForwardingDlg", "This button deletes selected port forwarding rule."));
    683683    m_pAddAction->setToolTip(QString("%1 (%2)").arg(m_pAddAction->text()).arg(m_pAddAction->shortcut().toString()));
    684684    m_pDelAction->setToolTip(QString("%1 (%2)").arg(m_pDelAction->text()).arg(m_pDelAction->shortcut().toString()));
    685685}
    686686
    687 /* Extended event-handler: */
    688 bool UIMachineSettingsPortForwardingDlg::eventFilter(QObject *pObj, QEvent *pEvent)
     687bool UIPortForwardingTable::eventFilter(QObject *pObject, QEvent *pEvent)
    689688{
    690689    /* Process table: */
    691     if (pObj == m_pTableView)
    692     {
    693         /* Switch for different event-types: */
     690    if (pObject == m_pTableView)
     691    {
     692        /* Process different event-types: */
    694693        switch (pEvent->type())
    695694        {
     695            case QEvent::Show:
     696            case QEvent::Resize:
     697            {
     698                /* Adjust table: */
     699                sltAdjustTable();
     700                break;
     701            }
    696702            case QEvent::FocusIn:
    697703            case QEvent::FocusOut:
     704            {
    698705                /* Update actions: */
    699706                sltCurrentChanged();
    700707                break;
    701             case QEvent::Show:
    702             case QEvent::Resize:
    703             {
    704                 /* Instant table adjusting: */
    705                 sltAdjustTable();
    706                 /* Delayed table adjusting: */
    707                 QTimer::singleShot(0, this, SLOT(sltAdjustTable()));
    708                 break;
    709708            }
    710709            default:
     
    712711        }
    713712    }
    714     /* Continue with base-class processing: */
    715     return QIWithRetranslateUI<QIDialog>::eventFilter(pObj, pEvent);
    716 }
    717 
    718 #include "UIMachineSettingsPortForwardingDlg.moc"
    719 
     713    /* Call to base-class: */
     714    return QIWithRetranslateUI<QWidget>::eventFilter(pObject, pEvent);
     715}
     716
     717#include "UIPortForwardingTable.moc"
     718
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIPortForwardingTable.h

    r48528 r48533  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIMachineSettingsPortForwardingDlg class declaration
     4 * UIPortForwardingTable class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2010-2012 Oracle Corporation
     8 * Copyright (C) 2010-2013 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIMachineSettingsPortForwardingDlg_h__
    20 #define __UIMachineSettingsPortForwardingDlg_h__
     19#ifndef __UIPortForwardingTable_h__
     20#define __UIPortForwardingTable_h__
    2121
    22 /* GUI includes */
     22/* Qt includes: */
     23#include <QWidget>
     24
     25/* GUI includes: */
    2326#include "QIWithRetranslateUI.h"
    24 #include "QIDialog.h"
    2527
    2628/* COM includes: */
     
    3941
    4042    NameData() : QString() {}
    41     NameData(const QString &ruleName) : QString(ruleName) {}
     43    NameData(const QString &strName) : QString(strName) {}
    4244};
    4345Q_DECLARE_METATYPE(NameData);
     
    4951
    5052    IpData() : QString() {}
    51     IpData(const QString &ipAddress) : QString(ipAddress) {}
     53    IpData(const QString &strIP) : QString(strIP) {}
    5254};
    5355Q_DECLARE_METATYPE(IpData);
     
    7375struct UIPortForwardingData
    7476{
    75     UIPortForwardingData(const NameData &strName, KNATProtocol eProtocol,
    76                          const IpData &strHostIp, PortData uHostPort,
    77                          const IpData &strGuestIp, PortData uGuestPort)
    78         : name(strName), protocol(eProtocol)
    79         , hostIp(strHostIp), hostPort(uHostPort)
    80         , guestIp(strGuestIp), guestPort(uGuestPort) {}
     77    UIPortForwardingData(const NameData &strName, KNATProtocol protocol,
     78                         const IpData &strHostIP, PortData uHostPort,
     79                         const IpData &strGuestIP, PortData uGuestPort)
     80        : name(strName), protocol(protocol)
     81        , hostIp(strHostIP), hostPort(uHostPort)
     82        , guestIp(strGuestIP), guestPort(uGuestPort) {}
    8183    bool operator==(const UIPortForwardingData &other)
    8284    {
     
    100102
    101103/* Port forwarding dialog: */
    102 class UIMachineSettingsPortForwardingDlg : public QIWithRetranslateUI<QIDialog>
     104class UIPortForwardingTable : public QIWithRetranslateUI<QWidget>
    103105{
    104106    Q_OBJECT;
     
    106108public:
    107109
    108     /* Port forwarding dialog constructor: */
    109     UIMachineSettingsPortForwardingDlg(QWidget *pParent = 0,
    110                                     const UIPortForwardingDataList &rules = UIPortForwardingDataList());
    111     /* Port forwarding dialog destructor: */
    112     ~UIMachineSettingsPortForwardingDlg();
     110    /* Constructor: */
     111    UIPortForwardingTable(const UIPortForwardingDataList &rules = UIPortForwardingDataList());
    113112
    114     /* The list of chosen rules: */
     113    /* API: Rules stuff: */
    115114    const UIPortForwardingDataList& rules() const;
     115    bool validate() const;
     116    bool discard() const;
    116117
    117118private slots:
    118119
    119     /* Action's slots: */
     120    /* Handlers: Table operation stuff: */
    120121    void sltAddRule();
    121122    void sltCopyRule();
    122123    void sltDelRule();
    123124
    124     /* Table slots: */
     125    /* Handlers: Table stuff: */
    125126    void sltTableDataChanged();
    126127    void sltCurrentChanged();
     
    128129    void sltAdjustTable();
    129130
    130     /* Dialog slots: */
    131     void accept();
    132     void reject();
    133 
    134131private:
    135132
    136     /* UI Translator: */
     133    /* Handler: Translation stuff: */
    137134    void retranslateUi();
    138135
    139     /* Event filter: */
    140     bool eventFilter(QObject *pObj, QEvent *pEvent);
     136    /* Handlers: Event-processing stuff: */
     137    bool eventFilter(QObject *pObject, QEvent *pEvent);
    141138
    142139    /* Flags: */
    143     bool fIsTableDataChanged;
     140    bool m_fIsTableDataChanged;
    144141
    145142    /* Widgets: */
    146143    QITableView *m_pTableView;
    147144    UIToolBar *m_pToolBar;
    148     QIDialogButtonBox *m_pButtonBox;
    149145
    150146    /* Model: */
     
    157153};
    158154
    159 #endif // __UIMachineSettingsPortForwardingDlg_h__
    160 
     155#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