Simple line numbering and fixed-width fonts for the script dialogue. Based on Qt examples. Should resolve Bugs #2505 and #2512.

test
cc9cii 10 years ago
parent f1c0847897
commit 28048c0bf3

@ -5,6 +5,8 @@
#include <QDragEnterEvent> #include <QDragEnterEvent>
#include <QRegExp> #include <QRegExp>
#include <QString> #include <QString>
#include <QPainter>
#include <QTextDocumentFragment>
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
@ -72,6 +74,20 @@ CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighli
connect (&mUpdateTimer, SIGNAL (timeout()), this, SLOT (updateHighlighting())); connect (&mUpdateTimer, SIGNAL (timeout()), this, SLOT (updateHighlighting()));
mUpdateTimer.setSingleShot (true); mUpdateTimer.setSingleShot (true);
// FIXME: make this configurable or provide a font selector dialogue
// FIXME: save QFontInfo somewhere before switching to a new one
QFont font("Monospace");
font.setStyleHint(QFont::TypeWriter);
setFont(font);
// FIXME: make this configurable
lineNumberArea = new LineNumberArea(this);
connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));
updateLineNumberAreaWidth(0);
} }
bool CSVWorld::ScriptEdit::isChangeLocked() const bool CSVWorld::ScriptEdit::isChangeLocked() const
@ -157,3 +173,109 @@ void CSVWorld::ScriptEdit::updateHighlighting()
mHighlighter->rehighlight(); mHighlighter->rehighlight();
} }
int CSVWorld::ScriptEdit::lineNumberAreaWidth()
{
int digits = 1;
int max = qMax(1, blockCount());
while (max >= 10)
{
max /= 10;
++digits;
}
int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;
return space;
}
void CSVWorld::ScriptEdit::updateLineNumberAreaWidth(int /* newBlockCount */)
{
setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
}
void CSVWorld::ScriptEdit::updateLineNumberArea(const QRect &rect, int dy)
{
if (dy)
lineNumberArea->scroll(0, dy);
else
lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());
if (rect.contains(viewport()->rect()))
updateLineNumberAreaWidth(0);
}
void CSVWorld::ScriptEdit::resizeEvent(QResizeEvent *e)
{
QPlainTextEdit::resizeEvent(e);
QRect cr = contentsRect();
lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
}
void CSVWorld::ScriptEdit::lineNumberAreaPaintEvent(QPaintEvent *event)
{
QPainter painter(lineNumberArea);
QTextBlock block = firstVisibleBlock();
int blockNumber = block.blockNumber();
int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
int bottom = top + (int) blockBoundingRect(block).height();
int startBlock = textCursor().blockNumber();
int endBlock = textCursor().blockNumber();
if(textCursor().hasSelection())
{
QString str = textCursor().selection().toPlainText();
int selectedLines = str.count("\n")+1;
if(textCursor().position() < textCursor().anchor())
endBlock += selectedLines;
else
startBlock -= selectedLines;
}
painter.setBackgroundMode(Qt::OpaqueMode);
QFont font = painter.font();
QBrush background = painter.background();
while (block.isValid() && top <= event->rect().bottom())
{
if (block.isVisible() && bottom >= event->rect().top())
{
QFont newFont = painter.font();
QString number = QString::number(blockNumber + 1);
if(blockNumber >= startBlock && blockNumber <= endBlock)
{
painter.setBackground(Qt::cyan);
painter.setPen(Qt::darkMagenta);
newFont.setBold(true);
}
else
{
painter.setBackground(background);
painter.setPen(Qt::black);
}
painter.setFont(newFont);
painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(),
Qt::AlignRight, number);
painter.setFont(font);
}
block = block.next();
top = bottom;
bottom = top + (int) blockBoundingRect(block).height();
++blockNumber;
}
}
CSVWorld::LineNumberArea::LineNumberArea(ScriptEdit *editor) : QWidget(editor), mScriptEdit(editor)
{}
QSize CSVWorld::LineNumberArea::sizeHint() const
{
return QSize(mScriptEdit->lineNumberAreaWidth(), 0);
}
void CSVWorld::LineNumberArea::paintEvent(QPaintEvent *event)
{
mScriptEdit->lineNumberAreaPaintEvent(event);
}

@ -2,6 +2,7 @@
#define SCRIPTEDIT_H #define SCRIPTEDIT_H
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <QWidget>
#include <QVector> #include <QVector>
#include <QTimer> #include <QTimer>
@ -9,7 +10,6 @@
#include "scripthighlighter.hpp" #include "scripthighlighter.hpp"
class QWidget;
class QRegExp; class QRegExp;
namespace CSMDoc namespace CSMDoc
@ -19,6 +19,8 @@ namespace CSMDoc
namespace CSVWorld namespace CSVWorld
{ {
class LineNumberArea;
class ScriptEdit : public QPlainTextEdit class ScriptEdit : public QPlainTextEdit
{ {
Q_OBJECT Q_OBJECT
@ -45,6 +47,7 @@ namespace CSVWorld
int mChangeLocked; int mChangeLocked;
ScriptHighlighter *mHighlighter; ScriptHighlighter *mHighlighter;
QTimer mUpdateTimer; QTimer mUpdateTimer;
QWidget *lineNumberArea;
public: public:
@ -56,6 +59,13 @@ namespace CSVWorld
/// \note This mechanism is used to avoid infinite update recursions /// \note This mechanism is used to avoid infinite update recursions
bool isChangeLocked() const; bool isChangeLocked() const;
void lineNumberAreaPaintEvent(QPaintEvent *event);
int lineNumberAreaWidth();
protected:
virtual void resizeEvent(QResizeEvent *e);
private: private:
QVector<CSMWorld::UniversalId::Type> mAllowedTypes; QVector<CSMWorld::UniversalId::Type> mAllowedTypes;
const CSMDoc::Document& mDocument; const CSMDoc::Document& mDocument;
@ -74,6 +84,23 @@ namespace CSVWorld
void idListChanged(); void idListChanged();
void updateHighlighting(); void updateHighlighting();
void updateLineNumberAreaWidth(int newBlockCount);
void updateLineNumberArea(const QRect &, int);
};
class LineNumberArea : public QWidget
{
ScriptEdit *mScriptEdit;
public:
LineNumberArea(ScriptEdit *editor);
QSize sizeHint() const;
protected:
void paintEvent(QPaintEvent *event);
}; };
} }
#endif // SCRIPTEDIT_H #endif // SCRIPTEDIT_H

Loading…
Cancel
Save