Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp	(revision 54952)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp	(revision 54953)
@@ -25,10 +25,16 @@
 # include "QIWidgetValidator.h"
 # include "UIMachineSettingsGeneral.h"
+ #include "UIModalWindowManager.h"
 # include "UIMessageCenter.h"
 # include "UIConverter.h"
+/* COM includes: */
+# include "CMedium.h"
+# include "CMediumAttachment.h"
 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
 
 UIMachineSettingsGeneral::UIMachineSettingsGeneral()
     : m_fHWVirtExEnabled(false)
+    , m_fEncryptionCipherChanged(false)
+    , m_fEncryptionPasswordChanged(false)
 {
     /* Prepare: */
@@ -95,4 +101,41 @@
     /* 'Description' tab data: */
     generalData.m_strDescription = m_machine.GetDescription();
+
+    /* 'Encryption' tab data: */
+    QString strCipher;
+    bool fEncryptionCipherCommon = true;
+    /* Prepare the map of the encrypted mediums: */
+    EncryptedMediumMap encryptedMediums;
+    foreach (const CMediumAttachment &attachment, m_machine.GetMediumAttachments())
+    {
+        /* Acquire hard-drive attachments only: */
+        if (attachment.GetType() == KDeviceType_HardDisk)
+        {
+            /* Get the attachment medium base: */
+            const CMedium medium = attachment.GetMedium();
+            /* Check medium encryption attributes: */
+            QString strCurrentCipher;
+            const QString strCurrentPasswordId = medium.GetEncryptionSettings(strCurrentCipher);
+            if (medium.isOk())
+            {
+                encryptedMediums.insert(strCurrentPasswordId, medium.GetId());
+                if (strCurrentCipher != strCipher)
+                {
+                    if (strCipher.isNull())
+                        strCipher = strCurrentCipher;
+                    else
+                        fEncryptionCipherCommon = false;
+                }
+            }
+        }
+    }
+    generalData.m_fEncryptionEnabled = !encryptedMediums.isEmpty();
+    generalData.m_fEncryptionCipherChanged = false;
+    generalData.m_fEncryptionPasswordChanged = false;
+    if (fEncryptionCipherCommon)
+        generalData.m_iEncryptionCipherIndex = m_encryptionCiphers.indexOf(strCipher);
+    if (generalData.m_iEncryptionCipherIndex == -1)
+        generalData.m_iEncryptionCipherIndex = 0;
+    generalData.m_encryptedMediums = encryptedMediums;
 
     /* Cache general data: */
@@ -126,4 +169,12 @@
     mTeDescription->setPlainText(generalData.m_strDescription);
 
+    /* 'Encryption' tab data: */
+    AssertPtrReturnVoid(m_pCheckBoxEncryption);
+    AssertPtrReturnVoid(m_pComboCipher);
+    m_pCheckBoxEncryption->setChecked(generalData.m_fEncryptionEnabled);
+    m_pComboCipher->setCurrentIndex(generalData.m_iEncryptionCipherIndex);
+    m_fEncryptionCipherChanged = generalData.m_fEncryptionCipherChanged;
+    m_fEncryptionPasswordChanged = generalData.m_fEncryptionPasswordChanged;
+
     /* Polish page finally: */
     polishPage();
@@ -155,4 +206,36 @@
     generalData.m_strDescription = mTeDescription->toPlainText().isEmpty() ?
                                    QString::null : mTeDescription->toPlainText();
+
+    /* 'Encryption' tab data: */
+    AssertPtrReturnVoid(m_pCheckBoxEncryption);
+    AssertPtrReturnVoid(m_pComboCipher);
+    AssertPtrReturnVoid(m_pEditorEncryptionPassword);
+    generalData.m_fEncryptionEnabled = m_pCheckBoxEncryption->isChecked();
+    generalData.m_fEncryptionCipherChanged = m_fEncryptionCipherChanged;
+    generalData.m_fEncryptionPasswordChanged = m_fEncryptionPasswordChanged;
+    generalData.m_iEncryptionCipherIndex = m_pComboCipher->currentIndex();
+    generalData.m_strEncryptionPassword = m_pEditorEncryptionPassword->text();
+    /* If encryption status, cipher or password is changed: */
+    if (generalData.m_fEncryptionEnabled != m_cache.base().m_fEncryptionEnabled ||
+        generalData.m_fEncryptionCipherChanged != m_cache.base().m_fEncryptionCipherChanged ||
+        generalData.m_fEncryptionPasswordChanged != m_cache.base().m_fEncryptionPasswordChanged)
+    {
+        /* Ask for the disk encryption passwords if necessary: */
+        if (!m_cache.base().m_encryptedMediums.isEmpty())
+        {
+            /* Create corresponding dialog: */
+            QWidget *pDlgParent = windowManager().realParentWindow(window());
+            QPointer<UIAddDiskEncryptionPasswordDialog> pDlg =
+                 new UIAddDiskEncryptionPasswordDialog(pDlgParent,
+                                                       generalData.m_strName,
+                                                       generalData.m_encryptedMediums);
+            /* Execute it and acquire the result: */
+            if (pDlg->exec() == QDialog::Accepted)
+                generalData.m_encryptionPasswords = pDlg->encryptionPasswords();
+            /* Delete dialog if still valid: */
+            if (pDlg)
+                delete pDlg;
+        }
+    }
 
     /* Cache general data: */
@@ -205,4 +288,66 @@
             if (generalData.m_strName != m_cache.base().m_strName)
                 m_machine.SetName(generalData.m_strName);
+
+            /* Encryption tab data: */
+            if (generalData.m_fEncryptionEnabled != m_cache.base().m_fEncryptionEnabled ||
+                generalData.m_fEncryptionCipherChanged != m_cache.base().m_fEncryptionCipherChanged ||
+                generalData.m_fEncryptionPasswordChanged != m_cache.base().m_fEncryptionPasswordChanged)
+            {
+                /* Cipher attribute changed? */
+                QString strNewCipher;
+                if (generalData.m_fEncryptionCipherChanged)
+                {
+                    strNewCipher = generalData.m_fEncryptionEnabled ?
+                                   m_encryptionCiphers.at(generalData.m_iEncryptionCipherIndex) : QString();
+                }
+                /* Password attribute changed? */
+                QString strNewPassword;
+                QString strNewPasswordId;
+                if (generalData.m_fEncryptionPasswordChanged)
+                {
+                    strNewPassword = generalData.m_fEncryptionEnabled ?
+                                     generalData.m_strEncryptionPassword : QString();
+                    strNewPasswordId = generalData.m_fEncryptionEnabled ?
+                                       m_machine.GetName() : QString();
+                }
+
+                /* Get the maps of encrypted mediums and their passwords: */
+                const EncryptedMediumMap &encryptedMedium = generalData.m_encryptedMediums;
+                const EncryptionPasswordsMap &encryptionPasswords = generalData.m_encryptionPasswords;
+                /* Enumerate attachments: */
+                foreach (const CMediumAttachment &attachment, m_machine.GetMediumAttachments())
+                {
+                    /* Enumerate hard-drives only: */
+                    if (attachment.GetType() == KDeviceType_HardDisk)
+                    {
+                        /* Get corresponding medium: */
+                        CMedium medium = attachment.GetMedium();
+
+                        /* Check if old password exists/provided: */
+                        QString strOldPasswordId = encryptedMedium.key(medium.GetId());
+                        QString strOldPassword = encryptionPasswords.value(strOldPasswordId);
+
+//                        printf(" Medium: %s, old password = %s, new cipher = %s, new password = %s, new password id = %s\n",
+//                               medium.GetId().toAscii().constData(),
+//                               strOldPassword.toAscii().constData(),
+//                               strNewCipher.toAscii().constData(),
+//                               strNewPassword.toAscii().constData(),
+//                               strNewPasswordId.toAscii().constData());
+
+                        /* Update encryption: */
+                        CProgress progress = medium.ChangeEncryption(strOldPassword,
+                                                                     strNewCipher,
+                                                                     strNewPassword,
+                                                                     strNewPasswordId);
+//                        if (!medium.isOk())
+//                            printf("  Medium API Error, rc = %s\n", msgCenter().formatRC(medium.lastRC()).toAscii().constData());
+                        progress.WaitForCompletion(-1);
+//                        if (!progress.isOk())
+//                            printf("  Progress API Error, rc = %s\n", msgCenter().formatRC(progress.lastRC()).toAscii().constData());
+//                        if (progress.GetResultCode() != 0)
+//                            printf("  Progress Processing Error, rc = %s\n", msgCenter().formatRC(progress.GetResultCode()).toAscii().constData());
+                    }
+                }
+            }
         }
     }
