Index: /trunk/src/VBox/Frontends/VirtualBox/src/softkeyboard/UISoftKeyboard.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/softkeyboard/UISoftKeyboard.cpp	(revision 79102)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/softkeyboard/UISoftKeyboard.cpp	(revision 79103)
@@ -19,8 +19,10 @@
 #include <QApplication>
 #include <QFile>
+#include <QGroupBox>
 #include <QLabel>
 #include <QLineEdit>
 #include <QMenu>
 #include <QPainter>
+#include <QPushButton>
 #include <QStatusBar>
 #include <QStyle>
@@ -70,15 +72,24 @@
 *********************************************************************************************************************************/
 
-class UISoftKeyEditor : public QIWithRetranslateUI<QMainWindow>
+class UISoftKeyEditor : public QIWithRetranslateUI<QWidget>
 {
     Q_OBJECT;
 
+signals:
+
+    void sigKeyCaptionEdited();
+
 public:
 
     UISoftKeyEditor(QWidget *pParent = 0);
+    void setKey(UISoftKeyboardKey *pKey);
 
 protected:
 
     virtual void retranslateUi() /* override */;
+
+private slots:
+
+    void sltHandleOkButton();
 
 private:
@@ -86,11 +97,19 @@
     void prepareObjects();
     void prepareConnections();
-
-    QGridLayout *m_pEditorLayout;
-
+    QWidget *prepareKeyCaptionEditWidgets();
+
+    QVBoxLayout *m_pMainLayout;
+    QGridLayout *m_pCaptionEditorLayout;
+    QGroupBox *m_pSelectedKeyGroupBox;
+    QGroupBox *m_pCaptionEditGroupBox;
+
+    QLabel *m_pScanCodeLabel;
+    QLabel *m_pPositionLabel;
     QLabel *m_pBaseCaptionLabel;
     QLabel *m_pShiftCaptionLabel;
     QLabel *m_pAltGrCaptionLabel;
 
+    QLineEdit *m_pScanCodeEdit;
+    QLineEdit *m_pPositionEdit;
     QLineEdit *m_pBaseCaptionEdit;
     QLineEdit *m_pShiftCaptionEdit;
@@ -99,4 +118,6 @@
     QPushButton *m_pOkButton;
     QPushButton *m_pCancelButton;
+    /** The key which is being currently edited. Might be Null. */
+    UISoftKeyboardKey  *m_pKey;
 };
 
@@ -147,9 +168,14 @@
     void setKeyGeometry(const QRect &rect);
 
-    const QString &staticKeyCap() const;
-    void setStaticKeyCap(const QString &strKeyCap);
-
-    const QString &keyCap() const;
-    void setKeyCap(const QString &strKeyCap);
+    const QString baseCaption() const;
+    void setBaseCaption(const QString &strBaseCaption);
+
+    const QString shiftCaption() const;
+    void setShiftCaption(const QString &strShiftCaption);
+
+    const QString altGrCaption() const;
+    void  setAltGrCaption(const QString &strAltGrCaption);
+
+    const QString text() const;
 
     void setWidth(int iWidth);
@@ -195,11 +221,13 @@
 
     void updateState(bool fPressed);
+    void updateText();
 
     QRect      m_keyGeometry;
-    /** Static keycaps are what is obtained from the layout file, as opposed to the keycaps file.
-      * normally they are the captions of modifier keys (Shift, etc) whose meaning stays the same across the layouts. */
-    QString    m_strStaticKeyCap;
-    /** Key caps are loaded from a keycap file and preferred over the static keycaps if they are not empty. */
-    QString    m_strKeyCap;
+
+    QString    m_strBaseCaption;
+    QString    m_strShiftCaption;
+    QString    m_strAltGrCaption;
+    /** m_strText is concatenation of base, shift, and altgr captions. */
+    QString    m_strText;
 
     /** Stores the key polygon in local coordinates. */
@@ -267,9 +295,9 @@
 
     void sltHandleContextMenuRequest(const QPoint &point);
-    void sltHandleLoadLayout(QAction *pSenderAction);
     void sltHandleSaveKeyCapFile();
     void sltHandleLoadKeyCapFile();
     void sltHandleUnloadKeyCaps();
     void sltHandleKepCapEditModeToggle(bool fToggle);
+    void sltHandleKeyCaptionEdited();
 
 private:
@@ -287,4 +315,6 @@
     void               prepareObjects();
     void               enableDisableKeyCapEditMode(bool fEnable);
+    /** Sets m_pKeyBeingEdited. */
+    void               setKeyBeingEdited(UISoftKeyboardKey* pKey);
 
     UISoftKeyboardKey *m_pKeyUnderMouse;
@@ -296,7 +326,8 @@
     QColor m_textDefaultColor;
     QColor m_textPressedColor;
+    QColor m_keyEditColor;
     QVector<UISoftKeyboardKey*> m_pressedModifiers;
     QVector<UISoftKeyboardRow>  m_rows;
-    QStringList defaultLayouts;
+    QStringList m_defaultLayouts;
 
     QSize m_minimumSize;
@@ -314,10 +345,7 @@
 
     QMenu   *m_pContextMenu;
-    QActionGroup *m_pLayoutActionGroup;
     QAction *m_pShowPositionsAction;
-    QAction *m_pLoadLayoutFileAction;
-    QAction *m_pLastSelectedLayout;
     QAction *m_pKeyCapEditModeToggleAction;
-    QLineEdit *m_pKeyCapEditor;
+    UISoftKeyEditor *m_pKeyCapEditor;
     Mode       m_enmMode;
 };
@@ -373,9 +401,16 @@
 
 UISoftKeyEditor::UISoftKeyEditor(QWidget *pParent /* = 0 */)
-    :QIWithRetranslateUI<QMainWindow>(pParent)
-    , m_pEditorLayout(0)
+    :QIWithRetranslateUI<QWidget>(pParent)
+    , m_pMainLayout(0)
+    , m_pCaptionEditorLayout(0)
+    , m_pSelectedKeyGroupBox(0)
+    , m_pCaptionEditGroupBox(0)
+    , m_pScanCodeLabel(0)
+    , m_pPositionLabel(0)
     , m_pBaseCaptionLabel(0)
     , m_pShiftCaptionLabel(0)
     , m_pAltGrCaptionLabel(0)
+    , m_pScanCodeEdit(0)
+    , m_pPositionEdit(0)
     , m_pBaseCaptionEdit(0)
     , m_pShiftCaptionEdit(0)
@@ -383,43 +418,145 @@
     , m_pOkButton(0)
     , m_pCancelButton(0)
