QmlJS: Lazy-load console items to allow for recursion

Using Utils:TreeView automatically gives us the capability for loading
item as they are expanded. This way we can show recursive structure in
the console as well as load data from the debug server on demand.

Also, properly print error messages received from unsuccessful
command evaluations.

Task-number: QTCREATORBUG-14931
Change-Id: I66d440eedd9723b04670169b27db1ee18f3f2891
Reviewed-by: hjk <hjk@theqtcompany.com>
This commit is contained in:
Ulf Hermann
2015-08-21 17:33:53 +02:00
parent 0b32832812
commit b5717a5315
15 changed files with 354 additions and 494 deletions

View File

@@ -38,111 +38,34 @@ namespace QmlJS {
// //
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
ConsoleItem::ConsoleItem(ConsoleItem *parent, ConsoleItem::ItemType itemType, QString addZeroWidthSpace(QString text)
const QString &text)
: m_parentItem(parent),
itemType(itemType),
line(-1)
{ {
setText(text); for (int i = 0; i < text.length(); ++i) {
} if (text.at(i).isPunct())
text.insert(++i, QChar(0x200b)); // ZERO WIDTH SPACE
ConsoleItem::~ConsoleItem()
{
qDeleteAll(m_childItems);
}
ConsoleItem *ConsoleItem::child(int number)
{
return m_childItems.value(number);
}
int ConsoleItem::childCount() const
{
return m_childItems.size();
}
int ConsoleItem::childNumber() const
{
if (m_parentItem)
return m_parentItem->m_childItems.indexOf(const_cast<ConsoleItem *>(this));
return 0;
}
bool ConsoleItem::insertChildren(int position, int count)
{
if (position < 0 || position > m_childItems.size())
return false;
for (int row = 0; row < count; ++row) {
ConsoleItem *item = new ConsoleItem(this, ConsoleItem::UndefinedType,
QString());
m_childItems.insert(position, item);
} }
return text;
return true;
} }
void ConsoleItem::insertChild(ConsoleItem *item, bool sorted) ConsoleItem::ConsoleItem(ItemType itemType, const QString &expression, const QString &file,
int line) :
m_itemType(itemType), m_text(addZeroWidthSpace(expression)), m_file(file), m_line(line)
{ {
if (!sorted) { setFlags(Qt::ItemFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable |
m_childItems.insert(m_childItems.count(), item); (itemType == InputType ? Qt::ItemIsEditable : Qt::NoItemFlags)));
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 ConsoleItem::insertChild(int position, ConsoleItem *item) ConsoleItem::ConsoleItem(ConsoleItem::ItemType itemType, const QString &expression,
std::function<void(ConsoleItem *)> doFetch) :
m_itemType(itemType), m_text(addZeroWidthSpace(expression)), m_line(-1), m_doFetch(doFetch)
{ {
if (position < 0 || position > m_childItems.size()) setFlags(Qt::ItemFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable |
return false; (itemType == InputType ? Qt::ItemIsEditable : Qt::NoItemFlags)));
m_childItems.insert(position, item);
return true;
} }
ConsoleItem *ConsoleItem::parent() ConsoleItem::ItemType ConsoleItem::itemType() const
{ {
return m_parentItem; return m_itemType;
}
bool ConsoleItem::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 ConsoleItem::detachChild(int position)
{
if (position < 0 || position > m_childItems.size())
return false;
m_childItems.removeAt(position);
return true;
}
void ConsoleItem::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
}
} }
QString ConsoleItem::text() const QString ConsoleItem::text() const
@@ -150,10 +73,95 @@ QString ConsoleItem::text() const
return m_text; return m_text;
} }
QString ConsoleItem::file() const
{
return m_file;
}
int ConsoleItem::line() const
{
return m_line;
}
QVariant ConsoleItem::data(int column, int role) const
{
if (column != 0)
return QVariant();
switch (role)
{
case TypeRole:
return m_itemType;
case FileRole:
return m_file;
case LineRole:
return m_line;
case ExpressionRole:
return expression();
case Qt::DisplayRole:
return m_text;
default:
return TreeItem::data(column, role);
}
}
bool ConsoleItem::setData(int column, const QVariant &data, int role)
{
if (column != 0)
return false;
switch (role)
{
case TypeRole:
m_itemType = ItemType(data.toInt());
return true;
case FileRole:
m_file = data.toString();
return true;
case LineRole:
m_line = data.toInt();
return true;
case ExpressionRole:
m_text = addZeroWidthSpace(data.toString());
return true;
case Qt::DisplayRole:
m_text = data.toString();
return true;
default:
return TreeItem::setData(column, data, role);
}
}
bool ConsoleItem::canFetchMore() const
{
// Always fetch all children, too, as the labels depend on them.
foreach (TreeItem *child, children()) {
if (static_cast<ConsoleItem *>(child)->m_doFetch)
return true;
}
return bool(m_doFetch);
}
void ConsoleItem::fetchMore()
{
if (m_doFetch) {
m_doFetch(this);
m_doFetch = std::function<void(ConsoleItem *)>();
}
foreach (TreeItem *child, children()) {
ConsoleItem *item = static_cast<ConsoleItem *>(child);
if (item->m_doFetch) {
item->m_doFetch(item);
item->m_doFetch = m_doFetch;
}
}
}
QString ConsoleItem::expression() const QString ConsoleItem::expression() const
{ {
QString text = m_text; return text().remove(QChar(0x200b)); // ZERO WIDTH SPACE
return text.remove(QChar(0x200b)); // ZERO WIDTH SPACE
} }
} // QmlJS } // QmlJS

View File

@@ -32,53 +32,56 @@
#define CONSOLEITEM_H #define CONSOLEITEM_H
#include "qmljs_global.h" #include "qmljs_global.h"
#include <utils/treemodel.h>
#include <QList>
#include <QString> #include <QString>
#include <functional>
namespace QmlJS { namespace QmlJS {
class QMLJS_EXPORT ConsoleItem class QMLJS_EXPORT ConsoleItem : public Utils::TreeItem
{ {
public: public:
enum Roles {
TypeRole = Qt::UserRole,
FileRole,
LineRole,
ExpressionRole
};
enum ItemType enum ItemType
{ {
UndefinedType = 0x01, // Can be used for unknown and for Return values DefaultType = 0x01, // Can be used for unknown and for Return values
DebugType = 0x02, DebugType = 0x02,
WarningType = 0x04, WarningType = 0x04,
ErrorType = 0x08, ErrorType = 0x08,
InputType = 0x10, InputType = 0x10,
DefaultTypes = InputType | UndefinedType
}; };
Q_DECLARE_FLAGS(ItemTypes, ItemType) Q_DECLARE_FLAGS(ItemTypes, ItemType)
ConsoleItem(ConsoleItem *parent, ConsoleItem(ItemType itemType = ConsoleItem::DefaultType, const QString &expression = QString(),
ConsoleItem::ItemType type = ConsoleItem::UndefinedType, const QString &file = QString(), int line = -1);
const QString &data = QString()); ConsoleItem(ItemType itemType, const QString &expression,
~ConsoleItem(); std::function<void(ConsoleItem *)> doFetch);
ConsoleItem *child(int number); ItemType itemType() const;
int childCount() const;
bool insertChildren(int position, int count);
void insertChild(ConsoleItem *item, bool sorted);
bool insertChild(int position, ConsoleItem *item);
ConsoleItem *parent();
bool removeChildren(int position, int count);
bool detachChild(int position);
int childNumber() const;
void setText(const QString &text);
QString text() const;
QString expression() const; QString expression() const;
QString text() const;
QString file() const;
int line() const;
QVariant data(int column, int role) const;
bool setData(int column, const QVariant &data, int role);
bool canFetchMore() const;
void fetchMore();
private: private:
ConsoleItem *m_parentItem; ItemType m_itemType;
QList<ConsoleItem *> m_childItems;
QString m_text; QString m_text;
QString m_file;
int m_line;
public: std::function<void(ConsoleItem *)> m_doFetch;
ConsoleItem::ItemType itemType;
QString file;
int line;
}; };
} // QmlJS } // QmlJS

View File

@@ -50,8 +50,6 @@ public:
virtual void showConsolePane() = 0; virtual void showConsolePane() = 0;
virtual ConsoleItem *rootItem() const = 0;
virtual void setScriptEvaluator(IScriptEvaluator *scriptEvaluator) = 0; virtual void setScriptEvaluator(IScriptEvaluator *scriptEvaluator) = 0;
virtual void setContext(const QString &context) = 0; virtual void setContext(const QString &context) = 0;

View File

@@ -530,7 +530,7 @@ void DebuggerEngine::showMessage(const QString &msg, int channel, int timeout) c
// qDebug() << qPrintable(msg) << "IN STATE" << state(); // qDebug() << qPrintable(msg) << "IN STATE" << state();
QmlJS::ConsoleManagerInterface *consoleManager = QmlJS::ConsoleManagerInterface::instance(); QmlJS::ConsoleManagerInterface *consoleManager = QmlJS::ConsoleManagerInterface::instance();
if (channel == ConsoleOutput && consoleManager) if (channel == ConsoleOutput && consoleManager)
consoleManager->printToConsolePane(QmlJS::ConsoleItem::UndefinedType, msg); consoleManager->printToConsolePane(QmlJS::ConsoleItem::DefaultType, msg);
Internal::showMessage(msg, channel, timeout); Internal::showMessage(msg, channel, timeout);
if (d->m_runControl) { if (d->m_runControl) {

View File

@@ -182,7 +182,7 @@ public:
QmlV8ObjectData extractData(const QVariant &data) const; QmlV8ObjectData extractData(const QVariant &data) const;
void insertSubItems(WatchItem *parent, const QVariantList &properties); void insertSubItems(WatchItem *parent, const QVariantList &properties);
void checkForFinishedUpdate(); void checkForFinishedUpdate();
ConsoleItem *constructLogItemTree(ConsoleItem *parent, const QmlV8ObjectData &objectData); ConsoleItem *constructLogItemTree(const QmlV8ObjectData &objectData);
public: public:
QHash<int, QmlV8ObjectData> refVals; // The mapping of target object handles to retrieved values. QHash<int, QmlV8ObjectData> refVals; // The mapping of target object handles to retrieved values.
@@ -220,6 +220,10 @@ public:
QmlDebug::QDebugMessageClient *msgClient = 0; QmlDebug::QDebugMessageClient *msgClient = 0;
QHash<int, QmlCallback> callbackForToken; QHash<int, QmlCallback> callbackForToken;
private:
ConsoleItem *constructLogItemTree(const QmlV8ObjectData &objectData, QList<int> &seenHandles);
void constructChildLogItems(ConsoleItem *item, const QmlV8ObjectData &objectData,
QList<int> &seenHandles);
}; };
static void updateDocument(IDocument *document, const QTextDocument *textDocument) static void updateDocument(IDocument *document, const QTextDocument *textDocument)
@@ -1012,44 +1016,73 @@ void QmlEngine::selectWatchData(const QByteArray &iname)
d->inspectorAdapter.agent()->watchDataSelected(item->id); d->inspectorAdapter.agent()->watchDataSelected(item->id);
} }
static ConsoleItem *constructLogItemTree(ConsoleItem *parent, bool compareConsoleItems(const ConsoleItem *a, const ConsoleItem *b)
const QVariant &result, {
if (a == 0)
return true;
if (b == 0)
return false;
return a->text() < b->text();
}
static ConsoleItem *constructLogItemTree(const QVariant &result,
const QString &key = QString()) const QString &key = QString())
{ {
bool sorted = boolSetting(SortStructMembers); bool sorted = boolSetting(SortStructMembers);
if (!result.isValid()) if (!result.isValid())
return 0; return 0;
ConsoleItem *item = new ConsoleItem(parent); QString text;
ConsoleItem *item = 0;
if (result.type() == QVariant::Map) { if (result.type() == QVariant::Map) {
if (key.isEmpty()) if (key.isEmpty())
item->setText(_("Object")); text = _("Object");
else else
item->setText(key + _(" : Object")); text = key + _(" : Object");
QMap<QString, QVariant> resultMap = result.toMap();
QVarLengthArray<ConsoleItem *> children(resultMap.size());
QMapIterator<QString, QVariant> i(result.toMap()); QMapIterator<QString, QVariant> i(result.toMap());
auto it = children.begin();
while (i.hasNext()) { while (i.hasNext()) {
i.next(); i.next();
ConsoleItem *child = constructLogItemTree(item, i.value(), i.key()); *(it++) = constructLogItemTree(i.value(), i.key());
if (child)
item->insertChild(child, sorted);
} }
// Sort before inserting as ConsoleItem::sortChildren causes a whole cascade of changes we
// may not want to handle here.
if (sorted)
std::sort(children.begin(), children.end(), compareConsoleItems);
item = new ConsoleItem(ConsoleItem::DefaultType, text);
foreach (ConsoleItem *child, children) {
if (child)
item->appendChild(child);
}
} else if (result.type() == QVariant::List) { } else if (result.type() == QVariant::List) {
if (key.isEmpty()) if (key.isEmpty())
item->setText(_("List")); text = _("List");
else else
item->setText(QString(_("[%1] : List")).arg(key)); text = QString(_("[%1] : List")).arg(key);
QVariantList resultList = result.toList(); QVariantList resultList = result.toList();
for (int i = 0; i < resultList.count(); i++) { QVarLengthArray<ConsoleItem *> children(resultList.size());
ConsoleItem *child = constructLogItemTree(item, resultList.at(i), for (int i = 0; i < resultList.count(); i++)
QString::number(i)); children[i] = constructLogItemTree(resultList.at(i), QString::number(i));
if (sorted)
std::sort(children.begin(), children.end(), compareConsoleItems);
item = new ConsoleItem(ConsoleItem::DefaultType, text);
foreach (ConsoleItem *child, children) {
if (child) if (child)
item->insertChild(child, sorted); item->appendChild(child);
} }
} else if (result.canConvert(QVariant::String)) { } else if (result.canConvert(QVariant::String)) {
item->setText(result.toString()); item = new ConsoleItem(ConsoleItem::DefaultType, result.toString());
} else { } else {
item->setText(_("Unknown Value")); item = new ConsoleItem(ConsoleItem::DefaultType, _("Unknown Value"));
} }
return item; return item;
@@ -1060,7 +1093,7 @@ void QmlEngine::expressionEvaluated(quint32 queryId, const QVariant &result)
if (d->queryIds.contains(queryId)) { if (d->queryIds.contains(queryId)) {
d->queryIds.removeOne(queryId); d->queryIds.removeOne(queryId);
if (auto consoleManager = ConsoleManagerInterface::instance()) { if (auto consoleManager = ConsoleManagerInterface::instance()) {
if (ConsoleItem *item = constructLogItemTree(consoleManager->rootItem(), result)) if (ConsoleItem *item = constructLogItemTree(result))
consoleManager->printToConsolePane(item); consoleManager->printToConsolePane(item);
} }
} }
@@ -2034,13 +2067,10 @@ void QmlEnginePrivate::messageReceived(const QByteArray &data)
//This is most probably due to a wrong eval expression. //This is most probably due to a wrong eval expression.
//Redirect output to console. //Redirect output to console.
if (eventType.isEmpty()) { if (eventType.isEmpty()) {
QmlV8ObjectData entry; if (auto consoleManager = ConsoleManagerInterface::instance())
entry.type = "string"; consoleManager->printToConsolePane(new ConsoleItem(
entry.value = resp.value(_("message")); ConsoleItem::ErrorType,
if (auto consoleManager = ConsoleManagerInterface::instance()) { resp.value(_(MESSAGE)).toString()));
if (ConsoleItem *item = constructLogItemTree(consoleManager->rootItem(), entry))
consoleManager->printToConsolePane(item);
}
} }
} //EVENT } //EVENT
@@ -2319,37 +2349,99 @@ void QmlEnginePrivate::checkForFinishedUpdate()
engine->watchHandler()->notifyUpdateFinished(); engine->watchHandler()->notifyUpdateFinished();
} }
ConsoleItem *QmlEnginePrivate::constructLogItemTree(ConsoleItem *parent, ConsoleItem *QmlEnginePrivate::constructLogItemTree(const QmlV8ObjectData &objectData)
const QmlV8ObjectData &objectData)
{ {
bool sorted = boolSetting(SortStructMembers); QList<int> handles;
if (!objectData.value.isValid()) return constructLogItemTree(objectData, handles);
return 0; }
void QmlEnginePrivate::constructChildLogItems(ConsoleItem *item, const QmlV8ObjectData &objectData,
QList<int> &seenHandles)
{
// We cannot sort the children after attaching them to the parent as that would cause layout
// changes, invalidating cached indices. So we presort them before inserting.
QVarLengthArray<ConsoleItem *> children(objectData.properties.size());
auto it = children.begin();
foreach (const QVariant &property, objectData.properties)
*(it++) = constructLogItemTree(extractData(property), seenHandles);
if (boolSetting(SortStructMembers))
std::sort(children.begin(), children.end(), compareConsoleItems);
foreach (ConsoleItem *child, children)
item->appendChild(child);
}
ConsoleItem *QmlEnginePrivate::constructLogItemTree(const QmlV8ObjectData &objectData,
QList<int> &seenHandles)
{
QString text; QString text;
if (objectData.name.isEmpty()) if (objectData.value.isValid()) {
text = objectData.value.toString(); text = objectData.value.toString();
else } else if (!objectData.type.isEmpty()) {
text = QString(_("%1: %2")).arg(QString::fromLatin1(objectData.name)) text = QString::fromLatin1(objectData.type);
.arg(objectData.value.toString()); } else {
int handle = objectData.handle;
ConsoleItem *item = new ConsoleItem(ConsoleItem::DefaultType,
QString::fromLatin1(objectData.name),
[this, handle](ConsoleItem *item)
{
DebuggerCommand cmd(LOOKUP);
cmd.arg(HANDLES, QList<int>() << handle);
runCommand(cmd, [this, item, handle](const QVariantMap &response) {
const QVariantMap body = response.value(_(BODY)).toMap();
QStringList handlesList = body.keys();
foreach (const QString &handleString, handlesList) {
if (handle != handleString.toInt())
continue;
ConsoleItem *item = new ConsoleItem(parent, ConsoleItem::UndefinedType, text); QmlV8ObjectData objectData = extractData(body.value(handleString));
QSet<QString> childrenFetched; // keep original name, if possible
foreach (const QVariant &property, objectData.properties) { QString name = item->expression();
const QmlV8ObjectData childObjectData = extractData(property); if (name.isEmpty())
if (childObjectData.handle == objectData.handle) name = QString::fromLatin1(objectData.name);
continue;
ConsoleItem *child = constructLogItemTree(item, childObjectData); QString value = objectData.value.isValid() ?
if (child) { objectData.value.toString() : QString::fromLatin1(objectData.type);
const QString text = child->text();
if (childrenFetched.contains(text)) // We can do setData() and cause dataChanged() here, but only because this
continue; // callback is executed after fetchMore() has returned.
childrenFetched.insert(text); item->model()->setData(item->index(),
item->insertChild(child, sorted); QString::fromLatin1("%1: %2").arg(name).arg(value),
} ConsoleItem::ExpressionRole);
QList<int> newHandles;
constructChildLogItems(item, objectData, newHandles);
break;
}
});
});
return item;
} }
if (!objectData.name.isEmpty())
text = QString(_("%1: %2")).arg(QString::fromLatin1(objectData.name)).arg(text);
if (objectData.properties.isEmpty())
return new ConsoleItem(ConsoleItem::DefaultType, text);
if (seenHandles.contains(objectData.handle)) {
ConsoleItem *item = new ConsoleItem(ConsoleItem::DefaultType, text,
[this, objectData](ConsoleItem *item)
{
QList<int> newHandles;
constructChildLogItems(item, objectData, newHandles);
});
return item;
}
seenHandles.append(objectData.handle);
ConsoleItem *item = new ConsoleItem(ConsoleItem::DefaultType, text);
constructChildLogItems(item, objectData, seenHandles);
seenHandles.removeLast();
return item; return item;
} }
@@ -2397,14 +2489,22 @@ void QmlEnginePrivate::insertSubItems(WatchItem *parent, const QVariantList &pro
void QmlEnginePrivate::handleExecuteDebuggerCommand(const QVariantMap &response) void QmlEnginePrivate::handleExecuteDebuggerCommand(const QVariantMap &response)
{ {
QmlV8ObjectData body = extractData(response.value(_(BODY))); auto consoleManager = ConsoleManagerInterface::instance();
if (auto consoleManager = ConsoleManagerInterface::instance()) { if (!consoleManager)
if (ConsoleItem *item = constructLogItemTree(consoleManager->rootItem(), body)) return;
consoleManager->printToConsolePane(item);
auto it = response.constFind(_(SUCCESS));
if (it != response.constEnd() && it.value().toBool()) {
consoleManager->printToConsolePane(constructLogItemTree(
extractData(response.value(_(BODY)))));
// Update the locals
foreach (int index, currentFrameScopes)
scope(index);
} else {
consoleManager->printToConsolePane(new ConsoleItem(ConsoleItem::ErrorType,
response.value(_(MESSAGE)).toString()));
} }
// Update the locals
foreach (int index, currentFrameScopes)
scope(index);
} }
void QmlEnginePrivate::handleLookup(const QVariantMap &response) void QmlEnginePrivate::handleLookup(const QVariantMap &response)

View File

@@ -250,12 +250,9 @@ void appendDebugOutput(QtMsgType type, const QString &message, const QDebugConte
return; return;
} }
if (auto consoleManager = ConsoleManagerInterface::instance()) { if (auto consoleManager = ConsoleManagerInterface::instance())
ConsoleItem *item = new ConsoleItem(consoleManager->rootItem(), itemType, message); consoleManager->printToConsolePane(new ConsoleItem(itemType, message, info.file,
item->file = info.file; info.line));
item->line = info.line;
consoleManager->printToConsolePane(item);
}
} }
void clearExceptionSelection() void clearExceptionSelection()

