mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#4583 Added Completer functionality to LineEditor
This commit is contained in:
parent
2784f5ce11
commit
cd1f312c34
@ -56,6 +56,12 @@
|
|||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
#include <QStatusBar>
|
#include <QStatusBar>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QCompleter>
|
||||||
|
#include <QStringListModel>
|
||||||
|
#include <QAbstractProxyModel>
|
||||||
|
#include <QAbstractItemView>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
|
||||||
namespace caf
|
namespace caf
|
||||||
{
|
{
|
||||||
@ -111,8 +117,8 @@ void PdmUiLineEditor::configureAndUpdateUi(const QString& uiConfigName)
|
|||||||
|
|
||||||
m_lineEdit->setToolTip(uiField()->uiToolTip(uiConfigName));
|
m_lineEdit->setToolTip(uiField()->uiToolTip(uiConfigName));
|
||||||
|
|
||||||
|
PdmUiLineEditorAttribute leab;
|
||||||
{
|
{
|
||||||
PdmUiLineEditorAttribute leab;
|
|
||||||
caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject());
|
caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject());
|
||||||
if (uiObject)
|
if (uiObject)
|
||||||
{
|
{
|
||||||
@ -126,31 +132,58 @@ void PdmUiLineEditor::configureAndUpdateUi(const QString& uiConfigName)
|
|||||||
|
|
||||||
m_lineEdit->setAvoidSendingEnterEventToParentWidget(leab.avoidSendingEnterEventToParentWidget);
|
m_lineEdit->setAvoidSendingEnterEventToParentWidget(leab.avoidSendingEnterEventToParentWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fromMenuOnly = true;
|
bool fromMenuOnly = true;
|
||||||
QList<PdmOptionItemInfo> enumNames = uiField()->valueOptions(&fromMenuOnly);
|
m_optionCache = uiField()->valueOptions(&fromMenuOnly);
|
||||||
CAF_ASSERT(fromMenuOnly); // Not supported
|
CAF_ASSERT(fromMenuOnly); // Not supported
|
||||||
|
|
||||||
if (!enumNames.isEmpty() && fromMenuOnly == true)
|
if (!m_optionCache.isEmpty() && fromMenuOnly == true)
|
||||||
{
|
{
|
||||||
|
if (!m_completer)
|
||||||
|
{
|
||||||
|
m_completer = new QCompleter(this);
|
||||||
|
m_completerTextList = new QStringListModel( this);
|
||||||
|
|
||||||
|
m_completer->setModel(m_completerTextList);
|
||||||
|
m_completer->setFilterMode( leab.completerFilterMode );
|
||||||
|
m_completer->setCaseSensitivity( leab.completerCaseSensitivity);
|
||||||
|
|
||||||
|
m_lineEdit->setCompleter(m_completer);
|
||||||
|
connect(m_completer, SIGNAL(activated(const QModelIndex&)), this, SLOT(slotCompleterActivated(const QModelIndex&)));
|
||||||
|
m_completer->popup()->installEventFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList optionNames;
|
||||||
|
for (const PdmOptionItemInfo& item: m_optionCache)
|
||||||
|
{
|
||||||
|
optionNames.push_back(item.optionUiText());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_completerTextList->setStringList(optionNames);
|
||||||
|
|
||||||
int enumValue = uiField()->uiValue().toInt();
|
int enumValue = uiField()->uiValue().toInt();
|
||||||
|
|
||||||
if (enumValue < enumNames.size() && enumValue > -1)
|
if (enumValue < m_optionCache.size() && enumValue > -1)
|
||||||
{
|
{
|
||||||
m_lineEdit->setText(enumNames[enumValue].optionUiText());
|
m_lineEdit->setText(m_optionCache[enumValue].optionUiText());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PdmUiLineEditorAttributeUiDisplayString leab;
|
m_lineEdit->setCompleter(nullptr);
|
||||||
|
delete m_completerTextList;
|
||||||
|
delete m_completer;
|
||||||
|
m_optionCache.clear();
|
||||||
|
|
||||||
|
PdmUiLineEditorAttributeUiDisplayString displayStringAttrib;
|
||||||
caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject());
|
caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject());
|
||||||
if (uiObject)
|
if (uiObject)
|
||||||
{
|
{
|
||||||
uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &leab);
|
uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &displayStringAttrib);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString displayString;
|
QString displayString;
|
||||||
if (leab.m_displayString.isEmpty())
|
if (displayStringAttrib.m_displayString.isEmpty())
|
||||||
{
|
{
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) && QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) && QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
|
||||||
bool valueOk = false;
|
bool valueOk = false;
|
||||||
@ -171,7 +204,7 @@ void PdmUiLineEditor::configureAndUpdateUi(const QString& uiConfigName)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
displayString = leab.m_displayString;
|
displayString = displayStringAttrib.m_displayString;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_lineEdit->setText(displayString);
|
m_lineEdit->setText(displayString);
|
||||||
@ -203,9 +236,50 @@ QMargins PdmUiLineEditor::calculateLabelContentMargins() const
|
|||||||
void PdmUiLineEditor::slotEditingFinished()
|
void PdmUiLineEditor::slotEditingFinished()
|
||||||
{
|
{
|
||||||
QVariant v;
|
QVariant v;
|
||||||
QString textValue = m_lineEdit->text();
|
|
||||||
v = textValue;
|
if (m_optionCache.size())
|
||||||
this->setValueToField(v);
|
{
|
||||||
|
int index = findIndexToOption(m_lineEdit->text());
|
||||||
|
if (index > -1)
|
||||||
|
{
|
||||||
|
v = QVariant(static_cast<unsigned int>(index));
|
||||||
|
this->setValueToField(v);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Try to complete the text in the widget
|
||||||
|
|
||||||
|
QModelIndex sourceindex = static_cast<QAbstractProxyModel*>(m_completer->completionModel())->mapToSource(m_completer->currentIndex());
|
||||||
|
|
||||||
|
if ( sourceindex.isValid() )
|
||||||
|
{
|
||||||
|
int currentRow = sourceindex.row();
|
||||||
|
{
|
||||||
|
// If the existing value in the field is the same as the completer will hit, we need to echo the
|
||||||
|
// choice into the text field because the field values are equal, so the normal echoing is considered unneccessary by the caf system.
|
||||||
|
int currentFieldIndexValue = uiField()->uiValue().toInt();
|
||||||
|
if ( currentRow == currentFieldIndexValue )
|
||||||
|
{
|
||||||
|
m_lineEdit->setText(m_completer->completionModel()->data(m_completer->currentIndex()).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v = QVariant(static_cast<unsigned int>(sourceindex.row()));
|
||||||
|
this->setValueToField(v);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Revert to value stored in the PdmField, because we didn't find any matches
|
||||||
|
this->updateUi();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QString textValue = m_lineEdit->text();
|
||||||
|
v = textValue;
|
||||||
|
this->setValueToField(v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -240,7 +314,6 @@ bool PdmUiLineEditor::isMultipleFieldsWithSameKeywordSelected(PdmFieldHandle* ed
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -274,6 +347,57 @@ void PdmUiLineEdit::keyPressEvent(QKeyEvent * event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
/// Event filter filtering events to the QCompleter
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool PdmUiLineEditor::eventFilter(QObject *watched, QEvent *event)
|
||||||
|
{
|
||||||
|
if ( event->type() == QEvent::KeyPress )
|
||||||
|
{
|
||||||
|
QKeyEvent * ke = static_cast<QKeyEvent*>(event);
|
||||||
|
|
||||||
|
if (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter)
|
||||||
|
{
|
||||||
|
m_ignoreCompleterActivated = true;
|
||||||
|
this->m_completer->popup()->close();
|
||||||
|
this->slotEditingFinished();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void PdmUiLineEditor::slotCompleterActivated(const QModelIndex& index)
|
||||||
|
{
|
||||||
|
if (m_completer && !m_ignoreCompleterActivated)
|
||||||
|
{
|
||||||
|
slotEditingFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ignoreCompleterActivated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
int PdmUiLineEditor::findIndexToOption(const QString& uiText)
|
||||||
|
{
|
||||||
|
QString uiTextTrimmed = uiText.trimmed();
|
||||||
|
for (int idx = 0; idx < m_optionCache.size(); ++idx)
|
||||||
|
{
|
||||||
|
if (uiTextTrimmed == m_optionCache[idx].optionUiText())
|
||||||
|
{
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Define at this location to avoid duplicate symbol definitions in 'cafPdmUiDefaultObjectEditor.cpp' in a cotire build. The
|
// Define at this location to avoid duplicate symbol definitions in 'cafPdmUiDefaultObjectEditor.cpp' in a cotire build. The
|
||||||
// variables defined by the macro are prefixed by line numbers causing a crash if the macro is defined at the same line number.
|
// variables defined by the macro are prefixed by line numbers causing a crash if the macro is defined at the same line number.
|
||||||
CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiLineEditor);
|
CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiLineEditor);
|
||||||
|
@ -47,6 +47,8 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class QGridLayout;
|
class QGridLayout;
|
||||||
|
class QCompleter;
|
||||||
|
class QStringListModel;
|
||||||
|
|
||||||
namespace caf
|
namespace caf
|
||||||
{
|
{
|
||||||
@ -60,11 +62,17 @@ public:
|
|||||||
PdmUiLineEditorAttribute()
|
PdmUiLineEditorAttribute()
|
||||||
{
|
{
|
||||||
avoidSendingEnterEventToParentWidget = false;
|
avoidSendingEnterEventToParentWidget = false;
|
||||||
|
completerCaseSensitivity = Qt::CaseSensitive;
|
||||||
|
completerFilterMode = Qt::MatchContains;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool avoidSendingEnterEventToParentWidget;
|
bool avoidSendingEnterEventToParentWidget;
|
||||||
QPointer<QValidator> validator;
|
QPointer<QValidator> validator;
|
||||||
|
|
||||||
|
// Completer setup
|
||||||
|
Qt::CaseSensitivity completerCaseSensitivity;
|
||||||
|
Qt::MatchFlags completerFilterMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -80,6 +88,9 @@ public:
|
|||||||
QString m_displayString;
|
QString m_displayString;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
class PdmUiLineEdit : public QLineEdit
|
class PdmUiLineEdit : public QLineEdit
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -101,7 +112,7 @@ class PdmUiLineEditor : public PdmUiFieldEditorHandle
|
|||||||
CAF_PDM_UI_FIELD_EDITOR_HEADER_INIT;
|
CAF_PDM_UI_FIELD_EDITOR_HEADER_INIT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PdmUiLineEditor() {}
|
PdmUiLineEditor() : m_ignoreCompleterActivated(false) {}
|
||||||
~PdmUiLineEditor() override {}
|
~PdmUiLineEditor() override {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -110,16 +121,25 @@ protected:
|
|||||||
void configureAndUpdateUi(const QString& uiConfigName) override;
|
void configureAndUpdateUi(const QString& uiConfigName) override;
|
||||||
QMargins calculateLabelContentMargins() const override;
|
QMargins calculateLabelContentMargins() const override;
|
||||||
|
|
||||||
|
virtual bool eventFilter(QObject *watched, QEvent *event) override;
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void slotEditingFinished();
|
void slotEditingFinished();
|
||||||
|
void slotCompleterActivated(const QModelIndex& index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isMultipleFieldsWithSameKeywordSelected(PdmFieldHandle* editorField) const;
|
bool isMultipleFieldsWithSameKeywordSelected(PdmFieldHandle* editorField) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QPointer<PdmUiLineEdit> m_lineEdit;
|
QPointer<PdmUiLineEdit> m_lineEdit;
|
||||||
QPointer<QShortenedLabel> m_label;
|
QPointer<QShortenedLabel> m_label;
|
||||||
|
|
||||||
|
QPointer<QCompleter> m_completer;
|
||||||
|
QPointer<QStringListModel> m_completerTextList;
|
||||||
|
QList<PdmOptionItemInfo> m_optionCache;
|
||||||
|
bool m_ignoreCompleterActivated;
|
||||||
|
|
||||||
|
int findIndexToOption(const QString& uiText);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user