changeset 13416:9a0e32b20743

Incorporated NumberedTextView class from QtOctave.
author Jacob Dawid <jacob.dawid@googlemail.com>
date Tue, 12 Apr 2011 22:43:50 +0200
parents d4e0d8f92511
children 5464586889ae
files gui//Quint.pro gui//src/BrowserWidget.cpp gui//src/BrowserWidget.h gui//src/FileEditorMdiSubWindow.cpp gui//src/FileEditorMdiSubWindow.h gui//src/NumberedCodeEdit.cpp gui//src/NumberedCodeEdit.h
diffstat 7 files changed, 761 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/gui//Quint.pro
+++ b/gui//Quint.pro
@@ -46,7 +46,8 @@
     src/CodeEdit.cpp \
     src/FileEditorMdiSubWindow.cpp \
     src/SyntaxHighlighter.cpp \
-    src/BrowserWidget.cpp
+    src/BrowserWidget.cpp \
+    src/NumberedCodeEdit.cpp
 
 HEADERS += \
         src/TerminalCharacterDecoder.h \
@@ -89,7 +90,8 @@
     src/CodeEdit.h \
     src/FileEditorMdiSubWindow.h \
     src/SyntaxHighlighter.h \
-    src/BrowserWidget.h
+    src/BrowserWidget.h \
+    src/NumberedCodeEdit.h
 
 INCFLAGS = -g3 $$system(mkoctfile -p INCFLAGS)
 LFLAGS = $$system(mkoctfile -p LFLAGS) \
--- a/gui//src/BrowserWidget.cpp
+++ b/gui//src/BrowserWidget.cpp
@@ -54,7 +54,7 @@
     connect(forwardAction, SIGNAL(triggered()), m_webView, SLOT(forward()));
     connect(m_webView, SIGNAL(urlChanged(QUrl)), this, SLOT(setUrl(QUrl)));
     connect(m_urlLineEdit, SIGNAL(returnPressed()), this, SLOT(jumpToWebsite()));
-    connect(m_webView, SIGNAL(statusBarMessage(QString)), m_statusBar, SLOT(showMessage(QString)));
+    connect(m_webView, SIGNAL(statusBarMessage(QString)), this, SLOT(showMessage(QString)));
 }
 
 void BrowserWidget::setUrl(QUrl url) {
@@ -68,6 +68,10 @@
     load(url);
 }
 
+void BrowserWidget::showStatusMessage(QString message) {
+    m_statusBar->showMessage(message, 1000);
+}
+
 void BrowserWidget::load(QUrl url) {
     m_webView->load(url);
 }
--- a/gui//src/BrowserWidget.h
+++ b/gui//src/BrowserWidget.h
@@ -34,6 +34,7 @@
 public slots:
     void setUrl(QUrl url);
     void jumpToWebsite();
+    void showStatusMessage(QString message);
 
 private:
     void construct();
--- a/gui//src/FileEditorMdiSubWindow.cpp
+++ b/gui//src/FileEditorMdiSubWindow.cpp
@@ -64,6 +64,7 @@
     m_toolBar = new QToolBar(this);
     m_codeEdit = new CodeEdit(this);
     m_statusBar = new QStatusBar(this);
+    m_numberedTextView = new NumberedTextView(this, m_codeEdit);
 
     m_codeEdit->setFontFamily("Courier");
     m_codeEdit->setLineWrapMode(QTextEdit::NoWrap);
@@ -84,7 +85,7 @@
 
     QVBoxLayout *layout = new QVBoxLayout();
     layout->addWidget(m_toolBar);
-    layout->addWidget(m_codeEdit);
+    layout->addWidget(m_numberedTextView);
     layout->addWidget(m_statusBar);
     layout->setMargin(2);
     widget()->setLayout(layout);
--- a/gui//src/FileEditorMdiSubWindow.h
+++ b/gui//src/FileEditorMdiSubWindow.h
@@ -23,6 +23,7 @@
 #include <QToolBar>
 #include <QStatusBar>
 #include "CodeEdit.h"
+#include "NumberedCodeEdit.h"
 
 class FileEditorMdiSubWindow : public QMdiSubWindow {
     Q_OBJECT
@@ -40,6 +41,7 @@
     void construct();
     QToolBar *m_toolBar;
     CodeEdit *m_codeEdit;
+    NumberedTextView *m_numberedTextView;
     QStatusBar *m_statusBar;
     QString m_fileName;
 };