-{
+    , m_pKey(0)
+{
+    setAutoFillBackground(true);
     prepareObjects();
 }
 
+void UISoftKeyEditor::setKey(UISoftKeyboardKey *pKey)
+{
+    if (m_pKey == pKey)
+        return;
+    m_pKey = pKey;
+    if (m_pSelectedKeyGroupBox)
+        m_pSelectedKeyGroupBox->setEnabled(m_pKey);
+    if (!m_pKey)
+        return;
+    if (m_pScanCodeEdit)
+        m_pScanCodeEdit->setText(QString::number(m_pKey->scanCode(), 16));
+    if (m_pPositionEdit)
+        m_pPositionEdit->setText(QString::number(m_pKey->position()));
+    if (m_pBaseCaptionEdit)
+        m_pBaseCaptionEdit->setText(m_pKey->baseCaption());
+    if (m_pShiftCaptionEdit)
+        m_pShiftCaptionEdit->setText(m_pKey->shiftCaption());
+    if (m_pAltGrCaptionEdit)
+        m_pAltGrCaptionEdit->setText(m_pKey->altGrCaption());
+}
+
 void UISoftKeyEditor::retranslateUi()
 {
+    if (m_pScanCodeLabel)
+        m_pScanCodeLabel->setText(UISoftKeyboard::tr("Scan Code"));
+    if (m_pPositionLabel)
+        m_pPositionLabel->setText(UISoftKeyboard::tr("Position"));
     if (m_pBaseCaptionLabel)
-        m_pBaseCaptionLabel->setText(UISoftKeyboard::tr("Base Caption"));
-
-
+        m_pBaseCaptionLabel->setText(UISoftKeyboard::tr("Base"));
     if (m_pShiftCaptionLabel)
-        m_pShiftCaptionLabel->setText(UISoftKeyboard::tr("Shift Caption"));
-
+        m_pShiftCaptionLabel->setText(UISoftKeyboard::tr("Shift"));
     if (m_pAltGrCaptionLabel)
-        m_pAltGrCaptionLabel->setText(UISoftKeyboard::tr("AltGr Caption"));
+        m_pAltGrCaptionLabel->setText(UISoftKeyboard::tr("AltGr"));
+    if (m_pOkButton)
+        m_pOkButton->setText(UISoftKeyboard::tr("Ok"));
+    if (m_pCancelButton)
+        m_pCancelButton->setText(UISoftKeyboard::tr("Cancel"));
+    if (m_pCaptionEditGroupBox)
+        m_pCaptionEditGroupBox->setTitle(UISoftKeyboard::tr("Captions"));
+    if (m_pSelectedKeyGroupBox)
+        m_pSelectedKeyGroupBox->setTitle(UISoftKeyboard::tr("Selected Key"));
+}
+
+void UISoftKeyEditor::sltHandleOkButton()
+{
+    if (!m_pKey)
+        return;
+    m_pKey->setBaseCaption(m_pBaseCaptionEdit->text());
+    m_pKey->setShiftCaption(m_pShiftCaptionEdit->text());
+    m_pKey->setAltGrCaption(m_pAltGrCaptionEdit->text());
+    emit sigKeyCaptionEdited();
 }
 
 void UISoftKeyEditor::prepareObjects()
 {
-    m_pEditorLayout = new QGridLayout;
-
-    if (!m_pEditorLayout)
-        return;
+    m_pMainLayout = new QVBoxLayout;
+    if (!m_pMainLayout)
+        return;
+    setLayout(m_pMainLayout);
+
+    m_pSelectedKeyGroupBox = new QGroupBox;
+    m_pSelectedKeyGroupBox->setEnabled(false);
+
+    m_pMainLayout->addWidget(m_pSelectedKeyGroupBox);
+    QGridLayout *pSelectedKeyLayout = new QGridLayout(m_pSelectedKeyGroupBox);
+    pSelectedKeyLayout->setSpacing(0);
+    pSelectedKeyLayout->setContentsMargins(0, 0, 0, 0);
+
+    m_pScanCodeLabel = new QLabel;
+    m_pScanCodeEdit = new QLineEdit;
+    m_pScanCodeLabel->setBuddy(m_pScanCodeEdit);
+    m_pScanCodeEdit->setReadOnly(true);
+    pSelectedKeyLayout->addWidget(m_pScanCodeLabel, 0, 0);
+    pSelectedKeyLayout->addWidget(m_pScanCodeEdit, 0, 1);
+
+    m_pPositionLabel= new QLabel;
+    m_pPositionEdit = new QLineEdit;
+    m_pPositionLabel->setBuddy(m_pPositionEdit);
+    m_pPositionEdit->setReadOnly(true);
+    pSelectedKeyLayout->addWidget(m_pPositionLabel, 1, 0);
+    pSelectedKeyLayout->addWidget(m_pPositionEdit, 1, 1);
+
+    QWidget *pCaptionEditor = prepareKeyCaptionEditWidgets();
+    if (pCaptionEditor)
+        pSelectedKeyLayout->addWidget(pCaptionEditor, 2, 0, 2, 2);
+
+    QSpacerItem *pSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding);
+    if (pSpacer)
+        pSelectedKeyLayout->addItem(pSpacer, 4, 1);
+
+    retranslateUi();
+}
+
+QWidget *UISoftKeyEditor::prepareKeyCaptionEditWidgets()
+{
+    m_pCaptionEditGroupBox = new QGroupBox;
+    if (!m_pCaptionEditGroupBox)
+        return 0;
+    m_pCaptionEditGroupBox->setFlat(false);
+    QGridLayout *pCaptionEditorLayout = new QGridLayout(m_pCaptionEditGroupBox);
+    pCaptionEditorLayout->setSpacing(0);
+    pCaptionEditorLayout->setContentsMargins(0, 0, 0, 0);
+
+    if (!pCaptionEditorLayout)
+        return 0;
 
     m_pBaseCaptionLabel = new QLabel;
     m_pBaseCaptionEdit = new QLineEdit;
     m_pBaseCaptionLabel->setBuddy(m_pBaseCaptionEdit);
+    pCaptionEditorLayout->addWidget(m_pBaseCaptionLabel, 0, 0);
+    pCaptionEditorLayout->addWidget(m_pBaseCaptionEdit, 0, 1);
 
     m_pShiftCaptionLabel = new QLabel;
     m_pShiftCaptionEdit = new QLineEdit;
     m_pShiftCaptionLabel->setBuddy(m_pShiftCaptionEdit);
+    pCaptionEditorLayout->addWidget(m_pShiftCaptionLabel, 1, 0);
+    pCaptionEditorLayout->addWidget(m_pShiftCaptionEdit, 1, 1);
 
     m_pAltGrCaptionLabel = new QLabel;
     m_pAltGrCaptionEdit = new QLineEdit;
     m_pAltGrCaptionLabel->setBuddy(m_pAltGrCaptionEdit);
-
-    setLayout(m_pEditorLayout);
-
-    retranslateUi();
+    pCaptionEditorLayout->addWidget(m_pAltGrCaptionLabel, 2, 0);
+    pCaptionEditorLayout->addWidget(m_pAltGrCaptionEdit, 2, 1);
+
+
+    m_pOkButton = new QPushButton;
+    pCaptionEditorLayout->addWidget(m_pOkButton, 3, 0);
+    connect(m_pOkButton, &QPushButton::pressed, this, &UISoftKeyEditor::sltHandleOkButton);
+    m_pCancelButton = new QPushButton;
+    pCaptionEditorLayout->addWidget(m_pCancelButton, 3, 1);
+
+    QSpacerItem *pSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding);
+    if (pSpacer)
+        pCaptionEditorLayout->addItem(pSpacer, 4, 1);
+    return m_pCaptionEditGroupBox;
 }
 
