forked from qt-creator/qt-creator
QmlDesigner: Display only file names in comboboxes
Full paths are displayed in tooltips. Also add a check mark to the selected item in the combobox's pop up. Task-number: QDS-2405 Change-Id: I69cbd4200a73183b4e747c87e9dd8197fc650ed7 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -27,7 +27,9 @@ import QtQuick 2.1
|
||||
import HelperWidgets 2.0
|
||||
import StudioControls 1.0 as StudioControls
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
import QtQuickDesignerTheme 1.0
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls 2.5
|
||||
|
||||
RowLayout {
|
||||
id: urlChooser
|
||||
@@ -50,6 +52,58 @@ RowLayout {
|
||||
StudioControls.ComboBox {
|
||||
id: comboBox
|
||||
|
||||
// Note: highlightedIndex property isn't used because it has no setter and it doesn't reset
|
||||
// when the combobox is closed by focusing on some other control.
|
||||
property int hoverIndex: -1
|
||||
|
||||
ToolTip {
|
||||
visible: comboBox.hovered
|
||||
text: urlChooser.backendValue.valueToString
|
||||
delay: 1000
|
||||
}
|
||||
|
||||
delegate: ItemDelegate {
|
||||
id: delegateItem
|
||||
width: parent.width
|
||||
height: 20
|
||||
highlighted: comboBox.hoverIndex === index
|
||||
|
||||
indicator: Label { // selected item check mark
|
||||
padding: 5
|
||||
y: (parent.height - height) / 2
|
||||
text: StudioTheme.Constants.tickIcon
|
||||
font.pixelSize: 10
|
||||
font.family: StudioTheme.Constants.iconFont.family
|
||||
color: Theme.color(comboBox.hoverIndex === index ? Theme.PanelTextColorLight
|
||||
: Theme.QmlDesigner_HighlightColor)
|
||||
visible: comboBox.currentIndex === index
|
||||
}
|
||||
|
||||
contentItem: Label {
|
||||
leftPadding: 10
|
||||
text: modelData
|
||||
anchors.top: parent.top
|
||||
color: Theme.color(Theme.PanelTextColorLight)
|
||||
font.pixelSize: 13
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
anchors.fill: parent
|
||||
color: parent.highlighted ? Theme.color(Theme.QmlDesigner_HighlightColor) : "transparent"
|
||||
}
|
||||
|
||||
ToolTip {
|
||||
visible: delegateItem.hovered && comboBox.highlightedIndex === index
|
||||
text: fileModel.fullPathModel[index]
|
||||
delay: 1000
|
||||
}
|
||||
|
||||
onHoveredChanged: {
|
||||
if (hovered)
|
||||
comboBox.hoverIndex = index
|
||||
}
|
||||
}
|
||||
|
||||
actionIndicator.icon.color: extFuncLogic.color
|
||||
actionIndicator.icon.text: extFuncLogic.glyph
|
||||
actionIndicator.onClicked: extFuncLogic.show()
|
||||
@@ -78,7 +132,9 @@ RowLayout {
|
||||
if (urlChooser.backendValue.isBound)
|
||||
return urlChooser.backendValue.expression
|
||||
|
||||
return urlChooser.backendValue.valueToString
|
||||
var fullPath = urlChooser.backendValue.valueToString;
|
||||
var fileName = fullPath.substr(fullPath.lastIndexOf('/') + 1);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
onTextValueChanged: comboBox.setCurrentText(comboBox.textValue)
|
||||
@@ -87,7 +143,7 @@ RowLayout {
|
||||
|
||||
editable: true
|
||||
|
||||
model: fileModel.fileModel
|
||||
model: fileModel.fileNameModel
|
||||
|
||||
onModelChanged: {
|
||||
if (!comboBox.isComplete)
|
||||
@@ -115,19 +171,17 @@ RowLayout {
|
||||
|
||||
function handleActivate(index)
|
||||
{
|
||||
var cText = comboBox.textAt(index)
|
||||
|
||||
if (index === -1)
|
||||
cText = comboBox.editText
|
||||
|
||||
if (urlChooser.backendValue === undefined)
|
||||
return
|
||||
|
||||
if (!comboBox.isComplete)
|
||||
return
|
||||
|
||||
if (urlChooser.backendValue.value !== cText)
|
||||
urlChooser.backendValue.value = cText
|
||||
if (index === -1) // select first item if index is invalid
|
||||
index = 0
|
||||
|
||||
if (urlChooser.backendValue.value !== fileModel.fullPathModel[index])
|
||||
urlChooser.backendValue.value = fileModel.fullPathModel[index]
|
||||
|
||||
comboBox.dirty = false
|
||||
}
|
||||
@@ -145,13 +199,29 @@ RowLayout {
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: comboBox
|
||||
function onStateChanged(state)
|
||||
{
|
||||
// update currentIndex when the popup opens to override the default behavior in super classes
|
||||
// that selects currentIndex based on values in the combo box.
|
||||
if (comboBox.popup.opened) {
|
||||
var index = fileModel.fullPathModel.indexOf(urlChooser.backendValue.value)
|
||||
if (index !== -1) {
|
||||
comboBox.currentIndex = index
|
||||
comboBox.hoverIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StudioControls.AbstractButton {
|
||||
buttonIcon: StudioTheme.Constants.addFile
|
||||
iconColor: urlChooser.textColor
|
||||
onClicked: {
|
||||
fileModel.openFileDialog()
|
||||
if (fileModel.fileName !== "")
|
||||
urlChooser.backendValue.value = fileModel.fileName
|
||||
if (fileModel.path !== "")
|
||||
urlChooser.backendValue.value = fileModel.path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -42,8 +42,7 @@ FileResourcesModel::FileResourcesModel(QObject *parent) :
|
||||
|
||||
void FileResourcesModel::setModelNodeBackend(const QVariant &modelNodeBackend)
|
||||
{
|
||||
|
||||
auto modelNodeBackendObject = modelNodeBackend.value<QObject*>();
|
||||
auto modelNodeBackendObject = modelNodeBackend.value<QObject *>();
|
||||
|
||||
const auto backendObjectCasted =
|
||||
qobject_cast<const QmlDesigner::QmlModelNodeProxy *>(modelNodeBackendObject);
|
||||
@@ -64,6 +63,7 @@ void FileResourcesModel::setFileNameStr(const QString &fileName)
|
||||
{
|
||||
setFileName(QUrl(fileName));
|
||||
}
|
||||
|
||||
void FileResourcesModel::setFileName(const QUrl &fileName)
|
||||
{
|
||||
if (fileName == m_fileName)
|
||||
@@ -103,26 +103,25 @@ QString FileResourcesModel::filter() const
|
||||
return m_filter;
|
||||
}
|
||||
|
||||
QStringList FileResourcesModel::fileModel() const
|
||||
QStringList FileResourcesModel::fullPathModel() const
|
||||
{
|
||||
if (m_model.isEmpty())
|
||||
return QStringList(QString());
|
||||
return m_fullPathModel;
|
||||
}
|
||||
|
||||
return m_model;
|
||||
QStringList FileResourcesModel::fileNameModel() const
|
||||
{
|
||||
return m_fileNameModel;
|
||||
}
|
||||
|
||||
void FileResourcesModel::openFileDialog()
|
||||
{
|
||||
QString modelPath;
|
||||
|
||||
modelPath = m_path.toLocalFile();
|
||||
QString modelPath = m_path.toLocalFile();
|
||||
|
||||
m_lastModelPath = modelPath;
|
||||
|
||||
bool documentChanged = m_lastModelPath == modelPath;
|
||||
|
||||
//First we try the last path this browser widget was opened with
|
||||
//if the document was not changed
|
||||
//First we try the last path this browser widget was opened with if the document was not changed
|
||||
QString path = documentChanged ? QString() : m_currentPath;
|
||||
|
||||
|
||||
@@ -154,7 +153,7 @@ void FileResourcesModel::openFileDialog()
|
||||
|
||||
void FileResourcesModel::registerDeclarativeType()
|
||||
{
|
||||
qmlRegisterType<FileResourcesModel>("HelperWidgets",2,0,"FileResourcesModel");
|
||||
qmlRegisterType<FileResourcesModel>("HelperWidgets", 2, 0, "FileResourcesModel");
|
||||
}
|
||||
|
||||
QVariant FileResourcesModel::modelNodeBackend() const
|
||||
@@ -167,8 +166,7 @@ bool filterMetaIcons(const QString &fileName)
|
||||
|
||||
QFileInfo info(fileName);
|
||||
|
||||
if (info.dir().path().split("/").contains("designer")) {
|
||||
|
||||
if (info.dir().path().split('/').contains("designer")) {
|
||||
QDir currentDir = info.dir();
|
||||
|
||||
int i = 0;
|
||||
@@ -192,7 +190,8 @@ bool filterMetaIcons(const QString &fileName)
|
||||
void FileResourcesModel::setupModel()
|
||||
{
|
||||
m_lock = true;
|
||||
m_model.clear();
|
||||
m_fullPathModel.clear();
|
||||
m_fileNameModel.clear();
|
||||
|
||||
m_dirPath = QFileInfo(m_path.toLocalFile()).dir();
|
||||
|
||||
@@ -201,11 +200,15 @@ void FileResourcesModel::setupModel()
|
||||
QDirIterator it(m_dirPath.absolutePath(), filterList, QDir::Files, QDirIterator::Subdirectories);
|
||||
while (it.hasNext()) {
|
||||
QString absolutePath = it.next();
|
||||
if (filterMetaIcons(absolutePath))
|
||||
m_model.append(m_dirPath.relativeFilePath(absolutePath));
|
||||
if (filterMetaIcons(absolutePath)) {
|
||||
QString filePath = m_dirPath.relativeFilePath(absolutePath);
|
||||
m_fullPathModel.append(filePath);
|
||||
m_fileNameModel.append(filePath.mid(filePath.lastIndexOf('/') + 1));
|
||||
}
|
||||
}
|
||||
|
||||
m_lock = false;
|
||||
|
||||
emit fileModelChanged();
|
||||
emit fullPathModelChanged();
|
||||
emit fileNameModelChanged();
|
||||
}
|
||||
|
@@ -42,7 +42,8 @@ class FileResourcesModel : public QObject
|
||||
Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged)
|
||||
Q_PROPERTY(QUrl path READ path WRITE setPath)
|
||||
Q_PROPERTY(QUrl dirPath READ dirPath)
|
||||
Q_PROPERTY(QStringList fileModel READ fileModel NOTIFY fileModelChanged)
|
||||
Q_PROPERTY(QStringList fullPathModel READ fullPathModel NOTIFY fullPathModelChanged)
|
||||
Q_PROPERTY(QStringList fileNameModel READ fileNameModel NOTIFY fileNameModelChanged)
|
||||
|
||||
public:
|
||||
explicit FileResourcesModel(QObject *parent = nullptr);
|
||||
@@ -56,7 +57,8 @@ public:
|
||||
QUrl dirPath() const;
|
||||
void setFilter(const QString &filter);
|
||||
QString filter() const;
|
||||
QStringList fileModel() const;
|
||||
QStringList fullPathModel() const;
|
||||
QStringList fileNameModel() const;
|
||||
void setupModel();
|
||||
|
||||
Q_INVOKABLE void openFileDialog();
|
||||
@@ -66,7 +68,8 @@ public:
|
||||
signals:
|
||||
void fileNameChanged(const QUrl &fileName);
|
||||
void modelNodeBackendChanged();
|
||||
void fileModelChanged();
|
||||
void fullPathModelChanged();
|
||||
void fileNameModelChanged();
|
||||
|
||||
private:
|
||||
QVariant modelNodeBackend() const;
|
||||
@@ -79,7 +82,8 @@ private:
|
||||
bool m_lock;
|
||||
QString m_currentPath;
|
||||
QString m_lastModelPath;
|
||||
QStringList m_model;
|
||||
QStringList m_fullPathModel;
|
||||
QStringList m_fileNameModel;
|
||||
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user