Skip to content
Snippets Groups Projects
ApplicationWindow.cpp 579 KiB
Newer Older
  Table* w = new Table(scriptingEnv(), r, c, legend, this, 0);
  initTable(w, name);
  return w;
}

Table* ApplicationWindow::newTable(const QString& caption, int r, int c, const QString& text)
{
  QStringList lst = caption.split("\t", QString::SkipEmptyParts);
  QString legend = QString();
  if (lst.count() == 2)
    legend = lst[1];

  Table* w = new Table(scriptingEnv(), r, c, legend, this, 0);

  QStringList rows = text.split("\n", QString::SkipEmptyParts);
  QString rlist = rows[0];
  QStringList list = rlist.split("\t");
  w->setHeader(list);

  for (int i=0; i<r; i++)
  {
    rlist=rows[i+1];
    list=rlist.split("\t");
    for (int j=0; j<c; j++)
      w->setText(i, j, list[j]);
  }

  initTable(w, lst[0]);
  w->showNormal();
  return w;
}

Table* ApplicationWindow::newHiddenTable(const QString& name, const QString& label, int r, int c, const QString& text)
{
  Table* w = new Table(scriptingEnv(), r, c, label, this, 0);

  if (!text.isEmpty()) {
    QStringList rows = text.split("\n", QString::SkipEmptyParts);
    QStringList list = rows[0].split("\t");
    w->setHeader(list);

    QString rlist;
    for (int i=0; i<r; i++){
      rlist=rows[i+1];
      list = rlist.split("\t");
      for (int j=0; j<c; j++)
        w->setText(i, j, list[j]);
    }
  }

  initTable(w, name);
  hideWindow(w);
  return w;
}

/* Perfom initialization on a Table?
 * @param w :: table that was created
 * @param caption :: title to set
 */
void ApplicationWindow::initTable(Table* w, const QString& caption)
{
  QString name = caption;
  name = name.replace ("_","-");

  while(name.isEmpty() || alreadyUsedName(name))
    name = generateUniqueName(tr("Table"));

  connectTable(w);
  customTable(w);

  w->setName(name);
  w->setIcon( getQPixmap("worksheet_xpm") );
  w->setSpecifications(w->saveToString(windowGeometryInfo(w)));

  addMdiSubWindow(w);
}

/*
 * !creates a new table with type statistics on target columns/rows of table base
 */
TableStatistics *ApplicationWindow::newTableStatistics(Table *base, int type, QList<int> target, const QString &caption)
{
  TableStatistics* s = new TableStatistics(scriptingEnv(), this, base, (TableStatistics::Type) type, target);
  if (caption.isEmpty())
    initTable(s, s->objectName());
  else
    initTable(s, caption);
  s->showNormal();
  return s;
}

/*
 *creates a new empty note window
 */
Note* ApplicationWindow::newNote(const QString& caption)
{
  Note* m = new Note("", this);

  QString name = caption;
  while(name.isEmpty() || alreadyUsedName(name))
    name = generateUniqueName(tr("Notes"));

  m->setName(name);
  m->setIcon(getQPixmap("note_xpm"));
  m->confirmClose(confirmCloseNotes);

  addMdiSubWindow(m);
  m->showNormal();
  return m;
}

Matrix* ApplicationWindow::newMatrix(int rows, int columns)
{
  Matrix* m = new Matrix(scriptingEnv(), rows, columns, "", this, 0);
  initMatrix(m, generateUniqueName(tr("Matrix")));
  m->showNormal();
  return m;
}

Matrix* ApplicationWindow::newMatrix(const QString& caption, int r, int c)
{
  Matrix* w = new Matrix(scriptingEnv(), r, c, "", this, 0);
  initMatrix(w, caption);
  if (w->objectName() != caption)//the matrix was renamed
    renamedTables << caption << w->objectName();

  w->showNormal();
  return w;
}

void ApplicationWindow::viewMatrixImage()
{
  Matrix* m = dynamic_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return;

  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
  m->undoStack()->push(new MatrixSetViewCommand(m, m->viewType(), Matrix::ImageView, tr("Set Image Mode")));
  m->setViewType(Matrix::ImageView);
  QApplication::restoreOverrideCursor();
}

