VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 16 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
Line 
1/* $Id: QIFileDialog.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - Qt extensions: QIFileDialog class implementation.
4 */
5
6/*
7 * Copyright (C) 2009-2023 Oracle and/or its affiliates.
8 *
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
26 */
27
28/* Qt includes: */
29#ifdef VBOX_WS_MAC
30# include <QEventLoop>
31#endif
32
33/* GUI includes: */
34#include "QIFileDialog.h"
35#include "UIModalWindowManager.h"
36
37
38QIFileDialog::QIFileDialog(QWidget *pParent, Qt::WindowFlags enmFlags)
39 : QFileDialog(pParent, enmFlags)
40{
41}
42
43/* static */
44QString QIFileDialog::getExistingDirectory(const QString &strDir,
45 QWidget *pParent,
46 const QString &strCaption,
47 bool fDirOnly,
48 bool fResolveSymLinks)
49{
50#ifdef VBOX_WS_MAC
51
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);
62 dlg.setOption(DontResolveSymlinks, !fResolveSymLinks);
63 dlg.setFileMode(QFileDialog::Directory);
64 if (fDirOnly)
65 dlg.setOption(ShowDirsOnly, true);
66
67 QEventLoop eventLoop;
68 QObject::connect(&dlg, &QFileDialog::finished,
69 &eventLoop, &QEventLoop::quit);
70 dlg.open();
71 eventLoop.exec();
72
73 return dlg.result() == QDialog::Accepted ? dlg.selectedFiles().value(0, QString()) : QString();
74
75#else /* !VBOX_WS_MAC */
76
77 QFileDialog::Options o;
78 if (fDirOnly)
79 o |= QFileDialog::ShowDirsOnly;
80 if (!fResolveSymLinks)
81 o |= QFileDialog::DontResolveSymlinks;
82 return QFileDialog::getExistingDirectory(pParent, strCaption, strDir, o);
83
84#endif /* !VBOX_WS_MAC */
85}
86
87/* static */
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 */)
95{
96#ifdef VBOX_WS_MAC
97
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);
107
108 /* Some predictive algorithm which seems missed in native code. */
109 QDir dir(strStartWith);
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);
115 if (strDirectory != strStartWith)
116 dlg.selectFile(QFileInfo(strStartWith).absoluteFilePath());
117
118 dlg.setNameFilter(strFilters);
119 dlg.setFileMode(QFileDialog::AnyFile);
120 dlg.setAcceptMode(QFileDialog::AcceptSave);
121 if (pStrSelectedFilter)
122 dlg.selectNameFilter(*pStrSelectedFilter);
123 dlg.setOption(DontResolveSymlinks, !fResolveSymLinks);
124 dlg.setOption(DontConfirmOverwrite, !fConfirmOverwrite);
125
126 QEventLoop eventLoop;
127 QObject::connect(&dlg, &QFileDialog::finished,
128 &eventLoop, &QEventLoop::quit);
129 dlg.open();
130 eventLoop.exec();
131
132 return dlg.result() == QDialog::Accepted ? dlg.selectedFiles().value(0, QString()) : QString();
133
134#else /* !VBOX_WS_MAC */
135
136 QFileDialog::Options o;
137 if (!fResolveSymLinks)
138 o |= QFileDialog::DontResolveSymlinks;
139 if (!fConfirmOverwrite)
140 o |= QFileDialog::DontConfirmOverwrite;
141 return QFileDialog::getSaveFileName(pParent, strCaption, strStartWith,
142 strFilters, pStrSelectedFilter, o);
143
144#endif /* !VBOX_WS_MAC */
145}
146
147/* static */
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 */)
154{
155 return getOpenFileNames(strStartWith,
156 strFilters,
157 pParent,
158 strCaption,
159 pStrSelectedFilter,
160 fResolveSymLinks,
161 true /* fSingleFile */).value(0, "");
162}
163
164/* static */
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 */)
172{
173#ifdef VBOX_WS_MAC
174
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);
184
185 /* Some predictive algorithm which seems missed in native code. */
186 QDir dir(strStartWith);
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);
192 if (strDirectory != strStartWith)
193 dlg.selectFile(QFileInfo(strStartWith).absoluteFilePath());
194
195 dlg.setNameFilter(strFilters);
196 if (fSingleFile)
197 dlg.setFileMode(QFileDialog::ExistingFile);
198 else
199 dlg.setFileMode(QFileDialog::ExistingFiles);
200 if (pStrSelectedFilter)
201 dlg.selectNameFilter(*pStrSelectedFilter);
202 dlg.setOption(DontResolveSymlinks, !fResolveSymLinks);
203
204 QEventLoop eventLoop;
205 QObject::connect(&dlg, &QFileDialog::finished,
206 &eventLoop, &QEventLoop::quit);
207 dlg.open();
208 eventLoop.exec();
209
210 return dlg.result() == QDialog::Accepted ? dlg.selectedFiles() : QStringList() << QString();
211
212#else
213
214 QFileDialog::Options o;
215 if (!fResolveSymLinks)
216 o |= QFileDialog::DontResolveSymlinks;
217
218 if (fSingleFile)
219 return QStringList() << QFileDialog::getOpenFileName(pParent, strCaption, strStartWith,
220 strFilters, pStrSelectedFilter, o);
221 else
222 return QFileDialog::getOpenFileNames(pParent, strCaption, strStartWith,
223 strFilters, pStrSelectedFilter, o);
224
225#endif
226}
227
228/* static */
229QString QIFileDialog::getFirstExistingDir(const QString &strStartDir)
230{
231 QString strResult = QString();
232 QDir dir(strStartDir);
233 while (!dir.exists() && !dir.isRoot())
234 {
235 QFileInfo dirInfo(dir.absolutePath());
236 if (dir == QDir(dirInfo.absolutePath()))
237 break;
238 dir = dirInfo.absolutePath();
239 }
240 if (dir.exists() && !dir.isRoot())
241 strResult = dir.absolutePath();
242 return strResult;
243}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use