changeset 13440:e7e671d727b2

Updated and patched text editor from QtOctave.
author Jacob Dawid <jacob.dawid@googlemail.com>
date Thu, 14 Apr 2011 12:24:05 +0200
parents 8b09300bbf29
children 466638363643
files gui//Quint.pro gui//src/CodeEdit.cpp gui//src/CodeEdit.h gui//src/FileEditorMdiSubWindow.cpp gui//src/FileEditorMdiSubWindow.h gui//src/MainWindow.cpp gui//src/MainWindow.h gui//src/NumberedCodeEdit.cpp gui//src/NumberedCodeEdit.h gui//src/SimpleEditor.cpp gui//src/SimpleEditor.h gui//src/SyntaxHighlighter.cpp gui//src/SyntaxHighlighter.h
diffstat 13 files changed, 1207 insertions(+), 973 deletions(-) [+]
line wrap: on
line diff
--- a/gui//Quint.pro
+++ b/gui//Quint.pro
@@ -43,11 +43,11 @@
     src/VariablesDockWidget.cpp \
     src/HistoryDockWidget.cpp \
     src/FilesDockWidget.cpp \
-    src/CodeEdit.cpp \
     src/FileEditorMdiSubWindow.cpp \
     src/SyntaxHighlighter.cpp \
     src/BrowserWidget.cpp \
-    src/NumberedCodeEdit.cpp
+    src/NumberedCodeEdit.cpp \
+    src/SimpleEditor.cpp
 
 HEADERS += \
         src/TerminalCharacterDecoder.h \
@@ -87,11 +87,11 @@
     src/VariablesDockWidget.h \
     src/HistoryDockWidget.h \
     src/FilesDockWidget.h \
-    src/CodeEdit.h \
     src/FileEditorMdiSubWindow.h \
     src/SyntaxHighlighter.h \
     src/BrowserWidget.h \
-    src/NumberedCodeEdit.h
+    src/NumberedCodeEdit.h \
+    src/SimpleEditor.h
 
 INCFLAGS = -g3 $$system(mkoctfile -p INCFLAGS)
 LFLAGS = $$system(mkoctfile -p LFLAGS) \
deleted file mode 100644
--- a/gui//src/CodeEdit.cpp
+++ /dev/null
@@ -1,316 +0,0 @@
-/* Copyright (C) 2007 Alejandro Álvarez
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <QContextMenuEvent>
-#include "CodeEdit.h"
-
-CodeEdit::CodeEdit(QWidget *parent)
-    : QPlainTextEdit(parent),
-      contextMenu(this) {
-
-    m_syntaxHighlighter=new SyntaxHighlighter(document());
-
-    setUndoRedoEnabled(true);
-    setTabStopWidth(32);
-    setFrameStyle(QFrame::NoFrame);
-
-    autocompletion_ok=true;//(get_config("autoCompletion")!="false");
-
-    // ContextMenu
-
-    connect(contextMenu.addAction(tr("Undo")), SIGNAL(triggered()),
-          this, SLOT(undo()));
-    connect(contextMenu.addAction(tr("Redo")), SIGNAL(triggered()),
-          this, SLOT(redo()));
-
-    contextMenu.addSeparator();
-
-    connect(contextMenu.addAction(tr("Cut")), SIGNAL(triggered()),
-          this, SLOT(cut()));
-    connect(contextMenu.addAction(tr("Copy")), SIGNAL(triggered()),
-          this, SLOT(copy()));
-    connect(contextMenu.addAction(tr("Paste")), SIGNAL(triggered()),
-          this, SLOT(paste()));
-    connect(contextMenu.addAction(tr("Delete")), SIGNAL(triggered()),
-          this, SLOT(deleteSelection()));
-
-    contextMenu.addSeparator();
-
-    connect(contextMenu.addAction(tr("Select all")), SIGNAL(triggered()),
-          this, SLOT(selectAll()));
-
-    contextMenu.addSeparator();
-
-    connect(contextMenu.addAction(tr("Toggle breakpoint")), SIGNAL(triggered()),
-          this, SLOT(toggleBreakpoint()));
-
-    //connect(this->document(), SIGNAL( contentsChange ( int , int , int  )), this, SLOT(buildUndoRedoStack(int , int , int)) );
-
-    if(autocompletion_ok)
-    {
-        connect(this->document(), SIGNAL( contentsChange ( int , int , int  )), this, SLOT(buildAutoCompletionList(int , int , int)) );
-        connect(&completion, SIGNAL(activated ( const QModelIndex &)), this, SLOT(doCompletion(const QModelIndex &)) );
-    }
-
-
-    octaveCommandTimer.setSingleShot(true);
-    octaveCommandTimer.setInterval(2000);
-
-    connect(&octaveCommandTimer, SIGNAL(timeout ()), this, SLOT(octaveCommandCompletion()));
-
-    completionTimer.setSingleShot(true);
-    completionTimer.setInterval(200);
-
-    connect(&completionTimer, SIGNAL(timeout ()), this, SLOT(buildAutoCompletionList()));
-
-    auto_indent=true;
-    setAcceptDrops(false);
-    if(autocompletion_ok)
-    {
-        completion.setWidget(this);
-        completion_model=new QStringListModel(&completion);
-        completion.setModel(completion_model);
-        completion.setCompletionMode(QCompleter::UnfilteredPopupCompletion);
-    }
-
-    text_modified_stop_ok=context_changed_ok=false;
-
-    connect(document(), SIGNAL(modificationChanged (bool)), this, SLOT(textModified_cb(bool)));
-
-    auto_indent=true;//("false"!=get_config("autoindent"));
-    automatic_indention_statement_ok=true;//(get_config("autoindent_statements")=="true");
-}
-
-CodeEdit::~CodeEdit() {
-    delete m_syntaxHighlighter;
-}
-
-void CodeEdit::contextMenuEvent(QContextMenuEvent *contextMenuEvent) {
-    contextMenu.exec(contextMenuEvent->globalPos());
-}
-
-void CodeEdit::undo() {
-    document()->undo();
-}
-
-void CodeEdit::redo() {
-    document()->redo();
-}
-
-void CodeEdit::deleteSelection() {
-    textCursor().removeSelectedText();
-}
-
-void CodeEdit::toggleBreakpoint() {
-    int line = 1;
-    for(QTextBlock tb = document()->begin(); tb.isValid(); line++, tb = tb.next()) {
-        if(tb == textCursor().block()) {
-            emit toggleBreakpoint(line);
-            return;
-        }
-    }
-}
-
-bool CodeEdit::event(QEvent * event) {
-    if(QEvent::KeyPress==event->type())
-    {
-        QKeyEvent *k=(QKeyEvent *)event;
-        if(autocompletion_ok && (Qt::Key_Left==k->key() || Qt::Key_Right==k->key())) {
-            completion.popup()->hide();
-        } else if(Qt::Key_Return==k->key() ||  Qt::Key_Enter==k->key()) {
-            if(autocompletion_ok && !completion.popup()->isHidden()) {
-                doCompletion(completion.popup()->currentIndex());
-            } else if(auto_indent) {
-                QTextCursor cursor=textCursor();
-                int pos=cursor.position();
-                cursor.movePosition(QTextCursor::StartOfBlock,QTextCursor::KeepAnchor);
-                QString line=cursor.selectedText();
-                QString start_blank;
-                start_blank.append('\n');
-                for(int i=0;i<line.length() && (line.at(i)==' ' || line.at(i)=='\t');i++)
-                    start_blank.append(line.at(i));
-                if( automatic_indention_statement_ok ) {
-                    QRegExp re("^while[ |(].*|^if[ |(].*|^for .*|^switch[ |(].*|^do$|^try|^else|^elseif$");
-                    if(re.exactMatch( line.trimmed() ) )
-                            start_blank.append("\t");
-                }
-
-                cursor.setPosition(pos);
-                cursor.insertText(start_blank);
-                setTextCursor(cursor);
-            } else {
-                return QPlainTextEdit::event(event);
-            }
-            return true;
-        }
-    }
-    return QPlainTextEdit::event(event);
-}
-
-void CodeEdit::buildAutoCompletionList(int pos, int charsRemoved, int charsAdded) {
-    octaveCommandTimer.stop();
-    document()->setModified(true);
-    context_changed_ok=true;
-
-    completionPosition=pos;
-    completionTimer.start();
-    completion.popup()->hide();
-}
-
-void CodeEdit::buildAutoCompletionList() {
-    QTextCursor cursor=textCursor();
-    int pos=cursor.position()-1;
-    //printf("[CodeEdit::buildAutoCompletionList] pos=%d completionPosition=%d\n", pos, completionPosition);
-    if(pos!=completionPosition)
-            return;
-
-    QTextBlock block=document()->findBlock(pos);
-
-    pos-=block.position();
-    int i=pos;
-    QString text=block.text();
-    QRegExp re("([^a-zA-Z_0-9]+)");
-    i=re.lastIndexIn(text, i);
-    //printf("pos=%d i=%d len=%d\n", pos, i, re.matchedLength());
-    if( i==pos ) {completion.popup()->hide();return;}
-    QString word_to_complete=text.mid(i+1,pos-i);
-    //printf("i=%d word=>%s<\n",i, word_to_complete.toLocal8Bit().data());
-    QString actual_word;
-    re.setPattern("([a-zA-Z_0-9]+)");
-    i=re.indexIn(text, pos);
-    if( i==pos ) actual_word=word_to_complete+text.mid(pos+1,re.matchedLength()-1);
-    //printf("i=%d word=>%s<\n",i, actual_word.toLocal8Bit().data());
-
-    if(word_to_complete.length()==2) {
-        completion_model->setStringList(m_syntaxHighlighter->octave_comands);
-        completion.setCompletionPrefix(word_to_complete);
-        completion.popup()->hide();
-
-        octaveCommandTimer.start();
-        return;
-    }
-    else if(word_to_complete.length()<3) {completion.popup()->hide();return;}
-
-    emit dynamicHelpRequired(word_to_complete);
-
-    //Se construye la lista de palabras a completar
-
-    QTextBlock blockInit, blockEnd;
-    blockInit=document()->firstBlock();
-    blockEnd =document()->lastBlock();
-    completion_list.clear();
-    buildAutoCompletionListSlide(completion_list, blockInit, blockEnd, word_to_complete, actual_word);
-
-    if(completion_list.isEmpty()) {completion.popup()->hide();return;}
-
-    completion_model->setStringList(completion_list);
-
-
-    QRect _position=cursorRect();
-
-    //printf("x=%d y=%d width=%d height=%d\n", _position.x(), _position.y(), _position.width(), _position.height() );
-
-    //_position.moveTo(_position.bottomRight() );
-    ////_position.setWidth(100);
-    _position.setWidth(width()/3);
-
-    completion.setCompletionPrefix(word_to_complete);
-    completion.complete(_position);
-    completion.popup()->show();
-    completion.popup()->setFocus(Qt::TabFocusReason);
-}
-
-void CodeEdit::buildAutoCompletionListSlide(QStringList &list, QTextBlock blockInit, QTextBlock blockEnd, QString word_to_complete, QString actual_word) {
-    //QStringList list;
-
-    //printf("Buscando lista\n");
-    //block=document()->findBlock(0);
-
-    QTextBlock block=blockInit;
-
-    //QString match;
-    QRegExp rx("([a-zA-Z_0-9]+)");
-
-    while( block.isValid() )
-    {
-            QString text=block.text();
-            int i = 0;
-
-            while ((i = rx.indexIn(text, i)) != -1) {
-                    QString word=rx.cap(1);
-                    if( word.startsWith(word_to_complete) && !list.contains(word) && word!=actual_word )
-                    {
-                            list << word;
-                            //printf("i=%d word=>%s< actual_word=>%s<\n",i, word.toLocal8Bit().data(), actual_word.toLocal8Bit().data());
-                    }
-                    i += rx.matchedLength();
-            }
-
-            if(block!=blockEnd) block=block.next();
-            else break;
-    }
-}
-
-void CodeEdit::octaveCommandCompletion() {
-    QRect _position=cursorRect();
-
-    _position.setWidth(width());
-
-    completion.complete(_position);
-    completion.popup()->show();
-    completion.popup()->setFocus(Qt::TabFocusReason);
-}
-
-
-void CodeEdit::doCompletion(const QModelIndex &index) {
-    QString word=index.data().toString();
-    QString prefix=completion.completionPrefix();
-
-    QString suffix=word.mid(prefix.length());
-
-    QTextCursor cursor=textCursor();
-    cursor.insertText(suffix);
-
-    completion.popup()->hide();
-}
-
-void CodeEdit::textModified_cb(bool ok) {
-    //printf("[CodeEdit::textModified_cb] Entered\n");
-    if(text_modified_stop_ok) return;
-    emit textModified(ok);
-    //printf("[CodeEdit::textModified_cb] text_modified emit\n");
-}
-
-void CodeEdit::publicBlockBoundingRectList(QVector<qreal> &list, int &first_line){
-
-    qreal pageBottom = viewport()->height();
-    QPointF offset=contentOffset();
-    QTextBlock block=firstVisibleBlock();
-    first_line=block.blockNumber()+1;
-    qreal first_position=blockBoundingGeometry(block).topLeft().y();
-
-    for ( ; block.isValid(); block = block.next() )
-    {
-            QRectF position=blockBoundingGeometry(block);
-            qreal y=position.topLeft().y()+offset.y()-first_position;
-
-            if(y>pageBottom) break;
-
-            list.append(y);
-    }  
-}
deleted file mode 100644
--- a/gui//src/CodeEdit.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Copyright (C) 2007 Alejandro Álvarez
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef CODEEDIT_H
-#define CODEEDIT_H
-
-#include <QPlainTextEdit>
-#include <QMenu>
-#include <QTextCursor>
-#include "SyntaxHighlighter.h"
-#include <QCompleter>
-#include <QStringListModel>
-#include <QTimer>
-#include "config.h"
-#include <QUndoStack>
-
-struct UndoRedoItem
-{
-	int size, pos;
-	QString text;
-};
-
-/**TextEdit that supports highlited syntax and autocompletion.*/
-class CodeEdit: public QPlainTextEdit {
-    Q_OBJECT
-public:
-    CodeEdit(QWidget *parent = 0);
-    ~CodeEdit();
-
-    /**List of y top left positions of bounding rects of each visible block of text.
-    * @param list List of top left positions.
-    * @param first_line First visible block in TextEdit.
-    */
-    void publicBlockBoundingRectList(QVector<qreal>  &list, int &first_line);
-
-public slots:
-    void undo();
-    void redo();
-    void deleteSelection();
-    void toggleBreakpoint();
-    void buildAutoCompletionList(int pos, int charsRemoved, int charsAdded );
-    void buildAutoCompletionList();
-    void doCompletion(const QModelIndex &index);
-    void octaveCommandCompletion();
-    void textModified_cb(bool ok);
-
-signals:
-    void toggleBreakpoint(int lineno);
-
-    /** Dynamic help required. */
-    void dynamicHelpRequired(const QString &text);
-
-    /** Text modified. */
-    void textModified(bool ok);
-
-protected:
-    SyntaxHighlighter *m_syntaxHighlighter;
-    QMenu contextMenu;
-    void contextMenuEvent(QContextMenuEvent *e);
-    bool event( QEvent * e );
-
-private:
-    bool auto_indent;
-    QCompleter completion;
-    QStringListModel *completion_model;
-    QTimer braketsTimer, octaveCommandTimer, completionTimer;
-    QStringList completion_list;
-    int completionPosition;
-
-    /** Builds auto completion list from block blockInit to blockEnd. */
-    void buildAutoCompletionListSlide(QStringList &list, QTextBlock blockInit, QTextBlock blockEnd, QString word_to_complete, QString actual_word);
-
-    bool text_modified_stop_ok; //Stops emit of text_modified signal
-    bool context_changed_ok;
-
-    /** Automatic indention for while, if, for, switch, do and try statements. */
-    bool automatic_indention_statement_ok;
-    /** Auto completion. */
-    bool autocompletion_ok;
-};
-
-#endif // CODEEDIT_H
--- a/gui//src/FileEditorMdiSubWindow.cpp
+++ b/gui//src/FileEditorMdiSubWindow.cpp
@@ -22,6 +22,7 @@
 #include <QFile>
 #include <QFileDialog>
 #include <QMessageBox>
