forked from teamnwah/openmw-tes3coop
Merge remote-tracking branch 'cc9cii/script-dialog'
This commit is contained in:
commit
efde061c7c
5 changed files with 259 additions and 6 deletions
|
@ -226,6 +226,18 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
|
|||
autoDelete->setDefaultValue ("true");
|
||||
}
|
||||
|
||||
declareSection ("script-editor", "Script Editor");
|
||||
{
|
||||
Setting *lineNum = createSetting (Type_CheckBox, "show-linenum", "Show Line Numbers");
|
||||
lineNum->setDefaultValue ("true");
|
||||
lineNum->setToolTip ("Show line numbers to the left of the script editor window."
|
||||
"The current row and column numbers of the text cursor are shown at the bottom.");
|
||||
|
||||
Setting *monoFont = createSetting (Type_CheckBox, "mono-font", "Use monospace font");
|
||||
monoFont->setDefaultValue ("true");
|
||||
monoFont->setToolTip ("Whether to use monospaced fonts on script edit subview.");
|
||||
}
|
||||
|
||||
{
|
||||
/******************************************************************
|
||||
* There are three types of values:
|
||||
|
|
|
@ -5,11 +5,14 @@
|
|||
#include <QDragEnterEvent>
|
||||
#include <QRegExp>
|
||||
#include <QString>
|
||||
#include <QPainter>
|
||||
#include <QTextDocumentFragment>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../../model/world/universalid.hpp"
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
|
||||
|
||||
CSVWorld::ScriptEdit::ChangeLock::ChangeLock (ScriptEdit& edit) : mEdit (edit)
|
||||
|
@ -28,7 +31,11 @@ CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighli
|
|||
: QPlainTextEdit (parent),
|
||||
mDocument (document),
|
||||
mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive),
|
||||
mChangeLocked (0)
|
||||
mChangeLocked (0),
|
||||
mLineNumberArea(0),
|
||||
mShowLineNum(false),
|
||||
mDefaultFont(font()),
|
||||
mMonoFont(QFont("Monospace"))
|
||||
{
|
||||
// setAcceptRichText (false);
|
||||
setLineWrapMode (QPlainTextEdit::NoWrap);
|
||||
|
@ -72,6 +79,41 @@ CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighli
|
|||
connect (&mUpdateTimer, SIGNAL (timeout()), this, SLOT (updateHighlighting()));
|
||||
|
||||
mUpdateTimer.setSingleShot (true);
|
||||
|
||||
// TODO: provide a font selector dialogue
|
||||
mMonoFont.setStyleHint(QFont::TypeWriter);
|
||||
std::string useMonoFont =
|
||||
CSMSettings::UserSettings::instance().setting("script-editor/mono-font", "true").toStdString();
|
||||
if (useMonoFont == "true")
|
||||
setFont(mMonoFont);
|
||||
|
||||
mLineNumberArea = new LineNumberArea(this);
|
||||
updateLineNumberAreaWidth(0);
|
||||
|
||||
connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
|
||||
connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));
|
||||
|
||||
std::string showStatusBar =
|
||||
CSMSettings::UserSettings::instance().settingValue("script-editor/show-linenum").toStdString();
|
||||
|
||||
showLineNum(showStatusBar == "true");
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptEdit::showLineNum(bool show)
|
||||
{
|
||||
if(show!=mShowLineNum)
|
||||
{
|
||||
mShowLineNum = show;
|
||||
updateLineNumberAreaWidth(0);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptEdit::setMonoFont(bool show)
|
||||
{
|
||||
if(show)
|
||||
setFont(mMonoFont);
|
||||
else
|
||||
setFont(mDefaultFont);
|
||||
}
|
||||
|
||||
bool CSVWorld::ScriptEdit::isChangeLocked() const
|
||||
|
@ -157,3 +199,112 @@ void CSVWorld::ScriptEdit::updateHighlighting()
|
|||
|
||||
mHighlighter->rehighlight();
|
||||
}
|
||||
|
||||
int CSVWorld::ScriptEdit::lineNumberAreaWidth()
|
||||
{
|
||||
if(!mShowLineNum)
|
||||
return 0;
|
||||
|
||||
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)
|
||||
mLineNumberArea->scroll(0, dy);
|
||||
else
|
||||
mLineNumberArea->update(0, rect.y(), mLineNumberArea->width(), rect.height());
|
||||
|
||||
if (rect.contains(viewport()->rect()))
|
||||
updateLineNumberAreaWidth(0);
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptEdit::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
QPlainTextEdit::resizeEvent(e);
|
||||
|
||||
QRect cr = contentsRect();
|
||||
mLineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptEdit::lineNumberAreaPaintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPainter painter(mLineNumberArea);
|
||||
|
||||
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, mLineNumberArea->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,14 +2,15 @@
|
|||
#define SCRIPTEDIT_H
|
||||
|
||||
#include <QPlainTextEdit>
|
||||
#include <QWidget>
|
||||
#include <QVector>
|
||||
#include <QTimer>
|
||||
#include <QFont>
|
||||
|
||||
#include "../../model/world/universalid.hpp"
|
||||
|
||||
#include "scripthighlighter.hpp"
|
||||
|
||||
class QWidget;
|
||||
class QRegExp;
|
||||
|
||||
namespace CSMDoc
|
||||
|
@ -19,6 +20,8 @@ namespace CSMDoc
|
|||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class LineNumberArea;
|
||||
|
||||
class ScriptEdit : public QPlainTextEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -45,6 +48,10 @@ namespace CSVWorld
|
|||
int mChangeLocked;
|
||||
ScriptHighlighter *mHighlighter;
|
||||
QTimer mUpdateTimer;
|
||||
bool mShowLineNum;
|
||||
LineNumberArea *mLineNumberArea;
|
||||
QFont mDefaultFont;
|
||||
QFont mMonoFont;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -56,6 +63,15 @@ namespace CSVWorld
|
|||
/// \note This mechanism is used to avoid infinite update recursions
|
||||
bool isChangeLocked() const;
|
||||
|
||||
void lineNumberAreaPaintEvent(QPaintEvent *event);
|
||||
int lineNumberAreaWidth();
|
||||
void showLineNum(bool show);
|
||||
void setMonoFont(bool show);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void resizeEvent(QResizeEvent *e);
|
||||
|
||||
private:
|
||||
QVector<CSMWorld::UniversalId::Type> mAllowedTypes;
|
||||
const CSMDoc::Document& mDocument;
|
||||
|
@ -74,6 +90,23 @@ namespace CSVWorld
|
|||
void idListChanged();
|
||||
|
||||
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
|
||||
|
|
|
@ -1,21 +1,42 @@
|
|||
|
||||
#include "scriptsubview.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <QStatusBar>
|
||||
#include <QStackedLayout>
|
||||
#include <QLabel>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
#include "../../model/world/universalid.hpp"
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
|
||||
#include "scriptedit.hpp"
|
||||
|
||||
CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
||||
: SubView (id), mDocument (document), mColumn (-1)
|
||||
: SubView (id), mDocument (document), mColumn (-1), mBottom(0), mStatus(0)
|
||||
{
|
||||
setWidget (mEditor = new ScriptEdit (mDocument, ScriptHighlighter::Mode_General, this));
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
layout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
mBottom = new QWidget(this);
|
||||
QStackedLayout *bottmLayout = new QStackedLayout(mBottom);
|
||||
bottmLayout->setContentsMargins (0, 0, 0, 0);
|
||||
QStatusBar *statusBar = new QStatusBar(mBottom);
|
||||
mStatus = new QLabel(mBottom);
|
||||
statusBar->addWidget (mStatus);
|
||||
bottmLayout->addWidget (statusBar);
|
||||
mBottom->setLayout (bottmLayout);
|
||||
|
||||
layout->addWidget (mBottom, 0);
|
||||
layout->insertWidget (0, mEditor = new ScriptEdit (mDocument, ScriptHighlighter::Mode_General, this), 2);
|
||||
|
||||
QWidget *widget = new QWidget;
|
||||
widget->setLayout (layout);
|
||||
setWidget (widget);
|
||||
|
||||
mModel = &dynamic_cast<CSMWorld::IdTable&> (
|
||||
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Scripts));
|
||||
|
@ -40,6 +61,33 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc:
|
|||
|
||||
connect (mModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||
this, SLOT (rowsAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||
|
||||
updateStatusBar();
|
||||
connect(mEditor, SIGNAL(cursorPositionChanged()), this, SLOT(updateStatusBar()));
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStringList& value)
|
||||
{
|
||||
if (name == "script-editor/show-linenum")
|
||||
{
|
||||
std::string showLinenum = value.at(0).toStdString();
|
||||
mEditor->showLineNum(showLinenum == "true");
|
||||
mBottom->setVisible(showLinenum == "true");
|
||||
}
|
||||
else if (name == "script-editor/mono-font")
|
||||
{
|
||||
mEditor->setMonoFont(value.at(0).toStdString() == "true");
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptSubView::updateStatusBar ()
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << "(" << mEditor->textCursor().blockNumber() + 1 << ", "
|
||||
<< mEditor->textCursor().columnNumber() + 1 << ")";
|
||||
|
||||
mStatus->setText (QString::fromUtf8 (stream.str().c_str()));
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptSubView::setEditLock (bool locked)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "../doc/subview.hpp"
|
||||
|
||||
class QModelIndex;
|
||||
class QLabel;
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
|
@ -27,6 +28,8 @@ namespace CSVWorld
|
|||
CSMDoc::Document& mDocument;
|
||||
CSMWorld::IdTable *mModel;
|
||||
int mColumn;
|
||||
QWidget *mBottom;
|
||||
QLabel *mStatus;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -36,6 +39,8 @@ namespace CSVWorld
|
|||
|
||||
virtual void useHint (const std::string& hint);
|
||||
|
||||
virtual void updateUserSetting (const QString& name, const QStringList& value);
|
||||
|
||||
public slots:
|
||||
|
||||
void textChanged();
|
||||
|
@ -43,6 +48,10 @@ namespace CSVWorld
|
|||
void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||
|
||||
void rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||
|
||||
private slots:
|
||||
|
||||
void updateStatusBar();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue