mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-26 16:11:02 +08:00
[ui] fixed search text highlighting, renamed some menu actions
This commit is contained in:
parent
357ac45834
commit
7d0c04bd73
@ -897,11 +897,11 @@ void BlocksTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
|||||||
|
|
||||||
if (!m_items.empty())
|
if (!m_items.empty())
|
||||||
{
|
{
|
||||||
action = menu.addAction("Expand all");
|
action = menu.addAction("Expand All");
|
||||||
connect(action, &QAction::triggered, this, &This::onExpandAllClicked);
|
connect(action, &QAction::triggered, this, &This::onExpandAllClicked);
|
||||||
action->setIcon(QIcon(imagePath("expand")));
|
action->setIcon(QIcon(imagePath("expand")));
|
||||||
|
|
||||||
action = menu.addAction("Collapse all");
|
action = menu.addAction("Collapse All");
|
||||||
connect(action, &QAction::triggered, this, &This::onCollapseAllClicked);
|
connect(action, &QAction::triggered, this, &This::onCollapseAllClicked);
|
||||||
action->setIcon(QIcon(imagePath("collapse")));
|
action->setIcon(QIcon(imagePath("collapse")));
|
||||||
|
|
||||||
@ -909,11 +909,11 @@ void BlocksTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
|||||||
{
|
{
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
|
|
||||||
action = menu.addAction("Expand all children");
|
action = menu.addAction("Expand All Children");
|
||||||
connect(action, &QAction::triggered, this, &This::onExpandAllChildrenClicked);
|
connect(action, &QAction::triggered, this, &This::onExpandAllChildrenClicked);
|
||||||
action->setIcon(QIcon(imagePath("expand")));
|
action->setIcon(QIcon(imagePath("expand")));
|
||||||
|
|
||||||
action = menu.addAction("Collapse all children");
|
action = menu.addAction("Collapse All Children");
|
||||||
connect(action, &QAction::triggered, this, &This::onCollapseAllChildrenClicked);
|
connect(action, &QAction::triggered, this, &This::onCollapseAllChildrenClicked);
|
||||||
action->setIcon(QIcon(imagePath("collapse")));
|
action->setIcon(QIcon(imagePath("collapse")));
|
||||||
}
|
}
|
||||||
@ -924,21 +924,21 @@ void BlocksTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
|||||||
auto actionGroup = new QActionGroup(&menu);
|
auto actionGroup = new QActionGroup(&menu);
|
||||||
actionGroup->setExclusive(true);
|
actionGroup->setExclusive(true);
|
||||||
|
|
||||||
auto actionHierarchy = new QAction("Call-stack", actionGroup);
|
auto actionHierarchy = new QAction("Call-Stack", actionGroup);
|
||||||
actionHierarchy->setCheckable(true);
|
actionHierarchy->setCheckable(true);
|
||||||
actionHierarchy->setChecked(m_mode == TreeMode::Full);
|
actionHierarchy->setChecked(m_mode == TreeMode::Full);
|
||||||
actionHierarchy->setToolTip("Display full call stack");
|
actionHierarchy->setToolTip("Display Full Call Stack");
|
||||||
actionHierarchy->setData((quint32)TreeMode::Full);
|
actionHierarchy->setData((quint32)TreeMode::Full);
|
||||||
menu.addAction(actionHierarchy);
|
menu.addAction(actionHierarchy);
|
||||||
|
|
||||||
auto actionPlain = new QAction("Per-frame stats", actionGroup);
|
auto actionPlain = new QAction("Per-Frame Stats", actionGroup);
|
||||||
actionPlain->setCheckable(true);
|
actionPlain->setCheckable(true);
|
||||||
actionPlain->setChecked(m_mode == TreeMode::Plain);
|
actionPlain->setChecked(m_mode == TreeMode::Plain);
|
||||||
actionPlain->setToolTip("Display plain list of blocks per frame.\nSome columns are disabled with this mode.");
|
actionPlain->setToolTip("Display plain list of blocks per frame.\nSome columns are disabled with this mode.");
|
||||||
actionPlain->setData((quint32)TreeMode::Plain);
|
actionPlain->setData((quint32)TreeMode::Plain);
|
||||||
menu.addAction(actionPlain);
|
menu.addAction(actionPlain);
|
||||||
|
|
||||||
auto actionSelectedArea = new QAction("Aggregate stats", actionGroup);
|
auto actionSelectedArea = new QAction("Aggregate Stats", actionGroup);
|
||||||
actionSelectedArea->setCheckable(true);
|
actionSelectedArea->setCheckable(true);
|
||||||
actionSelectedArea->setChecked(m_mode == TreeMode::SelectedArea);
|
actionSelectedArea->setChecked(m_mode == TreeMode::SelectedArea);
|
||||||
actionSelectedArea->setToolTip("Display aggregate stats for selected area.\nSome columns are disabled with this mode.");
|
actionSelectedArea->setToolTip("Display aggregate stats for selected area.\nSome columns are disabled with this mode.");
|
||||||
@ -968,17 +968,19 @@ void BlocksTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
|||||||
{
|
{
|
||||||
auto& block = item->block();
|
auto& block = item->block();
|
||||||
auto i = profiler_gui::numeric_max<uint32_t>();
|
auto i = profiler_gui::numeric_max<uint32_t>();
|
||||||
|
QString name;
|
||||||
switch (col)
|
switch (col)
|
||||||
{
|
{
|
||||||
case COL_MIN_PER_THREAD: i = block.per_thread_stats->min_duration_block; break;
|
case COL_MIN_PER_THREAD: name = QStringLiteral("Min"); i = block.per_thread_stats->min_duration_block; break;
|
||||||
case COL_MIN_PER_PARENT: i = block.per_parent_stats->min_duration_block; break;
|
case COL_MIN_PER_PARENT: name = QStringLiteral("Min"); i = block.per_parent_stats->min_duration_block; break;
|
||||||
case COL_MIN_PER_FRAME: i = block.per_frame_stats->min_duration_block; break;
|
case COL_MIN_PER_FRAME: name = QStringLiteral("Min"); i = block.per_frame_stats->min_duration_block; break;
|
||||||
case COL_MAX_PER_THREAD: i = block.per_thread_stats->max_duration_block; break;
|
case COL_MAX_PER_THREAD: name = QStringLiteral("Max"); i = block.per_thread_stats->max_duration_block; break;
|
||||||
case COL_MAX_PER_PARENT: i = block.per_parent_stats->max_duration_block; break;
|
case COL_MAX_PER_PARENT: name = QStringLiteral("Max"); i = block.per_parent_stats->max_duration_block; break;
|
||||||
case COL_MAX_PER_FRAME: i = block.per_frame_stats->max_duration_block; break;
|
case COL_MAX_PER_FRAME: name = QStringLiteral("Max"); i = block.per_frame_stats->max_duration_block; break;
|
||||||
|
|
||||||
case COL_MIN_PER_AREA:
|
case COL_MIN_PER_AREA:
|
||||||
{
|
{
|
||||||
|
name = QStringLiteral("Min");
|
||||||
auto data = item->data(COL_MIN_PER_AREA, MinMaxBlockIndexRole);
|
auto data = item->data(COL_MIN_PER_AREA, MinMaxBlockIndexRole);
|
||||||
if (!data.isNull())
|
if (!data.isNull())
|
||||||
i = data.toUInt();
|
i = data.toUInt();
|
||||||
@ -987,6 +989,7 @@ void BlocksTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
|||||||
|
|
||||||
case COL_MAX_PER_AREA:
|
case COL_MAX_PER_AREA:
|
||||||
{
|
{
|
||||||
|
name = QStringLiteral("Max");
|
||||||
auto data = item->data(COL_MAX_PER_AREA, MinMaxBlockIndexRole);
|
auto data = item->data(COL_MAX_PER_AREA, MinMaxBlockIndexRole);
|
||||||
if (!data.isNull())
|
if (!data.isNull())
|
||||||
i = data.toUInt();
|
i = data.toUInt();
|
||||||
@ -997,9 +1000,9 @@ void BlocksTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
|||||||
if (i != profiler_gui::numeric_max(i))
|
if (i != profiler_gui::numeric_max(i))
|
||||||
{
|
{
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
auto itemAction = new QAction("Jump to such item", nullptr);
|
auto itemAction = new QAction(QString("Jump To %1 Item").arg(name), nullptr);
|
||||||
itemAction->setData(i);
|
itemAction->setData(i);
|
||||||
itemAction->setToolTip("Jump to item with min/max duration (depending on clicked column)");
|
itemAction->setToolTip(QString("Jump to item with %1 duration").arg(name.toLower()));
|
||||||
connect(itemAction, &QAction::triggered, this, &This::onJumpToItemClicked);
|
connect(itemAction, &QAction::triggered, this, &This::onJumpToItemClicked);
|
||||||
menu.addAction(itemAction);
|
menu.addAction(itemAction);
|
||||||
}
|
}
|
||||||
@ -1013,7 +1016,7 @@ void BlocksTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto& desc = easyDescriptor(item->block().node->id());
|
const auto& desc = easyDescriptor(item->block().node->id());
|
||||||
auto submenu = menu.addMenu("Block status");
|
auto submenu = menu.addMenu("Block Status");
|
||||||
submenu->setToolTipsVisible(true);
|
submenu->setToolTipsVisible(true);
|
||||||
|
|
||||||
#define ADD_STATUS_ACTION(NameValue, StatusValue, ToolTipValue)\
|
#define ADD_STATUS_ACTION(NameValue, StatusValue, ToolTipValue)\
|
||||||
@ -1037,7 +1040,7 @@ void BlocksTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
|||||||
submenu->setTitle(QString("%1 (connection needed)").arg(submenu->title()));
|
submenu->setTitle(QString("%1 (connection needed)").arg(submenu->title()));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto hidemenu = menu.addMenu("Select columns");
|
auto hidemenu = menu.addMenu("Select Columns");
|
||||||
auto hdr = headerItem();
|
auto hdr = headerItem();
|
||||||
|
|
||||||
#define ADD_COLUMN_ACTION(i) \
|
#define ADD_COLUMN_ACTION(i) \
|
||||||
|
@ -56,6 +56,8 @@
|
|||||||
#include <QAbstractTextDocumentLayout>
|
#include <QAbstractTextDocumentLayout>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QActionGroup>
|
#include <QActionGroup>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QClipboard>
|
||||||
#include <QContextMenuEvent>
|
#include <QContextMenuEvent>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
@ -201,31 +203,63 @@ bool DescriptorsTreeItem::operator < (const Parent& _other) const
|
|||||||
|
|
||||||
QVariant DescriptorsTreeItem::data(int _column, int _role) const
|
QVariant DescriptorsTreeItem::data(int _column, int _role) const
|
||||||
{
|
{
|
||||||
if (_column == DESC_COL_TYPE)
|
switch (_column)
|
||||||
{
|
{
|
||||||
if (_role == Qt::ToolTipRole)
|
case DESC_COL_TYPE:
|
||||||
{
|
{
|
||||||
switch (m_type)
|
if (_role == Qt::ToolTipRole)
|
||||||
{
|
{
|
||||||
case Type::File: return QStringLiteral("File");
|
switch (m_type)
|
||||||
case Type::Event: return QStringLiteral("Event");
|
{
|
||||||
case Type::Block: return QStringLiteral("Block");
|
case Type::File: return QStringLiteral("File");
|
||||||
case Type::Value: return QStringLiteral("Arbitrary Value");
|
case Type::Event: return QStringLiteral("Event");
|
||||||
|
case Type::Block: return QStringLiteral("Block");
|
||||||
|
case Type::Value: return QStringLiteral("Arbitrary Value");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (_role == Qt::DisplayRole)
|
||||||
|
{
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case Type::File: return QStringLiteral("F");
|
||||||
|
case Type::Event: return QStringLiteral("E");
|
||||||
|
case Type::Block: return QStringLiteral("B");
|
||||||
|
case Type::Value: return QStringLiteral("V");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (_role == Qt::DisplayRole)
|
|
||||||
|
case DESC_COL_FILE_LINE:
|
||||||
{
|
{
|
||||||
switch (m_type)
|
if (parent() != nullptr)
|
||||||
{
|
{
|
||||||
case Type::File: return QStringLiteral("F");
|
if (_role == Qt::ToolTipRole)
|
||||||
case Type::Event: return QStringLiteral("E");
|
{
|
||||||
case Type::Block: return QStringLiteral("B");
|
const int row = data(_column, Qt::UserRole).toInt();
|
||||||
case Type::Value: return QStringLiteral("V");
|
return QString("%1:%2").arg(parent()->data(_column, Qt::UserRole).toString()).arg(row);
|
||||||
|
}
|
||||||
|
else if (_role == Qt::DisplayRole)
|
||||||
|
{
|
||||||
|
const int row = data(_column, Qt::UserRole).toInt();
|
||||||
|
return QString("%1:%2").arg(parent()->text(_column)).arg(row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (_role == Qt::ToolTipRole)
|
||||||
|
{
|
||||||
|
return data(_column, Qt::UserRole).toString();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QTreeWidgetItem::data(_column, _role);
|
return Parent::data(_column, _role);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -393,11 +427,11 @@ void DescriptorsTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
|||||||
|
|
||||||
QMenu menu;
|
QMenu menu;
|
||||||
menu.setToolTipsVisible(true);
|
menu.setToolTipsVisible(true);
|
||||||
auto action = menu.addAction("Expand all");
|
auto action = menu.addAction("Expand All");
|
||||||
action->setIcon(QIcon(imagePath("expand")));
|
action->setIcon(QIcon(imagePath("expand")));
|
||||||
connect(action, &QAction::triggered, this, &This::expandAll);
|
connect(action, &QAction::triggered, this, &This::expandAll);
|
||||||
|
|
||||||
action = menu.addAction("Collapse all");
|
action = menu.addAction("Collapse All");
|
||||||
action->setIcon(QIcon(imagePath("collapse")));
|
action->setIcon(QIcon(imagePath("collapse")));
|
||||||
connect(action, &QAction::triggered, this, &This::collapseAll);
|
connect(action, &QAction::triggered, this, &This::collapseAll);
|
||||||
|
|
||||||
@ -407,7 +441,7 @@ void DescriptorsTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
|||||||
const auto& desc = easyDescriptor(static_cast<DescriptorsTreeItem*>(item)->desc());
|
const auto& desc = easyDescriptor(static_cast<DescriptorsTreeItem*>(item)->desc());
|
||||||
|
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
auto submenu = menu.addMenu("Change status");
|
auto submenu = menu.addMenu("Change Status");
|
||||||
submenu->setToolTipsVisible(true);
|
submenu->setToolTipsVisible(true);
|
||||||
|
|
||||||
#define ADD_STATUS_ACTION(NameValue, StatusValue, ToolTipValue)\
|
#define ADD_STATUS_ACTION(NameValue, StatusValue, ToolTipValue)\
|
||||||
@ -431,6 +465,17 @@ void DescriptorsTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
|
|||||||
submenu->setTitle(QString("%1 (connection needed)").arg(submenu->title()));
|
submenu->setTitle(QString("%1 (connection needed)").arg(submenu->title()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item != nullptr)
|
||||||
|
{
|
||||||
|
menu.addSeparator();
|
||||||
|
action = menu.addAction(QStringLiteral("Copy Full Path"));
|
||||||
|
connect(action, &QAction::triggered, [this, item] (bool) {
|
||||||
|
auto fileItem = item->parent() == nullptr ? item : item->parent();
|
||||||
|
auto fullName = fileItem->data(DESC_COL_FILE_LINE, Qt::UserRole).toString();
|
||||||
|
qApp->clipboard()->setText(fullName);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
menu.exec(QCursor::pos());
|
menu.exec(QCursor::pos());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,16 +539,47 @@ void DescriptorsTreeWidget::build()
|
|||||||
memset(m_items.data(), 0, sizeof(void*) * m_items.size());
|
memset(m_items.data(), 0, sizeof(void*) * m_items.size());
|
||||||
|
|
||||||
const QSignalBlocker b(this);
|
const QSignalBlocker b(this);
|
||||||
::profiler::block_id_t id = 0;
|
profiler::block_id_t id = 0, count = 0;
|
||||||
|
|
||||||
|
QString commonDir;
|
||||||
for (auto desc : EASY_GLOBALS.descriptors)
|
for (auto desc : EASY_GLOBALS.descriptors)
|
||||||
{
|
{
|
||||||
if (desc != nullptr)
|
if (desc != nullptr)
|
||||||
{
|
{
|
||||||
|
++count;
|
||||||
|
|
||||||
auto& p = fileItems[desc->file()];
|
auto& p = fileItems[desc->file()];
|
||||||
if (p.item == nullptr)
|
if (p.item == nullptr)
|
||||||
{
|
{
|
||||||
auto item = new DescriptorsTreeItem(0);
|
auto item = new DescriptorsTreeItem(0);
|
||||||
item->setText(DESC_COL_FILE_LINE, QString(desc->file()).remove(QRegExp("^(\\.{2}\\\\+|\\/+)+")));
|
auto fullName = QString(desc->file()).remove(QRegExp("^(\\.{2}\\\\+)+")); // without leading "..\"
|
||||||
|
auto fileName = QString(desc->file()).remove(QRegExp("^(.+(\\\\|\\/)+)+"));
|
||||||
|
auto dir = fullName.left(fullName.length() - fileName.length());
|
||||||
|
|
||||||
|
if (count == 1)
|
||||||
|
{
|
||||||
|
commonDir = dir;
|
||||||
|
}
|
||||||
|
else if (!commonDir.isEmpty())
|
||||||
|
{
|
||||||
|
if (dir.length() < commonDir.length())
|
||||||
|
{
|
||||||
|
commonDir.truncate(dir.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (; i < commonDir.length(); ++i)
|
||||||
|
{
|
||||||
|
if (commonDir[i] != dir[i])
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commonDir.truncate(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
item->setData(DESC_COL_FILE_LINE, Qt::UserRole, fullName);
|
||||||
item->setType(DescriptorsTreeItem::Type::File);
|
item->setType(DescriptorsTreeItem::Type::File);
|
||||||
p.item = item;
|
p.item = item;
|
||||||
}
|
}
|
||||||
@ -512,7 +588,6 @@ void DescriptorsTreeWidget::build()
|
|||||||
if (it == p.children.end())
|
if (it == p.children.end())
|
||||||
{
|
{
|
||||||
auto item = new DescriptorsTreeItem(desc->id(), p.item);
|
auto item = new DescriptorsTreeItem(desc->id(), p.item);
|
||||||
item->setText(DESC_COL_FILE_LINE, QString::number(desc->line()));
|
|
||||||
item->setData(DESC_COL_FILE_LINE, Qt::UserRole, desc->line());
|
item->setData(DESC_COL_FILE_LINE, Qt::UserRole, desc->line());
|
||||||
item->setText(DESC_COL_NAME, desc->name());
|
item->setText(DESC_COL_NAME, desc->name());
|
||||||
|
|
||||||
@ -551,6 +626,8 @@ void DescriptorsTreeWidget::build()
|
|||||||
|
|
||||||
for (auto& p : fileItems)
|
for (auto& p : fileItems)
|
||||||
{
|
{
|
||||||
|
auto fullName = p.second.item->data(DESC_COL_FILE_LINE, Qt::UserRole).toString();
|
||||||
|
p.second.item->setText(DESC_COL_FILE_LINE, fullName.right(fullName.length() - commonDir.length()));
|
||||||
addTopLevelItem(p.second.item);
|
addTopLevelItem(p.second.item);
|
||||||
if (m_expandedFilesTemp.find(p.first) != m_expandedFilesTemp.end())
|
if (m_expandedFilesTemp.find(p.first) != m_expandedFilesTemp.end())
|
||||||
p.second.item->setExpanded(true);
|
p.second.item->setExpanded(true);
|
||||||
@ -1256,9 +1333,14 @@ void DescWidgetItemDelegate::highlightMatchingText(
|
|||||||
|
|
||||||
QTextDocument doc;
|
QTextDocument doc;
|
||||||
doc.setDefaultFont(painter->font());
|
doc.setDefaultFont(painter->font());
|
||||||
|
|
||||||
|
auto textOption = doc.defaultTextOption();
|
||||||
|
textOption.setWrapMode(QTextOption::NoWrap);
|
||||||
|
doc.setDefaultTextOption(textOption);
|
||||||
|
|
||||||
doc.setTextWidth(option.rect.width());
|
doc.setTextWidth(option.rect.width());
|
||||||
|
|
||||||
const auto elidedText = painter->fontMetrics().elidedText(text, Qt::ElideRight, std::max(option.rect.width(), 0));
|
const auto elidedText = painter->fontMetrics().elidedText(text, Qt::ElideRight, option.rect.width());
|
||||||
doc.setHtml(elidedText);
|
doc.setHtml(elidedText);
|
||||||
|
|
||||||
TextHighlighter highlighter(
|
TextHighlighter highlighter(
|
||||||
|
@ -561,6 +561,11 @@ void TreeWidgetItemDelegate::highlightMatchingText(
|
|||||||
|
|
||||||
QTextDocument doc;
|
QTextDocument doc;
|
||||||
doc.setDefaultFont(painter->font());
|
doc.setDefaultFont(painter->font());
|
||||||
|
|
||||||
|
auto textOption = doc.defaultTextOption();
|
||||||
|
textOption.setWrapMode(QTextOption::NoWrap);
|
||||||
|
doc.setDefaultTextOption(textOption);
|
||||||
|
|
||||||
doc.setTextWidth(option.rect.width() - padding);
|
doc.setTextWidth(option.rect.width() - padding);
|
||||||
|
|
||||||
const auto elidedText = painter->fontMetrics().elidedText(text, Qt::ElideRight, std::max(option.rect.width() - padding, 0));
|
const auto elidedText = painter->fontMetrics().elidedText(text, Qt::ElideRight, std::max(option.rect.width() - padding, 0));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user