+#include <QAction>
 
 FileEditorMdiSubWindow::FileEditorMdiSubWindow(QWidget *parent)
     : QMdiSubWindow(parent) {
@@ -34,7 +35,7 @@
     QFile file(fileName);
     file.open(QFile::ReadOnly);
 
-    m_codeEdit->setPlainText(file.readAll());
+    m_simpleEditor->setPlainText(file.readAll());
 
     file.close();
 }
@@ -59,7 +60,7 @@
 
     m_fileName = "<unnamed>";
     setWindowTitle(m_fileName);
-    m_codeEdit->setPlainText("");
+    m_simpleEditor->setPlainText("");
 }
 
 void FileEditorMdiSubWindow::saveFile() {
@@ -67,12 +68,12 @@
     QFile file(saveFileName);
     file.open(QFile::WriteOnly);
 
-    if(file.write(m_codeEdit->toPlainText().toLocal8Bit()) == -1) {
+    if(file.write(m_simpleEditor->toPlainText().toLocal8Bit()) == -1) {
         QMessageBox::warning(this,
                              "Error Saving File",
                              QString("The file could not be saved: %1.").arg(file.errorString()));
     } else {
-        m_codeEdit->document()->setModified(false);
+        m_simpleEditor->document()->setModified(false);
     }
 
     file.close();
@@ -102,12 +103,12 @@
     QStyle *style = QApplication::style();
     setWidget(new QWidget());
     m_toolBar = new QToolBar(this);
-    m_codeEdit = new CodeEdit(this);
+    m_simpleEditor = new SimpleEditor(this);
     m_statusBar = new QStatusBar(this);
-    m_numberedTextView = new NumberedTextView(this, m_codeEdit);
+    m_numberedTextView = new NumberedCodeEdit(this, m_simpleEditor);
 
-    m_codeEdit->setFont(QFont("Courier"));
-    m_codeEdit->setLineWrapMode(QPlainTextEdit::NoWrap);
+    m_simpleEditor->setFont(QFont("Courier"));
+    m_simpleEditor->setLineWrapMode(QPlainTextEdit::NoWrap);
 
     QAction *newAction = new QAction(style->standardIcon(QStyle::SP_FileIcon),
         "", m_toolBar);
@@ -131,8 +132,8 @@
     widget()->setLayout(layout);
 
     connect(newAction, SIGNAL(triggered()), this, SLOT(newFile()));
-    connect(undoAction, SIGNAL(triggered()), m_codeEdit, SLOT(undo()));
-    connect(redoAction, SIGNAL(triggered()), m_codeEdit, SLOT(redo()));
+    connect(undoAction, SIGNAL(triggered()), m_simpleEditor, SLOT(undo()));
+    connect(redoAction, SIGNAL(triggered()), m_simpleEditor, SLOT(redo()));
     connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile()));
 
     connect(newAction, SIGNAL(hovered()), this, SLOT(showToolTipNew()));
@@ -140,7 +141,7 @@
     connect(redoAction, SIGNAL(hovered()), this, SLOT(showToolTipRedo()));
     connect(saveAction, SIGNAL(hovered()), this, SLOT(showToolTipSave()));
 
-    connect(m_codeEdit, SIGNAL(modificationChanged(bool)), this, SLOT(registerModified(bool)));
+    connect(m_simpleEditor, SIGNAL(modificationChanged(bool)), this, SLOT(registerModified(bool)));
 
     m_fileName = "";
     setWindowTitle(m_fileName);
--- a/gui//src/FileEditorMdiSubWindow.h
+++ b/gui//src/FileEditorMdiSubWindow.h
@@ -22,7 +22,7 @@
 #include <QMdiSubWindow>
 #include <QToolBar>
 #include <QStatusBar>
-#include "CodeEdit.h"
+#include "SimpleEditor.h"
 #include "NumberedCodeEdit.h"
 
 class FileEditorMdiSubWindow : public QMdiSubWindow {
@@ -44,8 +44,8 @@
 private:
     void construct();
     QToolBar *m_toolBar;
-    CodeEdit *m_codeEdit;
-    NumberedTextView *m_numberedTextView;
+    SimpleEditor *m_simpleEditor;
+    NumberedCodeEdit *m_numberedTextView;
     QStatusBar *m_statusBar;
     QString m_fileName;
     bool m_modified;
--- a/gui//src/MainWindow.cpp
+++ b/gui//src/MainWindow.cpp
@@ -63,7 +63,6 @@
     QSettings settings(m_settingsFile, QSettings::IniFormat);
     restoreGeometry(settings.value("MainWindow/geometry").toByteArray());
     restoreState(settings.value("MainWindow/windowState").toByteArray());
-
 }
 
 void MainWindow::writeSettings() {
--- a/gui//src/MainWindow.h
+++ b/gui//src/MainWindow.h
@@ -30,7 +30,7 @@
 #include "VariablesDockWidget.h"
 #include "HistoryDockWidget.h"
 #include "FilesDockWidget.h"
-#include "CodeEdit.h"
+#include "SimpleEditor.h"
 #include "BrowserWidget.h"
 
 // Octave includes
--- a/gui//src/NumberedCodeEdit.cpp
+++ b/gui//src/NumberedCodeEdit.cpp
@@ -26,6 +26,9 @@
 #include <QToolTip>
 #include <QTextStream>
 #include <QProcess>
+#include <QRegExp>
+#include <QMessageBox>
+#include <QFileInfo>
 
 #include "NumberedCodeEdit.h"
 #include "config.h"
@@ -35,10 +38,9 @@
 {
     // Make room for 4 digits and the breakpoint icon
     setFixedWidth( fontMetrics().width( QString("0000") + 10 + 32 ) );
-    stopMarker = QPixmap(); //QString(ICON_PATH) + "/stop.png" );
-    currentMarker = QPixmap(); // QString(ICON_PATH) + "/bookmark.png" );
-    bugMarker = QPixmap(); // QString(ICON_PATH) + "/bug.png" );
-    setFont(QFont("Courier"));
+    stopMarker = QPixmap();// QString(ICON_PATH) + "/stop.png" );
+    currentMarker = QPixmap();// QString(ICON_PATH) + "/bookmark.png" );
+    bugMarker = QPixmap();// QString(ICON_PATH) + "/bug.png" );
 }
 
 NumberBar::~NumberBar()
@@ -70,7 +72,7 @@
   update();
 }
 
-void NumberBar::setTextEdit( CodeEdit *edit )
+void NumberBar::setTextEdit( SimpleEditor *edit )
 {
     this->edit = edit;
     setFixedWidth( edit->fontMetrics().width( QString("0000") + 10 + 32 ) );
@@ -87,7 +89,7 @@
     edit->publicBlockBoundingRectList(lines_list, first_line_no);
     
     const QFontMetrics fm = edit->fontMetrics();
-    const int ascent = fontMetrics().ascent(); // height = ascent + descent + 1
+    const int ascent = fontMetrics().ascent(); // height = ascent + descent
    
     QPainter p(this);
     p.setPen(palette().windowText().color());
@@ -107,7 +109,7 @@
     	lineCount=first_line_no+i;
     	
     	const QString txt = QString::number( lineCount );
-        p.drawText( width() - fm.width(txt) - 2, position_y+ascent, txt );
+        p.drawText( width() - fm.width(txt)- 2, position_y+ascent, txt );
         
         // Bug marker
 	if ( bugLine == lineCount ) {
@@ -127,6 +129,55 @@
 	    currentRect = QRect( 1, position_y, currentMarker.width(), currentMarker.height() );
 	}
     }
+    
+    /*
+    
+    int contentsY = edit->verticalScrollBar()->value();
+    qreal pageBottom = contentsY + edit->viewport()->height();
+    const QFontMetrics fm = fontMetrics();
+    const int ascent = fontMetrics().ascent() + 1; // height = ascent + descent + 1
+    int lineCount = 1;
+
+    QPainter p(this);
+    p.setPen(palette().windowText().color());
+
+    bugRect = QRect();
+    stopRect = QRect();
+    currentRect = QRect();
+
+    for ( QTextBlock block = edit->document()->begin();
+	  block.isValid(); block = block.next(), ++lineCount ) {
+
+        const QRectF boundingRect = edit->publicBlockBoundingRect( block );
+
+        QPointF position = boundingRect.topLeft();
+        if ( position.y() + boundingRect.height() < contentsY )
+            continue;
+        if ( position.y() > pageBottom )
+            break;
+
+        const QString txt = QString::number( lineCount );
+        p.drawText( width() - fm.width(txt), qRound( position.y() ) - contentsY + ascent, txt );
+
+	// Bug marker
+	if ( bugLine == lineCount ) {
+	    p.drawPixmap( 1, qRound( position.y() ) - contentsY, bugMarker );
+	    bugRect = QRect( 1, qRound( position.y() ) - contentsY, bugMarker.width(), bugMarker.height() );
+	}
+
+	// Stop marker
+	if ( breakpoints.contains(lineCount) ) {
+	    p.drawPixmap( 19, qRound( position.y() ) - contentsY, stopMarker );
+	    stopRect = QRect( 19, qRound( position.y() ) - contentsY, stopMarker.width(), stopMarker.height() );
+	}
+
+	// Current line marker
+	if ( currentLine == lineCount ) {
+	    p.drawPixmap( 19, qRound( position.y() ) - contentsY, currentMarker );
+	    currentRect = QRect( 19, qRound( position.y() ) - contentsY, currentMarker.width(), currentMarker.height() );
+	}
+    }
+    */
 }
 
 bool NumberBar::event( QEvent *event )
@@ -155,7 +206,7 @@
 
 
 
-NumberedTextView::NumberedTextView( QWidget *parent, CodeEdit *textEdit )
+NumberedCodeEdit::NumberedCodeEdit( QWidget *parent, SimpleEditor *textEdit )
     : QFrame( parent )
 {
 	setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
@@ -193,16 +244,16 @@
 	vbox->addLayout(messages_layout);
 	messages_layout->setSpacing( 0 );
 	messages_layout->setMargin( 0 );
-}
+	}
 
 
-NumberedTextView::~NumberedTextView()
+NumberedCodeEdit::~NumberedCodeEdit()
 {
 	hide();
 	//printf("Borrado ntv\n");
 }
 
-void NumberedTextView::setCurrentLine( int lineno )
+void NumberedCodeEdit::setCurrentLine( int lineno )
 {
 	currentLine = lineno;
 	if(numbers!=NULL) numbers->setCurrentLine( lineno );
@@ -223,20 +274,50 @@
 	textChanged( 0, 0, 1 );
 }
 
-void NumberedTextView::toggleBreakpoint( int lineno )
+void NumberedCodeEdit::toggleBreakpoint( int lineno )
 {
 	if(numbers!=NULL) numbers->toggleBreakpoint( lineno );
 }
 
-void NumberedTextView::setBugLine( int lineno )
+void NumberedCodeEdit::setBugLine( int lineno )
 {
 	if(numbers!=NULL) numbers->setBugLine( lineno );
 }
 
-void NumberedTextView::textChanged( int /*pos*/, int removed, int added )
+void NumberedCodeEdit::textChanged( int /*pos*/, int removed, int added )
 {
+    //Q_UNUSED( pos );
+
     if ( removed == 0 && added == 0 )
 	return;
+
+    //QTextBlock block = highlight.block();
+    //QTextBlock block = view->document()->begin();
+    //QTextBlockFormat fmt = block.blockFormat();
+    //QColor bg = view->palette().base().color();
+    //fmt.setBackground( bg );
+    //highlight.setBlockFormat( fmt );
+    /*
+    QTextBlockFormat fmt;
+
+    int lineCount = 1;
+    for ( QTextBlock block = view->document()->begin();
+	  block.isValid() && block!=view->document()->end(); block = block.next(), ++lineCount ) {
+
+	if ( lineCount == currentLine )
+	{
+	    fmt = block.blockFormat();
+	    QColor bg = view->palette().highlight().color();
+	    fmt.setBackground( bg );
+
+	    highlight = QTextCursor( block );
+	    highlight.movePosition( QTextCursor::EndOfBlock, QTextCursor::KeepAnchor );
+	    highlight.setBlockFormat( fmt );
+
+	    break;
+	}
+    }
+    */
     
     if( !textModifiedOk && view->document()->isModified() )
     {
@@ -245,7 +326,7 @@
     }
 }
 
-bool NumberedTextView::eventFilter( QObject *obj, QEvent *event )
+bool NumberedCodeEdit::eventFilter( QObject *obj, QEvent *event )
 {
     if ( obj != view )
 	return QFrame::eventFilter(obj, event);
@@ -260,48 +341,74 @@
 	QString word = cursor.selectedText();
 	emit mouseHover( word );
 	emit mouseHover( helpEvent->pos(), word );
+
+	// QToolTip::showText( helpEvent->globalPos(), word ); // For testing
     }
 
     return false;
 }
 
-QList<int> *NumberedTextView::getBreakpoints()
+QList<int> *NumberedCodeEdit::getBreakpoints()
 {
 	QList<int> *br=NULL;
 	if(numbers!=NULL) br=numbers->getBreakpoints();
 	return br;
 }
 
-void NumberedTextView::open(QString path)
+void NumberedCodeEdit::open(QString path)
 {
   FILE *fl;
 
   fl = fopen(path.toLocal8Bit().constData(), "rt");
   if(fl)
   {
-    filePath = path;
-    QTextStream stream(fl);
-    textEdit()->document()->setPlainText(stream.readAll());
-    fclose(fl);
-    textModifiedOk=false;
-     textEdit()->document()->setModified(false);
+	fclose(fl);
+	filePath = path;
+	
+	textEdit()->load(path);
+	
+	textModifiedOk=false;
+	textEdit()->document()->setModified(false);
   }else{
     throw path;
   }
 }
 
-void NumberedTextView::save(QString path)
+bool NumberedCodeEdit::save(QString path)
 {
   FILE *fl;
 
-  if(path.isEmpty())
-    path = filePath;
-  else
-    filePath = path;
-
+  if(path.isEmpty()) path = filePath;
+  QRegExp re("[A-Za-z_][A-Za-z0-9_]*\\.m");
+  
+  if( ! re.exactMatch( QFileInfo(path).fileName() ) )
+  {
+	QMessageBox msgBox;
+	msgBox.setText( tr("This file name is not valid.") );
+	msgBox.setInformativeText(tr("Octave doesn't understand this file name:\n")+path+tr("\nPlease, change it.\n Do you want to save your changes?"));
+	msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Cancel);
+	msgBox.setDefaultButton(QMessageBox::Save);
+	int ret = msgBox.exec();
+	switch (ret)
+	{
+		case QMessageBox::Save:
+		    // Save was clicked
+		    break;
+		case QMessageBox::Cancel:
+		    // Cancel was clicked
+		    	return false;
+		    break;
+		default:
+		    // should never be reached
+		    break;
+	}
+  }
+  
+  
   fl = fopen(path.toLocal8Bit().constData(), "wt");
   if(fl)
   {
+    filePath = path;
     QTextStream *stream = new QTextStream(fl);
     (*stream) << textEdit()->document()->toPlainText();
     delete stream;
@@ -309,37 +416,47 @@
     textModifiedOk=false;
     view->document()->setModified(false);
   }else{
-    throw path;
+    return false;
   }
   
-    QString repository=path+"~~";
-    QString command("simplercs \""+repository+"\" \""+path+"\"");
-    QProcess::startDetached(command);
-    //QProcess::execute(command);
-
+  /*if(get_config("simple_rcs")=="true")
+  {
+  	QString repository=path+"~~";
+  	QString command("simplercs \""+repository+"\" \""+path+"\"");
+  	QProcess::startDetached(command);
+  	//QProcess::execute(command);
+  	printf("[NumberedTextView::save] Comando: %s\n", command.toLocal8Bit().data() );
+  }
+  else
+  {
+  	//printf("[NumberedTextView::save] No rcs\n");
+  }*/
+  
+  return true;
 }
 
