VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/VBoxSnapshotDetailsDlg.cpp@ 67144

Last change on this file since 67144 was 67144, checked in by vboxsync, 8 years ago

FE/Qt: Selector UI: Tools pane: Snapshot pane: Moving screenshot viewer code into corresponding place.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 12.8 KB
Line 
1/* $Id: VBoxSnapshotDetailsDlg.cpp 67144 2017-05-30 14:47:41Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - VBoxSnapshotDetailsDlg class implementation.
4 */
5
6/*
7 * Copyright (C) 2008-2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifdef VBOX_WITH_PRECOMPILED_HEADERS
19# include <precomp.h>
20#else /* !VBOX_WITH_PRECOMPILED_HEADERS */
21
22/* Qt includes: */
23# include <QDateTime>
24# include <QPushButton>
25# include <QScrollArea>
26
27/* GUI includes: */
28# include "VBoxGlobal.h"
29# include "UIMessageCenter.h"
30# include "VBoxSnapshotDetailsDlg.h"
31# include "VBoxUtils.h"
32
33/* COM includes: */
34# include "CMachine.h"
35
36#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
37
38
39/** QWiget extension providing GUI with snapshot screenshot viewer widget. */
40class UIScreenshotViewer : public QIWithRetranslateUI2<QWidget>
41{
42 Q_OBJECT;
43
44public:
45
46 /** Constructs screenshow viewer passing @a pParent to the base-class.
47 * @param pixmapScreenshot Brings the screenshot to show.
48 * @param strSnapshotName Brings the snapshot name.
49 * @param strMachineName Brings the machine name. */
50 UIScreenshotViewer(const QPixmap &pixmapScreenshot,
51 const QString &strSnapshotName,
52 const QString &strMachineName,
53 QWidget *pParent = 0);
54
55protected:
56
57 /** Handles translation event. */
58 virtual void retranslateUi() /* override */;
59
60 /** Handles show @a pEvent. */
61 virtual void showEvent(QShowEvent *pEvent) /* override */;
62 /** Handles polish @a pEvent. */
63 virtual void polishEvent(QShowEvent *pEvent);
64
65 /** Handles resize @a pEvent. */
66 virtual void resizeEvent(QResizeEvent *pEvent) /* override */;
67
68 /** Handles mouse press @a pEvent. */
69 virtual void mousePressEvent(QMouseEvent *pEvent) /* override */;
70 /** Handles key press @a pEvent. */
71 virtual void keyPressEvent(QKeyEvent *pEvent) /* override */;
72
73private:
74
75 /** Prepares all. */
76 void prepare();
77
78 /** Adjusts picture. */
79 void adjustPicture();
80
81 /** Holds whether this widget was polished. */
82 bool m_fPolished;
83
84 /** Holds the screenshot to show. */
85 QPixmap m_pixmapScreenshot;
86 /** Holds the snapshot name. */
87 QString m_strSnapshotName;
88 /** Holds the machine name. */
89 QString m_strMachineName;
90
91 /** Holds the scroll-area instance. */
92 QScrollArea *m_pScrollArea;
93 /** Holds the picture label instance. */
94 QLabel *m_pLabelPicture;
95
96 /** Holds whether we are in zoom mode. */
97 bool m_fZoomMode;
98};
99
100
101/*********************************************************************************************************************************
102* Class UIScreenshotViewer implementation. *
103*********************************************************************************************************************************/
104
105UIScreenshotViewer::UIScreenshotViewer(const QPixmap &pixmapScreenshot,
106 const QString &strSnapshotName,
107 const QString &strMachineName,
108 QWidget *pParent /* = 0 */)
109 : QIWithRetranslateUI2<QWidget>(pParent, Qt::Tool)
110 , m_fPolished(false)
111 , m_pixmapScreenshot(pixmapScreenshot)
112 , m_strSnapshotName(strSnapshotName)
113 , m_strMachineName(strMachineName)
114 , m_pScrollArea(0)
115 , m_pLabelPicture(0)
116 , m_fZoomMode(true)
117{
118 /* Prepare: */
119 prepare();
120}
121
122void UIScreenshotViewer::retranslateUi()
123{
124 /* Translate window title: */
125 setWindowTitle(tr("Screenshot of %1 (%2)").arg(m_strSnapshotName).arg(m_strMachineName));
126}
127
128void UIScreenshotViewer::showEvent(QShowEvent *pEvent)
129{
130 /* Call to base-class: */
131 QIWithRetranslateUI2<QWidget>::showEvent(pEvent);
132
133 /* Make sure we should polish dialog: */
134 if (m_fPolished)
135 return;
136
137 /* Call to polish-event: */
138 polishEvent(pEvent);
139
140 /* Mark dialog as polished: */
141 m_fPolished = true;
142}
143
144void UIScreenshotViewer::polishEvent(QShowEvent * /* pEvent */)
145{
146 /* Adjust the picture: */
147 adjustPicture();
148}
149
150void UIScreenshotViewer::resizeEvent(QResizeEvent *pEvent)
151{
152 /* Call to base-class: */
153 QIWithRetranslateUI2<QWidget>::resizeEvent(pEvent);
154
155 /* Adjust the picture: */
156 adjustPicture();
157}
158
159void UIScreenshotViewer::mousePressEvent(QMouseEvent *pEvent)
160{
161 /* Toggle the zoom mode: */
162 m_fZoomMode = !m_fZoomMode;
163
164 /* Adjust the picture: */
165 adjustPicture();
166
167 /* Call to base-class: */
168 QIWithRetranslateUI2<QWidget>::mousePressEvent(pEvent);
169}
170
171void UIScreenshotViewer::keyPressEvent(QKeyEvent *pEvent)
172{
173 /* Close on escape: */
174 if (pEvent->key() == Qt::Key_Escape)
175 close();
176
177 /* Call to base-class: */
178 QIWithRetranslateUI2<QWidget>::keyPressEvent(pEvent);
179}
180
181void UIScreenshotViewer::prepare()
182{
183 /* Screenshot viewer is an application-modal window: */
184 setWindowModality(Qt::ApplicationModal);
185 /* With the pointing-hand cursor: */
186 setCursor(Qt::PointingHandCursor);
187 /* And it's being deleted when closed: */
188 setAttribute(Qt::WA_DeleteOnClose);
189
190 /* Create layout: */
191 new QVBoxLayout(this);
192 AssertPtrReturnVoid(layout());
193 {
194 /* Configure layout: */
195 layout()->setContentsMargins(0, 0, 0, 0);
196
197 /* Create scroll-area: */
198 m_pScrollArea = new QScrollArea;
199 AssertPtrReturnVoid(m_pScrollArea);
200 {
201 /* Configure scroll-area: */
202 m_pScrollArea->setWidgetResizable (true);
203
204 /* Create picture label: */
205 m_pLabelPicture = new QLabel;
206 AssertPtrReturnVoid(m_pLabelPicture);
207 {
208 /* Add into scroll-area: */
209 m_pScrollArea->setWidget(m_pLabelPicture);
210 }
211
212 /* Add into layout: */
213 layout()->addWidget(m_pScrollArea);
214 }
215 }
216
217 /* Calculate aspect-ratio: */
218 double dAspectRatio = (double)m_pixmapScreenshot.height() / m_pixmapScreenshot.width();
219 /* Calculate maximum window size: */
220 const QSize maxSize = m_pixmapScreenshot.size() + QSize(m_pScrollArea->frameWidth() * 2, m_pScrollArea->frameWidth() * 2);
221 /* Calculate initial window size: */
222 const QSize initSize = QSize(640, (int)(640 * dAspectRatio)).boundedTo(maxSize);
223
224 /* Apply maximum window size restrictions: */
225 setMaximumSize(maxSize);
226 /* Apply initial window size: */
227 resize(initSize);
228
229 /* Apply language settings: */
230 retranslateUi();
231
232 /* Center according requested widget: */
233 VBoxGlobal::centerWidget(this, parentWidget(), false);
234}
235
236void UIScreenshotViewer::adjustPicture()
237{
238 if (m_fZoomMode)
239 {
240 m_pScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
241 m_pScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
242 m_pLabelPicture->setPixmap(m_pixmapScreenshot.scaled(m_pScrollArea->viewport()->size(),
243 Qt::IgnoreAspectRatio,
244 Qt::SmoothTransformation));
245 m_pLabelPicture->setToolTip(tr("Click to view non-scaled screenshot."));
246 }
247 else
248 {
249 m_pScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
250 m_pScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
251 m_pLabelPicture->setPixmap(m_pixmapScreenshot);
252 m_pLabelPicture->setToolTip(tr("Click to view scaled screenshot."));
253 }
254}
255
256
257/*********************************************************************************************************************************
258* Class VBoxSnapshotDetailsDlg implementation. *
259*********************************************************************************************************************************/
260
261VBoxSnapshotDetailsDlg::VBoxSnapshotDetailsDlg (QWidget *aParent)
262 : QIWithRetranslateUI <QDialog> (aParent)
263{
264 /* Apply UI decorations */
265 Ui::VBoxSnapshotDetailsDlg::setupUi (this);
266
267 /* Setup mLbThumbnail label */
268 mLbThumbnail->setCursor (Qt::PointingHandCursor);
269 mLbThumbnail->installEventFilter (this);
270
271 /* Setup mTeDetails browser */
272 mTeDetails->viewport()->setAutoFillBackground (false);
273 mTeDetails->setFocus();
274
275 /* Setup connections */
276 connect (mLeName, SIGNAL (textChanged (const QString&)), this, SLOT (onNameChanged (const QString&)));
277 connect (mButtonBox, SIGNAL (helpRequested()), &msgCenter(), SLOT (sltShowHelpHelpDialog()));
278}
279
280void VBoxSnapshotDetailsDlg::getFromSnapshot (const CSnapshot &aSnapshot)
281{
282 mSnapshot = aSnapshot;
283 CMachine machine = mSnapshot.GetMachine();
284
285 /* Get general properties */
286 mLeName->setText (aSnapshot.GetName());
287 mTeDescription->setText (aSnapshot.GetDescription());
288
289 /* Get timestamp info */
290 QDateTime timestamp;
291 timestamp.setTime_t (mSnapshot.GetTimeStamp() / 1000);
292 bool dateTimeToday = timestamp.date() == QDate::currentDate();
293 QString dateTime = dateTimeToday ? timestamp.time().toString (Qt::LocalDate) : timestamp.toString (Qt::LocalDate);
294 mTxTaken->setText (dateTime);
295
296 /* Get thumbnail if present */
297 ULONG width = 0, height = 0;
298 QVector <BYTE> thumbData = machine.ReadSavedThumbnailToArray (0, KBitmapFormat_BGR0, width, height);
299 mThumbnail = thumbData.size() != 0 ? QPixmap::fromImage (QImage (thumbData.data(), width, height, QImage::Format_RGB32).copy()) : QPixmap();
300 QVector <BYTE> screenData = machine.ReadSavedScreenshotToArray (0, KBitmapFormat_PNG, width, height);
301 mScreenshot = screenData.size() != 0 ? QPixmap::fromImage (QImage::fromData (screenData.data(), screenData.size(), "PNG")) : QPixmap();
302
303 QGridLayout *lt = qobject_cast <QGridLayout*> (layout());
304 Assert (lt);
305 if (mThumbnail.isNull())
306 {
307 lt->removeWidget (mLbThumbnail);
308 mLbThumbnail->setHidden (true);
309
310 lt->removeWidget (mLeName);
311 lt->removeWidget (mTxTaken);
312 lt->addWidget (mLeName, 0, 1, 1, 2);
313 lt->addWidget (mTxTaken, 1, 1, 1, 2);
314 }
315 else
316 {
317 lt->removeWidget (mLeName);
318 lt->removeWidget (mTxTaken);
319 lt->addWidget (mLeName, 0, 1);
320 lt->addWidget (mTxTaken, 1, 1);
321
322 lt->removeWidget (mLbThumbnail);
323 lt->addWidget (mLbThumbnail, 0, 2, 2, 1);
324 mLbThumbnail->setHidden (false);
325 }
326
327 retranslateUi();
328}
329
330void VBoxSnapshotDetailsDlg::putBackToSnapshot()
331{
332 AssertReturn (!mSnapshot.isNull(), (void) 0);
333
334 /* We need a session when we manipulate the snapshot data of a machine. */
335 CSession session = vboxGlobal().openExistingSession(mSnapshot.GetMachine().GetId());
336 if (session.isNull())
337 return;
338
339 mSnapshot.SetName(mLeName->text());
340 mSnapshot.SetDescription(mTeDescription->toPlainText());
341
342 /* Close the session again. */
343 session.UnlockMachine();
344}
345
346void VBoxSnapshotDetailsDlg::retranslateUi()
347{
348 /* Translate uic generated strings */
349 Ui::VBoxSnapshotDetailsDlg::retranslateUi (this);
350
351 if(mSnapshot.isNull())
352 return;
353
354 CMachine machine = mSnapshot.GetMachine();
355
356 setWindowTitle (tr ("Details of %1 (%2)").arg (mSnapshot.GetName()).arg (machine.GetName()));
357
358 mLbThumbnail->setToolTip (mScreenshot.isNull() ? QString() : tr ("Click to enlarge the screenshot."));
359
360 mTeDetails->setText (vboxGlobal().detailsReport (machine, false /* with links? */));
361}
362
363bool VBoxSnapshotDetailsDlg::eventFilter (QObject *aObject, QEvent *aEvent)
364{
365 Assert (aObject == mLbThumbnail);
366 if (aEvent->type() == QEvent::MouseButtonPress && !mScreenshot.isNull())
367 {
368 UIScreenshotViewer *pViewer = new UIScreenshotViewer(mScreenshot,
369 mSnapshot.GetMachine().GetName(),
370 mSnapshot.GetName(),
371 this);
372 pViewer->show();
373 pViewer->activateWindow();
374 }
375 return QDialog::eventFilter (aObject, aEvent);
376}
377
378void VBoxSnapshotDetailsDlg::showEvent (QShowEvent *aEvent)
379{
380 if (!mLbThumbnail->pixmap() && !mThumbnail.isNull())
381 {
382 mLbThumbnail->setPixmap (mThumbnail.scaled (QSize (1, mLbThumbnail->height()),
383 Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
384 retranslateUi();
385 }
386
387 QDialog::showEvent (aEvent);
388}
389
390void VBoxSnapshotDetailsDlg::onNameChanged (const QString &aText)
391{
392 mButtonBox->button (QDialogButtonBox::Ok)->setEnabled (!aText.trimmed().isEmpty());
393}
394
395#include "VBoxSnapshotDetailsDlg.moc"
396
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