7#include <QtCore/qloggingcategory.h>
8#include <QtGui/private/qguiapplication_p.h>
9#include <QtGui/qpa/qplatformtheme.h>
10#include <QtQml/qqmlinfo.h>
11#include <QtQml/qqmlfile.h>
12#include <QtQuick/private/qquickitemview_p_p.h>
13#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p_p.h>
14#include <QtQuickTemplates2/private/qquickpopupitem_p_p.h>
15#include <QtQuickControls2Impl/private/qquickplatformtheme_p.h>
16#include <QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h>
23Q_LOGGING_CATEGORY(lcCurrentFolder,
"qt.quick.dialogs.quickfiledialogimpl.currentFolder")
25Q_LOGGING_CATEGORY(lcUpdateSelectedFile, "qt.quick.dialogs.quickfiledialogimpl.updateSelectedFile")
28Q_LOGGING_CATEGORY(lcAttachedNameFilters, "qt.quick.dialogs.quickfiledialogimplattached.namefilters")
29Q_LOGGING_CATEGORY(lcAttachedCurrentIndex, "qt.quick.dialogs.quickfiledialogimplattached.currentIndex")
42 emit q->nameFiltersChanged();
54 qmlWarning(
q).nospace() <<
"Can't update Open button's enabled state because it wasn't found";
76 qCDebug(lcUpdateSelectedFile) <<
"updateSelectedFile called with oldFolderPath" << oldFolderPath;
79 int newSelectedFileIndex = -1;
81 if (!oldFolderPath.isEmpty() && !newFolderPath.isEmpty()) {
89 const int indexOfFolder = oldFolderPath.indexOf(newFolderPath);
90 if (indexOfFolder != -1) {
96 newSelectedFilePath = newFolderPath +
QLatin1Char(
'/') + relativePaths.first();
99 const QDir newFolderDir(newFolderPath);
101 if (!newFolderDir.exists()) {
102 qmlWarning(
q) <<
"Directory" << newSelectedFilePath <<
"doesn't exist; can't get a file entry list for it";
107 const QFileInfo newSelectedFileInfo(newSelectedFilePath);
108 newSelectedFileIndex = filesInNewDir.indexOf(newSelectedFileInfo);
112 static const bool preselectFirstFile = []() {
114 if (envVar.isValid() && envVar.canConvert<
bool>())
115 return envVar.toBool();
120 if (preselectFirstFile && newSelectedFilePath.isEmpty()) {
127 const QDir newFolderDir(newFolderPath);
128 if (newFolderDir.exists()) {
131 newSelectedFileIndex = 0;
137 qCDebug(lcUpdateSelectedFile).nospace() <<
"updateSelectedFile is setting selectedFile to " << newSelectedFileUrl
138 <<
", newSelectedFileIndex is " << newSelectedFileIndex;
139 q->setSelectedFile(newSelectedFileUrl);
143 if (newSelectedFileIndex != -1)
173 qCDebug(lcSelectedFile) <<
"setting fileDialogListView's currentIndex to" << newCurrentIndex;
183 currentItem->forceActiveFocus();
194 qCDebug(lcSelectedFile) <<
"tryUpdateFileDialogListViewCurrentIndex called with newCurrentIndex" << newCurrentIndex;
203 qCDebug(lcSelectedFile) <<
"- trying to set currentIndex to" << newCurrentIndex
205 <<
"items; setting pendingCurrentIndexToSet to" << newCurrentIndex;
223 qCDebug(lcSelectedFile) <<
"- ListView has expected count;"
230 qCDebug(lcSelectedFile) <<
"- reset pendingCurrentIndexToSet to -1";
247 if (fileInfo.
isDir()) {
260 attached && fileInfo.
exists() && isSaveMode && !dontConfirmOverride) {
261 QQuickDialog *confirmationDialog = attached->overwriteConfirmationDialog();
262 confirmationDialog->
open();
295 return d->currentFolder;
302 <<
" (old currentFolder is " <<
d->currentFolder <<
")";
311 d->cachedFileList.clear();
312 qCDebug(lcCurrentFolder) <<
"- cachedFileList size is now " <<
d->cachedFileList.size();
324 d->updateSelectedFile(oldFolderPath);
332 return d->selectedFile;
365 qCDebug(lcSelectedFile) <<
"setting initial currentFolder to" << fileDirUrl <<
"and selectedFile to" <<
file;
368 d->updateFileNameTextEdit();
369 d->setCurrentIndexToInitiallySelectedFile =
true;
376 const QFileInfo newSelectedFileInfo(
d->selectedFile.toLocalFile());
377 const int indexOfSelectedFileInFileDialogListView =
d->cachedFileList.indexOf(newSelectedFileInfo);
378 d->tryUpdateFileDialogListViewCurrentIndex(indexOfSelectedFileInFileDialogListView);
390 qCDebug(lcOptions).nospace() <<
"setOptions called with:"
401 d->selectedNameFilter->setOptions(
options);
404 if (
auto attached =
d->attachedOrWarn()) {
406 attached->fileNameLabel()->setVisible(isSaveMode);
407 attached->fileNameTextField()->setVisible(isSaveMode);
420 return d->options ?
d->options->nameFilters() :
QStringList();
432 if (!
d->selectedNameFilter) {
436 d->selectedNameFilter->setOptions(
d->options);
438 return d->selectedNameFilter;
459 <<
"; failed to find Open button in DialogButtonBox of " <<
this;
466 acceptButton->setText(!
label.isEmpty()
481 <<
"; failed to find Open button in DialogButtonBox of " <<
this;
485 rejectButton->setText(!
label.isEmpty()
491 qCDebug(lcNameFilters) <<
"selectNameFilter called with" <<
filter;
493 d->selectedNameFilter->update(
filter);
507 QUrl newSelectedFile;
532 if (buttonCount == 0)
537 if (!rightMostButton) {
538 qmlWarning(
this) <<
"Can't find right-most button in DialogButtonBox";
543 if (!keyNavigationAttached) {
544 qmlWarning(
this) <<
"Can't create attached KeyNavigation object on" << QDebug::toString(rightMostButton);
571 qmlAttachedPropertiesObject<QQuickFileDialogImpl>(
q,
false));
573 qmlWarning(
q) <<
"Expected FileDialogImpl attached object to be present on" <<
this;
577void QQuickFileDialogImplAttachedPrivate::nameFiltersComboBoxItemActivated(
int index)
579 qCDebug(lcAttachedNameFilters) <<
"nameFiltersComboBoxItemActivated called with" <<
index;
580 auto fileDialogImpl = qobject_cast<QQuickFileDialogImpl*>(
parent);
587void QQuickFileDialogImplAttachedPrivate::fileDialogListViewCurrentIndexChanged()
589 auto fileDialogImpl = qobject_cast<QQuickFileDialogImpl*>(
parent);
594 if (!fileDialogDelegate)
599 <<
" with moveReason " << moveReason
600 <<
"; the file at that index is " << fileDialogDelegate->file();
608 fileDialogImpl->setSelectedFile(fileDialogDelegate->file());
609 fileDialogImplPrivate->updateFileNameTextEdit();
610 }
else if (fileDialogImplPrivate->setCurrentIndexToInitiallySelectedFile) {
615 const QFileInfo newSelectedFileInfo(fileDialogImplPrivate->selectedFile.toLocalFile());
616 const int indexOfSelectedFileInFileDialogListView = fileDialogImplPrivate->cachedFileList.indexOf(newSelectedFileInfo);
617 fileDialogImplPrivate->tryUpdateFileDialogListViewCurrentIndex(indexOfSelectedFileInFileDialogListView);
618 fileDialogImplPrivate->setCurrentIndexToInitiallySelectedFile =
false;
622void QQuickFileDialogImplAttachedPrivate::fileNameEditedByUser()
632void QQuickFileDialogImplAttachedPrivate::fileNameEditingByUserFinished()
634 auto fileDialogImpl = qobject_cast<QQuickFileDialogImpl *>(
parent);
644 if (!qobject_cast<QQuickFileDialogImpl*>(
parent)) {
645 qmlWarning(
this) <<
"FileDialogImpl attached properties should only be "
646 <<
"accessed through the root FileDialogImpl instance";
664 if (fileDialogImpl) {
679 if (fileDialogImpl) {
696 return d->nameFiltersComboBox;
708 d, &QQuickFileDialogImplAttachedPrivate::nameFiltersComboBoxItemActivated);
716 return d->nameFiltersComboBox ?
d->nameFiltersComboBox->currentText() :
QString();
722 qCDebug(lcAttachedNameFilters) <<
"selectNameFilter called with" <<
filter;
723 if (!
d->nameFiltersComboBox)
726 const int indexInComboBox =
d->nameFiltersComboBox->find(
filter);
727 if (indexInComboBox == -1)
730 qCDebug(lcAttachedNameFilters) <<
"setting ComboBox's currentIndex to" << indexInComboBox;
731 d->nameFiltersComboBox->setCurrentIndex(indexInComboBox);
737 return d->fileDialogListView;
749 d, &QQuickFileDialogImplAttachedPrivate::fileDialogListViewCurrentIndexChanged);
757 return d->breadcrumbBar;
773 return d->fileNameLabel;
790 return d->fileNameTextField;
799 if (
d->fileNameTextField) {
801 d, &QQuickFileDialogImplAttachedPrivate::fileNameEditingByUserFinished);
803 d, &QQuickFileDialogImplAttachedPrivate::fileNameEditedByUser);
808 if (
d->fileNameTextField) {
810 d, &QQuickFileDialogImplAttachedPrivate::fileNameEditingByUserFinished);
812 d, &QQuickFileDialogImplAttachedPrivate::fileNameEditedByUser);
820 return d->overwriteConfirmationDialog;
826 if (
dialog ==
d->overwriteConfirmationDialog)
830 if (
d->overwriteConfirmationDialog && fileDialogImpl)
834 d->overwriteConfirmationDialog =
dialog;
836 if (
d->overwriteConfirmationDialog && fileDialogImpl)
845#include "moc_qquickfiledialogimpl_p.cpp"
QString dirName() const
Returns the name of the directory; this is not the same as the path, e.g.
QString absolutePath() const
Returns the absolute path (a path that starts with "/" or with a drive specification),...
QString initiallySelectedNameFilter() const
AcceptMode acceptMode() const
QUrl initialDirectory() const
QStringList nameFilters() const
FileMode fileMode() const
QString absoluteFilePath() const
bool isFile() const
Returns true if this object points to a file or to a symbolic link to a file.
bool isDir() const
Returns true if this object points to a directory or to a symbolic link to a directory.
QDir dir() const
Returns a QDir object representing the path of the parent directory of the file system entry that thi...
bool exists() const
Returns true if the file system entry this QFileInfo refers to exists; otherwise returns false.
static QPlatformTheme * platformTheme()
qsizetype size() const noexcept
bool isEmpty() const noexcept
static QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot, Qt::ConnectionType type=Qt::AutoConnection)
static bool disconnect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot)
QObject * parent() const
Returns a pointer to the parent object.
static QString urlToLocalFileOrQrc(const QString &)
If url is a local file returns a path suitable for passing to \l{QFile}.
virtual void componentComplete()=0
Invoked after the root component that caused this instantiation has completed construction.
void activated(int index)
Q_INVOKABLE QString textAt(int index) const
\qmlmethod string QtQuick.Controls::ComboBox::textAt(int index)
Q_INVOKABLE QQuickItem * itemAt(int index) const
\qmlmethod Item QtQuick.Controls::Container::itemAt(int index)
virtual void handleClick(QQuickAbstractButton *button)
static QQuickDialogPrivate * get(QQuickDialog *dialog)
virtual void handleAccept()
static QPlatformDialogHelper::ButtonRole buttonRole(QQuickAbstractButton *button)
Popup dialog with standard buttons and a title, used for short-term interaction with the user.
virtual void handleReject()
QPointer< QQuickTextField > fileNameTextField
QPointer< QQuickDialogButtonBox > buttonBox
QPointer< QQuickListView > fileDialogListView
QPointer< QQuickComboBox > nameFiltersComboBox
void setNameFiltersComboBox(QQuickComboBox *nameFiltersComboBox)
QQuickTextField * fileNameTextField
QQuickDialogButtonBox * buttonBox
void fileNameLabelChanged()
QQuickFolderBreadcrumbBar * breadcrumbBar
QQuickListView * fileDialogListView
QQuickLabel * fileNameLabel
void setOverwriteConfirmationDialog(QQuickDialog *dialog)
QQuickFileDialogImplAttached(QObject *parent=nullptr)
void breadcrumbBarChanged()
void setFileNameTextField(QQuickTextField *fileNameTextField)
void nameFiltersComboBoxChanged()
void setFileNameLabel(QQuickLabel *fileNameLabel)
void setButtonBox(QQuickDialogButtonBox *buttonBox)
void setBreadcrumbBar(QQuickFolderBreadcrumbBar *breadcrumbBar)
void fileDialogListViewChanged()
void setFileDialogListView(QQuickListView *fileDialogListView)
void overwriteConfirmationDialogChanged()
QString selectedNameFilter() const
QQuickComboBox * nameFiltersComboBox
void selectNameFilter(const QString &filter)
void fileNameTextFieldChanged()
QQuickDialog * overwriteConfirmationDialog
static QDir::SortFlags fileListSortFlags()
static QQuickFileDialogImplPrivate * get(QQuickFileDialogImpl *dialog)
QQuickFileDialogImplAttached * attachedOrWarn()
void fileDialogListViewCountChanged()
void setFileDialogListViewCurrentIndex(int newCurrentIndex)
void updateSelectedFile(const QString &oldFolderPath)
void handleAccept() override
void handleClick(QQuickAbstractButton *button) override
static QFileInfoList fileList(const QDir &dir)
int pendingCurrentIndexToSet
void updateFileNameTextEdit()
void tryUpdateFileDialogListViewCurrentIndex(int newCurrentIndex)
QQuickAbstractButton * lastButtonClicked
void setNameFilters(const QStringList &filters)
QFileInfoList cachedFileList
void setRejectLabel(const QString &label)
QString currentFolderName
void setSelectedFile(const QUrl &file)
void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) override
void setAcceptLabel(const QString &label)
void filterSelected(const QString &filter)
void setFileName(const QString &fileName)
void setOptions(const QSharedPointer< QFileDialogOptions > &options)
void selectedFileChanged(const QUrl &selectedFileUrl)
void setCurrentFolder(const QUrl ¤tFolder, SetReason setReason=SetReason::External)
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
QQuickFileDialogImpl(QObject *parent=nullptr)
void selectNameFilter(const QString &filter)
QQuickFileNameFilter * selectedNameFilter
static QQuickFileDialogImplAttached * qmlAttachedProperties(QObject *object)
QSharedPointer< QFileDialogOptions > options() const
void setInitialCurrentFolderAndSelectedFile(const QUrl &file)
void currentFolderChanged(const QUrl &folderUrl)
QQuickTextField * textField
QQuickAbstractButton * upButton
static QQuickItemViewPrivate * get(QQuickItemView *o)
Q_INVOKABLE void positionViewAtIndex(int index, int mode)
void currentIndexChanged()
void setCurrentIndex(int idx)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Q_INVOKABLE void forceActiveFocus()
\qmlmethod point QtQuick::Item::mapToItem(Item item, real x, real y) \qmlmethod point QtQuick::Item::...
ItemChange
Used in conjunction with QQuickItem::itemChange() to notify the item about certain types of changes.
static QQuickKeyNavigationAttached * qmlAttachedProperties(QObject *)
void setText(const QString &)
Exception-safe wrapper around QObject::blockSignals().
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
QString fileName(ComponentFormattingOptions options=FullyDecoded) const
bool isValid() const
Returns true if the URL is non-empty and valid; otherwise returns false.
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
void setScheme(const QString &scheme)
Sets the scheme of the URL to scheme.
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
Combined button and popup list for selecting options.
QList< QString > QStringList
Constructs a string list that contains the given string, str.
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint GLsizei const GLchar * label
[43]
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLdouble GLdouble GLdouble GLdouble q
GLsizei const GLchar *const * path
static QString toLocalFile(const QString &url)
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
QFileDialog dialog(this)
[1]
const QStringList filters({"Image files (*.png *.xpm *.jpg)", "Text files (*.txt)", "Any files (*)" })
[6]
\inmodule QtCore \reentrant
QT_BEGIN_NAMESPACE bool toBool(const QString &str)