new file mode 100644
--- /dev/null
+++ b/gui//src/NumberedCodeEdit.cpp
@@ -0,0 +1,580 @@
+/* This file is part of the KDE libraries
+    Copyright (C) 2005, 2006 KJSEmbed Authors
+    See included AUTHORS file.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+#include <QTextDocument>
+#include <QTextBlock>
+#include <QHBoxLayout>
+#include <QScrollBar>
+#include <QPainter>
+#include <QAbstractTextDocumentLayout>
+#include <QToolTip>
+#include <QTextStream>
+#include <QProcess>
+
+#include "NumberedCodeEdit.h"
+#include "config.h"
+
+NumberBar::NumberBar( QWidget *parent )
+    : QWidget( parent ), edit(0), currentLine(-1), bugLine(-1)
+{
+    // 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" );
+}
+
+NumberBar::~NumberBar()
+{
+}
+
+void NumberBar::setCurrentLine( int lineno )
+{
+    currentLine = lineno;
+    update();
+}
+
+void NumberBar::setBugLine( int lineno )
+{
+    bugLine = lineno;
+}
+
+void NumberBar::toggleBreakpoint( int lineno )
+{
+  if(lineno > 0)
+  {
+    int i = breakpoints.indexOf(lineno);
+
+    if(i > -1)
+      breakpoints.removeAt(i);
+    else
+      breakpoints.push_back(lineno);
+  }
+  update();
+}
+
+void NumberBar::setTextEdit( CodeEdit *edit )
+{
+    this->edit = edit;
+    setFixedWidth( edit->fontMetrics().width( QString("0000") + 10 + 32 ) );
+    connect( edit->document()->documentLayout(), SIGNAL( update(const QRectF &) ),
+	     this, SLOT( update() ) );
+    connect( edit->verticalScrollBar(), SIGNAL(valueChanged(int) ),
+	     this, SLOT( update() ) );
+}
+
+void NumberBar::paintEvent( QPaintEvent * )
+{
+    QVector<qreal> lines_list;
+    int first_line_no;
+    edit->publicBlockBoundingRectList(lines_list, first_line_no);
+    
+    const QFontMetrics fm = edit->fontMetrics();
+    const int ascent = fontMetrics().ascent() + 1; // height = ascent + descent + 1
+   
+    QPainter p(this);
+    p.setPen(palette().windowText().color());
+    
+    bugRect = QRect();
+    stopRect = QRect();
+    currentRect = QRect();
+    
+    int position_y;
+    int lineCount;
+    
+    const int lines_list_size=lines_list.size();
+    
+    for(int i=0;i<lines_list_size;i++)
+    {
+    	position_y=qRound( lines_list[i] );
+    	lineCount=first_line_no+i;
+    	
+    	const QString txt = QString::number( lineCount );
+        p.drawText( width() - fm.width(txt), position_y+ascent, txt );
+        
+        // Bug marker
+	if ( bugLine == lineCount ) {
+	    p.drawPixmap( 1, position_y, bugMarker );
+	    bugRect = QRect( 19, position_y, bugMarker.width(), bugMarker.height() );
+	}
+	
+	// Stop marker
+	if ( breakpoints.contains(lineCount) ) {
+	    p.drawPixmap( 1, position_y, stopMarker );
+	    stopRect = QRect( 1, position_y,stopMarker.width(),  stopMarker.height() );
+	}
+	
+	// Current line marker
+	if ( currentLine == lineCount ) {
+	    p.drawPixmap( 1, position_y, currentMarker );
+	    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 )
+{
+    if ( event->type() == QEvent::ToolTip ) {
+	QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
+
+	if ( stopRect.contains( helpEvent->pos() ) ) {
+	    QToolTip::showText( helpEvent->globalPos(), tr("Stop Here"));
+	}
+	else if ( currentRect.contains( helpEvent->pos() ) ) {
+	    QToolTip::showText( helpEvent->globalPos(), tr("Current Line"));
+	}
+	else if ( bugRect.contains( helpEvent->pos() ) ) {
+	    QToolTip::showText( helpEvent->globalPos(), tr("Error Line" ));
+	}
+    }
+
+    return QWidget::event(event);
+}
+
+QList<int> *NumberBar::getBreakpoints()
+{
+  return &breakpoints;
+}
+
+
+
+NumberedTextView::NumberedTextView( QWidget *parent, CodeEdit *textEdit )
+    : QFrame( parent )
+{
+	setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
+	setLineWidth( 2 );
+	
+	view=textEdit;
+	view->installEventFilter( this );
+	
+	connect( view->document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(textChanged(int,int,int)) );
+	
+	connect( view, SIGNAL(cursorPositionChanged()), this, SLOT(cursor_moved_cb()) );
+	
+	// Setup the line number pane
+	
+	numbers = new NumberBar( this );
+	numbers->setTextEdit( view );
+	//numbers=NULL;
+	
+	
+	vbox = new QVBoxLayout(this);
+	vbox->setSpacing( 0 );
+	vbox->setMargin( 0 );
+	
+	hbox = new QHBoxLayout;
+	vbox->addLayout(hbox);
+	
+	hbox->setSpacing( 0 );
+	hbox->setMargin( 0 );
+	hbox->addWidget( numbers );
+	hbox->addWidget( view );
+
+	textModifiedOk=false;
+	
+	QHBoxLayout *messages_layout= new QHBoxLayout;
+	vbox->addLayout(messages_layout);
+	messages_layout->setSpacing( 0 );
+	messages_layout->setMargin( 0 );
+	
+	line_column_label=new QLabel("Line: 1 Col: 1", this);
+	messages_layout->addWidget(line_column_label);
+	line_column_label->show();
+}
+
+
+NumberedTextView::~NumberedTextView()
+{
+	hide();
+	//printf("Borrado ntv\n");
+}
+
+void NumberedTextView::setCurrentLine( int lineno )
+{
+	currentLine = lineno;
+	if(numbers!=NULL) numbers->setCurrentLine( lineno );
+	
+	//Move cursor to lineno
+	if(lineno>-1)
+	{
+		QTextCursor cursor=textEdit()->textCursor();
+		
+		cursor.movePosition(QTextCursor::Start);
+		
+		for(int i=1;i<lineno;i++)
+			cursor.movePosition(QTextCursor::NextBlock);
+		
+		textEdit()->setTextCursor(cursor);
+	}
+	
+	textChanged( 0, 0, 1 );
+}
+
+void NumberedTextView::toggleBreakpoint( int lineno )
+{
+	if(numbers!=NULL) numbers->toggleBreakpoint( lineno );
+}
+
+void NumberedTextView::setBugLine( int lineno )
+{
+	if(numbers!=NULL) numbers->setBugLine( lineno );
+}
+
+void NumberedTextView::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() )
+    {
+    	textModifiedOk=true;
+    	emit textModified();
+    }
+}
+
+bool NumberedTextView::eventFilter( QObject *obj, QEvent *event )
+{
+    if ( obj != view )
+	return QFrame::eventFilter(obj, event);
+
+    if ( event->type() == QEvent::ToolTip ) {
+	QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
+
+	QTextCursor cursor = view->cursorForPosition( helpEvent->pos() );
+	cursor.movePosition( QTextCursor::StartOfWord, QTextCursor::MoveAnchor );
+	cursor.movePosition( QTextCursor::EndOfWord, QTextCursor::KeepAnchor );
+
+	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> *br=NULL;
+	if(numbers!=NULL) br=numbers->getBreakpoints();
+	return br;
+}
+
+void NumberedTextView::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);
+  }else{
+    throw path;
+  }
+}
+
+void NumberedTextView::save(QString path)
+{
+  FILE *fl;
+
+  if(path.isEmpty())
+    path = filePath;
+  else
+    filePath = path;
+
+  fl = fopen(path.toLocal8Bit().constData(), "wt");
+  if(fl)
+  {
+    QTextStream *stream = new QTextStream(fl);
+    (*stream) << textEdit()->document()->toPlainText();
+    delete stream;
+    fclose(fl);
+    textModifiedOk=false;
+    view->document()->setModified(false);
+  }else{
+    throw path;
+  }
+  
+
+    QString repository=path+"~~";
+    QString command("simplercs \""+repository+"\" \""+path+"\"");
+    QProcess::startDetached(command);
+    //QProcess::execute(command);
+
+}
+
+QString NumberedTextView::path()
+{
+  return filePath;
+}
+
+void NumberedTextView::setPath(QString path)
+{
+	filePath=path;
+}
+
+void NumberedTextView::setModified(bool modify)
+{
+	textModifiedOk=modify;
+}
+
+bool NumberedTextView::modified()
+{
+	return textModifiedOk;
+}
+
+void NumberedTextView::cursor_moved_cb()
+{
+	QTextCursor cursor=view->textCursor();
+	QTextBlock actual_block=cursor.block();
+	int lineCount=1;
+	QTextBlock block = view->document()->begin();
+	
+	for ( ;block.isValid() && actual_block!=block; block = block.next()) lineCount++ ;
+	
+	int col= cursor.position() - block.position() + 1;
+	
+	line_column_label->setText("Line: "+QString::number(lineCount)+" Col: "+QString::number(col) );
+}
+
+static QString startLineInsertText(QString str, QString textToInsert)
+{
+	str.replace(QChar(0x2029), "\n");
+	//printf("str=%s\n", str.toLocal8Bit().data() );
+	
+	QStringList list = str.split("\n");
+	
+	for(int i=0;i<list.size();i++)
+	{
+		QString s=list[i];
+		
+		int x;
+		
+		for(x=0;x<s.size();x++)
+		{
+			if( s.at(x)!=' ' && s.at(x)!='\t' ) break;
+		}
+		
+		QString s1=s.left(x);
+		QString s2=s.right(s.size()-x);
+		//printf("s1=%s s2=%s\n", s1.toLocal8Bit().data(), s2.toLocal8Bit().data() );
+		list[i]=s1+textToInsert+s2;
+	}
+	
+	return list.join("\n");
+}
+
+static QString startLineRemoveText(QString str, QStringList textToRemove)
+{
+	str.replace(QChar(0x2029), "\n");
+	//printf("str=%s\n", str.toLocal8Bit().data() );
+	
+	QStringList list = str.split("\n");
+	
+	for(int i=0;i<list.size();i++)
+	{
+		QString s=list[i];
+		
+		int x;
+		
+		for(x=0;x<s.size();x++)
+		{
+			if( s.at(x)!=' ' && s.at(x)!='\t' ) break;
+		}
+		
+		QString s1=s.left(x);
+		QString s2=s.right(s.size()-x);
+		
+		for(int k=0;k<textToRemove.size();k++)
+		{
+			if(s1.endsWith(textToRemove[k]))
+			{
+				s1=s1.left(s1.size()-textToRemove[k].size());
+				break;
+			}
+			else if(s2.startsWith(textToRemove[k]))
+			{
+				s2=s2.right(s2.size()-textToRemove[k].size());
+				break;
+			}
+		}
+		
+		//printf("s1=%s s2=%s \n", s1.toLocal8Bit().data(), s2.toLocal8Bit().data());
+		list[i]=s1+s2;
+	}
+	
+	return list.join("\n");
+}
+
+void NumberedTextView::indent()
+{
+	//QTextDocument *doc=textEdit()->document();
+	
+	QTextCursor cursor(textEdit()->textCursor());
+	
+	if( !cursor.hasSelection() ) return;
+	
+	QString str=cursor.selectedText();
+	
+	str=startLineInsertText(str, "\t");
+	
+	cursor.insertText(str);
+	cursor.setPosition(cursor.position()-str.size(), QTextCursor::KeepAnchor);
+	textEdit()->setTextCursor(cursor);
+}
+
+void NumberedTextView::unindent()
+{
+	//QTextDocument *doc=textEdit()->document();
+	
+	QTextCursor cursor(textEdit()->textCursor());
+	
+	if( !cursor.hasSelection() ) return;
+	
+	QString str=cursor.selectedText();
+	
+	QStringList textToRemove;
+	textToRemove << "\t" << " ";
+	str=startLineRemoveText(str, textToRemove);
+	
+	cursor.insertText(str);
+	cursor.setPosition(cursor.position()-str.size(), QTextCursor::KeepAnchor);
+	textEdit()->setTextCursor(cursor);
+}
+
+void NumberedTextView::comment()
+{
+	//QTextDocument *doc=textEdit()->document();
+	
+	QTextCursor cursor(textEdit()->textCursor());
+	
+	if( !cursor.hasSelection() ) return;
+	
+	QString str=cursor.selectedText();
+	
+	str=startLineInsertText(str, "%");
+	
+	cursor.insertText(str);
+	cursor.setPosition(cursor.position()-str.size(), QTextCursor::KeepAnchor);
+	textEdit()->setTextCursor(cursor);
+}
+
+void NumberedTextView::uncomment()
+{
+	//QTextDocument *doc=textEdit()->document();
+	
+	QTextCursor cursor(textEdit()->textCursor());
+	
+	if( !cursor.hasSelection() ) return;
+	
+	QString str=cursor.selectedText();
+	
+	QStringList textToRemove;
+	textToRemove << "%" << "#";
+	str=startLineRemoveText(str, textToRemove);
+	
+	cursor.insertText(str);
+	cursor.setPosition(cursor.position()-str.size(), QTextCursor::KeepAnchor);
+	textEdit()->setTextCursor(cursor);
+}
new file mode 100644
--- /dev/null
+++ b/gui//src/NumberedCodeEdit.h
@@ -0,0 +1,167 @@
+/* This file is part of the KDE libraries
+    Copyright (C) 2005, 2006 KJSEmbed Authors
+    See included AUTHORS file.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+// -*- c++ -*-
+#ifndef NUMBERED_TEXT_VIEW_H
+#define NUMBERED_TEXT_VIEW_H
+
+#include <QFrame>
+#include <QPixmap>
+#include <QTextCursor>
+#include <QLabel>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include "CodeEdit.h"
+
+class CodeEdit;
+class QHBoxLayout;
+
+/**
+ * @internal Used to display the numbers.
+ */
+class NumberBar : public QWidget
+{
+    Q_OBJECT
+
+public:
+    NumberBar( QWidget *parent );
+    ~NumberBar();
+
+    void setCurrentLine( int lineno );
+    void setBugLine( int lineno );
+    void toggleBreakpoint( int lineno );
+    QList<int> *getBreakpoints();
+
+    void setTextEdit( CodeEdit *edit );
+    void paintEvent( QPaintEvent *ev );
+
+protected:
+    bool event( QEvent *ev );
+
+private:
+    CodeEdit *edit;
+    QPixmap stopMarker;
+    QPixmap currentMarker;
+    QPixmap bugMarker;
+    QList<int> breakpoints;
+    int currentLine;
+    int bugLine;
+    QRect stopRect;
+    QRect currentRect;
+    QRect bugRect;
+};
+
+/**
+ * Displays a CodeEdit with line numbers.
+ */
+class NumberedTextView : public QFrame
+{
+    Q_OBJECT
+
+public:
+    NumberedTextView( QWidget *parent = 0 , CodeEdit *textEdit=new CodeEdit() );
+    ~NumberedTextView();
+
+    QList<int> *getBreakpoints();
+
+    void open(QString path);
+    void save(QString path = QString());
+
+    QString path();
+    void setPath(QString path);
+    
+    bool modified();
+    void setModified(bool modify);
+
+    /** Returns the CodeEdit of the main view. */
+    CodeEdit *textEdit() const { return view; }
+
+    /**
+     * Sets the line that should have the current line indicator.
+     * A value of -1 indicates no line should show the indicator.
+     */
+    void setCurrentLine( int lineno );
+
+    /**
+     * Toggle breakpoint
+     */
+    void toggleBreakpoint( int lineno );
+
+    /**
+     * Sets the line that should have the bug line indicator.
+     * A value of -1 indicates no line should show the indicator.
+     */
+    void setBugLine( int lineno );
+
+    /** @internal Used to get tooltip events from the view for the hover signal. */
+    bool eventFilter( QObject *obj, QEvent *event );
+    
+    /**Indent selected text.*/
+    void indent();
+    
+    /**UnIndent selected text.*/
+    void unindent();
+    
+    /**Comment selected text.*/
+    void comment();
+    
+    /**UnComment selected text.*/
+    void uncomment();
+
+signals:
+    /**
+     * Emitted when the mouse is hovered over the text edit component.
+     * @param word The word under the mouse pointer
+     */
+    void mouseHover( const QString &word );
+
+    /**
+     * Emitted when the mouse is hovered over the text edit component.
+     * @param pos The position of the mouse pointer.
+     * @param word The word under the mouse pointer
+     */
+    void mouseHover( const QPoint &pos, const QString &word );
+    
+    /**
+     * Emitted when file is changed.
+     */
+    void textModified();
+
+protected slots:
+    /** @internal Used to update the highlight on the current line. */
+    void textChanged( int pos, int added, int removed );
+public slots:
+    void cursor_moved_cb();
+
+private:
+    QString filePath;
+    QLabel *line_column_label;
+    CodeEdit *view;
+    NumberBar *numbers;
+    QHBoxLayout *hbox;
+    QVBoxLayout *vbox;
+    int currentLine;
+    QTextCursor highlight;
+    bool textModifiedOk;
+};
+
+
+#endif // NUMBERED_TEXT_VIEW_H
+
+