55#include < QAbstractItemView>
66#include < QCompleter>
77#include < QScrollBar>
8- // #include <QDebug>
8+ #include < QPainter>
9+ #include < QTextBlock>
910
1011SqlTextEdit::SqlTextEdit (QWidget* parent) :
11- QTextEdit (parent), m_Completer(0 ), m_defaultCompleterModel(0 )
12+ QPlainTextEdit (parent), m_Completer(0 ), m_defaultCompleterModel(0 )
1213{
1314 // basic auto completer for sqliteedit
1415 m_Completer = new QCompleter (this );
@@ -17,10 +18,16 @@ SqlTextEdit::SqlTextEdit(QWidget* parent) :
1718 m_Completer->setWrapAround (false );
1819 m_Completer->setWidget (this );
1920
21+ // Create line number area
22+ lineNumberArea = new LineNumberArea (this );
23+
24+ connect (this , SIGNAL (blockCountChanged (int )), this , SLOT (updateLineNumberAreaWidth ()));
25+ connect (this , SIGNAL (updateRequest (QRect,int )), this , SLOT (updateLineNumberArea (QRect,int )));
2026 connect (m_Completer, SIGNAL (activated (QString)), this , SLOT (insertCompletion (QString)));
2127 connect (this , SIGNAL (cursorPositionChanged ()), this , SLOT (highlightCurrentLine ()));
2228
2329 highlightCurrentLine ();
30+ updateLineNumberAreaWidth ();
2431}
2532
2633SqlTextEdit::~SqlTextEdit ()
@@ -111,6 +118,74 @@ void SqlTextEdit::highlightCurrentLine()
111118 setExtraSelections (extra_selections);
112119}
113120
121+ int SqlTextEdit::lineNumberAreaWidth ()
122+ {
123+ int digits = 1 ;
124+ int max = qMax (1 , blockCount ());
125+ while (max >= 10 )
126+ {
127+ max /= 10 ;
128+ ++digits;
129+ }
130+
131+ return 3 + fontMetrics ().width (QLatin1Char (' 9' )) * digits;
132+ }
133+
134+ void SqlTextEdit::updateLineNumberAreaWidth ()
135+ {
136+ setViewportMargins (lineNumberAreaWidth (), 0 , 0 , 0 );
137+ }
138+
139+ void SqlTextEdit::updateLineNumberArea (const QRect& rect, int dy)
140+ {
141+ if (dy)
142+ lineNumberArea->scroll (0 , dy);
143+ else
144+ lineNumberArea->update (0 , rect.y (), lineNumberArea->width (), rect.height ());
145+
146+ if (rect.contains (viewport ()->rect ()))
147+ updateLineNumberAreaWidth ();
148+ }
149+
150+ void SqlTextEdit::resizeEvent (QResizeEvent* e)
151+ {
152+ QPlainTextEdit::resizeEvent (e);
153+
154+ QRect cr = contentsRect ();
155+ lineNumberArea->setGeometry (QRect (cr.left (), cr.top (), lineNumberAreaWidth (), cr.height ()));
156+ }
157+
158+ void SqlTextEdit::LineNumberArea::paintEvent (QPaintEvent* event)
159+ {
160+ QPainter painter (this );
161+ painter.fillRect (event->rect (), Qt::lightGray);
162+
163+ QTextBlock block = parent->firstVisibleBlock ();
164+ int blockNumber = block.blockNumber ();
165+ int top = parent->blockBoundingGeometry (block).translated (parent->contentOffset ()).top ();
166+ int bottom = top + parent->blockBoundingRect (block).height ();
167+
168+ while (block.isValid () && top <= event->rect ().bottom ())
169+ {
170+ if (block.isVisible () && bottom >= event->rect ().top ())
171+ {
172+ QString number = QString::number (blockNumber + 1 );
173+ painter.setPen (Qt::black);
174+ painter.drawText (0 , top, width (), fontMetrics ().height (), Qt::AlignRight, number);
175+ }
176+
177+ block = block.next ();
178+ top = bottom;
179+ bottom = top + parent->blockBoundingRect (block).height ();
180+ blockNumber++;
181+ }
182+ }
183+
184+ QSize SqlTextEdit::LineNumberArea::sizeHint () const
185+ {
186+ return QSize (parent->lineNumberAreaWidth (), 0 );
187+ }
188+
114189namespace {
115190bool isSqliteIdentifierChar (QChar c) {
116191 return c.isLetterOrNumber () || c == ' .' || c == ' _' ;
@@ -165,7 +240,7 @@ void SqlTextEdit::focusInEvent(QFocusEvent *e)
165240{
166241 if (m_Completer)
167242 m_Completer->setWidget (this );
168- QTextEdit ::focusInEvent (e);
243+ QPlainTextEdit ::focusInEvent (e);
169244}
170245
171246void SqlTextEdit::keyPressEvent (QKeyEvent *e)
@@ -187,7 +262,7 @@ void SqlTextEdit::keyPressEvent(QKeyEvent *e)
187262
188263 bool isShortcut = ((e->modifiers () & Qt::ControlModifier) && e->key () == Qt::Key_Space); // CTRL+SPACE
189264 if (!m_Completer || !isShortcut) // do not process the shortcut when we have a completer
190- QTextEdit ::keyPressEvent (e);
265+ QPlainTextEdit ::keyPressEvent (e);
191266 const bool ctrlOrShift = e->modifiers () & (Qt::ControlModifier | Qt::ShiftModifier);
192267 const bool cursorKey = e->key () == Qt::Key_Left ||
193268 e->key () == Qt::Key_Up ||
0 commit comments