VirtualBox

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

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

export to OSE again

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.9 KB
Line 
1/**
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * Snapshot details dialog (Qt Designer)
5 */
6
7/*
8 * Copyright (C) 2006 InnoTek Systemberatung GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. 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 void recache()
120 {
121 if (!mSnapshot.isNull())
122 {
123 mId = mSnapshot.GetId();
124 setText (0, mSnapshot.GetName());
125 mOnline = mSnapshot.GetOnline();
126 setPixmap (0, vboxGlobal().snapshotIcon (mOnline));
127 mDesc = mSnapshot.GetDescription();
128 mTimestamp.setTime_t (mSnapshot.GetTimeStamp() / 1000);
129 mCurStateModified = false;
130 }
131 else
132 {
133 Assert (!mMachine.isNull());
134 mCurStateModified = mMachine.GetCurrentStateModified();
135 setText (0, mCurStateModified ?
136 VBoxSnapshotsWgt::tr ("Current State (changed)",
137 "Current State (Modified)") :
138 VBoxSnapshotsWgt::tr ("Current State",
139 "Current State (Unmodified)"));
140 mDesc = mCurStateModified ?
141 VBoxSnapshotsWgt::tr ("The current state differs from the state "
142 "stored in the current snapshot") :
143 parent() != 0 ? /* we're not the only item in the view */
144 VBoxSnapshotsWgt::tr ("The current state is identical to the state "
145 "stored in the current snapshot") :
146 QString::null;
147 }
148 }
149
150 void updateCurrentState (CEnums::MachineState aState)
151 {
152 AssertReturn (!mMachine.isNull(), (void) 0);
153 setPixmap (0, vboxGlobal().toIcon (aState));
154 mMachineState = aState;
155 mTimestamp.setTime_t (mMachine.GetLastStateChange() / 1000);
156 }
157
158 QString toolTipText() const
159 {
160 QString name = !mSnapshot.isNull() ?
161 text (0) : text (0);
162
163 bool dateTimeToday = mTimestamp.date() == QDate::currentDate();
164 QString dateTime = dateTimeToday ?
165 mTimestamp.time().toString (Qt::LocalDate) :
166 mTimestamp.toString (Qt::LocalDate);
167
168 QString details;
169 if (!mSnapshot.isNull())
170 {
171 /* the current snapshot is always bold */
172 if (mBld)
173 details = VBoxSnapshotsWgt::tr (" (current, ", "Snapshot details");
174 else
175 details = " (";
176 details += mOnline ? VBoxSnapshotsWgt::tr ("online)", "Snapshot details")
177 : VBoxSnapshotsWgt::tr ("offline)", "Snapshot details");
178
179 if (dateTimeToday)
180 dateTime = VBoxSnapshotsWgt::tr ("Taken at %1", "Snapshot (time)")
181 .arg (dateTime);
182 else
183 dateTime = VBoxSnapshotsWgt::tr ("Taken on %1", "Snapshot (date + time)")
184 .arg (dateTime);
185 }
186 else
187 {
188 dateTime = VBoxSnapshotsWgt::tr ("%1 since %2", "Current State (time or date + time)")
189 .arg (vboxGlobal().toString (mMachineState))
190 .arg (dateTime);
191 }
192
193 QString toolTip = QString ("<nobr><b>%1</b>%2</nobr><br><nobr>%3</nobr>")
194 .arg (name) .arg (details)
195 .arg (dateTime);
196
197 if (!mDesc.isEmpty())
198 toolTip += "<br><hr>" + mDesc;
199
200 return toolTip;
201 }
202
203 void okRename (int aCol)
204 {
205 QListViewItem::okRename (aCol);
206 AssertReturn (aCol == 0 && !mSnapshot.isNull(), (void) 0);
207 mSnapshot.SetName (text (0));
208 }
209
210private:
211
212 bool mBld : 1;
213 bool mItal : 1;
214
215 CSnapshot mSnapshot;
216 CMachine mMachine;
217
218 QUuid mId;
219 bool mOnline;
220 QString mDesc;
221 QDateTime mTimestamp;
222
223 bool mCurStateModified;
224 CEnums::MachineState mMachineState;
225};
226
227////////////////////////////////////////////////////////////////////////////////
228
229/** Tooltips for snapshots */
230class VBoxSnapshotsWgt::ToolTip : public QToolTip
231{
232public:
233
234 ToolTip (QListView *aLV, QWidget *aParent, QToolTipGroup *aTG = 0)
235 : QToolTip (aParent, aTG), mLV (aLV)
236 {}
237
238 virtual ~ToolTip()
239 {
240 remove (parentWidget());
241 }
242
243 void maybeTip (const QPoint &aPnt);
244
245private:
246
247 QListView *mLV;
248};
249
250void VBoxSnapshotsWgt::ToolTip::maybeTip (const QPoint &aPnt)
251{
252 ListViewItem *lvi = static_cast <ListViewItem *> (mLV->itemAt (aPnt));
253 if (!lvi)
254 return;
255
256 if (parentWidget()->topLevelWidget()->inherits ("QMainWindow"))
257 {
258 /*
259 * Ensure the main window doesn't show the text from the previous
260 * tooltip in the status bar.
261 */
262 QToolTipGroup *toolTipGroup =
263 (::qt_cast <QMainWindow *> (parentWidget()->topLevelWidget()))->
264 toolTipGroup();
265 if (toolTipGroup)
266 {
267 int index = toolTipGroup->metaObject()->findSignal("removeTip()", false);
268 toolTipGroup->qt_emit (index, 0);
269 }
270 }
271
272 tip (mLV->itemRect (lvi), lvi->toolTipText());
273}
274
275////////////////////////////////////////////////////////////////////////////////
276
277void VBoxSnapshotsWgt::init()
278{
279 mCurSnapshotItem = 0;
280
281 listView->setItemMargin (2);
282 listView->header()->hide();
283 listView->setRootIsDecorated (true);
284 /* we have our own tooltips */
285 listView->setShowToolTips (false);
286 /* disable sorting */
287 listView->setSorting (-1);
288 /* disable unselecting items by clicking in the unused area of the list */
289 new QIListViewSelectionPreserver (this, listView);
290
291 /* toolbar */
292 VBoxToolBar *toolBar = new VBoxToolBar (0, this, "snapshotToolBar");
293
294 curStateActionGroup->addTo (toolBar);
295 toolBar->addSeparator();
296 snapshotActionGroup->addTo (toolBar);
297 toolBar->addSeparator();
298 showSnapshotDetailsAction->addTo (toolBar);
299
300 toolBar->setUsesTextLabel (false);
301 toolBar->setUsesBigPixmaps (true);
302 toolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
303 VBoxSnapshotsWgtLayout->insertWidget (0, toolBar);
304
305 /* context menu */
306 mContextMenu = new QPopupMenu (this);
307 mContextMenuDirty = true;
308
309 /* icons */
310 discardSnapshotAction->setIconSet (VBoxGlobal::iconSetEx (
311 "discard_snapshot_22px.png", "discard_snapshot_16px.png",
312 "discard_snapshot_dis_22px.png", "discard_snapshot_dis_16px.png"));
313 takeSnapshotAction->setIconSet (VBoxGlobal::iconSetEx (
314 "take_snapshot_22px.png", "take_snapshot_16px.png",
315 "take_snapshot_dis_22px.png", "take_snapshot_dis_16px.png"));
316 discardCurStateAction->setIconSet (VBoxGlobal::iconSetEx (
317 "discard_cur_state_22px.png", "discard_cur_state_16px.png",
318 "discard_cur_state_dis_22px.png", "discard_cur_state_dis_16px.png"));
319 discardCurSnapAndStateAction->setIconSet (VBoxGlobal::iconSetEx (
320 "discard_cur_state_snapshot_22px.png", "discard_cur_state_snapshot_16px.png",
321 "discard_cur_state_snapshot_dis_22px.png", "discard_cur_state_snapshot_dis_16px.png"));
322 showSnapshotDetailsAction->setIconSet (VBoxGlobal::iconSetEx (
323 "show_snapshot_details_22px.png", "show_snapshot_details_16px.png",
324 "show_snapshot_details_dis_22px.png", "show_snapshot_details_dis_16px.png"));
325
326 /* tooltip */
327 mToolTip = new ToolTip (listView, listView->viewport());
328}
329
330void VBoxSnapshotsWgt::destroy()
331{
332 delete mToolTip;
333}
334
335void VBoxSnapshotsWgt::setMachine (const CMachine &aMachine)
336{
337 mMachine = aMachine;
338 mMachineId = aMachine.isNull() ? QUuid() : aMachine.GetId();
339 refreshAll();
340}
341
342VBoxSnapshotsWgt::ListViewItem *VBoxSnapshotsWgt::findItem (const QUuid &aSnapshotId)
343{
344 QListViewItemIterator it (listView);
345 while (it.current())
346 {
347 ListViewItem *lvi = static_cast <ListViewItem *> (it.current());
348 if (lvi->snapshotId() == aSnapshotId)
349 return lvi;
350 ++ it;
351 }
352
353 return 0;
354}
355
356void VBoxSnapshotsWgt::refreshAll (bool aKeepSelected /* = false */)
357{
358 QUuid selected, selectedFirstChild;
359 if (aKeepSelected)
360 {
361 ListViewItem *cur = static_cast <ListViewItem *> (listView->selectedItem());
362 Assert (cur);
363 if (cur)
364 {
365 selected = cur->snapshotId();
366 if (cur->firstChild())
367 selectedFirstChild =
368 static_cast <ListViewItem *> (cur->firstChild())->snapshotId();
369 }
370 }
371
372 listView->clear();
373
374 if (mMachine.isNull())
375 {
376 listView_currentChanged (NULL);
377 return;
378 }
379
380 /* get the first snapshot */
381 if (mMachine.GetSnapshotCount() > 0)
382 {
383 CSnapshot snapshot = mMachine.GetSnapshot (QUuid());
384
385 populateSnapshots (snapshot, 0);
386 Assert (mCurSnapshotItem);
387
388 /* add the "current state" item */
389 new ListViewItem (mCurSnapshotItem, mMachine);
390
391 ListViewItem *cur = 0;
392 if (aKeepSelected)
393 {
394 cur = findItem (selected);
395 if (cur == 0)
396 cur = findItem (selectedFirstChild);
397 }
398 if (cur == 0)
399 cur = curStateItem();
400 listView->setSelected (cur, true);
401 listView->ensureItemVisible (cur);
402 }
403 else
404 {
405 mCurSnapshotItem = NULL;
406
407 /* add the "current state" item */
408 ListViewItem *csi = new ListViewItem (listView, mMachine);
409
410 listView->setSelected (csi, true);
411 /*
412 * stupid Qt doesn't issue this signal when only one item is added
413 * to the empty list -- do it manually
414 */
415 listView_currentChanged (csi);
416 }
417
418 listView->adjustColumn (0);
419}
420
421VBoxSnapshotsWgt::ListViewItem *VBoxSnapshotsWgt::curStateItem()
422{
423 QListViewItem *csi = mCurSnapshotItem ? mCurSnapshotItem->firstChild()
424 : listView->firstChild();
425 Assert (csi);
426 return static_cast <ListViewItem *> (csi);
427}
428
429void VBoxSnapshotsWgt::populateSnapshots (const CSnapshot &snapshot, QListViewItem *item)
430{
431
432 ListViewItem *si = 0;
433 if (item)
434 si = new ListViewItem (item, snapshot);
435 else
436 si = new ListViewItem (listView, snapshot);
437
438 if (mMachine.GetCurrentSnapshot().GetId() == snapshot.GetId())
439 {
440 si->setBold (true);
441 mCurSnapshotItem = si;
442 }
443
444 CSnapshotEnumerator en = snapshot.GetChildren().Enumerate();
445 while (en.HasMore())
446 {
447 CSnapshot sn = en.GetNext();
448 populateSnapshots (sn, si);
449 }
450
451 si->setOpen (true);
452 si->setRenameEnabled (0, true);
453}
454
455void VBoxSnapshotsWgt::listView_currentChanged (QListViewItem *item)
456{
457 if (item)
458 listView->ensureItemVisible (item);
459
460 /* enable/disable snapshot actions */
461 snapshotActionGroup->setEnabled (
462 item && mCurSnapshotItem && item != mCurSnapshotItem->firstChild());
463
464 showSnapshotDetailsAction->setEnabled (snapshotActionGroup->isEnabled());
465
466 /* enable/disable current state actions */
467 curStateActionGroup->setEnabled (
468 item && mCurSnapshotItem && item == mCurSnapshotItem->firstChild());
469
470 /* the Take Snapshot action is always enabled for the current state */
471 takeSnapshotAction->setEnabled (curStateActionGroup->isEnabled() ||
472 (item && !mCurSnapshotItem));
473
474 mContextMenuDirty = true;
475}
476
477void VBoxSnapshotsWgt::
478listView_contextMenuRequested (QListViewItem *item, const QPoint &pnt,
479 int /* col */)
480{
481 if (!item)
482 return;
483
484 if (mContextMenuDirty)
485 {
486 mContextMenu->clear();
487
488 if (!mCurSnapshotItem)
489 {
490 /* we have only one item -- current state */
491 takeSnapshotAction->addTo (mContextMenu);
492 }
493 else
494 {
495 if (item == mCurSnapshotItem->firstChild())
496 {
497 /* current state is selected */
498 curStateActionGroup->addTo (mContextMenu);
499 }
500 else
501 {
502 /* snapshot is selected */
503 snapshotActionGroup->addTo (mContextMenu);
504 mContextMenu->insertSeparator();
505 showSnapshotDetailsAction->addTo (mContextMenu);
506 }
507 }
508
509 mContextMenuDirty = false;
510 }
511
512 mContextMenu->exec (pnt);
513}
514
515void VBoxSnapshotsWgt::discardSnapshot()
516{
517 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
518 AssertReturn (item, (void) 0);
519
520 QUuid snapId = item->snapshotId();
521 AssertReturn (!snapId.isNull(), (void) 0);
522
523 /* open a direct session (this call will handle all errors) */
524 CSession session = vboxGlobal().openSession (mMachineId);
525 if (session.isNull())
526 return;
527
528 CConsole console = session.GetConsole();
529 CProgress progress = console.DiscardSnapshot (snapId);
530 if (console.isOk())
531 {
532 /* show the progress dialog */
533 vboxProblem().showModalProgressDialog (progress, mMachine.GetName(),
534 vboxProblem().mainWindowShown());
535
536 if (progress.GetResultCode() != 0)
537 vboxProblem().cannotDiscardSnapshot (progress, mMachine.GetSnapshot (snapId));
538 }
539 else
540 vboxProblem().cannotDiscardSnapshot (console, mMachine.GetSnapshot (snapId));
541
542 session.Close();
543}
544
545void VBoxSnapshotsWgt::takeSnapshot()
546{
547 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
548 AssertReturn (item, (void) 0);
549
550 VBoxTakeSnapshotDlg dlg (this, "VBoxTakeSnapshotDlg");
551
552 QString osType = mMachine.GetOSType().GetId();
553 dlg.pmIcon->setPixmap (vboxGlobal().vmGuestOSTypeIcon (osType));
554
555 dlg.leName->setText (tr ("Snapshot %1").arg (mMachine.GetSnapshotCount() + 1));
556
557 if (dlg.exec() == QDialog::Accepted)
558 {
559 /* open a direct session (this call will handle all errors) */
560 CSession session = vboxGlobal().openSession (mMachineId);
561 if (session.isNull())
562 return;
563
564 CConsole console = session.GetConsole();
565 CProgress progress =
566 console.TakeSnapshot (dlg.leName->text().stripWhiteSpace(),
567 dlg.txeDescription->text());
568 if (console.isOk())
569 {
570 /* show the progress dialog */
571 vboxProblem().showModalProgressDialog (progress, mMachine.GetName(),
572 vboxProblem().mainWindowShown());
573
574 if (progress.GetResultCode() != 0)
575 vboxProblem().cannotTakeSnapshot (progress);
576 }
577 else
578 vboxProblem().cannotTakeSnapshot (console);
579
580 session.Close();
581 }
582}
583
584void VBoxSnapshotsWgt::discardCurState()
585{
586 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
587 AssertReturn (item, (void) 0);
588
589 /* open a direct session (this call will handle all errors) */
590 CSession session = vboxGlobal().openSession (mMachineId);
591 if (session.isNull())
592 return;
593
594 CConsole console = session.GetConsole();
595 CProgress progress = console.DiscardCurrentState();
596 if (console.isOk())
597 {
598 /* show the progress dialog */
599 vboxProblem().showModalProgressDialog (progress, mMachine.GetName(),
600 vboxProblem().mainWindowShown());
601
602 if (progress.GetResultCode() != 0)
603 vboxProblem().cannotDiscardCurrentState (progress);
604 }
605 else
606 vboxProblem().cannotDiscardCurrentState (console);
607
608 session.Close();
609}
610
611void VBoxSnapshotsWgt::discardCurSnapAndState()
612{
613 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
614 AssertReturn (item, (void) 0);
615
616 /* open a direct session (this call will handle all errors) */
617 CSession session = vboxGlobal().openSession (mMachineId);
618 if (session.isNull())
619 return;
620
621 CConsole console = session.GetConsole();
622 CProgress progress = console.DiscardCurrentSnapshotAndState();
623 if (console.isOk())
624 {
625 /* show the progress dialog */
626 vboxProblem().showModalProgressDialog (progress, mMachine.GetName(),
627 vboxProblem().mainWindowShown());
628
629 if (progress.GetResultCode() != 0)
630 vboxProblem().cannotDiscardCurrentSnapshotAndState (progress);
631 }
632 else
633 vboxProblem().cannotDiscardCurrentSnapshotAndState (console);
634
635 session.Close();
636}
637
638void VBoxSnapshotsWgt::showSnapshotDetails()
639{
640 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
641 AssertReturn (item, (void) 0);
642
643 CSnapshot snap = item->snapshot();
644 AssertReturn (!snap.isNull(), (void) 0);
645
646 CMachine snapMachine = snap.GetMachine();
647
648 VBoxSnapshotDetailsDlg dlg (this);
649 dlg.getFromSnapshot (snap);
650
651 if (dlg.exec() == QDialog::Accepted)
652 {
653 dlg.putBackToSnapshot();
654 }
655}
656
657void VBoxSnapshotsWgt::machineDataChanged (const VBoxMachineDataChangeEvent &aE)
658{
659 if (aE.id != mMachineId)
660 return; /* not interested in other machines */
661
662 curStateItem()->recache();
663}
664
665void VBoxSnapshotsWgt::machineStateChanged (const VBoxMachineStateChangeEvent &aE)
666{
667 if (aE.id != mMachineId)
668 return; /* not interested in other machines */
669
670 curStateItem()->recache();
671 curStateItem()->updateCurrentState (aE.state);
672}
673
674void VBoxSnapshotsWgt::snapshotChanged (const VBoxSnapshotEvent &aE)
675{
676 if (aE.machineId != mMachineId)
677 return; /* not interested in other machines */
678
679 switch (aE.what)
680 {
681 case VBoxSnapshotEvent::Taken:
682 case VBoxSnapshotEvent::Discarded:
683 {
684 refreshAll (true);
685 break;
686 }
687 case VBoxSnapshotEvent::Changed:
688 {
689 ListViewItem *lvi = findItem (aE.snapshotId);
690 if (!lvi)
691 refreshAll();
692 else
693 {
694 lvi->recache();
695 lvi->repaint();
696 }
697 break;
698 }
699 }
700}
701
Note: See TracBrowser for help on using the repository browser.

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