- Timestamp:
- Aug 7, 2017 9:28:10 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIFileDialog.cpp
r68079 r68312 236 236 bool aResolveSymlinks) 237 237 { 238 #if defined(VBOX_WS_WIN) && (QT_VERSION < 0x050000) 239 240 /** 241 * QEvent class reimplementation to carry Win32 API 242 * native dialog's result folder information 243 */ 244 class GetExistDirectoryEvent : public OpenNativeDialogEvent 245 { 246 public: 247 248 enum { TypeId = QEvent::User + 1 }; 249 250 GetExistDirectoryEvent (const QString &aResult) 251 : OpenNativeDialogEvent (aResult, (QEvent::Type) TypeId) {} 252 }; 253 254 /** 255 * QThread class reimplementation to open Win32 API 256 * native folder's dialog 257 */ 258 class Thread : public QThread 259 { 260 public: 261 262 Thread (QWidget *aParent, QObject *aTarget, 263 const QString &aDir, const QString &aCaption) 264 : mParent (aParent), mTarget (aTarget), mDir (aDir), mCaption (aCaption) {} 265 266 virtual void run() 267 { 268 QString result; 269 270 QWidget *topParent = windowManager().realParentWindow(mParent ? mParent : windowManager().mainWindowShown()); 271 QString title = mCaption.isNull() ? tr ("Select a directory") : mCaption; 272 273 TCHAR path [MAX_PATH]; 274 path [0] = 0; 275 TCHAR initPath [MAX_PATH]; 276 initPath [0] = 0; 277 278 BROWSEINFO bi; 279 bi.hwndOwner = topParent ? topParent->winId() : 0; 280 bi.pidlRoot = 0; 281 bi.lpszTitle = (TCHAR*)(title.isNull() ? 0 : title.utf16()); 282 bi.pszDisplayName = initPath; 283 bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE; 284 bi.lpfn = winGetExistDirCallbackProc; 285 bi.lParam = uintptr_t(&mDir); 286 287 LPITEMIDLIST itemIdList = SHBrowseForFolder (&bi); 288 if (itemIdList) 289 { 290 SHGetPathFromIDList (itemIdList, path); 291 IMalloc *pMalloc; 292 if (SHGetMalloc (&pMalloc) != NOERROR) 293 result = QString::null; 294 else 295 { 296 pMalloc->Free (itemIdList); 297 pMalloc->Release(); 298 result = QString::fromUtf16 ((ushort*)path); 299 } 300 } 301 else 302 result = QString::null; 303 QApplication::postEvent (mTarget, new GetExistDirectoryEvent (result)); 304 } 305 306 private: 307 308 QWidget *mParent; 309 QObject *mTarget; 310 QString mDir; 311 QString mCaption; 312 }; 313 314 /* Local event loop to run while waiting for the result from another 315 * thread */ 316 QEventLoop loop; 317 318 QString dir = QDir::toNativeSeparators (aDir); 319 LoopObject loopObject ((QEvent::Type) GetExistDirectoryEvent::TypeId, loop); 320 321 Thread openDirThread (aParent, &loopObject, dir, aCaption); 322 openDirThread.start(); 323 loop.exec(); 324 openDirThread.wait(); 325 326 return loopObject.result(); 327 328 #elif defined (VBOX_WS_X11) && (QT_VERSION < 0x040400) 329 330 /* Here is workaround for Qt4.3 bug with QFileDialog which crushes when 331 * gets initial path as hidden directory if no hidden files are shown. 332 * See http://trolltech.com/developer/task-tracker/index_html?method=entry&id=193483 333 * for details */ 334 QFileDialog dlg (aParent); 335 dlg.setWindowTitle (aCaption); 336 dlg.setDirectory (aDir); 337 dlg.setResolveSymlinks (aResolveSymlinks); 338 dlg.setFileMode (aDirOnly ? QFileDialog::DirectoryOnly : QFileDialog::Directory); 339 QAction *hidden = dlg.findChild <QAction*> ("qt_show_hidden_action"); 340 if (hidden) 341 { 342 hidden->trigger(); 343 hidden->setVisible (false); 344 } 345 return dlg.exec() ? dlg.selectedFiles() [0] : QString::null; 346 #elif defined (VBOX_WS_MAC) && (QT_VERSION >= 0x040600) 238 #ifdef VBOX_WS_MAC 347 239 348 240 /* After 4.5 exec ignores the Qt::Sheet flag. … … 404 296 bool fConfirmOverwrite /* = false */) 405 297 { 406 #if defined(VBOX_WS_WIN) && (QT_VERSION < 0x050000) 407 408 /* Further code (WinAPI call to GetSaveFileName() in other thread) 409 * seems not necessary any more since the MS COM issue has been fixed, 410 * we can just call for the default QFileDialog::getSaveFileName(): */ 411 Q_UNUSED(aResolveSymlinks); 412 QFileDialog::Options o; 413 if (!fConfirmOverwrite) 414 o |= QFileDialog::DontConfirmOverwrite; 415 return QFileDialog::getSaveFileName(aParent, aCaption, aStartWith, 416 aFilters, aSelectedFilter, o); 417 418 /** 419 * QEvent class reimplementation to carry Win32 API native dialog's 420 * result folder information 421 */ 422 class GetOpenFileNameEvent : public OpenNativeDialogEvent 423 { 424 public: 425 426 enum { TypeId = QEvent::User + 2 }; 427 428 GetOpenFileNameEvent (const QString &aResult) 429 : OpenNativeDialogEvent (aResult, (QEvent::Type) TypeId) {} 430 }; 431 432 /** 433 * QThread class reimplementation to open Win32 API native file dialog 434 */ 435 class Thread : public QThread 436 { 437 public: 438 439 Thread (QWidget *aParent, QObject *aTarget, 440 const QString &aStartWith, const QString &aFilters, 441 const QString &aCaption, bool fConfirmOverwrite) : 442 mParent (aParent), mTarget (aTarget), 443 mStartWith (aStartWith), mFilters (aFilters), 444 mCaption (aCaption), 445 m_fConfirmOverwrite(fConfirmOverwrite) {} 446 447 virtual void run() 448 { 449 QString result; 450 451 QString workDir; 452 QString initSel; 453 QFileInfo fi (mStartWith); 454 455 if (fi.isDir()) 456 workDir = mStartWith; 457 else 458 { 459 workDir = fi.absolutePath(); 460 initSel = fi.fileName(); 461 } 462 463 workDir = QDir::toNativeSeparators (workDir); 464 if (!workDir.endsWith ("\\")) 465 workDir += "\\"; 466 467 QString title = mCaption.isNull() ? tr ("Select a file") : mCaption; 468 469 QWidget *topParent = windowManager().realParentWindow(mParent ? mParent : windowManager().mainWindowShown()); 470 QString winFilters = winFilter (mFilters); 471 AssertCompile (sizeof (TCHAR) == sizeof (QChar)); 472 TCHAR buf [1024]; 473 if (initSel.length() > 0 && initSel.length() < sizeof (buf)) 474 memcpy (buf, initSel.isNull() ? 0 : initSel.utf16(), 475 (initSel.length() + 1) * sizeof (TCHAR)); 476 else 477 buf [0] = 0; 478 479 OPENFILENAME ofn; 480 memset (&ofn, 0, sizeof (OPENFILENAME)); 481 482 ofn.lStructSize = sizeof (OPENFILENAME); 483 ofn.hwndOwner = topParent ? topParent->winId() : 0; 484 ofn.lpstrFilter = (TCHAR *)(winFilters.isNull() ? 0 : winFilters.utf16()); 485 ofn.lpstrFile = buf; 486 ofn.nMaxFile = sizeof (buf) - 1; 487 ofn.lpstrInitialDir = (TCHAR *)(workDir.isNull() ? 0 : workDir.utf16()); 488 ofn.lpstrTitle = (TCHAR *)(title.isNull() ? 0 : title.utf16()); 489 ofn.Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | 490 OFN_EXPLORER | OFN_ENABLEHOOK | 491 OFN_NOTESTFILECREATE | (m_fConfirmOverwrite ? OFN_OVERWRITEPROMPT : 0)); 492 ofn.lpfnHook = OFNHookProc; 493 494 if (GetSaveFileName (&ofn)) 495 { 496 result = QString::fromUtf16 ((ushort *) ofn.lpstrFile); 497 } 498 499 // qt_win_eatMouseMove(); 500 MSG msg = {0, 0, 0, 0, 0, 0, 0}; 501 while (PeekMessage (&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)); 502 if (msg.message == WM_MOUSEMOVE) 503 PostMessage (msg.hwnd, msg.message, 0, msg.lParam); 504 505 result = result.isEmpty() ? result : QFileInfo (result).absoluteFilePath(); 506 507 QApplication::postEvent (mTarget, new GetOpenFileNameEvent (result)); 508 } 509 510 private: 511 512 QWidget *mParent; 513 QObject *mTarget; 514 QString mStartWith; 515 QString mFilters; 516 QString mCaption; 517 bool m_fConfirmOverwrite; 518 }; 519 520 if (aSelectedFilter) 521 *aSelectedFilter = QString::null; 522 523 /* Local event loop to run while waiting for the result from another 524 * thread */ 525 QEventLoop loop; 526 527 QString startWith = QDir::toNativeSeparators (aStartWith); 528 LoopObject loopObject ((QEvent::Type) GetOpenFileNameEvent::TypeId, loop); 529 530 if (aParent) 531 aParent->setWindowModality (Qt::WindowModal); 532 533 Thread openDirThread (aParent, &loopObject, startWith, aFilters, aCaption, fConfirmOverwrite); 534 openDirThread.start(); 535 loop.exec(); 536 openDirThread.wait(); 537 538 if (aParent) 539 aParent->setWindowModality (Qt::NonModal); 540 541 return loopObject.result(); 542 543 #elif defined (VBOX_WS_X11) && (QT_VERSION < 0x040400) 544 545 /* Here is workaround for Qt4.3 bug with QFileDialog which crushes when 546 * gets initial path as hidden directory if no hidden files are shown. 547 * See http://trolltech.com/developer/task-tracker/index_html?method=entry&id=193483 548 * for details */ 549 QFileDialog dlg (aParent); 550 dlg.setWindowTitle (aCaption); 551 dlg.setDirectory (aStartWith); 552 dlg.setFilter (aFilters); 553 dlg.setFileMode (QFileDialog::QFileDialog::AnyFile); 554 dlg.setAcceptMode (QFileDialog::AcceptSave); 555 if (aSelectedFilter) 556 dlg.selectFilter (*aSelectedFilter); 557 dlg.setResolveSymlinks (aResolveSymlinks); 558 dlg.setConfirmOverwrite (fConfirmOverwrite); 559 QAction *hidden = dlg.findChild <QAction*> ("qt_show_hidden_action"); 560 if (hidden) 561 { 562 hidden->trigger(); 563 hidden->setVisible (false); 564 } 565 return dlg.exec() == QDialog::Accepted ? dlg.selectedFiles().value (0, "") : QString::null; 566 567 #elif defined (VBOX_WS_MAC) && (QT_VERSION >= 0x040600) && (QT_VERSION < 0x050000) 298 #ifdef VBOX_WS_MAC 568 299 569 300 /* After 4.5 exec ignores the Qt::Sheet flag. … … 588 319 dlg.setAcceptMode(QFileDialog::AcceptSave); 589 320 if (aSelectedFilter) 590 dlg.select Filter(*aSelectedFilter);321 dlg.selectNameFilter(*aSelectedFilter); 591 322 dlg.setResolveSymlinks(aResolveSymlinks); 592 323 dlg.setConfirmOverwrite(fConfirmOverwrite); … … 671 402 bool aSingleFile /* = false */) 672 403 { 673 /* It seems, running QFileDialog in separate thread is NOT needed under windows any more: */ 674 #if defined (VBOX_WS_WIN) && (QT_VERSION < 0x040403) 675 676 /** 677 * QEvent class reimplementation to carry Win32 API native dialog's 678 * result folder information 679 */ 680 class GetOpenFileNameEvent : public OpenNativeDialogEvent 681 { 682 public: 683 684 enum { TypeId = QEvent::User + 3 }; 685 686 GetOpenFileNameEvent (const QString &aResult) 687 : OpenNativeDialogEvent (aResult, (QEvent::Type) TypeId) {} 688 }; 689 690 /** 691 * QThread class reimplementation to open Win32 API native file dialog 692 */ 693 class Thread : public QThread 694 { 695 public: 696 697 Thread (QWidget *aParent, QObject *aTarget, 698 const QString &aStartWith, const QString &aFilters, 699 const QString &aCaption) : 700 mParent (aParent), mTarget (aTarget), 701 mStartWith (aStartWith), mFilters (aFilters), 702 mCaption (aCaption) {} 703 704 virtual void run() 705 { 706 QString result; 707 708 QString workDir; 709 QString initSel; 710 QFileInfo fi (mStartWith); 711 712 if (fi.isDir()) 713 workDir = mStartWith; 714 else 715 { 716 workDir = fi.absolutePath(); 717 initSel = fi.fileName(); 718 } 719 720 workDir = QDir::toNativeSeparators (workDir); 721 if (!workDir.endsWith ("\\")) 722 workDir += "\\"; 723 724 QString title = mCaption.isNull() ? tr ("Select a file") : mCaption; 725 726 QWidget *topParent = windowManager().realParentWindow(mParent ? mParent : windowManager().mainWindowShown()); 727 QString winFilters = winFilter (mFilters); 728 AssertCompile (sizeof (TCHAR) == sizeof (QChar)); 729 TCHAR buf [1024]; 730 if (initSel.length() > 0 && initSel.length() < sizeof (buf)) 731 memcpy (buf, initSel.isNull() ? 0 : initSel.utf16(), 732 (initSel.length() + 1) * sizeof (TCHAR)); 733 else 734 buf [0] = 0; 735 736 OPENFILENAME ofn; 737 memset (&ofn, 0, sizeof (OPENFILENAME)); 738 739 ofn.lStructSize = sizeof (OPENFILENAME); 740 ofn.hwndOwner = topParent ? topParent->winId() : 0; 741 ofn.lpstrFilter = (TCHAR *)(winFilters.isNull() ? 0 : winFilters.utf16()); 742 ofn.lpstrFile = buf; 743 ofn.nMaxFile = sizeof (buf) - 1; 744 ofn.lpstrInitialDir = (TCHAR *)(workDir.isNull() ? 0 : workDir.utf16()); 745 ofn.lpstrTitle = (TCHAR *)(title.isNull() ? 0 : title.utf16()); 746 ofn.Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | 747 OFN_EXPLORER | OFN_ENABLEHOOK | 748 OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST); 749 ofn.lpfnHook = OFNHookProc; 750 751 if (GetOpenFileName (&ofn)) 752 { 753 result = QString::fromUtf16 ((ushort *) ofn.lpstrFile); 754 } 755 756 // qt_win_eatMouseMove(); 757 MSG msg = {0, 0, 0, 0, 0, 0, 0}; 758 while (PeekMessage (&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)); 759 if (msg.message == WM_MOUSEMOVE) 760 PostMessage (msg.hwnd, msg.message, 0, msg.lParam); 761 762 result = result.isEmpty() ? result : QFileInfo (result).absoluteFilePath(); 763 764 QApplication::postEvent (mTarget, new GetOpenFileNameEvent (result)); 765 } 766 767 private: 768 769 QWidget *mParent; 770 QObject *mTarget; 771 QString mStartWith; 772 QString mFilters; 773 QString mCaption; 774 }; 775 776 if (aSelectedFilter) 777 *aSelectedFilter = QString::null; 778 779 /* Local event loop to run while waiting for the result from another 780 * thread */ 781 QEventLoop loop; 782 783 QString startWith = QDir::toNativeSeparators (aStartWith); 784 LoopObject loopObject ((QEvent::Type) GetOpenFileNameEvent::TypeId, loop); 785 786 if (aParent) 787 aParent->setWindowModality (Qt::WindowModal); 788 789 Thread openDirThread (aParent, &loopObject, startWith, aFilters, aCaption); 790 openDirThread.start(); 791 loop.exec(); 792 openDirThread.wait(); 793 794 if (aParent) 795 aParent->setWindowModality (Qt::NonModal); 796 797 return QStringList() << loopObject.result(); 798 799 #elif defined (VBOX_WS_X11) && (QT_VERSION < 0x040400) 800 801 /* Here is workaround for Qt4.3 bug with QFileDialog which crushes when 802 * gets initial path as hidden directory if no hidden files are shown. 803 * See http://trolltech.com/developer/task-tracker/index_html?method=entry&id=193483 804 * for details */ 805 QFileDialog dlg (aParent); 806 dlg.setWindowTitle (aCaption); 807 dlg.setDirectory (aStartWith); 808 dlg.setFilter (aFilters); 809 if (aSingleFile) 810 dlg.setFileMode (QFileDialog::ExistingFile); 811 else 812 dlg.setFileMode (QFileDialog::ExistingFiles); 813 if (aSelectedFilter) 814 dlg.selectFilter (*aSelectedFilter); 815 dlg.setResolveSymlinks (aResolveSymlinks); 816 QAction *hidden = dlg.findChild <QAction*> ("qt_show_hidden_action"); 817 if (hidden) 818 { 819 hidden->trigger(); 820 hidden->setVisible (false); 821 } 822 return dlg.exec() == QDialog::Accepted ? dlg.selectedFiles() : QStringList() << QString::null; 823 824 #elif defined (VBOX_WS_MAC) && (QT_VERSION >= 0x040600) && (QT_VERSION < 0x050000) 404 #ifdef VBOX_WS_MAC 825 405 826 406 /* After 4.5 exec ignores the Qt::Sheet flag. … … 847 427 dlg.setFileMode(QFileDialog::ExistingFiles); 848 428 if (aSelectedFilter) 849 dlg.select Filter(*aSelectedFilter);429 dlg.selectNameFilter(*aSelectedFilter); 850 430 dlg.setResolveSymlinks(aResolveSymlinks); 851 431
Note:
See TracChangeset
for help on using the changeset viewer.