forked from qt-creator/qt-creator
QmlJS: Clean up QML console editor
Align the text between editing and display mode, and remove the dead code. The prompt sign does not have to be part of the text and the JS parser does not have to retain the code it parses. Change-Id: I6e41f4fbc2cc863c84677640826d8663bcc648fb Task-number: QTCREATORBUG-14931 Reviewed-by: hjk <hjk@theqtcompany.com>
This commit is contained in:
@@ -51,23 +51,11 @@ namespace Internal {
|
||||
|
||||
QmlConsoleEdit::QmlConsoleEdit(const QModelIndex &index, QWidget *parent) :
|
||||
QTextEdit(parent),
|
||||
m_historyIndex(index),
|
||||
m_prompt(QLatin1String(":/qmljstools/images/prompt.png")),
|
||||
m_startOfEditableArea(0)
|
||||
m_historyIndex(index)
|
||||
{
|
||||
setFrameStyle(QFrame::NoFrame);
|
||||
setUndoRedoEnabled(false);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
document()->addResource(QTextDocument::ImageResource, QUrl(QLatin1String("prompt")), m_prompt);
|
||||
QTextImageFormat format;
|
||||
format.setName(QLatin1String("prompt"));
|
||||
format.setHeight(9);
|
||||
format.setWidth(9);
|
||||
textCursor().insertText(QLatin1String(" "));
|
||||
textCursor().insertImage(format);
|
||||
textCursor().insertText(QLatin1String(" "));
|
||||
m_startOfEditableArea = textCursor().position();
|
||||
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
ensureCursorVisible();
|
||||
setTextInteractionFlags(Qt::TextEditorInteraction);
|
||||
}
|
||||
@@ -79,34 +67,11 @@ void QmlConsoleEdit::keyPressEvent(QKeyEvent *e)
|
||||
switch (e->key()) {
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Enter: {
|
||||
m_interpreter.clearText();
|
||||
QString currentScript = getCurrentScript();
|
||||
m_interpreter.appendText(currentScript);
|
||||
if (currentScript.isEmpty()) {
|
||||
emit editingFinished();
|
||||
} else if (m_interpreter.canEvaluate()) {
|
||||
if (m_interpreter.canEvaluate(currentScript)) {
|
||||
QmlConsoleModel::evaluate(currentScript);
|
||||
emit editingFinished();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_Backspace:
|
||||
if (textCursor().selectionStart() <= m_startOfEditableArea)
|
||||
keyConsumed = true;
|
||||
break;
|
||||
|
||||
case Qt::Key_Delete:
|
||||
if (textCursor().selectionStart() < m_startOfEditableArea)
|
||||
keyConsumed = true;
|
||||
break;
|
||||
|
||||
case Qt::Key_Home: {
|
||||
QTextCursor c(textCursor());
|
||||
bool select = e->modifiers() & Qt::ShiftModifier;
|
||||
c.setPosition(m_startOfEditableArea,
|
||||
select ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
|
||||
setTextCursor(c);
|
||||
keyConsumed = true;
|
||||
break;
|
||||
}
|
||||
@@ -121,44 +86,7 @@ void QmlConsoleEdit::keyPressEvent(QKeyEvent *e)
|
||||
keyConsumed = true;
|
||||
break;
|
||||
|
||||
// Ctrl+Left: Moves the cursor one word to the left.
|
||||
// Left: Moves the cursor one character to the left.
|
||||
case Qt::Key_Left:
|
||||
if (textCursor().position() <= m_startOfEditableArea
|
||||
|| e->modifiers() & Qt::ControlModifier) {
|
||||
QTextCursor c(textCursor());
|
||||
bool select = e->modifiers() & Qt::ShiftModifier;
|
||||
c.setPosition(m_startOfEditableArea,
|
||||
select ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
|
||||
setTextCursor(c);
|
||||
keyConsumed = true;
|
||||
}
|
||||
break;
|
||||
|
||||
// Ctrl+Right: Moves the cursor one word to the right.
|
||||
// Right: Moves the cursor one character to the right.
|
||||
case Qt::Key_Right:
|
||||
if ( !(e->modifiers() & Qt::ControlModifier)
|
||||
&& textCursor().position() < m_startOfEditableArea) {
|
||||
QTextCursor c(textCursor());
|
||||
c.setPosition(m_startOfEditableArea);
|
||||
setTextCursor(c);
|
||||
keyConsumed = true;
|
||||
}
|
||||
break;
|
||||
|
||||
// Ctrl+C, Ctrl+Insert: Allow to Copy the selected text to the clipboard.
|
||||
case Qt::Key_C:
|
||||
case Qt::Key_Insert:
|
||||
if (textCursor().selectionStart() < m_startOfEditableArea &&
|
||||
!(e->modifiers() & Qt::ControlModifier))
|
||||
keyConsumed = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Disallow any other keys in the prompt area
|
||||
if (textCursor().selectionStart() < m_startOfEditableArea)
|
||||
keyConsumed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -166,37 +94,6 @@ void QmlConsoleEdit::keyPressEvent(QKeyEvent *e)
|
||||
QTextEdit::keyPressEvent(e);
|
||||
}
|
||||
|
||||
void QmlConsoleEdit::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
// TODO:: on right click the editor closes
|
||||
return QTextEdit::contextMenuEvent(event);
|
||||
|
||||
QTextCursor cursor = textCursor();
|
||||
bool editable = cursor.position() > m_startOfEditableArea;
|
||||
QMenu *menu = new QMenu();
|
||||
QAction *a;
|
||||
|
||||
a = menu->addAction(tr("Cu&t"), this, SLOT(cut()));
|
||||
a->setEnabled(cursor.hasSelection() && editable);
|
||||
|
||||
a = menu->addAction(tr("&Copy"), this, SLOT(copy()));
|
||||
a->setEnabled(cursor.hasSelection());
|
||||
|
||||
a = menu->addAction(tr("&Paste"), this, SLOT(paste()));
|
||||
a->setEnabled(canPaste() && editable);
|
||||
|
||||
menu->addSeparator();
|
||||
a = menu->addAction(tr("Select &All"), this, SLOT(selectAll()));
|
||||
a->setEnabled(!document()->isEmpty());
|
||||
|
||||
menu->addSeparator();
|
||||
menu->addAction(tr("C&lear"), this, SLOT(clear()));
|
||||
|
||||
menu->exec(event->globalPos());
|
||||
|
||||
delete menu;
|
||||
}
|
||||
|
||||
void QmlConsoleEdit::focusOutEvent(QFocusEvent * /*e*/)
|
||||
{
|
||||
emit editingFinished();
|
||||
@@ -252,16 +149,15 @@ void QmlConsoleEdit::handleDownKey()
|
||||
QString QmlConsoleEdit::getCurrentScript() const
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
cursor.setPosition(m_startOfEditableArea);
|
||||
cursor.setPosition(0);
|
||||
cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
|
||||
QString script = cursor.selectedText();
|
||||
return script.trimmed();
|
||||
return cursor.selectedText();
|
||||
}
|
||||
|
||||
void QmlConsoleEdit::replaceCurrentScript(const QString &script)
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
cursor.setPosition(m_startOfEditableArea);
|
||||
cursor.setPosition(0);
|
||||
cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
|
||||
cursor.removeSelectedText();
|
||||
cursor.insertText(script);
|
||||
|
||||
@@ -49,7 +49,6 @@ public:
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
void contextMenuEvent(QContextMenuEvent *event);
|
||||
void focusOutEvent(QFocusEvent *e);
|
||||
|
||||
signals:
|
||||
@@ -64,8 +63,6 @@ protected:
|
||||
private:
|
||||
QModelIndex m_historyIndex;
|
||||
QString m_cachedScript;
|
||||
QImage m_prompt;
|
||||
int m_startOfEditableArea;
|
||||
QmlJSInterpreter m_interpreter;
|
||||
};
|
||||
|
||||
|
||||
@@ -312,6 +312,18 @@ QWidget *QmlConsoleItemDelegate::createEditor(QWidget *parent,
|
||||
|
||||
{
|
||||
QmlConsoleEdit *editor = new QmlConsoleEdit(index, parent);
|
||||
// Fiddle the prompt into the margin so that we don't have to put it into the text.
|
||||
// Apparently you can have both background-image and background-color, which conveniently
|
||||
// prevents the painted text from shining through.
|
||||
editor->setStyleSheet(QLatin1String("QTextEdit {"
|
||||
"margin-left: 24px;"
|
||||
"margin-top: 4px;"
|
||||
"background-color: white;"
|
||||
"background-image: url(:/qmljstools/images/prompt.png);"
|
||||
"background-position: baseline left;"
|
||||
"background-origin: margin;"
|
||||
"background-repeat: none;"
|
||||
"}"));
|
||||
connect(editor, &QmlConsoleEdit::editingFinished,
|
||||
this, &QmlConsoleItemDelegate::commitAndCloseEditor);
|
||||
return editor;
|
||||
|
||||
@@ -33,13 +33,13 @@
|
||||
namespace QmlJSTools {
|
||||
namespace Internal {
|
||||
|
||||
bool QmlJSInterpreter::canEvaluate()
|
||||
bool QmlJSInterpreter::canEvaluate(QString code)
|
||||
{
|
||||
int yyaction = 0;
|
||||
int yytoken = -1;
|
||||
int yytos = -1;
|
||||
|
||||
setCode(m_code, 1);
|
||||
setCode(code, 1);
|
||||
m_tokens.append(T_FEED_JS_PROGRAM);
|
||||
|
||||
do {
|
||||
|
||||
@@ -48,20 +48,14 @@ public:
|
||||
: Lexer(&m_engine),
|
||||
m_stateStack(128)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void clearText() { m_code.clear(); }
|
||||
void appendText(const QString &text) { m_code += text; }
|
||||
|
||||
QString code() const { return m_code; }
|
||||
bool canEvaluate();
|
||||
bool canEvaluate(QString code);
|
||||
|
||||
private:
|
||||
QmlJS::Engine m_engine;
|
||||
QVector<int> m_stateStack;
|
||||
QList<int> m_tokens;
|
||||
QString m_code;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
Reference in New Issue
Block a user