Skip to content
Snippets Groups Projects
AlgorithmDialog.cpp 36.4 KiB
Newer Older
#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/IWorkspaceProperty.h"
#include "MantidKernel/DateAndTimeHelpers.h"
#include "MantidKernel/IPropertySettings.h"
#include "MantidKernel/Logger.h"

#include "MantidQtWidgets/Common/AlgorithmDialog.h"
#include "MantidQtWidgets/Common/AlgorithmInputHistory.h"
#include "MantidQtWidgets/Common/FilePropertyWidget.h"
#include "MantidQtWidgets/Common/HelpWindow.h"
#include "MantidQtWidgets/Common/MantidWidget.h"
#include <QCheckBox>
#include <QCloseEvent>
#include <QComboBox>
#include <QDateTimeEdit>
#include <QHBoxLayout>
#include <QMessageBox>

#include <Poco/ActiveResult.h>
using namespace Mantid::Kernel::DateAndTimeHelpers;
using Mantid::API::IAlgorithm;
using Mantid::Types::Core::DateAndTime;
namespace {
Mantid::Kernel::Logger g_log("AlgorithmDialog");
//------------------------------------------------------
// Public member functions
//------------------------------------------------------
/**
 * Default Constructor
 */
AlgorithmDialog::AlgorithmDialog(QWidget *parent)
    : QDialog(parent), m_algorithm(), m_algName(""), m_algProperties(),
      m_propertyValueMap(), m_tied_properties(), m_forScript(false),
      m_python_arguments(), m_enabled(), m_disabled(), m_strMessage(""),
      m_keepOpen(false), m_msgAvailable(false), m_isInitialized(false),
      m_autoParseOnInit(true), m_validators(), m_noValidation(),
      m_inputws_opts(), m_outputws_fields(), m_wsbtn_tracker(),
      m_keepOpenCheckBox(nullptr), m_okButton(nullptr), m_exitButton(nullptr),
      m_observers(), m_btnTimer(), m_statusTracked(false) {
  m_btnTimer.setSingleShot(true);
AlgorithmDialog::~AlgorithmDialog() {
  m_observers.clear();
    this->stopObserving(m_algorithm);
}

/**
 * Set if the keep open option is shown.
 * This must be set after calling initializeLayout.
 * @param showOption false to hide the control, otherwise true
 */
void AlgorithmDialog::setShowKeepOpen(const bool showOption) {
  if (m_keepOpenCheckBox) {
    // if hidden then turn it off
    if (!showOption) {
      m_keepOpenCheckBox->setCheckState(Qt::CheckState::Unchecked);
    }
    m_keepOpenCheckBox->setVisible(showOption);
  }
}
/**
 * Is the keep open option going to be shown?
 * @returns true if it will be shown
 */
bool AlgorithmDialog::isShowKeepOpen() const {
  bool retval = true;
  if (m_keepOpenCheckBox) {
    retval = m_keepOpenCheckBox->isVisible();
  }
  return retval;
 *
 * The default is to execute the algorithm when accept() is called. This
 * assumes that the AlgorithmManager owns the
 * algorithm pointer as it must survive after the dialog is destroyed.
void AlgorithmDialog::initializeLayout() {
  if (isInitialized())
    return;
  // Set a common title
  setWindowTitle(QString::fromStdString(getAlgorithm()->name()) +
                 " input dialog");
  // Set the icon
  setWindowIcon(QIcon(":/MantidPlot_Icon_32offset.png"));
  // These containers are for ensuring the 'replace input workspace; button
  // works correctly
  // Store all combo boxes that relate to an input workspace
  // Store all line edit fields that relate to an output workspace name
  // Keep track of the input workspace that has been used to fill the output
  // workspace. Each button click
  // cycles through all of the input workspaces
  // This derived class function creates the layout of the widget. It can also
  // add default input if the
    // Check if there is any default input
    // Unless told not to, try to set these values. This will validate the
    // defaults and mark those that are invalid, if any.
  connect(this, SIGNAL(algCompletedSignal()), this, SLOT(algorithmCompleted()));
}

/**
 * Has this dialog been initialized yet
 *  @returns Whether initialzedLayout has been called yet
 */
bool AlgorithmDialog::isInitialized() const { return m_isInitialized; }

//------------------------------------------------------
// Protected member functions
//------------------------------------------------------
 * Parse input from widgets on the dialog. This function does nothing in the
void AlgorithmDialog::parseInput() {}

//-------------------------------------------------------------------------------------------------
/**
 * Save the property values to the input history
 */
void AlgorithmDialog::saveInput() {
  AlgorithmInputHistory::Instance().clearAlgorithmInput(m_algName);
  QStringList::const_iterator pend = m_algProperties.end();
  for (QStringList::const_iterator pitr = m_algProperties.begin(); pitr != pend;
       ++pitr) {
    Mantid::Kernel::Property *p = getAlgorithmProperty(*pitr);
    if (p->remember()) {
      QString pName = *pitr;
      QString value = m_propertyValueMap.value(pName);
      AlgorithmInputHistory::Instance().storeNewValue(
          m_algName, QPair<QString, QString>(pName, value));
//-------------------------------------------------------------------------------------------------
/**
 * Set the algorithm pointer
 * @param alg :: A pointer to the algorithm
 */
void AlgorithmDialog::setAlgorithm(Mantid::API::IAlgorithm_sptr alg) {
  m_algorithm = alg;
  m_algName = QString::fromStdString(alg->name());
  m_algProperties.clear();
  m_tied_properties.clear();
  std::vector<Mantid::Kernel::Property *>::const_iterator iend =
      alg->getProperties().end();
  for (std::vector<Mantid::Kernel::Property *>::const_iterator itr =
           alg->getProperties().begin();
       itr != iend; ++itr) {
    if (dynamic_cast<Mantid::API::IWorkspaceProperty *>(p) ||
        p->direction() != Mantid::Kernel::Direction::Output) {
      m_algProperties.append(QString::fromStdString(p->name()));
/**
 * Get the algorithm pointer
 * @returns A pointer to the algorithm that is associated with the dialog
 */
Mantid::API::IAlgorithm_sptr AlgorithmDialog::getAlgorithm() const {
 * @param propName :: The name of the property
Mantid::Kernel::Property *
AlgorithmDialog::getAlgorithmProperty(const QString &propName) const {
  if (m_algProperties.contains(propName)) {
    return m_algorithm->getProperty(propName.toStdString());
/**
 * Return a true if the given property requires user input
 * @param propName :: The name of the property
 */
bool AlgorithmDialog::requiresUserInput(const QString &propName) const {
//-------------------------------------------------------------------------------------------------
 * Get an input value from the form, dealing with blank inputs etc
 * @param propName :: The name of the property
 */
QString AlgorithmDialog::getInputValue(const QString &propName) const {
  QString value = m_propertyValueMap.value(propName);
  if (value.isEmpty()) {
    Mantid::Kernel::Property *prop = getAlgorithmProperty(propName);
    if (prop)
      return QString::fromStdString(prop->getDefault());
    else
      return "";
//-------------------------------------------------------------------------------------------------
/** Get or make a property validator label (that little red star)
 *
 * @param propname :: name of the Property
 * @return the QLabel pointer. Will create one if needed.
QLabel *AlgorithmDialog::getValidatorMarker(const QString &propname) {
  if (m_noValidation.contains(propname))
    return nullptr;
  QLabel *validLbl(nullptr);
  if (!m_validators.contains(propname)) {
    validLbl = new QLabel("*", this);
    QPalette pal = validLbl->palette();
    pal.setColor(QPalette::WindowText, Qt::darkRed);
    validLbl->setPalette(pal);
    validLbl->setVisible(true);
    validLbl = m_validators.value(propname);
  }
  return validLbl;
//-------------------------------------------------------------------------------------------------
/**
 * Adds a property (name,value) pair to the stored map
 */
void AlgorithmDialog::storePropertyValue(const QString &name,
                                         const QString &value) {
  if (name.isEmpty())
    return;
//-------------------------------------------------------------------------------------------------
/**
 * Adds a property (name,value) pair to the stored map.
 * @param name :: The name of the property.
 */
void AlgorithmDialog::removePropertyValue(const QString &name) {
  if (name.isEmpty())
    return;
//-------------------------------------------------------------------------------------------------
/** Show the validators for all the properties */
void AlgorithmDialog::showValidators() {
  // Do nothing for non-generic algorithm dialogs
  QStringList::const_iterator pend = m_algProperties.end();
  for (QStringList::const_iterator pitr = m_algProperties.begin(); pitr != pend;
       ++pitr) {
    const QString propName = *pitr;

    // Find the widget for this property.
    if (m_tied_properties.contains(propName)) {
      // Show/hide the validator label (that red star)
      QString error = "";
      if (m_errors.contains(propName))
        error = m_errors[propName];

      QLabel *validator = getValidatorMarker(propName);
      // If there's no validator then assume it's handling its own validation
      // notification
      if (validator && validator->parent()) {
        validator->setToolTip(error);
        validator->setVisible(error.length() != 0);
      }
    } // widget is tied
}

//-------------------------------------------------------------------------------------------------
/** Sets the value of a single property, using the value previously stored using
 * storePropertyValue()
 *
 * @param pName :: name of the property to set
 * @param validateOthers :: set to true to validate, enable, or hide ALL other
 * properties after.
 *        Set false if you are setting ALL property values and do it once at the
 * end.
bool AlgorithmDialog::setPropertyValue(const QString pName,
                                       bool validateOthers) {
  // Mantid::Kernel::Property *p = getAlgorithmProperty(pName);
  QString value = getInputValue(pName);

  std::string error("");
  try {
    // error = p->setValue(value.toStdString());
    getAlgorithm()->setPropertyValue(pName.toStdString(), value.toStdString());
  } catch (std::exception &err_details) {
    error = err_details.what();
  }
  // Save the error string for later
  m_errors[pName] = QString::fromStdString(error).trimmed();

  // Go through all the other properties' validators
  if (validateOthers)
    this->showValidators();
  // Prop was valid if the error string is empty
  return error.empty();
}

//-------------------------------------------------------------------------------------------------
/** Set the properties that have been parsed from the dialog.
 *
 * @param skipList :: An optional list of property names whose values will not
 * be set
 * @returns A boolean that indicates if the validation was successful.
 */
bool AlgorithmDialog::setPropertyValues(const QStringList &skipList) {
  QStringList::const_iterator pend = m_algProperties.end();
  bool allValid(true);
  for (QStringList::const_iterator pitr = m_algProperties.begin(); pitr != pend;
       ++pitr) {
    if (skipList.contains(pName)) {
      // For the load dialog, skips setting some properties
      Mantid::Kernel::Property *p = getAlgorithmProperty(pName);
      std::string error = p->isValid();
      m_errors[pName] = QString::fromStdString(error).trimmed();
      if (!error.empty())
        allValid = false;
    } else {
      bool thisValid = this->setPropertyValue(pName, false);
      allValid = allValid && thisValid;
    }
  // Do additional validation on the WHOLE set of properties
  // But only if the individual validation passed
    std::map<std::string, std::string> errs = m_algorithm->validateInputs();
    for (auto it = errs.begin(); it != errs.end(); it++) {
      // only count as an error if the named property exists
      if (m_algorithm->existsProperty(it->first)) {
        const QString pName = QString::fromStdString(it->first);
        const QString value = QString::fromStdString(it->second);
        if (m_errors.contains(pName)) {
          if (!m_errors[pName].isEmpty())
            m_errors[pName] += "\n";
          m_errors[pName] += value;
          m_errors[pName] = value;
        // There is at least one whole-algo error
        allValid = false;
  // OK all the values have been set once. Time to look for which should be
  // enabled
  this->showValidators();
//-------------------------------------------------------------------------------------------------
 * Return the message string
 * @returns the message string
const QString &AlgorithmDialog::getOptionalMessage() const {
//-------------------------------------------------------------------------------------------------
/** Add the optional message in a light yellow box to the layout
 *
 * @param mainLay :: layout
 */
void AlgorithmDialog::addOptionalMessage(QVBoxLayout *mainLay) {
  QLabel *inputMessage = new QLabel(this);
  inputMessage->setFrameStyle(QFrame::Panel | QFrame::Sunken);
  QPalette pal = inputMessage->palette();
  pal.setColor(inputMessage->backgroundRole(),
               QColor(255, 255, 224)); // Light yellow
  pal.setColor(inputMessage->foregroundRole(), Qt::black);
  inputMessage->setPalette(pal);
  inputMessage->setAutoFillBackground(true);
  inputMessage->setWordWrap(true);
  inputMessage->setAlignment(Qt::AlignJustify);
  inputMessage->setMargin(3);
  inputMessage->setText(getOptionalMessage());
  QHBoxLayout *msgArea = new QHBoxLayout;
  msgArea->addWidget(inputMessage);
  mainLay->addLayout(msgArea, 0);
//-------------------------------------------------------------------------------------------------
 * Was this dialog raised from a script? This is important when deciding what to
 * do with properties that have old input
 * @returns A boolean inidcating whether we are being called from a script
bool AlgorithmDialog::isForScript() const { return m_forScript; }
/*
 * Is there a message string available
 * @returns A boolean indicating whether the message string is empty
bool AlgorithmDialog::isMessageAvailable() const {
//-------------------------------------------------------------------------------------------------
 * Check if the control should be enabled for this property
 * @param propName :: The name of the property
bool AlgorithmDialog::isWidgetEnabled(const QString &propName) const {
  if (propName.isEmpty())
    return true;
  // Otherwise it must be disabled but only if it is valid
  Mantid::Kernel::Property *property = getAlgorithmProperty(propName);
    // Regular C++ algo. Let the property tell us,
    // possibly using validators, if it is to be shown enabled
    if (property->getSettings())
      return property->getSettings()->isEnabled(getAlgorithm().get());
    // Algorithm dialog was called from a script(i.e. Python)
    // Keep things enabled if requested
    if (m_enabled.contains(propName))
      return true;
     * The control is disabled if
     *   (1) It is contained in the disabled list or
     *   (2) A user passed a value into the dialog
     */
    return !(m_disabled.contains(propName) ||
             m_python_arguments.contains(propName));
//-------------------------------------------------------------------------------------------------
/**
 * UnTie a property
 * @param property :: The name of the property to tie the given widget to
 */
void AlgorithmDialog::untie(const QString &property) {
  if (m_tied_properties.contains(property)) {

//-------------------------------------------------------------------------------------------------
 * Tie together an input widget and a property
 * @param widget :: The widget that will collect the input
 * @param property :: The name of the property to tie the given widget to
 * @param parent_layout :: An optional pointer to a QLayout class that is
 * reponsible for managing the passed widget.
 * If given, a validator label will be added for the given input widget
 * @param readHistory :: If true then a history value will be retrieved
 * @return A NULL pointer if a valid label was successfully add to a passed
 * parent_layout otherwise it
 *          returns a pointer to the QLabel instance marking the validity
QWidget *AlgorithmDialog::tie(QWidget *widget, const QString &property,
                              QLayout *parent_layout, bool readHistory) {
  if (m_tied_properties.contains(property))
  Mantid::Kernel::Property *prop = getAlgorithmProperty(property);
  if (prop) { // Set a few things on the widget
    widget->setToolTip(QString::fromStdString(prop->briefDocumentation()));
  widget->setEnabled(isWidgetEnabled(property));
  PropertyWidget *propWidget = qobject_cast<PropertyWidget *>(widget);
  m_tied_properties.insert(property, widget);
  // If the widget's layout has been given then assume that a validator is
  // required, else assume not
  QWidget *validlbl(nullptr);
    // Check if the validator is already there
    validlbl = getValidatorMarker(property);
      // Find where it was sitting in the layout
      int item_index;
      if (propWidget)
        item_index = parent_layout->indexOf(propWidget->getMainWidget());
      else
        item_index = parent_layout->indexOf(widget);

      if (QBoxLayout *box = qobject_cast<QBoxLayout *>(parent_layout)) {
      } else if (QGridLayout *grid =
                     qobject_cast<QGridLayout *>(parent_layout)) {
        int row(0), col(0), span(0);
        grid->getItemPosition(item_index, &row, &col, &span, &span);
        grid->addWidget(validlbl, row, col + 2);
      } else {
//-------------------------------------------------------------------------------------------------
 * Open a file selection box. The type of dialog, i.e. load/save will depend on
 * the
 * @param propName :: The property name that this is associated with.
QString AlgorithmDialog::openFileDialog(const QString &propName) {
  if (propName.isEmpty())
    return "";
  return FilePropertyWidget::openFileDialog(
      this->getAlgorithmProperty(propName));
//-------------------------------------------------------------------------------------------------
 * Takes a combobox and adds the allowed values of the given property to its
 * list.
 * It also sets the displayed value to the correct one based on either the
 * history
 * @param propName :: The name of the property
 * @param optionsBox :: A pointer to a QComoboBox object
void AlgorithmDialog::fillAndSetComboBox(const QString &propName,
                                         QComboBox *optionsBox) const {
  if (!optionsBox)
    return;
  Mantid::Kernel::Property *property = getAlgorithmProperty(propName);
  std::vector<std::string> items = property->allowedValues();
  std::vector<std::string>::const_iterator vend = items.end();
  for (std::vector<std::string>::const_iterator vitr = items.begin();
       vitr != vend; ++vitr) {
    optionsBox->addItem(QString::fromStdString(*vitr));
  }

  // Display the appropriate value
  QString displayed("");
  if (!isForScript()) {
    displayed =
        AlgorithmInputHistory::Instance().previousInput(m_algName, propName);
  if (displayed.isEmpty()) {
    displayed = QString::fromStdString(property->value());
  }

  int index = optionsBox->findText(displayed);
//-------------------------------------------------------------------------------------------------
/**
 * Set the input for a text box based on either the history or a script value
 * @param propName :: The name of the property
 * @param textField :: The QLineEdit field
void AlgorithmDialog::fillLineEdit(const QString &propName,
                                   QLineEdit *textField) {
  if (!isForScript()) {
    textField->setText(
        AlgorithmInputHistory::Instance().previousInput(m_algName, propName));
  } else {
    Mantid::Kernel::Property *property = getAlgorithmProperty(propName);
    if (property && property->isValid().empty() &&
        (m_python_arguments.contains(propName) || !property->isDefault())) {
      textField->setText(QString::fromStdString(property->value()));
    }
//-------------------------------------------------------------------------------------------------
/** Layout the buttons and others in the generic dialog */
QLayout *AlgorithmDialog::createDefaultButtonLayout(
    const QString &helpText, const QString &loadText, const QString &cancelText,
    const QString &keepOpenText) {
  m_okButton = new QPushButton(loadText);
  connect(m_okButton, SIGNAL(clicked()), this, SLOT(accept()));
  m_okButton->setDefault(true);
  m_exitButton = new QPushButton(cancelText);
  connect(m_exitButton, SIGNAL(clicked()), this, SLOT(reject()));

  QHBoxLayout *buttonRowLayout = new QHBoxLayout;
  buttonRowLayout->addWidget(createHelpButton(helpText));
  buttonRowLayout->addStretch();
  m_keepOpenCheckBox = new QCheckBox(keepOpenText);
  m_keepOpenCheckBox->setLayoutDirection(Qt::LayoutDirection::RightToLeft);
  connect(m_keepOpenCheckBox, SIGNAL(stateChanged(int)), this,
          SLOT(keepOpenChanged(int)));
  buttonRowLayout->addWidget(m_keepOpenCheckBox);
  if (keepOpenText.isEmpty()) {
    setShowKeepOpen(false);
  }

  buttonRowLayout->addWidget(m_okButton);
  buttonRowLayout->addWidget(m_exitButton);
//-------------------------------------------------------------------------------------------------
 * Create a help button that, when clicked, will open a browser to the Mantid
 * wiki page
QPushButton *AlgorithmDialog::createHelpButton(const QString &helpText) const {
  QPushButton *help = new QPushButton(helpText);
  help->setMaximumWidth(25);
  connect(help, SIGNAL(clicked()), this, SLOT(helpClicked()));
  return help;
}
 * @param inputWidget :: A widget used to enter the input workspace
void AlgorithmDialog::flagInputWS(QWidget *inputWidget) {
//-----------------------------------------------------------
// Protected slots
//-----------------------------------------------------------
/**
 * A slot that can be used to connect a button that accepts the dialog if
 * all of the properties are valid
 */
void AlgorithmDialog::accept() {
  // Try and set and validate the properties and
  if (setPropertyValues()) {
    // Store input for next time
    if (!this->m_keepOpen) {
      QDialog::accept();
    } else {
      executeAlgorithmAsync();
  } else {
    QMessageBox::critical(
        this, "",
        "One or more properties are invalid. The invalid properties are\n"
        "marked with a *, hold your mouse over the * for more information.");
//-------------------------------------------------------------------------------------------------
void AlgorithmDialog::helpClicked() {
  // determine the version to show
  int version(-1); // the latest version
  if (m_algorithm)
    version = m_algorithm->version();
  // bring up the help window
  HelpWindow::showAlgorithm(this->nativeParentWidget(), m_algName, version);
//-------------------------------------------------------------------------------------------------

/**
 * A slot to handle the keep open button click
 */
void AlgorithmDialog::keepOpenChanged(int state) {
  m_keepOpen = (state == Qt::Checked);
//-------------------------------------------------------------------------------------------------
/**
 * Execute the underlying algorithm
 */
void AlgorithmDialog::executeAlgorithmAsync() {
  Mantid::API::IAlgorithm_sptr algToExec = m_algorithm;
  // Clear any previous trackers so we know what state we are in
  this->stopObserving(algToExec);

    // Add any custom AlgorithmObservers to the algorithm
    for (auto it = m_observers.begin(); it != m_observers.end(); ++it) {
      (*it)->observeAll(algToExec);
    // Only need to observe finish events if we are staying open
    if (m_keepOpenCheckBox && m_keepOpenCheckBox->isChecked()) {
      this->observeFinish(algToExec);
      this->observeError(algToExec);
      // Disable close button for a short period. If it is clicked to soon then
      // Mantid crashes - https://github.com/mantidproject/mantid/issues/13836
        m_exitButton->setEnabled(false);
        m_btnTimer.setInterval(1000);
        connect(&m_btnTimer, SIGNAL(timeout()), this, SLOT(enableExitButton()));
      } else {
        m_statusTracked = false;
    algToExec->executeAsync();
    m_btnTimer.start();
    if (m_okButton) {
      m_okButton->setEnabled(false);
    }
  } catch (Poco::NoThreadAvailableException &) {
    g_log.error() << "No thread was available to run the " << algToExec->name()
                  << " algorithm in the background.\n";
//-------------------------------------------------------------------------------------------------
/*
 */
void AlgorithmDialog::removeAlgorithmFromManager() {
  using namespace Mantid::API;
  AlgorithmManager::Instance().removeById(m_algorithm->getAlgorithmID());
}

void AlgorithmDialog::enableExitButton() { m_exitButton->setEnabled(true); }
//------------------------------------------------------
// Private member functions
//------------------------------------------------------
void AlgorithmDialog::parse() {
  QHashIterator<QString, QWidget *> itr(m_tied_properties);
  while (itr.hasNext()) {
    // Need to do different things depending on the type of the widget. getValue
    // sorts this out
    storePropertyValue(itr.key(), getValue(itr.value()));
  }

  // Now call parseInput, which can be overridden in an inheriting class
//-------------------------------------------------------------------------------------------------
 * Set a list of values for the properties
 * @param presetValues :: A string containing a list of "name=value" pairs with
 * each separated by an '|' character
void AlgorithmDialog::setPresetValues(
    const QHash<QString, QString> &presetValues) {
  if (presetValues.isEmpty())
    return;
  QHashIterator<QString, QString> itr(presetValues);
    QString value = itr.value();
    storePropertyValue(name, value);
//------------------------------------------------------------------------------------------------
 * Set list of enabled and disabled parameter names
 * @param enabled:: A list of parameter names to keep enabled
 * @param disabled:: A list of parameter names whose widgets should be disabled
void AlgorithmDialog::addEnabledAndDisableLists(const QStringList &enabled,
                                                const QStringList &disabled) {
//------------------------------------------------------------------------------------------------
 * Returns true if the parameter name has been explicity requested to be kept
 * enabled. If the parameter
 * has been explicity requested to be disabled then return false as well as if
 * neither have been specified
bool AlgorithmDialog::requestedToKeepEnabled(const QString &propName) const {
  if (m_disabled.contains(propName)) {
  } else if (m_enabled.contains(propName)) // Definitely enable
  } else // Nothing was specified
//------------------------------------------------------------------------------------------------
/** Set if we are for a script or not
 * @param forScript :: A boolean indicating whether we are being called from a
 * script */
void AlgorithmDialog::isForScript(bool forScript) { m_forScript = forScript; }
//------------------------------------------------------------------------------------------------
/**
 * @param on If true the algorithm is executed when "ok" is pressed
 */
void AlgorithmDialog::executeOnAccept(bool on) {
  if (on) {
    connect(this, SIGNAL(accepted()), this, SLOT(executeAlgorithmAsync()));
    connect(this, SIGNAL(rejected()), this, SLOT(removeAlgorithmFromManager()));
    disconnect(this, SIGNAL(accepted()), this, SLOT(executeAlgorithmAsync()));
    disconnect(this, SIGNAL(rejected()), this,
               SLOT(removeAlgorithmFromManager()));
//-------------------------------------------------------------------------------------------------
/** Set an optional message to be displayed at the top of the widget
 * @param message :: The message string */
void AlgorithmDialog::setOptionalMessage(const QString &message) {
  if (message.isEmpty())
    m_strMessage = QString::fromStdString(getAlgorithm()->summary());
  if (m_strMessage.isEmpty())
    m_msgAvailable = false;
  else
    m_msgAvailable = true;
//-------------------------------------------------------------------------------------------------
/** Get a value from a widget.
 *
 * The function needs to know about the types of widgets
 * that are being used. Currently it knows about QComboBox, QLineEdit, QCheckBox
 * and MWRunFiles
QString AlgorithmDialog::getValue(QWidget *widget) {
  if (QComboBox *opts = qobject_cast<QComboBox *>(widget)) {
    return opts->currentText().trimmed();
  } else if (QLineEdit *textfield = qobject_cast<QLineEdit *>(widget)) {
  } else if (QAbstractButton *checker =
                 qobject_cast<QAbstractButton *>(widget)) {
    if (checker->isChecked())
  } else if (QDateTimeEdit *dateEdit = qobject_cast<QDateTimeEdit *>(widget)) {
    // String in ISO8601 format /* add toUTC() to go from local time */
    QString value = dateEdit->dateTime().toString(Qt::ISODate);
    return value;
  } else if (MantidWidget *mtd_widget = qobject_cast<MantidWidget *>(widget)) {
    return mtd_widget->getUserInput().toString().trimmed();
  } else if (PropertyWidget *propWidget =
                 qobject_cast<PropertyWidget *>(widget)) {
    return propWidget->getValue().trimmed();
  } else {
    QMessageBox::warning(
        this, windowTitle(),
        QString("Cannot parse input from ") +
            widget->metaObject()->className() +
            ". Update AlgorithmDialog::getValue() to cope with this widget.");
QString AlgorithmDialog::getPreviousValue(const QString &propName) const {
    value = m_propertyValueMap.value(propName);
    if (value.isEmpty())
      value =
          AlgorithmInputHistory::Instance().previousInput(m_algName, propName);
  } else if (getAlgorithmProperty(propName)) {
    value = m_propertyValueMap.value(propName);
  }

  return value;
}

//------------------------------------------------------------------------------------------------
/** Set a value for a widget.
 *
 * The function needs to know about the types of widgets
 * that are being used. Currently it knows about QComboBox, QLineEdit and
 * QCheckBox
 * @param propName :: The property name
void AlgorithmDialog::setPreviousValue(QWidget *widget,
                                       const QString &propName) {
Arturs Bekasovs's avatar
Arturs Bekasovs committed
  // If is called from a script, check if we have such property
  if (isForScript() && !getAlgorithmProperty(propName))
Arturs Bekasovs's avatar
Arturs Bekasovs committed
  QString value = getPreviousValue(propName);

  Mantid::Kernel::Property *property = getAlgorithmProperty(propName);
  if (QComboBox *opts = qobject_cast<QComboBox *>(widget)) {
    if (property && value.isEmpty()) {
      value = QString::fromStdString(property->value());
    }
  if (QAbstractButton *checker = qobject_cast<QAbstractButton *>(widget)) {
    if (value.isEmpty() &&
        dynamic_cast<Mantid::Kernel::PropertyWithValue<bool> *>(property))
      value = QString::fromStdString(property->value());
    checker->setChecked(value != "0");
    return;
  }
  if (QDateTimeEdit *dateEdit = qobject_cast<QDateTimeEdit *>(widget)) {
    // String in ISO8601 format