VirtualBox

Changeset 1790 in vbox


Ignore:
Timestamp:
Mar 29, 2007 10:42:05 AM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
19967
Message:

1902: "Select Directory" dialogs are not native:

New Win32 API wrapper for native windows file dialog implemented.
It allows avoid issue about “files disappearing after new file-filter selected”.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h

    r1767 r1790  
    338338    bool startMachine (const QUuid &id);
    339339
     340    QString getOpenFileName (const QString &, const QString &, QWidget*, const char*,
     341                             const QString &, QString *defaultFilter = 0,
     342                             bool resolveSymLinks = true);
     343
    340344    void startEnumeratingMedia();
    341345
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp

    r1767 r1790  
    3333#include <qiconset.h>
    3434#include <qwidgetlist.h>
     35#include <qfiledialog.h>
    3536
    3637#include <qfileinfo.h>
     
    289290NS_IMPL_THREADSAFE_ISUPPORTS1_CI (VBoxCallback, IVirtualBoxCallback)
    290291#endif
     292
     293#if defined Q_WS_WIN
     294/*
     295 * These definitions are used for Win32 API native dialog displaying.
     296 */
     297extern void qt_enter_modal (QWidget*);
     298extern void qt_leave_modal (QWidget*);
     299const char qt_file_dialog_filter_reg_exp[] = "([a-zA-Z0-9 ]*)\\(([a-zA-Z0-9_.*? +;#\\[\\]]*)\\)$";
     300
     301/*
     302 * This static function made for convenience using QFileDialog filter
     303 * format with our own Win32 native dialog. It composes QStringList of
     304 * filters for Win32 API.
     305 */
     306static QStringList makeFiltersList (const QString &aFilter)
     307{
     308    if (aFilter.isEmpty())
     309        return QStringList();
     310
     311    int i = aFilter.find (";;", 0);
     312    QString sep (";;");
     313    if (i == -1)
     314    {
     315        if (aFilter.find ("\n", 0) != -1)
     316        {
     317            sep = "\n";
     318            i = aFilter.find (sep, 0);
     319        }
     320    }
     321
     322    return QStringList::split (sep, aFilter);
     323}
     324
     325/*
     326 * This static function made for convenience using QFileDialog filter
     327 * format with our own Win32 native dialog. It converts filter from
     328 * QFileDialog format into Win32 API format.
     329 */
     330static QString extractFilter (const QString &aRawFilter)
     331{
     332    QString result = aRawFilter;
     333    QRegExp r (QString::fromLatin1 (qt_file_dialog_filter_reg_exp));
     334    int index = r.search (result);
     335    if (index >= 0)
     336        result = r.cap (2);
     337    return result.replace (QChar (' '), QChar (';'));
     338}
     339
     340/*
     341 * This static function made for convenience using QFileDialog filter
     342 * format with our own Win32 native dialog. This is wrapper used for
     343 * all QFileDialog filter converting into Win32 API format.
     344 */
     345static QString winFilter (const QString &aFilter)
     346{
     347    QStringList filterLst = makeFiltersList (aFilter);
     348    QStringList::Iterator it = filterLst.begin();
     349    QString winfilters;
     350    for (; it != filterLst.end(); ++it)
     351    {
     352        winfilters += *it;
     353        winfilters += QChar::null;
     354        winfilters += extractFilter (*it);
     355        winfilters += QChar::null;
     356    }
     357    winfilters += QChar::null;
     358    return winfilters;
     359}
     360
     361/*
     362 * This Win32 API callback function made for control using native
     363 * Win32 API dialog. It handles the situation of switching this dialog
     364 * from one file filter mode to another.
     365 */
     366UINT CALLBACK OFNHookProc (HWND aHdlg, UINT aUiMsg, WPARAM aWParam, LPARAM aLParam)
     367{
     368    if (aUiMsg == WM_NOTIFY)
     369    {
     370        OFNOTIFY *notif = (OFNOTIFY*) aLParam;
     371        if (notif->hdr.code == CDN_TYPECHANGE)
     372        {
     373            /* locating native dialog controls */
     374            HWND parent = GetParent (aHdlg);
     375            HWND button = GetDlgItem (parent, IDOK);
     376            HWND textfield = ::GetDlgItem (parent, cmb13);
     377            if (textfield == NULL)
     378                textfield = ::GetDlgItem (parent, edt1);
     379            if (textfield == NULL)
     380                return FALSE;
     381            HWND selector = ::GetDlgItem (parent, cmb1);
     382
     383            /* simulate filter change by pressing apply-key */
     384            int    size = 256;
     385            TCHAR *buffer = (TCHAR*)malloc (size);
     386            SendMessage (textfield, WM_GETTEXT, size, (LPARAM)buffer);
     387            SendMessage (textfield, WM_SETTEXT, 0, (LPARAM)"\0");
     388            SendMessage (button, BM_CLICK, 0, 0);
     389            SendMessage (textfield, WM_SETTEXT, 0, (LPARAM)buffer);
     390            free (buffer);
     391
     392            /* making request for focus moving to filter selector combo-box */
     393            HWND curFocus = GetFocus();
     394            PostMessage (curFocus, WM_KILLFOCUS, (WPARAM)selector, 0);
     395            PostMessage (selector, WM_SETFOCUS, (WPARAM)curFocus, 0);
     396            WPARAM wParam = MAKEWPARAM (WA_ACTIVE, 0);
     397            PostMessage (selector, WM_ACTIVATE, wParam, (LPARAM)curFocus);
     398        }
     399    }
     400    return FALSE;
     401}
     402
     403/*
     404 * This static function made for convenience using native Win32 API dialog.
     405 * This is function is used for composing settings for Win32 API native dialog.
     406 */
     407static OPENFILENAME* makeOFN (QWidget* parent,
     408                              const QString& initialSelection,
     409                              const QString& initialDirectory,
     410                              const QString& title,
     411                              const QString& filters,
     412                              QFileDialog::Mode mode)
     413{
     414    parent = parent ? parent->topLevelWidget() : qApp->mainWidget();
     415
     416    static QString tFilters = filters;
     417    QString tInitDir = QDir::convertSeparators (initialDirectory);
     418    QString initSel = QDir::convertSeparators (initialSelection);
     419    int maxLen = 1023;
     420    TCHAR *tInitSel = new TCHAR [maxLen+1];
     421    if (initSel.length() > 0 && initSel.length() <= (uint)maxLen)
     422        memcpy (tInitSel, initSel.ucs2(), (initSel.length()+1)*sizeof (QChar));
     423    else
     424        tInitSel[0] = 0;
     425
     426    OPENFILENAME* ofn = new OPENFILENAME;
     427    memset (ofn, 0, sizeof (OPENFILENAME));
     428
     429    ofn->lStructSize    = sizeof(OPENFILENAME);
     430    ofn->hwndOwner  = parent ? parent->winId() : 0;
     431    ofn->lpstrFilter    = (TCHAR *)tFilters.ucs2();
     432    ofn->lpstrFile  = tInitSel;
     433    ofn->nMaxFile   = maxLen;
     434    ofn->lpstrInitialDir = (TCHAR *)tInitDir.ucs2();
     435    ofn->lpstrTitle = (TCHAR *)title.ucs2();
     436    ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY |
     437                  OFN_EXPLORER | OFN_ENABLEHOOK |
     438                  OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST);
     439    ofn->lpfnHook = OFNHookProc;
     440    return ofn;
     441}
     442
     443/*
     444 * This static function made for convenience using native Win32 API dialog.
     445 * This is function is used for cleaning settings for Win32 API native dialog.
     446 */
     447static void cleanUpOFN (OPENFILENAME** ofn)
     448{
     449    delete (*ofn)->lpstrFile;
     450    delete *ofn;
     451    *ofn = 0;
     452}
     453#endif
     454
    291455
    292456// VBoxGlobal
     
    499663
    500664    return *console_wnd;
     665}
     666
     667QString VBoxGlobal::getOpenFileName (const QString &startWith,
     668                                                  const QString &filter,
     669                                                  QWidget       *parent,
     670                                                  const char    *name,
     671                                                  const QString &caption,
     672                                                  QString       *selectedFilter,
     673                                                  bool           resolveSymlinks )
     674{
     675#if defined Q_WS_WIN
     676    QString result;
     677    QFileInfo fi (startWith);
     678    QString workingDirectory = fi.exists() ? fi.dirPath (TRUE) : QDir::homeDirPath();
     679    QString initialSelection = fi.isFile() ? fi.fileName() : QString::null;
     680    QString title = caption.isNull() ? tr ("Select file to open") : caption;
     681
     682    if (parent)
     683    {
     684        QEvent e (QEvent::WindowBlocked);
     685        QApplication::sendEvent (parent, &e);
     686        qt_enter_modal (parent);
     687    }
     688
     689    OPENFILENAME* ofn = makeOFN (parent, initialSelection,
     690                                 workingDirectory, title,
     691                                 winFilter (filter), QFileDialog::ExistingFile);
     692    if (GetOpenFileName (ofn))
     693    {
     694        result = QString::fromUcs2 ((ushort*)ofn->lpstrFile);
     695    }
     696    cleanUpOFN (&ofn);
     697
     698    if (parent)
     699    {
     700        qt_leave_modal (parent);
     701        QEvent e (QEvent::WindowUnblocked);
     702        QApplication::sendEvent (parent, &e);
     703    }
     704
     705    // qt_win_eatMouseMove();
     706    MSG msg = {0, 0, 0, 0, 0, 0, 0};
     707    while (PeekMessage (&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE));
     708    if (msg.message == WM_MOUSEMOVE)
     709        PostMessage (msg.hwnd, msg.message, 0, msg.lParam);
     710
     711    return result.isEmpty() ? result : QFileInfo (result).absFilePath();
     712#else
     713    return QFileDialog::getOpenFileName (startWith, filter, parent, name,
     714                                         caption, selectedFilter, resolveSymlinks );
     715#endif
    501716}
    502717
     
    13711586}
    13721587
    1373 /** 
     1588/**
    13741589 * Opens the specified URL using OS/Desktop capabilities.
    1375  * 
     1590 *
    13761591 * @param aURL URL to open
    1377  * 
     1592 *
    13781593 * @return true on success and false otherwise
    13791594 */
  • trunk/src/VBox/Frontends/VirtualBox/ui/VBoxDiskImageManagerDlg.ui

    r1726 r1790  
    499499<includes>
    500500    <include location="global" impldecl="in implementation">qapplication.h</include>
    501     <include location="global" impldecl="in implementation">qfiledialog.h</include>
    502501    <include location="global" impldecl="in implementation">qprogressdialog.h</include>
    503502    <include location="global" impldecl="in implementation">qfocusdata.h</include>
  • trunk/src/VBox/Frontends/VirtualBox/ui/VBoxDiskImageManagerDlg.ui.h

    r1726 r1790  
    18291829    }
    18301830
    1831     QString src = QFileDialog::getOpenFileName (dir, filter,
    1832                                                 this, "AddDiskImageDialog",
    1833                                                 title);
     1831    QString src = vboxGlobal().getOpenFileName (dir, filter, this,
     1832                                                "AddDiskImageDialog", title);
    18341833    src =  QDir::convertSeparators (src);
    18351834
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette