// Makes a NUL-oriented Windows filter from a Qt filter. static QString qt_win_filter(const QString &filter) { QStringList filterLst = qt_win_make_filters_list(filter); QStringList::Iterator it = filterLst.begin(); QString winfilters; for (; it != filterLst.end(); ++it) { QString subfilter = *it; if (!subfilter.isEmpty()) { winfilters += subfilter; winfilters += QChar(); winfilters += qt_win_extract_filter(subfilter); winfilters += QChar(); } } winfilters += QChar(); return winfilters; }
// Makes a NUL-oriented Windows filter from a Qt filter. static QString qt_win_filter(const QString &filter, bool hideFiltersDetails) { QStringList filterLst = qt_win_make_filters_list(filter); QStringList::Iterator it = filterLst.begin(); QString winfilters; QRegExp r(QString::fromLatin1(qt_file_dialog_filter_reg_exp)); for (; it != filterLst.end(); ++it) { QString subfilter = *it; if (!subfilter.isEmpty()) { if (hideFiltersDetails) { int index = r.indexIn(subfilter); if (index >= 0) winfilters += r.cap(1); } else { winfilters += subfilter; } winfilters += QChar(); winfilters += qt_win_extract_filter(subfilter); winfilters += QChar(); } } winfilters += QChar(); return winfilters; }
static bool qt_win_set_IFileDialogOptions(IFileDialog *pfd, const QString& initialSelection, const QString& initialDirectory, const QString& title, const QStringList& filterLst, QFileDialog::FileMode mode, QFileDialog::Options options) { if (!pSHCreateItemFromParsingName) { // This function is available only in Vista & above. QLibrary shellLib(QLatin1String("Shell32")); pSHCreateItemFromParsingName = (PtrSHCreateItemFromParsingName) shellLib.resolve("SHCreateItemFromParsingName"); if (!pSHCreateItemFromParsingName) return false; } HRESULT hr; QString winfilters; int numFilters = 0; quint32 currentOffset = 0; QList<quint32> offsets; QStringList::ConstIterator it = filterLst.begin(); // Create the native filter string and save offset to each entry. for (; it != filterLst.end(); ++it) { QString subfilter = *it; if (!subfilter.isEmpty()) { offsets<<currentOffset; //Here the COMMON_ITEM_DIALOG API always add the details for the filter (e.g. *.txt) //so we don't need to handle the flag HideNameFilterDetails. winfilters += subfilter; // The name of the filter. winfilters += QChar(); currentOffset += subfilter.size()+1; offsets<<currentOffset; QString spec = qt_win_extract_filter(subfilter); winfilters += spec; // The actual filter spec. winfilters += QChar(); currentOffset += spec.size()+1; numFilters++; } } // Add the filters to the file dialog. if (numFilters) { wchar_t *szData = (wchar_t*)winfilters.utf16(); COMDLG_FILTERSPEC *filterSpec = new COMDLG_FILTERSPEC[numFilters]; for(int i = 0; i<numFilters; i++) { filterSpec[i].pszName = szData+offsets[i*2]; filterSpec[i].pszSpec = szData+offsets[(i*2)+1]; } hr = pfd->SetFileTypes(numFilters, filterSpec); delete []filterSpec; } // Set the starting folder. tInitDir = QDir::toNativeSeparators(initialDirectory); if (!tInitDir.isEmpty()) { IShellItem *psiDefaultFolder; hr = pSHCreateItemFromParsingName((wchar_t*)tInitDir.utf16(), NULL, IID_PPV_ARGS(&psiDefaultFolder)); if (SUCCEEDED(hr)) { hr = pfd->SetFolder(psiDefaultFolder); psiDefaultFolder->Release(); } } // Set the currently selected file. QString initSel = QDir::toNativeSeparators(initialSelection); if (!initSel.isEmpty()) { initSel.remove(QLatin1Char('<')); initSel.remove(QLatin1Char('>')); initSel.remove(QLatin1Char('\"')); initSel.remove(QLatin1Char('|')); } if (!initSel.isEmpty()) { hr = pfd->SetFileName((wchar_t*)initSel.utf16()); } // Set the title for the file dialog. if (!title.isEmpty()) { hr = pfd->SetTitle((wchar_t*)title.utf16()); } // Set other flags for the dialog. DWORD newOptions; hr = pfd->GetOptions(&newOptions); if (SUCCEEDED(hr)) { newOptions |= FOS_NOCHANGEDIR; if (mode == QFileDialog::ExistingFile || mode == QFileDialog::ExistingFiles) newOptions |= (FOS_FILEMUSTEXIST | FOS_PATHMUSTEXIST); if (mode == QFileDialog::ExistingFiles) newOptions |= FOS_ALLOWMULTISELECT; if (!(options & QFileDialog::DontConfirmOverwrite)) newOptions |= FOS_OVERWRITEPROMPT; hr = pfd->SetOptions(newOptions); } return SUCCEEDED(hr); }
QString qt_win_get_save_file_name(const QFileDialogArgs &args, QString *initialDirectory, QString *selectedFilter) { QString result; QString isel = args.selection; if (initialDirectory && initialDirectory->left(5) == QLatin1String("file:")) initialDirectory->remove(0, 5); QFileInfo fi(*initialDirectory); if (initialDirectory && !fi.isDir()) { *initialDirectory = fi.absolutePath(); if (isel.isEmpty()) isel = fi.fileName(); } if (!fi.exists()) *initialDirectory = QDir::homePath(); DWORD selFilIdx = 0; int idx = 0; if (selectedFilter) { QStringList filterLst = qt_win_make_filters_list(args.filter); idx = filterLst.indexOf(*selectedFilter); } QDialog modal_widget; modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true); modal_widget.setParent(args.parent, Qt::Window); QApplicationPrivate::enterModal(&modal_widget); bool hideFiltersDetails = args.options & QFileDialog::HideNameFilterDetails; // This block is used below for the lpstrDefExt member. // Note that the current MSDN docs document this member wrong. // It should rather be documented as "the default extension if no extension was given and if the // current filter does not have a extension (e.g (*)). If the current filter have an extension, use // the extension of the current filter" QString defaultSaveExt; if (selectedFilter && !selectedFilter->isEmpty()) { defaultSaveExt = qt_win_extract_filter(*selectedFilter); // make sure we only have the extension int firstDot = defaultSaveExt.indexOf(QLatin1Char('.')); if (firstDot != -1) { defaultSaveExt.remove(0, firstDot + 1); } else { defaultSaveExt.clear(); } } OPENFILENAME *ofn = qt_win_make_OFN(args.parent, args.selection, args.directory, args.caption, qt_win_filter(args.filter, hideFiltersDetails), QFileDialog::AnyFile, args.options); ofn->lpstrDefExt = (wchar_t*)defaultSaveExt.utf16(); if (idx) ofn->nFilterIndex = idx + 1; if (GetSaveFileName(ofn)) { result = QString::fromWCharArray(ofn->lpstrFile); selFilIdx = ofn->nFilterIndex; } qt_win_clean_up_OFN(&ofn); #if defined(Q_WS_WINCE) int semIndex = result.indexOf(QLatin1Char(';')); if (semIndex >= 0) result = result.left(semIndex); #endif QApplicationPrivate::leaveModal(&modal_widget); qt_win_eatMouseMove(); if (result.isEmpty()) return result; fi = result; *initialDirectory = fi.path(); if (selectedFilter) *selectedFilter = qt_win_selected_filter(args.filter, selFilIdx); return fi.absoluteFilePath(); }