From 7c64e78dcaac1421bc865a5c99694a7701e17ee6 Mon Sep 17 00:00:00 2001 From: asl Date: Thu, 13 Aug 2015 07:46:26 +0300 Subject: [PATCH] Issue #801: place holder for hint in input fields --- src/Config/Config_Keywords.h | 2 + .../ModuleBase_WidgetExprEditor.cpp | 50 ++++++++++++++++-- src/ModuleBase/ModuleBase_WidgetExprEditor.h | 12 +++-- src/ModuleBase/ModuleBase_WidgetFactory.cpp | 6 ++- src/ModuleBase/ModuleBase_WidgetLineEdit.cpp | 51 ++++++++++++++++++- src/ModuleBase/ModuleBase_WidgetLineEdit.h | 8 +-- src/ParametersPlugin/plugin-Parameters.xml | 4 +- 7 files changed, 117 insertions(+), 16 deletions(-) diff --git a/src/Config/Config_Keywords.h b/src/Config/Config_Keywords.h index 4a3943213..b9ee0b4a0 100644 --- a/src/Config/Config_Keywords.h +++ b/src/Config/Config_Keywords.h @@ -33,6 +33,8 @@ const static char* WDG_CHOICE = "choice"; const static char* WDG_DOUBLEVALUE_EDITOR = "doublevalue_editor"; const static char* WDG_FILE_SELECTOR= "file_selector"; const static char* WDG_EXPR_EDITOR = "expr_editor"; +const static char* WDG_PLACE_HOLDER = "placeholder"; + // Containers const static char* WDG_GROUP = "groupbox"; const static char* WDG_CHECK_GROUP = "check_groupbox"; diff --git a/src/ModuleBase/ModuleBase_WidgetExprEditor.cpp b/src/ModuleBase/ModuleBase_WidgetExprEditor.cpp index 20d8c8298..6c23c4a9a 100644 --- a/src/ModuleBase/ModuleBase_WidgetExprEditor.cpp +++ b/src/ModuleBase/ModuleBase_WidgetExprEditor.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -144,9 +145,51 @@ bool ExpressionEditor::handledCompletedAndSelected(QKeyEvent* theEvent) return true; } -ModuleBase_WidgetExprEditor::ModuleBase_WidgetExprEditor(QWidget* theParent, - const Config_WidgetAPI* theData, - const std::string& theParentId) +void ExpressionEditor::setPlaceHolderText( const QString& thePlaceHolderText ) +{ + myPlaceHolderText = thePlaceHolderText; +} + +QString ExpressionEditor::placeHolderText() const +{ + return myPlaceHolderText; +} + +void ExpressionEditor::paintEvent( QPaintEvent* theEvent ) +{ + QPlainTextEdit::paintEvent( theEvent ); + + if( toPlainText().isEmpty() ) + { + QPainter aPainter( viewport() ); + QFontMetrics aFontMetrics = fontMetrics(); + + QPointF offset(contentOffset()); + QRect r = rect(); + int m = (int)document()->documentMargin(); + QRect lineRect( r.x() + m + offset.x(), offset.y(), + r.width() - 2*m, aFontMetrics.height() ); + + Qt::Alignment va = QStyle::visualAlignment( layoutDirection(), Qt::AlignLeft ); + int minLB = qMax( 0, -aFontMetrics.minLeftBearing() ); + + QColor aColor = palette().text().color(); + aColor.setAlpha( 128 ); + QPen anOldpen = aPainter.pen(); + aPainter.setPen( aColor ); + lineRect.adjust(minLB, 0, 0, 0); + QString elidedText = aFontMetrics.elidedText( myPlaceHolderText, Qt::ElideRight, lineRect.width() ); + aPainter.drawText( lineRect, va, elidedText ); + aPainter.setPen( anOldpen ); + } +} + + + +ModuleBase_WidgetExprEditor::ModuleBase_WidgetExprEditor( QWidget* theParent, + const Config_WidgetAPI* theData, + const std::string& theParentId, + const std::string& thePlaceHolder ) : ModuleBase_ModelWidget(theParent, theData, theParentId) { QVBoxLayout* aMainLay = new QVBoxLayout(this); @@ -160,6 +203,7 @@ ModuleBase_WidgetExprEditor::ModuleBase_WidgetExprEditor(QWidget* theParent, aMainLay->addWidget(myResultLabel); myEditor = new ExpressionEditor(this); myEditor->setMinimumHeight(20); + myEditor->setPlaceHolderText( QString::fromStdString( thePlaceHolder ) ); aMainLay->addWidget(myEditor); this->setLayout(aMainLay); diff --git a/src/ModuleBase/ModuleBase_WidgetExprEditor.h b/src/ModuleBase/ModuleBase_WidgetExprEditor.h index 54262288e..c5ad7b264 100644 --- a/src/ModuleBase/ModuleBase_WidgetExprEditor.h +++ b/src/ModuleBase/ModuleBase_WidgetExprEditor.h @@ -33,6 +33,9 @@ class ExpressionEditor: public QPlainTextEdit void setCompletionList(QStringList&); + void setPlaceHolderText( const QString& ); + QString placeHolderText() const; + public slots: void insertCompletion(const QString&, bool isSingleWord = false); void performCompletion(); @@ -41,11 +44,13 @@ class ExpressionEditor: public QPlainTextEdit void performCompletion(const QString& theCompletionPrefix); virtual void keyPressEvent(QKeyEvent* theEvent); bool handledCompletedAndSelected(QKeyEvent* theEvent); + virtual void paintEvent( QPaintEvent* ); private: QStringListModel* myCompleterModel; QCompleter* myCompleter; bool myCompletedAndSelected; + QString myPlaceHolderText; }; /** @@ -60,9 +65,10 @@ class MODULEBASE_EXPORT ModuleBase_WidgetExprEditor : public ModuleBase_ModelWid /// \param theParent the parent object /// \param theData the widget configuration. /// \param theParentId is Id of a parent of the current attribute - ModuleBase_WidgetExprEditor(QWidget* theParent, - const Config_WidgetAPI* theData, - const std::string& theParentId); + ModuleBase_WidgetExprEditor( QWidget* theParent, + const Config_WidgetAPI* theData, + const std::string& theParentId, + const std::string& thePlaceHolder ); virtual ~ModuleBase_WidgetExprEditor(); virtual QList getControls() const; diff --git a/src/ModuleBase/ModuleBase_WidgetFactory.cpp b/src/ModuleBase/ModuleBase_WidgetFactory.cpp index 85fb353a7..b5d65a2cd 100644 --- a/src/ModuleBase/ModuleBase_WidgetFactory.cpp +++ b/src/ModuleBase/ModuleBase_WidgetFactory.cpp @@ -139,9 +139,11 @@ ModuleBase_ModelWidget* ModuleBase_WidgetFactory::createWidgetByType(const std:: } else if (theType == WDG_CHOICE) { result = new ModuleBase_WidgetChoice(theParent, myWidgetApi, myParentId); } else if (theType == WDG_STRINGVALUE) { - result = new ModuleBase_WidgetLineEdit(theParent, myWidgetApi, myParentId); + std::string aPlaceHolder = myWidgetApi->getProperty( WDG_PLACE_HOLDER ); + result = new ModuleBase_WidgetLineEdit( theParent, myWidgetApi, myParentId, aPlaceHolder ); } else if (theType == WDG_EXPR_EDITOR) { - result = new ModuleBase_WidgetExprEditor(theParent, myWidgetApi, myParentId); + std::string aPlaceHolder = myWidgetApi->getProperty( WDG_PLACE_HOLDER ); + result = new ModuleBase_WidgetExprEditor( theParent, myWidgetApi, myParentId, aPlaceHolder ); } else if (theType == WDG_MULTISELECTOR) { result = new ModuleBase_WidgetMultiSelector(theParent, myWorkshop, myWidgetApi, myParentId); } else if (theType == WDG_TOOLBOX) { diff --git a/src/ModuleBase/ModuleBase_WidgetLineEdit.cpp b/src/ModuleBase/ModuleBase_WidgetLineEdit.cpp index f2f5034b8..273cc9020 100644 --- a/src/ModuleBase/ModuleBase_WidgetLineEdit.cpp +++ b/src/ModuleBase/ModuleBase_WidgetLineEdit.cpp @@ -22,13 +22,53 @@ #include #include #include +#include +#include #include #include +class CustomLineEdit : public QLineEdit +{ +public: + CustomLineEdit( QWidget* theParent, const QString& thePlaceHolder ) + : QLineEdit( theParent ), myPlaceHolder( thePlaceHolder ) + { + } + + virtual ~CustomLineEdit() + { + } + + virtual void paintEvent( QPaintEvent* theEvent ) + { + QLineEdit::paintEvent( theEvent ); + if( text().isEmpty() && !myPlaceHolder.isEmpty() ) + { + QPainter aPainter( this ); + QRect aRect = rect(); + int aHorMargin = 5; + aRect.adjust( aHorMargin, 0, 0, 0 ); + + QColor aColor = palette().text().color(); + aColor.setAlpha( 128 ); + QPen anOldpen = aPainter.pen(); + aPainter.setPen( aColor ); + QFontMetrics aFontMetrics = fontMetrics(); + QString elidedText = aFontMetrics.elidedText( myPlaceHolder, Qt::ElideRight, aRect.width() ); + aPainter.drawText( aRect, Qt::AlignLeft | Qt::AlignVCenter, elidedText ); + aPainter.setPen( anOldpen ); + } + } + +private: + QString myPlaceHolder; +}; + ModuleBase_WidgetLineEdit::ModuleBase_WidgetLineEdit(QWidget* theParent, const Config_WidgetAPI* theData, - const std::string& theParentId) + const std::string& theParentId, + const std::string& thePlaceHolder ) : ModuleBase_ModelWidget(theParent, theData, theParentId) { QFormLayout* aMainLay = new QFormLayout(this); @@ -39,8 +79,15 @@ ModuleBase_WidgetLineEdit::ModuleBase_WidgetLineEdit(QWidget* theParent, if (!aLabelIcon.isEmpty()) aLabel->setPixmap(QPixmap(aLabelIcon)); - myLineEdit = new QLineEdit(this); + myLineEdit = new CustomLineEdit( this, QString::fromStdString( thePlaceHolder ) ); + // Here we do not use the Qt's standard method setPlaceHolderText() since it + // draws the place holder only if there is no focus on widget; + // we would like to see the place holder in the case of empty text + // even if the widget is focused. + // The corresponding patch appears in Qt only since version 5.x + myLineEdit->setMinimumHeight(20); + aMainLay->addRow(aLabel, myLineEdit); this->setLayout(aMainLay); diff --git a/src/ModuleBase/ModuleBase_WidgetLineEdit.h b/src/ModuleBase/ModuleBase_WidgetLineEdit.h index 624bdf917..d812bc158 100644 --- a/src/ModuleBase/ModuleBase_WidgetLineEdit.h +++ b/src/ModuleBase/ModuleBase_WidgetLineEdit.h @@ -33,9 +33,10 @@ class MODULEBASE_EXPORT ModuleBase_WidgetLineEdit : public ModuleBase_ModelWidge /// \param theParent the parent object /// \param theData the widget configuration. /// \param theParentId is Id of a parent of the current attribute - ModuleBase_WidgetLineEdit(QWidget* theParent, - const Config_WidgetAPI* theData, - const std::string& theParentId); + ModuleBase_WidgetLineEdit( QWidget* theParent, + const Config_WidgetAPI* theData, + const std::string& theParentId, + const std::string& thePlaceHolder ); virtual ~ModuleBase_WidgetLineEdit(); virtual QList getControls() const; @@ -48,7 +49,6 @@ protected: /// Saves the internal parameters to the given feature /// \return True in success virtual bool storeValueCustom() const; - virtual bool restoreValueCustom(); private: diff --git a/src/ParametersPlugin/plugin-Parameters.xml b/src/ParametersPlugin/plugin-Parameters.xml index f0dbaf3d1..3bab3831f 100644 --- a/src/ParametersPlugin/plugin-Parameters.xml +++ b/src/ParametersPlugin/plugin-Parameters.xml @@ -4,10 +4,10 @@ - + - + -- 2.30.2