Index: /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 20077)
+++ /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 20078)
@@ -242,4 +242,5 @@
 	include/QIHelpButton.h \
 	include/QIDialog.h \
+	include/QIFileDialog.h \
 	include/VBoxFilePathSelectorWidget.h \
 	include/VBoxOSTypeSelectorButton.h \
@@ -313,4 +314,8 @@
 	src/COMDefs.cpp
 endif
+ifeq ($(KBUILD_TARGET),win)
+VirtualBox_QT_MOCSRCS += \
+	src/QIFileDialog.cpp
+endif
 
 VirtualBox_SOURCES = \
@@ -326,4 +331,5 @@
 	src/QIAbstractWizard.cpp \
 	src/QIDialog.cpp \
+	src/QIFileDialog.cpp \
 	src/QIDialogButtonBox.cpp \
 	src/QIListView.cpp \
Index: /trunk/src/VBox/Frontends/VirtualBox/include/QIFileDialog.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/QIFileDialog.h	(revision 20078)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/QIFileDialog.h	(revision 20078)
@@ -0,0 +1,59 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * Qt extensions: QIFileDialog class declarations
+ */
+
+/*
+ * Copyright (C) 2009 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef __QIFileDialog_h__
+#define __QIFileDialog_h__
+
+/* Qt includes */
+#include <QFileDialog>
+
+class QIFileDialog : public QFileDialog
+{
+    Q_OBJECT;
+
+public:
+
+    QIFileDialog (QWidget *aParent, Qt::WindowFlags aFlags);
+
+    static QString getExistingDirectory (const QString &aDir, QWidget *aParent,
+                                         const QString &aCaption = QString::null,
+                                         bool aDirOnly = TRUE,
+                                         bool resolveSymlinks = TRUE);
+
+    static QString getSaveFileName (const QString &aStartWith, const QString &aFilters, QWidget *aParent,
+                                    const QString &aCaption, QString *aSelectedFilter = 0,
+                                    bool aResolveSymLinks = true);
+
+    static QString getOpenFileName (const QString &aStartWith, const QString &aFilters, QWidget *aParent,
+                                    const QString &aCaption, QString *aSelectedFilter = 0,
+                                    bool aResolveSymLinks = true);
+
+    static QStringList getOpenFileNames (const QString &aStartWith, const QString &aFilters, QWidget *aParent,
+                                         const QString &aCaption, QString *aSelectedFilter = 0,
+                                         bool aResolveSymLinks = true,
+                                         bool aSingleFile = false);
+
+    static QString getFirstExistingDir (const QString &aStartDir);
+};
+
+#endif /* __QIFileDialog_h__ */
+
Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h	(revision 20077)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h	(revision 20078)
@@ -719,24 +719,4 @@
     static QString systemLanguageId();
 