-QString NumberedTextView::path()
+QString NumberedCodeEdit::path()
 {
   return filePath;
 }
 
-void NumberedTextView::setPath(QString path)
+void NumberedCodeEdit::setPath(QString path)
 {
 	filePath=path;
+	textEdit()->setFile(path);
 }
 
-void NumberedTextView::setModified(bool modify)
+void NumberedCodeEdit::setModified(bool modify)
 {
 	textModifiedOk=modify;
 }
 
-bool NumberedTextView::modified()
+bool NumberedCodeEdit::modified()
 {
 	return textModifiedOk;
 }
 
-void NumberedTextView::cursor_moved_cb()
+void NumberedCodeEdit::cursor_moved_cb()
 {
 	QTextCursor cursor=view->textCursor();
 	QTextBlock actual_block=cursor.block();
@@ -347,7 +464,6 @@
 	QTextBlock block = view->document()->begin();
 	
 	for ( ;block.isValid() && actual_block!=block; block = block.next()) lineCount++ ;
-
 }
 
 static QString startLineInsertText(QString str, QString textToInsert)
@@ -419,7 +535,7 @@
 	return list.join("\n");
 }
 
-void NumberedTextView::indent()
+void NumberedCodeEdit::indent()
 {
 	//QTextDocument *doc=textEdit()->document();
 	
@@ -436,7 +552,7 @@
 	textEdit()->setTextCursor(cursor);
 }
 
-void NumberedTextView::unindent()
+void NumberedCodeEdit::unindent()
 {
 	//QTextDocument *doc=textEdit()->document();
 	
@@ -455,7 +571,7 @@
 	textEdit()->setTextCursor(cursor);
 }
 
-void NumberedTextView::comment()
+void NumberedCodeEdit::comment()
 {
 	//QTextDocument *doc=textEdit()->document();
 	
@@ -472,7 +588,7 @@
 	textEdit()->setTextCursor(cursor);
 }
 
-void NumberedTextView::uncomment()
+void NumberedCodeEdit::uncomment()
 {
 	//QTextDocument *doc=textEdit()->document();
 	
--- a/gui//src/NumberedCodeEdit.h
+++ b/gui//src/NumberedCodeEdit.h
@@ -27,9 +27,9 @@
 #include <QLabel>
 #include <QVBoxLayout>
 #include <QHBoxLayout>
-#include "CodeEdit.h"
+#include "SimpleEditor.h"
 
-class CodeEdit;
+class SimpleEditor;
 class QHBoxLayout;
 
 /**
@@ -48,14 +48,14 @@
     void toggleBreakpoint( int lineno );
     QList<int> *getBreakpoints();
 
-    void setTextEdit( CodeEdit *edit );
+    void setTextEdit( SimpleEditor *edit );
     void paintEvent( QPaintEvent *ev );
 
 protected:
     bool event( QEvent *ev );
 
 private:
-    CodeEdit *edit;
+    SimpleEditor *edit;
     QPixmap stopMarker;
     QPixmap currentMarker;
     QPixmap bugMarker;
@@ -70,18 +70,20 @@
 /**
  * Displays a CodeEdit with line numbers.
  */
-class NumberedTextView : public QFrame
+class NumberedCodeEdit : public QFrame
 {
     Q_OBJECT
 
 public:
-    NumberedTextView( QWidget *parent = 0 , CodeEdit *textEdit=new CodeEdit() );
-    ~NumberedTextView();
+    NumberedCodeEdit( QWidget *parent = 0 , SimpleEditor *textEdit=new SimpleEditor() );
+    ~NumberedCodeEdit();
 
     QList<int> *getBreakpoints();
 
     void open(QString path);
-    void save(QString path = QString());
+    
+    /**Saves file to path. @return true if all is OK.*/
+    bool save(QString path = QString());
 
     QString path();
     void setPath(QString path);
@@ -90,7 +92,7 @@
     void setModified(bool modify);
 
     /** Returns the CodeEdit of the main view. */
-    CodeEdit *textEdit() const { return view; }
+    SimpleEditor *textEdit() const { return view; }
 
     /**
      * Sets the line that should have the current line indicator.
@@ -151,7 +153,8 @@
 
 private:
     QString filePath;
-    CodeEdit *view;
+    QLabel *line_column_label;
+    SimpleEditor *view;
     NumberBar *numbers;
     QHBoxLayout *hbox;
     QVBoxLayout *vbox;
new file mode 100644
--- /dev/null
+++ b/gui//src/SimpleEditor.cpp
@@ -0,0 +1,363 @@
+/* Copyright (C) 2010 P.L. Lucas
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "SimpleEditor.h"
+#include <QFile>
+#include <QTextStream>
+#include <QTextBlock>
+#include <QFileInfo>
+#include <QDir>
+
+SimpleEditor::SimpleEditor(QWidget *parent):QPlainTextEdit(parent)
+{
+        syntaxHighlighter=NULL;
+	firtsTimeUsedOk=true;
+	completerModel=new QStringListModel ();
+	completer= new QCompleter(completerModel, this);
+	completer->setCompletionMode(QCompleter::PopupCompletion);
+	completer->setWidget(this);
+	connect(completer, SIGNAL(activated ( const QString &)), this, SLOT(activated ( const QString &)));
+        //if(get_config("bracketsMatch")!="false")
+        connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(cursorPositionChangedCallBack()));
+        //if((get_config("autoCompletion")!="false"))
+        connect(document(), SIGNAL(contentsChange(int, int, int)), this, SLOT(autoComplete(int, int, int)));
+	
+        auto_indent=true;//("false"!=get_config("autoindent"));
+        automatic_indention_statement_ok =true;// (get_config("autoindent_statements")=="true");
+	
+	//Set editor's font
+		
+	QFont text_edit_font;
+        QString font_name="Courier";//get_config("textEditFont");
+        QString font_size="10";//get_config("textEditFontSize");
+	if(font_name.isEmpty())
+	{
+		font_name=text_edit_font.family();
+	}
+	if(font_size.isEmpty())
+	{
+		font_size=QString::number(text_edit_font.pointSize());
+	}
+	text_edit_font.setFamily(font_name);
+	text_edit_font.setPointSize(font_size.toInt());
+	setFont(text_edit_font);
+}
+
+void SimpleEditor::loadSyntaxXMLDescription()
+{
+        QString installPath=QString("syntax_files")+QDir::separator();
+	QFileInfo file(fileName);
+	QString suffix=file.suffix();
+	
+	if(comands_completion_list.isEmpty())
+	{
+		QString home=QDir::home().path()+QDir::separator()+".qtoctave"+QDir::separator()+"commands.txt";
+
+		QFile file(home);
+
+		if (file.open(QFile::ReadOnly))
+		{
+			char buf[1024];
+
+			while(file.readLine(buf, sizeof(buf))>=0)
+			{
+				comands_completion_list.append(QString(buf).trimmed());
+			}
+
+			file.close();
+		}
+	}
+	
+        //if(get_config("syntaxHighlighting")!="true") return;
+	
+	QFileInfo xml(installPath+suffix+".xml");
+	if(xml.exists())
+	{
+		printf("[SimpleEditor::loadSyntaxXMLDescription] Loading syntax\n");
+                syntaxHighlighter=new SyntaxHighlighter( document() );
+                syntaxHighlighter->load(xml.absoluteFilePath());
+                syntaxHighlighter->setDocument(document());
+	}
+}
+
+bool SimpleEditor::load(QString file)
+{
+	if(file.isEmpty())
+	{
+		setPlainText("");
+		fileName=file;
+		return true;
+	}
+	
+	FILE *input=fopen(file.toLocal8Bit().data(),"r");
+	if(input==NULL) return false;
+	fclose(input);
+	QFile in(file);
+	if (!in.open(QIODevice::ReadOnly | QIODevice::Text))
+		return false;
+	QByteArray data=in.readAll();
+	
+	setPlainText( QString::fromLocal8Bit(data) );
+	fileName=file;
+	
+	firtsTimeUsedOk=false;
+	
+	loadSyntaxXMLDescription();
+	
+	return true;
+}
+
+bool SimpleEditor::save()
+{
+	QFile::remove(fileName+"~");
+	QFile::copy(fileName, fileName+"~");
+	FILE *out=fopen(fileName.toLocal8Bit().data(),"w");
+	if(out==NULL) return false;
+	fprintf( out, "%s", toPlainText().toLocal8Bit().data() );
+	fclose(out);
+	document()->setModified(false);
+	return true;
+}
+
+void SimpleEditor::keyPressEvent(QKeyEvent * e)
+{
+	//printf("%d %s\n",e->key(), e->text().toLocal8Bit().data());
+	
+	//In all cases completer popup must been hided.
+	if(e->key()!=Qt::Key_Return && e->key()!=Qt::Key_Enter )
+	{
+		QAbstractItemView *view=completer->popup();
+		if(view->isVisible()) view->hide();
+		//completer->setWidget(NULL);
+	}
+	
+	if(e->key()==Qt::Key_Return || e->key()==Qt::Key_Enter )
+	{
+		QAbstractItemView *view=completer->popup();
+		if(view->isVisible())
+		{
+			QString word=view->currentIndex().data().toString();
+			if( word.isEmpty() ) word=completer->currentCompletion();
+			activated( word );
+			return;
+		}
+		else if(auto_indent)
+		{
+			QTextCursor cursor=textCursor();
+			QString line=cursor.block().text();
+			QString line2=line;
+			for(int i=0;i<line.length();i++)
+			{
+				if(line[i]!=' ' && line[i]!='\t') { line.resize(i); break;}
+			}
+			cursor.insertText("\n"+line);
+			if( automatic_indention_statement_ok )
+			{
+				
+				printf("[SimpleEditor::keyPressEvent] automatic_indention_statement_ok=%s\n", line2.toLocal8Bit().data() );
+				
+				QRegExp re("^while .*|^if .*|^for .*|^switch .*|^do$|^try|^function .*|^else$|^elseif .*");
+				
+				if(re.exactMatch( line2.trimmed() ) )
+				{
+					cursor.insertText("\t");
+				}
+			}
+			setTextCursor(cursor);
+		}
+		else
+			QPlainTextEdit::keyPressEvent(e);
+	}
+	//else if( e->key()==(Qt::Key_B) && Qt::ControlModifier==e->modifiers() )
+	//{
+	//	autoComplete();
+	//	return;
+	//}
+	else if(e->key()==Qt::Key_Tab)
+	{
+		QTextCursor cursor=textCursor();
+		int start=cursor.selectionStart();
+		int end=cursor.selectionEnd();
+		if(start==end)
+		{
+			QPlainTextEdit::keyPressEvent(e);
+			return;
+		}
+		cursor.beginEditBlock();
+		cursor.setPosition(end);
+		end=cursor.blockNumber();
+		cursor.setPosition(start);
+		cursor.movePosition(QTextCursor::StartOfBlock);
+		while(true)
+		{
+			cursor.insertText("\t");
+			if(cursor.blockNumber()>=end) break;
+			cursor.movePosition(QTextCursor::NextBlock);
+		}
+		cursor.endEditBlock();
+	}
+	else if(e->key()==Qt::Key_Backtab )
+	{
+		QTextCursor cursor=textCursor();
+		int start=cursor.selectionStart();
+		int end=cursor.selectionEnd();
+		if(start==end)
+		{
+			QPlainTextEdit::keyPressEvent(e);
+			return;
+		}
+		cursor.beginEditBlock();
+		cursor.setPosition(end);
+		end=cursor.blockNumber();
+		cursor.setPosition(start);
+		cursor.movePosition(QTextCursor::StartOfBlock);
+		while( true )
+		{
+			QString line=cursor.block().text();
+			if(line.length()>0 && (line[0]==' ' || line[0]
+				=='\t') )
+			{
+				cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor);
+				cursor.removeSelectedText();
+			}
+			if(cursor.blockNumber()>=end) break;
+			cursor.movePosition(QTextCursor::NextBlock);
+			cursor.movePosition(QTextCursor::StartOfBlock);
+		}
+		cursor.endEditBlock();
+	}
+	else
+	{
+		if( e->key()==(Qt::Key_B) && Qt::ControlModifier==e->modifiers() )
+		{
+			autoComplete(0);
+			return;
+		}
+		
+		QPlainTextEdit::keyPressEvent(e);
+		
+	}
+	
+	
+}
+
+void SimpleEditor::setCharFormat(QTextCharFormat charFormat)
+{
+	this->charFormat=charFormat;
+	QTextCursor cursor=textCursor();
+	cursor.movePosition(QTextCursor::Start);
+	cursor.setCharFormat(charFormat);
+	cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
+	setFont(charFormat.font());
+	
+	QFontMetrics fm(charFormat.font());
+	int textWidthInPixels = fm.width("        ");
+	setTabStopWidth(textWidthInPixels);
+}
+
+void SimpleEditor::activated( const QString & text )
+{
+	QAbstractItemView *view=completer->popup();
+	QTextCursor cursor=textCursor();
+	cursor.movePosition( 
+		QTextCursor::PreviousWord, QTextCursor::KeepAnchor);
+	cursor.insertText(text);
+	view->hide();
+}
+
+void SimpleEditor::autoComplete(int position, int charsRemoved, int charsAdded)
+{
+	//printf("[SimpleEditor::autoComplete] charsAdded=%d\n", charsAdded);
+	if(charsAdded==1)
+		autoComplete();
+}
+
+void SimpleEditor::autoComplete(int size)
+{
+	QTextCursor cursor=textCursor();
+	
+	cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor);
+	
+	//printf("[SimpleEditor::autoComplete] >%s<\n", cursor.selectedText().toLocal8Bit().data());
+	
+	if( cursor.selectedText().endsWith(" ") || cursor.selectedText().trimmed().length()<size ) return;
+	
+	QStringList list=toPlainText().split(QRegExp("\\W+"));
+	
+	list.removeDuplicates();
+	list.removeOne(cursor.selectedText());
+	list.sort();
+	
+	list.append(comands_completion_list);
+	
+	completerModel->setStringList( list );
+	
+	completer->setCompletionPrefix(cursor.selectedText());
+	
+	//printf("[SimpleEditor::autoComplete] >%d<\n", completer->completionCount());
+	
+	if (completer->completionCount()>0 )
+	{
+		//completer->setWidget(this);
+		QRect r=cursorRect(cursor);
+		r.setWidth(200);
+		completer->complete(r);
+	}
+}
+
+
+QString SimpleEditor::getFileName()
+{
+	return fileName;
+}
+
+
+void SimpleEditor::setFile(QString file)
+{
+	fileName=file;
+	loadSyntaxXMLDescription();
+}
+
+
+void SimpleEditor::cursorPositionChangedCallBack()
+{
+	//Hightlight brackets
+        if(syntaxHighlighter!=NULL)
+                syntaxHighlighter->setFormatPairBrackets(this);
+}
+
+void SimpleEditor::publicBlockBoundingRectList(QVector<qreal> &list, int &first_line)
+{
+	qreal pageBottom = /*viewport()->*/height();
+	QPointF offset=contentOffset();
+	QTextBlock block=firstVisibleBlock();
+	first_line=block.blockNumber()+1;
+	qreal first_position=blockBoundingGeometry(block).topLeft().y();
+	
+	for ( ; block.isValid(); block = block.next() )
+	{
+		QRectF position=blockBoundingGeometry(block);
+		qreal y=position.topLeft().y()+offset.y()-first_position;
+		
+		if(y>pageBottom) break;
+		
+		list.append(y);
+	}
+}
+
new file mode 100644
--- /dev/null
+++ b/gui//src/SimpleEditor.h
@@ -0,0 +1,87 @@
+#ifndef __SIMPLEEDITOR_H__
+/* Copyright (C) 2010 P.L. Lucas
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#define __SIMPLEEDITOR_H__
+
+#include <QPlainTextEdit>
+#include <QCompleter>
+#include <QStringListModel>
+#include "SyntaxHighlighter.h"
+
+class SimpleEditor : public QPlainTextEdit
+{
+	Q_OBJECT
+	QString fileName;
+	QTextCharFormat charFormat;
+	QCompleter *completer;
+	QStringListModel *completerModel;
+        SyntaxHighlighter *syntaxHighlighter;
+	QStringList comands_completion_list;
+	
+	bool auto_indent, automatic_indention_statement_ok;
+	
+	void loadSyntaxXMLDescription();
+	
+	public:
+	bool firtsTimeUsedOk;
+	
+        SimpleEditor(QWidget * parent = 0);
+	
+	bool load(QString file);
+	bool save();
+	QString getFileName();
+	void setFile(QString file);
+	
+	void setCharFormat(QTextCharFormat charFormat);
+	
+	
+	
+	/**List of y top left positions of bounding rects of each visible block of text.
+	 * @param list List of top left positions.
+	 * @param first_line First visible block in TextEdit.
+	 */
+	void publicBlockBoundingRectList(QVector<qreal>  &list, int &first_line);
+	
+	public slots:
+	
+	void activated( const QString & text );
+	void cursorPositionChangedCallBack();
+	void autoComplete(int size=3);
+	void autoComplete(int position, int charsRemoved, int charsAdded);
+	
+	protected:
+	virtual void keyPressEvent(QKeyEvent * e);
+	//virtual void focusInEvent(QFocusEvent  * event);
+	
+
+	signals:
+	/**Dinamic help required.*/
+	void dynamic_help_required(const QString &text);
+	
+	///**Text modified.*/
+	//void text_modified(bool ok);
+	
+	//void toggleBreakpoint(int lineno);
+	
+	//void focusChanged(QWidget *);
+}
+;
+#endif
+
--- a/gui//src/SyntaxHighlighter.cpp
+++ b/gui//src/SyntaxHighlighter.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006-2008 P.L. Lucas
+/* Copyright (C) 2010 P.L. Lucas
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,453 +16,503 @@
  * Boston, MA 02111-1307, USA.
  */
 