@@ -505,22 +642,40 @@
 }
 
-const QString &UISoftKeyboardKey::staticKeyCap() const
-{
-    return m_strStaticKeyCap;
-}
-
-void UISoftKeyboardKey::setStaticKeyCap(const QString &strStaticKeyCap)
-{
-    m_strStaticKeyCap = strStaticKeyCap;
-}
-
-const QString &UISoftKeyboardKey::keyCap() const
-{
-    return m_strKeyCap;
-}
-
-void UISoftKeyboardKey::setKeyCap(const QString &strKeyCap)
-{
-    m_strKeyCap = strKeyCap;
+const QString UISoftKeyboardKey::baseCaption() const
+{
+    return m_strBaseCaption;
+}
+
+void UISoftKeyboardKey::setBaseCaption(const QString &strBaseCaption)
+{
+    m_strBaseCaption = strBaseCaption;
+    updateText();
+}
+
+const QString UISoftKeyboardKey::shiftCaption() const
+{
+    return m_strShiftCaption;
+}
+
+void UISoftKeyboardKey::setShiftCaption(const QString &strShiftCaption)
+{
+    m_strShiftCaption = strShiftCaption;
+    updateText();
+}
+
+const QString UISoftKeyboardKey::altGrCaption() const
+{
+    return m_strAltGrCaption;
+}
+
+void UISoftKeyboardKey::setAltGrCaption(const QString &strAltGrCaption)
+{
+    m_strAltGrCaption = strAltGrCaption;
+    updateText();
+}
+
+const QString UISoftKeyboardKey::text() const
+{
+    return m_strText;
 }
 
@@ -695,4 +850,15 @@
 }
 
+void UISoftKeyboardKey::updateText()
+{
+    m_strText.clear();
+    if (!m_strShiftCaption.isEmpty())
+        m_strText += QString("%1\n").arg(m_strShiftCaption);
+    if (!m_strBaseCaption.isEmpty())
+        m_strText += QString("%1\n").arg(m_strBaseCaption);
+    if (!m_strAltGrCaption.isEmpty())
+        m_strText += QString("%1\n").arg(m_strAltGrCaption);
+}
+
 /*********************************************************************************************************************************
 *   UISoftKeyboardWidget implementation.                                                                                  *
@@ -708,4 +874,5 @@
     , m_textDefaultColor(QColor(46, 49, 49))
     , m_textPressedColor(QColor(149, 165, 166))
+    , m_keyEditColor(QColor(249, 165, 166))
     , m_iInitialHeight(0)
     , m_iInitialWidth(0)
@@ -719,6 +886,4 @@
     , m_pContextMenu(0)
     , m_pShowPositionsAction(0)
-    , m_pLoadLayoutFileAction(0)
-    , m_pLastSelectedLayout(0)
     , m_pKeyCapEditModeToggleAction(0)
     , m_enmMode(Mode_Keyboard)
@@ -745,5 +910,8 @@
         return;
 
-    m_fScaleFactorX = width() / (float) m_iInitialWidth;
+    int iEditDialogWidth = 0;
+    if (m_enmMode == Mode_KeyCapEdit)
+        iEditDialogWidth = 34 * QApplication::fontMetrics().width('x');
+    m_fScaleFactorX = (width() - iEditDialogWidth) / (float) m_iInitialWidth;
     m_fScaleFactorY = height() / (float) m_iInitialHeight;
 
@@ -758,6 +926,15 @@
     float fLedRadius =  0.8 * unitSize;
     float fLedMargin =  0.6 * unitSize;
-    if (!m_pKeyBeingEdited && m_pKeyCapEditor)
+
+    if (m_enmMode == Mode_KeyCapEdit)
+    {
+        m_pKeyCapEditor->setGeometry(width() - iEditDialogWidth, 0,
+                                     iEditDialogWidth, height());
+        m_pKeyCapEditor->show();
+        m_pKeyCapEditor->setFocus();
+    }
+    else
         m_pKeyCapEditor->hide();
+
     for (int i = 0; i < m_rows.size(); ++i)
     {
@@ -767,17 +944,11 @@
             UISoftKeyboardKey &key = keys[j];
             painter.translate(key.keyGeometry().x(), key.keyGeometry().y());
-            if (&key  == m_pKeyUnderMouse)
+
+            if(&key  == m_pKeyBeingEdited)
+                painter.setBrush(QBrush(m_keyEditColor));
+            else if (&key  == m_pKeyUnderMouse)
                 painter.setBrush(QBrush(m_keyHoverColor));
             else
                 painter.setBrush(QBrush(m_keyDefaultColor));
-
-            if (m_enmMode == Mode_KeyCapEdit && &key == m_pKeyBeingEdited)
-            {
-                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();
-                m_pKeyCapEditor->setFocus();
-            }
 
             if (&key  == m_pKeyPressed)
@@ -794,6 +965,5 @@
                 painter.drawText(textRect, Qt::TextWordWrap, QString::number(key.position()));
             else
-                painter.drawText(textRect, Qt::TextWordWrap,
-                                 !key.keyCap().isEmpty() ? key.keyCap() : key.staticKeyCap());
+                painter.drawText(textRect, Qt::TextWordWrap, key.text());
 
             if (key.type() != UIKeyType_Ordinary)
@@ -831,9 +1001,9 @@
         if (m_pKeyBeingEdited && m_pKeyBeingEdited != m_pKeyUnderMouse)
         {
-            printf("farkli %p\n", m_pKeyBeingEdited);
+            //printf("farkli %p\n", m_pKeyBeingEdited);
         }
-        m_pKeyBeingEdited = m_pKeyUnderMouse;
-        if (m_pKeyBeingEdited && m_pKeyCapEditor)
-            m_pKeyCapEditor->setText(m_pKeyBeingEdited->keyCap());
+        setKeyBeingEdited(m_pKeyUnderMouse);
+        // if (m_pKeyBeingEdited && m_pKeyCapEditor)
+        //     m_pKeyCapEditor->setText(m_pKeyBeingEdited->keyCap());
     }
     update();
@@ -873,5 +1043,5 @@
             if (pKeyEvent && pKeyEvent->key() == Qt::Key_Escape)
             {
-                m_pKeyBeingEdited = 0;
+                setKeyBeingEdited(0);
                 update();
                 return true;
@@ -879,7 +1049,7 @@
             else if (pKeyEvent && (pKeyEvent->key() == Qt::Key_Enter || pKeyEvent->key() == Qt::Key_Return))
             {
-                if (m_pKeyBeingEdited)
-                    m_pKeyBeingEdited->setStaticKeyCap(m_pKeyCapEditor->text());
-                m_pKeyBeingEdited = 0;
+                // if (m_pKeyBeingEdited)
+                //     m_pKeyBeingEdited->setStaticKeyCap(m_pKeyCapEditor->text());
+                setKeyBeingEdited(0);
                 update();
                 return true;
@@ -904,39 +1074,39 @@
 }
 
-void UISoftKeyboardWidget::sltHandleLoadLayout(QAction *pSenderAction)
-{
-    if (!pSenderAction)
-        return;
-    if (pSenderAction == m_pLoadLayoutFileAction)
-    {
-        const QString strFileName = QIFileDialog::getOpenFileName(QString(), UISoftKeyboard::tr("XML files (*.xml)"), this,
-                                                                  UISoftKeyboard::tr("Choose file to load physical keyboard layout.."));
-        if (!strFileName.isEmpty() && createKeyboard(strFileName))
-        {
-            m_pLastSelectedLayout = pSenderAction;
-            m_pLoadLayoutFileAction->setData(strFileName);
-            emit sigLayoutChange(strFileName);
-            return;
-        }
-    }
-    else
-    {
-        QString strLayout = pSenderAction->data().toString();
-        if (!strLayout.isEmpty() && createKeyboard(strLayout))
-        {
-            m_pLastSelectedLayout = pSenderAction;
-            emit sigLayoutChange(strLayout);
-            return;
-        }
-    }
-    /* In case something went wrong try to restore the previous layout: */
-    if (m_pLastSelectedLayout)
-    {
-        QString strLayout = m_pLastSelectedLayout->data().toString();
-        createKeyboard(strLayout);
-        emit sigLayoutChange(strLayout);
-        m_pLastSelectedLayout->setChecked(true);
-    }
-}
+// void UISoftKeyboardWidget::sltHandleLoadLayout(QAction *pSenderAction)
+// {
+//     if (!pSenderAction)
+//         return;
+//     if (pSenderAction == m_pLoadLayoutFileAction)
+//     {
+//         const QString strFileName = QIFileDialog::getOpenFileName(QString(), UISoftKeyboard::tr("XML files (*.xml)"), this,
+//                                                                   UISoftKeyboard::tr("Choose file to load physical keyboard layout.."));
+//         if (!strFileName.isEmpty() && createKeyboard(strFileName))
+//         {
+//             m_pLastSelectedLayout = pSenderAction;
+//             m_pLoadLayoutFileAction->setData(strFileName);
+//             emit sigLayoutChange(strFileName);
+//             return;
+//         }
+//     }
+//     else
+//     {
+//         QString strLayout = pSenderAction->data().toString();
+//         if (!strLayout.isEmpty() && createKeyboard(strLayout))
+//         {
+//             m_pLastSelectedLayout = pSenderAction;
+//             emit sigLayoutChange(strLayout);
+//             return;
+//         }
+//     }
+//     /* In case something went wrong try to restore the previous layout: */
+//     if (m_pLastSelectedLayout)
+//     {
+//         QString strLayout = m_pLastSelectedLayout->data().toString();
+//         createKeyboard(strLayout);
+//         emit sigLayoutChange(strLayout);
+//         m_pLastSelectedLayout->setChecked(true);
+//     }
+// }
 
 void UISoftKeyboardWidget::sltHandleSaveKeyCapFile()
@@ -970,8 +1140,12 @@
            UISoftKeyboardKey &key = keys[j];
            xmlWriter.writeTextElement("position", QString::number(key.position()));
-           if (!key.keyCap().isEmpty())
-               xmlWriter.writeTextElement("keycap", key.keyCap());
-           else
-               xmlWriter.writeTextElement("keycap", key.staticKeyCap());
+           xmlWriter.writeTextElement("basecaption", key.baseCaption());
+           xmlWriter.writeTextElement("shiftcaption", key.shiftCaption());
+           xmlWriter.writeTextElement("altgrcaption", key.altGrCaption());
+
+           // if (!key.keyCap().isEmpty())
+           //     xmlWriter.writeTextElement("keycap", key.keyCap());
+           // else
+           //     xmlWriter.writeTextElement("keycap", key.staticKeyCap());
            xmlWriter.writeEndElement();
        }
@@ -990,15 +1164,15 @@
         return;
     UIKeyboardKeyCapReader keyCapReader(strFileName);
-    const QMap<int, QString> &keyCapMap = keyCapReader.keyCapMap();
+    //const QMap<int, QString> &keyCapMap = keyCapReader.keyCapMap();
 
     for (int i = 0; i < m_rows.size(); ++i)
     {
-        QVector<UISoftKeyboardKey> &keys = m_rows[i].keys();
-        for (int j = 0; j < keys.size(); ++j)
-        {
-            UISoftKeyboardKey &key = keys[j];
-            if (keyCapMap.contains(key.position()))
-                key.setKeyCap(keyCapMap[key.position()]);
-        }
+        //QVector<UISoftKeyboardKey> &keys = m_rows[i].keys();
+        // for (int j = 0; j < keys.size(); ++j)
+        // {
+        //     UISoftKeyboardKey &key = keys[j];
+        //     if (keyCapMap.contains(key.position()))
+        //         key.setKeyCap(keyCapMap[key.position()]);
+        // }
     }
     emit sigKeyCapChange(strFileName);
