VirtualBox

Changeset 90164 in vbox


Ignore:
Timestamp:
Jul 13, 2021 7:26:44 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
145670
Message:

FE/Qt: bugref:9996. Moving group box creation to a separate class

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

Legend:

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

    r90155 r90164  
    652652        src/wizards/editors/UIHostnameDomainNameEditor.h \
    653653        src/wizards/editors/UIUserNamePasswordEditor.h \
     654        src/wizards/editors/UIWizardNewVMEditors.h \
    654655        src/wizards/newcloudvm/UIWizardNewCloudVM.h \
    655656        src/wizards/newcloudvm/UIWizardNewCloudVMPageBasic1.h \
     
    11501151        src/wizards/editors/UIHostnameDomainNameEditor.cpp \
    11511152        src/wizards/editors/UIUserNamePasswordEditor.cpp \
     1153        src/wizards/editors/UIWizardNewVMEditors.cpp \
    11521154        src/wizards/newcloudvm/UIWizardNewCloudVM.cpp \
    11531155        src/wizards/newcloudvm/UIWizardNewCloudVMPageBasic1.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/editors/UIWizardNewVMEditors.cpp

    r90157 r90164  
    1717
    1818/* Qt includes: */
    19 #include <QGridLayout>
    20 #include <QLabel>
    21 #include <QLineEdit>
    22 #include <QStyle>
    2319#include <QVBoxLayout>
    2420
    2521/* GUI includes: */
    26 #include "QILineEdit.h"
    27 #include "QIRichTextLabel.h"
    28 #include "QIToolButton.h"
    29 #include "UICommon.h"
    30 #include "UIIconPool.h"
    3122#include "UIUserNamePasswordEditor.h"
    32 #include "UIWizardNewVM.h"
     23#include "UIWizardNewVMEditors.h"
    3324
    34 /*********************************************************************************************************************************
    35 *   UIPasswordLineEdit definition.                                                                                        *
    36 *********************************************************************************************************************************/
     25/* Other VBox includes: */
     26#include "iprt/assert.h"
    3727
    38 class UIPasswordLineEdit : public QLineEdit
    39 {
    40     Q_OBJECT;
    41 
    42 signals:
    43 
    44     void sigTextVisibilityToggled(bool fTextVisible);
    45 
    46 public:
    47 
    48     UIPasswordLineEdit(QWidget *pParent = 0);
    49     void toggleTextVisibility(bool fTextVisible);
    50     void mark(bool fError, const QString &strErrorToolTip);
    51 
    52 protected:
    53 
    54     virtual void resizeEvent(QResizeEvent *pEvent) /* override */;
    55     virtual void paintEvent(QPaintEvent *pPaintEvent) /* override */;
    56 
    57 private slots:
    58 
    59     void sltHandleTextVisibilityChange();
    60 
    61 private:
    62 
    63     void prepare();
    64     void adjustTextVisibilityButtonGeometry();
    65 
    66     QIToolButton *m_pTextVisibilityButton;
    67     QIcon m_markIcon;
    68     QLabel *m_pErrorIconLabel;
    69     QString m_strErrorToolTip;
    70     /** When true the line edit is marked with some icon to indicate some error. */
    71     bool m_fMarkForError;
    72 };
    73 
    74 
    75 /*********************************************************************************************************************************
    76 *   UIPasswordLineEdit implementation.                                                                                           *
    77 *********************************************************************************************************************************/
    78 
    79 UIPasswordLineEdit::UIPasswordLineEdit(QWidget *pParent /*= 0 */)
    80     : QLineEdit(pParent)
    81     , m_pTextVisibilityButton(0)
    82     , m_pErrorIconLabel(0)
    83     , m_fMarkForError(false)
     28UIUserNamePasswordGroupBox::UIUserNamePasswordGroupBox(QWidget *pParent /* = 0 */)
     29    :QGroupBox(pParent)
    8430{
    8531    prepare();
    8632}
    8733
    88 void UIPasswordLineEdit::toggleTextVisibility(bool fTextVisible)
     34void UIUserNamePasswordGroupBox::prepare()
    8935{
    90     AssertPtrReturnVoid(m_pTextVisibilityButton);
     36    QVBoxLayout *pUserNameContainerLayout = new QVBoxLayout(this);
     37    m_pUserNamePasswordEditor = new UIUserNamePasswordEditor;
     38    AssertReturnVoid(m_pUserNamePasswordEditor);
     39    m_pUserNamePasswordEditor->setLabelsVisible(true);
     40    m_pUserNamePasswordEditor->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
     41    pUserNameContainerLayout->addWidget(m_pUserNamePasswordEditor);
    9142
    92     if (fTextVisible)
    93     {
    94         setEchoMode(QLineEdit::Normal);
    95         if (m_pTextVisibilityButton)
    96             m_pTextVisibilityButton->setIcon(UIIconPool::iconSet(":/eye_closed_10px.png"));
    97     }
    98     else
    99     {
    100         setEchoMode(QLineEdit::Password);
    101         if (m_pTextVisibilityButton)
    102             m_pTextVisibilityButton->setIcon(UIIconPool::iconSet(":/eye_10px.png"));
    103     }
     43    connect(m_pUserNamePasswordEditor, &UIUserNamePasswordEditor::sigPasswordChanged,
     44            this, &UIUserNamePasswordGroupBox::sigPasswordChanged);
     45    connect(m_pUserNamePasswordEditor, &UIUserNamePasswordEditor::sigUserNameChanged,
     46            this, &UIUserNamePasswordGroupBox::sigUserNameChanged);
    10447}
    10548
    106 void UIPasswordLineEdit::mark(bool fError, const QString &strErrorToolTip)
     49QString UIUserNamePasswordGroupBox::userName() const
    10750{
    108     if (m_fMarkForError == fError &&  m_strErrorToolTip == strErrorToolTip)
    109         return;
    110     m_fMarkForError = fError;
    111     m_strErrorToolTip = strErrorToolTip;
    112     update();
    113 }
    114 
    115 void UIPasswordLineEdit::prepare()
    116 {
    117     m_markIcon = UIIconPool::iconSet(":/status_error_16px.png");
    118     /* Prepare text visibility button: */
    119     m_pTextVisibilityButton = new QIToolButton(this);
    120     if (m_pTextVisibilityButton)
    121     {
    122         m_pTextVisibilityButton->setIconSize(QSize(10, 10));
    123         m_pTextVisibilityButton->setFocusPolicy(Qt::ClickFocus);
    124         m_pTextVisibilityButton->setCursor(Qt::ArrowCursor);
    125         m_pTextVisibilityButton->show();
    126         connect(m_pTextVisibilityButton, &QToolButton::clicked, this, &UIPasswordLineEdit::sltHandleTextVisibilityChange);
    127     }
    128     m_pErrorIconLabel = new QLabel(this);
    129     toggleTextVisibility(false);
    130     adjustTextVisibilityButtonGeometry();
    131 }
    132 
    133 void UIPasswordLineEdit::adjustTextVisibilityButtonGeometry()
    134 {
    135     AssertPtrReturnVoid(m_pTextVisibilityButton);
    136 
    137 #ifdef VBOX_WS_MAC
    138     /* Do not forget to update QIToolButton size on macOS, it's FIXED: */
    139     m_pTextVisibilityButton->setFixedSize(m_pTextVisibilityButton->minimumSizeHint());
    140     /* Calculate suitable position for a QIToolButton, it's FRAMELESS: */
    141     const int iWidth = m_pTextVisibilityButton->width();
    142     const int iMinHeight = qMin(height(), m_pTextVisibilityButton->height());
    143     const int iMaxHeight = qMax(height(), m_pTextVisibilityButton->height());
    144     const int iHalfHeightDiff = (iMaxHeight - iMinHeight) / 2;
    145     m_pTextVisibilityButton->setGeometry(width() - iWidth - iHalfHeightDiff, iHalfHeightDiff, iWidth, iWidth);
    146 #else
    147     int iFrameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
    148     int iSize = height() - 2 * iFrameWidth;
    149     m_pTextVisibilityButton->setGeometry(width() - iSize, iFrameWidth, iSize, iSize);
    150 #endif
    151 }
    152 
    153 void UIPasswordLineEdit::resizeEvent(QResizeEvent *pEvent)
    154 {
    155     /* Call to base-class: */
    156     QLineEdit::resizeEvent(pEvent);
    157     adjustTextVisibilityButtonGeometry();
    158 }
    159 
    160 void UIPasswordLineEdit::paintEvent(QPaintEvent *pPaintEvent)
    161 {
    162     QLineEdit::paintEvent(pPaintEvent);
    163     if (m_fMarkForError)
    164     {
    165         const int iIconMargin = 1. * QApplication::style()->pixelMetric(QStyle::PM_LayoutTopMargin);
    166         int iIconSize = height() - 2 * iIconMargin;
    167         if (!m_pErrorIconLabel)
    168             m_pErrorIconLabel = new QLabel(this);
    169         m_pErrorIconLabel->setPixmap(m_markIcon.pixmap(windowHandle(), QSize(iIconSize, iIconSize)));
    170         int iIconX = width() - iIconSize - iIconMargin;
    171         if (m_pTextVisibilityButton)
    172             iIconX -= m_pTextVisibilityButton->width() - iIconMargin;
    173         m_pErrorIconLabel->move(iIconX, iIconMargin);
    174         m_pErrorIconLabel->setToolTip(m_strErrorToolTip);
    175         m_pErrorIconLabel->show();
    176     }
    177     else
    178     {
    179         if (m_pErrorIconLabel)
    180             m_pErrorIconLabel->hide();
    181     }
    182 }
    183 
    184 void UIPasswordLineEdit::sltHandleTextVisibilityChange()
    185 {
    186     bool fTextVisible = false;
    187     if (echoMode() == QLineEdit::Normal)
    188         fTextVisible = false;
    189     else
    190         fTextVisible = true;
    191     toggleTextVisibility(fTextVisible);
    192     emit sigTextVisibilityToggled(fTextVisible);
    193 }
    194 
    195 
    196 /*********************************************************************************************************************************
    197 *   UIUserNamePasswordEditor implementation.                                                                                     *
    198 *********************************************************************************************************************************/
    199 
    200 UIUserNamePasswordEditor::UIUserNamePasswordEditor(QWidget *pParent /*  = 0 */)
    201     : QIWithRetranslateUI<QWidget>(pParent)
    202     , m_pUserNameLineEdit(0)
    203     , m_pPasswordLineEdit(0)
    204     , m_pPasswordRepeatLineEdit(0)
    205     , m_pUserNameLabel(0)
    206     , m_pPasswordLabel(0)
    207     , m_pPasswordRepeatLabel(0)
    208     , m_fShowPlaceholderText(true)
    209     , m_fLabelsVisible(true)
    210 {
    211     prepare();
    212 }
    213 
    214 QString UIUserNamePasswordEditor::userName() const
    215 {
    216     if (m_pUserNameLineEdit)
    217         return m_pUserNameLineEdit->text();
     51    if (m_pUserNamePasswordEditor)
     52        return m_pUserNamePasswordEditor->userName();
    21853    return QString();
    21954}
    22055
    221 void UIUserNamePasswordEditor::setUserName(const QString &strUserName)
     56void UIUserNamePasswordGroupBox::setUserName(const QString &strUserName)
    22257{
    223     if (m_pUserNameLineEdit)
    224         return m_pUserNameLineEdit->setText(strUserName);
     58    if (m_pUserNamePasswordEditor)
     59        m_pUserNamePasswordEditor->setUserName(strUserName);
    22560}
    22661
    227 QString UIUserNamePasswordEditor::password() const
     62QString UIUserNamePasswordGroupBox::password() const
    22863{
    229     if (m_pPasswordLineEdit)
    230         return m_pPasswordLineEdit->text();
     64    if (m_pUserNamePasswordEditor)
     65        return m_pUserNamePasswordEditor->password();
    23166    return QString();
    23267}
    23368
    234 void UIUserNamePasswordEditor::setPassword(const QString &strPassword)
     69void UIUserNamePasswordGroupBox::setPassword(const QString &strPassword)
    23570{
    236     if (m_pPasswordLineEdit)
    237         m_pPasswordLineEdit->setText(strPassword);
    238     if (m_pPasswordRepeatLineEdit)
    239         m_pPasswordRepeatLineEdit->setText(strPassword);
     71    if (m_pUserNamePasswordEditor)
     72        m_pUserNamePasswordEditor->setPassword(strPassword);
    24073}
    24174
    242 bool UIUserNamePasswordEditor::isUserNameComplete()
     75bool UIUserNamePasswordGroupBox::isComplete()
    24376{
    244     bool fComplete = (m_pUserNameLineEdit && !m_pUserNameLineEdit->text().isEmpty());
    245     if (m_pUserNameLineEdit)
    246         m_pUserNameLineEdit->mark(!fComplete, UIUserNamePasswordEditor::tr("Invalid username"));
    247     return fComplete;
     77    if (m_pUserNamePasswordEditor)
     78        return m_pUserNamePasswordEditor->isComplete();
     79    return false;
    24880}
    249 
    250 bool UIUserNamePasswordEditor::isPasswordComplete()
    251 {
    252     bool fPasswordOK = true;
    253     if (m_pPasswordLineEdit && m_pPasswordRepeatLineEdit)
    254     {
    255         if (m_pPasswordLineEdit->text() != m_pPasswordRepeatLineEdit->text())
    256             fPasswordOK = false;
    257         if (m_pPasswordLineEdit->text().isEmpty())
    258             fPasswordOK = false;
    259         m_pPasswordLineEdit->mark(!fPasswordOK, m_strPasswordError);
    260         m_pPasswordRepeatLineEdit->mark(!fPasswordOK, m_strPasswordError);
    261     }
    262     return fPasswordOK;
    263 }
    264 
    265 bool UIUserNamePasswordEditor::isComplete()
    266 {
    267     bool fUserNameField = isUserNameComplete();
    268     bool fPasswordField = isPasswordComplete();
    269     return fUserNameField && fPasswordField;
    270 }
    271 
    272 void UIUserNamePasswordEditor::setPlaceholderTextEnabled(bool fEnabled)
    273 {
    274     if (m_fShowPlaceholderText == fEnabled)
    275         return;
    276     m_fShowPlaceholderText = fEnabled;
    277     retranslateUi();
    278 }
    279 
    280 void UIUserNamePasswordEditor::setLabelsVisible(bool fVisible)
    281 {
    282     if (m_fLabelsVisible == fVisible)
    283         return;
    284     m_fLabelsVisible = fVisible;
    285     m_pUserNameLabel->setVisible(fVisible);
    286     m_pPasswordLabel->setVisible(fVisible);
    287     m_pPasswordRepeatLabel->setVisible(fVisible);
    288 
    289 }
    290 
    291 void UIUserNamePasswordEditor::retranslateUi()
    292 {
    293     QString strPassword = UIUserNamePasswordEditor::tr("Pass&word");
    294     QString strRepeatPassword = UIUserNamePasswordEditor::tr("&Repeat Password");
    295     QString strUsername = UIUserNamePasswordEditor::tr("U&sername");
    296     if (m_pUserNameLabel)
    297     {
    298         m_pUserNameLabel->setText(QString("%1%2").arg(strUsername).arg(":"));
    299         m_pUserNameLabel->setToolTip(UIUserNamePasswordEditor::tr("Type the user name which will be used in attended install:"));
    300 
    301     }
    302     if (m_pPasswordLabel)
    303     {
    304         m_pPasswordLabel->setText(QString("%1%2").arg(strPassword).arg(":"));
    305         m_pPasswordLabel->setToolTip(UIUserNamePasswordEditor::tr("Type the password for the user name"));
    306 
    307     }
    308     if (m_pPasswordRepeatLabel)
    309     {
    310         m_pPasswordRepeatLabel->setText(QString("%1%2").arg(strRepeatPassword).arg(":"));
    311         m_pPasswordRepeatLabel->setToolTip(UIUserNamePasswordEditor::tr("Retype the password:"));
    312     }
    313 
    314     if (m_fShowPlaceholderText)
    315     {
    316         if(m_pUserNameLineEdit)
    317             m_pUserNameLineEdit->setPlaceholderText(strUsername.remove('&'));
    318         if (m_pPasswordLineEdit)
    319             m_pPasswordLineEdit->setPlaceholderText(strPassword.remove('&'));
    320         if (m_pPasswordRepeatLineEdit)
    321             m_pPasswordRepeatLineEdit->setPlaceholderText(strRepeatPassword.remove('&'));
    322     }
    323     else
    324     {
    325         if(m_pUserNameLineEdit)
    326             m_pUserNameLineEdit->setPlaceholderText(QString());
    327         if (m_pPasswordLineEdit)
    328             m_pPasswordLineEdit->setPlaceholderText(QString());
    329         if (m_pPasswordRepeatLineEdit)
    330             m_pPasswordRepeatLineEdit->setPlaceholderText(QString());
    331     }
    332     m_strPasswordError = UIUserNamePasswordEditor::tr("Invalid password pair");
    333 }
    334 
    335 template <class T>
    336 void UIUserNamePasswordEditor::addLineEdit(int &iRow, QLabel *&pLabel, T *&pLineEdit, QGridLayout *pLayout)
    337 {
    338     if (!pLayout || pLabel || pLineEdit)
    339         return;
    340     pLabel = new QLabel;
    341     if (!pLabel)
    342         return;
    343     pLabel->setAlignment(Qt::AlignRight);
    344     pLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
    345 
    346     pLayout->addWidget(pLabel, iRow, 0, 1, 1);
    347 
    348     pLineEdit = new T;
    349     if (!pLineEdit)
    350         return;
    351     pLayout->addWidget(pLineEdit, iRow, 1, 1, 3);
    352 
    353     pLabel->setBuddy(pLineEdit);
    354     ++iRow;
    355     return;
    356 }
    357 
    358 void UIUserNamePasswordEditor::prepare()
    359 {
    360     QGridLayout *pMainLayout = new QGridLayout;
    361     pMainLayout->setContentsMargins(0, 0, 0, 0);
    362     pMainLayout->setColumnStretch(0, 0);
    363     pMainLayout->setColumnStretch(1, 1);
    364     if (!pMainLayout)
    365         return;
    366     setLayout(pMainLayout);
    367     int iRow = 0;
    368     addLineEdit<QILineEdit>(iRow, m_pUserNameLabel, m_pUserNameLineEdit, pMainLayout);
    369     addLineEdit<UIPasswordLineEdit>(iRow, m_pPasswordLabel, m_pPasswordLineEdit, pMainLayout);
    370     addLineEdit<UIPasswordLineEdit>(iRow, m_pPasswordRepeatLabel, m_pPasswordRepeatLineEdit, pMainLayout);
    371 
    372     connect(m_pPasswordLineEdit, &UIPasswordLineEdit::sigTextVisibilityToggled,
    373             this, &UIUserNamePasswordEditor::sltHandlePasswordVisibility);
    374     connect(m_pPasswordRepeatLineEdit, &UIPasswordLineEdit::sigTextVisibilityToggled,
    375             this, &UIUserNamePasswordEditor::sltHandlePasswordVisibility);
    376     connect(m_pPasswordLineEdit, &UIPasswordLineEdit::textChanged,
    377             this, &UIUserNamePasswordEditor::sltPasswordChanged);
    378     connect(m_pPasswordRepeatLineEdit, &UIPasswordLineEdit::textChanged,
    379             this, &UIUserNamePasswordEditor::sltPasswordChanged);
    380     connect(m_pUserNameLineEdit, &QILineEdit::textChanged,
    381             this, &UIUserNamePasswordEditor::sltUserNameChanged);
    382 
    383     retranslateUi();
    384 }
    385 
    386 void UIUserNamePasswordEditor::sltHandlePasswordVisibility(bool fPasswordVisible)
    387 {
    388     if (m_pPasswordLineEdit)
    389         m_pPasswordLineEdit->toggleTextVisibility(fPasswordVisible);
    390     if (m_pPasswordRepeatLineEdit)
    391         m_pPasswordRepeatLineEdit->toggleTextVisibility(fPasswordVisible);
    392 }
    393 
    394 void UIUserNamePasswordEditor::sltUserNameChanged()
    395 {
    396     isUserNameComplete();
    397     emit sigUserNameChanged(m_pUserNameLineEdit->text());
    398 }
    399 
    400 void UIUserNamePasswordEditor::sltPasswordChanged()
    401 {
    402     isPasswordComplete();
    403     emit sigPasswordChanged(m_pPasswordLineEdit->text());
    404 }
    405 
    406 
    407 #include "UIUserNamePasswordEditor.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/editors/UIWizardNewVMEditors.h

    r90157 r90164  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIUserNamePasswordEditor class declaration.
     3 * VBox Qt GUI - UIWizardNewVMEditors class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef FEQT_INCLUDED_SRC_wizards_editors_UIUserNamePasswordEditor_h
    19 #define FEQT_INCLUDED_SRC_wizards_editors_UIUserNamePasswordEditor_h
     18#ifndef FEQT_INCLUDED_SRC_wizards_editors_UIWizardNewVMEditors_h
     19#define FEQT_INCLUDED_SRC_wizards_editors_UIWizardNewVMEditors_h
    2020#ifndef RT_WITHOUT_PRAGMA_ONCE
    2121# pragma once
     
    2424/* Qt includes: */
    2525#include <QIcon>
    26 #include <QWidget>
     26#include <QGroupBox>
    2727
    2828/* Local includes: */
     
    3434class QILineEdit;
    3535class UIPasswordLineEdit;
     36class UIUserNamePasswordEditor;
    3637
    37 class UIUserNamePasswordEditor : public QIWithRetranslateUI<QWidget>
     38class UIUserNamePasswordGroupBox : public QGroupBox
    3839{
    39 
    4040    Q_OBJECT;
    4141
     
    4747public:
    4848
    49     UIUserNamePasswordEditor(QWidget *pParent = 0);
     49    UIUserNamePasswordGroupBox(QWidget *pParent = 0);
    5050
    51     QString userName() const;
    52     void setUserName(const QString &strUserName);
     51    /** @name Wrappers for UIUserNamePasswordEditor
     52     * @{ */
     53       QString userName() const;
     54       void setUserName(const QString &strUserName);
    5355
    54     QString password() const;
    55     void setPassword(const QString &strPassword);
    56 
    57     /** Returns false if username or password fields are empty, or password fields do not match. */
    58     bool isComplete();
    59 
    60     /** When fEnabled true place holder texts for the line edits are shown. */
    61     void setPlaceholderTextEnabled(bool fEnabled);
    62     void setLabelsVisible(bool fVisible);
    63 
    64 protected:
    65 
    66     void retranslateUi();
    67 
    68 private slots:
    69 
    70     void sltHandlePasswordVisibility(bool fPasswordVisible);
    71     void sltUserNameChanged();
    72     void sltPasswordChanged();
     56       QString password() const;
     57       void setPassword(const QString &strPassword);
     58       bool isComplete();
     59    /** @} */
    7360
    7461private:
    7562
    7663    void prepare();
    77     template <class T>
    78     void addLineEdit(int &iRow, QLabel *&pLabel, T *&pLineEdit, QGridLayout *pLayout);
    7964
    80     bool isUserNameComplete();
    81     bool isPasswordComplete();
    82 
    83     QILineEdit         *m_pUserNameLineEdit;
    84     UIPasswordLineEdit *m_pPasswordLineEdit;
    85     UIPasswordLineEdit *m_pPasswordRepeatLineEdit;
    86 
    87     QLabel *m_pUserNameLabel;
    88     QLabel *m_pPasswordLabel;
    89     QLabel *m_pPasswordRepeatLabel;
    90 
    91     bool m_fShowPlaceholderText;
    92     bool m_fLabelsVisible;
    93 
    94     QString m_strPasswordError;
     65    UIUserNamePasswordEditor *m_pUserNamePasswordEditor;
    9566};
    9667
    97 #endif /* !FEQT_INCLUDED_SRC_wizards_editors_UIUserNamePasswordEditor_h */
     68#endif /* !FEQT_INCLUDED_SRC_wizards_editors_UIWizardNewVMEditors_h */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette