forked from qt-creator/qt-creator
ScriptConsole: Move from Debugger to QmlJSTools
The console is now a part of qmljstools plugin. The console appears as an output pane. A dummy QScriptEngine evaluates expressions when a declarative debug session is not in progress. During a debug session, the expressions are evaluated by the debug services. Task-Number: QTCREATORBUG-7402 Change-Id: Ic2eeac44fb335c706be03b89f8672b0356efe984 Reviewed-by: Christiaan Janssen <christiaan.janssen@digia.com> Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
BIN
src/plugins/qmljstools/images/collapse.png
Normal file
BIN
src/plugins/qmljstools/images/collapse.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 986 B |
BIN
src/plugins/qmljstools/images/error.png
Normal file
BIN
src/plugins/qmljstools/images/error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/plugins/qmljstools/images/expand.png
Normal file
BIN
src/plugins/qmljstools/images/expand.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 997 B |
BIN
src/plugins/qmljstools/images/log.png
Normal file
BIN
src/plugins/qmljstools/images/log.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/plugins/qmljstools/images/prompt.png
Normal file
BIN
src/plugins/qmljstools/images/prompt.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
BIN
src/plugins/qmljstools/images/warning.png
Normal file
BIN
src/plugins/qmljstools/images/warning.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
233
src/plugins/qmljstools/qmlconsoleedit.cpp
Normal file
233
src/plugins/qmljstools/qmlconsoleedit.cpp
Normal file
@@ -0,0 +1,233 @@
|
||||
#include "qmlconsoleedit.h"
|
||||
#include "qmlconsoleitemmodel.h"
|
||||
#include "qmlconsolemanager.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QUrl>
|
||||
#include <QMenu>
|
||||
#include <QKeyEvent>
|
||||
|
||||
namespace QmlJSTools {
|
||||
namespace Internal {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// QmlConsoleEdit
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
QmlConsoleEdit::QmlConsoleEdit(const QModelIndex &index, QWidget *parent) :
|
||||
QTextEdit(parent),
|
||||
m_historyIndex(index),
|
||||
m_prompt(QLatin1String(":/qmljstools/images/prompt.png")),
|
||||
m_startOfEditableArea(0)
|
||||
{
|
||||
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();
|
||||
|
||||
ensureCursorVisible();
|
||||
setTextInteractionFlags(Qt::TextEditorInteraction);
|
||||
}
|
||||
|
||||
void QmlConsoleEdit::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
bool keyConsumed = false;
|
||||
|
||||
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()) {
|
||||
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());
|
||||
c.setPosition(m_startOfEditableArea);
|
||||
setTextCursor(c);
|
||||
keyConsumed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_Up:
|
||||
handleUpKey();
|
||||
keyConsumed = true;
|
||||
break;
|
||||
|
||||
case Qt::Key_Down:
|
||||
handleDownKey();
|
||||
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());
|
||||
c.setPosition(m_startOfEditableArea);
|
||||
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;
|
||||
}
|
||||
|
||||
if (!keyConsumed)
|
||||
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();
|
||||
}
|
||||
|
||||
void QmlConsoleEdit::handleUpKey()
|
||||
{
|
||||
QTC_ASSERT(m_historyIndex.isValid(), return);
|
||||
int currentRow = m_historyIndex.row();
|
||||
const QAbstractItemModel *model = m_historyIndex.model();
|
||||
if (currentRow == model->rowCount() - 1)
|
||||
m_cachedScript = getCurrentScript();
|
||||
|
||||
while (currentRow) {
|
||||
currentRow--;
|
||||
if (model->hasIndex(currentRow, 0)) {
|
||||
QModelIndex index = model->index(currentRow, 0);
|
||||
if (QmlConsoleItem::InputType == (QmlConsoleItem::ItemType)model->data(
|
||||
index, QmlConsoleItemModel::TypeRole).toInt()) {
|
||||
m_historyIndex = index;
|
||||
replaceCurrentScript(model->data(index, Qt::DisplayRole).toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QmlConsoleEdit::handleDownKey()
|
||||
{
|
||||
QTC_ASSERT(m_historyIndex.isValid(), return);
|
||||
int currentRow = m_historyIndex.row();
|
||||
const QAbstractItemModel *model = m_historyIndex.model();
|
||||
while (currentRow < model->rowCount() - 1) {
|
||||
currentRow++;
|
||||
if (model->hasIndex(currentRow, 0)) {
|
||||
QModelIndex index = model->index(currentRow, 0);
|
||||
if (QmlConsoleItem::InputType == (QmlConsoleItem::ItemType)model->data(
|
||||
index, QmlConsoleItemModel::TypeRole).toInt()) {
|
||||
m_historyIndex = index;
|
||||
if (currentRow == model->rowCount() - 1)
|
||||
replaceCurrentScript(m_cachedScript);
|
||||
else
|
||||
replaceCurrentScript(model->data(index, Qt::DisplayRole).toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString QmlConsoleEdit::getCurrentScript() const
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
cursor.setPosition(m_startOfEditableArea);
|
||||
cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
|
||||
QString script = cursor.selectedText();
|
||||
return script.trimmed();
|
||||
}
|
||||
|
||||
void QmlConsoleEdit::replaceCurrentScript(const QString &script)
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
cursor.setPosition(m_startOfEditableArea);
|
||||
cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
|
||||
cursor.removeSelectedText();
|
||||
cursor.insertText(script);
|
||||
setTextCursor(cursor);
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // QmlJSTools
|
||||
45
src/plugins/qmljstools/qmlconsoleedit.h
Normal file
45
src/plugins/qmljstools/qmlconsoleedit.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef QMLCONSOLEEDIT_H
|
||||
#define QMLCONSOLEEDIT_H
|
||||
|
||||
#include "qmljsinterpreter.h"
|
||||
|
||||
#include <QTextEdit>
|
||||
#include <QModelIndex>
|
||||
|
||||
namespace QmlJSTools {
|
||||
namespace Internal {
|
||||
|
||||
class QmlConsoleEdit : public QTextEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QmlConsoleEdit(const QModelIndex &index, QWidget *parent);
|
||||
|
||||
QString getCurrentScript() const;
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
void contextMenuEvent(QContextMenuEvent *event);
|
||||
void focusOutEvent(QFocusEvent *e);
|
||||
|
||||
signals:
|
||||
void editingFinished();
|
||||
|
||||
protected:
|
||||
void handleUpKey();
|
||||
void handleDownKey();
|
||||
|
||||
void replaceCurrentScript(const QString &script);
|
||||
|
||||
private:
|
||||
QModelIndex m_historyIndex;
|
||||
QString m_cachedScript;
|
||||
QImage m_prompt;
|
||||
int m_startOfEditableArea;
|
||||
QmlJSInterpreter m_interpreter;
|
||||
};
|
||||
|
||||
} // QmlJSTools
|
||||
} // Internal
|
||||
|
||||
#endif // QMLCONSOLEEDIT_H
|
||||
123
src/plugins/qmljstools/qmlconsoleitem.cpp
Normal file
123
src/plugins/qmljstools/qmlconsoleitem.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
#include "qmlconsoleitem.h"
|
||||
|
||||
namespace QmlJSTools {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// QmlConsoleItem
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
QmlConsoleItem::QmlConsoleItem(QmlConsoleItem *parent, QmlConsoleItem::ItemType itemType,
|
||||
const QString &text)
|
||||
: m_parentItem(parent),
|
||||
itemType(itemType),
|
||||
line(-1)
|
||||
|
||||
{
|
||||
setText(text);
|
||||
}
|
||||
|
||||
QmlConsoleItem::~QmlConsoleItem()
|
||||
{
|
||||
qDeleteAll(m_childItems);
|
||||
}
|
||||
|
||||
QmlConsoleItem *QmlConsoleItem::child(int number)
|
||||
{
|
||||
return m_childItems.value(number);
|
||||
}
|
||||
|
||||
int QmlConsoleItem::childCount() const
|
||||
{
|
||||
return m_childItems.size();
|
||||
}
|
||||
|
||||
int QmlConsoleItem::childNumber() const
|
||||
{
|
||||
if (m_parentItem)
|
||||
return m_parentItem->m_childItems.indexOf(const_cast<QmlConsoleItem *>(this));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool QmlConsoleItem::insertChildren(int position, int count)
|
||||
{
|
||||
if (position < 0 || position > m_childItems.size())
|
||||
return false;
|
||||
|
||||
for (int row = 0; row < count; ++row) {
|
||||
QmlConsoleItem *item = new QmlConsoleItem(this, QmlConsoleItem::UndefinedType,
|
||||
QString());
|
||||
m_childItems.insert(position, item);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QmlConsoleItem::insertChild(QmlConsoleItem *item, bool sorted)
|
||||
{
|
||||
if (!sorted) {
|
||||
m_childItems.insert(m_childItems.count(), item);
|
||||
return;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (; i < m_childItems.count(); i++) {
|
||||
if (item->m_text < m_childItems[i]->m_text)
|
||||
break;
|
||||
}
|
||||
m_childItems.insert(i, item);
|
||||
}
|
||||
|
||||
bool QmlConsoleItem::insertChild(int position, QmlConsoleItem *item)
|
||||
{
|
||||
if (position < 0 || position > m_childItems.size())
|
||||
return false;
|
||||
|
||||
m_childItems.insert(position, item);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QmlConsoleItem *QmlConsoleItem::parent()
|
||||
{
|
||||
return m_parentItem;
|
||||
}
|
||||
|
||||
bool QmlConsoleItem::removeChildren(int position, int count)
|
||||
{
|
||||
if (position < 0 || position + count > m_childItems.size())
|
||||
return false;
|
||||
|
||||
for (int row = 0; row < count; ++row)
|
||||
delete m_childItems.takeAt(position);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QmlConsoleItem::detachChild(int position)
|
||||
{
|
||||
if (position < 0 || position > m_childItems.size())
|
||||
return false;
|
||||
|
||||
m_childItems.removeAt(position);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QmlConsoleItem::setText(const QString &text)
|
||||
{
|
||||
m_text = text;
|
||||
for (int i = 0; i < m_text.length(); ++i) {
|
||||
if (m_text.at(i).isPunct())
|
||||
m_text.insert(++i, QChar(0x200b)); // ZERO WIDTH SPACE
|
||||
}
|
||||
}
|
||||
|
||||
const QString &QmlConsoleItem::text() const
|
||||
{
|
||||
return m_text;
|
||||
}
|
||||
|
||||
} // QmlJSTools
|
||||
55
src/plugins/qmljstools/qmlconsoleitem.h
Normal file
55
src/plugins/qmljstools/qmlconsoleitem.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef QMLCONSOLEITEM_H
|
||||
#define QMLCONSOLEITEM_H
|
||||
|
||||
#include "qmljstools_global.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
namespace QmlJSTools {
|
||||
|
||||
class QMLJSTOOLS_EXPORT QmlConsoleItem
|
||||
{
|
||||
public:
|
||||
enum ItemType
|
||||
{
|
||||
UndefinedType = 0x01, // Can be used for unknown and for Return values
|
||||
DebugType = 0x02,
|
||||
WarningType = 0x04,
|
||||
ErrorType = 0x08,
|
||||
InputType = 0x10,
|
||||
DefaultTypes = InputType | UndefinedType
|
||||
};
|
||||
Q_DECLARE_FLAGS(ItemTypes, ItemType)
|
||||
|
||||
QmlConsoleItem(QmlConsoleItem *parent,
|
||||
QmlConsoleItem::ItemType type = QmlConsoleItem::UndefinedType,
|
||||
const QString &data = QString());
|
||||
~QmlConsoleItem();
|
||||
|
||||
QmlConsoleItem *child(int number);
|
||||
int childCount() const;
|
||||
bool insertChildren(int position, int count);
|
||||
void insertChild(QmlConsoleItem *item, bool sorted);
|
||||
bool insertChild(int position, QmlConsoleItem *item);
|
||||
QmlConsoleItem *parent();
|
||||
bool removeChildren(int position, int count);
|
||||
bool detachChild(int position);
|
||||
int childNumber() const;
|
||||
void setText(const QString &text);
|
||||
const QString &text() const;
|
||||
|
||||
private:
|
||||
QmlConsoleItem *m_parentItem;
|
||||
QList<QmlConsoleItem *> m_childItems;
|
||||
QString m_text;
|
||||
|
||||
public:
|
||||
QmlConsoleItem::ItemType itemType;
|
||||
QString file;
|
||||
int line;
|
||||
};
|
||||
|
||||
} // QmlJSTools
|
||||
|
||||
#endif // QMLCONSOLEITEM_H
|
||||
341
src/plugins/qmljstools/qmlconsoleitemdelegate.cpp
Normal file
341
src/plugins/qmljstools/qmlconsoleitemdelegate.cpp
Normal file
@@ -0,0 +1,341 @@
|
||||
#include "qmlconsoleitemdelegate.h"
|
||||
#include "qmlconsoleedit.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QTreeView>
|
||||
#include <QScrollBar>
|
||||
|
||||
const char CONSOLE_LOG_BACKGROUND_COLOR[] = "#E8EEF2";
|
||||
const char CONSOLE_WARNING_BACKGROUND_COLOR[] = "#F6F4EB";
|
||||
const char CONSOLE_ERROR_BACKGROUND_COLOR[] = "#F6EBE7";
|
||||
const char CONSOLE_EDITOR_BACKGROUND_COLOR[] = "#F7F7F7";
|
||||
|
||||
const char CONSOLE_LOG_BACKGROUND_SELECTED_COLOR[] = "#CDDEEA";
|
||||
const char CONSOLE_WARNING_BACKGROUND_SELECTED_COLOR[] = "#F3EED1";
|
||||
const char CONSOLE_ERROR_BACKGROUND_SELECTED_COLOR[] = "#F5D4CB";
|
||||
const char CONSOLE_EDITOR_BACKGROUND_SELECTED_COLOR[] = "#DEDEDE";
|
||||
|
||||
const char CONSOLE_LOG_TEXT_COLOR[] = "#333333";
|
||||
const char CONSOLE_WARNING_TEXT_COLOR[] = "#666666";
|
||||
const char CONSOLE_ERROR_TEXT_COLOR[] = "#1D5B93";
|
||||
const char CONSOLE_EDITOR_TEXT_COLOR[] = "#000000";
|
||||
|
||||
const char CONSOLE_BORDER_COLOR[] = "#C9C9C9";
|
||||
|
||||
const int ELLIPSIS_GRADIENT_WIDTH = 16;
|
||||
|
||||
namespace QmlJSTools {
|
||||
namespace Internal {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// QmlConsoleItemDelegate
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
QmlConsoleItemDelegate::QmlConsoleItemDelegate(QObject *parent) :
|
||||
QStyledItemDelegate(parent),
|
||||
m_logIcon(QLatin1String(":/qmljstools/images/log.png")),
|
||||
m_warningIcon(QLatin1String(":/qmljstools/images/warning.png")),
|
||||
m_errorIcon(QLatin1String(":/qmljstools/images/error.png")),
|
||||
m_expandIcon(QLatin1String(":/qmljstools/images/expand.png")),
|
||||
m_collapseIcon(QLatin1String(":/qmljstools/images/collapse.png")),
|
||||
m_prompt(QLatin1String(":/qmljstools/images/prompt.png")),
|
||||
m_cachedHeight(0)
|
||||
{
|
||||
}
|
||||
|
||||
void QmlConsoleItemDelegate::emitSizeHintChanged(const QModelIndex &index)
|
||||
{
|
||||
emit sizeHintChanged(index);
|
||||
}
|
||||
|
||||
QColor QmlConsoleItemDelegate::drawBackground(QPainter *painter, const QRect &rect,
|
||||
const QModelIndex &index,
|
||||
bool selected) const
|
||||
{
|
||||
painter->save();
|
||||
QmlConsoleItem::ItemType itemType = (QmlConsoleItem::ItemType)index.data(
|
||||
QmlConsoleItemModel::TypeRole).toInt();
|
||||
QColor backgroundColor;
|
||||
switch (itemType) {
|
||||
case QmlConsoleItem::DebugType:
|
||||
backgroundColor = selected ? QColor(CONSOLE_LOG_BACKGROUND_SELECTED_COLOR) :
|
||||
QColor(CONSOLE_LOG_BACKGROUND_COLOR);
|
||||
break;
|
||||
case QmlConsoleItem::WarningType:
|
||||
backgroundColor = selected ? QColor(CONSOLE_WARNING_BACKGROUND_SELECTED_COLOR) :
|
||||
QColor(CONSOLE_WARNING_BACKGROUND_COLOR);
|
||||
break;
|
||||
case QmlConsoleItem::ErrorType:
|
||||
backgroundColor = selected ? QColor(CONSOLE_ERROR_BACKGROUND_SELECTED_COLOR) :
|
||||
QColor(CONSOLE_ERROR_BACKGROUND_COLOR);
|
||||
break;
|
||||
case QmlConsoleItem::InputType:
|
||||
default:
|
||||
backgroundColor = selected ? QColor(CONSOLE_EDITOR_BACKGROUND_SELECTED_COLOR) :
|
||||
QColor(CONSOLE_EDITOR_BACKGROUND_COLOR);
|
||||
break;
|
||||
}
|
||||
if (!(index.flags() & Qt::ItemIsEditable))
|
||||
painter->setBrush(backgroundColor);
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->drawRect(rect);
|
||||
|
||||
// Separator lines
|
||||
painter->setPen(QColor(CONSOLE_BORDER_COLOR));
|
||||
if (!(index.flags() & Qt::ItemIsEditable))
|
||||
painter->drawLine(0, rect.bottom(), rect.right(),
|
||||
rect.bottom());
|
||||
painter->restore();
|
||||
return backgroundColor;
|
||||
}
|
||||
|
||||
void QmlConsoleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QStyleOptionViewItemV4 opt = option;
|
||||
initStyleOption(&opt, index);
|
||||
painter->save();
|
||||
|
||||
// Set Colors
|
||||
QColor textColor;
|
||||
QIcon taskIcon;
|
||||
QmlConsoleItem::ItemType type = (QmlConsoleItem::ItemType)index.data(
|
||||
QmlConsoleItemModel::TypeRole).toInt();
|
||||
switch (type) {
|
||||
case QmlConsoleItem::DebugType:
|
||||
textColor = QColor(CONSOLE_LOG_TEXT_COLOR);
|
||||
taskIcon = m_logIcon;
|
||||
break;
|
||||
case QmlConsoleItem::WarningType:
|
||||
textColor = QColor(CONSOLE_WARNING_TEXT_COLOR);
|
||||
taskIcon = m_warningIcon;
|
||||
break;
|
||||
case QmlConsoleItem::ErrorType:
|
||||
textColor = QColor(CONSOLE_ERROR_TEXT_COLOR);
|
||||
taskIcon = m_errorIcon;
|
||||
break;
|
||||
case QmlConsoleItem::InputType:
|
||||
textColor = QColor(CONSOLE_EDITOR_TEXT_COLOR);
|
||||
taskIcon = m_prompt;
|
||||
break;
|
||||
default:
|
||||
textColor = QColor(CONSOLE_EDITOR_TEXT_COLOR);
|
||||
break;
|
||||
}
|
||||
|
||||
// Paint background
|
||||
QColor backgroundColor = drawBackground(painter, opt.rect, index,
|
||||
bool(opt.state & QStyle::State_Selected));
|
||||
|
||||
// Calculate positions
|
||||
const QTreeView *view = qobject_cast<const QTreeView *>(opt.widget);
|
||||
int level = 0;
|
||||
QModelIndex idx(index);
|
||||
while (idx.parent() != QModelIndex()) {
|
||||
idx = idx.parent();
|
||||
level++;
|
||||
}
|
||||
int width = view->width() - level * view->indentation() - view->verticalScrollBar()->width();
|
||||
bool showTypeIcon = index.parent() == QModelIndex();
|
||||
bool showExpandableIcon = type == QmlConsoleItem::UndefinedType;
|
||||
|
||||
QRect rect(opt.rect.x(), opt.rect.top(), width, opt.rect.height());
|
||||
ConsoleItemPositions positions(rect, opt.font, showTypeIcon, showExpandableIcon);
|
||||
|
||||
// Paint TaskIconArea:
|
||||
if (showTypeIcon)
|
||||
painter->drawPixmap(positions.adjustedLeft(), positions.adjustedTop(),
|
||||
taskIcon.pixmap(positions.typeIconWidth(),
|
||||
positions.typeIconHeight()));
|
||||
|
||||
// Set Text Color
|
||||
painter->setPen(textColor);
|
||||
// Paint TextArea:
|
||||
// Layout the description
|
||||
QString str = index.data(Qt::DisplayRole).toString();
|
||||
bool showFileLineInfo = true;
|
||||
// show complete text if selected
|
||||
if (view->selectionModel()->currentIndex() == index) {
|
||||
QTextLayout tl(str, opt.font);
|
||||
layoutText(tl, positions.textAreaWidth(), &showFileLineInfo);
|
||||
tl.draw(painter, QPoint(positions.textAreaLeft(), positions.adjustedTop()));
|
||||
} else {
|
||||
QFontMetrics fm(opt.font);
|
||||
painter->drawText(positions.textArea(), fm.elidedText(str, Qt::ElideRight,
|
||||
positions.textAreaWidth()));
|
||||
}
|
||||
// skip if area is editable
|
||||
if (showExpandableIcon) {
|
||||
// Paint ExpandableIconArea:
|
||||
QIcon expandCollapseIcon;
|
||||
if (index.model()->rowCount(index)) {
|
||||
if (view->isExpanded(index))
|
||||
expandCollapseIcon = m_collapseIcon;
|
||||
else
|
||||
expandCollapseIcon = m_expandIcon;
|
||||
}
|
||||
painter->drawPixmap(positions.expandCollapseIconLeft(), positions.adjustedTop(),
|
||||
expandCollapseIcon.pixmap(positions.expandCollapseIconWidth(),
|
||||
positions.expandCollapseIconHeight()));
|
||||
}
|
||||
|
||||
if (showFileLineInfo) {
|
||||
// Check for file info
|
||||
QString file = index.data(QmlConsoleItemModel::FileRole).toString();
|
||||
if (!file.isEmpty()) {
|
||||
QFontMetrics fm(option.font);
|
||||
// Paint FileArea
|
||||
const int pos = file.lastIndexOf(QLatin1Char('/'));
|
||||
if (pos != -1)
|
||||
file = file.mid(pos +1);
|
||||
const int realFileWidth = fm.width(file);
|
||||
painter->setClipRect(positions.fileArea());
|
||||
painter->drawText(positions.fileAreaLeft(), positions.adjustedTop() + fm.ascent(),
|
||||
file);
|
||||
if (realFileWidth > positions.fileAreaWidth()) {
|
||||
// draw a gradient to mask the text
|
||||
int gradientStart = positions.fileAreaLeft() - 1;
|
||||
QLinearGradient lg(gradientStart + ELLIPSIS_GRADIENT_WIDTH, 0, gradientStart, 0);
|
||||
lg.setColorAt(0, Qt::transparent);
|
||||
lg.setColorAt(1, backgroundColor);
|
||||
painter->fillRect(gradientStart, positions.adjustedTop(),
|
||||
ELLIPSIS_GRADIENT_WIDTH, positions.lineHeight(), lg);
|
||||
}
|
||||
|
||||
// Paint LineArea
|
||||
QString lineText = index.data(QmlConsoleItemModel::LineRole).toString();
|
||||
painter->setClipRect(positions.lineArea());
|
||||
const int realLineWidth = fm.width(lineText);
|
||||
painter->drawText(positions.lineAreaRight() - realLineWidth,
|
||||
positions.adjustedTop() + fm.ascent(), lineText);
|
||||
}
|
||||
}
|
||||
painter->setClipRect(opt.rect);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QSize QmlConsoleItemDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QStyleOptionViewItemV4 opt = option;
|
||||
initStyleOption(&opt, index);
|
||||
|
||||
const QTreeView *view = qobject_cast<const QTreeView *>(opt.widget);
|
||||
int level = 0;
|
||||
QModelIndex idx(index);
|
||||
while (idx.parent() != QModelIndex()) {
|
||||
idx = idx.parent();
|
||||
level++;
|
||||
}
|
||||
int width = view->width() - level * view->indentation() - view->verticalScrollBar()->width();
|
||||
if (index.flags() & Qt::ItemIsEditable)
|
||||
return QSize(width, view->height() * 1/2);
|
||||
|
||||
const bool selected = (view->selectionModel()->currentIndex() == index);
|
||||
if (!selected && option.font == m_cachedFont && m_cachedHeight > 0)
|
||||
return QSize(width, m_cachedHeight);
|
||||
|
||||
QmlConsoleItem::ItemType type = (QmlConsoleItem::ItemType)index.data(
|
||||
QmlConsoleItemModel::TypeRole).toInt();
|
||||
bool showTypeIcon = index.parent() == QModelIndex();
|
||||
bool showExpandableIcon = type == QmlConsoleItem::UndefinedType;
|
||||
|
||||
QRect rect(level * view->indentation(), 0, width, 0);
|
||||
ConsoleItemPositions positions(rect, opt.font, showTypeIcon, showExpandableIcon);
|
||||
|
||||
QFontMetrics fm(option.font);
|
||||
qreal height = fm.height();
|
||||
|
||||
if (selected) {
|
||||
QString str = index.data(Qt::DisplayRole).toString();
|
||||
|
||||
QTextLayout tl(str, option.font);
|
||||
height = layoutText(tl, positions.textAreaWidth());
|
||||
}
|
||||
|
||||
height += 2 * ConsoleItemPositions::ITEM_PADDING;
|
||||
|
||||
if (height < positions.minimumHeight())
|
||||
height = positions.minimumHeight();
|
||||
|
||||
if (!selected) {
|
||||
m_cachedHeight = height;
|
||||
m_cachedFont = option.font;
|
||||
}
|
||||
|
||||
return QSize(width, height);
|
||||
}
|
||||
|
||||
QWidget *QmlConsoleItemDelegate::createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem &/*option*/,
|
||||
const QModelIndex &index) const
|
||||
|
||||
{
|
||||
QmlConsoleEdit *editor = new QmlConsoleEdit(index, parent);
|
||||
connect(editor, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor()));
|
||||
return editor;
|
||||
}
|
||||
|
||||
void QmlConsoleItemDelegate::setEditorData(QWidget *editor,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QmlConsoleEdit *edtr = qobject_cast<QmlConsoleEdit *>(editor);
|
||||
edtr->insertPlainText(index.data(Qt::DisplayRole).toString());
|
||||
}
|
||||
|
||||
void QmlConsoleItemDelegate::setModelData(QWidget *editor,
|
||||
QAbstractItemModel *model,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QmlConsoleEdit *edtr = qobject_cast<QmlConsoleEdit *>(editor);
|
||||
model->setData(index, edtr->getCurrentScript(), Qt::DisplayRole);
|
||||
model->setData(index, QmlConsoleItem::InputType, QmlConsoleItemModel::TypeRole);
|
||||
}
|
||||
|
||||
void QmlConsoleItemDelegate::updateEditorGeometry(QWidget *editor,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &/*index*/) const
|
||||
{
|
||||
QStyleOptionViewItemV4 opt = option;
|
||||
editor->setGeometry(QRect(opt.rect.x(), opt.rect.top(), opt.rect.width(), opt.rect.bottom()));
|
||||
}
|
||||
|
||||
void QmlConsoleItemDelegate::currentChanged(const QModelIndex ¤t,
|
||||
const QModelIndex &previous)
|
||||
{
|
||||
emit sizeHintChanged(current);
|
||||
emit sizeHintChanged(previous);
|
||||
}
|
||||
|
||||
void QmlConsoleItemDelegate::commitAndCloseEditor()
|
||||
{
|
||||
QmlConsoleEdit *editor = qobject_cast<QmlConsoleEdit *>(sender());
|
||||
emit commitData(editor);
|
||||
emit closeEditor(editor);
|
||||
}
|
||||
|
||||
qreal QmlConsoleItemDelegate::layoutText(QTextLayout &tl, int width,
|
||||
bool *showFileLineInfo) const
|
||||
{
|
||||
qreal height = 0;
|
||||
tl.beginLayout();
|
||||
while (true) {
|
||||
QTextLine line = tl.createLine();
|
||||
|
||||
if (!line.isValid())
|
||||
break;
|
||||
line.setLeadingIncluded(true);
|
||||
line.setLineWidth(width);
|
||||
if (width < line.naturalTextWidth() && showFileLineInfo)
|
||||
*showFileLineInfo = false;
|
||||
line.setPosition(QPoint(0, height));
|
||||
height += line.height();
|
||||
}
|
||||
tl.endLayout();
|
||||
return height;
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // QmlJSTools
|
||||
152
src/plugins/qmljstools/qmlconsoleitemdelegate.h
Normal file
152
src/plugins/qmljstools/qmlconsoleitemdelegate.h
Normal file
@@ -0,0 +1,152 @@
|
||||
#ifndef QMLCONSOLEITEMDELEGATE_H
|
||||
#define QMLCONSOLEITEMDELEGATE_H
|
||||
|
||||
#include "qmlconsoleitemmodel.h"
|
||||
#include "qmlconsolemanager.h"
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QTextLayout>
|
||||
|
||||
namespace QmlJSTools {
|
||||
namespace Internal {
|
||||
|
||||
class QmlConsoleItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QmlConsoleItemDelegate(QObject *parent);
|
||||
|
||||
void emitSizeHintChanged(const QModelIndex &index);
|
||||
QColor drawBackground(QPainter *painter, const QRect &rect, const QModelIndex &index,
|
||||
bool selected) const;
|
||||
|
||||
public slots:
|
||||
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
|
||||
protected:
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const;
|
||||
QSize sizeHint(const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const;
|
||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const;
|
||||
void setEditorData(QWidget *editor, const QModelIndex &index) const;
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
|
||||
|
||||
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const;
|
||||
|
||||
private slots:
|
||||
void commitAndCloseEditor();
|
||||
|
||||
private:
|
||||
qreal layoutText(QTextLayout &tl, int width, bool *success = 0) const;
|
||||
|
||||
private:
|
||||
const QIcon m_logIcon;
|
||||
const QIcon m_warningIcon;
|
||||
const QIcon m_errorIcon;
|
||||
const QIcon m_expandIcon;
|
||||
const QIcon m_collapseIcon;
|
||||
const QIcon m_prompt;
|
||||
mutable int m_cachedHeight;
|
||||
mutable QFont m_cachedFont;
|
||||
};
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| TYPEICONAREA EXPANDABLEICONAREA TEXTAREA FILEAREA LINEAREA |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
*/
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| PROMPTAREA EDITABLEAREA |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
*/
|
||||
class ConsoleItemPositions
|
||||
{
|
||||
public:
|
||||
ConsoleItemPositions(const QRect &rect, const QFont &font, bool showTaskIconArea,
|
||||
bool showExpandableIconArea)
|
||||
: m_x(rect.x()),
|
||||
m_width(rect.width()),
|
||||
m_top(rect.top()),
|
||||
m_bottom(rect.bottom()),
|
||||
m_maxFileLength(0),
|
||||
m_maxLineLength(0),
|
||||
m_showTaskIconArea(showTaskIconArea),
|
||||
m_showExpandableIconArea(showExpandableIconArea)
|
||||
{
|
||||
m_fontHeight = QFontMetrics(font).height();
|
||||
QmlConsoleItemModel *model = QmlConsoleModel::qmlConsoleItemModel();
|
||||
m_maxFileLength = model->sizeOfFile(font);
|
||||
m_maxLineLength = model->sizeOfLineNumber(font);
|
||||
}
|
||||
|
||||
int adjustedTop() const { return m_top + ITEM_PADDING; }
|
||||
int adjustedLeft() const { return m_x + ITEM_PADDING; }
|
||||
int adjustedRight() const { return m_width - ITEM_PADDING; }
|
||||
int adjustedBottom() const { return m_bottom; }
|
||||
int lineHeight() const { return m_fontHeight + 1; }
|
||||
int minimumHeight() const { return typeIconHeight() + 2 * ITEM_PADDING; }
|
||||
|
||||
// PROMPTAREA is same as TYPEICONAREA
|
||||
int typeIconLeft() const { return adjustedLeft(); }
|
||||
int typeIconWidth() const { return TASK_ICON_SIZE; }
|
||||
int typeIconHeight() const { return TASK_ICON_SIZE; }
|
||||
int typeIconRight() const { return m_showTaskIconArea ? typeIconLeft() + typeIconWidth()
|
||||
: adjustedLeft(); }
|
||||
QRect typeIcon() const { return QRect(typeIconLeft(), adjustedTop(), typeIconWidth(),
|
||||
typeIconHeight()); }
|
||||
|
||||
int expandCollapseIconLeft() const { return typeIconRight() + ITEM_SPACING; }
|
||||
int expandCollapseIconWidth() const { return TASK_ICON_SIZE; }
|
||||
int expandCollapseIconHeight() const { return TASK_ICON_SIZE; }
|
||||
int expandCollapseIconRight() const { return m_showExpandableIconArea ?
|
||||
expandCollapseIconLeft() + expandCollapseIconWidth() : typeIconRight(); }
|
||||
QRect expandCollapseIcon() const { return QRect(expandCollapseIconLeft(), adjustedTop(),
|
||||
expandCollapseIconWidth(),
|
||||
expandCollapseIconHeight()); }
|
||||
|
||||
int textAreaLeft() const { return expandCollapseIconRight() + ITEM_SPACING; }
|
||||
int textAreaWidth() const { return textAreaRight() - textAreaLeft(); }
|
||||
int textAreaRight() const { return fileAreaLeft() - ITEM_SPACING; }
|
||||
QRect textArea() const { return QRect(textAreaLeft(), adjustedTop(), textAreaWidth(),
|
||||
lineHeight()); }
|
||||
|
||||
int fileAreaLeft() const { return fileAreaRight() - fileAreaWidth(); }
|
||||
int fileAreaWidth() const { return m_maxFileLength; }
|
||||
int fileAreaRight() const { return lineAreaLeft() - ITEM_SPACING; }
|
||||
QRect fileArea() const { return QRect(fileAreaLeft(), adjustedTop(), fileAreaWidth(),
|
||||
lineHeight()); }
|
||||
|
||||
int lineAreaLeft() const { return lineAreaRight() - lineAreaWidth(); }
|
||||
int lineAreaWidth() const { return m_maxLineLength; }
|
||||
int lineAreaRight() const { return adjustedRight() - ITEM_SPACING; }
|
||||
QRect lineArea() const { return QRect(lineAreaLeft(), adjustedTop(), lineAreaWidth(),
|
||||
lineHeight()); }
|
||||
|
||||
private:
|
||||
int m_x;
|
||||
int m_width;
|
||||
int m_top;
|
||||
int m_bottom;
|
||||
int m_fontHeight;
|
||||
int m_maxFileLength;
|
||||
int m_maxLineLength;
|
||||
bool m_showTaskIconArea;
|
||||
bool m_showExpandableIconArea;
|
||||
|
||||
public:
|
||||
static const int TASK_ICON_SIZE = 16;
|
||||
static const int ITEM_PADDING = 8;
|
||||
static const int ITEM_SPACING = 4;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QmlJSTools
|
||||
|
||||
#endif // QMLCONSOLEITEMDELEGATE_H
|
||||
252
src/plugins/qmljstools/qmlconsoleitemmodel.cpp
Normal file
252
src/plugins/qmljstools/qmlconsoleitemmodel.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
#include "qmlconsoleitemmodel.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QFontMetrics>
|
||||
|
||||
namespace QmlJSTools {
|
||||
namespace Internal {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// QmlConsoleItemModel
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
QmlConsoleItemModel::QmlConsoleItemModel(QObject *parent) :
|
||||
QAbstractItemModel(parent),
|
||||
m_hasEditableRow(false),
|
||||
m_rootItem(new QmlConsoleItem(0)),
|
||||
m_maxSizeOfFileName(0)
|
||||
{
|
||||
}
|
||||
|
||||
QmlConsoleItemModel::~QmlConsoleItemModel()
|
||||
{
|
||||
delete m_rootItem;
|
||||
}
|
||||
|
||||
void QmlConsoleItemModel::clear()
|
||||
{
|
||||
beginResetModel();
|
||||
reset();
|
||||
delete m_rootItem;
|
||||
m_rootItem = new QmlConsoleItem(0);
|
||||
endResetModel();
|
||||
|
||||
if (m_hasEditableRow)
|
||||
appendEditableRow();
|
||||
}
|
||||
|
||||
bool QmlConsoleItemModel::appendItem(QmlConsoleItem *item, int position)
|
||||
{
|
||||
if (position < 0)
|
||||
position = m_rootItem->childCount() - 1;
|
||||
|
||||
if (position < 0)
|
||||
position = 0;
|
||||
|
||||
beginInsertRows(QModelIndex(), position, position);
|
||||
bool success = m_rootItem->insertChild(position, item);
|
||||
endInsertRows();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool QmlConsoleItemModel::appendMessage(QmlConsoleItem::ItemType itemType,
|
||||
const QString &message, int position)
|
||||
{
|
||||
return appendItem(new QmlConsoleItem(m_rootItem, itemType, message), position);
|
||||
}
|
||||
|
||||
void QmlConsoleItemModel::setHasEditableRow(bool hasEditableRow)
|
||||
{
|
||||
if (m_hasEditableRow && !hasEditableRow)
|
||||
removeEditableRow();
|
||||
|
||||
if (!m_hasEditableRow && hasEditableRow)
|
||||
appendEditableRow();
|
||||
|
||||
m_hasEditableRow = hasEditableRow;
|
||||
}
|
||||
|
||||
bool QmlConsoleItemModel::hasEditableRow() const
|
||||
{
|
||||
return m_hasEditableRow;
|
||||
}
|
||||
|
||||
void QmlConsoleItemModel::appendEditableRow()
|
||||
{
|
||||
int position = m_rootItem->childCount();
|
||||
if (appendItem(new QmlConsoleItem(m_rootItem, QmlConsoleItem::InputType), position))
|
||||
emit selectEditableRow(index(position, 0), QItemSelectionModel::ClearAndSelect);
|
||||
}
|
||||
|
||||
void QmlConsoleItemModel::removeEditableRow()
|
||||
{
|
||||
if (m_rootItem->child(m_rootItem->childCount() - 1)->itemType == QmlConsoleItem::InputType)
|
||||
removeRow(m_rootItem->childCount() - 1);
|
||||
}
|
||||
|
||||
int QmlConsoleItemModel::sizeOfFile(const QFont &font)
|
||||
{
|
||||
int lastReadOnlyRow = m_rootItem->childCount();
|
||||
if (m_hasEditableRow)
|
||||
lastReadOnlyRow -= 2;
|
||||
else
|
||||
lastReadOnlyRow -= 1;
|
||||
if (lastReadOnlyRow < 0)
|
||||
return 0;
|
||||
QString filename = m_rootItem->child(lastReadOnlyRow)->file;
|
||||
const int pos = filename.lastIndexOf(QLatin1Char('/'));
|
||||
if (pos != -1)
|
||||
filename = filename.mid(pos + 1);
|
||||
|
||||
QFontMetrics fm(font);
|
||||
m_maxSizeOfFileName = qMax(m_maxSizeOfFileName, fm.width(filename));
|
||||
|
||||
return m_maxSizeOfFileName;
|
||||
}
|
||||
|
||||
int QmlConsoleItemModel::sizeOfLineNumber(const QFont &font)
|
||||
{
|
||||
QFontMetrics fm(font);
|
||||
return fm.width(QLatin1String("88888"));
|
||||
}
|
||||
|
||||
QVariant QmlConsoleItemModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
QmlConsoleItem *item = getItem(index);
|
||||
|
||||
if (role == Qt::DisplayRole )
|
||||
return item->text();
|
||||
else if (role == QmlConsoleItemModel::TypeRole)
|
||||
return int(item->itemType);
|
||||
else if (role == QmlConsoleItemModel::FileRole)
|
||||
return item->file;
|
||||
else if (role == QmlConsoleItemModel::LineRole)
|
||||
return item->line;
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex QmlConsoleItemModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid() && parent.column() != 0)
|
||||
return QModelIndex();
|
||||
|
||||
if (column > 0)
|
||||
return QModelIndex();
|
||||
|
||||
QmlConsoleItem *parentItem = getItem(parent);
|
||||
|
||||
QmlConsoleItem *childItem = parentItem->child(row);
|
||||
if (childItem)
|
||||
return createIndex(row, column, childItem);
|
||||
else
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex QmlConsoleItemModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
QmlConsoleItem *childItem = getItem(index);
|
||||
QmlConsoleItem *parentItem = childItem->parent();
|
||||
|
||||
if (parentItem == m_rootItem)
|
||||
return QModelIndex();
|
||||
|
||||
if (!parentItem)
|
||||
return QModelIndex();
|
||||
return createIndex(parentItem->childNumber(), 0, parentItem);
|
||||
}
|
||||
|
||||
int QmlConsoleItemModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
QmlConsoleItem *parentItem = getItem(parent);
|
||||
|
||||
return parentItem->childCount();
|
||||
}
|
||||
|
||||
int QmlConsoleItemModel::columnCount(const QModelIndex & /* parent */) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
Qt::ItemFlags QmlConsoleItemModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
|
||||
QmlConsoleItem *item = getItem(index);
|
||||
if (m_hasEditableRow && item->parent() == m_rootItem
|
||||
&& index.row() == m_rootItem->childCount() - 1)
|
||||
return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
}
|
||||
|
||||
bool QmlConsoleItemModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
QmlConsoleItem *item = getItem(index);
|
||||
bool result = false;
|
||||
if (role == Qt::DisplayRole) {
|
||||
item->setText(value.toString());
|
||||
result = true;
|
||||
} else if (role == QmlConsoleItemModel::TypeRole) {
|
||||
item->itemType = (QmlConsoleItem::ItemType)value.toInt();
|
||||
result = true;
|
||||
} else if (role == QmlConsoleItemModel::FileRole) {
|
||||
item->file = value.toString();
|
||||
result = true;
|
||||
} else if (role == QmlConsoleItemModel::LineRole) {
|
||||
item->line = value.toInt();
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (result)
|
||||
emit dataChanged(index, index);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QmlConsoleItemModel::insertRows(int position, int rows, const QModelIndex &parent)
|
||||
{
|
||||
QmlConsoleItem *parentItem = getItem(parent);
|
||||
bool success;
|
||||
|
||||
beginInsertRows(parent, position, position + rows - 1);
|
||||
success = parentItem->insertChildren(position, rows);
|
||||
endInsertRows();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool QmlConsoleItemModel::removeRows(int position, int rows, const QModelIndex &parent)
|
||||
{
|
||||
QmlConsoleItem *parentItem = getItem(parent);
|
||||
bool success = true;
|
||||
|
||||
beginRemoveRows(parent, position, position + rows - 1);
|
||||
success = parentItem->removeChildren(position, rows);
|
||||
endRemoveRows();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
QmlConsoleItem *QmlConsoleItemModel::getItem(const QModelIndex &index) const
|
||||
{
|
||||
if (index.isValid()) {
|
||||
QmlConsoleItem *item = static_cast<QmlConsoleItem*>(index.internalPointer());
|
||||
if (item)
|
||||
return item;
|
||||
}
|
||||
return m_rootItem;
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // QmlJSTools
|
||||
73
src/plugins/qmljstools/qmlconsoleitemmodel.h
Normal file
73
src/plugins/qmljstools/qmlconsoleitemmodel.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#ifndef QMLCONSOLEITEMMODEL_H
|
||||
#define QMLCONSOLEITEMMODEL_H
|
||||
|
||||
#include "qmlconsoleitem.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QItemSelectionModel>
|
||||
#include <QFont>
|
||||
|
||||
namespace QmlJSTools {
|
||||
namespace Internal {
|
||||
|
||||
class QmlConsoleItemModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Roles { TypeRole = Qt::UserRole, FileRole, LineRole };
|
||||
|
||||
explicit QmlConsoleItemModel(QObject *parent = 0);
|
||||
~QmlConsoleItemModel();
|
||||
|
||||
void setHasEditableRow(bool hasEditableRow);
|
||||
bool hasEditableRow() const;
|
||||
void appendEditableRow();
|
||||
void removeEditableRow();
|
||||
|
||||
bool appendItem(QmlConsoleItem *item, int position = -1);
|
||||
bool appendMessage(QmlConsoleItem::ItemType itemType, const QString &message,
|
||||
int position = -1);
|
||||
|
||||
QAbstractItemModel *model() { return this; }
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
|
||||
int sizeOfFile(const QFont &font);
|
||||
int sizeOfLineNumber(const QFont &font);
|
||||
|
||||
QmlConsoleItem *root() const { return m_rootItem; }
|
||||
|
||||
public slots:
|
||||
void clear();
|
||||
|
||||
signals:
|
||||
void selectEditableRow(const QModelIndex &index, QItemSelectionModel::SelectionFlags flags);
|
||||
void rowInserted(const QModelIndex &index);
|
||||
|
||||
protected:
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
|
||||
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
|
||||
|
||||
bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex());
|
||||
bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex());
|
||||
|
||||
QmlConsoleItem *getItem(const QModelIndex &index) const;
|
||||
|
||||
private:
|
||||
bool m_hasEditableRow;
|
||||
QmlConsoleItem *m_rootItem;
|
||||
int m_maxSizeOfFileName;
|
||||
};
|
||||
|
||||
} // Internal
|
||||
} // QmlJSTools
|
||||
|
||||
#endif // QMLCONSOLEITEMMODEL_H
|
||||
162
src/plugins/qmljstools/qmlconsolemanager.cpp
Normal file
162
src/plugins/qmljstools/qmlconsolemanager.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
#include "qmlconsolemanager.h"
|
||||
#include "qmlconsolepane.h"
|
||||
#include "qmlconsoleitemmodel.h"
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <debugger/debuggerengine.h>
|
||||
|
||||
#include <QScriptEngine>
|
||||
#include <QVariant>
|
||||
|
||||
namespace QmlJSTools {
|
||||
|
||||
QmlConsoleManager *QmlConsoleManager::m_instance = 0;
|
||||
|
||||
class QmlConsoleManagerPrivate
|
||||
{
|
||||
public:
|
||||
QScriptEngine *scriptEngine;
|
||||
Internal::QmlConsoleItemModel *qmlConsoleItemModel;
|
||||
Internal::QmlConsolePane *qmlConsolePane;
|
||||
Debugger::DebuggerEngine *debuggerEngine;
|
||||
};
|
||||
|
||||
QmlConsoleManager::QmlConsoleManager(QObject *parent)
|
||||
: QObject(parent),
|
||||
d(new QmlConsoleManagerPrivate)
|
||||
{
|
||||
m_instance = this;
|
||||
d->scriptEngine = new QScriptEngine(this);
|
||||
d->qmlConsoleItemModel = new Internal::QmlConsoleItemModel(this);
|
||||
d->qmlConsoleItemModel->setHasEditableRow(true);
|
||||
d->qmlConsolePane = new Internal::QmlConsolePane(this);
|
||||
ExtensionSystem::PluginManager::addObject(d->qmlConsolePane);
|
||||
d->debuggerEngine = 0;
|
||||
}
|
||||
|
||||
QmlConsoleManager::~QmlConsoleManager()
|
||||
{
|
||||
if (d->qmlConsolePane) {
|
||||
ExtensionSystem::PluginManager::removeObject(d->qmlConsolePane);
|
||||
}
|
||||
delete d;
|
||||
m_instance = 0;
|
||||
}
|
||||
|
||||
void QmlConsoleManager::showConsolePane()
|
||||
{
|
||||
if (d->qmlConsolePane)
|
||||
d->qmlConsolePane->popup(Core::IOutputPane::ModeSwitch);
|
||||
}
|
||||
|
||||
QmlConsoleItem *QmlConsoleManager::rootItem() const
|
||||
{
|
||||
return d->qmlConsoleItemModel->root();
|
||||
}
|
||||
|
||||
void QmlConsoleManager::setDebuggerEngine(Debugger::DebuggerEngine *debuggerEngine)
|
||||
{
|
||||
d->debuggerEngine = debuggerEngine;
|
||||
}
|
||||
|
||||
void QmlConsoleManager::setContext(const QString &context)
|
||||
{
|
||||
d->qmlConsolePane->setContext(context);
|
||||
}
|
||||
|
||||
void QmlConsoleManager::printToConsolePane(QmlConsoleItem::ItemType itemType,
|
||||
const QString &text, bool bringToForeground)
|
||||
{
|
||||
if (!d->qmlConsolePane)
|
||||
return;
|
||||
if (itemType == QmlConsoleItem::ErrorType)
|
||||
bringToForeground = true;
|
||||
if (bringToForeground)
|
||||
d->qmlConsolePane->popup(Core::IOutputPane::ModeSwitch);
|
||||
d->qmlConsoleItemModel->appendMessage(itemType, text);
|
||||
}
|
||||
|
||||
void QmlConsoleManager::printToConsolePane(QmlConsoleItem *item, bool bringToForeground)
|
||||
{
|
||||
if (!d->qmlConsolePane)
|
||||
return;
|
||||
if (item->itemType == QmlConsoleItem::ErrorType)
|
||||
bringToForeground = true;
|
||||
if (bringToForeground)
|
||||
d->qmlConsolePane->popup(Core::IOutputPane::ModeSwitch);
|
||||
d->qmlConsoleItemModel->appendItem(item);
|
||||
}
|
||||
|
||||
namespace Internal {
|
||||
|
||||
QmlConsoleItem *constructLogItemTree(QmlConsoleItem *parent, const QVariant &result,
|
||||
const QString &key = QString())
|
||||
{
|
||||
if (!result.isValid())
|
||||
return 0;
|
||||
|
||||
QmlConsoleItem *item = new QmlConsoleItem(parent);
|
||||
if (result.type() == QVariant::Map) {
|
||||
if (key.isEmpty())
|
||||
item->setText(QLatin1String("Object"));
|
||||
else
|
||||
item->setText(key + QLatin1String(" : Object"));
|
||||
|
||||
QMapIterator<QString, QVariant> i(result.toMap());
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
QmlConsoleItem *child = constructLogItemTree(item, i.value(), i.key());
|
||||
if (child)
|
||||
item->insertChild(child, true);
|
||||
}
|
||||
} else if (result.type() == QVariant::List) {
|
||||
if (key.isEmpty())
|
||||
item->setText(QLatin1String("List"));
|
||||
else
|
||||
item->setText(QString(QLatin1String("[%1] : List")).arg(key));
|
||||
QVariantList resultList = result.toList();
|
||||
for (int i = 0; i < resultList.count(); i++) {
|
||||
QmlConsoleItem *child = constructLogItemTree(item, resultList.at(i),
|
||||
QString::number(i));
|
||||
if (child)
|
||||
item->insertChild(child, true);
|
||||
}
|
||||
} else if (result.canConvert(QVariant::String)) {
|
||||
item->setText(result.toString());
|
||||
} else {
|
||||
item->setText(QLatin1String("Unknown Value"));
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
QmlConsoleItemModel *QmlConsoleModel::qmlConsoleItemModel()
|
||||
{
|
||||
QmlConsoleManager *manager = QmlConsoleManager::instance();
|
||||
if (manager)
|
||||
return manager->d->qmlConsoleItemModel;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QmlConsoleModel::evaluate(const QString &expression)
|
||||
{
|
||||
QmlConsoleManager *manager = QmlConsoleManager::instance();
|
||||
if (manager) {
|
||||
if (manager->d->debuggerEngine) {
|
||||
QmlConsoleModel::qmlConsoleItemModel()->appendEditableRow();
|
||||
manager->d->debuggerEngine->evaluateScriptExpression(expression);
|
||||
} else {
|
||||
QVariant result = manager->d->scriptEngine->evaluate(expression).toVariant();
|
||||
QmlConsoleItem *root = manager->rootItem();
|
||||
QmlConsoleItem *item = constructLogItemTree(root, result);
|
||||
if (item) {
|
||||
QmlConsoleModel::qmlConsoleItemModel()->appendEditableRow();
|
||||
manager->printToConsolePane(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // QmlJSTools
|
||||
59
src/plugins/qmljstools/qmlconsolemanager.h
Normal file
59
src/plugins/qmljstools/qmlconsolemanager.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef QMLCONSOLEMANAGER_H
|
||||
#define QMLCONSOLEMANAGER_H
|
||||
|
||||
#include "qmljstools_global.h"
|
||||
#include "qmlconsoleitem.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace Debugger {
|
||||
class DebuggerEngine;
|
||||
}
|
||||
namespace QmlJSTools {
|
||||
|
||||
namespace Internal {
|
||||
class QmlConsoleItemModel;
|
||||
class QmlConsoleModel;
|
||||
}
|
||||
|
||||
class QmlConsoleManagerPrivate;
|
||||
class QMLJSTOOLS_EXPORT QmlConsoleManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QmlConsoleManager(QObject *parent);
|
||||
~QmlConsoleManager();
|
||||
|
||||
static QmlConsoleManager *instance() { return m_instance; }
|
||||
|
||||
void showConsolePane();
|
||||
|
||||
QmlConsoleItem *rootItem() const;
|
||||
|
||||
void setDebuggerEngine(Debugger::DebuggerEngine *debuggerEngine);
|
||||
void setContext(const QString &context);
|
||||
|
||||
void printToConsolePane(QmlConsoleItem::ItemType itemType, const QString &text,
|
||||
bool bringToForeground = false);
|
||||
void printToConsolePane(QmlConsoleItem *item, bool bringToForeground = false);
|
||||
|
||||
private:
|
||||
QmlConsoleManagerPrivate *d;
|
||||
static QmlConsoleManager *m_instance;
|
||||
friend class Internal::QmlConsoleModel;
|
||||
};
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class QmlConsoleModel
|
||||
{
|
||||
public:
|
||||
static QmlConsoleItemModel *qmlConsoleItemModel();
|
||||
static void evaluate(const QString &expression);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace QmlJSTools
|
||||
|
||||
#endif // QMLCONSOLEMANAGER_H
|
||||
215
src/plugins/qmljstools/qmlconsolepane.cpp
Normal file
215
src/plugins/qmljstools/qmlconsolepane.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
#include "qmlconsolepane.h"
|
||||
#include "qmlconsoleview.h"
|
||||
#include "qmlconsoleproxymodel.h"
|
||||
#include "qmlconsoleitemmodel.h"
|
||||
#include "qmlconsolemanager.h"
|
||||
#include "qmlconsoleitemdelegate.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <coreplugin/findplaceholder.h>
|
||||
#include <utils/savedaction.h>
|
||||
#include <aggregation/aggregate.h>
|
||||
#include <find/treeviewfind.h>
|
||||
|
||||
#include <QToolButton>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
static const char CONSOLE[] = "Console";
|
||||
static const char SHOW_LOG[] = "showLog";
|
||||
static const char SHOW_WARNING[] = "showWarning";
|
||||
static const char SHOW_ERROR[] = "showError";
|
||||
|
||||
namespace QmlJSTools {
|
||||
namespace Internal {
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// QmlConsolePane
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
QmlConsolePane::QmlConsolePane(QObject *parent)
|
||||
: Core::IOutputPane(parent)
|
||||
{
|
||||
m_consoleWidget = new QWidget;
|
||||
m_consoleWidget->setWindowTitle(displayName());
|
||||
m_consoleWidget->setEnabled(true);
|
||||
|
||||
QVBoxLayout *vbox = new QVBoxLayout(m_consoleWidget);
|
||||
vbox->setMargin(0);
|
||||
vbox->setSpacing(0);
|
||||
|
||||
m_consoleView = new QmlConsoleView(m_consoleWidget);
|
||||
m_proxyModel = new QmlConsoleProxyModel(this);
|
||||
m_proxyModel->setSourceModel(QmlConsoleModel::qmlConsoleItemModel());
|
||||
connect(QmlConsoleModel::qmlConsoleItemModel(),
|
||||
SIGNAL(selectEditableRow(QModelIndex, QItemSelectionModel::SelectionFlags)),
|
||||
m_proxyModel,
|
||||
SLOT(selectEditableRow(QModelIndex,QItemSelectionModel::SelectionFlags)));
|
||||
|
||||
//Scroll to bottom when rows matching current filter settings are inserted
|
||||
//Not connecting rowsRemoved as the only way to remove rows is to clear the
|
||||
//model which will automatically reset the view.
|
||||
connect(QmlConsoleModel::qmlConsoleItemModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
|
||||
m_proxyModel, SLOT(onRowsInserted(QModelIndex,int,int)));
|
||||
m_consoleView->setModel(m_proxyModel);
|
||||
|
||||
connect(m_proxyModel,
|
||||
SIGNAL(setCurrentIndex(QModelIndex,QItemSelectionModel::SelectionFlags)),
|
||||
m_consoleView->selectionModel(),
|
||||
SLOT(setCurrentIndex(QModelIndex,QItemSelectionModel::SelectionFlags)));
|
||||
connect(m_proxyModel, SIGNAL(scrollToBottom()), m_consoleView, SLOT(onScrollToBottom()));
|
||||
|
||||
m_itemDelegate = new QmlConsoleItemDelegate(this);
|
||||
connect(m_consoleView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
||||
m_itemDelegate, SLOT(currentChanged(QModelIndex,QModelIndex)));
|
||||
m_consoleView->setItemDelegate(m_itemDelegate);
|
||||
|
||||
Aggregation::Aggregate *aggregate = new Aggregation::Aggregate();
|
||||
aggregate->add(m_consoleView);
|
||||
aggregate->add(new Find::TreeViewFind(m_consoleView));
|
||||
|
||||
vbox->addWidget(m_consoleView);
|
||||
vbox->addWidget(new Core::FindToolBarPlaceHolder(m_consoleWidget));
|
||||
|
||||
m_showDebugButton = new QToolButton(m_consoleWidget);
|
||||
m_showDebugButton->setAutoRaise(true);
|
||||
|
||||
m_showDebugButtonAction = new Utils::SavedAction(this);
|
||||
m_showDebugButtonAction->setDefaultValue(true);
|
||||
m_showDebugButtonAction->setSettingsKey(QLatin1String(CONSOLE), QLatin1String(SHOW_LOG));
|
||||
m_showDebugButtonAction->setToolTip(tr("Show debug, log, and info messages."));
|
||||
m_showDebugButtonAction->setCheckable(true);
|
||||
m_showDebugButtonAction->setIcon(QIcon(QLatin1String(":/qmljstools/images/log.png")));
|
||||
connect(m_showDebugButtonAction, SIGNAL(toggled(bool)), m_proxyModel, SLOT(setShowLogs(bool)));
|
||||
m_showDebugButton->setDefaultAction(m_showDebugButtonAction);
|
||||
|
||||
m_showWarningButton = new QToolButton(m_consoleWidget);
|
||||
m_showWarningButton->setAutoRaise(true);
|
||||
|
||||
m_showWarningButtonAction = new Utils::SavedAction(this);
|
||||
m_showWarningButtonAction->setDefaultValue(true);
|
||||
m_showWarningButtonAction->setSettingsKey(QLatin1String(CONSOLE), QLatin1String(SHOW_WARNING));
|
||||
m_showWarningButtonAction->setToolTip(tr("Show debug, log, and info messages."));
|
||||
m_showWarningButtonAction->setCheckable(true);
|
||||
m_showWarningButtonAction->setIcon(QIcon(QLatin1String(":/qmljstools/images/warning.png")));
|
||||
connect(m_showWarningButtonAction, SIGNAL(toggled(bool)), m_proxyModel,
|
||||
SLOT(setShowWarnings(bool)));
|
||||
m_showWarningButton->setDefaultAction(m_showWarningButtonAction);
|
||||
|
||||
m_showErrorButton = new QToolButton(m_consoleWidget);
|
||||
m_showErrorButton->setAutoRaise(true);
|
||||
|
||||
m_showErrorButtonAction = new Utils::SavedAction(this);
|
||||
m_showErrorButtonAction->setDefaultValue(true);
|
||||
m_showErrorButtonAction->setSettingsKey(QLatin1String(CONSOLE), QLatin1String(SHOW_ERROR));
|
||||
m_showErrorButtonAction->setToolTip(tr("Show debug, log, and info messages."));
|
||||
m_showErrorButtonAction->setCheckable(true);
|
||||
m_showErrorButtonAction->setIcon(QIcon(QLatin1String(":/qmljstools/images/error.png")));
|
||||
connect(m_showErrorButtonAction, SIGNAL(toggled(bool)), m_proxyModel,
|
||||
SLOT(setShowErrors(bool)));
|
||||
m_showErrorButton->setDefaultAction(m_showErrorButtonAction);
|
||||
|
||||
m_spacer = new QWidget(m_consoleWidget);
|
||||
m_spacer->setMinimumWidth(30);
|
||||
|
||||
m_statusLabel = new QLabel(m_consoleWidget);
|
||||
|
||||
readSettings();
|
||||
connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()), SLOT(writeSettings()));
|
||||
}
|
||||
|
||||
QmlConsolePane::~QmlConsolePane()
|
||||
{
|
||||
writeSettings();
|
||||
delete m_consoleWidget;
|
||||
}
|
||||
|
||||
QWidget *QmlConsolePane::outputWidget(QWidget *)
|
||||
{
|
||||
return m_consoleWidget;
|
||||
}
|
||||
|
||||
QList<QWidget *> QmlConsolePane::toolBarWidgets() const
|
||||
{
|
||||
return QList<QWidget *>() << m_showDebugButton << m_showWarningButton << m_showErrorButton
|
||||
<< m_spacer << m_statusLabel;
|
||||
}
|
||||
|
||||
int QmlConsolePane::priorityInStatusBar() const
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
void QmlConsolePane::clearContents()
|
||||
{
|
||||
QmlConsoleModel::qmlConsoleItemModel()->clear();
|
||||
}
|
||||
|
||||
void QmlConsolePane::visibilityChanged(bool /*visible*/)
|
||||
{
|
||||
}
|
||||
|
||||
bool QmlConsolePane::canFocus() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QmlConsolePane::hasFocus() const
|
||||
{
|
||||
return m_consoleWidget->hasFocus();
|
||||
}
|
||||
|
||||
void QmlConsolePane::setFocus()
|
||||
{
|
||||
m_consoleWidget->setFocus();
|
||||
}
|
||||
|
||||
bool QmlConsolePane::canNext() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QmlConsolePane::canPrevious() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void QmlConsolePane::goToNext()
|
||||
{
|
||||
}
|
||||
|
||||
void QmlConsolePane::goToPrev()
|
||||
{
|
||||
}
|
||||
|
||||
bool QmlConsolePane::canNavigate() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void QmlConsolePane::readSettings()
|
||||
{
|
||||
QSettings *settings = Core::ICore::settings();
|
||||
m_showDebugButtonAction->readSettings(settings);
|
||||
m_showWarningButtonAction->readSettings(settings);
|
||||
m_showErrorButtonAction->readSettings(settings);
|
||||
}
|
||||
|
||||
void QmlConsolePane::setContext(const QString &context)
|
||||
{
|
||||
m_statusLabel->setText(context);
|
||||
}
|
||||
|
||||
void QmlConsolePane::writeSettings() const
|
||||
{
|
||||
QSettings *settings = Core::ICore::settings();
|
||||
m_showDebugButtonAction->writeSettings(settings);
|
||||
m_showWarningButtonAction->writeSettings(settings);
|
||||
m_showErrorButtonAction->writeSettings(settings);
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // QmlJSTools
|
||||
71
src/plugins/qmljstools/qmlconsolepane.h
Normal file
71
src/plugins/qmljstools/qmlconsolepane.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#ifndef QMLCONSOLEPANE_H
|
||||
#define QMLCONSOLEPANE_H
|
||||
|
||||
#include <coreplugin/ioutputpane.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QToolButton;
|
||||
class QLabel;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Utils {
|
||||
class SavedAction;
|
||||
}
|
||||
|
||||
namespace QmlJSTools {
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class QmlConsoleView;
|
||||
class QmlConsoleItemDelegate;
|
||||
class QmlConsoleProxyModel;
|
||||
class QmlConsoleItemModel;
|
||||
|
||||
class QmlConsolePane : public Core::IOutputPane
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QmlConsolePane(QObject *parent);
|
||||
~QmlConsolePane();
|
||||
|
||||
QWidget *outputWidget(QWidget *);
|
||||
QList<QWidget *> toolBarWidgets() const;
|
||||
QString displayName() const { return tr("Console"); }
|
||||
int priorityInStatusBar() const;
|
||||
void clearContents();
|
||||
void visibilityChanged(bool visible);
|
||||
bool canFocus() const;
|
||||
bool hasFocus() const;
|
||||
void setFocus();
|
||||
|
||||
bool canNext() const;
|
||||
bool canPrevious() const;
|
||||
void goToNext();
|
||||
void goToPrev();
|
||||
bool canNavigate() const;
|
||||
|
||||
void readSettings();
|
||||
void setContext(const QString &context);
|
||||
|
||||
public slots:
|
||||
void writeSettings() const;
|
||||
|
||||
private:
|
||||
QToolButton *m_showDebugButton;
|
||||
QToolButton *m_showWarningButton;
|
||||
QToolButton *m_showErrorButton;
|
||||
Utils::SavedAction *m_showDebugButtonAction;
|
||||
Utils::SavedAction *m_showWarningButtonAction;
|
||||
Utils::SavedAction *m_showErrorButtonAction;
|
||||
QWidget *m_spacer;
|
||||
QLabel *m_statusLabel;
|
||||
QmlConsoleView *m_consoleView;
|
||||
QmlConsoleItemDelegate *m_itemDelegate;
|
||||
QmlConsoleProxyModel *m_proxyModel;
|
||||
QWidget *m_consoleWidget;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QmlJSTools
|
||||
|
||||
#endif // QMLCONSOLEPANE_H
|
||||
58
src/plugins/qmljstools/qmlconsoleproxymodel.cpp
Normal file
58
src/plugins/qmljstools/qmlconsoleproxymodel.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "qmlconsoleproxymodel.h"
|
||||
#include "qmlconsoleitemmodel.h"
|
||||
|
||||
namespace QmlJSTools {
|
||||
namespace Internal {
|
||||
|
||||
QmlConsoleProxyModel::QmlConsoleProxyModel(QObject *parent) :
|
||||
QSortFilterProxyModel(parent),
|
||||
m_filter(QmlConsoleItem::DefaultTypes)
|
||||
{
|
||||
}
|
||||
|
||||
void QmlConsoleProxyModel::setShowLogs(bool show)
|
||||
{
|
||||
m_filter = show ? m_filter | QmlConsoleItem::DebugType : m_filter & ~QmlConsoleItem::DebugType;
|
||||
setFilterRegExp(QString());
|
||||
}
|
||||
|
||||
void QmlConsoleProxyModel::setShowWarnings(bool show)
|
||||
{
|
||||
m_filter = show ? m_filter | QmlConsoleItem::WarningType
|
||||
: m_filter & ~QmlConsoleItem::WarningType;
|
||||
setFilterRegExp(QString());
|
||||
}
|
||||
|
||||
void QmlConsoleProxyModel::setShowErrors(bool show)
|
||||
{
|
||||
m_filter = show ? m_filter | QmlConsoleItem::ErrorType : m_filter & ~QmlConsoleItem::ErrorType;
|
||||
setFilterRegExp(QString());
|
||||
}
|
||||
|
||||
void QmlConsoleProxyModel::selectEditableRow(const QModelIndex &index,
|
||||
QItemSelectionModel::SelectionFlags command)
|
||||
{
|
||||
emit setCurrentIndex(mapFromSource(index), command);
|
||||
}
|
||||
|
||||
bool QmlConsoleProxyModel::filterAcceptsRow(int sourceRow,
|
||||
const QModelIndex &sourceParent) const
|
||||
{
|
||||
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
return m_filter.testFlag((QmlConsoleItem::ItemType)sourceModel()->data(
|
||||
index, QmlConsoleItemModel::TypeRole).toInt());
|
||||
}
|
||||
|
||||
void QmlConsoleProxyModel::onRowsInserted(const QModelIndex &index, int start, int end)
|
||||
{
|
||||
int rowIndex = end;
|
||||
do {
|
||||
if (filterAcceptsRow(rowIndex, index)) {
|
||||
emit scrollToBottom();
|
||||
break;
|
||||
}
|
||||
} while (--rowIndex >= start);
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // QmlJSTools
|
||||
41
src/plugins/qmljstools/qmlconsoleproxymodel.h
Normal file
41
src/plugins/qmljstools/qmlconsoleproxymodel.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef QMLCONSOLEPROXYMODEL_H
|
||||
#define QMLCONSOLEPROXYMODEL_H
|
||||
|
||||
#include "qmlconsoleitem.h"
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QItemSelectionModel>
|
||||
|
||||
namespace QmlJSTools {
|
||||
namespace Internal {
|
||||
|
||||
class QmlConsoleProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QmlConsoleProxyModel(QObject *parent);
|
||||
|
||||
public slots:
|
||||
void setShowLogs(bool show);
|
||||
void setShowWarnings(bool show);
|
||||
void setShowErrors(bool show);
|
||||
void selectEditableRow(const QModelIndex &index,
|
||||
QItemSelectionModel::SelectionFlags command);
|
||||
void onRowsInserted(const QModelIndex &index, int start, int end);
|
||||
|
||||
signals:
|
||||
void scrollToBottom();
|
||||
void setCurrentIndex(const QModelIndex &index,
|
||||
QItemSelectionModel::SelectionFlags command);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
|
||||
|
||||
private:
|
||||
QFlags<QmlConsoleItem::ItemType> m_filter;
|
||||
};
|
||||
|
||||
} // Internal
|
||||
} // QmlJSTools
|
||||
|
||||
#endif // QMLCONSOLEPROXYMODEL_H
|
||||
221
src/plugins/qmljstools/qmlconsoleview.cpp
Normal file
221
src/plugins/qmljstools/qmlconsoleview.cpp
Normal file
@@ -0,0 +1,221 @@
|
||||
#include "qmlconsoleview.h"
|
||||
#include "qmlconsoleitemdelegate.h"
|
||||
#include "qmlconsoleitemmodel.h"
|
||||
|
||||
#include <texteditor/basetexteditor.h>
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QProxyStyle>
|
||||
#include <QPainter>
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QAbstractProxyModel>
|
||||
#include <QFileInfo>
|
||||
#include <QUrl>
|
||||
#include <QScrollBar>
|
||||
|
||||
namespace QmlJSTools {
|
||||
namespace Internal {
|
||||
|
||||
class QmlConsoleViewStyle : public QProxyStyle
|
||||
{
|
||||
public:
|
||||
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter,
|
||||
const QWidget *widget = 0) const
|
||||
{
|
||||
if (element != QStyle::PE_PanelItemViewRow)
|
||||
QProxyStyle::drawPrimitive(element, option, painter, widget);
|
||||
}
|
||||
|
||||
int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
|
||||
QStyleHintReturn *returnData = 0) const {
|
||||
if (hint == SH_ItemView_ShowDecorationSelected)
|
||||
return 0;
|
||||
else
|
||||
return QProxyStyle::styleHint(hint, option, widget, returnData);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// QmlConsoleView
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
QmlConsoleView::QmlConsoleView(QWidget *parent) :
|
||||
QTreeView(parent)
|
||||
{
|
||||
setFrameStyle(QFrame::NoFrame);
|
||||
setHeaderHidden(true);
|
||||
setRootIsDecorated(false);
|
||||
setEditTriggers(QAbstractItemView::AllEditTriggers);
|
||||
setStyleSheet(QLatin1String("QTreeView::branch:has-siblings:!adjoins-item {"
|
||||
"border-image: none;"
|
||||
"image: none; }"
|
||||
"QTreeView::branch:has-siblings:adjoins-item {"
|
||||
"border-image: none;"
|
||||
"image: none; }"
|
||||
"QTreeView::branch:!has-children:!has-siblings:adjoins-item {"
|
||||
"border-image: none;"
|
||||
"image: none; }"
|
||||
"QTreeView::branch:has-children:!has-siblings:closed,"
|
||||
"QTreeView::branch:closed:has-children:has-siblings {"
|
||||
"border-image: none;"
|
||||
"image: none; }"
|
||||
"QTreeView::branch:open:has-children:!has-siblings,"
|
||||
"QTreeView::branch:open:has-children:has-siblings {"
|
||||
"border-image: none;"
|
||||
"image: none; }"));
|
||||
QmlConsoleViewStyle *style = new QmlConsoleViewStyle;
|
||||
setStyle(style);
|
||||
style->setParent(this);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
|
||||
connect(this, SIGNAL(activated(QModelIndex)), SLOT(onRowActivated(QModelIndex)));
|
||||
}
|
||||
|
||||
void QmlConsoleView::onScrollToBottom()
|
||||
{
|
||||
// Keep scrolling to bottom if scroll bar is at maximum()
|
||||
if (verticalScrollBar()->value() == verticalScrollBar()->maximum())
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
void QmlConsoleView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
QPoint pos = event->pos();
|
||||
QModelIndex index = indexAt(pos);
|
||||
if (index.isValid()) {
|
||||
QmlConsoleItem::ItemType type = (QmlConsoleItem::ItemType)index.data(
|
||||
QmlConsoleItemModel::TypeRole).toInt();
|
||||
bool handled = false;
|
||||
if (type == QmlConsoleItem::UndefinedType) {
|
||||
bool showTypeIcon = index.parent() == QModelIndex();
|
||||
ConsoleItemPositions positions(visualRect(index), viewOptions().font, showTypeIcon,
|
||||
true);
|
||||
|
||||
if (positions.expandCollapseIcon().contains(pos)) {
|
||||
if (isExpanded(index))
|
||||
setExpanded(index, false);
|
||||
else
|
||||
setExpanded(index, true);
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
if (!handled)
|
||||
QTreeView::mousePressEvent(event);
|
||||
} else {
|
||||
selectionModel()->setCurrentIndex(model()->index(model()->rowCount() - 1, 0),
|
||||
QItemSelectionModel::ClearAndSelect);
|
||||
}
|
||||
}
|
||||
|
||||
void QmlConsoleView::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
if (!e->modifiers() && e->key() == Qt::Key_Return) {
|
||||
emit activated(currentIndex());
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
QTreeView::keyPressEvent(e);
|
||||
}
|
||||
|
||||
void QmlConsoleView::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
static_cast<QmlConsoleItemDelegate *>(itemDelegate())->emitSizeHintChanged(
|
||||
selectionModel()->currentIndex());
|
||||
QTreeView::resizeEvent(e);
|
||||
}
|
||||
|
||||
void QmlConsoleView::drawBranches(QPainter *painter, const QRect &rect,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
static_cast<QmlConsoleItemDelegate *>(itemDelegate())->drawBackground(painter, rect, index,
|
||||
false);
|
||||
QTreeView::drawBranches(painter, rect, index);
|
||||
}
|
||||
|
||||
void QmlConsoleView::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
QModelIndex itemIndex = indexAt(event->pos());
|
||||
QMenu menu;
|
||||
|
||||
QAction *copy = new QAction(tr("&Copy"), this);
|
||||
copy->setEnabled(itemIndex.isValid());
|
||||
menu.addAction(copy);
|
||||
QAction *show = new QAction(tr("&Show in Editor"), this);
|
||||
show->setEnabled(canShowItemInTextEditor(itemIndex));
|
||||
menu.addAction(show);
|
||||
menu.addSeparator();
|
||||
QAction *clear = new QAction(tr("C&lear"), this);
|
||||
menu.addAction(clear);
|
||||
|
||||
QAction *a = menu.exec(event->globalPos());
|
||||
if (a == 0)
|
||||
return;
|
||||
|
||||
if (a == copy) {
|
||||
copyToClipboard(itemIndex);
|
||||
} else if (a == show) {
|
||||
onRowActivated(itemIndex);
|
||||
} else if (a == clear) {
|
||||
QAbstractProxyModel *proxyModel = qobject_cast<QAbstractProxyModel *>(model());
|
||||
QmlConsoleItemModel *handler = qobject_cast<QmlConsoleItemModel *>(
|
||||
proxyModel->sourceModel());
|
||||
handler->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void QmlConsoleView::onRowActivated(const QModelIndex &index)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
// See if we have file and line Info
|
||||
QString filePath = model()->data(index,
|
||||
QmlConsoleItemModel::FileRole).toString();
|
||||
if (!filePath.isEmpty()) {
|
||||
QFileInfo fi(filePath);
|
||||
if (fi.exists() && fi.isFile() && fi.isReadable()) {
|
||||
int line = model()->data(index, QmlConsoleItemModel::LineRole).toInt();
|
||||
TextEditor::BaseTextEditorWidget::openEditorAt(fi.canonicalFilePath(), line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QmlConsoleView::copyToClipboard(const QModelIndex &index)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
QString contents = model()->data(index).toString();
|
||||
// See if we have file and line Info
|
||||
QString filePath = model()->data(index, QmlConsoleItemModel::FileRole).toString();
|
||||
if (!filePath.isEmpty()) {
|
||||
contents = QString(QLatin1String("%1 %2: %3")).arg(contents).arg(filePath).arg(
|
||||
model()->data(index, QmlConsoleItemModel::LineRole).toString());
|
||||
}
|
||||
QClipboard *cb = QApplication::clipboard();
|
||||
cb->setText(contents);
|
||||
}
|
||||
|
||||
bool QmlConsoleView::canShowItemInTextEditor(const QModelIndex &index)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return false;
|
||||
|
||||
// See if we have file and line Info
|
||||
QString filePath = model()->data(index, QmlConsoleItemModel::FileRole).toString();
|
||||
if (!filePath.isEmpty()) {
|
||||
QFileInfo fi(filePath);
|
||||
if (fi.exists() && fi.isFile() && fi.isReadable()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // QmlJSTools
|
||||
37
src/plugins/qmljstools/qmlconsoleview.h
Normal file
37
src/plugins/qmljstools/qmlconsoleview.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef QMLCONSOLEVIEW_H
|
||||
#define QMLCONSOLEVIEW_H
|
||||
|
||||
#include <QTreeView>
|
||||
|
||||
namespace QmlJSTools {
|
||||
namespace Internal {
|
||||
|
||||
class QmlConsoleView : public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QmlConsoleView(QWidget *parent);
|
||||
|
||||
public slots:
|
||||
void onScrollToBottom();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
void drawBranches(QPainter *painter, const QRect &rect,
|
||||
const QModelIndex &index) const;
|
||||
void contextMenuEvent(QContextMenuEvent *event);
|
||||
|
||||
private slots:
|
||||
void onRowActivated(const QModelIndex &index);
|
||||
|
||||
private:
|
||||
void copyToClipboard(const QModelIndex &index);
|
||||
bool canShowItemInTextEditor(const QModelIndex &index);
|
||||
};
|
||||
|
||||
} // Internal
|
||||
} // QmlJSTools
|
||||
|
||||
#endif // QMLCONSOLEVIEW_H
|
||||
58
src/plugins/qmljstools/qmljsinterpreter.cpp
Normal file
58
src/plugins/qmljstools/qmljsinterpreter.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "qmljsinterpreter.h"
|
||||
|
||||
namespace QmlJSTools {
|
||||
namespace Internal {
|
||||
|
||||
bool QmlJSInterpreter::canEvaluate()
|
||||
{
|
||||
int yyaction = 0;
|
||||
int yytoken = -1;
|
||||
int yytos = -1;
|
||||
|
||||
setCode(m_code, 1);
|
||||
m_tokens.append(T_FEED_JS_PROGRAM);
|
||||
|
||||
do {
|
||||
if (++yytos == m_stateStack.size())
|
||||
m_stateStack.resize(m_stateStack.size() * 2);
|
||||
|
||||
m_stateStack[yytos] = yyaction;
|
||||
|
||||
again:
|
||||
if (yytoken == -1 && action_index[yyaction] != -TERMINAL_COUNT) {
|
||||
if (m_tokens.isEmpty())
|
||||
yytoken = lex();
|
||||
else
|
||||
yytoken = m_tokens.takeFirst();
|
||||
}
|
||||
|
||||
yyaction = t_action(yyaction, yytoken);
|
||||
if (yyaction > 0) {
|
||||
if (yyaction == ACCEPT_STATE) {
|
||||
--yytos;
|
||||
return true;
|
||||
}
|
||||
yytoken = -1;
|
||||
} else if (yyaction < 0) {
|
||||
const int ruleno = -yyaction - 1;
|
||||
yytos -= rhs[ruleno];
|
||||
yyaction = nt_action(m_stateStack[yytos], lhs[ruleno] - TERMINAL_COUNT);
|
||||
}
|
||||
} while (yyaction);
|
||||
|
||||
const int errorState = m_stateStack[yytos];
|
||||
if (t_action(errorState, T_AUTOMATIC_SEMICOLON) && canInsertAutomaticSemicolon(yytoken)) {
|
||||
yyaction = errorState;
|
||||
m_tokens.prepend(yytoken);
|
||||
yytoken = T_SEMICOLON;
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (yytoken != EOF_SYMBOL)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QmlJSTools
|
||||
40
src/plugins/qmljstools/qmljsinterpreter.h
Normal file
40
src/plugins/qmljstools/qmljsinterpreter.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef QMLJSINTERPRETER_H
|
||||
#define QMLJSINTERPRETER_H
|
||||
|
||||
#include <qmljs/parser/qmljslexer_p.h>
|
||||
#include <qmljs/parser/qmljsengine_p.h>
|
||||
|
||||
#include <QVector>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
|
||||
namespace QmlJSTools {
|
||||
namespace Internal {
|
||||
|
||||
class QmlJSInterpreter: QmlJS::Lexer
|
||||
{
|
||||
public:
|
||||
QmlJSInterpreter()
|
||||
: 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();
|
||||
|
||||
private:
|
||||
QmlJS::Engine m_engine;
|
||||
QVector<int> m_stateStack;
|
||||
QList<int> m_tokens;
|
||||
QString m_code;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QmlJSTools
|
||||
|
||||
#endif // QMLJSINTERPRETER_H
|
||||
@@ -1,45 +0,0 @@
|
||||
!dll {
|
||||
DEFINES += QMLJSTOOLS_STATIC
|
||||
}
|
||||
|
||||
INCLUDEPATH += $$PWD/..
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/qmljstools_global.h \
|
||||
$$PWD/qmljstoolsplugin.h \
|
||||
$$PWD/qmljstoolsconstants.h \
|
||||
$$PWD/qmljstoolssettings.h \
|
||||
$$PWD/qmljscodestylepreferencesfactory.h \
|
||||
$$PWD/qmljsmodelmanager.h \
|
||||
$$PWD/qmljsqtstylecodeformatter.h \
|
||||
$$PWD/qmljsrefactoringchanges.h \
|
||||
$$PWD/qmljsplugindumper.h \
|
||||
$$PWD/qmljsfunctionfilter.h \
|
||||
$$PWD/qmljslocatordata.h \
|
||||
$$PWD/qmljsindenter.h \
|
||||
$$PWD/qmljscodestylesettingspage.h \
|
||||
$$PWD/qmljsfindexportedcpptypes.h \
|
||||
$$PWD/qmljssemanticinfo.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/qmljstoolsplugin.cpp \
|
||||
$$PWD/qmljstoolssettings.cpp \
|
||||
$$PWD/qmljscodestylepreferencesfactory.cpp \
|
||||
$$PWD/qmljsmodelmanager.cpp \
|
||||
$$PWD/qmljsqtstylecodeformatter.cpp \
|
||||
$$PWD/qmljsrefactoringchanges.cpp \
|
||||
$$PWD/qmljsplugindumper.cpp \
|
||||
$$PWD/qmljsfunctionfilter.cpp \
|
||||
$$PWD/qmljslocatordata.cpp \
|
||||
$$PWD/qmljsindenter.cpp \
|
||||
$$PWD/qmljscodestylesettingspage.cpp \
|
||||
$$PWD/qmljsfindexportedcpptypes.cpp \
|
||||
$$PWD/qmljssemanticinfo.cpp
|
||||
|
||||
FORMS += \
|
||||
$$PWD/qmljscodestylesettingspage.ui
|
||||
|
||||
equals(TEST, 1) {
|
||||
SOURCES += \
|
||||
$$PWD/qmljstools_test.cpp
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
include(qmljstools_dependencies.pri)
|
||||
|
||||
INCLUDEPATH *= $$PWD/..
|
||||
|
||||
LIBS *= -l$$qtLibraryName(QmlJSTools)
|
||||
|
||||
@@ -7,4 +7,69 @@ include(qmljstools_dependencies.pri)
|
||||
DEFINES += QT_NO_CAST_TO_ASCII
|
||||
DEFINES += QMLJSTOOLS_LIBRARY
|
||||
|
||||
include(qmljstools-lib.pri)
|
||||
!dll {
|
||||
DEFINES += QMLJSTOOLS_STATIC
|
||||
}
|
||||
|
||||
QT += script
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/qmljstoolsplugin.h \
|
||||
$$PWD/qmljstoolsconstants.h \
|
||||
$$PWD/qmljstoolssettings.h \
|
||||
$$PWD/qmljscodestylepreferencesfactory.h \
|
||||
$$PWD/qmljsmodelmanager.h \
|
||||
$$PWD/qmljsqtstylecodeformatter.h \
|
||||
$$PWD/qmljsrefactoringchanges.h \
|
||||
$$PWD/qmljsplugindumper.h \
|
||||
$$PWD/qmljsfunctionfilter.h \
|
||||
$$PWD/qmljslocatordata.h \
|
||||
$$PWD/qmljsindenter.h \
|
||||
$$PWD/qmljscodestylesettingspage.h \
|
||||
$$PWD/qmljsfindexportedcpptypes.h \
|
||||
$$PWD/qmljssemanticinfo.h \
|
||||
$$PWD/qmljstools_global.h \
|
||||
$$PWD/qmlconsolemanager.h \
|
||||
$$PWD/qmlconsoleitem.h \
|
||||
$$PWD/qmlconsoleitemmodel.h \
|
||||
$$PWD/qmlconsolepane.h \
|
||||
$$PWD/qmlconsoleview.h \
|
||||
$$PWD/qmlconsoleitemdelegate.h \
|
||||
$$PWD/qmlconsoleedit.h \
|
||||
$$PWD/qmljsinterpreter.h \
|
||||
$$PWD/qmlconsoleproxymodel.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/qmljstoolsplugin.cpp \
|
||||
$$PWD/qmljstoolssettings.cpp \
|
||||
$$PWD/qmljscodestylepreferencesfactory.cpp \
|
||||
$$PWD/qmljsmodelmanager.cpp \
|
||||
$$PWD/qmljsqtstylecodeformatter.cpp \
|
||||
$$PWD/qmljsrefactoringchanges.cpp \
|
||||
$$PWD/qmljsplugindumper.cpp \
|
||||
$$PWD/qmljsfunctionfilter.cpp \
|
||||
$$PWD/qmljslocatordata.cpp \
|
||||
$$PWD/qmljsindenter.cpp \
|
||||
$$PWD/qmljscodestylesettingspage.cpp \
|
||||
$$PWD/qmljsfindexportedcpptypes.cpp \
|
||||
$$PWD/qmljssemanticinfo.cpp \
|
||||
$$PWD/qmlconsolemanager.cpp \
|
||||
$$PWD/qmlconsoleitem.cpp \
|
||||
$$PWD/qmlconsoleitemmodel.cpp \
|
||||
$$PWD/qmlconsolepane.cpp \
|
||||
$$PWD/qmlconsoleview.cpp \
|
||||
$$PWD/qmlconsoleitemdelegate.cpp \
|
||||
$$PWD/qmlconsoleedit.cpp \
|
||||
$$PWD/qmljsinterpreter.cpp \
|
||||
$$PWD/qmlconsoleproxymodel.cpp
|
||||
|
||||
RESOURCES += \
|
||||
qmljstools.qrc
|
||||
|
||||
FORMS += \
|
||||
$$PWD/qmljscodestylesettingspage.ui
|
||||
|
||||
equals(TEST, 1) {
|
||||
SOURCES += \
|
||||
$$PWD/qmljstools_test.cpp
|
||||
}
|
||||
|
||||
@@ -53,6 +53,25 @@ QtcPlugin {
|
||||
"qmljstoolsplugin.h",
|
||||
"qmljstoolssettings.cpp",
|
||||
"qmljstoolssettings.h",
|
||||
"qmlconsolemanager.cpp",
|
||||
"qmlconsolemanager.h",
|
||||
"qmlconsoleitem.cpp",
|
||||
"qmlconsoleitem.h",
|
||||
"qmlcomsoleitemmodel.cpp",
|
||||
"qmlconsoleitemmodel.h",
|
||||
"qmlconsolepane.cpp",
|
||||
"qmlconsolepane.h",
|
||||
"qmlconsoleview.cpp",
|
||||
"qmlconsoleview.h",
|
||||
"qmlconsoleitemdelegate.cpp",
|
||||
"qmlconsoleitemdelegate.h",
|
||||
"qmlconsoleedit.cpp",
|
||||
"qmlconsoleedit.h",
|
||||
"qmljsinterpreter.cpp",
|
||||
"qmljsinterpreter.h",
|
||||
"qmljsconsoleproxymodel.cpp",
|
||||
"qmljsconsoleproxymodel.h",
|
||||
"qmljstools.qrc"
|
||||
]
|
||||
|
||||
Group {
|
||||
|
||||
10
src/plugins/qmljstools/qmljstools.qrc
Normal file
10
src/plugins/qmljstools/qmljstools.qrc
Normal file
@@ -0,0 +1,10 @@
|
||||
<RCC>
|
||||
<qresource prefix="/qmljstools">
|
||||
<file>images/prompt.png</file>
|
||||
<file>images/collapse.png</file>
|
||||
<file>images/warning.png</file>
|
||||
<file>images/log.png</file>
|
||||
<file>images/expand.png</file>
|
||||
<file>images/error.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "qmljscodestylesettingspage.h"
|
||||
#include "qmljstoolsconstants.h"
|
||||
#include "qmljstoolssettings.h"
|
||||
#include "qmlconsolemanager.h"
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
@@ -52,6 +53,7 @@
|
||||
#include <QSettings>
|
||||
#include <QMenu>
|
||||
|
||||
using namespace QmlJSTools;
|
||||
using namespace QmlJSTools::Internal;
|
||||
|
||||
enum { debug = 0 };
|
||||
@@ -68,6 +70,7 @@ QmlJSToolsPlugin::~QmlJSToolsPlugin()
|
||||
{
|
||||
m_instance = 0;
|
||||
m_modelManager = 0; // deleted automatically
|
||||
m_consoleManager = 0; // deleted automatically
|
||||
}
|
||||
|
||||
bool QmlJSToolsPlugin::initialize(const QStringList &arguments, QString *error)
|
||||
@@ -79,6 +82,8 @@ bool QmlJSToolsPlugin::initialize(const QStringList &arguments, QString *error)
|
||||
|
||||
// Objects
|
||||
m_modelManager = new ModelManager(this);
|
||||
m_consoleManager = new QmlConsoleManager(this);
|
||||
|
||||
// Core::VCSManager *vcsManager = core->vcsManager();
|
||||
// Core::DocumentManager *fileManager = core->fileManager();
|
||||
// connect(vcsManager, SIGNAL(repositoryChanged(QString)),
|
||||
|
||||
@@ -46,6 +46,7 @@ QT_END_NAMESPACE
|
||||
namespace QmlJSTools {
|
||||
|
||||
class QmlJSToolsSettings;
|
||||
class QmlConsoleManager;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
@@ -77,6 +78,7 @@ private slots:
|
||||
|
||||
private:
|
||||
ModelManager *m_modelManager;
|
||||
QmlConsoleManager *m_consoleManager;
|
||||
QmlJSToolsSettings *m_settings;
|
||||
QAction *m_resetCodeModelAction;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user