VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIFileDialog.cpp

Last change on this file was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.0 KB
RevLine 
[26714]1/* $Id: QIFileDialog.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
[25177]2/** @file
[52727]3 * VBox Qt GUI - Qt extensions: QIFileDialog class implementation.
[25177]4 */
5
6/*
[98103]7 * Copyright (C) 2009-2023 Oracle and/or its affiliates.
[25177]8 *
[96407]9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
[25177]26 */
27
[71356]28/* Qt includes: */
[76606]29#ifdef VBOX_WS_MAC
30# include <QEventLoop>
31#endif
[71356]32
33/* GUI includes: */
[76606]34#include "QIFileDialog.h"
35#include "UIModalWindowManager.h"
[25177]36
[52730]37
[71392]38QIFileDialog::QIFileDialog(QWidget *pParent, Qt::WindowFlags enmFlags)
39 : QFileDialog(pParent, enmFlags)
[25177]40{
41}
42
[71392]43/* static */
44QString QIFileDialog::getExistingDirectory(const QString &strDir,
45 QWidget *pParent,
46 const QString &strCaption,
47 bool fDirOnly,
48 bool fResolveSymLinks)
[25177]49{
[68312]50#ifdef VBOX_WS_MAC
[25177]51
[71392]52 // WORKAROUND:
53 // After 4.5 exec ignores the Qt::Sheet flag.
54 // See "New Ways of Using Dialogs" in http://doc.trolltech.com/qq/QtQuarterly30.pdf why.
55 // We want the old behavior for file-save dialog. Unfortunately there is a bug in Qt 4.5.x
56 // which result in showing the native & the Qt dialog at the same time.
57 QWidget *pRealParent = windowManager().realParentWindow(pParent);
58 QFileDialog dlg(pRealParent);
59 windowManager().registerNewParent(&dlg, pRealParent);
60 dlg.setWindowTitle(strCaption);
61 dlg.setDirectory(strDir);
[94061]62 dlg.setOption(DontResolveSymlinks, !fResolveSymLinks);
63 dlg.setFileMode(QFileDialog::Directory);
64 if (fDirOnly)
65 dlg.setOption(ShowDirsOnly, true);
[25177]66
67 QEventLoop eventLoop;
[68079]68 QObject::connect(&dlg, &QFileDialog::finished,
69 &eventLoop, &QEventLoop::quit);
[25177]70 dlg.open();
71 eventLoop.exec();
72
[51939]73 return dlg.result() == QDialog::Accepted ? dlg.selectedFiles().value(0, QString()) : QString();
[25177]74
[71392]75#else /* !VBOX_WS_MAC */
[25177]76
77 QFileDialog::Options o;
[71392]78 if (fDirOnly)
[31191]79 o |= QFileDialog::ShowDirsOnly;
[71392]80 if (!fResolveSymLinks)
[25177]81 o |= QFileDialog::DontResolveSymlinks;
[71392]82 return QFileDialog::getExistingDirectory(pParent, strCaption, strDir, o);
[25177]83
[71392]84#endif /* !VBOX_WS_MAC */
[25177]85}
86
87/* static */
[71392]88QString QIFileDialog::getSaveFileName(const QString &strStartWith,
89 const QString &strFilters,
90 QWidget *pParent,
91 const QString &strCaption,
92 QString *pStrSelectedFilter /* = 0 */,
93 bool fResolveSymLinks /* = true */,
94 bool fConfirmOverwrite /* = false */)
[25177]95{
[68312]96#ifdef VBOX_WS_MAC
[25177]97
[71392]98 // WORKAROUND:
99 // After 4.5 exec ignores the Qt::Sheet flag.
100 // See "New Ways of Using Dialogs" in http://doc.trolltech.com/qq/QtQuarterly30.pdf why.
101 // We want the old behavior for file-save dialog. Unfortunately there is a bug in Qt 4.5.x
102 // which result in showing the native & the Qt dialog at the same time.
103 QWidget *pRealParent = windowManager().realParentWindow(pParent);
104 QFileDialog dlg(pRealParent);
105 windowManager().registerNewParent(&dlg, pRealParent);
106 dlg.setWindowTitle(strCaption);
[51939]107
108 /* Some predictive algorithm which seems missed in native code. */
[71392]109 QDir dir(strStartWith);
[51939]110 while (!dir.isRoot() && !dir.exists())
111 dir = QDir(QFileInfo(dir.absolutePath()).absolutePath());
112 const QString strDirectory = dir.absolutePath();
113 if (!strDirectory.isNull())
114 dlg.setDirectory(strDirectory);
[71392]115 if (strDirectory != strStartWith)
116 dlg.selectFile(QFileInfo(strStartWith).absoluteFilePath());
[51939]117
[71392]118 dlg.setNameFilter(strFilters);
[51939]119 dlg.setFileMode(QFileDialog::AnyFile);
120 dlg.setAcceptMode(QFileDialog::AcceptSave);
[71392]121 if (pStrSelectedFilter)
122 dlg.selectNameFilter(*pStrSelectedFilter);
[94061]123 dlg.setOption(DontResolveSymlinks, !fResolveSymLinks);
124 dlg.setOption(DontConfirmOverwrite, !fConfirmOverwrite);
[25177]125
126 QEventLoop eventLoop;
[68079]127 QObject::connect(&dlg, &QFileDialog::finished,
128 &eventLoop, &QEventLoop::quit);
[25177]129 dlg.open();
130 eventLoop.exec();
131
[51939]132 return dlg.result() == QDialog::Accepted ? dlg.selectedFiles().value(0, QString()) : QString();
[25177]133
[71392]134#else /* !VBOX_WS_MAC */
[25177]135
136 QFileDialog::Options o;
[71392]137 if (!fResolveSymLinks)
[25177]138 o |= QFileDialog::DontResolveSymlinks;
[38477]139 if (!fConfirmOverwrite)
140 o |= QFileDialog::DontConfirmOverwrite;
[71392]141 return QFileDialog::getSaveFileName(pParent, strCaption, strStartWith,
142 strFilters, pStrSelectedFilter, o);
143
144#endif /* !VBOX_WS_MAC */
[25177]145}
146
147/* static */
[71392]148QString QIFileDialog::getOpenFileName(const QString &strStartWith,
149 const QString &strFilters,
150 QWidget *pParent,
151 const QString &strCaption,
152 QString *pStrSelectedFilter /* = 0 */,
153 bool fResolveSymLinks /* = true */)
[25177]154{
[71392]155 return getOpenFileNames(strStartWith,
156 strFilters,
157 pParent,
158 strCaption,
159 pStrSelectedFilter,
160 fResolveSymLinks,
161 true /* fSingleFile */).value(0, "");
[25177]162}
163
164/* static */
[71392]165QStringList QIFileDialog::getOpenFileNames(const QString &strStartWith,
166 const QString &strFilters,
167 QWidget *pParent,
168 const QString &strCaption,
169 QString *pStrSelectedFilter /* = 0 */,
170 bool fResolveSymLinks /* = true */,
171 bool fSingleFile /* = false */)
[25177]172{
[68312]173#ifdef VBOX_WS_MAC
[25177]174
[71392]175 // WORKAROUND:
176 // After 4.5 exec ignores the Qt::Sheet flag.
177 // See "New Ways of Using Dialogs" in http://doc.trolltech.com/qq/QtQuarterly30.pdf why.
178 // We want the old behavior for file-save dialog. Unfortunately there is a bug in Qt 4.5.x
179 // which result in showing the native & the Qt dialog at the same time.
180 QWidget *pRealParent = windowManager().realParentWindow(pParent);
181 QFileDialog dlg(pRealParent);
182 windowManager().registerNewParent(&dlg, pRealParent);
183 dlg.setWindowTitle(strCaption);
[51939]184
185 /* Some predictive algorithm which seems missed in native code. */
[71392]186 QDir dir(strStartWith);
[51939]187 while (!dir.isRoot() && !dir.exists())
188 dir = QDir(QFileInfo(dir.absolutePath()).absolutePath());
189 const QString strDirectory = dir.absolutePath();
190 if (!strDirectory.isNull())
191 dlg.setDirectory(strDirectory);
[71392]192 if (strDirectory != strStartWith)
193 dlg.selectFile(QFileInfo(strStartWith).absoluteFilePath());
[51939]194
[71392]195 dlg.setNameFilter(strFilters);
196 if (fSingleFile)
[51939]197 dlg.setFileMode(QFileDialog::ExistingFile);
[25177]198 else
[51939]199 dlg.setFileMode(QFileDialog::ExistingFiles);
[71392]200 if (pStrSelectedFilter)
201 dlg.selectNameFilter(*pStrSelectedFilter);
[94061]202 dlg.setOption(DontResolveSymlinks, !fResolveSymLinks);
[25177]203
204 QEventLoop eventLoop;
[68079]205 QObject::connect(&dlg, &QFileDialog::finished,
206 &eventLoop, &QEventLoop::quit);
[25177]207 dlg.open();
208 eventLoop.exec();
209
[51939]210 return dlg.result() == QDialog::Accepted ? dlg.selectedFiles() : QStringList() << QString();
[25177]211
212#else
213
214 QFileDialog::Options o;
[71392]215 if (!fResolveSymLinks)
[25177]216 o |= QFileDialog::DontResolveSymlinks;
[31191]217
[71392]218 if (fSingleFile)
219 return QStringList() << QFileDialog::getOpenFileName(pParent, strCaption, strStartWith,
220 strFilters, pStrSelectedFilter, o);
[25177]221 else
[71392]222 return QFileDialog::getOpenFileNames(pParent, strCaption, strStartWith,
223 strFilters, pStrSelectedFilter, o);
224
[25177]225#endif
226}
227
228/* static */
[71392]229QString QIFileDialog::getFirstExistingDir(const QString &strStartDir)
[25177]230{
[71392]231 QString strResult = QString();
232 QDir dir(strStartDir);
[25177]233 while (!dir.exists() && !dir.isRoot())
234 {
[71392]235 QFileInfo dirInfo(dir.absolutePath());
[36551]236 if (dir == QDir(dirInfo.absolutePath()))
237 break;
[25177]238 dir = dirInfo.absolutePath();
239 }
240 if (dir.exists() && !dir.isRoot())
[71392]241 strResult = dir.absolutePath();
242 return strResult;
[25177]243}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use