87 if (!defaultDir.isEmpty()) {
88 if (
d->defaultDirectory.isEmpty() || force) {
89 QFileInfo f(defaultDir);
91 d->defaultDirectory = defaultDir;
94 d->defaultDirectory = f.absolutePath();
97 if (!QFileInfo(defaultDir).isDir()) {
98 d->proposedFileName = QFileInfo(defaultDir).fileName();
141 if (!
d->defaultUri.isEmpty()) {
142 d->fileDialog->setDirectoryUrl(
d->defaultUri);
149 connect(
d->fileDialog.get(), SIGNAL(urlSelected (
const QUrl&)), bookmarkmngr, SLOT(addBookmarkAndCheckParentDir(
const QUrl&)));
153 KConfigGroup group = KSharedConfig::openConfig()->group(
"File Dialogs");
155 bool dontUseNative =
true;
157 dontUseNative =
false;
160 if (qgetenv(
"XDG_CURRENT_DESKTOP") ==
"KDE") {
161 dontUseNative =
false;
165 dontUseNative =
false;
168 dontUseNative =
false;
171 bool optionDontUseNative;
172 if (!qEnvironmentVariable(
"APPIMAGE").isEmpty()) {
174 optionDontUseNative =
false;
176 optionDontUseNative = group.readEntry(
"DontUseNativeFileDialog", dontUseNative);
179 d->fileDialog->setOption(QFileDialog::DontUseNativeDialog, optionDontUseNative);
180 d->fileDialog->setOption(QFileDialog::DontConfirmOverwrite,
false);
181 d->fileDialog->setOption(QFileDialog::HideNameFilterDetails, dontUseNative ?
true :
false);
186 QUrl volumes = QUrl::fromLocalFile(
"/Volumes");
187 if (!urls.contains(volumes)) {
188 urls.append(volumes);
191 d->fileDialog->setSidebarUrls(urls);
195 d->fileDialog->setAcceptMode(QFileDialog::AcceptSave);
196 d->fileDialog->setFileMode(QFileDialog::AnyFile);
200 d->fileDialog->setAcceptMode(QFileDialog::AcceptOpen);
203 d->fileDialog->setFileMode(QFileDialog::Directory);
204 d->fileDialog->setOption(QFileDialog::ShowDirsOnly,
true);
209 d->fileDialog->setFileMode(QFileDialog::ExistingFile);
212 d->fileDialog->setFileMode(QFileDialog::ExistingFiles);
218 d->fileDialog->setNameFilters(
d->filterList);
220 if (!
d->proposedFileName.isEmpty()) {
224 Q_FOREACH(
const QString &filter,
d->filterList) {
225 if (filter.startsWith(description)) {
226 d->fileDialog->selectNameFilter(filter);
231 else if (!
d->defaultFilter.isEmpty()) {
232 d->fileDialog->selectNameFilter(
d->defaultFilter);
240 bool allowModal =
true;
243 allowModal = optionDontUseNative;
252 d->fileDialog->setWindowModality(Qt::WindowModal);
255 d->fileDialog->resetIconProvider();
268 QString extension =
".kra";
269 QInputDialog mimeSelector;
270 mimeSelector.setLabelText(i18n(
"Save As:"));
271 mimeSelector.setComboBoxItems(
d->filterList);
272 mimeSelector.setOkButtonText(KStandardGuiItem::ok().text());
273 mimeSelector.setCancelButtonText(KStandardGuiItem::cancel().text());
275 mimeSelector.setOption(QInputDialog::UseListViewForComboBoxItems);
277 if (mimeSelector.exec() == QDialog::Accepted) {
278 const QString selectedFilter = mimeSelector.textValue();
279 int start = selectedFilter.indexOf(
"*.") + 1;
280 int end = selectedFilter.indexOf(
" ", start);
282 extension = selectedFilter.mid(start, n);
283 if (!extension.startsWith(
".")) {
284 extension =
"." + extension;
286 d->fileDialog->selectNameFilter(selectedFilter);
288 const QString proposedFileBaseName = QFileInfo(
d->proposedFileName).baseName();
290 d->fileDialog->setWindowTitle(proposedFileBaseName.isEmpty() ? QString(
"Untitled" + extension)
291 : proposedFileBaseName + extension);
301 if (
d->fileDialog->exec() == QDialog::Accepted) {
302 url =
d->fileDialog->selectedFiles().first();
312 const QString suffix = QFileInfo(url).suffix();
313 bool isValidSuffix =
true;
315 warnWidgetUtils <<
"Selected file name suffix" << suffix <<
"does not match known MIME types";
316 isValidSuffix =
false;
319 if (
d->type ==
SaveFile && (suffix.isEmpty() || !isValidSuffix)) {
321 if (
d->suffixes.contains(
d->fileDialog->selectedNameFilter())) {
322 extension =
d->suffixes[
d->fileDialog->selectedNameFilter()];
323 if (!extension.isEmpty()) {
332 url.append(
'.').append(extension);
333 d->fileDialog->selectFile(url);
336 if (extension.isEmpty()) {
338 QString selectedFilter;
340 for (
int i = 1; i <
d->filterList.size(); ++i) {
341 if (
d->filterList[i].startsWith(
d->fileDialog->selectedNameFilter())) {
342 selectedFilter =
d->filterList[i];
346 int start = selectedFilter.indexOf(
"*.") + 2;
347 int end = selectedFilter.indexOf(
" ", start);
348 if (start != -1 + 2 && end != -1) {
349 extension = selectedFilter.mid(start, end - start);
352 QMessageBox::warning(
d->parent,
d->caption,
353 i18n(
"The selected file name does not have a file extension that Krita understands.\n"
354 "Make sure the file name ends in '.%1' for example.", extension));
358#if !(defined(Q_OS_MACOS) || defined(Q_OS_ANDROID))
359 url = url + extension;
363 }
while (retryNeeded);
365 if (!url.isEmpty()) {
421 constexpr bool withAllSupportedEntry =
true;
426 QString descriptionOnly;
428 QString defaultSuffix;
433 QString allSupported;
435 FilterData kritaNative {};
441 bool hasAllFilesFilter =
false;
446 Q_FOREACH(
const QString &
mimeType, mimeList) {
448 if (
mimeType == QLatin1String(
"application/octet-stream")) {
451 hasAllFilesFilter =
true;
456 if (description.isEmpty() && !
mimeType.isEmpty()) {
457 description =
mimeType.split(
"/")[1];
458 if (description.startsWith(
"x-")) {
459 description = description.remove(0, 2);
471 Q_FOREACH(
const QString &suffix,
suffixes) {
472 const QString glob = QStringLiteral(
"*.") + suffix;
473 oneFilter.append(glob +
" ");
474 if (withAllSupportedEntry) {
475 allSupported.append(glob +
" ");
478 if (qgetenv(
"XDG_CURRENT_DESKTOP") ==
"GNOME") {
479 oneFilter.append(glob.toUpper() +
" ");
480 if (withAllSupportedEntry) {
481 allSupported.append(glob.toUpper() +
" ");
487 Q_ASSERT(!description.isEmpty());
489 FilterData filterData {};
490 filterData.descriptionOnly = description;
491 filterData.fullLine = description +
" ( " + oneFilter +
")";
492 filterData.defaultSuffix =
suffixes.first();
494 if (
mimeType == QLatin1String(
"application/x-krita")) {
495 kritaNative = filterData;
496 }
else if (
mimeType == QLatin1String(
"image/openraster")) {
499 otherFileTypes.append(filterData);
502 debugWidgetUtils <<
"KoFileDialog: Matched default MIME type to filter" << filterData.fullLine;
510 QMap<QString, QString> retFilterToSuffixMap;
511 auto addFilterItem = [&](
const FilterData &filterData) {
512 if (retFilterList.contains(filterData.fullLine)) {
513 debugWidgetUtils <<
"KoFileDialog: Duplicated filter" << filterData.fullLine;
516 retFilterList.append(filterData.fullLine);
518 retFilterToSuffixMap.insert(filterData.descriptionOnly, filterData.defaultSuffix);
520 retFilterToSuffixMap.insert(filterData.fullLine, filterData.defaultSuffix);
523 if (!allSupported.isEmpty()) {
524 FilterData allFilter {};
525 if (allSupported.contains(
"*.kra")) {
526 allSupported.remove(
"*.kra ");
527 allSupported.prepend(
"*.kra ");
528 allFilter.defaultSuffix = QStringLiteral(
"kra");
530 const QString suffixToMove = QString(
"*.") +
defaultFilter.defaultSuffix +
" ";
531 allSupported.remove(suffixToMove);
532 allSupported.prepend(suffixToMove);
536 warnWidgetUtils <<
"KoFileDialog: No default suffix for 'All supported formats'";
537 allFilter.defaultSuffix = QStringLiteral(
"");
539 allFilter.descriptionOnly = i18n(
"All supported formats");
540 allFilter.fullLine = allFilter.descriptionOnly +
" ( " + allSupported +
")";
541 addFilterItem(allFilter);
543 if (!kritaNative.fullLine.isEmpty()) {
544 addFilterItem(kritaNative);
546 if (!ora.fullLine.isEmpty()) {
550 std::sort(otherFileTypes.begin(), otherFileTypes.end(), [](
const FilterData &a,
const FilterData &b) {
551 return a.descriptionOnly < b.descriptionOnly;
553 Q_FOREACH(
const FilterData &filterData, otherFileTypes) {
554 addFilterItem(filterData);
557 if (hasAllFilesFilter) {
559 retFilterList.append(QFileDialog::tr(
"All files (*)"));
562 d->filterList = retFilterList;
563 d->suffixes = retFilterToSuffixMap;
595 QFileDialog::FileMode mode =
d->fileDialog->fileMode();
596 if (mode != QFileDialog::Directory && !
d->fileDialog->testOption(QFileDialog::ShowDirsOnly)) {
598 if (
d->suffixes.contains(filter)) {
599 QString suffix =
d->suffixes[filter];
601 d->fileDialog->setDefaultSuffix(suffix);
603 warnWidgetUtils <<
"KoFileDialog::onFilterSelected: Cannot find suffix for filter" << filter;
604 d->fileDialog->setDefaultSuffix(
"");