@@ -1007,10 +1181,10 @@
 void UISoftKeyboardWidget::sltHandleUnloadKeyCaps()
 {
-    for (int i = 0; i < m_rows.size(); ++i)
-    {
-        QVector<UISoftKeyboardKey> &keys = m_rows[i].keys();
-        for (int j = 0; j < keys.size(); ++j)
-            keys[j].setKeyCap(QString());
-    }
+    // for (int i = 0; i < m_rows.size(); ++i)
+    // {
+    //     QVector<UISoftKeyboardKey> &keys = m_rows[i].keys();
+    //     for (int j = 0; j < keys.size(); ++j)
+    //         keys[j].setKeyCap(QString());
+    // }
     emit sigKeyCapChange(QString());
 }
@@ -1021,5 +1195,13 @@
         m_enmMode = Mode_KeyCapEdit;
     else
+    {
         m_enmMode = Mode_Keyboard;
+        m_pKeyBeingEdited = 0;
+    }
+}
+
+void UISoftKeyboardWidget::sltHandleKeyCaptionEdited()
+{
+    update();
 }
 
@@ -1108,21 +1290,9 @@
 {
     /* Choose the first layout action's data as the default layout: */
-    if (!m_pLayoutActionGroup->actions().empty())
-    {
-        QAction *pAction = m_pLayoutActionGroup->actions().at(0);
-        if (pAction)
-        {
-            QString strLayout = pAction->data().toString();
-            if (!strLayout.isEmpty())
-            {
-                if (createKeyboard(strLayout))
-                {
-                    emit sigLayoutChange(strLayout);
-                    m_pLastSelectedLayout = pAction;
-                    pAction->setChecked(true);
-                }
-            }
-        }
-    }
+    if (m_defaultLayouts.isEmpty())
+        return;
+    const QString &strLayout = m_defaultLayouts.at(0);
+    if (createKeyboard(strLayout))
+        emit sigLayoutChange(strLayout);
 }
 