-#include "SyntaxHighlighter.h"
-#include <iostream>
-#include <QtXml/QXmlSimpleReader>
-#include <QtXml/QXmlDefaultHandler>
-#include <QTextBlockUserData>
-#include <QHash>
-#include <QDir>
-
-QList<SyntaxHighlighter::Rule*> SyntaxHighlighter::rules;
-QStringList SyntaxHighlighter::octave_comands;
 
-/*** Xml Handler ***/
-class SyntaxXmlHandler:public QXmlDefaultHandler {
-private:
-    SyntaxHighlighter *syntax;
-    QString type_name, text;
-    struct Tag
-    {
-        QString tag, type;
-        QStringList items;
-        QList<Tag> childs;
-    };
-    QList<Tag> stack;
-    QStringList *octave_comands;
+#include "SyntaxHighlighter.h"
+
 
-public:
-    // Constructor
-    SyntaxXmlHandler(SyntaxHighlighter *s, QStringList *octave_comands)
-        : QXmlDefaultHandler(), syntax(s) {
-            this->octave_comands=octave_comands;
-    }
-
-    bool startElement(const QString &/*namespaceURI*/, const QString &/*localName*/,
-                    const QString &qname, const QXmlAttributes &atts) {
-        Tag tag;
-        tag.tag=qname;
+#include <QXmlStreamReader>
+#include <QStack>
+#include <QFile>
+#include <stdio.h>
 
-        if(qname == "list")
-        {// List block. Get the type name.
-            tag.type = atts.value("name").trimmed();
-            if(tag.type=="functions")
-            {
-                    tag.items << (*octave_comands);
-            }
-        }
-        //else if(qname == "item")
-        //{// Item. Next string is an item.
-        //}
-        else if(qname == "comment")
-        {// Comments.
-            syntax->setComment(atts.value("start"), "$", atts.value("name"));
-        }
-
-        stack.append(tag);
-        return true;
-    }
+SyntaxHighlighter::SyntaxHighlighter(QObject * parent):QSyntaxHighlighter(parent)
+{
+}
 
 
-    bool characters(const QString &ch) {
-        text+=ch;
-        return true;
-    }
-
-    bool endElement(const QString & /*namespaceURI*/,
-                    const QString & /*localName*/,
-                    const QString & qname ) {
-        Tag tag;
-
-        if(stack.isEmpty()) return true;
-
-        tag=stack.last();
-        stack.removeLast();
-
-        if(tag.tag!=qname) {
-            printf("Error reading XML syntax\n");
-            return false;
-        }
-
-        if(qname == "list") {// List block. Get the type name.
-            if(stack.last().tag=="list") {
-                stack.last().childs.append(tag);
-            } else {
-                syntax->setItem(tag.items.join("|"), tag.type);
-                for(int i=0;i<tag.childs.size();i++) {
-                    syntax->setItem(tag.childs[i].items.join("|"), tag.childs[i].type,tag.type);
-                }
-            }
-        } else if(qname == "item") {
-            // Item. Next string is an item.
-            if(! text.trimmed().isEmpty() )
-                    stack.last().items << text.trimmed();
-        }
-
-        text="";
-        return true;
-    }
-};
-
-/*** Block data ***/
-class BlockData:public QTextBlockUserData {
-public:
-    BlockData() {braket_start_pos=braket_end_pos=-1;}
-    ~BlockData (){}
-    int braket_start_pos, braket_end_pos;
-    QHash<int,QString> bracket;
-};
-
-/*** Syntax ***/
-SyntaxHighlighter::SyntaxHighlighter(QTextDocument *parent)
-    : QSyntaxHighlighter(parent) {
-    QTextCharFormat f;
+bool SyntaxHighlighter::load(QString file)
+{
+	QXmlStreamReader xml;
+	QStack <QString> stack;
+	QFile fileDevice(file);
+	if (!fileDevice.open(QFile::ReadOnly | QFile::Text)) {
+	         printf("Error al abrir el archivo\n");
+	         return false;
+	}
+	
+	xml.setDevice(&fileDevice);
+	
+	QMap <QString,QString> values;
+	
+	QVector<QString> xmlMainItems;
+	xmlMainItems << "item" << "block" << "bracket";
+	
+	int ruleOrder=0;
+	
+	while (!xml.atEnd())
+	{
+		QXmlStreamReader::TokenType tokenType=xml.readNext();
+		switch(tokenType)
+		{
+			case QXmlStreamReader::StartElement:
+				if(xml.name()!="syntax")
+				{
+					if( xmlMainItems.contains(xml.name().toString()) )
+						stack.push(xml.name().toString());
+					else
+						values[xml.name().toString()]=xml.readElementText().trimmed();
+				}
+			break;
+			case QXmlStreamReader::EndElement:
+				if(stack.isEmpty()) break;
+				QString name=stack.top();
+				if(name==xml.name()) stack.pop();
+				if(stack.isEmpty())
+				{
+					QTextCharFormat format;
+					if(values.contains("bold") && values["bold"]=="true") format.setFontWeight(QFont::Bold);
+					if(values.contains("underline") && values["underline"]=="true") format.setFontUnderline(true);
+					if(values.contains("italic") && values["italic"]=="true") format.setFontItalic(true);
+					if(values.contains("foreground")) format.setForeground(QBrush(QColor(values["foreground"])));
+					if(values.contains("background")) format.setBackground(QBrush(QColor(values["background"])));
+					if(name=="item")
+					{
+						HighlightingRule rule;
+						rule.format=format;
+						rule.pattern=QRegExp(values["pattern"]);
+						rule.ruleOrder=ruleOrder++;
+						highlightingRules.append(rule);
+						values.clear();
+					}
+					else if(name=="block" || name=="bracket")
+					{
+						HighlightingBlockRule rule;
+						rule.format=format;
+						rule.startPattern=QRegExp(values["startPattern"]);
+						rule.endPattern=QRegExp(values["endPattern"]);
+						rule.ruleOrder=ruleOrder++;
+						if(name=="block") highlightingBlockRules.append(rule);
+						else highlightingBracketsRules.append(rule); //Bracket rule
+						values.clear();
+					}
+				}
+			break;
+		}
+	}
+	if (xml.hasError())
+	{
+		// do error handling
+		printf("Error %s: %ld:%ld %s\n", file.toLocal8Bit().data(), xml.lineNumber(), xml.columnNumber(), xml.errorString().toLocal8Bit().data() );
+		return false;
+	}
+	
+	return true;
+}
 
-    QFont text_edit_font;
-    QString font_name="Monospace";//get_config("textEditFont");
-    QString font_size="10";//get_config("textEditFontSize");
-    if(font_name.isEmpty()) {
-        font_name=text_edit_font.family();
-    }
-
-    if(font_size.isEmpty()) {
-        font_size=QString::number(text_edit_font.pointSize());
-    }
-
-    text_edit_font.setFamily(font_name);
-    text_edit_font.setPointSize(font_size.toInt());
-
-    f.setFont(text_edit_font);
-    f.setFontWeight(QFont::Bold);
-    _format["keywords"] = f;
-    _format["commands"] = f;
-    f.setFontWeight(QFont::Normal);
-    f.setForeground(Qt::darkGreen);
-    _format["builtin"] = f;
-    f.setForeground(Qt::blue);
-    _format["functions"] = f;
-    // operators
-    f.setForeground(Qt::black);
-    _format["variables"] = f;
-    f.setForeground(Qt::darkMagenta);
-    _format["numbers"] = f;
-    f.setForeground(Qt::red);
-    _format["strings"] = f;
-    // delimiters
-    f.setForeground(Qt::darkGray);
-    _format["singleLine"] = f;
-    //Brackets matched
-    f.setForeground(Qt::black);
-    //f.setFontWeight(QFont::Bold);
-    f.setBackground(Qt::yellow);
-    _format["bracket match"]=f;
-
-    active_ok=true;
-
-    braketsMacth_ok=false;
-
-    //printf("Syntax Builded\n");
-
-    //Add rules to vectors to help to highlightBlock method
-    __re.clear();
-    __i_aux.clear();
-    for(int n=0;n<rules.size();n++) {
-        __re.append(rules[n]->pattern);
-        __i_aux.append(-1);
-        //printf("%s %d %d\n", rules.at(n)->type.toLocal8Bit().data(), __re.size(), __i_aux[n]);
-    }
+SyntaxHighlighter::Rule1st SyntaxHighlighter::highlight1stRule(const QString & text, int startIndex)
+{
+	Rule1st rule1st;
+	rule1st.startIndex=text.length();
+	rule1st.rule=-1;
+	
+	for(int i=0; i<highlightingRules.size(); i++)
+	{
+		HighlightingRule *rule=&(highlightingRules[i]);
+		
+		QRegExp *expression = &(rule->pattern);
+		int index = rule->lastFound;
+		//printf("[Syntax::highlight1stRule] i=%d pos=%d startIndex=%d\n", i, index, startIndex);
+		if(index>-1 && index<startIndex)
+		{
+			rule->lastFound = index = expression->indexIn(text, startIndex);
+		}
+		if ( index>-1 && index<rule1st.startIndex )
+		{
+			rule1st.startIndex=index;
+			rule1st.length=expression->matchedLength();
+			rule1st.rule=i;
+			rule1st.ruleOrder=rule->ruleOrder;
+		}
+		
+		if(index==startIndex) break;
+	}
+	
+	if(rule1st.rule==-1) rule1st.startIndex=-1;
+	
+	return rule1st;
 }
 
-SyntaxHighlighter::~SyntaxHighlighter() {
-	//foreach(Rule *value, rules_map)
-	//{
-	//	delete value;
-	//}
+SyntaxHighlighter::Rule1st SyntaxHighlighter::highlight1stBlockRule(const QString & text, int startIndex)
+{
+	Rule1st rule1st;
+	rule1st.startIndex=text.length();
+	rule1st.rule=-1;
+	
+	for(int i=0; i<highlightingBlockRules.size(); i++)
+	{
+		HighlightingBlockRule rule=highlightingBlockRules[i];
+		
+		int index = rule.startPattern.indexIn(text, startIndex);
+		
+		if ( index>-1 && index<rule1st.startIndex )
+		{
+			rule1st.startIndex=index;
+			rule1st.rule=i;
+			rule1st.ruleOrder=rule.ruleOrder;
+		}
+		
+		if(index==startIndex) break;
+	}
+	
+	if(rule1st.rule==-1) rule1st.startIndex=-1;
+	
+	return rule1st;
+}
+
+/**Inserts brackets in position order in blockData->brackets
+ */
+static void insertInOrder(BlockData *blockData, BlockData::Bracket &bracket)
+{
+	if(blockData->brackets.isEmpty()) blockData->brackets.append(bracket);
+	else
+	{
+		int j=0;
+		
+		for(;j<blockData->brackets.size();j++)
+		{
+			if(blockData->brackets[j].pos>bracket.pos)
+			{
+				blockData->brackets.insert(j,bracket);
+				break;
+			}
+		}
+		if(j>=blockData->brackets.size())
+		{
+			blockData->brackets.append(bracket);
+		}
+	}
+}
+
 
-	//This line is added because sometimes Qt try rehighlight text at destroy
-	setDocument(NULL);
+void SyntaxHighlighter::findBrackets(const QString & text, int start, int end, BlockData *blockData)
+{
+	//blockData->brackets.clear();
+	
+	if( end<0 || end>text.length() ) end=text.length();
+	
+	if(start>end) return;
+	
+	for(int i=0; i<highlightingBracketsRules.size(); i++)
+	{
+		HighlightingBlockRule rule=highlightingBracketsRules[i];
+		
+		int startIndex=start;
+		
+		int index = rule.startPattern.indexIn(text, startIndex);
+		
+		while( index>-1 && index<end )
+		{
+			BlockData::Bracket bracket;
+			bracket.pos=index;
+			bracket.type=i;
+			bracket.length=rule.startPattern.matchedLength();
+			bracket.startBracketOk=true;
+			
+			startIndex=index+bracket.length;
+			
+			insertInOrder(blockData, bracket);
+			
+			//printf("[Syntax::findBrackets] bracket.pos=%d bracket.type=%d bracket.len=%d bracket.start=%d startIndex=%d\n", bracket.pos, bracket.type, bracket.length, (bracket.startBracketOk), startIndex );
+			
+			index = rule.startPattern.indexIn(text, startIndex);
+		}
+		
+		startIndex=start;
+		
+		index = rule.endPattern.indexIn(text, startIndex);
+		
+		
+		
+		while( index>-1 && index<end )
+		{
+			BlockData::Bracket bracket;
+			bracket.pos=index;
+			bracket.type=i;
+			bracket.length=rule.endPattern.matchedLength();
+			bracket.startBracketOk=false;
+			insertInOrder(blockData, bracket);
+			startIndex=index+bracket.length;
+			index = rule.endPattern.indexIn(text, startIndex);
+		}
+	}
+}
+
+
+int SyntaxHighlighter::ruleSetFormat(Rule1st rule1st)
+{
+	HighlightingRule rule=highlightingRules[rule1st.rule];
+	
+	setFormat(rule1st.startIndex, rule1st.length, rule.format);
+	
+	return rule1st.startIndex + rule1st.length;
 }
 
-void SyntaxHighlighter::load(const QString &path) {
-    if(octave_comands.isEmpty()) {
-        QString home=QDir::home().path()+"/.qtoctave/commands.txt";
 
-        QFile file(home);
-
-        if(file.open(QFile::ReadOnly)) {
-            char buf[1024];
-
-            while(file.readLine(buf, sizeof(buf))>=0) {
-                octave_comands.append(QString(buf).trimmed());
-            }
-            file.close();
-        }
-    }
-
-    //rules = &(instances[path]);
-    if(rules.isEmpty()) {
-        // Load from file
-        FILE *fl;
-
-        fl = fopen(path.toLocal8Bit().constData(), "rt");
-        if(!fl) {
-            std::cerr << "[Syntax::load] Can not load the syntax file" << std::endl;
-            return;
-        }
-
-        QFile file(path);
-        QXmlSimpleReader parser;
-        QXmlInputSource source(&file);
-        SyntaxXmlHandler handler(this, &octave_comands);
-
-        file.open(fl, QIODevice::ReadOnly);
-
-        parser.setContentHandler(&handler);
-        parser.setErrorHandler(&handler);
-
-        parser.parse(&source);
-
-        file.close();
-
-        fclose(fl);
-
-        std::cout << "[Sytax::load] "
-                << path.toLocal8Bit().constData()
-                << " loaded"
-                << std::endl;
-    }
+int SyntaxHighlighter::blockRuleSetFormat(const QString & text, Rule1st rule1st)
+{
+	HighlightingBlockRule rule=highlightingBlockRules[rule1st.rule];
+		
+	int endIndex = rule.endPattern.indexIn(text, rule1st.startIndex);
+	int commentLength;
+	if (endIndex == -1)
+	{
+	    setCurrentBlockState(rule1st.rule);
+	    commentLength = text.length() - rule1st.startIndex;
+	    setFormat(rule1st.startIndex, commentLength, rule.format);
+	    return text.length();
+	}
+	else
+	{
+	    commentLength = endIndex - rule1st.startIndex
+	                    + rule.endPattern.matchedLength();
+	    setFormat(rule1st.startIndex, commentLength, rule.format);
+	    
+	    return endIndex+1;
+	}
 }
 
-void SyntaxHighlighter::setItem(const QString &item, const QString &type, const QString parent) {
-    Rule *r;
-    if(!item.isEmpty()) {
-        r=new Rule;
-        r->pattern = QRegExp(item);
-        r->type = type;
-        r->format = _format[type];
-        rules_map[type]=r;
-        if(parent.isEmpty() || !rules_map.contains(parent))
-            rules.push_back(r);
-        else
-            rules_map[parent]->rules.push_back(r);
-    }
-}
+
+void SyntaxHighlighter::highlightBlock ( const QString & text )
+{
+
+	setCurrentBlockState(-1);
+	
+	int startIndex = 0;
+	
+	//Checks previous block state
+	if (previousBlockState() >= 0)
+	{
+		Rule1st rule1st;
+		rule1st.rule=previousBlockState();
+		rule1st.startIndex=0;
+		
+		startIndex=blockRuleSetFormat(text,rule1st);
+		
+		//TODO: Posible fallo al establecer el estado del bloque
+		
+		if(startIndex==text.length()) return;
+	}
+	
+	//Gets BlockData
+	BlockData *blockData=new BlockData();
+	
+	//Finds first rule to apply. 
 
-void SyntaxHighlighter::setComment(const QString &start, const QString &end, const QString &type) {
-    Rule *r;
-    if(!type.isEmpty()) {
-        r=new Rule;
-        r->pattern = QRegExp(/*QString("^") +*/ start + ".*" + end);
-        r->type = type;
-        r->format = _format[type];
-        rules_map[type]=r;
-        rules.push_back(r);
-    }
-}
-
-void SyntaxHighlighter::setType(const QString &type, const QTextCharFormat &f) {
-      _format[type] = f;
+	Rule1st rule1st, blockRule1st;
+	
+	//Find initial matches
+	for(int i=0; i<highlightingRules.size(); i++)
+	{
+		HighlightingRule *rule= &(highlightingRules[i]);
+		QRegExp *expression = &(rule->pattern);
+		int index = expression->indexIn(text, startIndex);
+		rule->lastFound = index;
+		//printf("[Syntax::highlightBlock] index=%d pos=%d \n", index, expression->pos(0));
+	}
+	
+	//printf("[Syntax::highlightBlock] Find initial matches \n");
+	
+	rule1st=highlight1stRule( text, startIndex);
+	blockRule1st=highlight1stBlockRule( text, startIndex);
+	
+	//if(rule1st.rule<0 && blockRule1st.rule<0)
+	//{
+	//	findBrackets(text, startIndex, -1, blockData);
+	//}
+	//else 
+	while(rule1st.rule>=0 || blockRule1st.rule>=0)
+	{
+		if(rule1st.rule>=0 && blockRule1st.rule>=0)
+		{
+			if
+				( 
+					rule1st.startIndex<blockRule1st.startIndex
+					|| 
+					(
+						rule1st.startIndex==blockRule1st.startIndex
+						&&
+						rule1st.ruleOrder<blockRule1st.ruleOrder
+					)
+				)
+			{
+				findBrackets(text, startIndex, rule1st.startIndex, blockData);
+				startIndex=ruleSetFormat(rule1st);
+				rule1st=highlight1stRule( text, startIndex);
+			}
+			else
+			{
+				findBrackets(text, startIndex, blockRule1st.startIndex, blockData);
+				startIndex=blockRuleSetFormat(text,blockRule1st);
+				blockRule1st=highlight1stBlockRule( text, startIndex);
+			}
+		}
+		else if(rule1st.rule>=0)
+		{
+			findBrackets(text, startIndex, rule1st.startIndex, blockData);
+			startIndex=ruleSetFormat(rule1st);
+			rule1st=highlight1stRule( text, startIndex);
+		}
+		else
+		{
+			findBrackets(text, startIndex, blockRule1st.startIndex, blockData);
+			startIndex=blockRuleSetFormat(text,blockRule1st);
+			blockRule1st=highlight1stBlockRule( text, startIndex);
+		}
+		
+		//Finds next 1st rule
+		//rule1st=highlight1stRule( text, startIndex);
+		//blockRule1st=highlight1stBlockRule( text, startIndex);
+	}
+	
+	findBrackets(text,startIndex, -1, blockData);
+	
+	setCurrentBlockUserData(blockData);
 }
 
-void SyntaxHighlighter::highlightBlock(const QString &str) {
-    //Para aumentar el rendimiento se hace una tabla i_aux con la posición de lo
-    //que ha encontrado cada expresión regular rules.at(n)->pattern.
-    //Se aplicará el formato debido a la Rule que tenga la i_aux más pequeña
-    if(!str.isEmpty() && !rules.isEmpty() && active_ok) {
-
-    int i=0, len=0; //Actual position
-    int n_min; //Minimal position
-
-    BlockData *dat=(BlockData *)currentBlockUserData();
-    if(dat!=NULL) {
-            dat->bracket.clear();
-    }
-
-    for(int n=0;n<__re.size();n++) {
-        //re[n]=rules.at(n)->pattern;
-        __i_aux[n] = __re[n].indexIn( str, i);
-        //printf("%s %d %d\n", rules.at(n)->type.toLocal8Bit().data(), n, __i_aux[n]);
-    }
-
-    while(i >= 0) {
-            n_min=-1;
-            for(int n=0;n<__re.size();n++)
-            {
-                    if(__i_aux[n]<0) continue;
-                    if(__i_aux[n]<i ) __i_aux[n] = __re[n].indexIn( str, i);
-                    //printf("%s n=%d i_aux=%d n_min=%d i=%d\n", rules.at(n)->type.toLocal8Bit().data(), n, i_aux[n], n_min, i);
-                    if( n_min<0 || __i_aux[n_min]<0 || (__i_aux[n]>=0 && __i_aux[n]<__i_aux[n_min]) )
-                    {
-                            n_min=n;
-                            if(__i_aux[n]==i) break;
-                    }
-            }
-            //printf("n_min=%d elegido\n", n_min);
-            if(n_min>=0) i=__i_aux[n_min];
-            else break;
-            if( i<0 ) break;
-            len = __re[n_min].matchedLength();
-
-            //QStringList list=re[n_min].capturedTexts ();
-            //printf("\n");
-            //for(int n=0;n<list.size();n++)
-            //{
-            //	printf("%d >%s<\n", n, list.at(n).toLocal8Bit().data() );
-            //}
-            //printf("Aplicando %s i=%d len=%d\n", rules.at(n_min)->type.toLocal8Bit().data(), i, len);
-            if(len<1) break;
-            //QTextCharFormat i_format=format(i);
-            //if( !(i_format==strings) )
-
-            if(rules.at(n_min)->rules.isEmpty())
-            {
-                    setFormat(i, len, rules.at(n_min)->format);
-
-                    if( rules.at(n_min)->type=="delimiters" )
-                    {
-                            QString bracket_found=__re[n_min].cap();
-
-                            if(dat==NULL)
-                            {
-                                    dat=new BlockData();
-                                    setCurrentBlockUserData(dat);
-                            }
-                            dat->bracket[i]=bracket_found;
-
-                            //Do brackets macth
-                            if( braketsMacth_ok && dat != NULL )
-                            {
-                                    if(dat->braket_start_pos>=0)
-                                            setFormat(dat->braket_start_pos, 1, _format["bracket match"]);
-                                    if(dat->braket_end_pos>=0)
-                                            setFormat(dat->braket_end_pos, 1, _format["bracket match"]);
-                            }
-                    }
-
-            }
-            else
-            {
-                    //Rules can contains another rules
-                    QString text=str.mid(i,len);
-                    //printf("text=%s\n", text.toLocal8Bit().data() );
-                    bool format_ok=true;
-                    for(int n=0;n<rules.at(n_min)->rules.size(); n++)
-                    {
-                            if(rules.at(n_min)->rules.at(n)->pattern.exactMatch(text))
-                            {
-                                    setFormat(i, len, rules.at(n_min)->rules.at(n)->format);
-                                    format_ok=false;
-                                    break;
-                            }
-                    }
-                    if(format_ok) setFormat(i, len, rules.at(n_min)->format);
-            }
-            i+=len;
-
-    }
-}
+/**Search brackets in one QTextBlock.*/
+static BlockData::Bracket *searchBracket(int i, int increment, int &bracketsCount, BlockData *blockData, BlockData::Bracket *bracket1)
+{
+	if(blockData==NULL) return NULL;
+	
+	if(i==-1) i=blockData->brackets.size()-1;
+	
+	for(; i>=0 && i<blockData->brackets.size(); i+=increment)
+	{
+		BlockData::Bracket *bracket=&(blockData->brackets[i]);
+		if(bracket->type==bracket1->type)
+		{
+			if(bracket->startBracketOk!=bracket1->startBracketOk)
+				bracketsCount--;
+			else
+				bracketsCount++;
+			
+			if(bracketsCount==0)
+				return bracket;
+		}
+	}
+	
+	//printf("[searchBracket] bracketsCount=%d\n", bracketsCount);
+	
+	return NULL;
 }
 
-int SyntaxHighlighter::forwardSearch(QTextBlock &textBlock, int position, char bracketStart, char bracketEnd) {
-    int i=position,  open=0;
-
-    while(textBlock.isValid()) {
-        BlockData *dat=(BlockData *)textBlock.userData();
-        if(dat!=NULL) {
-            QList<int> positions=dat->bracket.keys();
-            qSort(positions);
-            for(int k=0;k<positions.size();k++) {
-                int b_pos=positions[k];
-                if(b_pos<i) continue;
-
-                QChar ch=dat->bracket[b_pos].at(0);
-
-                if(ch==bracketEnd) {
-                        open--;
-                        if(open==0) return b_pos;
-                }
-                else if(ch==bracketStart) open++;
-            }
-        }
-        textBlock=textBlock.next();
-        i=0;
-    }
-    return -1;
+void SyntaxHighlighter::setFormatPairBrackets(QPlainTextEdit *textEdit)
+{
+	QList<QTextEdit::ExtraSelection> selections;
+	
+	textEdit->setExtraSelections(selections);
+	
+	QTextCursor cursor=textEdit->textCursor();
+	QTextBlock block=cursor.block();
+	BlockData *blockData=(BlockData *)block.userData();
+	if(blockData==NULL) return;
+	
+	int pos=cursor.position()-block.position();
+	
+	BlockData::Bracket *bracket1;
+	QTextBlock block_bracket1=block;
+	
+	int i=blockData->brackets.size()-1;
+	
+	/*
+	printf("[Syntax::setFormatPairBrackets] brackets.size=%d\n", i+1);
+	for(int x=0;x<blockData->brackets.size();x++)
+	{
+		BlockData::Bracket *bracket=&(blockData->brackets[x]);
+		printf("[Syntax::setFormatPairBrackets] bracket.pos=%d bracket.type=%d bracket.len=%d bracket.start=%d\n", bracket->pos, bracket->type, bracket->length, (bracket->startBracketOk) );
+	}
+	*/
+	
+	
+	for(; i>=0; i--)
+	{
+		BlockData::Bracket *bracket=&(blockData->brackets[i]);
+		if(bracket->pos==pos)
+		{
+			bracket1=bracket;
+			break;
+		}
+	}
+	
+	if(i<0) return;
+	
+	int increment=(bracket1->startBracketOk) ? +1:-1;
+	int bracketsCount=0;
+	//i+=increment;
+	
+	//Looks in this block the other bracket
+	BlockData::Bracket *bracket2=NULL;
+	QTextBlock block_bracket2=block;
+	
+	bracket2=searchBracket( i, increment, bracketsCount, blockData, bracket1);
+	
+	{ //Search brackets in other blocks
+		while( bracket2==NULL )
+		{
+			if(increment>0)
+			{
+				block_bracket2=block_bracket2.next();
+				i=0;
+			}
+			else
+			{
+				block_bracket2=block_bracket2.previous();
+				i=-1;
+			}
+			
+			if(!block_bracket2.isValid()) break;
+			
+			blockData=(BlockData *)block_bracket2.userData();
+			/*
+			printf("[Syntax::setFormatPairBrackets] Interno brackets.size=%d\n", blockData->brackets.size());
+			for(int x=0;x<blockData->brackets.size();x++)
+			{
+				BlockData::Bracket *bracket=&(blockData->brackets[x]);
+				printf("[Syntax::setFormatPairBrackets] bracket.pos=%d bracket.type=%d bracket.len=%d bracket.start=%d\n", bracket->pos, bracket->type, bracket->length, (bracket->startBracketOk) );
+			}
+			*/
+			
+			bracket2=searchBracket( i, increment, bracketsCount, blockData, bracket1);
+		}
+		
+		if(bracket2==NULL) return;
+	}
+	
+	pos=cursor.position();
+	
+	QTextEdit::ExtraSelection selection1;
+	
+	cursor.setPosition(pos+bracket1->length, QTextCursor::KeepAnchor);
+	selection1.cursor=cursor;
+	selection1.format=highlightingBracketsRules[bracket1->type].format;
+	
+	pos=bracket2->pos+block_bracket2.position();
+	QTextEdit::ExtraSelection selection2;
+	cursor.setPosition(pos);
+	cursor.setPosition(pos+bracket2->length, QTextCursor::KeepAnchor);
+	selection2.cursor=cursor;
+	selection2.format=highlightingBracketsRules[bracket2->type].format;
+	
+	selections.append(selection1); selections.append(selection2);
+	
+	textEdit->setExtraSelections(selections);
+	
 }
 
-int SyntaxHighlighter::backwardSearch(QTextBlock & textBlock, int position, char bracketStart, char bracketEnd) {
-    int i=position,  open=0;
-    while(textBlock.isValid()) {
-        BlockData *dat=(BlockData *)textBlock.userData();
-        if(dat!=NULL) {
-            QList<int> positions=dat->bracket.keys();
-            qSort(positions);
-            for(int k=positions.size()-1;k>=0;k--) {
-                int b_pos=positions[k];
-                if(b_pos>i) continue;
 
-                QChar ch=dat->bracket[b_pos].at(0);
 
-                if(ch==bracketStart) {
-                    open--;
-                    if(open==0) return b_pos;
-                }
-                else if(ch==bracketEnd) open++;
-            }
-        }
-
-        textBlock=textBlock.previous();
-        if(textBlock.isValid() && !textBlock.text().isEmpty()) i=textBlock.length()-1;
-    }
-    return -1;
+BlockData::BlockData():QTextBlockUserData()
+{
 }
 
-static void set_block_data(QTextBlock & block0, QTextBlock & block1, int start, int end) {
-    BlockData *udat=(BlockData *)block0.userData();
-    if(udat==NULL) {
-        udat=new BlockData();
-        block0.setUserData(udat);
-    }
-    udat->braket_start_pos=start;
 
-    if(block0==block1) {
-        udat->braket_end_pos=end;
-    } else {
-        BlockData *udat=(BlockData *)block1.userData();
-        if(udat==NULL) {
-            udat=new BlockData();
-            block1.setUserData(udat);
-        }
-        udat->braket_end_pos=end;
-    }
-}
-
-static void clear_block_data(QTextDocument *doc, bool rehigh) {
-    QTextBlock block=doc->findBlock(0);
-    while(block.isValid()) {
-        BlockData *udat=(BlockData *)block.userData();
-        if(udat!=NULL && (udat->braket_end_pos!=-1 || udat->braket_start_pos!=-1)) {
-            udat->braket_end_pos=-1; udat->braket_start_pos=-1;
-            if(rehigh) {
-                //QTextCursor cursor(doc);
-                //cursor.setPosition(block.position());
-                //cursor.setBlockFormat(block.blockFormat());
-            }
-        }
-        block=block.next();
-    }
-}
-
-void SyntaxHighlighter::setActive(bool active) {
-    active_ok=active;
-}
--- a/gui//src/SyntaxHighlighter.h
+++ b/gui//src/SyntaxHighlighter.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 P.L. Lucas
+/* Copyright (C) 2010 P.L. Lucas
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -12,68 +12,96 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, 
- * Boston, MA 02111-1307, USA. 
+ * Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
  */
 
-#ifndef SYNTAXHIGHLIGHTER_H
-#define SYNTAXHIGHLIGHTER_H
-#include <QPlainTextEdit>
-#include <QSyntaxHighlighter>
-#include <QVector>
-#include <QTextCharFormat>
-#include <QMap>
-#include "config.h"
+#ifndef __SYNTAX_H__
+#define __SYNTAX_H__
 
-/**SyntaxHighlighter for Octave code.*/
-class SyntaxHighlighter: public QSyntaxHighlighter {
-    Q_OBJECT
-public:
-    SyntaxHighlighter(QTextDocument *parent);
-    ~SyntaxHighlighter();
-    void highlightBlock(const QString &str);
-    void load(const QString &file);
-
-    //void setItem(const QString &item, const QString &type);
-    void setItem(const QString &item, const QString &type, const QString parent=QString() );
-    void setComment(const QString &start, const QString &end, const QString &type);
-    void setType(const QString &type, const QTextCharFormat &format);
-
-    /**Stops syntax highlight*/
-    void setActive(bool active);
-
-    static QStringList octave_comands;
+#include <QSyntaxHighlighter>
+#include <QTextBlockUserData>
+#include <QVector>
+#include <QPlainTextEdit>
 
-public slots:
-    /**Return true or false if brackets are been macthed*/
-    inline bool getIsActiveBraketsMacth() {return braketsMacth_ok;}
- 
-  
-private:
-    struct Rule
-    {
-        QRegExp pattern;
-        QString type;
-        QTextCharFormat format;
-        QList<Rule*> rules;
-    };
-
-    int backwardSearch(QTextBlock &textBlock, int position, char bracketStart, char bracketEnd);
-    int forwardSearch(QTextBlock &textBlock, int position, char bracketStart, char bracketEnd);
-
-    //static QMap<QString, QList<Rule> > instances;
-
-    QMap<QString, Rule *> rules_map;
-
-    static QList<Rule*> rules;
-    QMap<QString, QTextCharFormat> _format;
-
-    //Next two properties are used inside highlightBlock method
-    QVector<int> __i_aux; //Auxiliar positions
-    QVector<QRegExp> __re; //Regular expresions
-
-    bool active_ok;
-    bool braketsMacth_ok;
+class BlockData:public QTextBlockUserData
+{
+	public:
+	BlockData();
+	
+	struct Bracket
+	{
+		int type;	//Type of bracket
+		int pos;	//Position of bracket
+		int length;	//Number of chars of bracket
+		bool startBracketOk;	//Is it a start or end bracket?
+	};
+	
+	QVector <Bracket> brackets;
 };
 
-#endif // SYNTAXHIGHLIGHTER_H
+class SyntaxHighlighter:public QSyntaxHighlighter
+{
+	Q_OBJECT
+	
+	struct HighlightingRule
+	{
+		QRegExp pattern;
+		QTextCharFormat format;
+		int ruleOrder;
+		int lastFound;
+	};
+	
+	QVector<HighlightingRule> highlightingRules;
+	
+	struct HighlightingBlockRule
+	{
+		QRegExp startPattern, endPattern;
+		QTextCharFormat format;
+		int ruleOrder;
+	};
+	
+	QVector<HighlightingBlockRule> highlightingBlockRules;
+	QVector<HighlightingBlockRule> highlightingBracketsRules;
+	
+	struct Rule1st
+	{
+		int rule;
+		int startIndex;
+		int length;
+		int ruleOrder;
+	};
+	
+	/**1st rule to apply from startIndex.
+	 */
+	Rule1st highlight1stRule(const QString & text, int startIndex);
+	
+	/**1st block rule to apply from startIndex.
+	 */
+	Rule1st highlight1stBlockRule(const QString & text, int startIndex);
+	
+	/** Set format using rule.
+	 */
+	int ruleSetFormat(Rule1st rule);
+	
+	/** Set format using block rule.
+	 */
+	int blockRuleSetFormat(const QString & text, Rule1st rule1st);
+	
+	/** Finds brackets and put them in BlockData.
+	 */
+	void findBrackets(const QString & text, int start, int end, BlockData *blockData);
+	
+	public:
+	
+        SyntaxHighlighter(QObject * parent = 0);
+	bool load(QString file);
+	
+	/**Formats pair of brackets
+	 */
+	void setFormatPairBrackets(QPlainTextEdit *textEdit);
+	
+	protected:
+	void highlightBlock ( const QString & text );
+};
+#endif