void ApplicationWindow::viewMatrixTable()
{
  Matrix* m = static_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return;

  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
  m->undoStack()->push(new MatrixSetViewCommand(m, m->viewType(), Matrix::TableView, tr("Set Data Mode")));
  m->setViewType(Matrix::TableView);
  QApplication::restoreOverrideCursor();
}

void ApplicationWindow::viewMatrixXY()
{
  Matrix* m = static_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return;

  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
  m->undoStack()->push(new MatrixSetHeaderViewCommand(m, m->headerViewType(), Matrix::XY, tr("Show X/Y")));
  m->setHeaderViewType(Matrix::XY);
  QApplication::restoreOverrideCursor();
}

void ApplicationWindow::viewMatrixColumnRow()
{
  Matrix* m = static_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return;

  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
  m->undoStack()->push(new MatrixSetHeaderViewCommand(m, m->headerViewType(), Matrix::ColumnRow, tr("Show Column/Row")));
  m->setHeaderViewType(Matrix::ColumnRow);
  QApplication::restoreOverrideCursor();
}

void ApplicationWindow::setMatrixGrayScale()
{
  Matrix* m = static_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return;

  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
  m->undoStack()->push(new MatrixSetColorMapCommand(m, m->colorMapType(), m->colorMap(),
      Matrix::GrayScale, QwtLinearColorMap(), tr("Set Gray Scale Palette")));
  m->setGrayScale();
  QApplication::restoreOverrideCursor();
}

void ApplicationWindow::setMatrixRainbowScale()
{
  Matrix* m = static_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return;

  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
  m->undoStack()->push(new MatrixSetColorMapCommand(m, m->colorMapType(), m->colorMap(),
      Matrix::Rainbow, QwtLinearColorMap(), tr("Set Rainbow Palette")));
  m->setRainbowColorMap();
  QApplication::restoreOverrideCursor();
}

void ApplicationWindow::showColorMapDialog()
{
  Matrix* m = static_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return;

  ColorMapDialog *cmd = new ColorMapDialog(this);
  cmd->setAttribute(Qt::WA_DeleteOnClose);
  cmd->setMatrix(m);
  cmd->exec();
}

void ApplicationWindow::transposeMatrix()
{
  Matrix* m = dynamic_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return;

  m->transpose();
}

void ApplicationWindow::flipMatrixVertically()
{
  Matrix* m = dynamic_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return;

  m->flipVertically();
}

void ApplicationWindow::flipMatrixHorizontally()
{
  Matrix* m = dynamic_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return;

  m->flipHorizontally();
}

void ApplicationWindow::rotateMatrix90()
{
  Matrix* m = dynamic_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return;

  m->rotate90();
}

void ApplicationWindow::rotateMatrixMinus90()
{
  Matrix* m = dynamic_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return;

  m->rotate90(false);
}

void ApplicationWindow::matrixDeterminant()
{
  Matrix* m = dynamic_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return;

  QDateTime dt = QDateTime::currentDateTime ();
  QString info=dt.toString(Qt::LocalDate);
  info+= "\n" + tr("Determinant of ") + QString(m->objectName()) + ":\t";
  info+= "det = " + QString::number(m->determinant()) + "\n";
  info+="-------------------------------------------------------------\n";

  current_folder->appendLogInfo(info);

  showResults(true);
}

void ApplicationWindow::invertMatrix()
{
  Matrix* m = dynamic_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return;

  m->invert();
}

Table* ApplicationWindow::convertMatrixToTableDirect()
{
  Matrix* m = dynamic_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return 0;

  return matrixToTable(m, Direct);
}

Table* ApplicationWindow::convertMatrixToTableXYZ()
{
  Matrix* m = dynamic_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return 0;

  return matrixToTable(m, XYZ);
}

Table* ApplicationWindow::convertMatrixToTableYXZ()
{
  Matrix* m = dynamic_cast<Matrix*>(activeWindow(MatrixWindow));
  if (!m)
    return 0;

  return matrixToTable(m, YXZ);
}

Table* ApplicationWindow::matrixToTable(Matrix* m, MatrixToTableConversion conversionType)
{
  if (!m)
    return 0;

  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));

  int rows = m->numRows();
  int cols = m->numCols();
  MatrixModel *mModel = m->matrixModel();

  Table* w = NULL;
  if (conversionType == Direct){
    w = new Table(scriptingEnv(), rows, cols, "", this, 0);
    for (int i = 0; i<rows; i++){
      for (int j = 0; j<cols; j++)
        w->setCell(i, j, m->cell(i,j));
    }
  } else if (conversionType == XYZ){
    int tableRows = rows*cols;
    w = new Table(scriptingEnv(), tableRows, 3, "", this, 0);
    for (int i = 0; i<rows; i++){
      for (int j = 0; j<cols; j++){
        int cell = i*cols + j;
        w->setCell(cell, 0, mModel->x(j));
        w->setCell(cell, 1, mModel->y(i));
        w->setCell(cell, 2, mModel->cell(i, j));
      }
    }
  } else if (conversionType == YXZ){
    int tableRows = rows*cols;
    w = new Table(scriptingEnv(), tableRows, 3, "", this, 0);
    for (int i = 0; i<cols; i++){
      for (int j = 0; j<rows; j++){
        int cell = i*rows + j;
        w->setCell(cell, 0, mModel->x(i));
        w->setCell(cell, 1, mModel->y(j));
        w->setCell(cell, 2, mModel->cell(i, j));
      }
    }
  }


  initTable(w, generateUniqueName(tr("Table")));
  w->setWindowLabel(m->windowLabel());
  w->setCaptionPolicy(m->captionPolicy());
  w->resize(m->size());
  w->showNormal();

  QApplication::restoreOverrideCursor();
  return w;
}

void ApplicationWindow::initMatrix(Matrix* m, const QString& caption)
{
  QString name = caption;
  while(alreadyUsedName(name)){name = generateUniqueName(tr("Matrix"));}

  m->setWindowTitle(name);
  m->setName(name);
  m->setIcon( m->matrixIcon() );//Mantid
  m->confirmClose(confirmCloseMatrix);
  m->setNumericPrecision(d_decimal_digits);

  addMdiSubWindow(m);

  QUndoStack *stack = m->undoStack();
  connect(stack, SIGNAL(canUndoChanged(bool)), actionUndo, SLOT(setEnabled(bool)));
  connect(stack, SIGNAL(canRedoChanged(bool)), actionRedo, SLOT(setEnabled(bool)));

  connect(m, SIGNAL(modifiedWindow(MdiSubWindow*)), this, SLOT(updateMatrixPlots(MdiSubWindow *)));

  emit modified();
}

Matrix* ApplicationWindow::convertTableToMatrix()
{
  Table* t = dynamic_cast<Table*>(activeWindow(TableWindow));
  if (!t)
    return 0;

  return tableToMatrix (t);
}

/**
 * Convert Table in the active window to a TableWorkspace
 */
void ApplicationWindow::convertTableToWorkspace()
{
  Table* t = dynamic_cast<Table*>(activeWindow(TableWindow));
  if (!t) return;
  MantidTable* mt = dynamic_cast<MantidTable*>(t);
  if (!mt)
  {
    mt = convertTableToTableWorkspace(t);
  }
}

/**
 * Convert Table in the active window to a TableWorkspace
 */
void ApplicationWindow::convertTableToMatrixWorkspace()
{
  Table* t = dynamic_cast<Table*>(activeWindow(TableWindow));
  if (!t) return;
  MantidTable* mt = dynamic_cast<MantidTable*>(t);
  if (!mt)
  {
    mt = convertTableToTableWorkspace(t);
  }
  //mantidUI->executeAlgorithm("ConvertTableToMatrixWorkspace","InputWorkspace="+QString::fromStdString(mt->getWorkspaceName()));
  QMap<QString,QString> params;
  params["InputWorkspace"] = QString::fromStdString(mt->getWorkspaceName());
  mantidUI->executeAlgorithmDlg("ConvertTableToMatrixWorkspace",params);
}

/**
 * Convert a Table to a TableWorkspace. Columns with plot designations X,Y,Z,xErr,yErr
 * are transformed to doubles, others - to strings.
 * @param t :: The Table to convert.
 */
MantidTable* ApplicationWindow::convertTableToTableWorkspace(Table* t)
{
  if (!t) return NULL;
  Mantid::API::ITableWorkspace_sptr tws = Mantid::API::WorkspaceFactory::Instance().createTable();
  for(int col = 0; col < t->numCols(); ++col)
  {
    Table::PlotDesignation des = (Table::PlotDesignation)t->colPlotDesignation(col);
    QString name = t->colLabel(col);
    std::string type;
    int plotType = 6; // Label
    case Table::X: {plotType = 1; type = "double"; break;}
    case Table::Y: {plotType = 2; type = "double"; break;}
    case Table::Z: {plotType = 3; type = "double"; break;}
    case Table::xErr:  {plotType = 4; type = "double"; break;}
    case Table::yErr: {plotType = 5; type = "double"; break;}
      type = "string"; plotType = 6;
    std::string columnName = name.toStdString();
    tws->addColumn(type,columnName);
    Mantid::API::Column_sptr column = tws->getColumn(columnName);
    column->setPlotType(plotType);
  }
  tws->setRowCount(t->numRows());
  for(int col = 0; col < t->numCols(); ++col)
  {
    Mantid::API::Column_sptr column = tws->getColumn(col);
    for(int row = 0; row < t->numRows(); ++row)
    {
      column->read(row, t->text(row,col).toStdString());
    }
  }
  std::string wsName = t->objectName().toStdString();
  if (Mantid::API::AnalysisDataService::Instance().doesExist(wsName))
  {
    if (QMessageBox::query("MantidPlot","Workspace with name " + t->objectName() + " already exists\n"
      "Do you want to overwrite it?"))
    {
      Mantid::API::AnalysisDataService::Instance().addOrReplace(wsName,tws);
    }
    else
    {
      return NULL;
    }
  }
  else
  {
    Mantid::API::AnalysisDataService::Instance().add(wsName,tws);
  }
  MantidTable* mt = new MantidTable(scriptingEnv(), tws, t->objectName(), this);
  return mt;
}

Matrix* ApplicationWindow::tableToMatrix(Table* t)
{
  if (!t)
    return 0;

  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));

  int rows = t->numRows();
  int cols = t->numCols();

  QString caption = generateUniqueName(tr("Matrix"));
  Matrix* m = new Matrix(scriptingEnv(), rows, cols, "", this, 0);
  initMatrix(m, caption);

  for (int i = 0; i<rows; i++){
    for (int j = 0; j<cols; j++)
      m->setCell(i, j, t->cell(i, j));
  }

  m->setWindowLabel(m->windowLabel());
  m->setCaptionPolicy(m->captionPolicy());
  m->resize(m->size());
  m->showNormal();

  QApplication::restoreOverrideCursor();
  return m;
}

MdiSubWindow* ApplicationWindow::window(const QString& name)
{
  QList<MdiSubWindow *> windows = windowsList();
  foreach(MdiSubWindow *w, windows){
    if (w->objectName() == name)
      return w;
  }
  return  NULL;
}

Table* ApplicationWindow::table(const QString& name)
{
  int pos = name.find("_", 0);
  QString caption = name.left(pos);

  Folder *f = projectFolder();
  while (f){
    QList<MdiSubWindow *> folderWindows = f->windowsList();
    foreach(MdiSubWindow *w, folderWindows){
      if (w->inherits("Table") && w->objectName() == caption)
        return dynamic_cast<Table*>(w);
    }
    f = f->folderBelow();
  }

  return  0;
}

Matrix* ApplicationWindow::matrix(const QString& name)
{
  QString caption = name;
  if (!renamedTables.isEmpty() && renamedTables.contains(caption)){
    int index = renamedTables.findIndex(caption);
    caption = renamedTables[index+1];
  }

  Folder *f = projectFolder();
  while (f){
    QList<MdiSubWindow *> folderWindows = f->windowsList();
    foreach(MdiSubWindow *w, folderWindows){
      if (w->isA("Matrix") && w->objectName() == caption)
        return dynamic_cast<Matrix*>(w);
    }
    f = f->folderBelow();
  }
  return  0;
}

MdiSubWindow *ApplicationWindow::activeWindow(WindowType type)
{
  MdiSubWindow* active = getActiveWindow();
  if (!active)
    return NULL;

  switch(type){
  case NoWindow:
    break;

  case TableWindow:
    if (active->inherits("Table"))
      return active;
    else
      return NULL;
    break;

  case MatrixWindow:
    if (active->inherits("Matrix"))//Mantid
      return active;
    else
      return NULL;
    break;

  case MultiLayerWindow:
    if (active->isA("MultiLayer"))
      return active;
    else
      return NULL;
    break;

  case NoteWindow:
    if (active->isA("Note"))
      return active;
    else
      return NULL;
    break;

  case Plot3DWindow:
    if (active->isA("Graph3D"))
      return active;
    else
      return NULL;
    break;
  }
  return active;
}

void ApplicationWindow::windowActivated(QMdiSubWindow *w)
{	
  if ( !w ) return;

  MdiSubWindow *qti_subwin = qobject_cast<MdiSubWindow*>(w->widget());
  if( !qti_subwin ) return;

  activateWindow(qti_subwin);

}

void ApplicationWindow::addErrorBars()
{
  MdiSubWindow *w = activeWindow(MultiLayerWindow);
  if (!w)
    return;

  MultiLayer* plot = dynamic_cast<MultiLayer*>(w);
  if (plot->isEmpty()){
    QMessageBox::warning(this,tr("MantidPlot - Warning"),//Mantid
        tr("<h4>There are no plot layers available in this window.</h4>"
            "<p><h4>Please add a layer and try again!</h4>"));
    return;
  }

  Graph* g = dynamic_cast<Graph*>(plot->activeGraph());
  if (!g)
    return;

  if (!g->curves()){
    QMessageBox::warning(this, tr("MantidPlot - Warning"), tr("There are no curves available on this plot!"));//Mantid
    return;
  }

  if (g->isPiePlot()){
    QMessageBox::warning(this, tr("MantidPlot - Warning"), tr("This functionality is not available for pie plots!"));//Mantid
    return;
  }

  ErrDialog* ed = new ErrDialog(this);
  ed->setAttribute(Qt::WA_DeleteOnClose);
  connect (ed,SIGNAL(options(const QString&,int,const QString&,int,bool)),this,SLOT(defineErrorBars(const QString&,int,const QString&,int,bool))); 
  connect (ed,SIGNAL(options(const QString&,const QString&,int)),this,SLOT(defineErrorBars(const QString&,const QString&,int)));

  ed->setCurveNames(g->analysableCurvesList());
  ed->setSrcTables(tableList());
  ed->exec();
}

void ApplicationWindow::removeErrorBars()
{
  MdiSubWindow *w = activeWindow(MultiLayerWindow);
  if (!w)
    return;

  MultiLayer* plot = dynamic_cast<MultiLayer*>(w);
  if (plot->isEmpty()){
    QMessageBox::warning(this,tr("MantidPlot - Warning"),//Mantid
        tr("<h4>There are no plot layers available in this window.</h4>"
            "<p><h4>Please add a layer and try again!</h4>"));
    return;
  }

  Graph* g = dynamic_cast<Graph*>(plot->activeGraph());
  if (!g)
    return;

  if (!g->curves()){
    QMessageBox::warning(this, tr("MantidPlot - Warning"), tr("There are no curves available on this plot!"));//Mantid
    return;
  }

  if (g->isPiePlot()){
    QMessageBox::warning(this, tr("MantidPlot - Warning"), tr("This functionality is not available for pie plots!"));//Mantid
    return;
  }

  RemoveErrorsDialog* ed = new RemoveErrorsDialog(this);
  connect (ed,SIGNAL(curveName(const QString&)),this,SLOT(removeErrorBars(const QString&)));

  ed->setCurveNames(g->analysableCurvesList());
  ed->exec();
}

void ApplicationWindow::removeErrorBars(const QString& name)
{
  MdiSubWindow *w = activeWindow(MultiLayerWindow);
  if (!w)
    return;

  Graph* g = dynamic_cast<MultiLayer*>(w)->activeGraph();
  if (!g)
    return;

  g->removeMantidErrorBars(name);

}

void ApplicationWindow::defineErrorBars(const QString& name, int type, const QString& percent, int direction, bool drawAll)
{
  MdiSubWindow *w = activeWindow(MultiLayerWindow);
  if (!w)
    return;

  Graph* g = dynamic_cast<MultiLayer*>(w)->activeGraph();
  if (!g)
    return;

  if (type == 2) // A MantidCurve - do all the work in the Graph method
  {
    g->addMantidErrorBars(name, drawAll);
    return;
  }

  Table *t = table(name);
  if (!t){//user defined function
    QMessageBox::critical(this,tr("MantidPlot - Error bars error"),//Mantid
        tr("This feature is not available for user defined function curves!"));
    return;
  }

  DataCurve *master_curve = dynamic_cast<DataCurve *>(g->curve(name));
  QString xColName = master_curve->xColumnName();
  if (xColName.isEmpty())
    return;

  if (direction == QwtErrorPlotCurve::Horizontal)
    t->addCol(Table::xErr);
  else
    t->addCol(Table::yErr);

  int r=t->numRows();
  int c=t->numCols()-1;
  int ycol=t->colIndex(name);
  if (!direction)
    ycol=t->colIndex(xColName);

  QVarLengthArray<double> Y(r);
  Y=t->col(ycol);
  QString errColName=t->colName(c);

  double prc=percent.toDouble();
  if (type==0){
    for (int i=0;i<r;i++){
      if (!t->text(i,ycol).isEmpty())
        t->setText(i, c, QString::number(Y[i]*prc/100.0,'g',15));
    }
  } else if (type==1) {
    int i;
    double dev=0.0;
    double moyenne=0.0;
    for (i=0;i<r;i++)
      moyenne+=Y[i];
    moyenne/=r;
    for (i=0;i<r;i++)
      dev+=(Y[i]-moyenne)*(Y[i]-moyenne);
    dev=sqrt(dev/(r-1));
    for (i=0;i<r;i++){
      if (!t->table()->item(i,ycol)->text().isEmpty())
        t->setText(i, c, QString::number(dev, 'g', 15));
    }
  }
  QwtErrorPlotCurve * errs = g->addErrorBars(xColName, name, t, errColName, direction);
  if ( errs )
  {
    // Error bars should be the same color as the curve line
    errs->setColor(master_curve->pen().color());
    g->updatePlot();
  }
}

void ApplicationWindow::defineErrorBars(const QString& curveName, const QString& errColumnName, int direction)
{
  Table *w=table(curveName);
  if (!w){//user defined function --> no worksheet available
    QMessageBox::critical(this,tr("MantidPlot - Error"),//Mantid
        tr("This feature is not available for user defined function curves!"));
    return;
  }

  Table *errTable=table(errColumnName);
  if (w->numRows() != errTable->numRows()){
    QMessageBox::critical(this,tr("MantidPlot - Error"),//Mantid
        tr("The selected columns have different numbers of rows!"));

    addErrorBars();
    return;
  }

  int errCol=errTable->colIndex(errColumnName);
  if (errTable->isEmptyColumn(errCol)){
    QMessageBox::critical(this, tr("MantidPlot - Error"),//Mantid
        tr("The selected error column is empty!"));
    addErrorBars();
    return;
  }

  MultiLayer *plot = dynamic_cast<MultiLayer*>(activeWindow(MultiLayerWindow));
  if (!plot)
    return;

  Graph* g = plot->activeGraph();
  if (!g)
    return;

  QwtErrorPlotCurve * errs = g->addErrorBars(curveName, errTable, errColumnName, direction);
  if ( errs )
  {
    QwtPlotCurve * master_curve = g->curve(curveName);
    if (master_curve) errs->setColor(master_curve->pen().color());
    g->updatePlot();
  }
  emit modified();
}

void ApplicationWindow::removeCurves(const QString& name)
{
  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));

  QList<MdiSubWindow *> windows = windowsList();
  foreach(MdiSubWindow *w, windows){
    if (w->isA("MultiLayer"))
    {
      QList<Graph *> layers = dynamic_cast<MultiLayer*>(w)->layersList();
      foreach(Graph *g, layers)
      g->removeCurves(name);
    }
    else if (w->isA("Graph3D"))
    {
      if ( (dynamic_cast<Graph3D*>(w)->formula()).contains(name) )
        dynamic_cast<Graph3D*>(w)->clearData();
    }
  }
  QApplication::restoreOverrideCursor();
}

void ApplicationWindow::updateCurves(Table *t, const QString& name)
{
  QList<MdiSubWindow *> windows = windowsList();
  foreach(MdiSubWindow *w, windows){
    if (w->isA("MultiLayer")){
      QList<Graph *> layers = dynamic_cast<MultiLayer*>(w)->layersList();
      foreach(Graph *g, layers)
      g->updateCurvesData(t, name);
    } else if (w->isA("Graph3D")){
      Graph3D* g = dynamic_cast<Graph3D*>(w);
      if ((g->formula()).contains(name))
        g->updateData(t);
    }
  }
}

void ApplicationWindow::showPreferencesDialog()
{
  ConfigDialog* cd= new ConfigDialog(this);
  cd->setAttribute(Qt::WA_DeleteOnClose);
  cd->setColumnSeparator(columnSeparator);
  cd->exec();
}

void ApplicationWindow::setSaveSettings(bool autoSaving, int min)
{
  if (autoSave==autoSaving && autoSaveTime==min)
    return;

  autoSave=autoSaving;
  autoSaveTime=min;

  killTimer(savingTimerId);

  if (autoSave)
    savingTimerId=startTimer(autoSaveTime*60000);
  else
    savingTimerId=0;
}

void ApplicationWindow::changeAppStyle(const QString& s)
{
  // style keys are case insensitive
  if (appStyle.toLower() == s.toLower())
    return;

  qApp->setStyle(s);
  appStyle = qApp->style()->objectName();

  QPalette pal = qApp->palette();
  pal.setColor (QPalette::Active, QPalette::Base, QColor(panelsColor));
  qApp->setPalette(pal);

}

void ApplicationWindow::changeAppFont(const QFont& f)
{
  if (appFont == f)
    return;

  appFont = f;
  updateAppFonts();
}

void ApplicationWindow::updateAppFonts()
{
  qApp->setFont(appFont);
  this->setFont(appFont);
  info->setFont(QFont(appFont.family(), 2 + appFont.pointSize(), QFont::Bold,false));
}

void ApplicationWindow::updateConfirmOptions(bool askTables, bool askMatrices, bool askPlots2D,
    bool askPlots3D, bool askNotes,bool askInstrWindow)
{
  QList<MdiSubWindow *> windows = windowsList();


  if (confirmCloseTable != askTables){
    confirmCloseTable=askTables;
    foreach(MdiSubWindow *w, windows){

      if (w->inherits("Table"))
      {w->confirmClose(confirmCloseTable);
      }
    }
  }

  if (confirmCloseMatrix != askMatrices){
    confirmCloseMatrix = askMatrices;
    foreach(MdiSubWindow *w, windows){
      if (w->isA("Matrix"))
      {w->confirmClose(confirmCloseMatrix);
      }
    }
  }

  if (confirmClosePlot2D != askPlots2D){
    confirmClosePlot2D=askPlots2D;
    foreach(MdiSubWindow *w, windows){
      if (w->isA("MultiLayer"))
      {w->confirmClose(confirmClosePlot2D);
      }
    }
  }

  if (confirmClosePlot3D != askPlots3D){
    confirmClosePlot3D=askPlots3D;
    foreach(MdiSubWindow *w, windows){
      if (w->isA("Graph3D"))
        w->confirmClose(confirmClosePlot3D);
    }
  }

  if (confirmCloseNotes != askNotes){
    confirmCloseNotes = askNotes;
    foreach(MdiSubWindow *w, windows){
      if (w->isA("Note"))
        w->confirmClose(confirmCloseNotes);
    }
  }

  if (confirmCloseInstrWindow != askInstrWindow){
    confirmCloseInstrWindow = askInstrWindow;

    foreach(MdiSubWindow *w, windows){
      if (w->isA("InstrumentWindow"))
      {w->confirmClose(confirmCloseInstrWindow);
      }
    }
  }
}

void ApplicationWindow::setGraphDefaultSettings(bool autoscale, bool scaleFonts,
    bool resizeLayers, bool antialiasing, bool fixedAspectRatio)
{
  if (autoscale2DPlots == autoscale &&
      autoScaleFonts == scaleFonts &&
      autoResizeLayers != resizeLayers &&
      antialiasing2DPlots == antialiasing &&
      fixedAspectRatio2DPlots == fixedAspectRatio)
    return;

  autoscale2DPlots = autoscale;
  autoScaleFonts = scaleFonts;
  autoResizeLayers = !resizeLayers;
  antialiasing2DPlots = antialiasing;
  fixedAspectRatio2DPlots = fixedAspectRatio;

  QList<MdiSubWindow *> windows = windowsList();
  foreach(MdiSubWindow *w, windows){