Commit 5babad8c authored by Ulf Hermann's avatar Ulf Hermann

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: default avatarhjk <hjk@theqtcompany.com>
parent 19ab7886
...@@ -51,23 +51,11 @@ namespace Internal { ...@@ -51,23 +51,11 @@ namespace Internal {
QmlConsoleEdit::QmlConsoleEdit(const QModelIndex &index, QWidget *parent) : QmlConsoleEdit::QmlConsoleEdit(const QModelIndex &index, QWidget *parent) :
QTextEdit(parent), QTextEdit(parent),
m_historyIndex(index), m_historyIndex(index)
m_prompt(QLatin1String(":/qmljstools/images/prompt.png")),
m_startOfEditableArea(0)
{ {
setFrameStyle(QFrame::NoFrame); setFrameStyle(QFrame::NoFrame);
setUndoRedoEnabled(false); setUndoRedoEnabled(false);
setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
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();
ensureCursorVisible(); ensureCursorVisible();
setTextInteractionFlags(Qt::TextEditorInteraction); setTextInteractionFlags(Qt::TextEditorInteraction);
} }
...@@ -79,34 +67,11 @@ void QmlConsoleEdit::keyPressEvent(QKeyEvent *e) ...@@ -79,34 +67,11 @@ void QmlConsoleEdit::keyPressEvent(QKeyEvent *e)
switch (e->key()) { switch (e->key()) {
case Qt::Key_Return: case Qt::Key_Return:
case Qt::Key_Enter: { case Qt::Key_Enter: {
m_interpreter.clearText();
QString currentScript = getCurrentScript(); QString currentScript = getCurrentScript();
m_interpreter.appendText(currentScript); if (m_interpreter.canEvaluate(currentScript)) {
if (currentScript.isEmpty()) {
emit editingFinished();
} else if (m_interpreter.canEvaluate()) {
QmlConsoleModel::evaluate(currentScript); QmlConsoleModel::evaluate(currentScript);
emit editingFinished(); 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; keyConsumed = true;
break; break;
} }
...@@ -121,44 +86,7 @@ void QmlConsoleEdit::keyPressEvent(QKeyEvent *e) ...@@ -121,44 +86,7 @@ void QmlConsoleEdit::keyPressEvent(QKeyEvent *e)
keyConsumed = true; keyConsumed = true;
break; 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: default:
// Disallow any other keys in the prompt area
if (textCursor().selectionStart() < m_startOfEditableArea)
keyConsumed = true;
break; break;
} }
...@@ -166,37 +94,6 @@ void QmlConsoleEdit::keyPressEvent(QKeyEvent *e) ...@@ -166,37 +94,6 @@ void QmlConsoleEdit::keyPressEvent(QKeyEvent *e)
QTextEdit::keyPressEvent(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*/) void QmlConsoleEdit::focusOutEvent(QFocusEvent * /*e*/)
{ {
emit editingFinished(); emit editingFinished();
...@@ -252,16 +149,15 @@ void QmlConsoleEdit::handleDownKey() ...@@ -252,16 +149,15 @@ void QmlConsoleEdit::handleDownKey()
QString QmlConsoleEdit::getCurrentScript() const QString QmlConsoleEdit::getCurrentScript() const
{ {
QTextCursor cursor = textCursor(); QTextCursor cursor = textCursor();
cursor.setPosition(m_startOfEditableArea); cursor.setPosition(0);
cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
QString script = cursor.selectedText(); return cursor.selectedText();
return script.trimmed();
} }
void QmlConsoleEdit::replaceCurrentScript(const QString &script) void QmlConsoleEdit::replaceCurrentScript(const QString &script)
{ {
QTextCursor cursor = textCursor(); QTextCursor cursor = textCursor();
cursor.setPosition(m_startOfEditableArea); cursor.setPosition(0);
cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
cursor.removeSelectedText(); cursor.removeSelectedText();
cursor.insertText(script); cursor.insertText(script);
......
...@@ -49,7 +49,6 @@ public: ...@@ -49,7 +49,6 @@ public:
protected: protected:
void keyPressEvent(QKeyEvent *e); void keyPressEvent(QKeyEvent *e);
void contextMenuEvent(QContextMenuEvent *event);
void focusOutEvent(QFocusEvent *e); void focusOutEvent(QFocusEvent *e);
signals: signals:
...@@ -64,8 +63,6 @@ protected: ...@@ -64,8 +63,6 @@ protected:
private: private:
QModelIndex m_historyIndex; QModelIndex m_historyIndex;
QString m_cachedScript; QString m_cachedScript;
QImage m_prompt;
int m_startOfEditableArea;
QmlJSInterpreter m_interpreter; QmlJSInterpreter m_interpreter;
}; };
......
...@@ -312,6 +312,18 @@ QWidget *QmlConsoleItemDelegate::createEditor(QWidget *parent, ...@@ -312,6 +312,18 @@ QWidget *QmlConsoleItemDelegate::createEditor(QWidget *parent,
{ {
QmlConsoleEdit *editor = new QmlConsoleEdit(index, 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, connect(editor, &QmlConsoleEdit::editingFinished,
this, &QmlConsoleItemDelegate::commitAndCloseEditor); this, &QmlConsoleItemDelegate::commitAndCloseEditor);
return editor; return editor;
......
...@@ -33,13 +33,13 @@ ...@@ -33,13 +33,13 @@
namespace QmlJSTools { namespace QmlJSTools {
namespace Internal { namespace Internal {
bool QmlJSInterpreter::canEvaluate() bool QmlJSInterpreter::canEvaluate(QString code)
{ {
int yyaction = 0; int yyaction = 0;
int yytoken = -1; int yytoken = -1;
int yytos = -1; int yytos = -1;
setCode(m_code, 1); setCode(code, 1);
m_tokens.append(T_FEED_JS_PROGRAM); m_tokens.append(T_FEED_JS_PROGRAM);
do { do {
......
...@@ -48,20 +48,14 @@ public: ...@@ -48,20 +48,14 @@ public:
: Lexer(&m_engine), : Lexer(&m_engine),
m_stateStack(128) m_stateStack(128)
{ {
} }
void clearText() { m_code.clear(); } bool canEvaluate(QString code);
void appendText(const QString &text) { m_code += text; }
QString code() const { return m_code; }
bool canEvaluate();
private: private:
QmlJS::Engine m_engine; QmlJS::Engine m_engine;
QVector<int> m_stateStack; QVector<int> m_stateStack;
QList<int> m_tokens; QList<int> m_tokens;
QString m_code;
}; };
} // namespace Internal } // namespace Internal
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment