23#include <QDateTimeEdit>
31#include <Poco/ActiveResult.h>
36using Mantid::Types::Core::DateAndTime;
49 : QDialog(parent), m_algorithm(), m_algName(
""), m_algProperties(), m_propertyValueMap(), m_tied_properties(),
50 m_forScript(false), m_python_arguments(), m_enabled(), m_disabled(), m_strMessage(
""), m_keepOpen(false),
51 m_msgAvailable(false), m_isInitialized(false), m_autoParseOnInit(true), m_validators(), m_noValidation(),
52 m_inputws_opts(), m_outputws_fields(), m_wsbtn_tracker(), m_keepOpenCheckBox(nullptr), m_okButton(nullptr),
53 m_exitButton(nullptr), m_observers(), m_btnTimer(), m_statusTracked(false) {
105 setWindowTitle(QString::fromStdString(
getAlgorithm()->
name()) +
" input dialog");
107 setWindowIcon(QIcon(
":/mantidplot.png"));
160 AlgorithmInputHistory::Instance().clearAlgorithmInput(
m_algName);
162 for (QStringList::const_iterator pitr =
m_algProperties.begin(); pitr != pend; ++pitr) {
165 QString pName = *pitr;
168 AlgorithmInputHistory::Instance().storeNewValue(
m_algName, QPair<QString, QString>(pName,
value));
180 m_algName = QString::fromStdString(alg->name());
183 std::vector<Mantid::Kernel::Property *>::const_iterator iend = alg->getProperties().end();
184 for (std::vector<Mantid::Kernel::Property *>::const_iterator itr = alg->getProperties().begin(); itr != iend; ++itr) {
207 return m_algorithm->getProperty(propName.toStdString());
225 if (
value.isEmpty()) {
228 return QString::fromStdString(prop->
getDefault());
245 QLabel *validLbl(
nullptr);
247 validLbl =
new QLabel(
"*",
this);
248 QPalette pal = validLbl->palette();
249 pal.setColor(QPalette::WindowText, Qt::darkRed);
250 validLbl->setPalette(pal);
251 validLbl->setVisible(
true);
285 for (QStringList::const_iterator pitr =
m_algProperties.begin(); pitr != pend; ++pitr) {
286 const QString propName = *pitr;
298 if (validator && validator->parent()) {
299 validator->setToolTip(
error);
300 validator->setVisible(
error.length() != 0);
320 std::string
error(
"");
323 }
catch (std::exception &err_details) {
324 error = err_details.what();
334 return error.empty();
347 for (QStringList::const_iterator pitr =
m_algProperties.begin(); pitr != pend; ++pitr) {
348 const QString pName = *pitr;
349 if (skipList.contains(pName)) {
358 allValid = allValid && thisValid;
365 std::map<std::string, std::string> errs =
m_algorithm->validateInputs();
366 for (
auto &err : errs) {
369 const QString pName = QString::fromStdString(err.first);
370 const QString
value = QString::fromStdString(err.second);
403 QLabel *inputMessage =
new QLabel(
this);
404 inputMessage->setFrameStyle(
static_cast<int>(QFrame::Panel) |
static_cast<int>(QFrame::Sunken));
405 QPalette pal = inputMessage->palette();
406 pal.setColor(inputMessage->backgroundRole(), QColor(255, 255, 224));
407 pal.setColor(inputMessage->foregroundRole(), Qt::black);
408 inputMessage->setPalette(pal);
409 inputMessage->setAutoFillBackground(
true);
410 inputMessage->setWordWrap(
true);
411 inputMessage->setAlignment(Qt::AlignJustify);
412 inputMessage->setMargin(3);
414 auto *msgArea =
new QHBoxLayout;
415 msgArea->addWidget(inputMessage);
416 mainLay->addLayout(msgArea, 0);
443 if (propName.isEmpty())
449 return m_algorithm->isPropertyEnabled(propName.toStdString());
491QWidget *
AlgorithmDialog::tie(QWidget *widget,
const QString &property, QLayout *parent_layout,
bool readHistory) {
497 widget->setToolTip(QString::fromStdString(prop->
documentation()));
501 PropertyWidget *propWidget = qobject_cast<PropertyWidget *>(widget);
508 QWidget *validlbl(
nullptr);
516 item_index = parent_layout->indexOf(propWidget->
getMainWidget());
518 item_index = parent_layout->indexOf(widget);
520 if (QBoxLayout *box = qobject_cast<QBoxLayout *>(parent_layout)) {
521 box->insertWidget(item_index + 1, validlbl);
522 }
else if (QGridLayout *grid = qobject_cast<QGridLayout *>(parent_layout)) {
523 int row(0), col(0), span(0);
524 grid->getItemPosition(item_index, &row, &col, &span, &span);
525 grid->addWidget(validlbl, row, col + 2);
539 QLineEdit *textfield = qobject_cast<QLineEdit *>(widget);
557 if (propName.isEmpty())
579 std::vector<std::string> items =
property->allowedValues();
580 std::vector<std::string>::const_iterator vend = items.end();
581 for (std::vector<std::string>::const_iterator vitr = items.begin(); vitr != vend; ++vitr) {
582 optionsBox->addItem(QString::fromStdString(*vitr));
586 QString displayed(
"");
588 displayed = AlgorithmInputHistory::Instance().previousInput(
m_algName, propName);
590 if (displayed.isEmpty()) {
591 displayed = QString::fromStdString(property->value());
594 int index = optionsBox->findText(displayed);
596 optionsBox->setCurrentIndex(
index);
608 textField->setText(AlgorithmInputHistory::Instance().previousInput(
m_algName, propName));
611 if (property && property->isValid().empty() && (
m_python_arguments.contains(propName) || !property->isDefault())) {
612 textField->setText(QString::fromStdString(property->value()));
620 const QString &cancelText,
const QString &keepOpenText) {
628 auto *buttonRowLayout =
new QHBoxLayout;
630 buttonRowLayout->addStretch();
636 if (keepOpenText.isEmpty()) {
643 return buttonRowLayout;
653 auto *help =
new QPushButton(helpText);
654 connect(help, SIGNAL(clicked()),
this, SLOT(
helpClicked()));
685 QMessageBox::critical(
this,
"",
686 "One or more properties are invalid. The invalid properties are\n"
687 "marked with a *, hold your mouse over the * for more information.");
731 observer->observeAll(algToExec);
747 algToExec->executeAsync();
753 }
catch (Poco::NoThreadAvailableException &) {
754 g_log.
error() <<
"No thread was available to run the " << algToExec->name() <<
" algorithm in the background.\n";
762 AlgorithmManager::Instance().removeById(
m_algorithm->getAlgorithmID());
777 while (itr.hasNext()) {
795 if (presetValues.isEmpty())
797 QHashIterator<QString, QString> itr(presetValues);
799 while (itr.hasNext()) {
801 QString
name = itr.key();
803 QString
value = itr.value();
866 if (message.isEmpty())
883 if (QComboBox *opts = qobject_cast<QComboBox *>(widget)) {
884 return opts->currentText().trimmed();
885 }
else if (QLineEdit *textfield = qobject_cast<QLineEdit *>(widget)) {
886 return textfield->text().trimmed();
887 }
else if (QAbstractButton *checker = qobject_cast<QAbstractButton *>(widget)) {
888 if (checker->isChecked())
892 }
else if (QDateTimeEdit *dateEdit = qobject_cast<QDateTimeEdit *>(widget)) {
894 QString
value = dateEdit->dateTime().toString(Qt::ISODate);
896 }
else if (
const MantidWidget *mtd_widget = qobject_cast<MantidWidget *>(widget)) {
897 return mtd_widget->getUserInput().toString().trimmed();
898 }
else if (
const PropertyWidget *propWidget = qobject_cast<PropertyWidget *>(widget)) {
899 return propWidget->getValue().trimmed();
901 QMessageBox::warning(
this, windowTitle(),
902 QString(
"Cannot parse input from ") + widget->metaObject()->className() +
903 ". Update AlgorithmDialog::getValue() to cope with this widget.");
914 value = AlgorithmInputHistory::Instance().previousInput(
m_algName, propName);
950 if (QComboBox *opts = qobject_cast<QComboBox *>(widget)) {
951 if (property &&
value.isEmpty()) {
952 value = QString::fromStdString(property->value());
956 opts->setCurrentIndex(
index);
960 if (QAbstractButton *checker = qobject_cast<QAbstractButton *>(widget)) {
962 value = QString::fromStdString(property->value());
963 checker->setChecked(
value !=
"0");
966 if (QDateTimeEdit *dateEdit = qobject_cast<QDateTimeEdit *>(widget)) {
968 DateAndTime t = DateAndTime::getCurrentTime();
971 }
catch (std::exception &) {
973 dateEdit->setDate(QDate(t.year(), t.month(), t.day()));
974 dateEdit->setTime(QTime(t.hour(), t.minute(), t.second(), 0));
978 QLineEdit *textfield = qobject_cast<QLineEdit *>(widget);
979 MantidWidget *mtdwidget = qobject_cast<MantidWidget *>(widget);
980 if (textfield || mtdwidget) {
983 textfield->setText(
value);
991 textfield->setText(
value);
999 PropertyWidget *propWidget = qobject_cast<PropertyWidget *>(widget);
1010 QMessageBox::warning(
this, windowTitle(),
1011 QString(
"Cannot set value for ") + widget->metaObject()->className() +
1012 ". Update AlgorithmDialog::setValue() to cope with this widget.");
1063 QDialog::closeEvent(evt);
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
void disableExitButton()
Disable the exit button.
bool isMessageAvailable() const
Is there a message string available.
void addEnabledAndDisableLists(const QStringList &enabled, const QStringList &disabled)
Set comma-separated-list of enabled parameter names.
QStringList m_enabled
A list of property names that should have their widgets enabled.
void algCompletedSignal()
Emitted when alg completes and dialog is staying open.
virtual void executeAlgorithmAsync()
Executes the algorithm in a separate thread.
void setAlgorithm(const Mantid::API::IAlgorithm_sptr &)
The following methods were made public for testing in GenericDialogDemo.cpp.
bool requestedToKeepEnabled(const QString &propName) const
Test if the given name's widget has been explicity asked to be enabled.
QPushButton * createHelpButton(const QString &helpText=QString("?")) const
Create a help button for this algorithm.
virtual void algorithmCompleted()
Keep the running algorithm has completed.
virtual void removeAlgorithmFromManager()
Removes the algorithm from the manager.
bool m_statusTracked
A flag to track whether the status of the algorithm is being tracked.
bool setPropertyValues(const QStringList &skipList=QStringList())
Set properties on this algorithm by pulling values from the tied widgets.
void setShowKeepOpen(const bool showOption)
Set if the keep open option is shown.
QString getPreviousValue(const QString &propName) const
Get the property value from either the previous input store or from Python argument.
QStringList m_python_arguments
A list of property names that have been passed from Python.
virtual void parseInput()
Parse out the values entered into the dialog boxes.
QString m_strMessage
The message string to be displayed at the top of the widget; if it exists.
bool isWidgetEnabled(const QString &propName) const
Check is a given property should have its control enabled or not.
~AlgorithmDialog() override
Destructor.
QString getInputValue(const QString &propName) const
Get an input value from the form, dealing with blank inputs etc.
QHash< QString, QWidget * > m_tied_properties
A list pointers to the widget for each property.
QVector< QWidget * > m_inputws_opts
Store a list of the names of input workspace boxes.
QStringList m_disabled
A list of property names that the user has requested to be disabled (overrides those in enabled)
bool isForScript() const
Get the usage boolean value.
bool requiresUserInput(const QString &propName) const
Return a true if the given property requires user input.
bool m_forScript
A boolean indicating whether this is for a script or not.
void setOptionalMessage(const QString &message)
Set an optional message to be displayed at the top of the dialog.
void enableExitButton()
Enable to exit button.
void executeOnAccept(bool on)
If true then execute the algorithm on acceptance.
virtual void initLayout()=0
This does the work and must be overridden in each deriving class.
QString getValue(QWidget *widget)
Retrieve a text value for a property from a widget.
bool m_autoParseOnInit
Flag if the input should be parsed automatically on initialization.
void fillAndSetComboBox(const QString &propName, QComboBox *optionsBox) const
Fill a combo box for the named algorithm's allowed values.
Mantid::API::IAlgorithm_sptr m_algorithm
The algorithm associated with this dialog.
bool setPropertyValue(const QString &pName, bool validateOthers)
Sets the value of a single property, using the value previously stored using storePropertyValue()
AlgorithmDialog(QWidget *parent=nullptr)
DefaultConstructor.
void reject() override
A default slot that can be used for a rejected button.
void errorHandle(const Mantid::API::IAlgorithm *alg, const std::string &what) override
Handle completion of algorithm started while staying open.
bool m_msgAvailable
Is the message string empty or not.
QString openFileDialog(const QString &propName)
Open a file dialog to select a file.
QHash< QString, QString > m_errors
A map where key = property name; value = the error for this property (i.e.
QHash< QString, QString > m_propertyValueMap
A map of property <name, value> pairs that have been taken from the dialog.
QString m_algName
The name of the algorithm.
bool m_keepOpen
Whether to keep the dialog box open after alg execution.
virtual void helpClicked()
Help button clicked;.
QLabel * getValidatorMarker(const QString &propname)
Get a property validator label.
std::vector< Mantid::API::AlgorithmObserver * > m_observers
A list of AlgorithmObservers to add to the algorithm prior to execution.
void closeEvent(QCloseEvent *evt) override
Only allow close when close is enabled.
QLayout * createDefaultButtonLayout(const QString &helpText=QString("?"), const QString &loadText=QString("Run"), const QString &cancelText=QString("Close"), const QString &keepOpenText=QString("Keep Open"))
Create a row layout of buttons with specified text.
void initializeLayout()
Create the layout of the widget. Can only be called once.
void storePropertyValue(const QString &name, const QString &value)
Adds a property (name,value) pair to the stored map.
QVector< QLineEdit * > m_outputws_fields
Store a list of output workspace text edits.
QPushButton * m_exitButton
void addAlgorithmObserver(Mantid::API::AlgorithmObserver *observer)
Add an AlgorithmObserver to the algorithm.
void parse()
Parse out the input from the dialog.
void removePropertyValue(const QString &name)
Removes a property (name, value) pair from the stored map.
void fillLineEdit(const QString &propName, QLineEdit *field)
Fill in the necessary input for a text field.
QWidget * tie(QWidget *widget, const QString &property, QLayout *parent_layout=nullptr, bool readHistory=true)
Tie a widget to a property.
QTimer m_btnTimer
Enable the close button when the timer fires.
void setPresetValues(const QHash< QString, QString > &presetValues)
Set a list of suggested values.
Mantid::API::IAlgorithm_sptr getAlgorithm() const
Get the algorithm pointer.
void setPreviousValue(QWidget *widget, const QString &property)
Set a value based on any old input that we have.
void flagInputWS(QWidget *inputWidget)
Flag an input workspace combobox with its property name.
void addOptionalMessage(QVBoxLayout *mainLay)
Add the optional message to the given layout.
QStringList m_algProperties
The properties associated with this dialog.
Mantid::Kernel::Property * getAlgorithmProperty(const QString &propName) const
Get a pointer to the named property.
QStringList m_noValidation
A list of property names whose widgets handle their own validation.
virtual void saveInput()
Save the input history of an accepted dialog.
void showValidators()
Show the validators for all the properties.
void untie(const QString &property)
Untie a widget to a property.
void accept() override
A default slot that can be used for an OK button.
bool isShowKeepOpen() const
Set if the keep open option is shown.
virtual void keepOpenChanged(int state)
Keep open checkbox clicked;.
bool isInitialized() const
Is this dialog initialized.
void finishHandle(const Mantid::API::IAlgorithm *alg) override
Handle completion of algorithm started while staying open.
bool m_isInitialized
Whether the layout has been initialized.
QHash< QPushButton *, int > m_wsbtn_tracker
A map to keep track of replace workspace button presses.
QCheckBox * m_keepOpenCheckBox
const QString & getOptionalMessage() const
Get the message string.
QHash< QString, QLabel * > m_validators
A list of labels to use as validation markers.
static void showAlgorithm(const std::string &name=std::string(), const int version=-1)
Observes Algorithm notifications: start,progress,finish,error.
void observeFinish(const IAlgorithm_const_sptr &alg)
Connect to algorithm alg and observe its finish notification.
void stopObserving(const IAlgorithm_const_sptr &alg)
Disconnect from algorithm alg.
void observeError(const IAlgorithm_const_sptr &alg)
Connect to algorithm alg and observe its error notification.
IAlgorithm is the interface implemented by the Algorithm base class.
An interface that is implemented by WorkspaceProperty.
The Logger class is in charge of the publishing messages from the framework through various channels.
void error(const std::string &msg)
Logs at error level.
The concrete, templated class for properties.
Base class for properties.
bool isDynamicDefault() const
Returns a flag indicating that the property's value has been set programmatically,...
unsigned int direction() const
returns the direction of the property
const std::string & documentation() const
Get the property's documentation string.
bool remember() const
Whether to save input values.
virtual std::string isValid() const
Overridden function that checks whether the property, if not overriden returns "".
virtual bool isDefault() const =0
Overriden function that returns if property has the same value that it was initialised with,...
const std::string & name() const
Get the property's name.
virtual std::string getDefault() const =0
Get the default value for the property which is the value the property was initialised with.
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
MANTID_KERNEL_DLL std::string verifyAndSanitizeISO8601(const std::string &date, bool displayWarnings=true)
Verifies whether or not a string conforms to ISO8601.
Logger g_log("DateAndTime")
@ Output
An output workspace.