@@ -219,7 +364,11 @@
     /* Prepare message: */
     UIValidationMessage message;
+
+    /* 'Basic' tab validations: */
     message.first = VBoxGlobal::removeAccelMark(mTwGeneral->tabText(0));
+    message.second.clear();
 
     /* VM name validation: */
+    AssertPtrReturn(m_pNameAndSystemEditor, false);
     if (m_pNameAndSystemEditor->name().trimmed().isEmpty())
     {
@@ -234,4 +383,43 @@
                              "64-bit guest systems require hardware virtualization, "
                              "so this will be enabled automatically if you confirm the changes.");
+    }
+
+    /* Serialize message: */
+    if (!message.second.isEmpty())
+        messages << message;
+
+    /* 'Encryption' tab validations: */
+    message.first = VBoxGlobal::removeAccelMark(mTwGeneral->tabText(3));
+    message.second.clear();
+
+    /* Encryption validation: */
+    AssertPtrReturn(m_pCheckBoxEncryption, false);
+    if (m_pCheckBoxEncryption->isChecked())
+    {
+        /* Cipher should be chosen if once changed: */
+        AssertPtrReturn(m_pComboCipher, false);
+        if (!m_cache.base().m_fEncryptionEnabled ||
+            m_fEncryptionCipherChanged)
+        {
+            if (m_pComboCipher->currentIndex() == 0)
+                message.second << tr("Encryption cipher type is not specified.");
+        }
+        /* Password should be entered and confirmed if once changed: */
+        AssertPtrReturn(m_pEditorEncryptionPassword, false);
+        AssertPtrReturn(m_pEditorEncryptionPasswordConfirm, false);
+        if (!m_cache.base().m_fEncryptionEnabled ||
+            m_fEncryptionPasswordChanged)
+        {
+            if (m_pEditorEncryptionPassword->text().isEmpty())
+                message.second << tr("Encryption password is not entered.");
+            else
+            if (m_pEditorEncryptionPasswordConfirm->text().isEmpty())
+                message.second << tr("Encryption password is not confirmed.");
+            else
+            if (m_pEditorEncryptionPassword->text() !=
+                m_pEditorEncryptionPasswordConfirm->text())
+                message.second << tr("Entered and confirmed encryption passwords doesn't match.");
+            fPass = false;
+        }
     }
 
