aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libs/qmljsdebugclient/qdebugmessageclient.cpp15
-rw-r--r--src/libs/qmljsdebugclient/qdebugmessageclient.h10
-rw-r--r--src/plugins/debugger/debuggerengine.cpp12
-rw-r--r--src/plugins/debugger/debuggerengine.h2
-rw-r--r--src/plugins/debugger/qml/qmlengine.cpp42
-rw-r--r--src/plugins/debugger/qml/qmlengine.h5
-rw-r--r--src/plugins/debugger/qtmessagelogeditor.cpp4
-rw-r--r--src/plugins/debugger/qtmessageloghandler.cpp103
-rw-r--r--src/plugins/debugger/qtmessageloghandler.h57
-rw-r--r--src/plugins/debugger/qtmessagelogitemdelegate.cpp72
-rw-r--r--src/plugins/debugger/qtmessagelogitemdelegate.h36
-rw-r--r--src/plugins/debugger/qtmessagelogview.cpp143
-rw-r--r--src/plugins/debugger/qtmessagelogview.h9
-rw-r--r--src/plugins/debugger/qtmessagelogwindow.cpp7
-rw-r--r--src/plugins/debugger/qtmessagelogwindow.h2
15 files changed, 390 insertions, 129 deletions
diff --git a/src/libs/qmljsdebugclient/qdebugmessageclient.cpp b/src/libs/qmljsdebugclient/qdebugmessageclient.cpp
index a140fdeaba1..6da461eb3de 100644
--- a/src/libs/qmljsdebugclient/qdebugmessageclient.cpp
+++ b/src/libs/qmljsdebugclient/qdebugmessageclient.cpp
@@ -63,12 +63,21 @@ void QDebugMessageClient::messageReceived(const QByteArray &data)
int type;
QDataStream ms(messagePacket);
ms >> type >> debugMessage;
- emit message(QtMsgType(type), QString::fromUtf8(debugMessage.data()));
+ QDebugContextInfo info;
+ emit message(QtMsgType(type), QString::fromUtf8(debugMessage.data()),
+ info);
} else {
int type;
+ int line;
QByteArray debugMessage;
- ds >> type >> debugMessage;
- emit message(QtMsgType(type), QString::fromUtf8(debugMessage));
+ QByteArray file;
+ QByteArray function;
+ ds >> type >> debugMessage >> file >> line >> function;
+ QDebugContextInfo info;
+ info.line = line;
+ info.file = QString::fromUtf8(file);
+ info.function = QString::fromUtf8(function);
+ emit message(QtMsgType(type), QString::fromUtf8(debugMessage), info);
}
}
}
diff --git a/src/libs/qmljsdebugclient/qdebugmessageclient.h b/src/libs/qmljsdebugclient/qdebugmessageclient.h
index 032e3b2c508..36381392d3a 100644
--- a/src/libs/qmljsdebugclient/qdebugmessageclient.h
+++ b/src/libs/qmljsdebugclient/qdebugmessageclient.h
@@ -39,6 +39,13 @@
namespace QmlJsDebugClient {
class QDebugMessageClientPrivate;
+struct QDebugContextInfo
+{
+ int line;
+ QString file;
+ QString function;
+};
+
class QMLJSDEBUGCLIENT_EXPORT QDebugMessageClient : public QDeclarativeDebugClient
{
Q_OBJECT
@@ -53,7 +60,8 @@ protected:
signals:
void newStatus(QDeclarativeDebugClient::Status);
- void message(QtMsgType, const QString &);
+ void message(QtMsgType, const QString &,
+ const QmlJsDebugClient::QDebugContextInfo &);
private:
class QDebugMessageClientPrivate *d;
diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp
index ccd03eb75c3..36ce8e53456 100644
--- a/src/plugins/debugger/debuggerengine.cpp
+++ b/src/plugins/debugger/debuggerengine.cpp
@@ -66,6 +66,7 @@
#include <utils/savedaction.h>
#include <utils/qtcassert.h>
+#include <utils/fileinprojectfinder.h>
#include <QDebug>
#include <QTimer>
@@ -312,6 +313,7 @@ public:
bool m_isStateDebugging;
+ Utils::FileInProjectFinder m_fileFinder;
// Testing
void handleAutoTests();
void handleAutoTestLine(int line);
@@ -1282,6 +1284,16 @@ DebuggerLanguages DebuggerEngine::languages() const
return d->m_languages;
}
+QString DebuggerEngine::toFileInProject(const QUrl &fileUrl)
+{
+ // make sure file finder is properly initialized
+ d->m_fileFinder.setProjectDirectory(startParameters().projectSourceDirectory);
+ d->m_fileFinder.setProjectFiles(startParameters().projectSourceFiles);
+ d->m_fileFinder.setSysroot(startParameters().sysroot);
+
+ return d->m_fileFinder.findFile(fileUrl);
+}
+
bool DebuggerEngine::debuggerActionsEnabled() const
{
return debuggerActionsEnabled(d->m_state);
diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h
index 5c5eeedb58f..1e559e3e658 100644
--- a/src/plugins/debugger/debuggerengine.h
+++ b/src/plugins/debugger/debuggerengine.h
@@ -286,6 +286,8 @@ public:
virtual void notifyInferiorIll();
+ QString toFileInProject(const QUrl &fileUrl);
+
signals:
void stateChanged(const Debugger::DebuggerState &state);
// A new stack frame is on display including locals.
diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp
index 541d7b37d87..53ca0368a03 100644
--- a/src/plugins/debugger/qml/qmlengine.cpp
+++ b/src/plugins/debugger/qml/qmlengine.cpp
@@ -58,11 +58,9 @@
#include <projectexplorer/applicationlauncher.h>
#include <qmljsdebugclient/qdeclarativeoutputparser.h>
#include <qmljseditor/qmljseditorconstants.h>
-#include <qmljsdebugclient/qdebugmessageclient.h>
#include <utils/environment.h>
#include <utils/qtcassert.h>
-#include <utils/fileinprojectfinder.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
@@ -110,7 +108,6 @@ private:
friend class QmlEngine;
QmlAdapter m_adapter;
ApplicationLauncher m_applicationLauncher;
- Utils::FileInProjectFinder fileFinder;
QTimer m_noDebugOutputTimer;
QmlJsDebugClient::QDeclarativeOutputParser m_outputParser;
QHash<QString, QTextDocument*> m_sourceDocuments;
@@ -157,8 +154,11 @@ QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters,
SLOT(updateCurrentContext()));
connect(&d->m_adapter, SIGNAL(selectionChanged()),
SLOT(updateCurrentContext()));
- connect(d->m_adapter.messageClient(), SIGNAL(message(QtMsgType,QString)),
- SLOT(appendDebugOutput(QtMsgType,QString)));
+ connect(d->m_adapter.messageClient(),
+ SIGNAL(message(QtMsgType,QString,
+ QmlJsDebugClient::QDebugContextInfo)),
+ SLOT(appendDebugOutput(QtMsgType,QString,
+ QmlJsDebugClient::QDebugContextInfo)));
connect(&d->m_applicationLauncher,
SIGNAL(processExited(int)),
@@ -852,16 +852,6 @@ bool QmlEngine::hasCapability(unsigned cap) const
| AddWatcherCapability;*/
}
-QString QmlEngine::toFileInProject(const QUrl &fileUrl)
-{
- // make sure file finder is properly initialized
- d->fileFinder.setProjectDirectory(startParameters().projectSourceDirectory);
- d->fileFinder.setProjectFiles(startParameters().projectSourceFiles);
- d->fileFinder.setSysroot(startParameters().sysroot);
-
- return d->fileFinder.findFile(fileUrl);
-}
-
void QmlEngine::inferiorSpontaneousStop()
{
if (state() == InferiorRunOk)
@@ -892,7 +882,8 @@ void QmlEngine::updateCurrentContext()
showMessage(tr("Context: ").append(context), QtMessageLogStatus);
}
-void QmlEngine::appendDebugOutput(QtMsgType type, const QString &message)
+void QmlEngine::appendDebugOutput(QtMsgType type, const QString &message,
+ const QmlJsDebugClient::QDebugContextInfo &info)
{
QtMessageLogHandler::ItemType itemType;
switch (type) {
@@ -910,7 +901,10 @@ void QmlEngine::appendDebugOutput(QtMsgType type, const QString &message)
//This case is not possible
return;
}
- qtMessageLogHandler()->appendItem(new QtMessageLogItem(itemType, message));
+ QtMessageLogItem *item = new QtMessageLogItem(itemType, message);
+ item->file = info.file;
+ item->line = info.line;
+ qtMessageLogHandler()->appendItem(item);
}
void QmlEngine::executeDebuggerCommand(const QString& command)
@@ -987,7 +981,7 @@ void QmlEngine::setSourceFiles(const QStringList &fileNames)
QMap<QString,QString> files;
foreach (const QString &file, fileNames) {
QString shortName = file;
- QString fullName = d->fileFinder.findFile(file);
+ QString fullName = toFileInProject(file);
files.insert(shortName, fullName);
}
@@ -1080,9 +1074,9 @@ QtMessageLogItem *QmlEngine::constructLogItemTree(
QtMessageLogItem *item = new QtMessageLogItem();
if (result.type() == QVariant::Map) {
if (key.isEmpty())
- item->setText(_("Object"));
+ item->text = _("Object");
else
- item->setText(QString(_("%1: Object")).arg(key));
+ item->text = QString(_("%1: Object")).arg(key);
QMapIterator<QString, QVariant> i(result.toMap());
while (i.hasNext()) {
@@ -1093,9 +1087,9 @@ QtMessageLogItem *QmlEngine::constructLogItemTree(
}
} else if (result.type() == QVariant::List) {
if (key.isEmpty())
- item->setText(_("List"));
+ item->text = _("List");
else
- item->setText(QString(_("[%1] : List")).arg(key));
+ item->text = QString(_("[%1] : List")).arg(key);
QVariantList resultList = result.toList();
for (int i = 0; i < resultList.count(); i++) {
QtMessageLogItem *child = constructLogItemTree(resultList.at(i),
@@ -1104,9 +1098,9 @@ QtMessageLogItem *QmlEngine::constructLogItemTree(
item->insertChild(item->childCount(), child);
}
} else if (result.canConvert(QVariant::String)) {
- item->setText(result.toString());
+ item->text = result.toString();
} else {
- item->setText(_("Unknown Value"));
+ item->text = _("Unknown Value");
}
return item;
diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h
index c6170bbc917..fc7c47c268b 100644
--- a/src/plugins/debugger/qml/qmlengine.h
+++ b/src/plugins/debugger/qml/qmlengine.h
@@ -35,6 +35,7 @@
#include "debuggerengine.h"
#include <qmljsdebugclient/qdeclarativeenginedebug.h>
+#include <qmljsdebugclient/qdebugmessageclient.h>
#include <utils/outputformat.h>
#include <QAbstractSocket>
@@ -80,7 +81,6 @@ public:
void gotoLocation(const Internal::Location &location);
void filterApplicationMessage(const QString &msg, int channel);
- QString toFileInProject(const QUrl &fileUrl);
void inferiorSpontaneousStop();
void logMessage(const QString &service, LogDirection direction, const QString &str);
@@ -98,7 +98,8 @@ private slots:
void wrongSetupMessageBox(const QString &errorMessage);
void wrongSetupMessageBoxFinished(int result);
void updateCurrentContext();
- void appendDebugOutput(QtMsgType type, const QString &message);
+ void appendDebugOutput(QtMsgType type, const QString &message,
+ const QmlJsDebugClient::QDebugContextInfo &info);
private:
// DebuggerEngine implementation.
diff --git a/src/plugins/debugger/qtmessagelogeditor.cpp b/src/plugins/debugger/qtmessagelogeditor.cpp
index 2d95d4caf1f..62e3fdf821d 100644
--- a/src/plugins/debugger/qtmessagelogeditor.cpp
+++ b/src/plugins/debugger/qtmessagelogeditor.cpp
@@ -164,6 +164,10 @@ void QtMessageLogEditor::keyPressEvent(QKeyEvent *e)
void QtMessageLogEditor::contextMenuEvent(QContextMenuEvent *event)
{
+ //TODO:: on right click the editor closes
+ //FIXIT
+ return QTextEdit::contextMenuEvent(event);
+
QTextCursor cursor = textCursor();
bool editable = cursor.position() > m_startOfEditableArea;
QMenu *menu = new QMenu();
diff --git a/src/plugins/debugger/qtmessageloghandler.cpp b/src/plugins/debugger/qtmessageloghandler.cpp
index a9bf672ea69..e8eae4038ae 100644
--- a/src/plugins/debugger/qtmessageloghandler.cpp
+++ b/src/plugins/debugger/qtmessageloghandler.cpp
@@ -32,6 +32,10 @@
#include "qtmessageloghandler.h"
+#include <utils/qtcassert.h>
+
+#include <QFontMetrics>
+
namespace Debugger {
namespace Internal {
@@ -43,9 +47,10 @@ namespace Internal {
QtMessageLogItem::QtMessageLogItem(QtMessageLogHandler::ItemType itemType,
const QString &text, QtMessageLogItem *parent)
- : m_text(text),
- m_itemType(itemType),
- m_parentItem(parent)
+ : m_parentItem(parent),
+ text(text),
+ itemType(itemType),
+ line(-1)
{
}
@@ -62,34 +67,27 @@ QtMessageLogItem *QtMessageLogItem::child(int number)
int QtMessageLogItem::childCount() const
{
- return m_childItems.count();
+ return m_childItems.size();
}
int QtMessageLogItem::childNumber() const
{
if (m_parentItem)
- return m_parentItem->m_childItems.indexOf(const_cast<QtMessageLogItem *>(this));
+ return m_parentItem->m_childItems.indexOf(
+ const_cast<QtMessageLogItem *>(this));
return 0;
}
-QString QtMessageLogItem::text() const
-{
- return m_text;
-}
-
-QtMessageLogHandler::ItemType QtMessageLogItem::itemType() const
-{
- return m_itemType;
-}
-\
bool QtMessageLogItem::insertChildren(int position, int count)
{
if (position < 0 || position > m_childItems.size())
return false;
for (int row = 0; row < count; ++row) {
- QtMessageLogItem *item = new QtMessageLogItem(QtMessageLogHandler::UndefinedType, QString(), this);
+ QtMessageLogItem *item = new
+ QtMessageLogItem(QtMessageLogHandler::UndefinedType, QString(),
+ this);
m_childItems.insert(position, item);
}
@@ -136,18 +134,6 @@ bool QtMessageLogItem::detachChild(int position)
return true;
}
-bool QtMessageLogItem::setText(const QString &text)
-{
- m_text = text;
- return true;
-}
-
-bool QtMessageLogItem::setItemType(QtMessageLogHandler::ItemType itemType)
-{
- m_itemType = itemType;
- return true;
-}
-
///////////////////////////////////////////////////////////////////////
//
// QtMessageLogHandler
@@ -157,7 +143,8 @@ bool QtMessageLogItem::setItemType(QtMessageLogHandler::ItemType itemType)
QtMessageLogHandler::QtMessageLogHandler(QObject *parent) :
QAbstractItemModel(parent),
m_hasEditableRow(false),
- m_rootItem(new QtMessageLogItem())
+ m_rootItem(new QtMessageLogItem()),
+ m_maxSizeOfFileName(0)
{
}
@@ -222,10 +209,37 @@ void QtMessageLogHandler::appendEditableRow()
void QtMessageLogHandler::removeEditableRow()
{
- if (m_rootItem->child(m_rootItem->childCount() - 1)->itemType() == QtMessageLogHandler::InputType)
+ if (m_rootItem->child(m_rootItem->childCount() - 1)->itemType ==
+ QtMessageLogHandler::InputType)
removeRow(m_rootItem->childCount() - 1);
}
+int QtMessageLogHandler::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 QtMessageLogHandler::sizeOfLineNumber(const QFont &font)
+{
+ QFontMetrics fm(font);
+ return fm.width(QLatin1String("88888"));
+}
+
QVariant QtMessageLogHandler::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
@@ -234,9 +248,13 @@ QVariant QtMessageLogHandler::data(const QModelIndex &index, int role) const
QtMessageLogItem *item = getItem(index);
if (role == Qt::DisplayRole )
- return item->text();
+ return item->text;
else if (role == QtMessageLogHandler::TypeRole)
- return int(item->itemType());
+ return int(item->itemType);
+ else if (role == QtMessageLogHandler::FileRole)
+ return item->file;
+ else if (role == QtMessageLogHandler::LineRole)
+ return item->line;
else
return QVariant();
}
@@ -270,6 +288,8 @@ QModelIndex QtMessageLogHandler::parent(const QModelIndex &index) const
if (parentItem == m_rootItem)
return QModelIndex();
+ //can parentItem be 0?
+ QTC_ASSERT(parentItem, qDebug("Parent is Null!!"));
return createIndex(parentItem->childNumber(), 0, parentItem);
}
@@ -302,12 +322,19 @@ bool QtMessageLogHandler::setData(const QModelIndex &index, const QVariant &valu
{
QtMessageLogItem *item = getItem(index);
bool result = false;
- if (role == Qt::DisplayRole )
- result = item->setText(value.toString());
- else if (role == QtMessageLogHandler::TypeRole)
- result = item->setItemType((QtMessageLogHandler::ItemType)value.toInt());
- else if (value.canConvert(QVariant::String))
- result = item->setText(value.toString());
+ if (role == Qt::DisplayRole) {
+ item->text = value.toString();
+ result = true;
+ } else if (role == QtMessageLogHandler::TypeRole) {
+ item->itemType = (QtMessageLogHandler::ItemType)value.toInt();
+ result = true;
+ } else if (role == QtMessageLogHandler::FileRole) {
+ item->file = value.toString();
+ result = true;
+ } else if (role == QtMessageLogHandler::LineRole) {
+ item->line = value.toInt();
+ result = true;
+ }
if (result)
emit dataChanged(index, index);
diff --git a/src/plugins/debugger/qtmessageloghandler.h b/src/plugins/debugger/qtmessageloghandler.h
index f83ea3d2c92..9031c8e94c3 100644
--- a/src/plugins/debugger/qtmessageloghandler.h
+++ b/src/plugins/debugger/qtmessageloghandler.h
@@ -35,6 +35,7 @@
#include <QAbstractItemModel>
#include <QItemSelectionModel>
+#include <QFont>
namespace Debugger {
namespace Internal {
@@ -56,7 +57,7 @@ public:
};
Q_DECLARE_FLAGS(ItemTypes, ItemType)
- enum Roles { TypeRole = Qt::UserRole };
+ enum Roles { TypeRole = Qt::UserRole, FileRole, LineRole };
explicit QtMessageLogHandler(QObject *parent = 0);
~QtMessageLogHandler();
@@ -74,6 +75,9 @@ public:
int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int sizeOfFile(const QFont &font);
+ int sizeOfLineNumber(const QFont &font);
+
public slots:
void clear();
@@ -106,35 +110,36 @@ protected:
private:
bool m_hasEditableRow;
QtMessageLogItem *m_rootItem;
+ int m_maxSizeOfFileName;
};
class QtMessageLogItem
- {
- public:
+{
+public:
QtMessageLogItem(QtMessageLogHandler::ItemType type = QtMessageLogHandler::UndefinedType,
- const QString &data = QString(),
- QtMessageLogItem *parent = 0);
- ~QtMessageLogItem();
-
- QtMessageLogItem *child(int number);
- int childCount() const;
- QString text() const;
- QtMessageLogHandler::ItemType itemType() const;
- bool insertChildren(int position, int count);
- bool insertChild(int position, QtMessageLogItem *item);
- QtMessageLogItem *parent();
- bool removeChildren(int position, int count);
- bool detachChild(int position);
- int childNumber() const;
- bool setText(const QString &text);
- bool setItemType(QtMessageLogHandler::ItemType itemType);
-
- private:
- QList<QtMessageLogItem *> m_childItems;
- QString m_text;
- QtMessageLogHandler::ItemType m_itemType;
- QtMessageLogItem *m_parentItem;
- };
+ const QString &data = QString(),
+ QtMessageLogItem *parent = 0);
+ ~QtMessageLogItem();
+
+ QtMessageLogItem *child(int number);
+ int childCount() const;
+ bool insertChildren(int position, int count);
+ bool insertChild(int position, QtMessageLogItem *item);
+ QtMessageLogItem *parent();
+ bool removeChildren(int position, int count);
+ bool detachChild(int position);
+ int childNumber() const;
+
+private:
+ QtMessageLogItem *m_parentItem;
+ QList<QtMessageLogItem *> m_childItems;
+
+public:
+ QString text;
+ QtMessageLogHandler::ItemType itemType;
+ QString file;
+ int line;
+};
} //Internal
} //Debugger
diff --git a/src/plugins/debugger/qtmessagelogitemdelegate.cpp b/src/plugins/debugger/qtmessagelogitemdelegate.cpp
index b08ab5e45ce..1d8122f538c 100644
--- a/src/plugins/debugger/qtmessagelogitemdelegate.cpp
+++ b/src/plugins/debugger/qtmessagelogitemdelegate.cpp
@@ -32,10 +32,10 @@
#include "qtmessagelogitemdelegate.h"
#include "qtmessagelogeditor.h"
-#include "qtmessageloghandler.h"
#include <QPainter>
#include <QTreeView>
+#include <QScrollBar>
const char CONSOLE_LOG_BACKGROUND_COLOR[] = "#E8EEF2";
const char CONSOLE_WARNING_BACKGROUND_COLOR[] = "#F6F4EB";
@@ -54,6 +54,8 @@ const char CONSOLE_EDITOR_TEXT_COLOR[] = "#000000";
const char CONSOLE_BORDER_COLOR[] = "#C9C9C9";
+const int ELLIPSIS_GRADIENT_WIDTH = 16;
+
namespace Debugger {
namespace Internal {
@@ -70,7 +72,8 @@ QtMessageLogItemDelegate::QtMessageLogItemDelegate(QObject *parent) :
m_errorIcon(QLatin1String(":/debugger/images/error.png")),
m_expandIcon(QLatin1String(":/debugger/images/expand.png")),
m_collapseIcon(QLatin1String(":/debugger/images/collapse.png")),
- m_prompt(QLatin1String(":/debugger/images/prompt.png"))
+ m_prompt(QLatin1String(":/debugger/images/prompt.png")),
+ m_itemModel(0)
{
}
@@ -79,7 +82,7 @@ void QtMessageLogItemDelegate::emitSizeHintChanged(const QModelIndex &index)
emit sizeHintChanged(index);
}
-void QtMessageLogItemDelegate::drawBackground(QPainter *painter, const QRect &rect,
+QColor QtMessageLogItemDelegate::drawBackground(QPainter *painter, const QRect &rect,
const QModelIndex &index,
bool selected) const
{
@@ -110,7 +113,14 @@ void QtMessageLogItemDelegate::drawBackground(QPainter *painter, const QRect &re
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 QtMessageLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
@@ -148,7 +158,7 @@ void QtMessageLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewIt
}
//Paint background
- drawBackground(painter, opt.rect, index,
+ QColor backgroundColor = drawBackground(painter, opt.rect, index,
bool(opt.state & QStyle::State_Selected));
//Calculate positions
@@ -159,13 +169,14 @@ void QtMessageLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewIt
idx = idx.parent();
level++;
}
- int width = view->width() - level * view->indentation();
+ int width = view->width() - level * view->indentation() -
+ view->verticalScrollBar()->width();
bool showTypeIcon = index.parent() == QModelIndex();
bool showExpandableIcon = type == QtMessageLogHandler::UndefinedType;
QRect rect(opt.rect.x(), opt.rect.top(), width, opt.rect.height());
ConsoleItemPositions positions(rect, opt.font, showTypeIcon,
- showExpandableIcon);
+ showExpandableIcon, m_itemModel);
// Paint TaskIconArea:
if (showTypeIcon)
@@ -198,11 +209,39 @@ void QtMessageLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewIt
positions.expandCollapseIconHeight()));
}
- // Separator lines
- painter->setPen(QColor(CONSOLE_BORDER_COLOR));
- if (!(index.flags() & Qt::ItemIsEditable))
- painter->drawLine(0, opt.rect.bottom(), opt.rect.right(),
- opt.rect.bottom());
+ //Check for file info
+ QString file = index.data(QtMessageLogHandler::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(qMin(positions.fileAreaLeft(),
+ positions.fileAreaRight() - realFileWidth),
+ 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(QtMessageLogHandler::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();
}
@@ -219,7 +258,8 @@ QSize QtMessageLogItemDelegate::sizeHint(const QStyleOptionViewItem &option,
idx = idx.parent();
level++;
}
- int width = view->width() - level * view->indentation();
+ int width = view->width() - level * view->indentation() -
+ view->verticalScrollBar()->width();
if (index.flags() & Qt::ItemIsEditable)
return QSize(width, view->height() * 1/2);
@@ -230,8 +270,7 @@ QSize QtMessageLogItemDelegate::sizeHint(const QStyleOptionViewItem &option,
QRect rect(level * view->indentation(), 0, width, 0);
ConsoleItemPositions positions(rect, opt.font,
- showTypeIcon,
- showExpandableIcon);
+ showTypeIcon, showExpandableIcon, m_itemModel);
QTextLayout tl(index.data(Qt::DisplayRole).toString(), option.font);
qreal height = layoutText(tl, positions.textAreaWidth());
@@ -310,5 +349,10 @@ qreal QtMessageLogItemDelegate::layoutText(QTextLayout &tl, int width) const
return height;
}
+void QtMessageLogItemDelegate::setItemModel(QtMessageLogHandler *model)
+{
+ m_itemModel = model;
+}
+
} //Internal
} //Debugger
diff --git a/src/plugins/debugger/qtmessagelogitemdelegate.h b/src/plugins/debugger/qtmessagelogitemdelegate.h
index 7bce80fb4df..7d35f507273 100644
--- a/src/plugins/debugger/qtmessagelogitemdelegate.h
+++ b/src/plugins/debugger/qtmessagelogitemdelegate.h
@@ -33,6 +33,8 @@
#ifndef QTMESSAGELOGITEMDELEGATE_H
#define QTMESSAGELOGITEMDELEGATE_H
+#include "qtmessageloghandler.h"
+
#include <QTextLayout>
#include <QStyledItemDelegate>
@@ -45,10 +47,12 @@ class QtMessageLogItemDelegate : public QStyledItemDelegate
public:
explicit QtMessageLogItemDelegate(QObject *parent = 0);
void emitSizeHintChanged(const QModelIndex &index);
- void drawBackground(QPainter *painter, const QRect &rect,
+ QColor drawBackground(QPainter *painter, const QRect &rect,
const QModelIndex &index,
bool selected) const;
+ void setItemModel(QtMessageLogHandler *model);
+
public slots:
void currentChanged(const QModelIndex &current, const QModelIndex &previous);
@@ -80,11 +84,12 @@ private:
const QIcon m_expandIcon;
const QIcon m_collapseIcon;
const QIcon m_prompt;
+ QtMessageLogHandler *m_itemModel;
};
/*
+----------------------------------------------------------------------------+
- | TYPEICONAREA EXPANDABLEICONAREA TEXTAREA |
+ | TYPEICONAREA EXPANDABLEICONAREA TEXTAREA FILEAREA LINEAREA |
+----------------------------------------------------------------------------+
*/
@@ -98,9 +103,10 @@ class ConsoleItemPositions
{
public:
ConsoleItemPositions(const QRect &rect,
- const QFont &font = QFont(),
- bool showTaskIconArea = true,
- bool showExpandableIconArea = true)
+ const QFont &font,
+ bool showTaskIconArea,
+ bool showExpandableIconArea,
+ QtMessageLogHandler *model = 0)
: m_x(rect.x()),
m_width(rect.width()),
m_top(rect.top()),
@@ -109,6 +115,10 @@ public:
m_showExpandableIconArea(showExpandableIconArea)
{
m_fontHeight = QFontMetrics(font).height();
+ if (model) {
+ m_maxFileLength = model->sizeOfFile(font);
+ m_maxLineLength = model->sizeOfLineNumber(font);
+ }
}
int adjustedTop() const { return m_top + ITEM_PADDING; }
@@ -141,16 +151,30 @@ public:
int textAreaLeft() const { return expandCollapseIconRight() + ITEM_SPACING; }
int textAreaWidth() const { return textAreaRight() - textAreaLeft(); }
- int textAreaRight() const { return adjustedRight() - ITEM_SPACING; }
+ 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;
diff --git a/src/plugins/debugger/qtmessagelogview.cpp b/src/plugins/debugger/qtmessagelogview.cpp
index 34f7ba96e22..0029235ea3d 100644
--- a/src/plugins/debugger/qtmessagelogview.cpp
+++ b/src/plugins/debugger/qtmessagelogview.cpp
@@ -33,10 +33,20 @@
#include "qtmessagelogview.h"
#include "qtmessagelogitemdelegate.h"
#include "qtmessageloghandler.h"
+#include "debuggerstringutils.h"
+#include "debuggercore.h"
+#include "debuggerengine.h"
+
+#include <texteditor/basetexteditor.h>
#include <QMouseEvent>
#include <QProxyStyle>
#include <QPainter>
+#include <QApplication>
+#include <QClipboard>
+#include <QAbstractProxyModel>
+#include <QFileInfo>
+#include <QUrl>
namespace Debugger {
namespace Internal {
@@ -97,6 +107,12 @@ QtMessageLogView::QtMessageLogView(QWidget *parent) :
QtMessageLogViewViewStyle *style = new QtMessageLogViewViewStyle;
setStyle(style);
style->setParent(this);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
+
+ connect(this, SIGNAL(activated(QModelIndex)),
+ SLOT(onRowActivated(QModelIndex)));
}
void QtMessageLogView::mousePressEvent(QMouseEvent *event)
@@ -106,19 +122,22 @@ void QtMessageLogView::mousePressEvent(QMouseEvent *event)
if (index.isValid()) {
QtMessageLogHandler::ItemType type = (QtMessageLogHandler::ItemType)index.data(
QtMessageLogHandler::TypeRole).toInt();
- bool showTypeIcon = index.parent() == QModelIndex();
- bool showExpandableIcon = type == QtMessageLogHandler::UndefinedType;
- ConsoleItemPositions positions(visualRect(index), viewOptions().font,
- showTypeIcon, showExpandableIcon);
-
- if (positions.expandCollapseIcon().contains(pos)) {
- if (isExpanded(index))
- setExpanded(index, false);
- else
- setExpanded(index, true);
- } else {
- QTreeView::mousePressEvent(event);
+ bool handled = false;
+ if (type == QtMessageLogHandler::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),
@@ -126,6 +145,16 @@ void QtMessageLogView::mousePressEvent(QMouseEvent *event)
}
}
+void QtMessageLogView::keyPressEvent(QKeyEvent *e)
+{
+ if (!e->modifiers() && e->key() == Qt::Key_Return) {
+ emit activated(currentIndex());
+ e->accept();
+ return;
+ }
+ QTreeView::keyPressEvent(e);
+}
+
void QtMessageLogView::resizeEvent(QResizeEvent *e)
{
static_cast<QtMessageLogItemDelegate *>(itemDelegate())->emitSizeHintChanged(
@@ -141,5 +170,95 @@ void QtMessageLogView::drawBranches(QPainter *painter, const QRect &rect,
QTreeView::drawBranches(painter, rect, index);
}
+void QtMessageLogView::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());
+ QtMessageLogHandler *handler =
+ qobject_cast<QtMessageLogHandler *>(proxyModel->sourceModel());
+ handler->clear();
+ }
+}
+
+void QtMessageLogView::onRowActivated(const QModelIndex &index)
+{
+ if (!index.isValid())
+ return;
+
+ //See if we have file and line Info
+ QString filePath = model()->data(index,
+ QtMessageLogHandler::FileRole).toString();
+ if (!filePath.isEmpty()) {
+ filePath = debuggerCore()->currentEngine()->toFileInProject(
+ QUrl(filePath));
+ QFileInfo fi(filePath);
+ if (fi.exists() && fi.isFile() && fi.isReadable()) {
+ int line = model()->data(index,
+ QtMessageLogHandler::LineRole).toInt();
+ TextEditor::BaseTextEditorWidget::openEditorAt(
+ fi.canonicalFilePath(), line);
+ }
+ }
+}
+
+void QtMessageLogView::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,
+ QtMessageLogHandler::FileRole).toString();
+ if (!filePath.isEmpty()) {
+ contents = QString(_("%1 %2: %3")).arg(contents).arg(filePath).arg(
+ model()->data(index,
+ QtMessageLogHandler::LineRole).toString());
+ }
+ QClipboard *cb = QApplication::clipboard();
+ cb->setText(contents);
+}
+
+bool QtMessageLogView::canShowItemInTextEditor(const QModelIndex &index)
+{
+ if (!index.isValid())
+ return false;
+
+ //See if we have file and line Info
+ QString filePath = model()->data(index,
+ QtMessageLogHandler::FileRole).toString();
+ if (!filePath.isEmpty()) {
+ filePath = debuggerCore()->currentEngine()->toFileInProject(
+ QUrl(filePath));
+ QFileInfo fi(filePath);
+ if (fi.exists() && fi.isFile() && fi.isReadable()) {
+ return true;
+ }
+ }
+ return false;
+}
+
} //Internal
} //Debugger
diff --git a/src/plugins/debugger/qtmessagelogview.h b/src/plugins/debugger/qtmessagelogview.h
index 4a6a301d268..103d6ff19df 100644
--- a/src/plugins/debugger/qtmessagelogview.h
+++ b/src/plugins/debugger/qtmessagelogview.h
@@ -46,9 +46,18 @@ public:
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
diff --git a/src/plugins/debugger/qtmessagelogwindow.cpp b/src/plugins/debugger/qtmessagelogwindow.cpp
index c3a8e52638b..e54ccae8ab2 100644
--- a/src/plugins/debugger/qtmessagelogwindow.cpp
+++ b/src/plugins/debugger/qtmessagelogwindow.cpp
@@ -161,10 +161,10 @@ QtMessageLogWindow::QtMessageLogWindow(QWidget *parent)
m_treeView,
SLOT(scrollToBottom()));
- QtMessageLogItemDelegate *itemDelegate = new QtMessageLogItemDelegate(this);
+ m_itemDelegate = new QtMessageLogItemDelegate(this);
connect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- itemDelegate, SLOT(currentChanged(QModelIndex,QModelIndex)));
- m_treeView->setItemDelegate(itemDelegate);
+ m_itemDelegate, SLOT(currentChanged(QModelIndex,QModelIndex)));
+ m_treeView->setItemDelegate(m_itemDelegate);
vbox->addWidget(statusbarContainer);
vbox->addWidget(m_treeView);
@@ -204,6 +204,7 @@ void QtMessageLogWindow::setModel(QAbstractItemModel *model)
{
m_proxyModel->setSourceModel(model);
QtMessageLogHandler *handler = qobject_cast<QtMessageLogHandler *>(model);
+ m_itemDelegate->setItemModel(handler);
connect(m_clearAction, SIGNAL(triggered()), handler, SLOT(clear()));
connect(handler,
SIGNAL(selectEditableRow(QModelIndex,QItemSelectionModel::SelectionFlags)),
diff --git a/src/plugins/debugger/qtmessagelogwindow.h b/src/plugins/debugger/qtmessagelogwindow.h
index 25caa0140a7..e8cc96478c0 100644
--- a/src/plugins/debugger/qtmessagelogwindow.h
+++ b/src/plugins/debugger/qtmessagelogwindow.h
@@ -49,6 +49,7 @@ namespace Debugger {
namespace Internal {
class QtMessageLogView;
+class QtMessageLogItemDelegate;
class QtMessageLogProxyModel;
class QtMessageLogWindow : public QWidget
{
@@ -71,6 +72,7 @@ private:
Utils::SavedAction *m_showErrorAction;
QAction *m_clearAction;
QtMessageLogView *m_treeView;
+ QtMessageLogItemDelegate *m_itemDelegate;
QtMessageLogProxyModel *m_proxyModel;
};