Index: trunk/src/VBox/Frontends/VirtualBox/src/softkeyboard/UISoftKeyboard.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/softkeyboard/UISoftKeyboard.cpp	(revision 78974)
+++ trunk/src/VBox/Frontends/VirtualBox/src/softkeyboard/UISoftKeyboard.cpp	(revision 78975)
@@ -19,4 +19,5 @@
 #include <QApplication>
 #include <QFile>
+#include <QLineEdit>
 #include <QMenu>
 #include <QPainter>
@@ -63,4 +64,5 @@
 *   UISoftKeyboardRow definition.                                                                                  *
 *********************************************************************************************************************************/
+
 /** UISoftKeyboardRow represents a row in the physical keyboard. */
 class UISoftKeyboardRow
@@ -94,4 +96,5 @@
 *   UISoftKeyboardKey definition.                                                                                  *
 *********************************************************************************************************************************/
+
 /** UISoftKeyboardKey is a place holder for a keyboard key. Graphical key represantations are drawn according to this class. */
 class UISoftKeyboardKey
@@ -199,4 +202,5 @@
     void mouseReleaseEvent(QMouseEvent *pEvent) /* override */;
     void mouseMoveEvent(QMouseEvent *pEvent) /* override */;
+    bool eventFilter(QObject *pWatched, QEvent *pEvent)/* override */;
 
     virtual void retranslateUi() /* override */;
@@ -206,5 +210,5 @@
     void sltHandleMenuBarContextMenuRequest(const QPoint &point);
     void sltHandleLoadLayout(QAction *pSenderAction);
-    void sltHandleShowKeyPositions();
+    void sltHandleKeyCapEdit();
 
 private:
@@ -214,4 +218,5 @@
     /** Searches for the key which contains the position of the @p pEvent and returns it if found. */
     UISoftKeyboardKey *keyUnderMouse(QMouseEvent *pEvent);
+    UISoftKeyboardKey *keyUnderMouse(const QPoint &point);
     void               handleKeyPress(UISoftKeyboardKey *pKey);
     void               handleKeyRelease(UISoftKeyboardKey *pKey);
@@ -222,4 +227,6 @@
 
     UISoftKeyboardKey *m_pKeyUnderMouse;
+    UISoftKeyboardKey *m_pKeyBeingEdited;
+
     UISoftKeyboardKey *m_pKeyPressed;
     QColor m_keyDefaultColor;
@@ -248,4 +255,6 @@
     QAction *m_pLoadLayoutFileAction;
     QAction *m_pLastSelectedLayout;
+    QAction *m_pChangeKeyCapAction;
+    QLineEdit *m_pKeyCapEditor;
 };
 
@@ -362,8 +371,5 @@
 void UISoftKeyboardKey::setKeyCap(const QString &strKeyCap)
 {
-    if (m_strKeyCap.isEmpty())
-        m_strKeyCap = strKeyCap;
-    else
-        m_strKeyCap += "\n" + strKeyCap;
+    m_strKeyCap = strKeyCap;
 }
 
@@ -545,4 +551,5 @@
     :QIWithRetranslateUI<QWidget>(pParent)
     , m_pKeyUnderMouse(0)
+    , m_pKeyBeingEdited(0)
     , m_pKeyPressed(0)
     , m_keyDefaultColor(QColor(103, 128, 159))
@@ -562,4 +569,5 @@
     , m_pLoadLayoutFileAction(0)
     , m_pLastSelectedLayout(0)