View File

@@ -105,6 +105,8 @@ const char REFS[] = "refs";
const char BODY[] = "body"; const char BODY[] = "body";
const char NAME[] = "name"; const char NAME[] = "name";
const char VALUE[] = "value"; const char VALUE[] = "value";
const char SUCCESS[] = "success";
const char MESSAGE[] = "message";
const char OBJECT[] = "{}"; const char OBJECT[] = "{}";
const char ARRAY[] = "[]"; const char ARRAY[] = "[]";

View File

@@ -215,10 +215,10 @@ void QmlConsoleEdit::handleUpKey()
if (model->hasIndex(currentRow, 0)) { if (model->hasIndex(currentRow, 0)) {
QModelIndex index = model->index(currentRow, 0); QModelIndex index = model->index(currentRow, 0);
if (ConsoleItem::InputType == (ConsoleItem::ItemType)model->data( if (ConsoleItem::InputType == (ConsoleItem::ItemType)model->data(
index, QmlConsoleItemModel::TypeRole).toInt()) { index, ConsoleItem::TypeRole).toInt()) {
m_historyIndex = index; m_historyIndex = index;
replaceCurrentScript( replaceCurrentScript(
model->data(index, QmlConsoleItemModel::ExpressionRole).toString()); model->data(index, ConsoleItem::ExpressionRole).toString());
break; break;
} }
} }
@@ -235,13 +235,13 @@ void QmlConsoleEdit::handleDownKey()
if (model->hasIndex(currentRow, 0)) { if (model->hasIndex(currentRow, 0)) {
QModelIndex index = model->index(currentRow, 0); QModelIndex index = model->index(currentRow, 0);
if (ConsoleItem::InputType == (ConsoleItem::ItemType)model->data( if (ConsoleItem::InputType == (ConsoleItem::ItemType)model->data(
index, QmlConsoleItemModel::TypeRole).toInt()) { index, ConsoleItem::TypeRole).toInt()) {
m_historyIndex = index; m_historyIndex = index;
if (currentRow == model->rowCount() - 1) { if (currentRow == model->rowCount() - 1) {
replaceCurrentScript(m_cachedScript); replaceCurrentScript(m_cachedScript);
} else { } else {
replaceCurrentScript( replaceCurrentScript(
model->data(index, QmlConsoleItemModel::ExpressionRole).toString()); model->data(index, ConsoleItem::ExpressionRole).toString());
} }
break; break;
} }

View File

@@ -92,7 +92,7 @@ QColor QmlConsoleItemDelegate::drawBackground(QPainter *painter, const QRect &re
{ {
painter->save(); painter->save();
ConsoleItem::ItemType itemType = (ConsoleItem::ItemType)index.data( ConsoleItem::ItemType itemType = (ConsoleItem::ItemType)index.data(
QmlConsoleItemModel::TypeRole).toInt(); ConsoleItem::TypeRole).toInt();
QColor backgroundColor; QColor backgroundColor;
switch (itemType) { switch (itemType) {
case ConsoleItem::DebugType: case ConsoleItem::DebugType:
@@ -138,7 +138,7 @@ void QmlConsoleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem
QColor textColor; QColor textColor;
QIcon taskIcon; QIcon taskIcon;
ConsoleItem::ItemType type = (ConsoleItem::ItemType)index.data( ConsoleItem::ItemType type = (ConsoleItem::ItemType)index.data(
QmlConsoleItemModel::TypeRole).toInt(); ConsoleItem::TypeRole).toInt();
switch (type) { switch (type) {
case ConsoleItem::DebugType: case ConsoleItem::DebugType:
textColor = QColor(CONSOLE_LOG_TEXT_COLOR); textColor = QColor(CONSOLE_LOG_TEXT_COLOR);
@@ -175,7 +175,7 @@ void QmlConsoleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem
} }
int width = view->width() - level * view->indentation() - view->verticalScrollBar()->width(); int width = view->width() - level * view->indentation() - view->verticalScrollBar()->width();
bool showTypeIcon = index.parent() == QModelIndex(); bool showTypeIcon = index.parent() == QModelIndex();
bool showExpandableIcon = type == ConsoleItem::UndefinedType; bool showExpandableIcon = type == ConsoleItem::DefaultType;
QRect rect(opt.rect.x(), opt.rect.top(), width, opt.rect.height()); QRect rect(opt.rect.x(), opt.rect.top(), width, opt.rect.height());
ConsoleItemPositions positions(rect, opt.font, showTypeIcon, showExpandableIcon); ConsoleItemPositions positions(rect, opt.font, showTypeIcon, showExpandableIcon);
@@ -206,7 +206,7 @@ void QmlConsoleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem
if (showExpandableIcon) { if (showExpandableIcon) {
// Paint ExpandableIconArea: // Paint ExpandableIconArea:
QIcon expandCollapseIcon; QIcon expandCollapseIcon;
if (index.model()->rowCount(index)) { if (index.model()->rowCount(index) || index.model()->canFetchMore(index)) {
if (view->isExpanded(index)) if (view->isExpanded(index))
expandCollapseIcon = m_collapseIcon; expandCollapseIcon = m_collapseIcon;
else else
@@ -219,7 +219,7 @@ void QmlConsoleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem
if (showFileLineInfo) { if (showFileLineInfo) {
// Check for file info // Check for file info
QString file = index.data(QmlConsoleItemModel::FileRole).toString(); QString file = index.data(ConsoleItem::FileRole).toString();
const QUrl fileUrl = QUrl(file); const QUrl fileUrl = QUrl(file);
if (fileUrl.isLocalFile()) if (fileUrl.isLocalFile())
file = fileUrl.toLocalFile(); file = fileUrl.toLocalFile();
@@ -244,7 +244,7 @@ void QmlConsoleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem
} }
// Paint LineArea // Paint LineArea
QString lineText = index.data(QmlConsoleItemModel::LineRole).toString(); QString lineText = index.data(ConsoleItem::LineRole).toString();
painter->setClipRect(positions.lineArea()); painter->setClipRect(positions.lineArea());
const int realLineWidth = fm.width(lineText); const int realLineWidth = fm.width(lineText);
painter->drawText(positions.lineAreaRight() - realLineWidth, painter->drawText(positions.lineAreaRight() - realLineWidth,
@@ -277,9 +277,9 @@ QSize QmlConsoleItemDelegate::sizeHint(const QStyleOptionViewItem &option,
return QSize(width, m_cachedHeight); return QSize(width, m_cachedHeight);
ConsoleItem::ItemType type = (ConsoleItem::ItemType)index.data( ConsoleItem::ItemType type = (ConsoleItem::ItemType)index.data(
QmlConsoleItemModel::TypeRole).toInt(); ConsoleItem::TypeRole).toInt();
bool showTypeIcon = index.parent() == QModelIndex(); bool showTypeIcon = index.parent() == QModelIndex();
bool showExpandableIcon = type == ConsoleItem::UndefinedType; bool showExpandableIcon = type == ConsoleItem::DefaultType;
QRect rect(level * view->indentation(), 0, width, 0); QRect rect(level * view->indentation(), 0, width, 0);
ConsoleItemPositions positions(rect, opt.font, showTypeIcon, showExpandableIcon); ConsoleItemPositions positions(rect, opt.font, showTypeIcon, showExpandableIcon);
@@ -322,7 +322,7 @@ void QmlConsoleItemDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const const QModelIndex &index) const
{ {
QmlConsoleEdit *edtr = qobject_cast<QmlConsoleEdit *>(editor); QmlConsoleEdit *edtr = qobject_cast<QmlConsoleEdit *>(editor);
edtr->insertPlainText(index.data(QmlConsoleItemModel::ExpressionRole).toString()); edtr->insertPlainText(index.data(ConsoleItem::ExpressionRole).toString());
} }
void QmlConsoleItemDelegate::setModelData(QWidget *editor, void QmlConsoleItemDelegate::setModelData(QWidget *editor,
@@ -330,8 +330,8 @@ void QmlConsoleItemDelegate::setModelData(QWidget *editor,
const QModelIndex &index) const const QModelIndex &index) const
{ {
QmlConsoleEdit *edtr = qobject_cast<QmlConsoleEdit *>(editor); QmlConsoleEdit *edtr = qobject_cast<QmlConsoleEdit *>(editor);
model->setData(index, edtr->getCurrentScript(), Qt::DisplayRole); model->setData(index, edtr->getCurrentScript(), ConsoleItem::ExpressionRole);
model->setData(index, ConsoleItem::InputType, QmlConsoleItemModel::TypeRole); model->setData(index, ConsoleItem::InputType, ConsoleItem::TypeRole);
} }
void QmlConsoleItemDelegate::updateEditorGeometry(QWidget *editor, void QmlConsoleItemDelegate::updateEditorGeometry(QWidget *editor,

View File

@@ -45,89 +45,55 @@ namespace Internal {
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
QmlConsoleItemModel::QmlConsoleItemModel(QObject *parent) : QmlConsoleItemModel::QmlConsoleItemModel(QObject *parent) :
QAbstractItemModel(parent), Utils::TreeModel(new ConsoleItem, parent),
m_hasEditableRow(false),
m_rootItem(new ConsoleItem(0)),
m_maxSizeOfFileName(0) m_maxSizeOfFileName(0)
{ {
} clear();
QmlConsoleItemModel::~QmlConsoleItemModel()
{
delete m_rootItem;
} }
void QmlConsoleItemModel::clear() void QmlConsoleItemModel::clear()
{ {
beginResetModel(); Utils::TreeModel::clear();
delete m_rootItem; appendItem(new ConsoleItem(ConsoleItem::InputType));
m_rootItem = new ConsoleItem(0); emit selectEditableRow(index(0, 0, QModelIndex()), QItemSelectionModel::ClearAndSelect);
endResetModel();
if (m_hasEditableRow)
appendEditableRow();
} }
bool QmlConsoleItemModel::appendItem(ConsoleItem *item, int position) void QmlConsoleItemModel::appendItem(ConsoleItem *item, int position)
{ {
if (position < 0) if (position < 0)
position = m_rootItem->childCount() - 1; position = rootItem()->childCount() - 1; // append before editable row
if (position < 0) if (position < 0)
position = 0; position = 0;
beginInsertRows(QModelIndex(), position, position); rootItem()->insertChild(position, item);
bool success = m_rootItem->insertChild(position, item);
endInsertRows();
return success;
} }
bool QmlConsoleItemModel::appendMessage(ConsoleItem::ItemType itemType, void QmlConsoleItemModel::appendMessage(ConsoleItem::ItemType itemType,
const QString &message, int position) const QString &message, int position)
{ {
return appendItem(new ConsoleItem(m_rootItem, itemType, message), position); appendItem(new ConsoleItem(itemType, message), position);
} }
void QmlConsoleItemModel::setHasEditableRow(bool hasEditableRow) void QmlConsoleItemModel::shiftEditableRow()
{ {
if (m_hasEditableRow && !hasEditableRow) int position = rootItem()->childCount();
removeEditableRow(); Q_ASSERT(position > 0);
if (!m_hasEditableRow && hasEditableRow) // Disable editing for old editable row
appendEditableRow(); rootItem()->lastChild()->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
m_hasEditableRow = hasEditableRow; appendItem(new ConsoleItem(ConsoleItem::InputType), position);
} emit selectEditableRow(index(position, 0, QModelIndex()), QItemSelectionModel::ClearAndSelect);
bool QmlConsoleItemModel::hasEditableRow() const
{
return m_hasEditableRow;
}
void QmlConsoleItemModel::appendEditableRow()
{
int position = m_rootItem->childCount();
if (appendItem(new ConsoleItem(m_rootItem, ConsoleItem::InputType), position))
emit selectEditableRow(index(position, 0), QItemSelectionModel::ClearAndSelect);
}
void QmlConsoleItemModel::removeEditableRow()
{
if (m_rootItem->child(m_rootItem->childCount() - 1)->itemType == ConsoleItem::InputType)
removeRow(m_rootItem->childCount() - 1);
} }
int QmlConsoleItemModel::sizeOfFile(const QFont &font) int QmlConsoleItemModel::sizeOfFile(const QFont &font)
{ {
int lastReadOnlyRow = m_rootItem->childCount(); int lastReadOnlyRow = rootItem()->childCount();
if (m_hasEditableRow) lastReadOnlyRow -= 2; // skip editable row
lastReadOnlyRow -= 2;
else
lastReadOnlyRow -= 1;
if (lastReadOnlyRow < 0) if (lastReadOnlyRow < 0)
return 0; return 0;
QString filename = m_rootItem->child(lastReadOnlyRow)->file; QString filename = static_cast<ConsoleItem *>(rootItem()->child(lastReadOnlyRow))->file();
const int pos = filename.lastIndexOf(QLatin1Char('/')); const int pos = filename.lastIndexOf(QLatin1Char('/'));
if (pos != -1) if (pos != -1)
filename = filename.mid(pos + 1); filename = filename.mid(pos + 1);
@@ -144,141 +110,5 @@ int QmlConsoleItemModel::sizeOfLineNumber(const QFont &font)
return fm.width(QLatin1String("88888")); return fm.width(QLatin1String("88888"));
} }
QVariant QmlConsoleItemModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
ConsoleItem *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 if (role == QmlConsoleItemModel::ExpressionRole)
return item->expression();
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();
ConsoleItem *parentItem = getItem(parent);
ConsoleItem *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();
ConsoleItem *childItem = getItem(index);
ConsoleItem *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
{
ConsoleItem *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;
ConsoleItem *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)
{
ConsoleItem *item = getItem(index);
bool result = false;
if (role == Qt::DisplayRole) {
item->setText(value.toString());
result = true;
} else if (role == QmlConsoleItemModel::TypeRole) {
item->itemType = (ConsoleItem::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)
{
ConsoleItem *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)
{
ConsoleItem *parentItem = getItem(parent);
bool success = true;
beginRemoveRows(parent, position, position + rows - 1);
success = parentItem->removeChildren(position, rows);
endRemoveRows();
return success;
}
ConsoleItem *QmlConsoleItemModel::getItem(const QModelIndex &index) const
{
if (index.isValid()) {
ConsoleItem *item = static_cast<ConsoleItem*>(index.internalPointer());
if (item)
return item;
}
return m_rootItem;
}
} // Internal } // Internal
} // QmlJSTools } // QmlJSTools

View File

@@ -32,8 +32,8 @@
#define QMLCONSOLEITEMMODEL_H #define QMLCONSOLEITEMMODEL_H
#include <qmljs/consoleitem.h> #include <qmljs/consoleitem.h>
#include <utils/treemodel.h>
#include <QAbstractItemModel>
#include <QItemSelectionModel> #include <QItemSelectionModel>
QT_FORWARD_DECLARE_CLASS(QFont) QT_FORWARD_DECLARE_CLASS(QFont)
@@ -41,58 +41,29 @@ QT_FORWARD_DECLARE_CLASS(QFont)
namespace QmlJSTools { namespace QmlJSTools {
namespace Internal { namespace Internal {
class QmlConsoleItemModel : public QAbstractItemModel class QmlConsoleItemModel : public Utils::TreeModel
{ {
Q_OBJECT Q_OBJECT
public: public:
enum Roles { TypeRole = Qt::UserRole, FileRole, LineRole, ExpressionRole };
explicit QmlConsoleItemModel(QObject *parent = 0); explicit QmlConsoleItemModel(QObject *parent = 0);
~QmlConsoleItemModel();
void setHasEditableRow(bool hasEditableRow); void shiftEditableRow();
bool hasEditableRow() const;
void appendEditableRow();
void removeEditableRow();
bool appendItem(QmlJS::ConsoleItem *item, int position = -1); void appendItem(QmlJS::ConsoleItem *item, int position = -1);
bool appendMessage(QmlJS::ConsoleItem::ItemType itemType, const QString &message, void appendMessage(QmlJS::ConsoleItem::ItemType itemType, const QString &message,
int position = -1); int position = -1);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int sizeOfFile(const QFont &font); int sizeOfFile(const QFont &font);
int sizeOfLineNumber(const QFont &font); int sizeOfLineNumber(const QFont &font);
QmlJS::ConsoleItem *root() const { return m_rootItem; }
public slots: public slots:
void clear(); void clear();
signals: signals:
void selectEditableRow(const QModelIndex &index, QItemSelectionModel::SelectionFlags flags); 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());
QmlJS::ConsoleItem *getItem(const QModelIndex &index) const;
private: private:
bool m_hasEditableRow;
QmlJS::ConsoleItem *m_rootItem;
int m_maxSizeOfFileName; int m_maxSizeOfFileName;
}; };

View File

@@ -57,7 +57,6 @@ QmlConsoleManager::QmlConsoleManager(QObject *parent)
d(new QmlConsoleManagerPrivate) d(new QmlConsoleManagerPrivate)
{ {
d->qmlConsoleItemModel = new Internal::QmlConsoleItemModel(this); d->qmlConsoleItemModel = new Internal::QmlConsoleItemModel(this);
d->qmlConsoleItemModel->setHasEditableRow(true);
d->qmlConsolePane = new Internal::QmlConsolePane(this); d->qmlConsolePane = new Internal::QmlConsolePane(this);
d->scriptEvaluator = 0; d->scriptEvaluator = 0;
ExtensionSystem::PluginManager::addObject(d->qmlConsolePane); ExtensionSystem::PluginManager::addObject(d->qmlConsolePane);
@@ -76,11 +75,6 @@ void QmlConsoleManager::showConsolePane()
d->qmlConsolePane->popup(Core::IOutputPane::ModeSwitch); d->qmlConsolePane->popup(Core::IOutputPane::ModeSwitch);
} }
ConsoleItem *QmlConsoleManager::rootItem() const
{
return d->qmlConsoleItemModel->root();
}
void QmlConsoleManager::setScriptEvaluator(IScriptEvaluator *scriptEvaluator) void QmlConsoleManager::setScriptEvaluator(IScriptEvaluator *scriptEvaluator)
{ {
d->scriptEvaluator = scriptEvaluator; d->scriptEvaluator = scriptEvaluator;
@@ -109,7 +103,7 @@ void QmlConsoleManager::printToConsolePane(ConsoleItem *item, bool bringToForegr
{ {
if (!d->qmlConsolePane) if (!d->qmlConsolePane)
return; return;
if (item->itemType == ConsoleItem::ErrorType) if (item->itemType() == ConsoleItem::ErrorType)
bringToForeground = true; bringToForeground = true;
if (bringToForeground) if (bringToForeground)
d->qmlConsolePane->popup(Core::IOutputPane::ModeSwitch); d->qmlConsolePane->popup(Core::IOutputPane::ModeSwitch);
@@ -118,47 +112,6 @@ void QmlConsoleManager::printToConsolePane(ConsoleItem *item, bool bringToForegr
namespace Internal { namespace Internal {
ConsoleItem *constructLogItemTree(ConsoleItem *parent, const QVariant &result,
const QString &key = QString())
{
if (!result.isValid())
return 0;
ConsoleItem *item = new ConsoleItem(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();
ConsoleItem *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::fromLatin1("[%1] : List").arg(key));
QVariantList resultList = result.toList();
for (int i = 0; i < resultList.count(); i++) {
ConsoleItem *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() QmlConsoleItemModel *QmlConsoleModel::qmlConsoleItemModel()
{ {
QmlConsoleManager *manager = qobject_cast<QmlConsoleManager *>(QmlConsoleManager::instance()); QmlConsoleManager *manager = qobject_cast<QmlConsoleManager *>(QmlConsoleManager::instance());
@@ -172,15 +125,15 @@ void QmlConsoleModel::evaluate(const QString &expression)
QmlConsoleManager *manager = qobject_cast<QmlConsoleManager *>(QmlConsoleManager::instance()); QmlConsoleManager *manager = qobject_cast<QmlConsoleManager *>(QmlConsoleManager::instance());
if (manager) { if (manager) {
if (manager->d->scriptEvaluator) { if (manager->d->scriptEvaluator) {
QmlConsoleModel::qmlConsoleItemModel()->appendEditableRow(); QmlConsoleModel::qmlConsoleItemModel()->shiftEditableRow();
manager->d->scriptEvaluator->evaluateScript(expression); manager->d->scriptEvaluator->evaluateScript(expression);
} else { } else {
ConsoleItem *root = manager->rootItem(); ConsoleItem *item = new ConsoleItem(
ConsoleItem *item = constructLogItemTree( ConsoleItem::ErrorType, QCoreApplication::translate(
root, QCoreApplication::translate("QmlJSTools::Internal::QmlConsoleModel", "QmlJSTools::Internal::QmlConsoleModel",
"Can only evaluate during a QML debug session.")); "Can only evaluate during a QML debug session."));
if (item) { if (item) {
QmlConsoleModel::qmlConsoleItemModel()->appendEditableRow(); QmlConsoleModel::qmlConsoleItemModel()->shiftEditableRow();
manager->printToConsolePane(item); manager->printToConsolePane(item);
} }
} }

View File

@@ -52,8 +52,6 @@ public:
void showConsolePane(); void showConsolePane();
QmlJS::ConsoleItem *rootItem() const;
void setScriptEvaluator(QmlJS::IScriptEvaluator *scriptEvaluator); void setScriptEvaluator(QmlJS::IScriptEvaluator *scriptEvaluator);
void setContext(const QString &context); void setContext(const QString &context);

View File

@@ -38,7 +38,7 @@ namespace Internal {
QmlConsoleProxyModel::QmlConsoleProxyModel(QObject *parent) : QmlConsoleProxyModel::QmlConsoleProxyModel(QObject *parent) :
QSortFilterProxyModel(parent), QSortFilterProxyModel(parent),
m_filter(ConsoleItem::DefaultTypes) m_filter(ConsoleItem::DefaultType | ConsoleItem::InputType)
{ {
} }
@@ -72,7 +72,7 @@ bool QmlConsoleProxyModel::filterAcceptsRow(int sourceRow,
{ {
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
return m_filter.testFlag((ConsoleItem::ItemType)sourceModel()->data( return m_filter.testFlag((ConsoleItem::ItemType)sourceModel()->data(
index, QmlConsoleItemModel::TypeRole).toInt()); index, ConsoleItem::TypeRole).toInt());
} }
void QmlConsoleProxyModel::onRowsInserted(const QModelIndex &index, int start, int end) void QmlConsoleProxyModel::onRowsInserted(const QModelIndex &index, int start, int end)

View File

@@ -147,9 +147,9 @@ void QmlConsoleView::mousePressEvent(QMouseEvent *event)
QModelIndex index = indexAt(pos); QModelIndex index = indexAt(pos);
if (index.isValid()) { if (index.isValid()) {
ConsoleItem::ItemType type = (ConsoleItem::ItemType)index.data( ConsoleItem::ItemType type = (ConsoleItem::ItemType)index.data(
QmlConsoleItemModel::TypeRole).toInt(); ConsoleItem::TypeRole).toInt();
bool handled = false; bool handled = false;
if (type == ConsoleItem::UndefinedType) { if (type == ConsoleItem::DefaultType) {
bool showTypeIcon = index.parent() == QModelIndex(); bool showTypeIcon = index.parent() == QModelIndex();
ConsoleItemPositions positions(visualRect(index), viewOptions().font, showTypeIcon, ConsoleItemPositions positions(visualRect(index), viewOptions().font, showTypeIcon,
true); true);
@@ -222,14 +222,14 @@ void QmlConsoleView::onRowActivated(const QModelIndex &index)
return; return;
// See if we have file and line Info // See if we have file and line Info
QString filePath = model()->data(index, QmlConsoleItemModel::FileRole).toString(); QString filePath = model()->data(index, ConsoleItem::FileRole).toString();
const QUrl fileUrl = QUrl(filePath); const QUrl fileUrl = QUrl(filePath);
if (fileUrl.isLocalFile()) if (fileUrl.isLocalFile())
filePath = fileUrl.toLocalFile(); filePath = fileUrl.toLocalFile();
if (!filePath.isEmpty()) { if (!filePath.isEmpty()) {
QFileInfo fi(filePath); QFileInfo fi(filePath);
if (fi.exists() && fi.isFile() && fi.isReadable()) { if (fi.exists() && fi.isFile() && fi.isReadable()) {
int line = model()->data(index, QmlConsoleItemModel::LineRole).toInt(); int line = model()->data(index, ConsoleItem::LineRole).toInt();
Core::EditorManager::openEditorAt(fi.canonicalFilePath(), line); Core::EditorManager::openEditorAt(fi.canonicalFilePath(), line);
} }
} }
@@ -240,15 +240,15 @@ void QmlConsoleView::copyToClipboard(const QModelIndex &index)
if (!index.isValid()) if (!index.isValid())
return; return;
QString contents = model()->data(index, QmlConsoleItemModel::ExpressionRole).toString(); QString contents = model()->data(index, ConsoleItem::ExpressionRole).toString();
// See if we have file and line Info // See if we have file and line Info
QString filePath = model()->data(index, QmlConsoleItemModel::FileRole).toString(); QString filePath = model()->data(index, ConsoleItem::FileRole).toString();
const QUrl fileUrl = QUrl(filePath); const QUrl fileUrl = QUrl(filePath);
if (fileUrl.isLocalFile()) if (fileUrl.isLocalFile())
filePath = fileUrl.toLocalFile(); filePath = fileUrl.toLocalFile();
if (!filePath.isEmpty()) { if (!filePath.isEmpty()) {
contents = QString::fromLatin1("%1 %2: %3").arg(contents).arg(filePath).arg( contents = QString::fromLatin1("%1 %2: %3").arg(contents).arg(filePath).arg(
model()->data(index, QmlConsoleItemModel::LineRole).toString()); model()->data(index, ConsoleItem::LineRole).toString());
} }
QClipboard *cb = QApplication::clipboard(); QClipboard *cb = QApplication::clipboard();
cb->setText(contents); cb->setText(contents);
@@ -260,7 +260,7 @@ bool QmlConsoleView::canShowItemInTextEditor(const QModelIndex &index)
return false; return false;
// See if we have file and line Info // See if we have file and line Info
QString filePath = model()->data(index, QmlConsoleItemModel::FileRole).toString(); QString filePath = model()->data(index, ConsoleItem::FileRole).toString();
const QUrl fileUrl = QUrl(filePath); const QUrl fileUrl = QUrl(filePath);
if (fileUrl.isLocalFile()) if (fileUrl.isLocalFile())
filePath = fileUrl.toLocalFile(); filePath = fileUrl.toLocalFile();