0
0
mirror of https://github.com/yse/easy_profiler.git synced 2024-12-26 08:01:51 +08:00

#31 [Gui] Double click on arbitrary value on the Diagram will open values viewer and will select appropriate arbitrary value

This commit is contained in:
Victor Zarubkin 2018-03-12 01:47:20 +03:00
parent 402612ee2b
commit 769236c35a
8 changed files with 127 additions and 29 deletions

View File

@ -1677,9 +1677,9 @@ struct UsedValueTypes {
//////////////////////////////////////////////////////////////////////////
ArbitraryTreeWidgetItem::ArbitraryTreeWidgetItem(QTreeWidgetItem* _parent, bool _checkable, profiler::color_t _color, profiler::vin_t _vin)
ArbitraryTreeWidgetItem::ArbitraryTreeWidgetItem(QTreeWidgetItem* _parent, bool _checkable, profiler::color_t _color, const profiler::ArbitraryValue& _value)
: Parent(_parent, ValueItemType)
, m_vin(_vin)
, m_value(_value)
, m_color(_color)
, m_widthHint(0)
{
@ -1705,9 +1705,16 @@ QVariant ArbitraryTreeWidgetItem::data(int _column, int _role) const
return QSize(static_cast<int>(m_widthHint * (m_font.bold() ? 1.2f : 1.f)), 26);
if (_role == Qt::FontRole)
return m_font;
if (_column == int_cast(ArbitraryColumns::Vin) && _role == Qt::DisplayRole && getSelfIndexInArray() < 0)
return QString("0x%1").arg(m_value.value_id(), 0, 16);
return Parent::data(_column, _role);
}
const profiler::ArbitraryValue& ArbitraryTreeWidgetItem::value() const
{
return m_value;
}
void ArbitraryTreeWidgetItem::setWidthHint(int _width)
{
m_widthHint = _width;
@ -1750,11 +1757,11 @@ profiler::block_id_t ArbitraryTreeWidgetItem::getParentBlockId(QTreeWidgetItem*
}
}
int ArbitraryTreeWidgetItem::getSelfIndexInArray()
int ArbitraryTreeWidgetItem::getSelfIndexInArray() const
{
if (data(int_cast(ArbitraryColumns::Type), Qt::UserRole).toInt() != 3)
return -1;
return parent()->indexOfChild(this);
return parent()->indexOfChild(const_cast<ArbitraryTreeWidgetItem*>(this));
}
void ArbitraryTreeWidgetItem::collectValues(profiler::thread_id_t _threadId, ChartType _chartType)
@ -1770,7 +1777,7 @@ void ArbitraryTreeWidgetItem::collectValues(profiler::thread_id_t _threadId, Cha
EASY_CONSTEXPR auto nameColumn = int_cast(ArbitraryColumns::Name);
const auto name = index < 0 ? text(nameColumn).toStdString() : parent()->text(nameColumn).toStdString();
m_collection->collectValuesAndPoints(_chartType, _threadId, m_vin, name.c_str(),
m_collection->collectValuesAndPoints(_chartType, _threadId, m_value.value_id(), name.c_str(),
EASY_GLOBALS.begin_time, parentBlockId, index);
}
@ -1795,7 +1802,7 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
, m_splitter(new QSplitter(Qt::Horizontal, this))
, m_treeWidget(new QTreeWidget(this))
, m_chart(new GraphicsChart(this))
, m_filterBoxLabel(new QLabel(tr(" Approx filter:"), this))
, m_filterBoxLabel(new QLabel(tr(" Filter:"), this))
, m_filterComboBox(new QComboBox(this))
, m_filterWindowLabel(new QLabel(tr(" Window size:"), this))
, m_filterWindowPicker(new QSpinBox(this))
@ -1822,7 +1829,7 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
tb->setIconSize(applicationIconsSize());
auto action = tb->addAction(QIcon(imagePath("reload")), tr("Refresh values list"));
connect(action, &QAction::triggered, this, &This::rebuild);
connect(action, &QAction::triggered, this, Overload<void>::of(&This::rebuild));
m_exportToCsvAction = tb->addAction(QIcon(imagePath("csv")), tr("Export to csv"));
connect(m_exportToCsvAction, &QAction::triggered, this, &This::onExportToCsvClicked);
@ -1881,7 +1888,7 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
auto globalEvents = &EASY_GLOBALS.events;
connect(globalEvents, &profiler_gui::GlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChanged);
connect(globalEvents, &profiler_gui::GlobalSignals::selectedBlockIdChanged, this, &This::onSelectedBlockIdChanged);
connect(globalEvents, &profiler_gui::GlobalSignals::fileOpened, this, &This::rebuild);
connect(globalEvents, &profiler_gui::GlobalSignals::fileOpened, this, Overload<void>::of(&This::rebuild));
loadSettings();
@ -2104,14 +2111,66 @@ void ArbitraryValuesWidget::onCurrentItemChanged(QTreeWidgetItem* _current, QTre
}
void ArbitraryValuesWidget::rebuild()
{
rebuild(EASY_GLOBALS.selected_thread);
}
void ArbitraryValuesWidget::rebuild(profiler::thread_id_t _threadId)
{
clear();
buildTree(EASY_GLOBALS.selected_thread, EASY_GLOBALS.selected_block, EASY_GLOBALS.selected_block_id);
buildTree(_threadId, EASY_GLOBALS.selected_block, EASY_GLOBALS.selected_block_id);
m_treeWidget->expandAll();
for (int i = 0, columns = m_treeWidget->columnCount(); i < columns; ++i)
m_treeWidget->resizeColumnToContents(i);
if (!profiler_gui::is_max(EASY_GLOBALS.selected_block))
{
const auto& block = easyBlocksTree(EASY_GLOBALS.selected_block);
if (easyDescriptor(block.node->id()).type() == profiler::BlockType::Value)
select(*block.value, false);
}
}
void ArbitraryValuesWidget::select(const profiler::ArbitraryValue& _value, bool _resetOthers)
{
if (!m_checkedItems.empty() && _resetOthers)
{
disconnect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged);
for (auto item : m_checkedItems)
item->setCheckState(CheckColumn, Qt::Unchecked);
decltype(m_checkedItems) uncheckedItems(std::move(m_checkedItems));
m_exportToCsvAction->setEnabled(false);
onCollectionsTimeout();
for (auto item : uncheckedItems)
item->interrupt();
connect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged);
}
auto items = m_treeWidget->findItems(easyDescriptor(_value.id()).name(), Qt::MatchExactly | Qt::MatchCaseSensitive | Qt::MatchRecursive, int_cast(ArbitraryColumns::Name));
if (!items.empty())
{
for (auto i : items)
{
if (i->type() != ValueItemType)
continue;
auto item = reinterpret_cast<ArbitraryTreeWidgetItem*>(i);
const auto& value = item->value();
if (value.value_id() != _value.value_id() || value.type() != _value.type())
continue;
m_treeWidget->setCurrentItem(item);
item->setCheckState(CheckColumn, Qt::Checked);
break;
}
}
}
void ArbitraryValuesWidget::onCollectionsTimeout()
@ -2342,19 +2401,23 @@ QTreeWidgetItem* ArbitraryValuesWidget::buildTreeForThread(const profiler::Block
profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, _threadRoot, EASY_GLOBALS.hex_thread_id));
rootItem->setData(int_cast(ArbitraryColumns::Type), Qt::UserRole, 0);
const bool hasParticularBlockIndex = !profiler_gui::is_max(_blockIndex);
bool hasParticularBlockIndex = !profiler_gui::is_max(_blockIndex);
if (hasParticularBlockIndex)
{
const auto& block = easyBlocksTree(_blockIndex);
const auto& desc = easyDescriptor(block.node->id());
if (desc.type() == profiler::BlockType::Value)
if (desc.type() != profiler::BlockType::Block)
{
hasParticularBlockIndex = false;
profiler_gui::set_max(_blockIndex);
profiler_gui::set_max(_blockId);
/*
auto value = block.value;
const bool isString = value->type() == profiler::DataType::String;
auto valueItem = new ArbitraryTreeWidgetItem(rootItem, !isString, desc.color(), value->value_id());
auto valueItem = new ArbitraryTreeWidgetItem(rootItem, !isString, desc.color(), *value);
valueItem->setText(int_cast(ArbitraryColumns::Type), profiler_gui::valueTypeString(*value));
valueItem->setText(int_cast(ArbitraryColumns::Name), desc.name());
valueItem->setText(int_cast(ArbitraryColumns::Vin), QString("0x%1").arg(value->value_id(), 0, 16));
valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*value));
valueItem->setData(int_cast(ArbitraryColumns::Type), Qt::UserRole, 2);
@ -2362,9 +2425,12 @@ QTreeWidgetItem* ArbitraryValuesWidget::buildTreeForThread(const profiler::Block
valueItem->setWidthHint(std::max(sizeHintWidth, fm.width(valueItem->text(CheckColumn))) + 32);
return rootItem;
*/
}
else
{
_blockId = block.node->id();
}
_blockId = block.node->id();
}
const bool anyBlockId = profiler_gui::is_max(_blockId);
@ -2458,7 +2524,7 @@ QTreeWidgetItem* ArbitraryValuesWidget::buildTreeForThread(const profiler::Block
{
for (int childIndex = valueItem->childCount(); childIndex < size; ++childIndex)
{
auto item = new ArbitraryTreeWidgetItem(valueItem, true, desc.color(), vin);
auto item = new ArbitraryTreeWidgetItem(valueItem, true, desc.color(), *value);
item->setText(int_cast(ArbitraryColumns::Name), QString("%1[%2]").arg(desc.name()).arg(childIndex));
item->setData(int_cast(ArbitraryColumns::Type), Qt::UserRole, 3);
@ -2500,10 +2566,9 @@ QTreeWidgetItem* ArbitraryValuesWidget::buildTreeForThread(const profiler::Block
}
const bool isString = value->type() == profiler::DataType::String;
valueItem = new ArbitraryTreeWidgetItem(blockItem, !isString, desc.color(), vin);
valueItem = new ArbitraryTreeWidgetItem(blockItem, !isString, desc.color(), *value);
valueItem->setText(int_cast(ArbitraryColumns::Type), profiler_gui::valueTypeString(*value));
valueItem->setText(int_cast(ArbitraryColumns::Name), desc.name());
valueItem->setText(int_cast(ArbitraryColumns::Vin), QString("0x%1").arg(vin, 0, 16));
valueItem->setData(int_cast(ArbitraryColumns::Type), Qt::UserRole, 2);
if (i == _blockIndex)
@ -2521,7 +2586,7 @@ QTreeWidgetItem* ArbitraryValuesWidget::buildTreeForThread(const profiler::Block
{
for (int childIndex = valueItem->childCount(); childIndex < size; ++childIndex)
{
auto item = new ArbitraryTreeWidgetItem(valueItem, true, desc.color(), vin);
auto item = new ArbitraryTreeWidgetItem(valueItem, true, desc.color(), *value);
item->setText(int_cast(ArbitraryColumns::Name), QString("%1[%2]").arg(desc.name()).arg(childIndex));
item->setData(int_cast(ArbitraryColumns::Type), Qt::UserRole, 3);

View File

@ -296,19 +296,21 @@ class ArbitraryTreeWidgetItem : public QTreeWidgetItem
using This = ArbitraryTreeWidgetItem;
using CollectionPtr = std::unique_ptr<ArbitraryValuesCollection>;
const profiler::ArbitraryValue& m_value;
QFont m_font;
CollectionPtr m_collection;
profiler::vin_t m_vin;
profiler::color_t m_color;
int m_widthHint;
public:
explicit ArbitraryTreeWidgetItem(QTreeWidgetItem* _parent, bool _checkable, profiler::color_t _color, profiler::vin_t _vin = 0);
explicit ArbitraryTreeWidgetItem(QTreeWidgetItem* _parent, bool _checkable, profiler::color_t _color, const profiler::ArbitraryValue& _value);
~ArbitraryTreeWidgetItem() override;
QVariant data(int _column, int _role) const override;
const profiler::ArbitraryValue& value() const;
void setWidthHint(int _width);
void setBold(bool _isBold);
@ -320,7 +322,7 @@ public:
profiler::color_t color() const;
bool isArrayItem() const;
int getSelfIndexInArray();
int getSelfIndexInArray() const;
private:
@ -354,12 +356,14 @@ public:
explicit ArbitraryValuesWidget(QWidget* _parent = nullptr);
~ArbitraryValuesWidget() override;
void contextMenuEvent(QContextMenuEvent*) override {}
void contextMenuEvent(QContextMenuEvent*) override { /* ignore context menu event */ }
public slots:
void clear();
void rebuild();
void rebuild(profiler::thread_id_t _threadId);
void select(const profiler::ArbitraryValue& _value, bool _resetOthers = true);
private slots:

View File

@ -1058,6 +1058,7 @@ void BlocksGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
}
}
const bool isDoubleClick = m_bDoubleClick;
m_bDoubleClick = false;
m_mouseButtons = _event->buttons();
m_mouseMovePath = QPoint();
@ -1072,12 +1073,6 @@ void BlocksGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
{
profiler_gui::BoolFlagGuard guard(m_bUpdatingRect, true);
if (selectedBlock != nullptr && previouslySelectedBlock == EASY_GLOBALS.selected_block && !selectedBlock->tree.children.empty())
{
EASY_GLOBALS.gui_blocks[previouslySelectedBlock].expanded = !EASY_GLOBALS.gui_blocks[previouslySelectedBlock].expanded;
emit EASY_GLOBALS.events.itemsExpandStateChanged();
}
emit EASY_GLOBALS.events.selectedBlockChanged(EASY_GLOBALS.selected_block);
if (EASY_GLOBALS.selecting_block_changes_thread && selectedBlock != nullptr && EASY_GLOBALS.selected_thread != selectedBlockThread)
@ -1089,6 +1084,20 @@ void BlocksGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
emit EASY_GLOBALS.events.unlockCharts();
}
if (selectedBlock != nullptr && isDoubleClick)
{
if (!selectedBlock->tree.children.empty())
{
auto& selected = EASY_GLOBALS.gui_blocks[EASY_GLOBALS.selected_block];
selected.expanded = !selected.expanded;
emit EASY_GLOBALS.events.itemsExpandStateChanged();
}
else if (easyDescriptor(selectedBlock->tree.node->id()).type() == profiler::BlockType::Value)
{
emit EASY_GLOBALS.events.selectValue(selectedBlockThread, *selectedBlock->tree.value);
}
}
guard.restore();
if (selectedBlock != nullptr && selectedBlockThread == EASY_GLOBALS.selected_thread)

View File

@ -914,6 +914,11 @@ void BlockDescriptorsWidget::clear()
m_values->clear();
}
ArbitraryValuesWidget* BlockDescriptorsWidget::dataViewer() const
{
return m_values;
}
void BlockDescriptorsWidget::onSeachBoxReturnPressed()
{
if (m_searchButton->data().toBool() == true)

View File

@ -211,6 +211,7 @@ public:
void build();
void clear();
class ArbitraryValuesWidget* dataViewer() const;
private slots:

View File

@ -58,6 +58,8 @@
#include <QObject>
#include <easy/details/profiler_public_types.h>
namespace profiler { class ArbitraryValue; }
namespace profiler_gui {
class GlobalSignals Q_DECL_FINAL : public QObject
@ -100,6 +102,8 @@ namespace profiler_gui {
void chartWheeled(qreal pos, int delta);
void chartSliderChanged(qreal pos);
void selectValue(::profiler::thread_id_t _threadId, const ::profiler::ArbitraryValue& _value);
}; // END of class GlobalSignals.
} // END of namespace profiler_gui.

View File

@ -97,6 +97,7 @@
#include <QDateTime>
#include "main_window.h"
#include "arbitrary_value_inspector.h"
#include "blocks_tree_widget.h"
#include "blocks_graphics_view.h"
#include "descriptors_tree_widget.h"
@ -795,6 +796,7 @@ MainWindow::MainWindow() : Parent(), m_theme("default"), m_lastAddress("localhos
connect(&EASY_GLOBALS.events, &::profiler_gui::GlobalSignals::blockStatusChanged, this, &This::onBlockStatusChange);
connect(&EASY_GLOBALS.events, &::profiler_gui::GlobalSignals::blocksRefreshRequired, this, &This::onGetBlockDescriptionsClicked);
connect(&EASY_GLOBALS.events, &::profiler_gui::GlobalSignals::selectValue, this, &This::onSelectValue);
}
MainWindow::~MainWindow()
@ -2416,6 +2418,12 @@ void MainWindow::onBlockStatusChange(::profiler::block_id_t _id, ::profiler::Eas
m_listener.send(profiler::net::BlockStatusMessage(_id, static_cast<uint8_t>(_status)));
}
void MainWindow::onSelectValue(profiler::thread_id_t _threadId, const profiler::ArbitraryValue& _value)
{
onEditBlocksClicked(true);
m_dialogDescTree->dataViewer()->rebuild(_threadId);
}
void DialogWithGeometry::create()
{
ptr = new QDialog();

View File

@ -328,6 +328,8 @@ protected slots:
void onBlockStatusChange(profiler::block_id_t _id, profiler::EasyBlockStatus _status);
void onSelectValue(profiler::thread_id_t _threadId, const profiler::ArbitraryValue& _value);
void checkFrameTimeReady();
void validateLastDir();