+    , m_pChangeKeyCapAction(0)
 {
 
@@ -597,5 +605,6 @@
     float fLedRadius =  0.8 * unitSize;
     float fLedMargin =  0.6 * unitSize;
-
+    if (!m_pKeyBeingEdited && m_pKeyCapEditor)
+        m_pKeyCapEditor->hide();
     for (int i = 0; i < m_rows.size(); ++i)
     {
@@ -609,4 +618,14 @@
             else
                 painter.setBrush(QBrush(m_keyDefaultColor));
+
+            if (&key == m_pKeyBeingEdited)
+            {
+                //m_pKeyCapEditor->setText(key.keyCap());
+                m_pKeyCapEditor->setFont(painterFont);
+                m_pKeyCapEditor->setGeometry(m_fScaleFactorX * key.keyGeometry().x(), m_fScaleFactorY * key.keyGeometry().y(),
+                                             m_fScaleFactorX * key.keyGeometry().width(), m_fScaleFactorY * key.keyGeometry().height());
+                m_pKeyCapEditor->show();
+
+            }
 
             if (&key  == m_pKeyPressed)
@@ -647,4 +666,5 @@
 void UISoftKeyboardWidget::mousePressEvent(QMouseEvent *pEvent)
 {
+    QWidget::mousePressEvent(pEvent);
     if (pEvent->button() != Qt::LeftButton)
         return;
@@ -656,4 +676,5 @@
 void UISoftKeyboardWidget::mouseReleaseEvent(QMouseEvent *pEvent)
 {
+    QWidget::mouseReleaseEvent(pEvent);
     if (pEvent->button() != Qt::LeftButton)
         return;
@@ -667,12 +688,45 @@
 void UISoftKeyboardWidget::mouseMoveEvent(QMouseEvent *pEvent)
 {
+    QWidget::mouseMoveEvent(pEvent);
     keyUnderMouse(pEvent);
 }
 
-void UISoftKeyboard::focusOutEvent(QFocusEvent *pEvent)
-{
-    QIWithRetranslateUI<QMainWindow>::focusOutEvent(pEvent);
-    printf("booo\n");
-}
+bool UISoftKeyboardWidget::eventFilter(QObject *pWatched, QEvent *pEvent)
+{
+    if (pWatched != m_pKeyCapEditor)
+        return QIWithRetranslateUI<QWidget>::eventFilter(pWatched, pEvent);
+
+    switch (pEvent->type())
+    {
+        /* Process key press only: */
+        case QEvent::KeyPress:
+        {
+            /* Cast to corresponding key press event: */
+            QKeyEvent *pKeyEvent = static_cast<QKeyEvent*>(pEvent);
+
+            /* Handle Ctrl+T key combination as a shortcut to focus search field: */
+            if (pKeyEvent->key() == Qt::Key_Escape)
+            {
+                m_pKeyBeingEdited = 0;
+                update();
+                return true;
+            }
+            else if (pKeyEvent->key() == Qt::Key_Enter || pKeyEvent->key() == Qt::Key_Return)
+            {
+                if (m_pKeyBeingEdited)
+                    m_pKeyBeingEdited->setKeyCap(m_pKeyCapEditor->text());
+                m_pKeyBeingEdited = 0;
+                update();
+                return true;
+            }
+            break;
+        }
+        default:
+            break;
+    }
+
+    return QIWithRetranslateUI<QWidget>::eventFilter(pWatched, pEvent);
+}
+
 
 void UISoftKeyboardWidget::retranslateUi()
@@ -682,4 +736,5 @@
 void UISoftKeyboardWidget::sltHandleMenuBarContextMenuRequest(const QPoint &point)
 {
+    m_pChangeKeyCapAction->setEnabled(m_pKeyUnderMouse);
     m_pContextMenu->exec(mapToGlobal(point));
     update();
@@ -719,7 +774,9 @@
 }
 
-void UISoftKeyboardWidget::sltHandleShowKeyPositions()
-{
-
+void UISoftKeyboardWidget::sltHandleKeyCapEdit()
+{
+    m_pKeyBeingEdited = m_pKeyUnderMouse;
+    if (m_pKeyBeingEdited && m_pKeyCapEditor)
+        m_pKeyCapEditor->setText(m_pKeyBeingEdited->keyCap());
 }
 
@@ -739,5 +796,10 @@
 {
     QPoint eventPosition(pEvent->pos().x() / m_fScaleFactorX, pEvent->pos().y() / m_fScaleFactorY);
-    QWidget::mousePressEvent(pEvent);
+    return keyUnderMouse(eventPosition);
+}
+
+UISoftKeyboardKey *UISoftKeyboardWidget::keyUnderMouse(const QPoint &eventPosition)
+{
+    UISoftKeyboardKey *pKey = 0;
     for (int i = 0; i < m_rows.size(); ++i)
     {
@@ -748,15 +810,15 @@
             if (key.polygonInGlobal().containsPoint(eventPosition, Qt::OddEvenFill))
             {
-                if (&key != m_pKeyUnderMouse)
-                {
-                    m_pKeyUnderMouse = &key;
-                    update();
-                }
-                return &key;
+                pKey = &key;
                 break;
             }
         }
     }
-    return 0;
+    if (m_pKeyUnderMouse != pKey)
+    {
+        m_pKeyUnderMouse = pKey;
+        update();
+    }
+    return pKey;
 }
 
@@ -894,6 +956,11 @@
 void UISoftKeyboardWidget::prepareObjects()
 {
+    m_pKeyCapEditor = new QLineEdit(this);
+    if (m_pKeyCapEditor)
+    {
+        m_pKeyCapEditor->hide();
+        m_pKeyCapEditor->installEventFilter(this);
+    }
     m_pContextMenu = new QMenu(this);
-    //m_pShowPositionsAction = m_pContextMenu->addAction("
     m_pLayoutActionGroup = new QActionGroup(this);
     m_pLayoutActionGroup->setExclusive(true);
@@ -914,7 +981,12 @@
 
     m_pShowPositionsAction = m_pContextMenu->addAction(UISoftKeyboard::tr("Show key positions instead of key caps"));
-    connect(m_pLayoutActionGroup, &QActionGroup::triggered, this, &UISoftKeyboardWidget::sltHandleShowKeyPositions);
+
     m_pShowPositionsAction->setCheckable(true);
     m_pShowPositionsAction->setChecked(false);
+
+    m_pChangeKeyCapAction = m_pContextMenu->addAction(UISoftKeyboard::tr("Add/change key cap"));
+    connect(m_pChangeKeyCapAction, &QAction::triggered, this, &UISoftKeyboardWidget::sltHandleKeyCapEdit);
+    QAction *pSaveKepCapFile = m_pContextMenu->addAction(UISoftKeyboard::tr("Save key caps to file"));
+    Q_UNUSED(pSaveKepCapFile);
 
     /* Choose the first layput action's data as the defaults one: */
@@ -1018,5 +1090,5 @@
     key.setWidth(row.defaultWidth());
     key.setHeight(row.defaultHeight());
-
+    QString strKeyCap;
     while (m_xmlReader.readNextStartElement())
     {
@@ -1038,8 +1110,14 @@
         }
         else if (m_xmlReader.name() == "keycap")
-            key.setKeyCap(m_xmlReader.readElementText());
+        {
+            QString strCap = m_xmlReader.readElementText();
+            if (strKeyCap.isEmpty())
+                strKeyCap = strCap;
+            else
+                strKeyCap += "\n" + strCap;
+        }
         else if (m_xmlReader.name() == "cutout")
             parseCutout(key);
-       else if (m_xmlReader.name() == "position")
+        else if (m_xmlReader.name() == "position")
             key.setPosition(m_xmlReader.readElementText().toInt());
         else if (m_xmlReader.name() == "type")
@@ -1054,4 +1132,5 @@
             m_xmlReader.skipCurrentElement();
     }
+    key.setKeyCap(strKeyCap);
 }
 
Index: trunk/src/VBox/Frontends/VirtualBox/src/softkeyboard/UISoftKeyboard.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/softkeyboard/UISoftKeyboard.h	(revision 78974)
+++ trunk/src/VBox/Frontends/VirtualBox/src/softkeyboard/UISoftKeyboard.h	(revision 78975)
@@ -56,5 +56,4 @@
 
     virtual void retranslateUi() /* override */;
-    void focusOutEvent(QFocusEvent *pEvent) /* override */;
 
 private slots:
