VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/ui/VBoxSnapshotsWgt.ui.h@ 4005

Last change on this file since 4005 was 4005, checked in by vboxsync, 18 years ago

2150: Make snapshot tree items visible when selected:

Done as requested.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.9 KB
Line 
1/**
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * Snapshot details dialog (Qt Designer)
5 */
6
7/*
8 * Copyright (C) 2006-2007 innotek GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.215389.xyz. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * If you received this file as part of a commercial VirtualBox
19 * distribution, then only the terms of your commercial VirtualBox
20 * license agreement apply instead of the previous paragraph.
21 */
22
23/****************************************************************************
24** ui.h extension file, included from the uic-generated form implementation.
25**
26** If you want to add, delete, or rename functions or slots, use
27** Qt Designer to update this file, preserving your code.
28**
29** You should not define a constructor or destructor in this file.
30** Instead, write your code in functions called init() and destroy().
31** These will automatically be called by the form's constructor and
32** destructor.
33*****************************************************************************/
34
35/** QListViewItem subclass for snapshots */
36class VBoxSnapshotsWgt::ListViewItem : public QListViewItem
37{
38public:
39
40 /** Normal snapshot item */
41 ListViewItem (QListView *lv, const CSnapshot &aSnapshot)
42 : QListViewItem (lv)
43 , mBld (false), mItal (false)
44 , mSnapshot (aSnapshot)
45 {
46 recache();
47 }
48
49 /** Normal snapshot item */
50 ListViewItem (QListViewItem *lvi, const CSnapshot &aSnapshot)
51 : QListViewItem (lvi)
52 , mBld (false), mItal (false)
53 , mSnapshot (aSnapshot)
54 {
55 recache();
56 }
57
58 /** Current state item */
59 ListViewItem (QListView *lv, const CMachine &aMachine)
60 : QListViewItem (lv)
61 , mBld (false), mItal (true)
62 , mMachine (aMachine)
63 {
64 recache();
65 updateCurrentState (mMachine.GetState());
66 }
67
68 /** Current state item */
69 ListViewItem (QListViewItem *lvi, const CMachine &aMachine)
70 : QListViewItem (lvi)
71 , mBld (false), mItal (true)
72 , mMachine (aMachine)
73 {
74 recache();
75 updateCurrentState (mMachine.GetState());
76 }
77
78 bool bold() const { return mBld; }
79 void setBold (bool bold)
80 {
81 mBld = bold;
82 repaint();
83 }
84
85 bool italic() const { return mItal; }
86 void setItalic (bool italic)
87 {
88 mItal = italic;
89 repaint();
90 }
91
92 void paintCell (QPainter *p, const QColorGroup &cg, int column, int width, int align)
93 {
94 QFont font = p->font();
95 if (font.bold() != mBld)
96 font.setBold (mBld);
97 if (font.italic() != mItal)
98 font.setItalic (mItal);
99 if (font != p->font())
100 p->setFont (font);
101 QListViewItem::paintCell (p, cg, column, width, align);
102 }
103
104 int width (const QFontMetrics &fm, const QListView *lv, int c) const
105 {
106 QFont font = lv->font();
107 if (font.bold() != mBld)
108 font.setBold (mBld);
109 if (font.italic() != mItal)
110 font.setItalic (mItal);
111 if (font != lv->font())
112 return QListViewItem::width (QFontMetrics (font), lv, c);
113 return QListViewItem::width (fm, lv, c);
114 }
115
116 CSnapshot snapshot() const { return mSnapshot; }
117 QUuid snapshotId() const { return mId; }
118
119 CEnums::MachineState machineState() const { return mMachineState; }
120
121 void recache()
122 {
123 if (!mSnapshot.isNull())
124 {
125 mId = mSnapshot.GetId();
126 setText (0, mSnapshot.GetName());
127 mOnline = mSnapshot.GetOnline();
128 setPixmap (0, vboxGlobal().snapshotIcon (mOnline));
129 mDesc = mSnapshot.GetDescription();
130 mTimestamp.setTime_t (mSnapshot.GetTimeStamp() / 1000);
131 mCurStateModified = false;
132 }
133 else
134 {
135 Assert (!mMachine.isNull());
136 mCurStateModified = mMachine.GetCurrentStateModified();
137 setText (0, mCurStateModified ?
138 VBoxSnapshotsWgt::tr ("Current State (changed)",
139 "Current State (Modified)") :
140 VBoxSnapshotsWgt::tr ("Current State",
141 "Current State (Unmodified)"));
142 mDesc = mCurStateModified ?
143 VBoxSnapshotsWgt::tr ("The current state differs from the state "
144 "stored in the current snapshot") :
145 parent() != 0 ? /* we're not the only item in the view */
146 VBoxSnapshotsWgt::tr ("The current state is identical to the state "
147 "stored in the current snapshot") :
148 QString::null;
149 }
150 }
151
152 void updateCurrentState (CEnums::MachineState aState)
153 {
154 AssertReturn (!mMachine.isNull(), (void) 0);
155 setPixmap (0, vboxGlobal().toIcon (aState));
156 mMachineState = aState;
157 mTimestamp.setTime_t (mMachine.GetLastStateChange() / 1000);
158 }
159
160 QString toolTipText() const
161 {
162 QString name = !mSnapshot.isNull() ?
163 text (0) : text (0);
164
165 bool dateTimeToday = mTimestamp.date() == QDate::currentDate();
166 QString dateTime = dateTimeToday ?
167 mTimestamp.time().toString (Qt::LocalDate) :
168 mTimestamp.toString (Qt::LocalDate);
169
170 QString details;
171 if (!mSnapshot.isNull())
172 {
173 /* the current snapshot is always bold */
174 if (mBld)
175 details = VBoxSnapshotsWgt::tr (" (current, ", "Snapshot details");
176 else
177 details = " (";
178 details += mOnline ? VBoxSnapshotsWgt::tr ("online)", "Snapshot details")
179 : VBoxSnapshotsWgt::tr ("offline)", "Snapshot details");
180
181 if (dateTimeToday)
182 dateTime = VBoxSnapshotsWgt::tr ("Taken at %1", "Snapshot (time)")
183 .arg (dateTime);
184 else
185 dateTime = VBoxSnapshotsWgt::tr ("Taken on %1", "Snapshot (date + time)")
186 .arg (dateTime);
187 }
188 else
189 {
190 dateTime = VBoxSnapshotsWgt::tr ("%1 since %2", "Current State (time or date + time)")
191 .arg (vboxGlobal().toString (mMachineState))
192 .arg (dateTime);
193 }
194
195 QString toolTip = QString ("<nobr><b>%1</b>%2</nobr><br><nobr>%3</nobr>")
196 .arg (name) .arg (details)
197 .arg (dateTime);
198
199 if (!mDesc.isEmpty())
200 toolTip += "<br><hr>" + mDesc;
201
202 return toolTip;
203 }
204
205 void okRename (int aCol)
206 {
207 QListViewItem::okRename (aCol);
208 AssertReturn (aCol == 0 && !mSnapshot.isNull(), (void) 0);
209 mSnapshot.SetName (text (0));
210 }
211
212private:
213
214 bool mBld : 1;
215 bool mItal : 1;
216
217 CSnapshot mSnapshot;
218 CMachine mMachine;
219
220 QUuid mId;
221 bool mOnline;
222 QString mDesc;
223 QDateTime mTimestamp;
224
225 bool mCurStateModified;
226 CEnums::MachineState mMachineState;
227};
228
229////////////////////////////////////////////////////////////////////////////////
230
231/** Tooltips for snapshots */
232class VBoxSnapshotsWgt::ToolTip : public QToolTip
233{
234public:
235
236 ToolTip (QListView *aLV, QWidget *aParent, QToolTipGroup *aTG = 0)
237 : QToolTip (aParent, aTG), mLV (aLV)
238 {}
239
240 virtual ~ToolTip()
241 {
242 remove (parentWidget());
243 }
244
245 void maybeTip (const QPoint &aPnt);
246
247private:
248
249 QListView *mLV;
250};
251
252void VBoxSnapshotsWgt::ToolTip::maybeTip (const QPoint &aPnt)
253{
254 ListViewItem *lvi = static_cast <ListViewItem *> (mLV->itemAt (aPnt));
255 if (!lvi)
256 return;
257
258 if (parentWidget()->topLevelWidget()->inherits ("QMainWindow"))
259 {
260 /*
261 * Ensure the main window doesn't show the text from the previous
262 * tooltip in the status bar.
263 */
264 QToolTipGroup *toolTipGroup =
265 (::qt_cast <QMainWindow *> (parentWidget()->topLevelWidget()))->
266 toolTipGroup();
267 if (toolTipGroup)
268 {
269 int index = toolTipGroup->metaObject()->findSignal("removeTip()", false);
270 toolTipGroup->qt_emit (index, 0);
271 }
272 }
273
274 tip (mLV->itemRect (lvi), lvi->toolTipText());
275}
276
277////////////////////////////////////////////////////////////////////////////////
278
279void VBoxSnapshotsWgt::init()
280{
281 mCurSnapshotItem = 0;
282
283 listView->setItemMargin (2);
284 listView->header()->hide();
285 listView->setRootIsDecorated (true);
286 /* we have our own tooltips */
287 listView->setShowToolTips (false);
288 /* disable sorting */
289 listView->setSorting (-1);
290 /* disable unselecting items by clicking in the unused area of the list */
291 new QIListViewSelectionPreserver (this, listView);
292
293 /* toolbar */
294 VBoxToolBar *toolBar = new VBoxToolBar (0, this, "snapshotToolBar");
295
296 curStateActionGroup->addTo (toolBar);
297 toolBar->addSeparator();
298 snapshotActionGroup->addTo (toolBar);
299 toolBar->addSeparator();
300 showSnapshotDetailsAction->addTo (toolBar);
301
302 toolBar->setUsesTextLabel (false);
303 toolBar->setUsesBigPixmaps (true);
304 toolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
305 VBoxSnapshotsWgtLayout->insertWidget (0, toolBar);
306#ifdef Q_WS_MAC
307 toolBar->setMacStyle();
308#endif
309
310 /* context menu */
311 mContextMenu = new QPopupMenu (this);
312 mContextMenuDirty = true;
313
314 /* icons */
315 discardSnapshotAction->setIconSet (VBoxGlobal::iconSetEx (
316 "discard_snapshot_22px.png", "discard_snapshot_16px.png",
317 "discard_snapshot_dis_22px.png", "discard_snapshot_dis_16px.png"));
318 takeSnapshotAction->setIconSet (VBoxGlobal::iconSetEx (
319 "take_snapshot_22px.png", "take_snapshot_16px.png",
320 "take_snapshot_dis_22px.png", "take_snapshot_dis_16px.png"));
321 revertToCurSnapAction->setIconSet (VBoxGlobal::iconSetEx (
322 "discard_cur_state_22px.png", "discard_cur_state_16px.png",
323 "discard_cur_state_dis_22px.png", "discard_cur_state_dis_16px.png"));
324 discardCurSnapAndStateAction->setIconSet (VBoxGlobal::iconSetEx (
325 "discard_cur_state_snapshot_22px.png", "discard_cur_state_snapshot_16px.png",
326 "discard_cur_state_snapshot_dis_22px.png", "discard_cur_state_snapshot_dis_16px.png"));
327 showSnapshotDetailsAction->setIconSet (VBoxGlobal::iconSetEx (
328 "show_snapshot_details_22px.png", "show_snapshot_details_16px.png",
329 "show_snapshot_details_dis_22px.png", "show_snapshot_details_dis_16px.png"));
330
331 /* tooltip */
332 mToolTip = new ToolTip (listView, listView->viewport());
333}
334
335void VBoxSnapshotsWgt::destroy()
336{
337 delete mToolTip;
338}
339
340void VBoxSnapshotsWgt::setMachine (const CMachine &aMachine)
341{
342 mMachine = aMachine;
343
344 if (aMachine.isNull())
345 {
346 mMachineId = QUuid();
347 mSessionState = CEnums::InvalidSessionState;
348 }
349 else
350 {
351 mMachineId = aMachine.GetId();
352 mSessionState = aMachine.GetSessionState();
353 }
354
355 refreshAll();
356}
357
358VBoxSnapshotsWgt::ListViewItem *VBoxSnapshotsWgt::findItem (const QUuid &aSnapshotId)
359{
360 QListViewItemIterator it (listView);
361 while (it.current())
362 {
363 ListViewItem *lvi = static_cast <ListViewItem *> (it.current());
364 if (lvi->snapshotId() == aSnapshotId)
365 return lvi;
366 ++ it;
367 }
368
369 return 0;
370}
371
372void VBoxSnapshotsWgt::refreshAll (bool aKeepSelected /* = false */)
373{
374 QUuid selected, selectedFirstChild;
375 if (aKeepSelected)
376 {
377 ListViewItem *cur = static_cast <ListViewItem *> (listView->selectedItem());
378 Assert (cur);
379 if (cur)
380 {
381 selected = cur->snapshotId();
382 if (cur->firstChild())
383 selectedFirstChild =
384 static_cast <ListViewItem *> (cur->firstChild())->snapshotId();
385 }
386 }
387
388 listView->clear();
389
390 if (mMachine.isNull())
391 {
392 listView_currentChanged (NULL);
393 return;
394 }
395
396 /* get the first snapshot */
397 if (mMachine.GetSnapshotCount() > 0)
398 {
399 CSnapshot snapshot = mMachine.GetSnapshot (QUuid());
400
401 populateSnapshots (snapshot, 0);
402 Assert (mCurSnapshotItem);
403
404 /* add the "current state" item */
405 new ListViewItem (mCurSnapshotItem, mMachine);
406
407 ListViewItem *cur = 0;
408 if (aKeepSelected)
409 {
410 cur = findItem (selected);
411 if (cur == 0)
412 cur = findItem (selectedFirstChild);
413 }
414 if (cur == 0)
415 cur = curStateItem();
416 listView->setSelected (cur, true);
417 listView->ensureItemVisible (cur);
418 }
419 else
420 {
421 mCurSnapshotItem = NULL;
422
423 /* add the "current state" item */
424 ListViewItem *csi = new ListViewItem (listView, mMachine);
425
426 listView->setSelected (csi, true);
427 /*
428 * stupid Qt doesn't issue this signal when only one item is added
429 * to the empty list -- do it manually
430 */
431 listView_currentChanged (csi);
432 }
433
434 listView->adjustColumn (0);
435}
436
437VBoxSnapshotsWgt::ListViewItem *VBoxSnapshotsWgt::curStateItem()
438{
439 QListViewItem *csi = mCurSnapshotItem ? mCurSnapshotItem->firstChild()
440 : listView->firstChild();
441 Assert (csi);
442 return static_cast <ListViewItem *> (csi);
443}
444
445void VBoxSnapshotsWgt::populateSnapshots (const CSnapshot &snapshot, QListViewItem *item)
446{
447
448 ListViewItem *si = 0;
449 if (item)
450 si = new ListViewItem (item, snapshot);
451 else
452 si = new ListViewItem (listView, snapshot);
453
454 if (mMachine.GetCurrentSnapshot().GetId() == snapshot.GetId())
455 {
456 si->setBold (true);
457 mCurSnapshotItem = si;
458 }
459
460 CSnapshotEnumerator en = snapshot.GetChildren().Enumerate();
461 while (en.HasMore())
462 {
463 CSnapshot sn = en.GetNext();
464 populateSnapshots (sn, si);
465 }
466
467 si->setOpen (true);
468 si->setRenameEnabled (0, true);
469}
470
471void VBoxSnapshotsWgt::listView_currentChanged (QListViewItem *item)
472{
473 /* Make the selected item visible */
474 if (item)
475 {
476 listView->ensureItemVisible (item);
477 listView->setContentsPos (item->height() * item->depth(),
478 listView->contentsY());
479 }
480
481 /* whether another direct session is open or not */
482 bool busy = mSessionState != CEnums::SessionClosed;
483
484 /* enable/disable snapshot actions */
485 snapshotActionGroup->setEnabled (!busy &&
486 item && mCurSnapshotItem && item != mCurSnapshotItem->firstChild());
487
488 /* enable/disable the details action regardles of the session state */
489 showSnapshotDetailsAction->setEnabled (
490 item && mCurSnapshotItem && item != mCurSnapshotItem->firstChild());
491
492 /* enable/disable current state actions */
493 curStateActionGroup->setEnabled (!busy &&
494 item && mCurSnapshotItem && item == mCurSnapshotItem->firstChild());
495
496 /* the Take Snapshot action is always enabled for the current state */
497 takeSnapshotAction->setEnabled (!busy && curStateActionGroup->isEnabled() ||
498 (item && !mCurSnapshotItem));
499
500 mContextMenuDirty = true;
501}
502
503void VBoxSnapshotsWgt::
504listView_contextMenuRequested (QListViewItem *item, const QPoint &pnt,
505 int /* col */)
506{
507 if (!item)
508 return;
509
510 if (mContextMenuDirty)
511 {
512 mContextMenu->clear();
513
514 if (!mCurSnapshotItem)
515 {
516 /* we have only one item -- current state */
517 curStateActionGroup->addTo (mContextMenu);
518 }
519 else
520 {
521 if (item == mCurSnapshotItem->firstChild())
522 {
523 /* current state is selected */
524 curStateActionGroup->addTo (mContextMenu);
525 }
526 else
527 {
528 /* snapshot is selected */
529 snapshotActionGroup->addTo (mContextMenu);
530 mContextMenu->insertSeparator();
531 showSnapshotDetailsAction->addTo (mContextMenu);
532 }
533 }
534
535 mContextMenuDirty = false;
536 }
537
538 mContextMenu->exec (pnt);
539}
540
541void VBoxSnapshotsWgt::discardSnapshot()
542{
543 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
544 AssertReturn (item, (void) 0);
545
546 QUuid snapId = item->snapshotId();
547 AssertReturn (!snapId.isNull(), (void) 0);
548
549 /* open a direct session (this call will handle all errors) */
550 CSession session = vboxGlobal().openSession (mMachineId);
551 if (session.isNull())
552 return;
553
554 CConsole console = session.GetConsole();
555 CProgress progress = console.DiscardSnapshot (snapId);
556 if (console.isOk())
557 {
558 /* show the progress dialog */
559 vboxProblem().showModalProgressDialog (progress, mMachine.GetName(),
560 vboxProblem().mainWindowShown());
561
562 if (progress.GetResultCode() != 0)
563 vboxProblem().cannotDiscardSnapshot (progress, mMachine.GetSnapshot (snapId));
564 }
565 else
566 vboxProblem().cannotDiscardSnapshot (console, mMachine.GetSnapshot (snapId));
567
568 session.Close();
569}
570
571void VBoxSnapshotsWgt::takeSnapshot()
572{
573 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
574 AssertReturn (item, (void) 0);
575
576 VBoxTakeSnapshotDlg dlg (this, "VBoxTakeSnapshotDlg");
577
578 QString typeId = mMachine.GetOSTypeId();
579 dlg.pmIcon->setPixmap (vboxGlobal().vmGuestOSTypeIcon (typeId));
580
581 dlg.leName->setText (tr ("Snapshot %1").arg (mMachine.GetSnapshotCount() + 1));
582
583 if (dlg.exec() == QDialog::Accepted)
584 {
585 /* open a direct session (this call will handle all errors) */
586 CSession session = vboxGlobal().openSession (mMachineId);
587 if (session.isNull())
588 return;
589
590 CConsole console = session.GetConsole();
591 CProgress progress =
592 console.TakeSnapshot (dlg.leName->text().stripWhiteSpace(),
593 dlg.txeDescription->text());
594 if (console.isOk())
595 {
596 /* show the progress dialog */
597 vboxProblem().showModalProgressDialog (progress, mMachine.GetName(),
598 vboxProblem().mainWindowShown());
599
600 if (progress.GetResultCode() != 0)
601 vboxProblem().cannotTakeSnapshot (progress);
602 }
603 else
604 vboxProblem().cannotTakeSnapshot (console);
605
606 session.Close();
607 }
608}
609
610void VBoxSnapshotsWgt::discardCurState()
611{
612 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
613 AssertReturn (item, (void) 0);
614
615 /* open a direct session (this call will handle all errors) */
616 CSession session = vboxGlobal().openSession (mMachineId);
617 if (session.isNull())
618 return;
619
620 CConsole console = session.GetConsole();
621 CProgress progress = console.DiscardCurrentState();
622 if (console.isOk())
623 {
624 /* show the progress dialog */
625 vboxProblem().showModalProgressDialog (progress, mMachine.GetName(),
626 vboxProblem().mainWindowShown());
627
628 if (progress.GetResultCode() != 0)
629 vboxProblem().cannotDiscardCurrentState (progress);
630 }
631 else
632 vboxProblem().cannotDiscardCurrentState (console);
633
634 session.Close();
635}
636
637void VBoxSnapshotsWgt::discardCurSnapAndState()
638{
639 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
640 AssertReturn (item, (void) 0);
641
642 /* open a direct session (this call will handle all errors) */
643 CSession session = vboxGlobal().openSession (mMachineId);
644 if (session.isNull())
645 return;
646
647 CConsole console = session.GetConsole();
648 CProgress progress = console.DiscardCurrentSnapshotAndState();
649 if (console.isOk())
650 {
651 /* show the progress dialog */
652 vboxProblem().showModalProgressDialog (progress, mMachine.GetName(),
653 vboxProblem().mainWindowShown());
654
655 if (progress.GetResultCode() != 0)
656 vboxProblem().cannotDiscardCurrentSnapshotAndState (progress);
657 }
658 else
659 vboxProblem().cannotDiscardCurrentSnapshotAndState (console);
660
661 session.Close();
662}
663
664void VBoxSnapshotsWgt::showSnapshotDetails()
665{
666 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
667 AssertReturn (item, (void) 0);
668
669 CSnapshot snap = item->snapshot();
670 AssertReturn (!snap.isNull(), (void) 0);
671
672 CMachine snapMachine = snap.GetMachine();
673
674 VBoxSnapshotDetailsDlg dlg (this);
675 dlg.getFromSnapshot (snap);
676
677 if (dlg.exec() == QDialog::Accepted)
678 {
679 dlg.putBackToSnapshot();
680 }
681}
682
683void VBoxSnapshotsWgt::machineDataChanged (const VBoxMachineDataChangeEvent &aE)
684{
685 if (aE.id != mMachineId)
686 return; /* not interested in other machines */
687
688 curStateItem()->recache();
689}
690
691void VBoxSnapshotsWgt::machineStateChanged (const VBoxMachineStateChangeEvent &aE)
692{
693 if (aE.id != mMachineId)
694 return; /* not interested in other machines */
695
696 curStateItem()->recache();
697 curStateItem()->updateCurrentState (aE.state);
698}
699
700void VBoxSnapshotsWgt::sessionStateChanged (const VBoxSessionStateChangeEvent &aE)
701{
702 if (aE.id != mMachineId)
703 return; /* not interested in other machines */
704
705 mSessionState = aE.state;
706 listView_currentChanged (listView->currentItem());
707}
708
709void VBoxSnapshotsWgt::snapshotChanged (const VBoxSnapshotEvent &aE)
710{
711 if (aE.machineId != mMachineId)
712 return; /* not interested in other machines */
713
714 switch (aE.what)
715 {
716 case VBoxSnapshotEvent::Taken:
717 case VBoxSnapshotEvent::Discarded:
718 {
719 refreshAll (true);
720 break;
721 }
722 case VBoxSnapshotEvent::Changed:
723 {
724 ListViewItem *lvi = findItem (aE.snapshotId);
725 if (!lvi)
726 refreshAll();
727 else
728 {
729 lvi->recache();
730 lvi->repaint();
731 }
732 break;
733 }
734 }
735}
736
Note: See TracBrowser for help on using the repository browser.

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