Index: trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h	(revision 3805)
+++ trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h	(revision 3806)
@@ -117,11 +117,14 @@
 
     /** VM display rendering mode. */
-    enum RenderMode {
+    enum RenderMode
+    {
         InvalidRenderMode, TimerMode, QImageMode, SDLMode, DDRAWMode
     };
 
     /** Additional Qt event types. */
-    enum {
-        ResizeEventType = QEvent::User,
+    enum
+    {
+        AsyncEventType = QEvent::User + 100,
+        ResizeEventType,
         RepaintEventType,
         SetRegionEventType,
@@ -137,5 +140,5 @@
         RuntimeErrorEventType,
         ModifierKeyChangeEventType,
-        EnumerateMediaEventType = QEvent::User + 100,
+        EnumerateMediaEventType,
 #if defined (Q_WS_WIN)
         ShellExecuteEventType,
Index: trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h	(revision 3805)
+++ trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h	(revision 3806)
@@ -435,4 +435,8 @@
     static QString removeAccelMark (const QString &aText);
 
+    static QWidget *findWidget (QWidget *aParent, const char *aName,
+                                const char *aClassName = NULL,
+                                bool aRecursive = false);
+
 signals:
 
@@ -548,4 +552,40 @@
 inline VBoxGlobal &vboxGlobal() { return VBoxGlobal::instance(); }
 
+// Helper classes
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  Generic asyncronous event.
+ *
+ *  This abstract class is intended to provide a conveinent way to execute
+ *  code on the main GUI thread asynchronously to the calling party. This is
+ *  done by putting necessary actions to the #handle() function in a subclass
+ *  and then posting an instance of the subclass using #post(). The instance
+ *  must be allocated on the heap using the <tt>new</tt> operation and will be
+ *  automatically deleted after processing. Note that if you don't call #post()
+ *  on the created instance, you have to delete it yourself.
+ */
+class VBoxAsyncEvent : public QEvent
+{
+public:
+
+    VBoxAsyncEvent() : QEvent ((QEvent::Type) VBoxDefs::AsyncEventType) {}
+
+    /**
+     *  Worker function. Gets executed on the GUI thread when the posted event
+     *  is processed by the main event loop.
+     */
+    virtual void handle() = 0;
+
+    /**
+     *  Posts this event to the main event loop.
+     *  The caller loses ownership of this object after this method returns
+     *  and must not delete the object.
+     */
+    void post()
+    {
+        QApplication::postEvent (&vboxGlobal(), this);
+    }
+};
 
 /**
Index: trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp	(revision 3805)
+++ trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp	(revision 3806)
@@ -2990,4 +2990,48 @@
 }
 
+/**
+ *  Searches for a widget that with @a aName (if it is not NULL) which inherits
+ *  @a aClassName (if it is not NULL) and among children of @a aParent. If @a
+ *  aParent is NULL, all top-level widgets are searched. If @a aRecursive is
+ *  true, child widgets are recursively searched as well.  
+ */
+/* static */
+QWidget *VBoxGlobal::findWidget (QWidget *aParent, const char *aName,
+                                 const char *aClassName /* = NULL */,
+                                 bool aRecursive /* = false */)
+{
+    if (aParent == NULL)
+    {
+        QWidgetList *list = QApplication::topLevelWidgets();
+        QWidgetListIt it (*list);
+        QWidget *w = NULL;
+        for (; (w = it.current()) != NULL; ++ it)
+        {
+            if ((!aName || strcmp (w->name(), aName) == 0) &&
+                (!aClassName || strcmp (w->className(), aClassName) == 0))
+                break;
+            if (aRecursive)
+            {
+                w = findWidget (w, aName, aClassName, aRecursive);
+                if (w)
+                    break;
+            }
+        }
+        delete list;
+        return w;
+    }
+
+    QObjectList *list = aParent->queryList (aName, aClassName, false, true);
+    QObjectListIt it (*list);
+    QObject *obj = NULL;
+    for (; (obj = it.current()) != NULL; ++ it)
+    {
+        if (obj->isWidgetType())
+            break;
+    }
+    delete list;
+    return (QWidget *) obj;
+}
+
 // Protected members
 ////////////////////////////////////////////////////////////////////////////////
@@ -3009,4 +3053,11 @@
         }
 #endif
+
+        case VBoxDefs::AsyncEventType:
+        {
+            VBoxAsyncEvent *ev = (VBoxAsyncEvent *) e;
+            ev->handle();
+            return true;
+        }
 
         case VBoxDefs::EnumerateMediaEventType:
