bool MatrixModel::calculate(int startRow, int endRow, int startCol, int endCol)
{
	QString formula = d_matrix->formula();
	if (formula.isEmpty())
		return false;

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

	ScriptingEnv *scriptEnv = d_matrix->scriptingEnv();
	Script *script = scriptEnv->newScript(formula, this, QString("<%1>").arg(objectName()));
	connect(script, SIGNAL(error(const QString&,const QString&,int)), scriptEnv, SIGNAL(error(const QString&,const QString&,int)));
	connect(script, SIGNAL(print(const QString&)), scriptEnv, SIGNAL(print(const QString&)));
	
	if (!script->compile()){
		QApplication::restoreOverrideCursor();
		return false;
	}

	if (endRow < 0)
		endRow = d_rows - 1;
	if (endCol < 0)
		endCol = d_cols - 1;
    if (endCol >= d_cols)
		setColumnCount(endCol + 1);
	if (endRow >= d_rows)
        setRowCount(endRow + 1);

	QVariant res;
	double dx = d_matrix->dx();
	double dy = d_matrix->dy();
	double x_start = d_matrix->xStart();
	double y_start = d_matrix->yStart();
	double r = 0.0, c = 0.0;
	for(int row = startRow; row <= endRow; row++){
	    r = row + 1.0;
		script->setDouble(r, "i");
		script->setDouble(r, "row");
		script->setDouble(y_start + row*dy, "y");
		int aux = row*d_cols + startCol;
		for(int col = startCol; col <= endCol; col++){
		    c = col + 1.0;
			script->setDouble(c, "j");
			script->setDouble(c, "col");
			script->setDouble(x_start + col*dx, "x");
			res = script->eval();
			if (res.canConvert(QVariant::Double))
				d_data[aux++] = res.toDouble();
			else {
				QApplication::restoreOverrideCursor();
				d_data[aux++] = GSL_NAN;
				return false;
			}
		}
		qApp->processEvents();
	}

	QApplication::restoreOverrideCursor();
	return true;
}
/**
 * @param env :: A pointer to the current scripting envment
 * @param identifier :: A string identifier, used mainly in error messages to
 * identify the
 * current script
 */
void ScriptFileInterpreter::setupScriptRunner(const ScriptingEnv &env,
                                              const QString &identifier) {
  m_runner = QSharedPointer<Script>(
      env.newScript(identifier, this, Script::Interactive));

  connect(m_runner.data(), SIGNAL(started(const QString &)), this,
          SLOT(setExecutingStatus()));
  connect(m_runner.data(), SIGNAL(started(const QString &)), m_messages,
          SLOT(displayMessageWithTimestamp(const QString &)));
  connect(m_runner.data(), SIGNAL(started(const QString &)), this,
          SIGNAL(executionStarted()));

  connect(m_runner.data(), SIGNAL(finished(const QString &)), m_messages,
          SLOT(displayMessageWithTimestamp(const QString &)));
  connect(m_runner.data(), SIGNAL(finished(const QString &)), this,
          SLOT(setStoppedStatus()));
  connect(m_runner.data(), SIGNAL(finished(const QString &)), this,
          SIGNAL(executionStopped()));

  connect(m_runner.data(), SIGNAL(print(const QString &)), m_messages,
          SLOT(displayMessage(const QString &)));

  connect(m_runner.data(), SIGNAL(error(const QString &, const QString &, int)),
          m_messages, SLOT(displayError(const QString &)));
  connect(m_runner.data(), SIGNAL(error(const QString &, const QString &, int)),
          this, SLOT(setStoppedStatus()));
  connect(m_runner.data(), SIGNAL(error(const QString &, const QString &, int)),
          this, SIGNAL(executionStopped()));
}
/**
 * Construct an object with the given parent
 */
CommandLineInterpreter::CommandLineInterpreter(const ScriptingEnv & environ, QWidget *parent)
  : ScriptEditor(parent,environ.createCodeLexer()), m_runner(), m_history(),
    m_inputBuffer(),m_status(Waiting),
    m_promptKey(markerDefine(QsciScintilla::ThreeRightArrows)),
    m_continuationKey(markerDefine(QsciScintilla::ThreeDots)),
    m_currentPromptLineIndex(0),
    m_pastedText(), m_pasteQueue(),
    m_copy(NULL), m_cut(NULL), m_paste(NULL), m_saveAs(NULL),
    m_zoomIn(NULL), m_zoomOut(NULL)
{
  enableAutoCompletion();
  setupEnvironment(environ);
  setupMargin();
  setupIndentation();
  setupFont();

  initActions();

  setContextMenuPolicy(Qt::CustomContextMenu);
  connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
          this, SLOT(showContextMenu(const QPoint &)));
  setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  // Need to disable some default key bindings that Scintilla provides as they don't really
  // fit here
  remapWindowEditingKeys();
}
/**
 * @param environ :: A pointer to the current scripting environment
 * @param identifier :: A string identifier, used mainly in error messages to identify the
 * current script
 */
void ScriptFileInterpreter::setupEditor(const ScriptingEnv & environ, const QString & identifier)
{
  if(QFileInfo(identifier).exists())
  {
    readFileIntoEditor(identifier);
  }
  m_editor->setLexer(environ.createCodeLexer());
  m_editor->padMargin();
  m_editor->setAutoMarginResize();
  m_editor->enableAutoCompletion();
  m_editor->setCursorPosition(0,0);

  connect(m_editor, SIGNAL(textChanged()), this, SIGNAL(textChanged()));
  connect(m_editor, SIGNAL(modificationChanged(bool)), this, SIGNAL(editorModificationChanged(bool)));
  connect(m_editor, SIGNAL(undoAvailable(bool)), this, SIGNAL(editorUndoAvailable(bool)));
  connect(m_editor, SIGNAL(redoAvailable(bool)), this, SIGNAL(editorRedoAvailable(bool)));
}