#include "toonzqt/scriptconsole.h" #include "toonz/scriptengine.h" #include #include #include #include ScriptConsole::ScriptConsole(QWidget *parent) : QTextEdit(parent), m_commandIndex(0) { setObjectName("ScriptConsole"); m_prompt = ">> "; append(m_prompt); moveCursor(QTextCursor::EndOfLine); m_engine = new ScriptEngine(); connect(m_engine, SIGNAL(evaluationDone()), this, SLOT(onEvaluationDone())); connect(m_engine, SIGNAL(output(int, const QString &)), this, SLOT(output(int, const QString &))); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(onCursorPositionChanged())); } ScriptConsole::~ScriptConsole() { delete m_engine; } void ScriptConsole::keyPressEvent(QKeyEvent *e) { if (e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Y) { if (m_engine->isEvaluating()) { m_engine->interrupt(); setTextColor(QColor(255, 127, 0)); append("Interrupt"); moveCursor(QTextCursor::EndOfLine); setTextColor(Qt::black); } return; } switch (e->key()) { case Qt::Key_Return: onReturnKeyPress(); break; case Qt::Key_Up: if (m_commandIndex > 0) { moveCursor(QTextCursor::End); moveCursor(QTextCursor::StartOfBlock); moveCursor(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); // the first KeyUp save the current command, possibly not completed yet // note: m_currentCommand is the whole line, containing the prompt if (m_commandIndex == m_commands.count()) m_currentCommand = textCursor().selectedText(); textCursor().insertText(m_prompt + m_commands[--m_commandIndex]); } break; case Qt::Key_Down: if (m_commandIndex < m_commands.count()) { moveCursor(QTextCursor::End); moveCursor(QTextCursor::StartOfBlock); moveCursor(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); if (m_commandIndex == m_commands.count() - 1) { // the last KeyDown insert back the current command, possibly not // completed yet textCursor().insertText(m_currentCommand); ++m_commandIndex; } else textCursor().insertText(m_prompt + m_commands[++m_commandIndex]); } break; case Qt::Key_Backspace: case Qt::Key_Left: if (textCursor().positionInBlock() > 3) QTextEdit::keyPressEvent(e); else e->ignore(); break; default: QTextEdit::keyPressEvent(e); } } void ScriptConsole::onCursorPositionChanged() { // only the last block (i.e. the current command) is editable setReadOnly(textCursor().block().next().isValid()); } bool ScriptConsole::canInsertFromMimeData(const QMimeData *source) const { if (source->hasText()) { QString text = source->text(); if (text.contains("\n")) return false; else return true; } else if (source->hasUrls() && source->urls().length() == 1) { return true; } else return false; } void ScriptConsole::insertFromMimeData(const QMimeData *source) { if (canInsertFromMimeData(source)) { if (source->hasText()) QTextEdit::insertFromMimeData(source); else if (source->hasUrls() && source->urls().length() == 1) { QUrl url = source->urls()[0]; QString text = url.toString(); if (url.isLocalFile()) text = url.toLocalFile(); text = "\"" + text.replace("\\", "\\\\").replace("\"", "\\\"") + "\""; textCursor().insertText(text); } } } void ScriptConsole::onReturnKeyPress() { int promptLength = m_prompt.length(); QTextCursor cursor = textCursor(); cursor.movePosition(QTextCursor::StartOfLine); cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, promptLength); cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); QString command = cursor.selectedText(); QTextCharFormat fmt; fmt.setForeground(QColor(120, 120, 120)); cursor.mergeCharFormat(fmt); cursor.clearSelection(); if (command.trimmed() != "") { int k = m_commands.indexOf(command); if (k < 0) m_commands.append(command); else if (k <= m_commands.length() - 1) { m_commands.takeAt(k); m_commands.append(command); } m_commandIndex = m_commands.count(); // m_currentCommand = m_prompt; } moveCursor(QTextCursor::EndOfLine); if (command.trimmed() != "") { append(""); cursor.movePosition(QTextCursor::StartOfBlock); m_engine->evaluate(command); } else { append(""); onEvaluationDone(); } } void ScriptConsole::onEvaluationDone() { moveCursor(QTextCursor::End); setTextColor(Qt::black); textCursor().insertText(m_prompt); moveCursor(QTextCursor::EndOfLine); } void ScriptConsole::output(int type, const QString &value) { moveCursor(QTextCursor::End); if (type == ScriptEngine::ExecutionError || type == ScriptEngine::SyntaxError) { setTextColor(Qt::red); } else if (type == ScriptEngine::UndefinedEvaluationResult || type == ScriptEngine::Warning) { setTextColor(QColor(250, 120, 40)); } else { setTextColor(QColor(10, 150, 240)); } textCursor().insertText(value + "\n"); moveCursor(QTextCursor::EndOfLine); } void ScriptConsole::executeCommand(const QString &cmd) { moveCursor(QTextCursor::End); setTextColor(Qt::black); append(m_prompt); moveCursor(QTextCursor::EndOfLine); textCursor().insertText(cmd); moveCursor(QTextCursor::EndOfLine); onReturnKeyPress(); }