VirtualBox

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

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

FE/Qt: Details/Snapshots tabs are not disabled as a whole any more; inappropriate actions are disabled instead.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.7 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 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
307 /* context menu */
308 mContextMenu = new QPopupMenu (this);
309 mContextMenuDirty = true;
310
311 /* icons */
312 discardSnapshotAction->setIconSet (VBoxGlobal::iconSetEx (
313 "discard_snapshot_22px.png", "discard_snapshot_16px.png",
314 "discard_snapshot_dis_22px.png", "discard_snapshot_dis_16px.png"));
315 takeSnapshotAction->setIconSet (VBoxGlobal::iconSetEx (
316 "take_snapshot_22px.png", "take_snapshot_16px.png",
317 "take_snapshot_dis_22px.png", "take_snapshot_dis_16px.png"));
318 discardCurStateAction->setIconSet (VBoxGlobal::iconSetEx (
319 "discard_cur_state_22px.png", "discard_cur_state_16px.png",
320 "discard_cur_state_dis_22px.png", "discard_cur_state_dis_16px.png"));
321 discardCurSnapAndStateAction->setIconSet (VBoxGlobal::iconSetEx (
322 "discard_cur_state_snapshot_22px.png", "discard_cur_state_snapshot_16px.png",
323 "discard_cur_state_snapshot_dis_22px.png", "discard_cur_state_snapshot_dis_16px.png"));
324 showSnapshotDetailsAction->setIconSet (VBoxGlobal::iconSetEx (
325 "show_snapshot_details_22px.png", "show_snapshot_details_16px.png",
326 "show_snapshot_details_dis_22px.png", "show_snapshot_details_dis_16px.png"));
327
328 /* tooltip */
329 mToolTip = new ToolTip (listView, listView->viewport());
330}
331
332void VBoxSnapshotsWgt::destroy()
333{
334 delete mToolTip;
335}
336
337void VBoxSnapshotsWgt::setMachine (const CMachine &aMachine)
338{
339 mMachine = aMachine;
340
341 if (aMachine.isNull())
342 {
343 mMachineId = QUuid();
344 mSessionState = CEnums::InvalidSessionState;
345 }
346 else
347 {
348 mMachineId = aMachine.GetId();
349 mSessionState = aMachine.GetSessionState();
350 }
351
352 refreshAll();
353}
354
355VBoxSnapshotsWgt::ListViewItem *VBoxSnapshotsWgt::findItem (const QUuid &aSnapshotId)
356{
357 QListViewItemIterator it (listView);
358 while (it.current())
359 {
360 ListViewItem *lvi = static_cast <ListViewItem *> (it.current());
361 if (lvi->snapshotId() == aSnapshotId)
362 return lvi;
363 ++ it;
364 }
365
366 return 0;
367}
368
369void VBoxSnapshotsWgt::refreshAll (bool aKeepSelected /* = false */)
370{
371 QUuid selected, selectedFirstChild;
372 if (aKeepSelected)
373 {
374 ListViewItem *cur = static_cast <ListViewItem *> (listView->selectedItem());
375 Assert (cur);
376 if (cur)
377 {
378 selected = cur->snapshotId();
379 if (cur->firstChild())
380 selectedFirstChild =
381 static_cast <ListViewItem *> (cur->firstChild())->snapshotId();
382 }
383 }
384
385 listView->clear();
386
387 if (mMachine.isNull())
388 {
389 listView_currentChanged (NULL);
390 return;
391 }
392
393 /* get the first snapshot */
394 if (mMachine.GetSnapshotCount() > 0)
395 {
396 CSnapshot snapshot = mMachine.GetSnapshot (QUuid());
397
398 populateSnapshots (snapshot, 0);
399 Assert (mCurSnapshotItem);
400
401 /* add the "current state" item */
402 new ListViewItem (mCurSnapshotItem, mMachine);
403
404 ListViewItem *cur = 0;
405 if (aKeepSelected)
406 {
407 cur = findItem (selected);
408 if (cur == 0)
409 cur = findItem (selectedFirstChild);
410 }
411 if (cur == 0)
412 cur = curStateItem();
413 listView->setSelected (cur, true);
414 listView->ensureItemVisible (cur);
415 }
416 else
417 {
418 mCurSnapshotItem = NULL;
419
420 /* add the "current state" item */
421 ListViewItem *csi = new ListViewItem (listView, mMachine);
422
423 listView->setSelected (csi, true);
424 /*
425 * stupid Qt doesn't issue this signal when only one item is added
426 * to the empty list -- do it manually
427 */
428 listView_currentChanged (csi);
429 }
430
431 listView->adjustColumn (0);
432}
433
434VBoxSnapshotsWgt::ListViewItem *VBoxSnapshotsWgt::curStateItem()
435{
436 QListViewItem *csi = mCurSnapshotItem ? mCurSnapshotItem->firstChild()
437 : listView->firstChild();
438 Assert (csi);
439 return static_cast <ListViewItem *> (csi);
440}
441
442void VBoxSnapshotsWgt::populateSnapshots (const CSnapshot &snapshot, QListViewItem *item)
443{
444
445 ListViewItem *si = 0;
446 if (item)
447 si = new ListViewItem (item, snapshot);
448 else
449 si = new ListViewItem (listView, snapshot);
450
451 if (mMachine.GetCurrentSnapshot().GetId() == snapshot.GetId())
452 {
453 si->setBold (true);
454 mCurSnapshotItem = si;
455 }
456
457 CSnapshotEnumerator en = snapshot.GetChildren().Enumerate();
458 while (en.HasMore())
459 {
460 CSnapshot sn = en.GetNext();
461 populateSnapshots (sn, si);
462 }
463
464 si->setOpen (true);
465 si->setRenameEnabled (0, true);
466}
467
468void VBoxSnapshotsWgt::listView_currentChanged (QListViewItem *item)
469{
470 if (item)
471 listView->ensureItemVisible (item);
472
473 /* whether another direct session is open or not */
474 bool busy = mSessionState != CEnums::SessionClosed;
475
476 /* enable/disable snapshot actions */
477 snapshotActionGroup->setEnabled (!busy &&
478 item && mCurSnapshotItem && item != mCurSnapshotItem->firstChild());
479
480 /* enable/disable the details action regardles of the session state */
481 showSnapshotDetailsAction->setEnabled (
482 item && mCurSnapshotItem && item != mCurSnapshotItem->firstChild());
483
484 /* enable/disable current state actions */
485 curStateActionGroup->setEnabled (!busy &&
486 item && mCurSnapshotItem && item == mCurSnapshotItem->firstChild());
487
488 /* the Take Snapshot action is always enabled for the current state */
489 takeSnapshotAction->setEnabled (!busy && curStateActionGroup->isEnabled() ||
490 (item && !mCurSnapshotItem));
491
492 mContextMenuDirty = true;
493}
494
495void VBoxSnapshotsWgt::
496listView_contextMenuRequested (QListViewItem *item, const QPoint &pnt,
497 int /* col */)
498{
499 if (!item)
500 return;
501
502 if (mContextMenuDirty)
503 {
504 mContextMenu->clear();
505
506 if (!mCurSnapshotItem)
507 {
508 /* we have only one item -- current state */
509 curStateActionGroup->addTo (mContextMenu);
510 }
511 else
512 {
513 if (item == mCurSnapshotItem->firstChild())
514 {
515 /* current state is selected */
516 curStateActionGroup->addTo (mContextMenu);
517 }
518 else
519 {
520 /* snapshot is selected */
521 snapshotActionGroup->addTo (mContextMenu);
522 mContextMenu->insertSeparator();
523 showSnapshotDetailsAction->addTo (mContextMenu);
524 }
525 }
526
527 mContextMenuDirty = false;
528 }
529
530 mContextMenu->exec (pnt);
531}
532
533void VBoxSnapshotsWgt::discardSnapshot()
534{
535 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
536 AssertReturn (item, (void) 0);
537
538 QUuid snapId = item->snapshotId();
539 AssertReturn (!snapId.isNull(), (void) 0);
540
541 /* open a direct session (this call will handle all errors) */
542 CSession session = vboxGlobal().openSession (mMachineId);
543 if (session.isNull())
544 return;
545
546 CConsole console = session.GetConsole();
547 CProgress progress = console.DiscardSnapshot (snapId);
548 if (console.isOk())
549 {
550 /* show the progress dialog */
551 vboxProblem().showModalProgressDialog (progress, mMachine.GetName(),
552 vboxProblem().mainWindowShown());
553
554 if (progress.GetResultCode() != 0)
555 vboxProblem().cannotDiscardSnapshot (progress, mMachine.GetSnapshot (snapId));
556 }
557 else
558 vboxProblem().cannotDiscardSnapshot (console, mMachine.GetSnapshot (snapId));
559
560 session.Close();
561}
562
563void VBoxSnapshotsWgt::takeSnapshot()
564{
565 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
566 AssertReturn (item, (void) 0);
567
568 VBoxTakeSnapshotDlg dlg (this, "VBoxTakeSnapshotDlg");
569
570 QString osType = mMachine.GetOSType().GetId();
571 dlg.pmIcon->setPixmap (vboxGlobal().vmGuestOSTypeIcon (osType));
572
573 dlg.leName->setText (tr ("Snapshot %1").arg (mMachine.GetSnapshotCount() + 1));
574
575 if (dlg.exec() == QDialog::Accepted)
576 {
577 /* open a direct session (this call will handle all errors) */
578 CSession session = vboxGlobal().openSession (mMachineId);
579 if (session.isNull())
580 return;
581
582 CConsole console = session.GetConsole();
583 CProgress progress =
584 console.TakeSnapshot (dlg.leName->text().stripWhiteSpace(),
585 dlg.txeDescription->text());
586 if (console.isOk())
587 {
588 /* show the progress dialog */
589 vboxProblem().showModalProgressDialog (progress, mMachine.GetName(),
590 vboxProblem().mainWindowShown());
591
592 if (progress.GetResultCode() != 0)
593 vboxProblem().cannotTakeSnapshot (progress);
594 }
595 else
596 vboxProblem().cannotTakeSnapshot (console);
597
598 session.Close();
599 }
600}
601
602void VBoxSnapshotsWgt::discardCurState()
603{
604 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
605 AssertReturn (item, (void) 0);
606
607 /* open a direct session (this call will handle all errors) */
608 CSession session = vboxGlobal().openSession (mMachineId);
609 if (session.isNull())
610 return;
611
612 CConsole console = session.GetConsole();
613 CProgress progress = console.DiscardCurrentState();
614 if (console.isOk())
615 {
616 /* show the progress dialog */
617 vboxProblem().showModalProgressDialog (progress, mMachine.GetName(),
618 vboxProblem().mainWindowShown());
619
620 if (progress.GetResultCode() != 0)
621 vboxProblem().cannotDiscardCurrentState (progress);
622 }
623 else
624 vboxProblem().cannotDiscardCurrentState (console);
625
626 session.Close();
627}
628
629void VBoxSnapshotsWgt::discardCurSnapAndState()
630{
631 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
632 AssertReturn (item, (void) 0);
633
634 /* open a direct session (this call will handle all errors) */
635 CSession session = vboxGlobal().openSession (mMachineId);
636 if (session.isNull())
637 return;
638
639 CConsole console = session.GetConsole();
640 CProgress progress = console.DiscardCurrentSnapshotAndState();
641 if (console.isOk())
642 {
643 /* show the progress dialog */
644 vboxProblem().showModalProgressDialog (progress, mMachine.GetName(),
645 vboxProblem().mainWindowShown());
646
647 if (progress.GetResultCode() != 0)
648 vboxProblem().cannotDiscardCurrentSnapshotAndState (progress);
649 }
650 else
651 vboxProblem().cannotDiscardCurrentSnapshotAndState (console);
652
653 session.Close();
654}
655
656void VBoxSnapshotsWgt::showSnapshotDetails()
657{
658 ListViewItem *item = static_cast <ListViewItem *> (listView->currentItem());
659 AssertReturn (item, (void) 0);
660
661 CSnapshot snap = item->snapshot();
662 AssertReturn (!snap.isNull(), (void) 0);
663
664 CMachine snapMachine = snap.GetMachine();
665
666 VBoxSnapshotDetailsDlg dlg (this);
667 dlg.getFromSnapshot (snap);
668
669 if (dlg.exec() == QDialog::Accepted)
670 {
671 dlg.putBackToSnapshot();
672 }
673}
674
675void VBoxSnapshotsWgt::machineDataChanged (const VBoxMachineDataChangeEvent &aE)
676{
677 if (aE.id != mMachineId)
678 return; /* not interested in other machines */
679
680 curStateItem()->recache();
681}
682
683void VBoxSnapshotsWgt::machineStateChanged (const VBoxMachineStateChangeEvent &aE)
684{
685 if (aE.id != mMachineId)
686 return; /* not interested in other machines */
687
688 curStateItem()->recache();
689 curStateItem()->updateCurrentState (aE.state);
690}
691
692void VBoxSnapshotsWgt::sessionStateChanged (const VBoxSessionStateChangeEvent &aE)
693{
694 if (aE.id != mMachineId)
695 return; /* not interested in other machines */
696
697 mSessionState = aE.state;
698 listView_currentChanged (listView->currentItem());
699}
700
701void VBoxSnapshotsWgt::snapshotChanged (const VBoxSnapshotEvent &aE)
702{
703 if (aE.machineId != mMachineId)
704 return; /* not interested in other machines */
705
706 switch (aE.what)
707 {
708 case VBoxSnapshotEvent::Taken:
709 case VBoxSnapshotEvent::Discarded:
710 {
711 refreshAll (true);
712 break;
713 }
714 case VBoxSnapshotEvent::Changed:
715 {
716 ListViewItem *lvi = findItem (aE.snapshotId);
717 if (!lvi)
718 refreshAll();
719 else
720 {
721 lvi->recache();
722 lvi->repaint();
723 }
724 break;
725 }
726 }
727}
728
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