@@ -289,4 +477,8 @@
     mCbDragAndDrop->setItemText(2, gpConverter->toString(KDnDMode_GuestToHost));
     mCbDragAndDrop->setItemText(3, gpConverter->toString(KDnDMode_Bidirectional));
+
+    /* Translate Cipher type combo: */
+    AssertPtrReturnVoid(m_pComboCipher);
+    m_pComboCipher->setItemText(0, tr("Leave Unchanged", "cipher type"));
 }
 
@@ -300,4 +492,5 @@
     prepareTabAdvanced();
     prepareTabDescription();
+    prepareTabEncryption();
 }
 
@@ -345,4 +538,50 @@
         mTeDescription->setMinimumHeight(150);
 #endif /* Q_WS_MAC */
+    }
+}
+
+void UIMachineSettingsGeneral::prepareTabEncryption()
+{
+    /* Encryption check-box was created in the .ui file: */
+    AssertPtrReturnVoid(m_pCheckBoxEncryption);
+    {
+        /* Configure Encryption check-box: */
+        connect(m_pCheckBoxEncryption, SIGNAL(toggled(bool)),
+                this, SLOT(revalidate()));
+    }
+    /* Encryption Cipher combo was created in the .ui file: */
+    AssertPtrReturnVoid(m_pComboCipher);
+    {
+        /* Configure Encryption Cipher combo: */
+        m_encryptionCiphers << QString()
+                            << "AES-XTS256-PLAIN64"
+                            << "AES-XTS128-PLAIN64";
+        m_pComboCipher->addItems(m_encryptionCiphers);
+        connect(m_pComboCipher, SIGNAL(currentIndexChanged(int)),
+                this, SLOT(sltMarkEncryptionCipherChanged()));
+        connect(m_pComboCipher, SIGNAL(currentIndexChanged(int)),
+                this, SLOT(revalidate()));
+    }
+    /* Encryption Password editor was created in the .ui file: */
+    AssertPtrReturnVoid(m_pEditorEncryptionPassword);
+    {
+        /* Configure Encryption Password editor: */
+        m_pEditorEncryptionPassword->setAlignment(Qt::AlignCenter);
+        m_pEditorEncryptionPassword->setEchoMode(QLineEdit::Password);
+        connect(m_pEditorEncryptionPassword, SIGNAL(textEdited(const QString&)),
+                this, SLOT(sltMarkEncryptionPasswordChanged()));
+        connect(m_pEditorEncryptionPassword, SIGNAL(textEdited(const QString&)),
+                this, SLOT(revalidate()));
+    }
+    /* Encryption Password Confirmation editor was created in the .ui file: */
+    AssertPtrReturnVoid(m_pEditorEncryptionPasswordConfirm);
+    {
+        /* Configure Encryption Password Confirmation editor: */
+        m_pEditorEncryptionPasswordConfirm->setAlignment(Qt::AlignCenter);
+        m_pEditorEncryptionPasswordConfirm->setEchoMode(QLineEdit::Password);
+        connect(m_pEditorEncryptionPasswordConfirm, SIGNAL(textEdited(const QString&)),
+                this, SLOT(sltMarkEncryptionPasswordChanged()));
+        connect(m_pEditorEncryptionPasswordConfirm, SIGNAL(textEdited(const QString&)),
+                this, SLOT(revalidate()));
     }
 }
@@ -371,4 +610,10 @@
     AssertPtrReturnVoid(mTeDescription);
     mTeDescription->setEnabled(isMachineInValidMode());
-}
-
+
+    /* 'Encryption' tab: */
+    AssertPtrReturnVoid(m_pCheckBoxEncryption);
+    AssertPtrReturnVoid(m_pWidgetEncryption);
+    m_pCheckBoxEncryption->setEnabled(isMachineOffline());
+    m_pWidgetEncryption->setEnabled(isMachineOffline() && m_pCheckBoxEncryption->isChecked());
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.h	(revision 54952)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.h	(revision 54953)
@@ -21,4 +21,5 @@
 #include "UISettingsPage.h"
 #include "UIMachineSettingsGeneral.gen.h"
+#include "UIAddDiskEncryptionPasswordDialog.h"
 
 /** Machine settings: General page: Data structure. */
@@ -34,4 +35,9 @@
         , m_dndMode(KDnDMode_Disabled)
         , m_strDescription(QString())
+        , m_fEncryptionEnabled(false)
+        , m_fEncryptionCipherChanged(false)
+        , m_fEncryptionPasswordChanged(false)
+        , m_iEncryptionCipherIndex(-1)
+        , m_strEncryptionPassword(QString())
     {}
 
@@ -45,5 +51,8 @@
                (m_clipboardMode == other.m_clipboardMode) &&
                (m_dndMode == other.m_dndMode) &&
-               (m_strDescription == other.m_strDescription);
+               (m_strDescription == other.m_strDescription) &&
+               (m_fEncryptionEnabled == other.m_fEncryptionEnabled) &&
+               (m_fEncryptionCipherChanged == other.m_fEncryptionCipherChanged) &&
+               (m_fEncryptionPasswordChanged == other.m_fEncryptionPasswordChanged);
     }
 
@@ -69,4 +78,19 @@
     /** Holds the VM description. */
     QString m_strDescription;
+
+    /** Holds whether the encryption is enabled. */
+    bool m_fEncryptionEnabled;
+    /** Holds whether the encryption cipher was changed. */
+    bool m_fEncryptionCipherChanged;
+    /** Holds whether the encryption password was changed. */
+    bool m_fEncryptionPasswordChanged;
+    /** Holds the encryption cipher index. */
+    int m_iEncryptionCipherIndex;
+    /** Holds the encryption password. */
+    QString m_strEncryptionPassword;
+    /** Holds the encrypted medium ids. */
+    EncryptedMediumMap m_encryptedMediums;
+    /** Holds the encryption passwords. */
+    EncryptionPasswordsMap m_encryptionPasswords;
 };
 typedef UISettingsCache<UIDataSettingsMachineGeneral> UICacheSettingsMachineGeneral;
@@ -123,4 +147,11 @@
     void retranslateUi();
 
+private slots:
+
+    /** Marks the encryption cipher as changed. */
+    void sltMarkEncryptionCipherChanged() { m_fEncryptionCipherChanged = true; }
+    /** Marks the encryption cipher and password as changed. */
+    void sltMarkEncryptionPasswordChanged() { m_fEncryptionCipherChanged = true; m_fEncryptionPasswordChanged = true; }
+
 private:
 
@@ -133,4 +164,6 @@
     /** Prepare 'Description' tab routine. */
     void prepareTabDescription();
+    /** Prepare 'Encryption' tab routine. */
+    void prepareTabEncryption();
 
     /** Polish routine. */
@@ -142,4 +175,17 @@
     /** Holds whether HW virtualization extension is enabled. */
     bool m_fHWVirtExEnabled;
+
+    /** Holds whether the encryption cipher was changed.
+      * We are holding that argument here because we do not know
+      * the old <i>cipher</i> for sure to compare the new one with. */
+    bool m_fEncryptionCipherChanged;
+    /** Holds whether the encryption password was changed.
+      * We are holding that argument here because we do not know
+      * the old <i>password</i> at all to compare the new one with. */
+    bool m_fEncryptionPasswordChanged;
+
+    /** Holds the hard-coded encryption cipher list.
+      * We are hard-coding it because there is no place we can get it from. */
+    QStringList m_encryptionCiphers;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.ui
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.ui	(revision 54952)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.ui	(revision 54953)
@@ -208,4 +208,137 @@
       </layout>
      </widget>
+     <widget class="QWidget" name="m_pTabEncryption">
+      <attribute name="title">
+       <string>Enc&amp;ryption</string>
+      </attribute>
+      <layout class="QGridLayout" name="m_pLayoutEncryption">
+       <item row="0" column="0" colspan="2">
+        <widget class="QCheckBox" name="m_pCheckBoxEncryption">
+         <property name="whatsThis">
+          <string>When checked, enables the encryption of this virtual machine.</string>
+         </property>
+         <property name="text">
+          <string>En&amp;able Encryption</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="0">
+        <spacer>
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Fixed</enum>
+         </property>
+         <property name="sizeHint">
+          <size>
+           <width>20</width>
+           <height>0</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="1">
+        <widget class="QWidget" name="m_pWidgetEncryption">
+         <property name="sizePolicy">
+          <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding">
+           <horstretch>1</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <layout class="QGridLayout" name="m_pLayoutEncryptionSettings">
+          <property name="leftMargin">
+           <number>0</number>
+          </property>
+          <property name="topMargin">
+           <number>0</number>
+          </property>
+          <property name="rightMargin">
+           <number>0</number>
+          </property>
+          <property name="bottomMargin">
+           <number>0</number>
+          </property>
+          <item row="0" column="0">
+           <widget class="QLabel" name="m_pLabelCipher">
+            <property name="text">
+             <string>Encryption C&amp;ipher:</string>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+            </property>
+            <property name="buddy">
+             <cstring>m_pComboCipher</cstring>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QComboBox" name="m_pComboCipher">
+            <property name="whatsThis" >
+             <string>Holds the cipher to be used for the virtual machine storage encryption.</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="m_pLabelPassword1">
+            <property name="text">
+             <string>E&amp;nter New Password:</string>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+            </property>
+            <property name="buddy">
+             <cstring>m_pEditorEncryptionPassword</cstring>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QLineEdit" name="m_pEditorEncryptionPassword">
+            <property name="whatsThis" >
+             <string>Holds the password to be assigned for the virtual machine.</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="m_pLabelPassword2">
+            <property name="text">
+             <string>C&amp;onfirm New Password:</string>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+            </property>
+            <property name="buddy">
+             <cstring>m_pEditorEncryptionPasswordConfirm</cstring>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <widget class="QLineEdit" name="m_pEditorEncryptionPasswordConfirm">
+            <property name="whatsThis" >
+             <string>Confirms the password to be assigned for the virtual machine.</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item row="2" column="1">
+        <spacer>
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Expanding</enum>
+         </property>
+         <property name="sizeHint">
+          <size>
+           <width>0</width>
+           <height>0</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
     </widget>
    </item>
@@ -231,4 +364,11 @@
  </customwidgets>
  <resources/>
- <connections/>
+ <connections>
+  <connection>
+   <sender>m_pCheckBoxEncryption</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>m_pWidgetEncryption</receiver>
+   <slot>setEnabled(bool)</slot>
+  </connection>
+ </connections>
 </ui>
