Changeset View
Changeset View
Standalone View
Standalone View
src/filechooser.cpp
1 | /* | 1 | /* | ||
---|---|---|---|---|---|
2 | * Copyright © 2016 Red Hat, Inc | 2 | * Copyright © 2016-2018 Red Hat, Inc | ||
3 | * | 3 | * | ||
4 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | 5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | 6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2 of the License, or (at your option) any later version. | 7 | * version 2 of the License, or (at your option) any later version. | ||
8 | * | 8 | * | ||
9 | * This library is distributed in the hope that it will be useful, | 9 | * This library is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * Lesser General Public License for more details. | 12 | * Lesser General Public License for more details. | ||
13 | * | 13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | 14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | 15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
16 | * | 16 | * | ||
17 | * Authors: | 17 | * Authors: | ||
18 | * Jan Grulich <jgrulich@redhat.com> | 18 | * Jan Grulich <jgrulich@redhat.com> | ||
19 | */ | 19 | */ | ||
20 | 20 | | |||
21 | #include "filechooser.h" | 21 | #include "filechooser.h" | ||
22 | 22 | | |||
23 | #include <QDialogButtonBox> | ||||
23 | #include <QDBusMetaType> | 24 | #include <QDBusMetaType> | ||
24 | #include <QDBusArgument> | 25 | #include <QDBusArgument> | ||
25 | #include <QLoggingCategory> | 26 | #include <QLoggingCategory> | ||
26 | #include <QFileDialog> | 27 | #include <QPushButton> | ||
28 | #include <QVBoxLayout> | ||||
29 | #include <QUrl> | ||||
30 | | ||||
27 | #include <KLocalizedString> | 31 | #include <KLocalizedString> | ||
32 | #include <KFileWidget> | ||||
28 | 33 | | |||
29 | Q_LOGGING_CATEGORY(XdgDesktopPortalKdeFileChooser, "xdp-kde-file-chooser") | 34 | Q_LOGGING_CATEGORY(XdgDesktopPortalKdeFileChooser, "xdp-kde-file-chooser") | ||
30 | 35 | | |||
31 | // Keep in sync with qflatpakfiledialog from flatpak-platform-plugin | 36 | // Keep in sync with qflatpakfiledialog from flatpak-platform-plugin | ||
32 | Q_DECLARE_METATYPE(FileChooserPortal::Filter) | 37 | Q_DECLARE_METATYPE(FileChooserPortal::Filter) | ||
33 | Q_DECLARE_METATYPE(FileChooserPortal::Filters) | 38 | Q_DECLARE_METATYPE(FileChooserPortal::Filters) | ||
34 | Q_DECLARE_METATYPE(FileChooserPortal::FilterList) | 39 | Q_DECLARE_METATYPE(FileChooserPortal::FilterList) | ||
35 | Q_DECLARE_METATYPE(FileChooserPortal::FilterListList) | 40 | Q_DECLARE_METATYPE(FileChooserPortal::FilterListList) | ||
Show All 35 Lines | 72 | { | |||
71 | arg >> userVisibleName >> filters; | 76 | arg >> userVisibleName >> filters; | ||
72 | filterList.userVisibleName = userVisibleName; | 77 | filterList.userVisibleName = userVisibleName; | ||
73 | filterList.filters = filters; | 78 | filterList.filters = filters; | ||
74 | arg.endStructure(); | 79 | arg.endStructure(); | ||
75 | 80 | | |||
76 | return arg; | 81 | return arg; | ||
77 | } | 82 | } | ||
78 | 83 | | |||
84 | FileDialog::FileDialog(QDialog *parent, Qt::WindowFlags flags) | ||||
85 | : QDialog(parent, flags) | ||||
86 | , m_fileWidget(new KFileWidget(QUrl(), this)) | ||||
87 | { | ||||
88 | setLayout(new QVBoxLayout); | ||||
89 | layout()->addWidget(m_fileWidget); | ||||
90 | | ||||
91 | m_buttons = new QDialogButtonBox(this); | ||||
92 | m_buttons->addButton(m_fileWidget->okButton(), QDialogButtonBox::AcceptRole); | ||||
93 | m_buttons->addButton(m_fileWidget->cancelButton(), QDialogButtonBox::RejectRole); | ||||
94 | connect(m_buttons, SIGNAL(rejected()), m_fileWidget, SLOT(slotCancel())); | ||||
95 | connect(m_fileWidget->okButton(), SIGNAL(clicked(bool)), m_fileWidget, SLOT(slotOk())); | ||||
96 | connect(m_fileWidget, SIGNAL(accepted()), m_fileWidget, SLOT(accept())); | ||||
97 | connect(m_fileWidget, SIGNAL(accepted()), SLOT(accept())); | ||||
98 | connect(m_fileWidget->cancelButton(), SIGNAL(clicked(bool)), SLOT(reject())); | ||||
99 | layout()->addWidget(m_buttons); | ||||
100 | } | ||||
101 | | ||||
102 | FileDialog::~FileDialog() | ||||
103 | { | ||||
104 | } | ||||
105 | | ||||
79 | FileChooserPortal::FileChooserPortal(QObject *parent) | 106 | FileChooserPortal::FileChooserPortal(QObject *parent) | ||
80 | : QDBusAbstractAdaptor(parent) | 107 | : QDBusAbstractAdaptor(parent) | ||
81 | { | 108 | { | ||
82 | qDBusRegisterMetaType<Filter>(); | 109 | qDBusRegisterMetaType<Filter>(); | ||
83 | qDBusRegisterMetaType<Filters>(); | 110 | qDBusRegisterMetaType<Filters>(); | ||
84 | qDBusRegisterMetaType<FilterList>(); | 111 | qDBusRegisterMetaType<FilterList>(); | ||
85 | qDBusRegisterMetaType<FilterListList>(); | 112 | qDBusRegisterMetaType<FilterListList>(); | ||
86 | } | 113 | } | ||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Line(s) | 168 | for (const Filter &filterStruct : filterList.filters) { | |||
142 | if (filterStruct.type == 0) { | 169 | if (filterStruct.type == 0) { | ||
143 | filterStrings << filterStruct.filterString; | 170 | filterStrings << filterStruct.filterString; | ||
144 | } else { | 171 | } else { | ||
145 | mimeTypeFilters << filterStruct.filterString; | 172 | mimeTypeFilters << filterStruct.filterString; | ||
146 | } | 173 | } | ||
147 | } | 174 | } | ||
148 | 175 | | |||
149 | if (!filterStrings.isEmpty()) { | 176 | if (!filterStrings.isEmpty()) { | ||
150 | nameFilters << QStringLiteral("%1 (%2)").arg(filterList.userVisibleName).arg(filterStrings.join(QLatin1String(" "))); | 177 | nameFilters << QStringLiteral("%1|%2").arg(filterStrings.join(QLatin1Char(' '))).arg(filterList.userVisibleName); | ||
151 | } | 178 | } | ||
152 | } | 179 | } | ||
153 | } | 180 | } | ||
154 | 181 | | |||
155 | QFileDialog *fileDialog = new QFileDialog(); | 182 | FileDialog *fileDialog = new FileDialog(); | ||
156 | fileDialog->setWindowTitle(title); | 183 | fileDialog->setWindowTitle(title); | ||
157 | fileDialog->setModal(modalDialog); | 184 | fileDialog->setModal(modalDialog); | ||
158 | fileDialog->setFileMode(multipleFiles ? QFileDialog::ExistingFiles : QFileDialog::ExistingFile); | 185 | fileDialog->m_fileWidget->setMode(multipleFiles ? KFile::Mode::File | KFile::Mode::ExistingOnly : KFile::Mode::Files | KFile::Mode::ExistingOnly); | ||
159 | fileDialog->setLabelText(QFileDialog::Accept, !acceptLabel.isEmpty() ? acceptLabel : i18n("Open")); | 186 | fileDialog->m_fileWidget->okButton()->setText(!acceptLabel.isEmpty() ? acceptLabel : i18n("Open")); | ||
160 | 187 | | |||
161 | if (!nameFilters.isEmpty()) { | 188 | if (!nameFilters.isEmpty()) { | ||
162 | fileDialog->setNameFilters(nameFilters); | 189 | fileDialog->m_fileWidget->setFilter(nameFilters.join(QLatin1Char('\n'))); | ||
163 | } | 190 | } | ||
164 | 191 | | |||
165 | if (!mimeTypeFilters.isEmpty()) { | 192 | if (!mimeTypeFilters.isEmpty()) { | ||
166 | fileDialog->setMimeTypeFilters(mimeTypeFilters); | 193 | fileDialog->m_fileWidget->setMimeFilter(mimeTypeFilters); | ||
167 | } | 194 | } | ||
168 | 195 | | |||
169 | if (fileDialog->exec() == QDialog::Accepted) { | 196 | if (fileDialog->exec() == QDialog::Accepted) { | ||
170 | QStringList files; | 197 | QStringList files; | ||
171 | for (const QString &filename : fileDialog->selectedFiles()) { | 198 | for (const QString &filename : fileDialog->m_fileWidget->selectedFiles()) { | ||
172 | QUrl url = QUrl::fromLocalFile(filename); | 199 | QUrl url = QUrl::fromLocalFile(filename); | ||
173 | files << url.toDisplayString(); | 200 | files << url.toDisplayString(); | ||
174 | } | 201 | } | ||
175 | results.insert(QLatin1String("uris"), files); | 202 | results.insert(QLatin1String("uris"), files); | ||
176 | fileDialog->deleteLater(); | 203 | fileDialog->deleteLater(); | ||
177 | return 0; | 204 | return 0; | ||
178 | } | 205 | } | ||
179 | 206 | | |||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Line(s) | 260 | for (const Filter &filterStruct : filterList.filters) { | |||
234 | if (filterStruct.type == 0) { | 261 | if (filterStruct.type == 0) { | ||
235 | filterStrings << filterStruct.filterString; | 262 | filterStrings << filterStruct.filterString; | ||
236 | } else { | 263 | } else { | ||
237 | mimeTypeFilters << filterStruct.filterString; | 264 | mimeTypeFilters << filterStruct.filterString; | ||
238 | } | 265 | } | ||
239 | } | 266 | } | ||
240 | 267 | | |||
241 | if (!filterStrings.isEmpty()) { | 268 | if (!filterStrings.isEmpty()) { | ||
242 | nameFilters << QStringLiteral("%1 (%2)").arg(filterList.userVisibleName).arg(filterStrings.join(QLatin1String(" "))); | 269 | nameFilters << QStringLiteral("%1|%2").arg(filterStrings.join(QLatin1Char(' '))).arg(filterList.userVisibleName); | ||
243 | } | 270 | } | ||
244 | } | 271 | } | ||
245 | } | 272 | } | ||
246 | 273 | | |||
247 | QFileDialog *fileDialog = new QFileDialog(); | 274 | FileDialog *fileDialog = new FileDialog(); | ||
248 | fileDialog->setWindowTitle(title); | 275 | fileDialog->setWindowTitle(title); | ||
249 | fileDialog->setModal(modalDialog); | 276 | fileDialog->setModal(modalDialog); | ||
250 | fileDialog->setAcceptMode(QFileDialog::AcceptSave); | 277 | fileDialog->m_fileWidget->setOperationMode(KFileWidget::Saving); | ||
251 | 278 | | |||
252 | if (!currentFolder.isEmpty()) { | 279 | if (!currentFolder.isEmpty()) { | ||
253 | fileDialog->setDirectoryUrl(QUrl(currentFolder)); | 280 | fileDialog->m_fileWidget->setUrl(QUrl::fromLocalFile(currentFolder)); | ||
254 | } | 281 | } | ||
255 | 282 | | |||
256 | if (!currentFile.isEmpty()) { | 283 | if (!currentFile.isEmpty()) { | ||
257 | fileDialog->selectFile(currentFile); | 284 | fileDialog->m_fileWidget->setSelectedUrl(QUrl::fromLocalFile(currentFile)); | ||
258 | } | 285 | } | ||
259 | 286 | | |||
260 | if (!currentName.isEmpty()) { | 287 | if (!currentName.isEmpty()) { | ||
261 | fileDialog->selectFile(currentName); | 288 | QUrl url = fileDialog->m_fileWidget->baseUrl(); | ||
289 | fileDialog->m_fileWidget->setSelectedUrl(QUrl::fromLocalFile(QStringLiteral("%1/%2").arg(url.toDisplayString(QUrl::StripTrailingSlash)).arg(currentName))); | ||||
davidedmundson: .arg(QString,QString) not arg(QString).arg(QString)
It can change behaviour if the first… | |||||
262 | } | 290 | } | ||
263 | 291 | | |||
264 | if (!acceptLabel.isEmpty()) { | 292 | if (!acceptLabel.isEmpty()) { | ||
265 | fileDialog->setLabelText(QFileDialog::Accept, acceptLabel); | 293 | fileDialog->m_fileWidget->okButton()->setText(acceptLabel); | ||
266 | } | 294 | } | ||
267 | 295 | | |||
268 | if (!nameFilters.isEmpty()) { | 296 | if (!nameFilters.isEmpty()) { | ||
269 | fileDialog->setNameFilters(nameFilters); | 297 | fileDialog->m_fileWidget->setFilter(nameFilters.join(QLatin1Char('\n'))); | ||
270 | } | 298 | } | ||
271 | 299 | | |||
272 | if (!mimeTypeFilters.isEmpty()) { | 300 | if (!mimeTypeFilters.isEmpty()) { | ||
273 | fileDialog->setMimeTypeFilters(mimeTypeFilters); | 301 | fileDialog->m_fileWidget->setMimeFilter(mimeTypeFilters); | ||
274 | } | 302 | } | ||
275 | 303 | | |||
276 | if (fileDialog->exec() == QDialog::Accepted) { | 304 | if (fileDialog->exec() == QDialog::Accepted) { | ||
davidedmundson: https://blogs.kde.org/2009/03/26/how-crash-almost-every-qtkde-application-and-how-fix-it-0 | |||||
277 | QStringList files; | 305 | QStringList files; | ||
278 | for (const QString &filename : fileDialog->selectedFiles()) { | 306 | QUrl url = QUrl::fromLocalFile(fileDialog->m_fileWidget->selectedFile()); | ||
davidedmundson: const | |||||
279 | QUrl url = QUrl::fromLocalFile(filename); | | |||
280 | files << url.toDisplayString(); | 307 | files << url.toDisplayString(); | ||
281 | } | | |||
282 | results.insert(QLatin1String("uris"), files); | 308 | results.insert(QLatin1String("uris"), files); | ||
283 | fileDialog->deleteLater(); | 309 | fileDialog->deleteLater(); | ||
284 | return 0; | 310 | return 0; | ||
285 | } | 311 | } | ||
286 | 312 | | |||
287 | fileDialog->deleteLater(); | 313 | fileDialog->deleteLater(); | ||
288 | return 1; | 314 | return 1; | ||
289 | } | 315 | } | ||
290 | 316 | |
.arg(QString,QString) not arg(QString).arg(QString)
It can change behaviour if the first inserted string contains the literal "%2"