@@ -1217,5 +1387,5 @@
 void UISoftKeyboardWidget::configure()
 {
-    defaultLayouts << ":/101_ansi.xml" << ":/102_iso.xml";
+    m_defaultLayouts << ":/101_ansi.xml" << ":/102_iso.xml";
     setMouseTracking(true);
     setContextMenuPolicy(Qt::CustomContextMenu);
@@ -1226,26 +1396,12 @@
 void UISoftKeyboardWidget::prepareObjects()
 {
-    m_pKeyCapEditor = new QLineEdit(this);
+    m_pKeyCapEditor = new UISoftKeyEditor(this);
     if (m_pKeyCapEditor)
     {
         m_pKeyCapEditor->hide();
         m_pKeyCapEditor->installEventFilter(this);
+        connect(m_pKeyCapEditor, &UISoftKeyEditor::sigKeyCaptionEdited, this, &UISoftKeyboardWidget::sltHandleKeyCaptionEdited);
     }
     m_pContextMenu = new QMenu(this);
-    /* Layout menu: */
-    m_pLayoutActionGroup = new QActionGroup(this);
-    m_pLayoutActionGroup->setExclusive(true);
-    connect(m_pLayoutActionGroup, &QActionGroup::triggered, this, &UISoftKeyboardWidget::sltHandleLoadLayout);
-
-    foreach (const QString &strLayout, defaultLayouts)
-    {
-        QString strName = strLayout.left(strLayout.indexOf('.'));
-        QAction *pAction = m_pLayoutActionGroup->addAction(QString("%1 %2").arg(UISoftKeyboard::tr("Load Layout ")).arg(strName.remove(":/")));
-        pAction->setData(strLayout);
-        pAction->setCheckable(true);
-    }
-    m_pLoadLayoutFileAction = m_pLayoutActionGroup->addAction(UISoftKeyboard::tr("Load Layout File..."));
-    m_pLoadLayoutFileAction->setCheckable(true);
-    m_pContextMenu->addActions(m_pLayoutActionGroup->actions());
 
     /* Keycaps menu: */
@@ -1274,4 +1430,13 @@
         return;
     m_enmMode = Mode_KeyCapEdit;
+}
+
+void UISoftKeyboardWidget::setKeyBeingEdited(UISoftKeyboardKey* pKey)
+{
+    if (m_pKeyBeingEdited == pKey)
+        return;
+    m_pKeyBeingEdited = pKey;
+    if (m_pKeyCapEditor)
+        m_pKeyCapEditor->setKey(pKey);
 }
 
@@ -1399,5 +1564,5 @@
             m_xmlReader.skipCurrentElement();
     }
-    key.setStaticKeyCap(strKeyCap);
+    //key.setStaticKeyCap(strKeyCap);
 }
 
@@ -1532,5 +1697,4 @@
             m_xmlReader.skipCurrentElement();
     }
-
     return true;
 }
@@ -1542,5 +1706,9 @@
     while (m_xmlReader.readNextStartElement())
     {
-        if (m_xmlReader.name() == "keycap")
+        if (m_xmlReader.name() == "basecaption")
+            strKeyCap = m_xmlReader.readElementText();
+        if (m_xmlReader.name() == "shiftcaption")
+            strKeyCap = m_xmlReader.readElementText();
+        if (m_xmlReader.name() == "altgrcaption")
             strKeyCap = m_xmlReader.readElementText();
         else if (m_xmlReader.name() == "position")
@@ -1657,8 +1825,4 @@
 
     statusBar()->setStyleSheet( "QStatusBar::item { border: 0px}" );
-    // QWidget *pStatusBarWidget = new QWidget;
-    // QHBoxLayout *pStatusBarLayout = new QHBoxLayout(pStatusBarWidget);
-    // pStatusBarLayout->setSpacing(0);
-    // pStatusBarLayout->setContentsMargins(0, 0, 0, 0);
 
     m_pSettingsButton = new QToolButton;
@@ -1670,11 +1834,4 @@
     statusBar()->addPermanentWidget(m_pSettingsButton);
 
-    QToolButton *pButton = new QToolButton;
-    pButton->setIcon(UIIconPool::iconSet(":/hd_modify_16px.png"));
-    pButton->setStyleSheet("QToolButton { border: 0px none black; margin: 0px 0px 0px 0px; } QToolButton::menu-indicator {image: none;}");
-    statusBar()->addPermanentWidget(pButton);
-
-
-
     retranslateUi();
 }
