VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumEnumerator.cpp@ 102493

Last change on this file since 102493 was 98103, checked in by vboxsync, 20 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.2 KB
Line 
1/* $Id: UIMediumEnumerator.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMediumEnumerator class implementation.
4 */
5
6/*
7 * Copyright (C) 2013-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QSet>
30
31/* GUI includes: */
32#include "UICommon.h"
33#include "UIErrorString.h"
34#include "UIMediumEnumerator.h"
35#include "UINotificationCenter.h"
36#include "UITask.h"
37#include "UIThreadPool.h"
38#include "UIVirtualBoxEventHandler.h"
39
40/* COM includes: */
41#include "COMEnums.h"
42#include "CMachine.h"
43#include "CMediumAttachment.h"
44#include "CSnapshot.h"
45
46
47/** Template function to convert a list of
48 * abstract objects to a human readable string list.
49 * @note T should have .toString() member implemented. */
50template<class T> static QStringList toStringList(const QList<T> &list)
51{
52 QStringList l;
53 foreach(const T &t, list)
54 l << t.toString();
55 return l;
56}
57
58
59/** UITask extension used for medium-enumeration purposes.
60 * @note We made setting/getting medium a thread-safe stuff. But this wasn't
61 * dangerous for us before since setter/getter calls are splitted in time
62 * by enumeration logic. Previously we were even using
63 * property/setProperty API for that but latest Qt versions prohibits
64 * property/setProperty API usage from other than the GUI thread so we
65 * had to rework that stuff to be thread-safe for Qt >= 5.11. */
66class UITaskMediumEnumeration : public UITask
67{
68 Q_OBJECT;
69
70public:
71
72 /** Constructs @a guiMedium enumeration task. */
73 UITaskMediumEnumeration(const UIMedium &guiMedium)
74 : UITask(UITask::Type_MediumEnumeration)
75 , m_guiMedium(guiMedium)
76 {}
77
78 /** Returns GUI medium. */
79 UIMedium medium() const
80 {
81 /* Acquire under a proper lock: */
82 m_mutex.lock();
83 const UIMedium guiMedium = m_guiMedium;
84 m_mutex.unlock();
85 return guiMedium;
86 }
87
88private:
89
90 /** Contains medium-enumeration task body. */
91 virtual void run() RT_OVERRIDE
92 {
93 /* Enumerate under a proper lock: */
94 m_mutex.lock();
95 m_guiMedium.blockAndQueryState();
96 m_mutex.unlock();
97 }
98
99 /** Holds the mutex to access m_guiMedium member. */
100 mutable QMutex m_mutex;
101 /** Holds the medium being enumerated. */
102 UIMedium m_guiMedium;
103};
104
105
106/*********************************************************************************************************************************
107* Class UIMediumEnumerator implementation. *
108*********************************************************************************************************************************/
109
110UIMediumEnumerator::UIMediumEnumerator()
111 : m_fFullMediumEnumerationRequested(false)
112 , m_fMediumEnumerationInProgress(false)
113{
114 /* Allow UIMedium to be used in inter-thread signals: */
115 qRegisterMetaType<UIMedium>();
116
117 /* Prepare Main event handlers: */
118 /* Machine related events: */
119 connect(gVBoxEvents, &UIVirtualBoxEventHandler::sigMachineDataChange,
120 this, &UIMediumEnumerator::sltHandleMachineDataChange);
121 /* Medium related events: */
122 connect(gVBoxEvents, &UIVirtualBoxEventHandler::sigStorageControllerChange,
123 this, &UIMediumEnumerator::sltHandleStorageControllerChange);
124 connect(gVBoxEvents, &UIVirtualBoxEventHandler::sigStorageDeviceChange,
125 this, &UIMediumEnumerator::sltHandleStorageDeviceChange);
126 connect(gVBoxEvents, &UIVirtualBoxEventHandler::sigMediumChange,
127 this, &UIMediumEnumerator::sltHandleMediumChange);
128 connect(gVBoxEvents, &UIVirtualBoxEventHandler::sigMediumConfigChange,
129 this, &UIMediumEnumerator::sltHandleMediumConfigChange);
130 connect(gVBoxEvents, &UIVirtualBoxEventHandler::sigMediumRegistered,
131 this, &UIMediumEnumerator::sltHandleMediumRegistered);
132
133 /* Prepare global thread-pool listener: */
134 connect(uiCommon().threadPool(), &UIThreadPool::sigTaskComplete,
135 this, &UIMediumEnumerator::sltHandleMediumEnumerationTaskComplete);
136
137 /* We should make sure media map contains at least NULL medium object: */
138 addNullMediumToMap(m_media);
139 /* Notify listener about initial enumeration started/finished instantly: */
140 LogRel(("GUI: UIMediumEnumerator: Initial medium-enumeration finished!\n"));
141 emit sigMediumEnumerationStarted();
142 emit sigMediumEnumerationFinished();
143}
144
145QList<QUuid> UIMediumEnumerator::mediumIDs() const
146{
147 /* Return keys of current media map: */
148 return m_media.keys();
149}
150
151UIMedium UIMediumEnumerator::medium(const QUuid &uMediumID) const
152{
153 /* Search through current media map
154 * for the UIMedium with passed ID: */
155 if (m_media.contains(uMediumID))
156 return m_media.value(uMediumID);
157 /* Return NULL UIMedium otherwise: */
158 return UIMedium();
159}
160
161void UIMediumEnumerator::createMedium(const UIMedium &guiMedium)
162{
163 /* Get UIMedium ID: */
164 const QUuid uMediumID = guiMedium.id();
165
166 /* Do not create UIMedium(s) with incorrect ID: */
167 AssertReturnVoid(!uMediumID.isNull());
168 /* Make sure UIMedium doesn't exist already: */
169 if (m_media.contains(uMediumID))
170 return;
171
172 /* Insert UIMedium: */
173 m_media[uMediumID] = guiMedium;
174 LogRel(("GUI: UIMediumEnumerator: Medium with key={%s} created\n", uMediumID.toString().toUtf8().constData()));
175
176 /* Notify listener: */
177 emit sigMediumCreated(uMediumID);
178}
179
180void UIMediumEnumerator::enumerateMedia(const CMediumVector &comMedia /* = CMediumVector() */)
181{
182 /* Compose new map of currently cached media & their children.
183 * While composing we are using data from already cached media. */
184 UIMediumMap guiMedia;
185 addNullMediumToMap(guiMedia);
186 if (comMedia.isEmpty())
187 {
188 /* Compose new map of all known media & their children: */
189 addMediaToMap(uiCommon().virtualBox().GetHardDisks(), guiMedia);
190 addMediaToMap(uiCommon().host().GetDVDDrives(), guiMedia);
191 addMediaToMap(uiCommon().virtualBox().GetDVDImages(), guiMedia);
192 addMediaToMap(uiCommon().host().GetFloppyDrives(), guiMedia);
193 addMediaToMap(uiCommon().virtualBox().GetFloppyImages(), guiMedia);
194 }
195 else
196 {
197 /* Compose new map of passed media & their children: */
198 addMediaToMap(comMedia, guiMedia);
199 }
200
201 /* UICommon is cleaning up, abort immediately: */
202 if (uiCommon().isCleaningUp())
203 return;
204
205 if (comMedia.isEmpty())
206 {
207 /* Replace existing media map since
208 * we have full medium enumeration: */
209 m_fFullMediumEnumerationRequested = true;
210 m_media = guiMedia;
211 }
212 else
213 {
214 /* Throw the media to existing map: */
215 foreach (const QUuid &uMediumId, guiMedia.keys())
216 m_media[uMediumId] = guiMedia.value(uMediumId);
217 }
218
219 /* If enumeration hasn't yet started: */
220 if (!m_fMediumEnumerationInProgress)
221 {
222 /* Notify listener about enumeration started: */
223 LogRel(("GUI: UIMediumEnumerator: Medium-enumeration started...\n"));
224 m_fMediumEnumerationInProgress = true;
225 emit sigMediumEnumerationStarted();
226
227 /* Make sure we really have more than one UIMedium (which is NULL): */
228 if ( guiMedia.size() == 1
229 && guiMedia.first().id() == UIMedium::nullID())
230 {
231 /* Notify listener about enumeration finished instantly: */
232 LogRel(("GUI: UIMediumEnumerator: Medium-enumeration finished!\n"));
233 m_fMediumEnumerationInProgress = false;
234 emit sigMediumEnumerationFinished();
235 }
236 }
237
238 /* Start enumeration for media with non-NULL ID: */
239 foreach (const QUuid &uMediumID, guiMedia.keys())
240 if (!uMediumID.isNull())
241 createMediumEnumerationTask(guiMedia[uMediumID]);
242}
243
244void UIMediumEnumerator::refreshMedia()
245{
246 /* Make sure we are not already in progress: */
247 AssertReturnVoid(!m_fMediumEnumerationInProgress);
248
249 /* Refresh all cached media we have: */
250 foreach (const QUuid &uMediumID, m_media.keys())
251 m_media[uMediumID].refresh();
252}
253
254void UIMediumEnumerator::retranslateUi()
255{
256 /* Translating NULL UIMedium by recreating it: */
257 if (m_media.contains(UIMedium::nullID()))
258 m_media[UIMedium::nullID()] = UIMedium();
259}
260
261void UIMediumEnumerator::sltHandleMachineDataChange(const QUuid &uMachineId)
262{
263 //printf("MachineDataChange: machine-id=%s\n",
264 // uMachineId.toString().toUtf8().constData());
265 LogRel2(("GUI: UIMediumEnumerator: MachineDataChange event received, Machine ID = {%s}\n",
266 uMachineId.toString().toUtf8().constData()));
267
268 /* Enumerate all the media of machine with this ID: */
269 QList<QUuid> result;
270 enumerateAllMediaOfMachineWithId(uMachineId, result);
271}
272
273void UIMediumEnumerator::sltHandleStorageControllerChange(const QUuid &uMachineId, const QString &strControllerName)
274{
275 //printf("StorageControllerChanged: machine-id=%s, controller-name=%s\n",
276 // uMachineId.toString().toUtf8().constData(), strControllerName.toUtf8().constData());
277 LogRel2(("GUI: UIMediumEnumerator: StorageControllerChanged event received, Medium ID = {%s}, Controller Name = {%s}\n",
278 uMachineId.toString().toUtf8().constData(), strControllerName.toUtf8().constData()));
279}
280
281void UIMediumEnumerator::sltHandleStorageDeviceChange(CMediumAttachment comAttachment, bool fRemoved, bool fSilent)
282{
283 //printf("StorageDeviceChanged: removed=%d, silent=%d\n",
284 // fRemoved, fSilent);
285 LogRel2(("GUI: UIMediumEnumerator: StorageDeviceChanged event received, Removed = {%d}, Silent = {%d}\n",
286 fRemoved, fSilent));
287
288 /* Parse attachment: */
289 QList<QUuid> result;
290 parseAttachment(comAttachment, result);
291}
292
293void UIMediumEnumerator::sltHandleMediumChange(CMediumAttachment comAttachment)
294{
295 //printf("MediumChanged\n");
296 LogRel2(("GUI: UIMediumEnumerator: MediumChanged event received\n"));
297
298 /* Parse attachment: */
299 QList<QUuid> result;
300 parseAttachment(comAttachment, result);
301}
302
303void UIMediumEnumerator::sltHandleMediumConfigChange(CMedium comMedium)
304{
305 //printf("MediumConfigChanged\n");
306 LogRel2(("GUI: UIMediumEnumerator: MediumConfigChanged event received\n"));
307
308 /* Parse medium: */
309 QList<QUuid> result;
310 parseMedium(comMedium, result);
311}
312
313void UIMediumEnumerator::sltHandleMediumRegistered(const QUuid &uMediumId, KDeviceType enmMediumType, bool fRegistered)
314{
315 //printf("MediumRegistered: medium-id=%s, medium-type=%d, registered=%d\n",
316 // uMediumId.toString().toUtf8().constData(), enmMediumType, fRegistered);
317 //printf(" Medium to recache: %s\n",
318 // uMediumId.toString().toUtf8().constData());
319 LogRel2(("GUI: UIMediumEnumerator: MediumRegistered event received, Medium ID = {%s}, Medium type = {%d}, Registered = {%d}\n",
320 uMediumId.toString().toUtf8().constData(), enmMediumType, fRegistered));
321
322 /* New medium registered: */
323 if (fRegistered)
324 {
325 /* Make sure this medium isn't already cached: */
326 if (!medium(uMediumId).isNull())
327 {
328 /* This medium can be known because of async event nature. Currently medium registration event comes
329 * very late and other even unrelated events can come before it and request for this particular medium
330 * enumeration, so we just ignore repetitive events but enumerate this UIMedium at least once if it
331 * wasn't registered before. */
332 if (!m_registeredMediaIds.contains(uMediumId))
333 {
334 LogRel2(("GUI: UIMediumEnumerator: Medium {%s} is cached but not registered already, so will be enumerated..\n",
335 uMediumId.toString().toUtf8().constData()));
336 createMediumEnumerationTask(m_media.value(uMediumId));
337
338 /* Mark medium registered: */
339 m_registeredMediaIds << uMediumId;
340 }
341 }
342 else
343 {
344 /* Get VBox for temporary usage, it will cache the error info: */
345 CVirtualBox comVBox = uiCommon().virtualBox();
346 /* Open existing medium, this API can be used to open known medium as well, using ID as location for that: */
347 CMedium comMedium = comVBox.OpenMedium(uMediumId.toString(), enmMediumType, KAccessMode_ReadWrite, false);
348 if (!comVBox.isOk())
349 LogRel(("GUI: UIMediumEnumerator: Unable to open registered medium! %s\n",
350 UIErrorString::simplifiedErrorInfo(comVBox).toUtf8().constData()));
351 else
352 {
353 /* Create new UIMedium: */
354 const UIMedium guiMedium(comMedium, UIMediumDefs::mediumTypeToLocal(comMedium.GetDeviceType()));
355 const QUuid &uUIMediumKey = guiMedium.key();
356
357 /* Cache corresponding UIMedium: */
358 m_media.insert(uUIMediumKey, guiMedium);
359 LogRel2(("GUI: UIMediumEnumerator: Medium {%s} is now cached and will be enumerated..\n",
360 uUIMediumKey.toString().toUtf8().constData()));
361
362 /* And notify listeners: */
363 emit sigMediumCreated(uUIMediumKey);
364
365 /* Enumerate corresponding UIMedium: */
366 createMediumEnumerationTask(m_media.value(uMediumId));
367
368 /* Mark medium registered: */
369 m_registeredMediaIds << uMediumId;
370 }
371 }
372 }
373 /* Old medium unregistered: */
374 else
375 {
376 /* Make sure this medium is still cached: */
377 if (medium(uMediumId).isNull())
378 {
379 /* This medium can be wiped out already because of async event nature. Currently
380 * medium unregistration event comes very late and other even unrealted events
381 * can come before it and request for this particular medium enumeration. If medium
382 * enumeration is performed fast enough (before medium unregistration event comes),
383 * medium will be wiped out already, so we just ignore it. */
384 LogRel2(("GUI: UIMediumEnumerator: Medium {%s} was not currently cached!\n",
385 uMediumId.toString().toUtf8().constData()));
386 }
387 else
388 {
389 /* Forget corresponding UIMedium: */
390 m_media.remove(uMediumId);
391 LogRel2(("GUI: UIMediumEnumerator: Medium {%s} is no more cached!\n",
392 uMediumId.toString().toUtf8().constData()));
393
394 /* And notify listeners: */
395 emit sigMediumDeleted(uMediumId);
396
397 /* Besides that we should enumerate all the
398 * 1st level children of deleted medium: */
399 QList<QUuid> result;
400 enumerateAllMediaOfMediumWithId(uMediumId, result);
401 }
402
403 /* Mark medium unregistered: */
404 m_registeredMediaIds.remove(uMediumId);
405 }
406}
407
408void UIMediumEnumerator::sltHandleMediumEnumerationTaskComplete(UITask *pTask)
409{
410 /* Make sure that is one of our tasks: */
411 if (pTask->type() != UITask::Type_MediumEnumeration)
412 return;
413 AssertReturnVoid(m_tasks.contains(pTask));
414
415 /* Get enumerated UIMedium: */
416 const UIMedium guiMedium = qobject_cast<UITaskMediumEnumeration*>(pTask)->medium();
417 const QUuid uMediumKey = guiMedium.key();
418 LogRel2(("GUI: UIMediumEnumerator: Medium with key={%s} enumerated\n",
419 uMediumKey.toString().toUtf8().constData()));
420
421 /* Remove task from internal set: */
422 m_tasks.remove(pTask);
423
424 /* Make sure such UIMedium still exists: */
425 if (!m_media.contains(uMediumKey))
426 {
427 LogRel2(("GUI: UIMediumEnumerator: Medium with key={%s} already deleted by a third party\n",
428 uMediumKey.toString().toUtf8().constData()));
429 return;
430 }
431
432 /* Check if UIMedium ID was changed: */
433 const QUuid uMediumID = guiMedium.id();
434 /* UIMedium ID was changed to nullID: */
435 if (uMediumID == UIMedium::nullID())
436 {
437 /* Delete this UIMedium: */
438 m_media.remove(uMediumKey);
439 LogRel2(("GUI: UIMediumEnumerator: Medium with key={%s} closed and deleted (after enumeration)\n",
440 uMediumKey.toString().toUtf8().constData()));
441
442 /* And notify listener about delete: */
443 emit sigMediumDeleted(uMediumKey);
444 }
445 /* UIMedium ID was changed to something proper: */
446 else if (uMediumID != uMediumKey)
447 {
448 /* We have to reinject enumerated UIMedium: */
449 m_media.remove(uMediumKey);
450 m_media[uMediumID] = guiMedium;
451 m_media[uMediumID].setKey(uMediumID);
452 LogRel2(("GUI: UIMediumEnumerator: Medium with key={%s} has it changed to {%s}\n",
453 uMediumKey.toString().toUtf8().constData(),
454 uMediumID.toString().toUtf8().constData()));
455
456 /* And notify listener about delete/create: */
457 emit sigMediumDeleted(uMediumKey);
458 emit sigMediumCreated(uMediumID);
459 }
460 /* UIMedium ID was not changed: */
461 else
462 {
463 /* Just update enumerated UIMedium: */
464 m_media[uMediumID] = guiMedium;
465 LogRel2(("GUI: UIMediumEnumerator: Medium with key={%s} updated\n",
466 uMediumID.toString().toUtf8().constData()));
467
468 /* And notify listener about update: */
469 emit sigMediumEnumerated(uMediumID);
470 }
471
472 /* If there are no more tasks we know about: */
473 if (m_tasks.isEmpty())
474 {
475 /* Notify listener: */
476 LogRel(("GUI: UIMediumEnumerator: Medium-enumeration finished!\n"));
477 m_fMediumEnumerationInProgress = false;
478 emit sigMediumEnumerationFinished();
479 }
480}
481
482void UIMediumEnumerator::createMediumEnumerationTask(const UIMedium &guiMedium)
483{
484 /* Prepare medium-enumeration task: */
485 UITask *pTask = new UITaskMediumEnumeration(guiMedium);
486 /* Append to internal set: */
487 m_tasks << pTask;
488 /* Post into global thread-pool: */
489 uiCommon().threadPool()->enqueueTask(pTask);
490}
491
492void UIMediumEnumerator::addNullMediumToMap(UIMediumMap &media)
493{
494 /* Insert NULL UIMedium to the passed media map.
495 * Get existing one from the previous map if any. */
496 const UIMedium guiMedium = m_media.contains(UIMedium::nullID())
497 ? m_media[UIMedium::nullID()]
498 : UIMedium();
499 media.insert(UIMedium::nullID(), guiMedium);
500}
501
502void UIMediumEnumerator::addMediaToMap(const CMediumVector &inputMedia, UIMediumMap &outputMedia)
503{
504 /* Iterate through passed inputMedia vector: */
505 foreach (const CMedium &comMedium, inputMedia)
506 {
507 /* If UICommon is cleaning up, abort immediately: */
508 if (uiCommon().isCleaningUp())
509 break;
510
511 /* Insert UIMedium to the passed media map.
512 * Get existing one from the previous map if any.
513 * Create on the basis of comMedium otherwise. */
514 const QUuid uMediumID = comMedium.GetId();
515 const UIMedium guiMedium = m_media.contains(uMediumID)
516 ? m_media.value(uMediumID)
517 : UIMedium(comMedium, UIMediumDefs::mediumTypeToLocal(comMedium.GetDeviceType()));
518 outputMedia.insert(guiMedium.id(), guiMedium);
519
520 /* Insert comMedium children into map as well: */
521 addMediaToMap(comMedium.GetChildren(), outputMedia);
522 }
523}
524
525void UIMediumEnumerator::parseAttachment(CMediumAttachment comAttachment, QList<QUuid> &result)
526{
527 /* Make sure attachment is valid: */
528 if (comAttachment.isNull())
529 {
530 LogRel2(("GUI: UIMediumEnumerator: Attachment is NULL!\n"));
531 /// @todo is this possible case?
532 AssertFailed();
533 }
534 else
535 {
536 /* Acquire attachment medium: */
537 CMedium comMedium = comAttachment.GetMedium();
538 if (!comAttachment.isOk())
539 LogRel(("GUI: UIMediumEnumerator: Unable to acquire attachment medium! %s\n",
540 UIErrorString::simplifiedErrorInfo(comAttachment).toUtf8().constData()));
541 else
542 {
543 /* Parse medium: */
544 parseMedium(comMedium, result);
545
546 // WORKAROUND:
547 // In current architecture there is no way to determine medium previously mounted
548 // to this attachment, so we will have to enumerate all other cached media which
549 // belongs to the same VM, since they may no longer belong to it.
550
551 /* Acquire parent VM: */
552 CMachine comMachine = comAttachment.GetMachine();
553 if (!comAttachment.isOk())
554 LogRel(("GUI: UIMediumEnumerator: Unable to acquire attachment parent machine! %s\n",
555 UIErrorString::simplifiedErrorInfo(comAttachment).toUtf8().constData()));
556 else
557 {
558 /* Acquire machine ID: */
559 const QUuid uMachineId = comMachine.GetId();
560 if (!comMachine.isOk())
561 LogRel(("GUI: UIMediumEnumerator: Unable to acquire machine ID! %s\n",
562 UIErrorString::simplifiedErrorInfo(comMachine).toUtf8().constData()));
563 else
564 {
565 /* Enumerate all the media of machine with this ID: */
566 enumerateAllMediaOfMachineWithId(uMachineId, result);
567 }
568 }
569 }
570 }
571}
572
573void UIMediumEnumerator::parseMedium(CMedium comMedium, QList<QUuid> &result)
574{
575 /* Make sure medium is valid: */
576 if (comMedium.isNull())
577 {
578 /* This medium is NULL by some reason, the obvious case when this
579 * can happen is when optical/floppy device is created empty. */
580 LogRel2(("GUI: UIMediumEnumerator: Medium is NULL!\n"));
581 }
582 else
583 {
584 /* Acquire medium ID: */
585 const QUuid uMediumId = comMedium.GetId();
586 if (!comMedium.isOk())
587 LogRel(("GUI: UIMediumEnumerator: Unable to acquire medium ID! %s\n",
588 UIErrorString::simplifiedErrorInfo(comMedium).toUtf8().constData()));
589 else
590 {
591 //printf(" Medium to recache: %s\n", uMediumId.toString().toUtf8().constData());
592
593 /* Make sure this medium is already cached: */
594 if (medium(uMediumId).isNull())
595 {
596 /* This medium isn't cached by some reason, which can be different.
597 * One of such reasons is when config-changed event comes earlier than
598 * corresponding registration event. For now we are ignoring that at all. */
599 LogRel2(("GUI: UIMediumEnumerator: Medium {%s} isn't cached yet!\n",
600 uMediumId.toString().toUtf8().constData()));
601 }
602 else
603 {
604 /* Enumerate corresponding UIMedium: */
605 LogRel2(("GUI: UIMediumEnumerator: Medium {%s} will be enumerated..\n",
606 uMediumId.toString().toUtf8().constData()));
607 createMediumEnumerationTask(m_media.value(uMediumId));
608 result << uMediumId;
609 }
610 }
611 }
612}
613
614void UIMediumEnumerator::enumerateAllMediaOfMachineWithId(const QUuid &uMachineId, QList<QUuid> &result)
615{
616 /* For each the cached UIMedium we have: */
617 foreach (const QUuid &uMediumId, mediumIDs())
618 {
619 /* Check if medium isn't NULL, used by our
620 * machine and wasn't already enumerated. */
621 const UIMedium guiMedium = medium(uMediumId);
622 if ( !guiMedium.isNull()
623 && guiMedium.machineIds().contains(uMachineId)
624 && !result.contains(uMediumId))
625 {
626 /* Enumerate corresponding UIMedium: */
627 //printf(" Medium to recache: %s\n",
628 // uMediumId.toString().toUtf8().constData());
629 LogRel2(("GUI: UIMediumEnumerator: Medium {%s} of machine {%s} will be enumerated..\n",
630 uMediumId.toString().toUtf8().constData(),
631 uMachineId.toString().toUtf8().constData()));
632 createMediumEnumerationTask(guiMedium);
633 result << uMediumId;
634 }
635 }
636}
637
638void UIMediumEnumerator::enumerateAllMediaOfMediumWithId(const QUuid &uParentMediumId, QList<QUuid> &result)
639{
640 /* For each the cached UIMedium we have: */
641 foreach (const QUuid &uMediumId, mediumIDs())
642 {
643 /* Check if medium isn't NULL, and is
644 * a child of specified parent medium. */
645 const UIMedium guiMedium = medium(uMediumId);
646 if ( !guiMedium.isNull()
647 && guiMedium.parentID() == uParentMediumId)
648 {
649 /* Enumerate corresponding UIMedium: */
650 //printf(" Medium to recache: %s\n",
651 // uMediumId.toString().toUtf8().constData());
652 LogRel2(("GUI: UIMediumEnumerator: Medium {%s} a child of medium {%s} will be enumerated..\n",
653 uMediumId.toString().toUtf8().constData(),
654 uParentMediumId.toString().toUtf8().constData()));
655 createMediumEnumerationTask(guiMedium);
656 result << uMediumId;
657 }
658 }
659}
660
661
662#include "UIMediumEnumerator.moc"
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