-    static QString getExistingDirectory (const QString &aDir, QWidget *aParent,
-                                         const QString &aCaption = QString::null,
-                                         bool aDirOnly = TRUE,
-                                         bool resolveSymlinks = TRUE);
-
-    static QString getSaveFileName (const QString &aStartWith, const QString &aFilters, QWidget *aParent,
-                                    const QString &aCaption, QString *aSelectedFilter = NULL,
-                                    bool aResolveSymLinks = true);
-
-    static QString getOpenFileName (const QString &aStartWith, const QString &aFilters, QWidget *aParent,
-                                    const QString &aCaption, QString *aSelectedFilter = NULL,
-                                    bool aResolveSymLinks = true);
-
-    static QStringList getOpenFileNames (const QString &aStartWith, const QString &aFilters, QWidget *aParent,
-                                         const QString &aCaption, QString *aSelectedFilter = NULL,
-                                         bool aResolveSymLinks = true,
-                                         bool aSingleFile = false);
-
-    static QString getFirstExistingDir (const QString &);
-
     static bool activateWindow (WId aWId, bool aSwitchDesktop = true);
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/QIFileDialog.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/QIFileDialog.cpp	(revision 20078)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/QIFileDialog.cpp	(revision 20078)
@@ -0,0 +1,778 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * Qt extensions: QIFileDialog class implementation
+ */
+
+/*
+ * Copyright (C) 2009 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/* VBox includes */
+#include "VBoxGlobal.h"
+#include "QIFileDialog.h"
+
+#if defined Q_WS_WIN
+
+/// @todo bird: Use (U)INT_PTR, (U)LONG_PTR, DWORD_PTR, or (u)intptr_t.
+#if defined Q_OS_WIN64
+typedef unsigned __int64 Q_ULONG;   /* word up to 64 bit unsigned */
+#else
+typedef unsigned long Q_ULONG;      /* word up to 64 bit unsigned */
+#endif
+
+/* Qt includes */
+#include <QEvent>
+#include <QEventLoop>
+#include <QThread>
+
+/* WinAPI includes */
+#include "shlobj.h"
+
+static QString extractFilter (const QString &aRawFilter)
+{
+    static const char qt_file_dialog_filter_reg_exp[] =
+        "([a-zA-Z0-9 ]*)\\(([a-zA-Z0-9_.*? +;#\\[\\]]*)\\)$";
+
+    QString result = aRawFilter;
+    QRegExp r (QString::fromLatin1 (qt_file_dialog_filter_reg_exp));
+    int index = r.indexIn (result);
+    if (index >= 0)
+        result = r.cap (2);
+    return result.replace (QChar (' '), QChar (';'));
+}
+
+/**
+ * Converts QFileDialog filter list to Win32 API filter list.
+ */
+static QString winFilter (const QString &aFilter)
+{
+    QStringList filterLst;
+
+    if (!aFilter.isEmpty())
+    {
+        int i = aFilter.indexOf (";;", 0);
+        QString sep (";;");
+        if (i == -1)
+        {
+            if (aFilter.indexOf ("\n", 0) != -1)
+            {
+                sep = "\n";
+                i = aFilter.indexOf (sep, 0);
+            }
+        }
+
+        filterLst = aFilter.split (sep);
+    }
+
+    QStringList::Iterator it = filterLst.begin();
+    QString winfilters;
+    for (; it != filterLst.end(); ++ it)
+    {
+        winfilters += *it;
+        winfilters += QChar::Null;
+        winfilters += extractFilter (*it);
+        winfilters += QChar::Null;
+    }
+    winfilters += QChar::Null;
+    return winfilters;
+}
+
+/*
+ * Callback function to control the native Win32 API file dialog
+ */
+UINT_PTR CALLBACK OFNHookProc (HWND aHdlg, UINT aUiMsg, WPARAM aWParam, LPARAM aLParam)
+{
+    if (aUiMsg == WM_NOTIFY)
+    {
+        OFNOTIFY *notif = (OFNOTIFY*) aLParam;
+        if (notif->hdr.code == CDN_TYPECHANGE)
+        {
+            /* locate native dialog controls */
+            HWND parent = GetParent (aHdlg);
+            HWND button = GetDlgItem (parent, IDOK);
+            HWND textfield = ::GetDlgItem (parent, cmb13);
+            if (textfield == NULL)
+                textfield = ::GetDlgItem (parent, edt1);
+            if (textfield == NULL)
+                return FALSE;
+            HWND selector = ::GetDlgItem (parent, cmb1);
+
+            /* simulate filter change by pressing apply-key */
+            int    size = 256;
+            TCHAR *buffer = (TCHAR*)malloc (size);
+            SendMessage (textfield, WM_GETTEXT, size, (LPARAM)buffer);
+            SendMessage (textfield, WM_SETTEXT, 0, (LPARAM)"\0");
+            SendMessage (button, BM_CLICK, 0, 0);
+            SendMessage (textfield, WM_SETTEXT, 0, (LPARAM)buffer);
+            free (buffer);
+
+            /* make request for focus moving to filter selector combo-box */
+            HWND curFocus = GetFocus();
+            PostMessage (curFocus, WM_KILLFOCUS, (WPARAM)selector, 0);
+            PostMessage (selector, WM_SETFOCUS, (WPARAM)curFocus, 0);
+            WPARAM wParam = MAKEWPARAM (WA_ACTIVE, 0);
+            PostMessage (selector, WM_ACTIVATE, wParam, (LPARAM)curFocus);
+        }
+    }
+    return FALSE;
+}
+
+/*
+ * Callback function to control the native Win32 API folders dialog
+ */
+static int __stdcall winGetExistDirCallbackProc (HWND hwnd, UINT uMsg,
+                                                 LPARAM lParam, LPARAM lpData)
+{
+    if (uMsg == BFFM_INITIALIZED && lpData != 0)
+    {
+        QString *initDir = (QString *)(lpData);
+        if (!initDir->isEmpty())
+        {
+            SendMessage (hwnd, BFFM_SETSELECTION, TRUE, Q_ULONG (
+                initDir->isNull() ? 0 : initDir->utf16()));
+        }
+    }
+    else if (uMsg == BFFM_SELCHANGED)
+    {
+        TCHAR path [MAX_PATH];
+        SHGetPathFromIDList (LPITEMIDLIST (lParam), path);
+        QString tmpStr = QString::fromUtf16 ((ushort*)path);
+        if (!tmpStr.isEmpty())
+            SendMessage (hwnd, BFFM_ENABLEOK, 1, 1);
+        else
+            SendMessage (hwnd, BFFM_ENABLEOK, 0, 0);
+        SendMessage (hwnd, BFFM_SETSTATUSTEXT, 1, Q_ULONG (path));
+    }
+    return 0;
+}
+
+/**
+ *  QEvent class to carry Win32 API native dialog's result information
+ */
+class OpenNativeDialogEvent : public QEvent
+{
+public:
+
+    OpenNativeDialogEvent (const QString &aResult, QEvent::Type aType)
+        : QEvent (aType), mResult (aResult) {}
+
+    const QString& result() { return mResult; }
+
+private:
+
+    QString mResult;
+};
+
+/**
+ *  QObject class reimplementation which is the target for OpenNativeDialogEvent
+ *  event. It receives OpenNativeDialogEvent event from another thread,
+ *  stores result information and exits the given local event loop.
+ */
+class LoopObject : public QObject
+{
+    Q_OBJECT;
+
+public:
+
+    LoopObject (QEvent::Type aType, QEventLoop &aLoop)
+        : mType (aType), mLoop (aLoop), mResult (QString::null) {}
+    const QString& result() { return mResult; }
+
+private:
+
+    bool event (QEvent *aEvent)
+    {
+        if (aEvent->type() == mType)
+        {
+            OpenNativeDialogEvent *ev = (OpenNativeDialogEvent*) aEvent;
+            mResult = ev->result();
+            mLoop.quit();
+            return true;
+        }
+        return QObject::event (aEvent);
+    }
+
+    QEvent::Type mType;
+    QEventLoop &mLoop;
+    QString mResult;
+};
+
+#endif /* Q_WS_WIN */
+
+QIFileDialog::QIFileDialog (QWidget *aParent, Qt::WindowFlags aFlags)
+    : QFileDialog (aParent, aFlags)
+{
+}
+
+/**
+ *  Reimplementation of QFileDialog::getExistingDirectory() that removes some
+ *  oddities and limitations.
+ *
+ *  On Win32, this function makes sure a native dialog is launched in
+ *  another thread to avoid dialog visualization errors occuring due to
+ *  multi-threaded COM apartment initialization on the main UI thread while
+ *  the appropriate native dialog function expects a single-threaded one.
+ *
+ *  On all other platforms, this function is equivalent to
+ *  QFileDialog::getExistingDirectory().
+ */
+QString QIFileDialog::getExistingDirectory (const QString &aDir,
+                                            QWidget *aParent,
+                                            const QString &aCaption,
+                                            bool aDirOnly,
+                                            bool aResolveSymlinks)
+{
+#if defined Q_WS_WIN
+
+    /**
+     *  QEvent class reimplementation to carry Win32 API
+     *  native dialog's result folder information
+     */
+    class GetExistDirectoryEvent : public OpenNativeDialogEvent
+    {
+    public:
+
+        enum { TypeId = QEvent::User + 1 };
+
+        GetExistDirectoryEvent (const QString &aResult)
+            : OpenNativeDialogEvent (aResult, (QEvent::Type) TypeId) {}
+    };
+
+    /**
+     *  QThread class reimplementation to open Win32 API
+     *  native folder's dialog
+     */
+    class Thread : public QThread
+    {
+    public:
+
+        Thread (QWidget *aParent, QObject *aTarget,
+                const QString &aDir, const QString &aCaption)
+            : mParent (aParent), mTarget (aTarget), mDir (aDir), mCaption (aCaption) {}
+
+        virtual void run()
+        {
+            QString result;
+
+            QWidget *topParent = mParent ? mParent->window() : vboxGlobal().mainWindow();
+            QString title = mCaption.isNull() ? tr ("Select a directory") : mCaption;
+
+            TCHAR path [MAX_PATH];
+            path [0] = 0;
+            TCHAR initPath [MAX_PATH];
+            initPath [0] = 0;
+
+            BROWSEINFO bi;
+            bi.hwndOwner = topParent ? topParent->winId() : 0;
+            bi.pidlRoot = 0;
+            bi.lpszTitle = (TCHAR*)(title.isNull() ? 0 : title.utf16());
+            bi.pszDisplayName = initPath;
+            bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE;
+            bi.lpfn = winGetExistDirCallbackProc;
+            bi.lParam = Q_ULONG (&mDir);
+
+            LPITEMIDLIST itemIdList = SHBrowseForFolder (&bi);
+            if (itemIdList)
+            {
+                SHGetPathFromIDList (itemIdList, path);
+                IMalloc *pMalloc;
+                if (SHGetMalloc (&pMalloc) != NOERROR)
+                    result = QString::null;
+                else
+                {
+                    pMalloc->Free (itemIdList);
+                    pMalloc->Release();
+                    result = QString::fromUtf16 ((ushort*)path);
+                }
+            }
+            else
+                result = QString::null;
+            QApplication::postEvent (mTarget, new GetExistDirectoryEvent (result));
+        }
+
+    private:
+
+        QWidget *mParent;
+        QObject *mTarget;
+        QString mDir;
+        QString mCaption;
+    };
+
+    /* Local event loop to run while waiting for the result from another
+     * thread */
+    QEventLoop loop;
+
+    QString dir = QDir::toNativeSeparators (aDir);
+    LoopObject loopObject ((QEvent::Type) GetExistDirectoryEvent::TypeId, loop);
+
+    Thread openDirThread (aParent, &loopObject, dir, aCaption);
+    openDirThread.start();
+    loop.exec();
+    openDirThread.wait();
+
+    return loopObject.result();
+
+#elif defined (Q_WS_X11) && (QT_VERSION < 0x040400)
+
+    /* Here is workaround for Qt4.3 bug with QFileDialog which crushes when
+     * gets initial path as hidden directory if no hidden files are shown.
+     * See http://trolltech.com/developer/task-tracker/index_html?method=entry&id=193483
+     * for details */
+    QFileDialog dlg (aParent);
+    dlg.setWindowTitle (aCaption);
+    dlg.setDirectory (aDir);
+    dlg.setResolveSymlinks (aResolveSymlinks);
+    dlg.setFileMode (aDirOnly ? QFileDialog::DirectoryOnly : QFileDialog::Directory);
+    QAction *hidden = dlg.findChild <QAction*> ("qt_show_hidden_action");
+    if (hidden)
+    {
+        hidden->trigger();
+        hidden->setVisible (false);
+    }
+    return dlg.exec() ? dlg.selectedFiles() [0] : QString::null;
+
+#else
+
+    QFileDialog::Options o;
+    if (aDirOnly)
+        o = QFileDialog::ShowDirsOnly;
+    if (!aResolveSymlinks)
+        o |= QFileDialog::DontResolveSymlinks;
+    return QFileDialog::getExistingDirectory (aParent, aCaption, aDir, o);
+
+#endif
+}
+
+/**
+ *  Reimplementation of QFileDialog::getSaveFileName() that removes some
+ *  oddities and limitations.
+ *
+ *  On Win32, this function makes sure a file filter is applied automatically
+ *  right after it is selected from the drop-down list, to conform to common
+ *  experience in other applications. Note that currently, @a selectedFilter
+ *  is always set to null on return.
+ *
+ *  On all other platforms, this function is equivalent to
+ *  QFileDialog::getSaveFileName().
+ */
+/* static */
+QString QIFileDialog::getSaveFileName (const QString &aStartWith,
+                                       const QString &aFilters,
+                                       QWidget       *aParent,
+                                       const QString &aCaption,
+                                       QString       *aSelectedFilter /* = 0 */,
+                                       bool           aResolveSymlinks /* = true */)
+{
+#if defined Q_WS_WIN
+
+    /**
+     *  QEvent class reimplementation to carry Win32 API native dialog's
+     *  result folder information
+     */
+    class GetOpenFileNameEvent : public OpenNativeDialogEvent
+    {
+    public:
+
+        enum { TypeId = QEvent::User + 2 };
+
+        GetOpenFileNameEvent (const QString &aResult)
+            : OpenNativeDialogEvent (aResult, (QEvent::Type) TypeId) {}
+    };
+
+    /**
+     *  QThread class reimplementation to open Win32 API native file dialog
+     */
+    class Thread : public QThread
+    {
+    public:
+
+        Thread (QWidget *aParent, QObject *aTarget,
+                const QString &aStartWith, const QString &aFilters,
+                const QString &aCaption) :
+                mParent (aParent), mTarget (aTarget),
+                mStartWith (aStartWith), mFilters (aFilters),
+                mCaption (aCaption) {}
+
+        virtual void run()
+        {
+            QString result;
+
+            QString workDir;
+            QString initSel;
+            QFileInfo fi (mStartWith);
+
+            if (fi.isDir())
+                workDir = mStartWith;
+            else
+            {
+                workDir = fi.absolutePath();
+                initSel = fi.fileName();
+            }
+
+            workDir = QDir::toNativeSeparators (workDir);
+            if (!workDir.endsWith ("\\"))
+                workDir += "\\";
+
+            QString title = mCaption.isNull() ? tr ("Select a file") : mCaption;
+
+            QWidget *topParent = mParent ? mParent->window() : vboxGlobal().mainWindow();
+            QString winFilters = winFilter (mFilters);
+            AssertCompile (sizeof (TCHAR) == sizeof (QChar));
+            TCHAR buf [1024];
+            if (initSel.length() > 0 && initSel.length() < sizeof (buf))
+                memcpy (buf, initSel.isNull() ? 0 : initSel.utf16(),
+                        (initSel.length() + 1) * sizeof (TCHAR));
+            else
+                buf [0] = 0;
+
+            OPENFILENAME ofn;
+            memset (&ofn, 0, sizeof (OPENFILENAME));
+
+            ofn.lStructSize = sizeof (OPENFILENAME);
+            ofn.hwndOwner = topParent ? topParent->winId() : 0;
+            ofn.lpstrFilter = (TCHAR *) winFilters.isNull() ? 0 : winFilters.utf16();
+            ofn.lpstrFile = buf;
+            ofn.nMaxFile = sizeof (buf) - 1;
+            ofn.lpstrInitialDir = (TCHAR *) workDir.isNull() ? 0 : workDir.utf16();
+            ofn.lpstrTitle = (TCHAR *) title.isNull() ? 0 : title.utf16();
+            ofn.Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY |
+                         OFN_EXPLORER | OFN_ENABLEHOOK |
+                         OFN_NOTESTFILECREATE);
+            ofn.lpfnHook = OFNHookProc;
+
+            if (GetSaveFileName (&ofn))
+            {
+                result = QString::fromUtf16 ((ushort *) ofn.lpstrFile);
+            }
+
+            // qt_win_eatMouseMove();
+            MSG msg = {0, 0, 0, 0, 0, 0, 0};
+            while (PeekMessage (&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE));
+            if (msg.message == WM_MOUSEMOVE)
+                PostMessage (msg.hwnd, msg.message, 0, msg.lParam);
+
+            result = result.isEmpty() ? result : QFileInfo (result).absoluteFilePath();
+
+            QApplication::postEvent (mTarget, new GetOpenFileNameEvent (result));
+        }
+
+    private:
+
+        QWidget *mParent;
+        QObject *mTarget;
+        QString mStartWith;
+        QString mFilters;
+        QString mCaption;
+    };
+
+    if (aSelectedFilter)
+        *aSelectedFilter = QString::null;
+
+    /* Local event loop to run while waiting for the result from another
+     * thread */
+    QEventLoop loop;
+
+    QString startWith = QDir::toNativeSeparators (aStartWith);
+    LoopObject loopObject ((QEvent::Type) GetOpenFileNameEvent::TypeId, loop);
+
+    if (aParent)
+        aParent->setWindowModality (Qt::WindowModal);
+
+    Thread openDirThread (aParent, &loopObject, startWith, aFilters, aCaption);
+    openDirThread.start();
+    loop.exec();
+    openDirThread.wait();
+
+    if (aParent)
+        aParent->setWindowModality (Qt::NonModal);
+
+    return loopObject.result();
+
+#elif defined (Q_WS_X11) && (QT_VERSION < 0x040400)
+
+    /* Here is workaround for Qt4.3 bug with QFileDialog which crushes when
+     * gets initial path as hidden directory if no hidden files are shown.
+     * See http://trolltech.com/developer/task-tracker/index_html?method=entry&id=193483
+     * for details */
+    QFileDialog dlg (aParent);
+    dlg.setWindowTitle (aCaption);
+    dlg.setDirectory (aStartWith);
+    dlg.setFilter (aFilters);
+    dlg.setFileMode (QFileDialog::QFileDialog::AnyFile);
+    dlg.setAcceptMode (QFileDialog::AcceptSave);
+    if (aSelectedFilter)
+        dlg.selectFilter (*aSelectedFilter);
+    dlg.setResolveSymlinks (aResolveSymlinks);
+    dlg.setConfirmOverwrite (false);
+    QAction *hidden = dlg.findChild <QAction*> ("qt_show_hidden_action");
+    if (hidden)
+    {
+        hidden->trigger();
+        hidden->setVisible (false);
+    }
+    return dlg.exec() == QDialog::Accepted ? dlg.selectedFiles().value (0, "") : QString::null;
+
+#else
+
+    QFileDialog::Options o;
+    if (!aResolveSymlinks)
+        o |= QFileDialog::DontResolveSymlinks;
+    o |= QFileDialog::DontConfirmOverwrite;
+    return QFileDialog::getSaveFileName (aParent, aCaption, aStartWith,
+                                         aFilters, aSelectedFilter, o);
+#endif
+}
+
+/**
+ *  Reimplementation of QFileDialog::getOpenFileName() that removes some
+ *  oddities and limitations.
+ *
+ *  On Win32, this function makes sure a file filter is applied automatically
+ *  right after it is selected from the drop-down list, to conform to common
+ *  experience in other applications. Note that currently, @a selectedFilter
+ *  is always set to null on return.
+ *
+ *  On all other platforms, this function is equivalent to
+ *  QFileDialog::getOpenFileName().
+ */
+/* static */
+QString QIFileDialog::getOpenFileName (const QString &aStartWith,
+                                       const QString &aFilters,
+                                       QWidget       *aParent,
+                                       const QString &aCaption,
+                                       QString       *aSelectedFilter /* = 0 */,
+                                       bool           aResolveSymlinks /* = true */)
+{
+    return getOpenFileNames (aStartWith,
+                             aFilters,
+                             aParent,
+                             aCaption,
+                             aSelectedFilter,
+                             aResolveSymlinks,
+                             true /* aSingleFile */).value (0, "");
+}
+
+/**
+ *  Reimplementation of QFileDialog::getOpenFileNames() that removes some
+ *  oddities and limitations.
+ *
+ *  On Win32, this function makes sure a file filter is applied automatically
+ *  right after it is selected from the drop-down list, to conform to common
+ *  experience in other applications. Note that currently, @a selectedFilter
+ *  is always set to null on return.
+ *  @todo: implement the multiple file selection on win
+ *  @todo: is this extra handling on win still necessary with Qt4?
+ *
+ *  On all other platforms, this function is equivalent to
+ *  QFileDialog::getOpenFileNames().
+ */
+/* static */
+QStringList QIFileDialog::getOpenFileNames (const QString &aStartWith,
+                                            const QString &aFilters,
+                                            QWidget       *aParent,
+                                            const QString &aCaption,
+                                            QString       *aSelectedFilter /* = 0 */,
+                                            bool           aResolveSymlinks /* = true */,
+                                            bool           aSingleFile /* = false */)
+{
+#if defined Q_WS_WIN
+
+    /**
+     *  QEvent class reimplementation to carry Win32 API native dialog's
+     *  result folder information
+     */
+    class GetOpenFileNameEvent : public OpenNativeDialogEvent
+    {
+    public:
+
+        enum { TypeId = QEvent::User + 3 };
+
+        GetOpenFileNameEvent (const QString &aResult)
+            : OpenNativeDialogEvent (aResult, (QEvent::Type) TypeId) {}
+    };
+
+    /**
+     *  QThread class reimplementation to open Win32 API native file dialog
+     */
+    class Thread : public QThread
+    {
+    public:
+
+        Thread (QWidget *aParent, QObject *aTarget,
+                const QString &aStartWith, const QString &aFilters,
+                const QString &aCaption) :
+                mParent (aParent), mTarget (aTarget),
+                mStartWith (aStartWith), mFilters (aFilters),
+                mCaption (aCaption) {}
+
+        virtual void run()
+        {
+            QString result;
+
+            QString workDir;
+            QString initSel;
+            QFileInfo fi (mStartWith);
+
+            if (fi.isDir())
+                workDir = mStartWith;
+            else
+            {
+                workDir = fi.absolutePath();
+                initSel = fi.fileName();
+            }
+
+            workDir = QDir::toNativeSeparators (workDir);
+            if (!workDir.endsWith ("\\"))
+                workDir += "\\";
+
+            QString title = mCaption.isNull() ? tr ("Select a file") : mCaption;
+
+            QWidget *topParent = mParent ? mParent->window() : vboxGlobal().mainWindow();
+            QString winFilters = winFilter (mFilters);
+            AssertCompile (sizeof (TCHAR) == sizeof (QChar));
+            TCHAR buf [1024];
+            if (initSel.length() > 0 && initSel.length() < sizeof (buf))
+                memcpy (buf, initSel.isNull() ? 0 : initSel.utf16(),
+                        (initSel.length() + 1) * sizeof (TCHAR));
+            else
+                buf [0] = 0;
+
+            OPENFILENAME ofn;
+            memset (&ofn, 0, sizeof (OPENFILENAME));
+
+            ofn.lStructSize = sizeof (OPENFILENAME);
+            ofn.hwndOwner = topParent ? topParent->winId() : 0;
+            ofn.lpstrFilter = (TCHAR *) winFilters.isNull() ? 0 : winFilters.utf16();
+            ofn.lpstrFile = buf;
+            ofn.nMaxFile = sizeof (buf) - 1;
+            ofn.lpstrInitialDir = (TCHAR *) workDir.isNull() ? 0 : workDir.utf16();
+            ofn.lpstrTitle = (TCHAR *) title.isNull() ? 0 : title.utf16();
+            ofn.Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY |
+                          OFN_EXPLORER | OFN_ENABLEHOOK |
+                          OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST);
+            ofn.lpfnHook = OFNHookProc;
+
+            if (GetOpenFileName (&ofn))
+            {
+                result = QString::fromUtf16 ((ushort *) ofn.lpstrFile);
+            }
+
+            // qt_win_eatMouseMove();
+            MSG msg = {0, 0, 0, 0, 0, 0, 0};
+            while (PeekMessage (&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE));
+            if (msg.message == WM_MOUSEMOVE)
+                PostMessage (msg.hwnd, msg.message, 0, msg.lParam);
+
+            result = result.isEmpty() ? result : QFileInfo (result).absoluteFilePath();
+
+            QApplication::postEvent (mTarget, new GetOpenFileNameEvent (result));
+        }
+
+    private:
+
+        QWidget *mParent;
+        QObject *mTarget;
+        QString mStartWith;
+        QString mFilters;
+        QString mCaption;
+    };
+
+    if (aSelectedFilter)
+        *aSelectedFilter = QString::null;
+
+    /* Local event loop to run while waiting for the result from another
+     * thread */
+    QEventLoop loop;
+
+    QString startWith = QDir::toNativeSeparators (aStartWith);
+    LoopObject loopObject ((QEvent::Type) GetOpenFileNameEvent::TypeId, loop);
+
+    if (aParent)
+        aParent->setWindowModality (Qt::WindowModal);
+
+    Thread openDirThread (aParent, &loopObject, startWith, aFilters, aCaption);
+    openDirThread.start();
+    loop.exec();
+    openDirThread.wait();
+
+    if (aParent)
+        aParent->setWindowModality (Qt::NonModal);
+
+    return QStringList() << loopObject.result();
+
+#elif defined (Q_WS_X11) && (QT_VERSION < 0x040400)
+
+    /* Here is workaround for Qt4.3 bug with QFileDialog which crushes when
+     * gets initial path as hidden directory if no hidden files are shown.
+     * See http://trolltech.com/developer/task-tracker/index_html?method=entry&id=193483
+     * for details */
+    QFileDialog dlg (aParent);
+    dlg.setWindowTitle (aCaption);
+    dlg.setDirectory (aStartWith);
+    dlg.setFilter (aFilters);
+    if (aSingleFile)
+        dlg.setFileMode (QFileDialog::ExistingFile);
+    else
+        dlg.setFileMode (QFileDialog::ExistingFiles);
+    if (aSelectedFilter)
+        dlg.selectFilter (*aSelectedFilter);
+    dlg.setResolveSymlinks (aResolveSymlinks);
+    QAction *hidden = dlg.findChild <QAction*> ("qt_show_hidden_action");
+    if (hidden)
+    {
+        hidden->trigger();
+        hidden->setVisible (false);
+    }
+    return dlg.exec() == QDialog::Accepted ? dlg.selectedFiles() : QStringList() << QString::null;
+
+#else
+
+    QFileDialog::Options o;
+    if (!aResolveSymlinks)
+        o |= QFileDialog::DontResolveSymlinks;
+    if (aSingleFile)
+        return QStringList() << QFileDialog::getOpenFileName (aParent, aCaption, aStartWith,
+                                                              aFilters, aSelectedFilter, o);
+    else
+        return QFileDialog::getOpenFileNames (aParent, aCaption, aStartWith,
+                                              aFilters, aSelectedFilter, o);
+#endif
+}
+
+/**
+ *  Search for the first directory that exists starting from the passed one
+ *  and going up through its parents.  In case if none of the directories
+ *  exist (except the root one), the function returns QString::null.
+ */
+/* static */
+QString QIFileDialog::getFirstExistingDir (const QString &aStartDir)
+{
+    QString result = QString::null;
+    QDir dir (aStartDir);
+    while (!dir.exists() && !dir.isRoot())
+    {
+        QFileInfo dirInfo (dir.absolutePath());
+        dir = dirInfo.absolutePath();
+    }
+    if (dir.exists() && !dir.isRoot())
+        result = dir.absolutePath();
+    return result;
+}
+
+#if defined Q_WS_WIN
+#include "QIFileDialog.moc"
+#endif
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp	(revision 20077)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp	(revision 20078)
@@ -21,30 +21,31 @@
  */
 
+/* VBox includes */
 #include "VBoxConsoleWnd.h"
 #include "VBoxConsoleView.h"
 #include "VBoxCloseVMDlg.h"
+#include "VBoxDownloaderWgt.h"
+#include "VBoxGlobal.h"
+#include "VBoxMediaManagerDlg.h"
+#include "VBoxMiniToolBar.h"
+#include "VBoxProblemReporter.h"
 #include "VBoxTakeSnapshotDlg.h"
-#include "VBoxMediaManagerDlg.h"
 #include "VBoxVMFirstRunWzd.h"
 #include "VBoxVMSettingsSF.h"
 #include "VBoxVMInformationDlg.h"
-#include "VBoxDownloaderWgt.h"
-#include "VBoxGlobal.h"
-#include "VBoxProblemReporter.h"
-#include "VBoxMiniToolBar.h"
-
+#include "QIFileDialog.h"
+#include "QIHotKeyEdit.h"
+#include "QIHttp.h"
 #include "QIStateIndicator.h"
 #include "QIStatusBar.h"
-#include "QIHotKeyEdit.h"
-#include "QIHttp.h"
 
 /* Qt includes */
 #include <QActionGroup>
 #include <QDesktopWidget>
+#include <QDir>
+#include <QFileInfo>
 #include <QMenuBar>
-#include <QFileInfo>
-#include <QDir>
+#include <QProgressBar>
 #include <QTimer>
-#include <QProgressBar>
 #ifdef Q_WS_X11
 # include <QX11Info>
@@ -159,5 +160,5 @@
                 }
 
-                QString target = vboxGlobal().getExistingDirectory (
+                QString target = QIFileDialog::getExistingDirectory (
                     QFileInfo (mTarget).absolutePath(), this,
                     tr ("Select folder to save Guest Additions image to"), true);
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFilePathSelectorWidget.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFilePathSelectorWidget.cpp	(revision 20077)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFilePathSelectorWidget.cpp	(revision 20078)
@@ -21,6 +21,8 @@
  */
 
+/* VBox includes */
 #include "VBoxFilePathSelectorWidget.h"
 #include "VBoxGlobal.h"
+#include "QIFileDialog.h"
 #include "QILabel.h"
 
@@ -31,8 +33,8 @@
 #include <QDir>
 #include <QFileIconProvider>
+#include <QFocusEvent>
 #include <QLineEdit>
+#include <QPushButton>
 #include <QTimer>
-#include <QPushButton>
-#include <QFocusEvent>
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -383,5 +385,5 @@
     /* Preparing initial directory. */
     QString initDir = mPath.isNull() ? mHomeDir :
-        VBoxGlobal::getFirstExistingDir (mPath);
+        QIFileDialog::getFirstExistingDir (mPath);
     if (initDir.isNull())
         initDir = mHomeDir;
@@ -391,8 +393,8 @@
     {
         case Mode_File_Open:
-            path = VBoxGlobal::getOpenFileName (initDir, mFileFilters, parentWidget(), mFileDialogTitle); break;
+            path = QIFileDialog::getOpenFileName (initDir, mFileFilters, parentWidget(), mFileDialogTitle); break;
         case Mode_File_Save:
             {
-                path = VBoxGlobal::getSaveFileName (initDir, mFileFilters, parentWidget(), mFileDialogTitle);
+                path = QIFileDialog::getSaveFileName (initDir, mFileFilters, parentWidget(), mFileDialogTitle);
                 if (!path.isEmpty() && QFileInfo (path).suffix().isEmpty())
                     path = QString ("%1.%2").arg (path).arg (mDefaultSaveExt);
@@ -400,5 +402,5 @@
             }
         case Mode_Folder:
-            path = VBoxGlobal::getExistingDirectory (initDir, parentWidget(), mFileDialogTitle); break;
+            path = QIFileDialog::getExistingDirectory (initDir, parentWidget(), mFileDialogTitle); break;
     }
 
@@ -633,9 +635,9 @@
     /* Preparing initial directory. */
     QString initDir = path.isNull() ? mHomeDir :
-        VBoxGlobal::getFirstExistingDir (path);
+        QIFileDialog::getFirstExistingDir (path);
     if (initDir.isNull())
         initDir = mHomeDir;
 
-    path = VBoxGlobal::getOpenFileName (initDir, mFileFilters, parentWidget(), mFileDialogTitle);
+    path = QIFileDialog::getOpenFileName (initDir, mFileFilters, parentWidget(), mFileDialogTitle);
     if (!path.isEmpty())
     {
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp	(revision 20077)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp	(revision 20078)
@@ -485,183 +485,4 @@
 #endif
 
-// Helpers for VBoxGlobal::getOpenFileName() & getExistingDirectory()
-/////////////////////////////////////////////////////////////////////////////
-
-#if defined Q_WS_WIN
-
-extern void qt_enter_modal (QWidget*);
-extern void qt_leave_modal (QWidget*);
-
-static QString extractFilter (const QString &aRawFilter)
-{
-    static const char qt_file_dialog_filter_reg_exp[] =
-        "([a-zA-Z0-9 ]*)\\(([a-zA-Z0-9_.*? +;#\\[\\]]*)\\)$";
-
-    QString result = aRawFilter;
-    QRegExp r (QString::fromLatin1 (qt_file_dialog_filter_reg_exp));
-    int index = r.indexIn (result);
-    if (index >= 0)
-        result = r.cap (2);
-    return result.replace (QChar (' '), QChar (';'));
-}
-
-/**
- * Converts QFileDialog filter list to Win32 API filter list.
- */
-static QString winFilter (const QString &aFilter)
-{
-    QStringList filterLst;
-
-    if (!aFilter.isEmpty())
-    {
-        int i = aFilter.indexOf (";;", 0);
-        QString sep (";;");
-        if (i == -1)
-        {
-            if (aFilter.indexOf ("\n", 0) != -1)
-            {
-                sep = "\n";
-                i = aFilter.indexOf (sep, 0);
-            }
-        }
-
-        filterLst = aFilter.split (sep);
-    }
-
-    QStringList::Iterator it = filterLst.begin();
-    QString winfilters;
-    for (; it != filterLst.end(); ++it)
-    {
-        winfilters += *it;
-        winfilters += QChar::Null;
-        winfilters += extractFilter (*it);
-        winfilters += QChar::Null;
-    }
-    winfilters += QChar::Null;
-    return winfilters;
-}
-
-/*
- * Callback function to control the native Win32 API file dialog
- */
-UINT_PTR CALLBACK OFNHookProc (HWND aHdlg, UINT aUiMsg, WPARAM aWParam, LPARAM aLParam)
-{
-    if (aUiMsg == WM_NOTIFY)
-    {
-        OFNOTIFY *notif = (OFNOTIFY*) aLParam;
-        if (notif->hdr.code == CDN_TYPECHANGE)
-        {
-            /* locate native dialog controls */
-            HWND parent = GetParent (aHdlg);
-            HWND button = GetDlgItem (parent, IDOK);
-            HWND textfield = ::GetDlgItem (parent, cmb13);
-            if (textfield == NULL)
-                textfield = ::GetDlgItem (parent, edt1);
-            if (textfield == NULL)
-                return FALSE;
-            HWND selector = ::GetDlgItem (parent, cmb1);
-
-            /* simulate filter change by pressing apply-key */
-            int    size = 256;
-            TCHAR *buffer = (TCHAR*)malloc (size);
-            SendMessage (textfield, WM_GETTEXT, size, (LPARAM)buffer);
-            SendMessage (textfield, WM_SETTEXT, 0, (LPARAM)"\0");
-            SendMessage (button, BM_CLICK, 0, 0);
-            SendMessage (textfield, WM_SETTEXT, 0, (LPARAM)buffer);
-            free (buffer);
-
-            /* make request for focus moving to filter selector combo-box */
-            HWND curFocus = GetFocus();
-            PostMessage (curFocus, WM_KILLFOCUS, (WPARAM)selector, 0);
-            PostMessage (selector, WM_SETFOCUS, (WPARAM)curFocus, 0);
-            WPARAM wParam = MAKEWPARAM (WA_ACTIVE, 0);
-            PostMessage (selector, WM_ACTIVATE, wParam, (LPARAM)curFocus);
-        }
-    }
-    return FALSE;
-}
-
-/*
- * Callback function to control the native Win32 API folders dialog
- */
-static int __stdcall winGetExistDirCallbackProc (HWND hwnd, UINT uMsg,
-                                                 LPARAM lParam, LPARAM lpData)
-{
-    if (uMsg == BFFM_INITIALIZED && lpData != 0)
-    {
-        QString *initDir = (QString *)(lpData);
-        if (!initDir->isEmpty())
-        {
-            SendMessage (hwnd, BFFM_SETSELECTION, TRUE, Q_ULONG (
-                initDir->isNull() ? 0 : initDir->utf16()));
-            //SendMessage (hwnd, BFFM_SETEXPANDED, TRUE, Q_ULONG (initDir->utf16()));
-        }
-    }
-    else if (uMsg == BFFM_SELCHANGED)
-    {
-        TCHAR path [MAX_PATH];
-        SHGetPathFromIDList (LPITEMIDLIST (lParam), path);
-        QString tmpStr = QString::fromUtf16 ((ushort*)path);
-        if (!tmpStr.isEmpty())
-            SendMessage (hwnd, BFFM_ENABLEOK, 1, 1);
-        else
-            SendMessage (hwnd, BFFM_ENABLEOK, 0, 0);
-        SendMessage (hwnd, BFFM_SETSTATUSTEXT, 1, Q_ULONG (path));
-    }
-    return 0;
-}
-
-/**
- *  QEvent class to carry Win32 API native dialog's result information
- */
-class OpenNativeDialogEvent : public QEvent
-{
-public:
-
-    OpenNativeDialogEvent (const QString &aResult, QEvent::Type aType)
-        : QEvent (aType), mResult (aResult) {}
-
-    const QString& result() { return mResult; }
-
-private:
-
-    QString mResult;
-};
-
-/**
- *  QObject class reimplementation which is the target for OpenNativeDialogEvent
- *  event. It receives OpenNativeDialogEvent event from another thread,
- *  stores result information and exits the given local event loop.
- */
-class LoopObject : public QObject
-{
-public:
-
-    LoopObject (QEvent::Type aType, QEventLoop &aLoop)
-        : mType (aType), mLoop (aLoop), mResult (QString::null) {}
-    const QString& result() { return mResult; }
-
-private:
-
-    bool event (QEvent *aEvent)
-    {
-        if (aEvent->type() == mType)
-        {
-            OpenNativeDialogEvent *ev = (OpenNativeDialogEvent*) aEvent;
-            mResult = ev->result();
-            mLoop.quit();
-            return true;
-        }
-        return QObject::event (aEvent);
-    }
-
-    QEvent::Type mType;
-    QEventLoop &mLoop;
-    QString mResult;
-};
-
-#endif /* Q_WS_WIN */
-
-
 // VBoxGlobal
 ////////////////////////////////////////////////////////////////////////////////
@@ -3971,562 +3792,4 @@
 #endif
     return  QLocale::system().name();
-}
-
-/**
- *  Reimplementation of QFileDialog::getExistingDirectory() that removes some
- *  oddities and limitations.
- *
- *  On Win32, this function makes sure a native dialog is launched in
- *  another thread to avoid dialog visualization errors occuring due to
- *  multi-threaded COM apartment initialization on the main UI thread while
- *  the appropriate native dialog function expects a single-threaded one.
- *
- *  On all other platforms, this function is equivalent to
- *  QFileDialog::getExistingDirectory().
- */
-QString VBoxGlobal::getExistingDirectory (const QString &aDir,
-                                          QWidget *aParent,
-                                          const QString &aCaption,
-                                          bool aDirOnly,
-                                          bool aResolveSymlinks)
-{
-#if defined Q_WS_WIN
-
-    /**
-     *  QEvent class reimplementation to carry Win32 API native dialog's
-     *  result folder information
-     */
-    class GetExistDirectoryEvent : public OpenNativeDialogEvent
-    {
-    public:
-
-        enum { TypeId = QEvent::User + 300 };
-
-        GetExistDirectoryEvent (const QString &aResult)
-            : OpenNativeDialogEvent (aResult, (QEvent::Type) TypeId) {}
-    };
-
-    /**
-     *  QThread class reimplementation to open Win32 API native folder's dialog
-     */
-    class Thread : public QThread
-    {
-    public:
-
-        Thread (QWidget *aParent, QObject *aTarget,
-                const QString &aDir, const QString &aCaption)
-            : mParent (aParent), mTarget (aTarget), mDir (aDir), mCaption (aCaption) {}
-
-        virtual void run()
-        {
-            QString result;
-
-            QWidget *topParent = mParent ? mParent->window() : vboxGlobal().mainWindow();
-            QString title = mCaption.isNull() ? tr ("Select a directory") : mCaption;
-
-            TCHAR path[MAX_PATH];
-            path [0] = 0;
-            TCHAR initPath [MAX_PATH];
-            initPath [0] = 0;
-
-            BROWSEINFO bi;
-            bi.hwndOwner = topParent ? topParent->winId() : 0;
-            bi.pidlRoot = NULL;
-            bi.lpszTitle = (TCHAR*)(title.isNull() ? 0 : title.utf16());
-            bi.pszDisplayName = initPath;
-            bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE;
-            bi.lpfn = winGetExistDirCallbackProc;
-            bi.lParam = Q_ULONG (&mDir);
-
-            LPITEMIDLIST itemIdList = SHBrowseForFolder (&bi);
-            if (itemIdList)
-            {
-                SHGetPathFromIDList (itemIdList, path);
-                IMalloc *pMalloc;
-                if (SHGetMalloc (&pMalloc) != NOERROR)
-                    result = QString::null;
-                else
-                {
-                    pMalloc->Free (itemIdList);
-                    pMalloc->Release();
-                    result = QString::fromUtf16 ((ushort*)path);
-                }
-            }
-            else
-                result = QString::null;
-            QApplication::postEvent (mTarget, new GetExistDirectoryEvent (result));
-        }
-
-    private:
-
-        QWidget *mParent;
-        QObject *mTarget;
-        QString mDir;
-        QString mCaption;
-    };
-
-    /* Local event loop to run while waiting for the result from another
-     * thread */
-    QEventLoop loop;
-
-    QString dir = QDir::toNativeSeparators (aDir);
-    LoopObject loopObject ((QEvent::Type) GetExistDirectoryEvent::TypeId, loop);
-
-    Thread openDirThread (aParent, &loopObject, dir, aCaption);
-    openDirThread.start();
-    loop.exec();
-    openDirThread.wait();
-
-    return loopObject.result();
-
-#elif defined (Q_WS_X11) && (QT_VERSION < 0x040400)
-
-    /* Here is workaround for Qt4.3 bug with QFileDialog which crushes when
-     * gets initial path as hidden directory if no hidden files are shown.
-     * See http://trolltech.com/developer/task-tracker/index_html?method=entry&id=193483
-     * for details */
-    QFileDialog dlg (aParent);
-    dlg.setWindowTitle (aCaption);
-    dlg.setDirectory (aDir);
-    dlg.setResolveSymlinks (aResolveSymlinks);
-    dlg.setFileMode (aDirOnly ? QFileDialog::DirectoryOnly : QFileDialog::Directory);
-    QAction *hidden = dlg.findChild <QAction*> ("qt_show_hidden_action");
-    if (hidden)
-    {
-        hidden->trigger();
-        hidden->setVisible (false);
-    }
-    return dlg.exec() ? dlg.selectedFiles() [0] : QString::null;
-
-#else
-
-    QFileDialog::Options o;
-    if (aDirOnly)
-        o = QFileDialog::ShowDirsOnly;
-    if (!aResolveSymlinks)
-        o |= QFileDialog::DontResolveSymlinks;
-    return QFileDialog::getExistingDirectory (aParent, aCaption, aDir, o);
-
-#endif
-}
-
-/**
- *  Reimplementation of QFileDialog::getSaveFileName() that removes some
- *  oddities and limitations.
- *
- *  On Win32, this function makes sure a file filter is applied automatically
- *  right after it is selected from the drop-down list, to conform to common
- *  experience in other applications. Note that currently, @a selectedFilter
- *  is always set to null on return.
- *
- *  On all other platforms, this function is equivalent to
- *  QFileDialog::getSaveFileName().
- */
-/* static */
-QString VBoxGlobal::getSaveFileName (const QString &aStartWith,
-                                     const QString &aFilters,
-                                     QWidget       *aParent,
-                                     const QString &aCaption,
-                                     QString       *aSelectedFilter /* = NULL */,
-                                     bool           aResolveSymlinks /* = true */)
-{
-#if defined Q_WS_WIN
-
-    /**
-     *  QEvent class reimplementation to carry Win32 API native dialog's
-     *  result folder information
-     */
-    class GetOpenFileNameEvent : public OpenNativeDialogEvent
-    {
-    public:
-
-        enum { TypeId = QEvent::User + 301 };
-
-        GetOpenFileNameEvent (const QString &aResult)
-            : OpenNativeDialogEvent (aResult, (QEvent::Type) TypeId) {}
-    };
-
-    /**
-     *  QThread class reimplementation to open Win32 API native file dialog
-     */
-    class Thread : public QThread
-    {
-    public:
-
-        Thread (QWidget *aParent, QObject *aTarget,
-                const QString &aStartWith, const QString &aFilters,
-                const QString &aCaption) :
-                mParent (aParent), mTarget (aTarget),
-                mStartWith (aStartWith), mFilters (aFilters),
-                mCaption (aCaption) {}
-
-        virtual void run()
-        {
-            QString result;
-
-            QString workDir;
-            QString initSel;
-            QFileInfo fi (mStartWith);
-
-            if (fi.isDir())
-                workDir = mStartWith;
-            else
-            {
-                workDir = fi.absolutePath();
-                initSel = fi.fileName();
-            }
-
-            workDir = QDir::toNativeSeparators (workDir);
-            if (!workDir.endsWith ("\\"))
-                workDir += "\\";
-
-            QString title = mCaption.isNull() ? tr ("Select a file") : mCaption;
-
-            QWidget *topParent = mParent ? mParent->window() : vboxGlobal().mainWindow();
-            QString winFilters = winFilter (mFilters);
-            AssertCompile (sizeof (TCHAR) == sizeof (QChar));
-            TCHAR buf [1024];
-            if (initSel.length() > 0 && initSel.length() < sizeof (buf))
-                memcpy (buf, initSel.isNull() ? 0 : initSel.utf16(),
-                        (initSel.length() + 1) * sizeof (TCHAR));
-            else
-                buf [0] = 0;
-
-            OPENFILENAME ofn;
-            memset (&ofn, 0, sizeof (OPENFILENAME));
-
-            ofn.lStructSize = sizeof (OPENFILENAME);
-            ofn.hwndOwner = topParent ? topParent->winId() : 0;
-            ofn.lpstrFilter = (TCHAR *) winFilters.isNull() ? 0 : winFilters.utf16();
-            ofn.lpstrFile = buf;
-            ofn.nMaxFile = sizeof (buf) - 1;
-            ofn.lpstrInitialDir = (TCHAR *) workDir.isNull() ? 0 : workDir.utf16();
-            ofn.lpstrTitle = (TCHAR *) title.isNull() ? 0 : title.utf16();
-            ofn.Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY |
-                         OFN_EXPLORER | OFN_ENABLEHOOK |
-                         OFN_NOTESTFILECREATE);
-            ofn.lpfnHook = OFNHookProc;
-
-            if (GetSaveFileName (&ofn))
-            {
-                result = QString::fromUtf16 ((ushort *) ofn.lpstrFile);
-            }
-
-            // qt_win_eatMouseMove();
-            MSG msg = {0, 0, 0, 0, 0, 0, 0};
-            while (PeekMessage (&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE));
-            if (msg.message == WM_MOUSEMOVE)
-                PostMessage (msg.hwnd, msg.message, 0, msg.lParam);
-
-            result = result.isEmpty() ? result : QFileInfo (result).absoluteFilePath();
-
-            QApplication::postEvent (mTarget, new GetOpenFileNameEvent (result));
-        }
-
-    private:
-
-        QWidget *mParent;
-        QObject *mTarget;
-        QString mStartWith;
-        QString mFilters;
-        QString mCaption;
-    };
-
-    if (aSelectedFilter)
-        *aSelectedFilter = QString::null;
-
-    /* Local event loop to run while waiting for the result from another
-     * thread */
-    QEventLoop loop;
-
-    QString startWith = QDir::toNativeSeparators (aStartWith);
-    LoopObject loopObject ((QEvent::Type) GetOpenFileNameEvent::TypeId, loop);
-
-//#warning check me!
-    if (aParent)
-        aParent->setWindowModality (Qt::WindowModal);
-
-    Thread openDirThread (aParent, &loopObject, startWith, aFilters, aCaption);
-    openDirThread.start();
-    loop.exec();
-    openDirThread.wait();
-
-//#warning check me!
-    if (aParent)
-        aParent->setWindowModality (Qt::NonModal);
-
-    return loopObject.result();
-
-#elif defined (Q_WS_X11) && (QT_VERSION < 0x040400)
-
-    /* Here is workaround for Qt4.3 bug with QFileDialog which crushes when
-     * gets initial path as hidden directory if no hidden files are shown.
-     * See http://trolltech.com/developer/task-tracker/index_html?method=entry&id=193483
-     * for details */
-    QFileDialog dlg (aParent);
-    dlg.setWindowTitle (aCaption);
-    dlg.setDirectory (aStartWith);
-    dlg.setFilter (aFilters);
-    dlg.setFileMode (QFileDialog::QFileDialog::AnyFile);
-    dlg.setAcceptMode (QFileDialog::AcceptSave);
-    if (aSelectedFilter)
-        dlg.selectFilter (*aSelectedFilter);
-    dlg.setResolveSymlinks (aResolveSymlinks);
-    dlg.setConfirmOverwrite (false);
-    QAction *hidden = dlg.findChild <QAction*> ("qt_show_hidden_action");
-    if (hidden)
-    {
-        hidden->trigger();
-        hidden->setVisible (false);
-    }
-    return dlg.exec() == QDialog::Accepted ? dlg.selectedFiles().value (0, "") : QString::null;
-
-#else
-
-    QFileDialog::Options o;
-    if (!aResolveSymlinks)
-        o |= QFileDialog::DontResolveSymlinks;
-    o |= QFileDialog::DontConfirmOverwrite;
-    return QFileDialog::getSaveFileName (aParent, aCaption, aStartWith,
-                                         aFilters, aSelectedFilter, o);
-#endif
-}
-
-/**
- *  Reimplementation of QFileDialog::getOpenFileName() that removes some
- *  oddities and limitations.
- *
- *  On Win32, this function makes sure a file filter is applied automatically
- *  right after it is selected from the drop-down list, to conform to common
- *  experience in other applications. Note that currently, @a selectedFilter
- *  is always set to null on return.
- *
- *  On all other platforms, this function is equivalent to
- *  QFileDialog::getOpenFileName().
- */
-/* static */
-QString VBoxGlobal::getOpenFileName (const QString &aStartWith,
-                                     const QString &aFilters,
-                                     QWidget       *aParent,
-                                     const QString &aCaption,
-                                     QString       *aSelectedFilter /* = NULL */,
-                                     bool           aResolveSymlinks /* = true */)
-{
-    return getOpenFileNames (aStartWith,
-                             aFilters,
-                             aParent,
-                             aCaption,
-                             aSelectedFilter,
-                             aResolveSymlinks,
-                             true /* aSingleFile */).value (0, "");
-}
-
-/**
- *  Reimplementation of QFileDialog::getOpenFileNames() that removes some
- *  oddities and limitations.
- *
- *  On Win32, this function makes sure a file filter is applied automatically
- *  right after it is selected from the drop-down list, to conform to common
- *  experience in other applications. Note that currently, @a selectedFilter
- *  is always set to null on return.
- *  @todo: implement the multiple file selection on win
- *  @todo: is this extra handling on win still necessary with Qt4?
- *
- *  On all other platforms, this function is equivalent to
- *  QFileDialog::getOpenFileNames().
- */
-/* static */
-QStringList VBoxGlobal::getOpenFileNames (const QString &aStartWith,
-                                          const QString &aFilters,
-                                          QWidget       *aParent,
-                                          const QString &aCaption,
-                                          QString       *aSelectedFilter /* = NULL */,
-                                          bool           aResolveSymlinks /* = true */,
-                                          bool           aSingleFile /* = false */)
-{
-#if defined Q_WS_WIN
-
-    /**
-     *  QEvent class reimplementation to carry Win32 API native dialog's
-     *  result folder information
-     */
-    class GetOpenFileNameEvent : public OpenNativeDialogEvent
-    {
-    public:
-
-        enum { TypeId = QEvent::User + 301 };
-
-        GetOpenFileNameEvent (const QString &aResult)
-            : OpenNativeDialogEvent (aResult, (QEvent::Type) TypeId) {}
-    };
-
-    /**
-     *  QThread class reimplementation to open Win32 API native file dialog
-     */
-    class Thread : public QThread
-    {
-    public:
-
-        Thread (QWidget *aParent, QObject *aTarget,
-                const QString &aStartWith, const QString &aFilters,
-                const QString &aCaption) :
-                mParent (aParent), mTarget (aTarget),
-                mStartWith (aStartWith), mFilters (aFilters),
-                mCaption (aCaption) {}
-
-        virtual void run()
-        {
-            QString result;
-
-            QString workDir;
-            QString initSel;
-            QFileInfo fi (mStartWith);
-
-            if (fi.isDir())
-                workDir = mStartWith;
-            else
-            {
-                workDir = fi.absolutePath();
-                initSel = fi.fileName();
-            }
-
-            workDir = QDir::toNativeSeparators (workDir);
-            if (!workDir.endsWith ("\\"))
-                workDir += "\\";
-
-            QString title = mCaption.isNull() ? tr ("Select a file") : mCaption;
-
-            QWidget *topParent = mParent ? mParent->window() : vboxGlobal().mainWindow();
-            QString winFilters = winFilter (mFilters);
-            AssertCompile (sizeof (TCHAR) == sizeof (QChar));
-            TCHAR buf [1024];
-            if (initSel.length() > 0 && initSel.length() < sizeof (buf))
-                memcpy (buf, initSel.isNull() ? 0 : initSel.utf16(),
-                        (initSel.length() + 1) * sizeof (TCHAR));
-            else
-                buf [0] = 0;
-
-            OPENFILENAME ofn;
-            memset (&ofn, 0, sizeof (OPENFILENAME));
-
-            ofn.lStructSize = sizeof (OPENFILENAME);
-            ofn.hwndOwner = topParent ? topParent->winId() : 0;
-            ofn.lpstrFilter = (TCHAR *) winFilters.isNull() ? 0 : winFilters.utf16();
-            ofn.lpstrFile = buf;
-            ofn.nMaxFile = sizeof (buf) - 1;
-            ofn.lpstrInitialDir = (TCHAR *) workDir.isNull() ? 0 : workDir.utf16();
-            ofn.lpstrTitle = (TCHAR *) title.isNull() ? 0 : title.utf16();
-            ofn.Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY |
-                          OFN_EXPLORER | OFN_ENABLEHOOK |
-                          OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST);
-            ofn.lpfnHook = OFNHookProc;
-
-            if (GetOpenFileName (&ofn))
-            {
-                result = QString::fromUtf16 ((ushort *) ofn.lpstrFile);
-            }
-
-            // qt_win_eatMouseMove();
-            MSG msg = {0, 0, 0, 0, 0, 0, 0};
-            while (PeekMessage (&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE));
-            if (msg.message == WM_MOUSEMOVE)
-                PostMessage (msg.hwnd, msg.message, 0, msg.lParam);
-
-            result = result.isEmpty() ? result : QFileInfo (result).absoluteFilePath();
-
-            QApplication::postEvent (mTarget, new GetOpenFileNameEvent (result));
-        }
-
-    private:
-
-        QWidget *mParent;
-        QObject *mTarget;
-        QString mStartWith;
-        QString mFilters;
-        QString mCaption;
-    };
-
-    if (aSelectedFilter)
-        *aSelectedFilter = QString::null;
-
-    /* Local event loop to run while waiting for the result from another
-     * thread */
-    QEventLoop loop;
-
-    QString startWith = QDir::toNativeSeparators (aStartWith);
-    LoopObject loopObject ((QEvent::Type) GetOpenFileNameEvent::TypeId, loop);
-
-//#warning check me!
-    if (aParent)
-        aParent->setWindowModality (Qt::WindowModal);
-
-    Thread openDirThread (aParent, &loopObject, startWith, aFilters, aCaption);
-    openDirThread.start();
-    loop.exec();
-    openDirThread.wait();
-
-//#warning check me!
-    if (aParent)
-        aParent->setWindowModality (Qt::NonModal);
-
-    return QStringList() << loopObject.result();
-
-#elif defined (Q_WS_X11) && (QT_VERSION < 0x040400)
-
-    /* Here is workaround for Qt4.3 bug with QFileDialog which crushes when
-     * gets initial path as hidden directory if no hidden files are shown.
-     * See http://trolltech.com/developer/task-tracker/index_html?method=entry&id=193483
-     * for details */
-    QFileDialog dlg (aParent);
-    dlg.setWindowTitle (aCaption);
-    dlg.setDirectory (aStartWith);
-    dlg.setFilter (aFilters);
-    if (aSingleFile)
-        dlg.setFileMode (QFileDialog::ExistingFile);
-    else
-        dlg.setFileMode (QFileDialog::ExistingFiles);
-    if (aSelectedFilter)
-        dlg.selectFilter (*aSelectedFilter);
-    dlg.setResolveSymlinks (aResolveSymlinks);
-    QAction *hidden = dlg.findChild <QAction*> ("qt_show_hidden_action");
-    if (hidden)
-    {
-        hidden->trigger();
-        hidden->setVisible (false);
-    }
-    return dlg.exec() == QDialog::Accepted ? dlg.selectedFiles() : QStringList() << QString::null;
-
-#else
-
-    QFileDialog::Options o;
-    if (!aResolveSymlinks)
-        o |= QFileDialog::DontResolveSymlinks;
-    if (aSingleFile)
-        return QStringList() << QFileDialog::getOpenFileName (aParent, aCaption, aStartWith,
-                                                              aFilters, aSelectedFilter, o);
-    else
-        return QFileDialog::getOpenFileNames (aParent, aCaption, aStartWith,
-                                              aFilters, aSelectedFilter, o);
-#endif
-}
-
-/**
- *  Search for the first directory that exists starting from the passed one
- *  and going up through its parents.  In case if none of the directories
- *  exist (except the root one), the function returns QString::null.
- */
-/* static */
-QString VBoxGlobal::getFirstExistingDir (const QString &aStartDir)
-{
-    QString result = QString::null;
-    QDir dir (aStartDir);
-    while (!dir.exists() && !dir.isRoot())
-    {
-        QFileInfo dirInfo (dir.absolutePath());
-        dir = dirInfo.absolutePath();
-    }
-    if (dir.exists() && !dir.isRoot())
-        result = dir.absolutePath();
-    return result;
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxImportApplianceWzd.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxImportApplianceWzd.cpp	(revision 20077)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxImportApplianceWzd.cpp	(revision 20078)
@@ -22,14 +22,15 @@
 
 /* VBox includes */
+#include "VBoxGlobal.h"
 #include "VBoxImportApplianceWzd.h"
-#include "VBoxGlobal.h"
+#include "VBoxProblemReporter.h"
+#include "QIFileDialog.h"
 #include "QIWidgetValidator.h"
-#include "VBoxProblemReporter.h"
 
 /* Qt includes */
+#include <QDialogButtonBox>
 #include <QFileInfo>
-#include <QDialogButtonBox>
+#include <QPrintDialog>
 #include <QPrinter>
-#include <QPrintDialog>
 #include <QTextStream>
 
@@ -100,5 +101,5 @@
 void VBoxImportLicenseViewer::save()
 {
-    QString fileName = vboxGlobal().getSaveFileName (vboxGlobal().documentsPath(), tr("Text (*.txt)"), this, tr("Save license to file..."));
+    QString fileName = QIFileDialog::getSaveFileName (vboxGlobal().documentsPath(), tr("Text (*.txt)"), this, tr("Save license to file..."));
     if (!fileName.isEmpty())
     {
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxLineTextEdit.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxLineTextEdit.cpp	(revision 20077)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxLineTextEdit.cpp	(revision 20078)
@@ -22,14 +22,15 @@
 
 /* VBox includes */
+#include "VBoxGlobal.h"
 #include "VBoxLineTextEdit.h"
-#include "VBoxGlobal.h"
+#include "QIFileDialog.h"
 
 /* Qt includes */
-#include <QPushButton>
-#include <QLineEdit>
 #include <QDialogButtonBox>
 #include <QFile>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QTextEdit>
 #include <QTextStream>
-#include <QTextEdit>
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -81,5 +82,5 @@
 void VBoxTextEditor::open()
 {
-    QString fileName = vboxGlobal().getOpenFileName (vboxGlobal().documentsPath(), tr("Text (*.txt);;All (*.*)"), this, tr("Select a file to open..."));
+    QString fileName = QIFileDialog::getOpenFileName (vboxGlobal().documentsPath(), tr("Text (*.txt);;All (*.*)"), this, tr("Select a file to open..."));
     if (!fileName.isEmpty())
     {
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.cpp	(revision 20077)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.cpp	(revision 20078)
@@ -21,23 +21,25 @@
  */
 
+/* VBox includes */
+#include "VBoxGlobal.h"
 #include "VBoxMediaManagerDlg.h"
-#include "VBoxToolBar.h"
-#include "QILabel.h"
 #include "VBoxNewHDWzd.h"
 #include "VBoxProblemReporter.h"
-#include "VBoxGlobal.h"
+#include "VBoxToolBar.h"
+#include "QIFileDialog.h"
+#include "QILabel.h"
 
 /* Qt includes */
+#include <QCloseEvent>
 #include <QDir>
+#include <QDragEnterEvent>
+#include <QDropEvent>
 #include <QFileInfo>
 #include <QHeaderView>
 #include <QMenuBar>
+#include <QProgressBar>
 #include <QPushButton>
+#include <QTimer>
 #include <QUrl>
-#include <QProgressBar>
-#include <QTimer>
-#include <QCloseEvent>
-#include <QDragEnterEvent>
-#include <QDropEvent>
 
 class AddVDMUrlsEvent: public QEvent
@@ -1047,5 +1049,5 @@
     }
 
-    QStringList files = VBoxGlobal::getOpenFileNames (dir, filter, this, title);
+    QStringList files = QIFileDialog::getOpenFileNames (dir, filter, this, title);
     foreach (QString loc, files)
     {
