7#include <QtCore/qdir.h>
8#include <QtCore/qloggingcategory.h>
10#include <QtGui/private/qshortcutmap_p.h>
12#include <QtGui/private/qguiapplication_p.h>
13#include <QtQml/QQmlFile>
14#include <QtQuick/private/qquicktextinput_p.h>
15#include <QtQuickTemplates2/private/qquickabstractbutton_p.h>
16#include <QtQuickTemplates2/private/qquickpopupitem_p_p.h>
17#include <QtQuickTemplates2/private/qquickshortcutcontext_p_p.h>
46 if (!
component->isBound() && initialProperties.isEmpty()) {
54 qCDebug(lcDelegates) <<
"- created delegate item" <<
item <<
"with initialProperties" << initialProperties;
65 return folderPath.
mid(0, folderPath.
size() - 1);
91 qCDebug(lcDelegates) <<
"attemping to repopulate breadcrumb bar using folder...";
96 if (!buttonDelegate || !separatorDelegate || !
q->contentItem()) {
97 qCWarning(lcDelegates) <<
"Both delegates and contentItem must be set before repopulating";
103 auto failureCleanup = [
this,
q](){
105 while (
q->count() > 0)
106 q->removeItem(
q->itemAt(0));
112 while (
q->count() > 0)
113 q->removeItem(
q->itemAt(0));
115 for (
int i = 0;
i < folderPaths.
size(); ++
i) {
116 const QString &folderPath = folderPaths.
at(
i);
124 qCWarning(lcDelegates) <<
"Failed creating breadcrumb buttonDelegate item:\n" << buttonDelegate->
errorString();
135 if (
i < folderPaths.
size() - 1) {
136 initialProperties = {};
138 if (!separatorItem) {
139 qCWarning(lcDelegates) <<
"Failed creating breadcrumb separatorDelegate item:\n" << buttonDelegate->
errorString();
147 const int finalCount =
q->count();
150 const int newCurrentIndex = finalCount > 2 ? finalCount - 1 : -1;
151 qCDebug(lcDelegates) <<
"- setting currentIndex to" << newCurrentIndex;
152 q->setCurrentIndex(newCurrentIndex);
156 qCDebug(lcDelegates) <<
"... bar now contains" <<
q->count()
157 <<
"buttons and separators in total, for the following paths:" << folderPaths;
163 qCDebug(lcCurrentItem) <<
"updateCurrentIndex called by sender" <<
q->sender();
167 q->setCurrentIndex(buttonIndex);
170 qCDebug(lcCurrentItem) <<
"setting file dialog's folder to" << folderUrl;
198 if (!upButton || complete)
228 if (!textField || complete)
238 qCDebug(lcTextInput).nospace() <<
"text field visibility was " << textField->
isVisible()
239 <<
"; setting it to " << !textField->
isVisible();
257 fileDialogPrivate->updateEnabled();
260 folderDialogPrivate->updateEnabled();
269 const bool enteredPathIsValidUrl = fileUrl.
isValid();
270 bool enteredPathExists =
false;
271 bool enteredPathIsDir =
false;
272 if (enteredPathIsValidUrl) {
274 enteredPathExists = fileInfo.
exists();
275 if (enteredPathExists)
276 enteredPathIsDir = fileInfo.
isDir();
279 qCDebug(lcTextInput).nospace() <<
"text field accepted -"
280 <<
" text=" << textField->
text()
281 <<
" fileUrl=" << fileUrl
282 <<
" mustExist=" << mustExist
283 <<
" enteredPathIsValidUrl=" << enteredPathIsValidUrl
284 <<
" enteredPathExists=" << enteredPathExists
285 <<
" enteredPathIsDir=" << enteredPathIsDir;
287 if (enteredPathIsDir && (enteredPathExists || !mustExist)) {
288 qCDebug(lcTextInput) <<
"path entered is a folder; setting folder";
290 }
else if (!enteredPathIsDir && (enteredPathExists || !mustExist)) {
291 qCDebug(lcTextInput) <<
"path entered is a file; setting file and calling accept()";
294 fileDialog->setSelectedFile(fileUrl);
295 fileDialog->accept();
300 qCDebug(lcTextInput) <<
"path entered is not valid; not setting file/folder";
308 if (dialog->isVisible())
314 qCDebug(lcShortcuts) <<
"text field was either hidden or shown";
339#if QT_CONFIG(shortcut)
340 if (editPathToggleShortcutId == 0)
343 qCDebug(lcShortcuts) <<
"text field was shown; ungrabbing edit path shortcut";
356#if QT_CONFIG(shortcut)
360 qCDebug(lcShortcuts) <<
"text field was hidden; grabbing edit path shortcut";
362 if (editPathToggleShortcutId == 0) {
363 editPathToggleShortcutId = appPrivate->shortcutMap.addShortcut(
367 qCDebug(lcShortcuts).nospace() <<
"... editPathToggleShortcutId=" << editPathToggleShortcutId;
373#if QT_CONFIG(shortcut)
376 if (editPathToggleShortcutId != 0) {
377 appPrivate->shortcutMap.removeShortcut(editPathToggleShortcutId,
q);
378 editPathToggleShortcutId = 0;
385 return qobject_cast<QQuickFileDialogImpl*>(dialog);
390 return qobject_cast<QQuickFolderDialogImpl*>(dialog);
407 qmlWarning(
q) <<
"Failed to set currentFolder property of dialog" << dialog->
objectName() <<
"to" << folder;
419 if (!
p->widthValid())
420 totalWidth +=
item->implicitWidth();
422 totalWidth +=
item->width();
425 qCDebug(lcContentSize) <<
"content width:" << totalWidth;
437 maxHeight =
qMax(maxHeight,
item->implicitHeight());
439 qCDebug(lcContentSize) <<
"content height:" << maxHeight;
447 const int upButtonSpace =
q->upButton() ?
q->upButton()->width() + upButtonSpacing : 0;
508 if (
auto fileDialog =
d->asFileDialog()) {
512 }
else if (
auto folderDialog =
d->asFolderDialog()) {
521 if (
auto fileDialog =
d->asFileDialog()) {
524 }
else if (
auto folderDialog =
d->asFolderDialog()) {
536 return d->buttonDelegate;
542 qCDebug(lcFolderBreadcrumbBar) <<
"setButtonDelegate called with" << delegate;
543 if (
d->componentComplete) {
545 qCWarning(lcFolderBreadcrumbBar) <<
"BreadcrumbBar does not support setting delegates after component completion";
549 if (delegate ==
d->buttonDelegate)
552 d->buttonDelegate = delegate;
559 return d->separatorDelegate;
565 qCDebug(lcFolderBreadcrumbBar) <<
"setSeparatorDelegate called with" << delegate;
566 if (
d->componentComplete) {
567 qCWarning(lcFolderBreadcrumbBar) <<
"BreadcrumbBar does not support setting delegates after component completion";
571 if (delegate ==
d->separatorDelegate)
574 d->separatorDelegate = delegate;
582 d->executeUpButton();
592 if (!
d->upButton.isExecuting())
603 if (!
d->upButton->parentItem())
604 d->upButton->setParentItem(
this);
609 if (!
d->upButton.isExecuting())
616 return d->upButtonSpacing;
641 if (!
d->textField.isExecuting())
645 d->handleTextFieldHidden();
659 if (!
d->textField->parentItem())
660 d->textField->setParentItem(
this);
662 d->textField->setVisible(
false);
671 if (!
d->textField.isExecuting())
677#if QT_CONFIG(shortcut)
681 if (shortcutEvent->shortcutId() ==
d->editPathToggleShortcutId) {
682 d->toggleTextFieldVisibility();
684 }
else if (shortcutEvent->shortcutId() ==
d->goUpShortcutId) {
694#if QT_CONFIG(shortcut)
698 d->toggleTextFieldVisibility();
710 qCDebug(lcFolderBreadcrumbBar) <<
"componentComplete";
716 d->textFieldVisibleChanged();
726 if (
data.boolValue &&
d->dialog->isVisible()) {
728 d->handleTextFieldHidden();
730#if QT_CONFIG(shortcut)
738 d->textField->setVisible(
false);
742 d->contentItem->setVisible(
true);
745 d->ungrabEditPathShortcut();
747#if QT_CONFIG(shortcut)
748 if (
d->goUpShortcutId != 0) {
750 d->goUpShortcutId = 0;
774#if QT_CONFIG(accessibility)
775QAccessible::Role QQuickFolderBreadcrumbBar::accessibleRole()
const
778 return QAccessible::PageTabList;
784#include "moc_qquickfolderbreadcrumbbar_p.cpp"
static QString fromNativeSeparators(const QString &pathName)
\inmodule QtCore \reentrant
bool isDir() const
Returns true if this object points to a directory or to a symbolic link to a directory.
bool exists() const
Returns true if the file exists; otherwise returns false.
static QGuiApplicationPrivate * instance()
The QKeyEvent class describes a key event.
The QKeySequence class encapsulates a key sequence as used by shortcuts.
qsizetype size() const noexcept
const_reference at(qsizetype i) 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)
QString objectName
the name of this object
QVariant property(const char *name) const
Returns the value of the object's name property.
bool setProperty(const char *name, const QVariant &value)
Sets the value of the object's name property to value.
\inmodule QtCore\reentrant
The QQmlComponent class encapsulates a QML component definition.
Q_INVOKABLE QString errorString() const
\qmlmethod string Component::errorString()
The QQmlContext class defines a context within a QML engine.
static QString urlToLocalFileOrQrc(const QString &)
If url is a local file returns a path suitable for passing to QFile.
int count() const override
\qmlproperty int QtQml.Models::ObjectModel::count
int indexOf(QObject *object, QObject *objectContext) const override
void insertItem(int index, QQuickItem *item)
QQmlObjectModel * contentModel
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void itemChange(ItemChange change, const ItemChangeData &data) override
Called when change occurs for this item.
void updateImplicitContentSize()
QQuickDeferredPointer< QQuickItem > contentItem
void updateImplicitContentWidth()
static void hideOldItem(QQuickItem *item)
void updateImplicitContentHeight()
static QQuickFileDialogImplPrivate * get(QQuickFileDialogImpl *dialog)
void currentFolderChanged(const QUrl &folderUrl)
void resizeContent() override
QQuickFolderDialogImpl * asFolderDialog() const
void textFieldVisibleChanged()
qreal getContentWidth() const override
void executeUpButton(bool complete=false)
QQuickFileDialogImpl * asFileDialog() const
void toggleTextFieldVisibility()
void itemImplicitWidthChanged(QQuickItem *item) override
void itemImplicitHeightChanged(QQuickItem *item) override
void textFieldActiveFocusChanged()
static QStringList crumbPathsForFolder(const QUrl &folder)
void handleTextFieldShown()
qreal getContentHeight() const override
static QString folderBaseName(const QString &folderPath)
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override
QQuickItem * createDelegateItem(QQmlComponent *component, const QVariantMap &initialProperties)
void ungrabEditPathShortcut()
QUrl dialogFolder() const
void handleTextFieldHidden()
void executeTextField(bool complete=false)
void setDialogFolder(const QUrl &folder)
bool isFileDialog() const
void setButtonDelegate(QQmlComponent *delegate)
void keyPressEvent(QKeyEvent *event) override
This event handler can be reimplemented in a subclass to receive key press events for an item.
bool event(QEvent *event) override
This virtual function receives events to an object and should return true if the event e was recogniz...
QQmlComponent * separatorDelegate
QFont defaultFont() const override
void setDialog(QQuickDialog *dialog)
void setTextField(QQuickTextField *textField)
void setUpButton(QQuickAbstractButton *upButton)
QQmlComponent * buttonDelegate
QQuickTextField * textField
bool isContent(QQuickItem *item) const override
void itemChange(ItemChange change, const ItemChangeData &data) override
Called when change occurs for this item.
QQuickAbstractButton * upButton
void upButtonSpacingChanged()
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void buttonDelegateChanged()
void separatorDelegateChanged()
QQuickFolderBreadcrumbBar(QQuickItem *parent=nullptr)
void setSeparatorDelegate(QQmlComponent *delegate)
void setUpButtonSpacing(int upButtonSpacing)
static QQuickFolderDialogImplPrivate * get(QQuickFolderDialogImpl *dialog)
void currentFolderChanged(const QUrl &folderUrl)
virtual void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &)
virtual void itemImplicitWidthChanged(QQuickItem *)
virtual void itemImplicitHeightChanged(QQuickItem *)
quint32 componentComplete
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
bool event(QEvent *) override
\reimp
void activeFocusChanged(bool)
void setSize(const QSizeF &size)
virtual void keyPressEvent(QKeyEvent *event)
This event handler can be reimplemented in a subclass to receive key press events for an item.
bool hasActiveFocus() const
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
Q_INVOKABLE void forceActiveFocus()
\qmlmethod point QtQuick::Item::mapToItem(Item item, real x, real y) \qmlmethod point QtQuick::Item::...
void setPosition(const QPointF &)
ItemChange
Used in conjunction with QQuickItem::itemChange() to notify the item about certain types of changes.
void selectAll()
\qmlmethod QtQuick::TextInput::selectAll()
void setText(const QString &)
static QFont font(Scope scope)
\inmodule QtCore\reentrant
The QShortcutEvent class provides an event which is generated when the user presses a key combination...
\macro QT_RESTRICTED_CAST_FROM_ASCII
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
qsizetype size() const
Returns the number of characters in this string.
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
bool isValid() const
Returns true if the URL is non-empty and valid; otherwise returns false.
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
QUrl toUrl() const
Returns the variant as a QUrl if the variant has userType() \l QMetaType::QUrl; otherwise returns an ...
Combined button and popup list for selecting options.
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
constexpr const T & qMax(const T &a, const T &b)
GLenum GLenum GLsizei count
GLsizei const GLuint * paths
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLdouble GLdouble GLdouble GLdouble q
static qreal component(const QPointF &point, unsigned int i)
QQmlContext * qmlContext(const QObject *obj)
void QQml_setParent_noEvent(QObject *object, QObject *parent)
Makes the object a child of parent.
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
void quickCancelDeferred(QObject *object, const QString &property)
void quickCompleteDeferred(QObject *object, const QString &property, QQuickDeferredPointer< T > &delegate)
void quickBeginDeferred(QObject *object, const QString &property, QQuickDeferredPointer< T > &delegate)
static QString upButtonName()
static QString textFieldName()
QQuickItem * qobject_cast< QQuickItem * >(QObject *o)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
QFileDialog dialog(this)
[1]
\inmodule QtCore \reentrant
static bool matcher(QObject *object, Qt::ShortcutContext context)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent