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";
// Containers
const static char* WDG_GROUP = "groupbox";
const static char* WDG_CHECK_GROUP = "check_groupbox";
// Created: 07 Jul 2014
// Author: Vitaly SMETANNIKOV
-#ifndef ModelAPI_ResultParameters_H_
-#define ModelAPI_ResultParameters_H_
+#ifndef MODELAPI_RESULTPARAMETERS_H_
+#define MODELAPI_RESULTPARAMETERS_H_
#include "ModelAPI_Result.h"
ModuleBase_WidgetSwitch.h
ModuleBase_WidgetToolbox.h
ModuleBase_WidgetValidated.h
+ ModuleBase_WidgetExprEditor.h
)
SET(PROJECT_SOURCES
ModuleBase_WidgetSwitch.cpp
ModuleBase_WidgetToolbox.cpp
ModuleBase_WidgetValidated.cpp
+ ModuleBase_WidgetExprEditor.cpp
)
SET(PROJECT_LIBRARIES
--- /dev/null
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+/*
+ * ModuleBase_WidgetExprEditor.cpp
+ *
+ * Created on: Aug 28, 2014
+ * Author: sbh
+ */
+
+#include <ModuleBase_WidgetExprEditor.h>
+#include <ModuleBase_Tools.h>
+
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Object.h>
+#include <ModelAPI_Validator.h>
+
+#include <Config_WidgetAPI.h>
+
+#include <QVBoxLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <QObject>
+#include <QString>
+#include <QStringListModel>
+#include <QCompleter>
+#include <QSize>
+#include <QShortcut>
+#include <QScrollBar>
+
+#include <memory>
+#include <string>
+
+ExpressionEditor::ExpressionEditor(QWidget* theParent)
+: QPlainTextEdit(theParent)
+{
+ myCompleter = new QCompleter(this);
+ myCompleter->setWidget(this);
+ myCompleter->setCompletionMode(QCompleter::PopupCompletion);
+
+ myCompleterModel = new QStringListModel(this);
+ myCompleter->setModel(myCompleterModel);
+ // Use sorted model to accelerate completion (QCompleter will use binary search)
+ myCompleter->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
+ myCompleter->setCaseSensitivity(Qt::CaseInsensitive);
+
+ connect(myCompleter, SIGNAL(activated(const QString&)),
+ this, SLOT(insertCompletion(const QString&)));
+ (void) new QShortcut(QKeySequence(tr("Ctrl+Space", "Complete")),
+ this, SLOT(performCompletion()));
+}
+
+ExpressionEditor::~ExpressionEditor()
+{
+
+}
+
+void ExpressionEditor::setCompletionList(QStringList& theList)
+{
+ theList.sort();
+ theList.removeDuplicates();
+ myCompleterModel->setStringList(theList);
+}
+
+void ExpressionEditor::insertCompletion(const QString& theCompletion, bool isSingleWord)
+{
+ QTextCursor aCursor = textCursor();
+ int numberOfCharsToComplete = theCompletion.length() -
+ myCompleter->completionPrefix().length();
+ int insertionPosition = aCursor.position();
+ aCursor.insertText(theCompletion.right(numberOfCharsToComplete));
+ if (isSingleWord) {
+ aCursor.setPosition(insertionPosition);
+ aCursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+ myCompletedAndSelected = true;
+ }
+ setTextCursor(aCursor);
+}
+
+void ExpressionEditor::performCompletion()
+{
+ QTextCursor aCursor = textCursor();
+ aCursor.select(QTextCursor::WordUnderCursor);
+ const QString aPrefix = aCursor.selectedText();
+ if (!aPrefix.isEmpty() && aPrefix.at(aPrefix.length() - 1).isLetter()) {
+ performCompletion(aPrefix);
+ }
+}
+
+void ExpressionEditor::performCompletion(const QString& theCompletionPrefix)
+{
+ //populate model?
+ if (theCompletionPrefix != myCompleter->completionPrefix()) {
+ myCompleter->setCompletionPrefix(theCompletionPrefix);
+ myCompleter->popup()->setCurrentIndex(myCompleter->completionModel()->index(0, 0));
+ }
+ if (myCompleter->completionCount() == 1) {
+ insertCompletion(myCompleter->currentCompletion(), true);
+ } else {
+ QRect aRect = cursorRect();
+ aRect.setWidth(myCompleter->popup()->sizeHintForColumn(0)
+ + myCompleter->popup()->verticalScrollBar()->sizeHint().width());
+ myCompleter->complete(aRect);
+ }
+}
+
+void ExpressionEditor::keyPressEvent(QKeyEvent* theEvent)
+{
+ if (myCompletedAndSelected && handledCompletedAndSelected(theEvent))
+ return;
+ myCompletedAndSelected = false;
+ if (myCompleter->popup()->isVisible()) {
+ switch (theEvent->key()) {
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ case Qt::Key_Escape:
+ theEvent->ignore();
+ return;
+ default:
+ myCompleter->popup()->hide();
+ break;
+ }
+ }
+ QPlainTextEdit::keyPressEvent(theEvent);
+}
+
+bool ExpressionEditor::handledCompletedAndSelected(QKeyEvent* theEvent)
+{
+ myCompletedAndSelected = false;
+ QTextCursor aCursor = textCursor();
+ switch (theEvent->key()) {
+ case Qt::Key_Enter:
+ case Qt::Key_Return: aCursor.clearSelection(); break;
+ case Qt::Key_Escape: aCursor.removeSelectedText(); break;
+ default: return false;
+ }
+ setTextCursor(aCursor);
+ theEvent->accept();
+ return true;
+}
+
+ModuleBase_WidgetExprEditor::ModuleBase_WidgetExprEditor(QWidget* theParent,
+ const Config_WidgetAPI* theData,
+ const std::string& theParentId)
+ : ModuleBase_ModelWidget(theParent, theData, theParentId)
+{
+ QVBoxLayout* aMainLay = new QVBoxLayout(this);
+ ModuleBase_Tools::adjustMargins(aMainLay);
+
+ myEditor = new ExpressionEditor(this);
+ myEditor->setMinimumHeight(20);
+ aMainLay->addWidget(myEditor);
+ this->setLayout(aMainLay);
+
+ connect(myEditor, SIGNAL(textChanged()), this, SLOT(onTextChanged()));
+}
+
+ModuleBase_WidgetExprEditor::~ModuleBase_WidgetExprEditor()
+{
+}
+
+bool ModuleBase_WidgetExprEditor::storeValueCustom() const
+{
+ // A rare case when plugin was not loaded.
+ if(!myFeature)
+ return false;
+ DataPtr aData = myFeature->data();
+ AttributeStringPtr aStringAttr = aData->string(attributeID());
+ QString aWidgetValue = myEditor->toPlainText();
+ aStringAttr->setValue(aWidgetValue.toStdString());
+ updateObject(myFeature);
+ return true;
+}
+
+bool ModuleBase_WidgetExprEditor::restoreValue()
+{
+ // A rare case when plugin was not loaded.
+ if(!myFeature)
+ return false;
+ DataPtr aData = myFeature->data();
+ AttributeStringPtr aStringAttr = aData->string(attributeID());
+
+ bool isBlocked = myEditor->blockSignals(true);
+ QTextCursor aCursor = myEditor->textCursor();
+ int pos = aCursor.position();
+ std::string aRestoredStr = aStringAttr->value();
+ myEditor->setPlainText(QString::fromStdString(aRestoredStr));
+ aCursor.setPosition(pos);
+ myEditor->setTextCursor(aCursor);
+ myEditor->blockSignals(isBlocked);
+
+ return true;
+}
+
+QList<QWidget*> ModuleBase_WidgetExprEditor::getControls() const
+{
+ QList<QWidget*> result;
+ result << myEditor;
+ return result;
+}
+
+void ModuleBase_WidgetExprEditor::onTextChanged()
+{
+ storeValue();
+}
--- /dev/null
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+/*
+ * ModuleBase_WidgetExprEditor.h
+ *
+ * Created on: Oct 8, 2014
+ * Author: sbh
+ */
+
+#ifndef MODULEBASE_WIDGETEXPREDITOR_H_
+#define MODULEBASE_WIDGETEXPREDITOR_H_
+
+#include <ModuleBase.h>
+#include <ModuleBase_ModelWidget.h>
+
+#include <QList>
+#include <QString>
+#include <QStringList>
+#include <QPlainTextEdit>
+
+class QWidget;
+class QStringListModel;
+class QCompleter;
+
+class ExpressionEditor: public QPlainTextEdit
+{
+ Q_OBJECT
+
+ public:
+ explicit ExpressionEditor(QWidget* theParent = 0);
+ virtual ~ExpressionEditor();
+
+ void setCompletionList(QStringList&);
+
+ public slots:
+ void insertCompletion(const QString&, bool isSingleWord = false);
+ void performCompletion();
+
+ protected:
+ void performCompletion(const QString& theCompletionPrefix);
+ virtual void keyPressEvent(QKeyEvent* theEvent);
+ bool handledCompletedAndSelected(QKeyEvent* theEvent);
+
+ private:
+ QStringListModel* myCompleterModel;
+ QCompleter* myCompleter;
+ bool myCompletedAndSelected;
+};
+
+/**
+* \ingroup GUI
+* TODO(sbh) add doc
+*/
+class MODULEBASE_EXPORT ModuleBase_WidgetExprEditor : public ModuleBase_ModelWidget
+{
+ Q_OBJECT
+ public:
+ /// Constructor
+ /// \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);
+ virtual ~ModuleBase_WidgetExprEditor();
+
+ virtual bool restoreValue();
+
+ virtual QList<QWidget*> getControls() const;
+
+ public slots:
+ /// A slot for processing text changed event
+ void onTextChanged();
+
+protected:
+ /// Saves the internal parameters to the given feature
+ /// \return True in success
+ virtual bool storeValueCustom() const;
+
+private:
+ /// A line edit control
+ ExpressionEditor* myEditor;
+};
+
+#endif /* MODULEBASE_WIDGETEXPREDITOR_H_ */
#include <ModuleBase_Operation.h>
#include <ModuleBase_OperationDescription.h>
-//#include <ModuleBase_WidgetFeatureOrAttribute.h>
-//#include <ModuleBase_WidgetFeature.h>
#include <ModuleBase_WidgetEditor.h>
#include <ModuleBase_WidgetSwitch.h>
#include <ModuleBase_WidgetShapeSelector.h>
#include <ModuleBase_WidgetDoubleValue.h>
#include <ModuleBase_WidgetBoolValue.h>
-//#include <ModuleBase_WidgetPoint2dDistance.h>
#include <ModuleBase_WidgetFileSelector.h>
#include <ModuleBase_WidgetChoice.h>
#include <ModuleBase_IWorkshop.h>
#include <ModuleBase_PageBase.h>
#include <ModuleBase_PageGroupBox.h>
#include <ModuleBase_PageWidget.h>
+#include <ModuleBase_WidgetExprEditor.h>
#include <ModelAPI_Validator.h>
#include <ModelAPI_Session.h>
thePage->alignToTop();
}
-ModuleBase_ModelWidget* ModuleBase_WidgetFactory
-::createWidgetByType(const std::string& theType, QWidget* theParent)
+ModuleBase_ModelWidget* ModuleBase_WidgetFactory::createWidgetByType(const std::string& theType,
+ QWidget* theParent)
{
ModuleBase_ModelWidget* result = NULL;
if (theType == WDG_INFO) {
result = new ModuleBase_WidgetLabel(theParent, myWidgetApi, myParentId);
-
} else if (theType == WDG_DOUBLEVALUE) {
result = new ModuleBase_WidgetDoubleValue(theParent, myWidgetApi, myParentId);
-
} else if (theType == WDG_SHAPE_SELECTOR) {
- result = new ModuleBase_WidgetShapeSelector(theParent, myWorkshop, myWidgetApi, myParentId);
-
+ result = new ModuleBase_WidgetShapeSelector(theParent, myWorkshop, myWidgetApi, myParentId);
} else if (theType == WDG_BOOLVALUE) {
result = new ModuleBase_WidgetBoolValue(theParent, myWidgetApi, myParentId);
-
} else if (theType == WDG_DOUBLEVALUE_EDITOR) {
result = new ModuleBase_WidgetEditor(theParent, myWidgetApi, myParentId);
-
} else if (theType == WDG_FILE_SELECTOR) {
result = new ModuleBase_WidgetFileSelector(theParent, myWidgetApi, myParentId);
-
} else if (theType == WDG_CHOICE) {
- result = new ModuleBase_WidgetChoice(theParent, myWidgetApi,myParentId);
-
+ result = new ModuleBase_WidgetChoice(theParent, myWidgetApi, myParentId);
} else if (theType == WDG_STRINGVALUE) {
- result = new ModuleBase_WidgetLineEdit(theParent, myWidgetApi,myParentId);
-
+ result = new ModuleBase_WidgetLineEdit(theParent, myWidgetApi, myParentId);
+ } else if (theType == WDG_EXPR_EDITOR) {
+ result = new ModuleBase_WidgetExprEditor(theParent, myWidgetApi, myParentId);
} else if (theType == WDG_MULTISELECTOR) {
- result = new ModuleBase_WidgetMultiSelector(theParent, myWorkshop, myWidgetApi,myParentId);
-
+ result = new ModuleBase_WidgetMultiSelector(theParent, myWorkshop, myWidgetApi, myParentId);
} else if (theType == WDG_TOOLBOX) {
result = new ModuleBase_WidgetToolbox(theParent, myWidgetApi, myParentId);
-
} else if (theType == WDG_SWITCH) {
result = new ModuleBase_WidgetSwitch(theParent, myWidgetApi, myParentId);
-
} else if (theType == WDG_TOOLBOX_BOX || theType == WDG_SWITCH_CASE) {
// Do nothing for "box" and "case"
result = NULL;
} else {
- result = myWorkshop->module()->createWidgetByType(theType, theParent, myWidgetApi,
- myParentId);
-#ifdef _DEBUG
- if (!result) {qDebug("ModuleBase_WidgetFactory::fillWidget: find bad widget type");}
-#endif
+ result = myWorkshop->module()->createWidgetByType(theType, theParent, myWidgetApi, myParentId);
+ #ifdef _DEBUG
+ if (!result) {
+ qDebug("ModuleBase_WidgetFactory::fillWidget: find bad widget type");
+ }
+ #endif
}
if (result) {
myModelWidgets.append(result);
{
QFormLayout* aMainLay = new QFormLayout(this);
ModuleBase_Tools::adjustMargins(aMainLay);
- QString aTitle = QString::fromStdString(theData->widgetLabel());
+ QString aLabelText = QString::fromStdString(theData->widgetLabel());
+ QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
+ QLabel* aLabel = new QLabel(aLabelText, this);
+ if (!aLabelIcon.isEmpty())
+ aLabel->setPixmap(QPixmap(aLabelIcon));
+
myLineEdit = new QLineEdit(this);
myLineEdit->setMinimumHeight(20);
- aMainLay->addRow(aTitle, myLineEdit);
+ aMainLay->addRow(aLabel, myLineEdit);
this->setLayout(aMainLay);
connect(myLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged()));
<workbench id="Part">
<group id="Parameters">
<feature id="Parameter" title="New Variable" tooltip="Creates a variable" icon=":pictures/expression.png">
- <stringvalue id="variable" label="Name"/>
- <stringvalue id="expression" icon="Value"/>
+ <stringvalue id="variable" label="Name" icon=":pictures/expression.png"/>
+ <expr_editor id="expression"/>
</feature>
</group>
</workbench>