mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-27 08:41:02 +08:00
#31 [UI] Open several arbitrary values viewer windows
This commit is contained in:
parent
769236c35a
commit
dd5af5350b
@ -56,6 +56,7 @@
|
|||||||
#include <QActionGroup>
|
#include <QActionGroup>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
#include <QDialog>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QGraphicsScene>
|
#include <QGraphicsScene>
|
||||||
@ -73,6 +74,7 @@
|
|||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <set>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "arbitrary_value_inspector.h"
|
#include "arbitrary_value_inspector.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
@ -691,6 +693,8 @@ void ArbitraryValuesChartItem::paintMouseIndicator(QPainter* _painter, qreal _to
|
|||||||
{
|
{
|
||||||
const auto value = m_minValue + ((_bottom - ChartBound - yvalue) / _height) * (m_maxValue - m_minValue);
|
const auto value = m_minValue + ((_bottom - ChartBound - yvalue) / _height) * (m_maxValue - m_minValue);
|
||||||
valueString = QString::number(value, 'f', 3);
|
valueString = QString::number(value, 'f', 3);
|
||||||
|
if (valueString.endsWith(QStringLiteral(".000")))
|
||||||
|
valueString.chop(4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1797,7 +1801,8 @@ profiler::color_t ArbitraryTreeWidgetItem::color() const
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
|
ArbitraryValuesWidget::ArbitraryValuesWidget(bool _isMainWidget, profiler::thread_id_t _threadId
|
||||||
|
, profiler::block_index_t _blockIndex, profiler::block_id_t _blockId, QWidget* _parent)
|
||||||
: Parent(_parent)
|
: Parent(_parent)
|
||||||
, m_splitter(new QSplitter(Qt::Horizontal, this))
|
, m_splitter(new QSplitter(Qt::Horizontal, this))
|
||||||
, m_treeWidget(new QTreeWidget(this))
|
, m_treeWidget(new QTreeWidget(this))
|
||||||
@ -1808,7 +1813,13 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
|
|||||||
, m_filterWindowPicker(new QSpinBox(this))
|
, m_filterWindowPicker(new QSpinBox(this))
|
||||||
, m_exportToCsvAction(nullptr)
|
, m_exportToCsvAction(nullptr)
|
||||||
, m_boldItem(nullptr)
|
, m_boldItem(nullptr)
|
||||||
|
, m_threadId(_threadId)
|
||||||
|
, m_blockIndex(_blockIndex)
|
||||||
|
, m_blockId(_blockId)
|
||||||
|
, m_bMainWidget(_isMainWidget)
|
||||||
{
|
{
|
||||||
|
m_collectionsTimer.setInterval(100);
|
||||||
|
|
||||||
m_splitter->setHandleWidth(1);
|
m_splitter->setHandleWidth(1);
|
||||||
m_splitter->setContentsMargins(0, 0, 0, 0);
|
m_splitter->setContentsMargins(0, 0, 0, 0);
|
||||||
m_splitter->addWidget(m_treeWidget);
|
m_splitter->addWidget(m_treeWidget);
|
||||||
@ -1831,9 +1842,11 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
|
|||||||
auto action = tb->addAction(QIcon(imagePath("reload")), tr("Refresh values list"));
|
auto action = tb->addAction(QIcon(imagePath("reload")), tr("Refresh values list"));
|
||||||
connect(action, &QAction::triggered, this, Overload<void>::of(&This::rebuild));
|
connect(action, &QAction::triggered, this, Overload<void>::of(&This::rebuild));
|
||||||
|
|
||||||
|
action = tb->addAction(QIcon(imagePath("window")), tr("Open new window"));
|
||||||
|
connect(action, &QAction::triggered, this, &This::onOpenInNewWindowClicked);
|
||||||
|
|
||||||
m_exportToCsvAction = tb->addAction(QIcon(imagePath("csv")), tr("Export to csv"));
|
m_exportToCsvAction = tb->addAction(QIcon(imagePath("csv")), tr("Export to csv"));
|
||||||
connect(m_exportToCsvAction, &QAction::triggered, this, &This::onExportToCsvClicked);
|
connect(m_exportToCsvAction, &QAction::triggered, this, &This::onExportToCsvClicked);
|
||||||
m_exportToCsvAction->setEnabled(false);
|
|
||||||
|
|
||||||
tb->addSeparator();
|
tb->addSeparator();
|
||||||
|
|
||||||
@ -1881,14 +1894,21 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
|
|||||||
|
|
||||||
connect(&m_collectionsTimer, &QTimer::timeout, this, &This::onCollectionsTimeout);
|
connect(&m_collectionsTimer, &QTimer::timeout, this, &This::onCollectionsTimeout);
|
||||||
|
|
||||||
|
using profiler_gui::GlobalSignals;
|
||||||
|
auto globalEvents = &EASY_GLOBALS.events;
|
||||||
|
connect(globalEvents, &GlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChanged);
|
||||||
|
connect(globalEvents, &GlobalSignals::selectedBlockIdChanged, this, &This::onSelectedBlockIdChanged);
|
||||||
|
connect(globalEvents, &GlobalSignals::allDataGoingToBeDeleted, this, &This::clear);
|
||||||
|
|
||||||
|
if (_isMainWidget)
|
||||||
|
{
|
||||||
connect(m_treeWidget, &QTreeWidget::itemDoubleClicked, this, &This::onItemDoubleClicked);
|
connect(m_treeWidget, &QTreeWidget::itemDoubleClicked, this, &This::onItemDoubleClicked);
|
||||||
connect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged);
|
connect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged);
|
||||||
connect(m_treeWidget, &QTreeWidget::currentItemChanged, this, &This::onCurrentItemChanged);
|
connect(m_treeWidget, &QTreeWidget::currentItemChanged, this, &This::onCurrentItemChanged);
|
||||||
|
|
||||||
auto globalEvents = &EASY_GLOBALS.events;
|
connect(globalEvents, &GlobalSignals::fileOpened, this, Overload<void>::of(&This::rebuild));
|
||||||
connect(globalEvents, &profiler_gui::GlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChanged);
|
connect(globalEvents, &GlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChanged);
|
||||||
connect(globalEvents, &profiler_gui::GlobalSignals::selectedBlockIdChanged, this, &This::onSelectedBlockIdChanged);
|
}
|
||||||
connect(globalEvents, &profiler_gui::GlobalSignals::fileOpened, this, Overload<void>::of(&This::rebuild));
|
|
||||||
|
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
|
||||||
@ -1910,7 +1930,128 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
|
|||||||
connect(m_filterComboBox, Overload<int>::of(&QComboBox::currentIndexChanged), this, &This::onFilterComboBoxChanged);
|
connect(m_filterComboBox, Overload<int>::of(&QComboBox::currentIndexChanged), this, &This::onFilterComboBoxChanged);
|
||||||
connect(m_filterWindowPicker, Overload<int>::of(&QSpinBox::valueChanged), this, &This::onFilterWindowSizeChanged);
|
connect(m_filterWindowPicker, Overload<int>::of(&QSpinBox::valueChanged), this, &This::onFilterWindowSizeChanged);
|
||||||
|
|
||||||
rebuild();
|
rebuild(_threadId, _blockIndex, _blockId);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
|
||||||
|
: ArbitraryValuesWidget(true, EASY_GLOBALS.selected_thread, EASY_GLOBALS.selected_block, EASY_GLOBALS.selected_block_id, _parent)
|
||||||
|
{
|
||||||
|
m_exportToCsvAction->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArbitraryTreeWidgetItem* findSimilarItem(QTreeWidgetItem* _parentItem, ArbitraryTreeWidgetItem* _item)
|
||||||
|
{
|
||||||
|
for (int c = 0, childrenCount = _parentItem->childCount(); c < childrenCount; ++c)
|
||||||
|
{
|
||||||
|
auto child = _parentItem->child(c);
|
||||||
|
if (child->type() == ValueItemType)
|
||||||
|
{
|
||||||
|
auto item = reinterpret_cast<ArbitraryTreeWidgetItem*>(child);
|
||||||
|
if (&_item->value() == &item->value())
|
||||||
|
return item;
|
||||||
|
|
||||||
|
if (_item->value().value_id() == item->value().value_id() &&
|
||||||
|
_item->value().type() == item->value().type() &&
|
||||||
|
_item->value().isArray() == item->value().isArray() &&
|
||||||
|
_item->text(int_cast(ArbitraryColumns::Name)) == item->text(int_cast(ArbitraryColumns::Name)))
|
||||||
|
{
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto item = findSimilarItem(child, _item);
|
||||||
|
if (item != nullptr)
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArbitraryValuesWidget::ArbitraryValuesWidget(const QList<ArbitraryTreeWidgetItem*>& _checkedItems
|
||||||
|
, QTreeWidgetItem* _currentItem, profiler::thread_id_t _threadId, profiler::block_index_t _blockIndex
|
||||||
|
, profiler::block_id_t _blockId, QWidget* _parent)
|
||||||
|
: ArbitraryValuesWidget(false, _threadId, _blockIndex, _blockId, _parent)
|
||||||
|
{
|
||||||
|
for (auto item : _checkedItems)
|
||||||
|
{
|
||||||
|
for (int i = 0, topLevelItemsCount = m_treeWidget->topLevelItemCount(); i < topLevelItemsCount; ++i)
|
||||||
|
{
|
||||||
|
auto foundItem = findSimilarItem(m_treeWidget->topLevelItem(i), item);
|
||||||
|
if (foundItem != nullptr)
|
||||||
|
{
|
||||||
|
const auto checkState = item->checkState(CheckColumn);
|
||||||
|
foundItem->setCheckState(CheckColumn, checkState);
|
||||||
|
if (checkState == Qt::Checked)
|
||||||
|
{
|
||||||
|
m_checkedItems.push_back(foundItem);
|
||||||
|
foundItem->collectValues(m_threadId, m_chart->chartType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_checkedItems.empty())
|
||||||
|
{
|
||||||
|
m_collectionsTimer.start();
|
||||||
|
|
||||||
|
std::set<QTreeWidgetItem*> checked;
|
||||||
|
for (auto item : m_checkedItems)
|
||||||
|
{
|
||||||
|
if (item->getSelfIndexInArray() >= 0)
|
||||||
|
{
|
||||||
|
auto parentItem = item->parent();
|
||||||
|
if (checked.find(parentItem) != checked.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
checked.insert(parentItem);
|
||||||
|
|
||||||
|
Qt::CheckState newState = Qt::Checked;
|
||||||
|
for (int i = 0, childCount = parentItem->childCount(); i < childCount; ++i)
|
||||||
|
{
|
||||||
|
auto child = parentItem->child(i);
|
||||||
|
if (child->checkState(CheckColumn) != Qt::Checked)
|
||||||
|
{
|
||||||
|
newState = Qt::PartiallyChecked;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parentItem->setCheckState(CheckColumn, newState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_exportToCsvAction->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_currentItem != nullptr)
|
||||||
|
{
|
||||||
|
if (_currentItem->type() == ValueItemType)
|
||||||
|
{
|
||||||
|
auto item = reinterpret_cast<ArbitraryTreeWidgetItem*>(_currentItem);
|
||||||
|
for (int i = 0, topLevelItemsCount = m_treeWidget->topLevelItemCount(); i < topLevelItemsCount; ++i)
|
||||||
|
{
|
||||||
|
auto foundItem = findSimilarItem(m_treeWidget->topLevelItem(i), item);
|
||||||
|
if (foundItem != nullptr)
|
||||||
|
{
|
||||||
|
m_treeWidget->setCurrentItem(foundItem);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const int col = static_cast<int>(ArbitraryColumns::Name);
|
||||||
|
auto items = m_treeWidget->findItems(_currentItem->text(col), Qt::MatchExactly | Qt::MatchCaseSensitive | Qt::MatchRecursive, col);
|
||||||
|
if (!items.empty())
|
||||||
|
m_treeWidget->setCurrentItem(items.front());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(m_treeWidget, &QTreeWidget::itemDoubleClicked, this, &This::onItemDoubleClicked);
|
||||||
|
connect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged);
|
||||||
|
connect(m_treeWidget, &QTreeWidget::currentItemChanged, this, &This::onCurrentItemChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArbitraryValuesWidget::~ArbitraryValuesWidget()
|
ArbitraryValuesWidget::~ArbitraryValuesWidget()
|
||||||
@ -1933,6 +2074,11 @@ void ArbitraryValuesWidget::clear()
|
|||||||
m_boldItem = nullptr;
|
m_boldItem = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArbitraryValuesWidget::onSelectedThreadChanged(profiler::thread_id_t)
|
||||||
|
{
|
||||||
|
//rebuild();
|
||||||
|
}
|
||||||
|
|
||||||
void ArbitraryValuesWidget::onSelectedBlockChanged(uint32_t)
|
void ArbitraryValuesWidget::onSelectedBlockChanged(uint32_t)
|
||||||
{
|
{
|
||||||
if (profiler_gui::is_max(EASY_GLOBALS.selected_block))
|
if (profiler_gui::is_max(EASY_GLOBALS.selected_block))
|
||||||
@ -2032,7 +2178,7 @@ void ArbitraryValuesWidget::onItemChanged(QTreeWidgetItem* _item, int _column)
|
|||||||
if (prevSize != m_checkedItems.size())
|
if (prevSize != m_checkedItems.size())
|
||||||
{
|
{
|
||||||
if (!m_collectionsTimer.isActive())
|
if (!m_collectionsTimer.isActive())
|
||||||
m_collectionsTimer.start(100);
|
m_collectionsTimer.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2089,7 +2235,9 @@ void ArbitraryValuesWidget::onItemChanged(QTreeWidgetItem* _item, int _column)
|
|||||||
|
|
||||||
if (!uncheckedItems.isEmpty())
|
if (!uncheckedItems.isEmpty())
|
||||||
{
|
{
|
||||||
m_exportToCsvAction->setEnabled(!m_checkedItems.empty());
|
const bool hasCheckedItems = !m_checkedItems.empty();
|
||||||
|
m_exportToCsvAction->setEnabled(hasCheckedItems);
|
||||||
|
|
||||||
onCollectionsTimeout();
|
onCollectionsTimeout();
|
||||||
|
|
||||||
for (auto uncheckedItem : uncheckedItems)
|
for (auto uncheckedItem : uncheckedItems)
|
||||||
@ -2112,14 +2260,19 @@ void ArbitraryValuesWidget::onCurrentItemChanged(QTreeWidgetItem* _current, QTre
|
|||||||
|
|
||||||
void ArbitraryValuesWidget::rebuild()
|
void ArbitraryValuesWidget::rebuild()
|
||||||
{
|
{
|
||||||
rebuild(EASY_GLOBALS.selected_thread);
|
rebuild(EASY_GLOBALS.selected_thread, EASY_GLOBALS.selected_block, EASY_GLOBALS.selected_block_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArbitraryValuesWidget::rebuild(profiler::thread_id_t _threadId)
|
void ArbitraryValuesWidget::rebuild(profiler::thread_id_t _threadId, profiler::block_index_t _blockIndex
|
||||||
|
, profiler::block_id_t _blockId)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
buildTree(_threadId, EASY_GLOBALS.selected_block, EASY_GLOBALS.selected_block_id);
|
m_threadId = _threadId;
|
||||||
|
m_blockIndex = _blockIndex;
|
||||||
|
m_blockId = _blockId;
|
||||||
|
|
||||||
|
buildTree(_threadId, _blockIndex, _blockId);
|
||||||
|
|
||||||
m_treeWidget->expandAll();
|
m_treeWidget->expandAll();
|
||||||
for (int i = 0, columns = m_treeWidget->columnCount(); i < columns; ++i)
|
for (int i = 0, columns = m_treeWidget->columnCount(); i < columns; ++i)
|
||||||
@ -2144,6 +2297,7 @@ void ArbitraryValuesWidget::select(const profiler::ArbitraryValue& _value, bool
|
|||||||
decltype(m_checkedItems) uncheckedItems(std::move(m_checkedItems));
|
decltype(m_checkedItems) uncheckedItems(std::move(m_checkedItems));
|
||||||
|
|
||||||
m_exportToCsvAction->setEnabled(false);
|
m_exportToCsvAction->setEnabled(false);
|
||||||
|
|
||||||
onCollectionsTimeout();
|
onCollectionsTimeout();
|
||||||
|
|
||||||
for (auto item : uncheckedItems)
|
for (auto item : uncheckedItems)
|
||||||
@ -2212,7 +2366,7 @@ void ArbitraryValuesWidget::repaint()
|
|||||||
item->collectValues(EASY_GLOBALS.selected_thread, m_chart->chartType());
|
item->collectValues(EASY_GLOBALS.selected_thread, m_chart->chartType());
|
||||||
|
|
||||||
if (!m_collectionsTimer.isActive())
|
if (!m_collectionsTimer.isActive())
|
||||||
m_collectionsTimer.start(100);
|
m_collectionsTimer.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2367,6 +2521,35 @@ void ArbitraryValuesWidget::onExportToCsvClicked(bool)
|
|||||||
csv.write("\n");
|
csv.write("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArbitraryValuesWidget::onOpenInNewWindowClicked(bool)
|
||||||
|
{
|
||||||
|
saveSettings();
|
||||||
|
|
||||||
|
auto dialog = new QDialog(nullptr);
|
||||||
|
dialog->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||||
|
dialog->setWindowTitle("EasyProfiler");
|
||||||
|
connect(&EASY_GLOBALS.events, &profiler_gui::GlobalSignals::allDataGoingToBeDeleted, dialog, &QDialog::reject);
|
||||||
|
|
||||||
|
auto viewer = new ArbitraryValuesWidget(m_checkedItems, m_treeWidget->currentItem(), m_threadId, m_blockIndex, m_blockId, dialog);
|
||||||
|
|
||||||
|
auto layout = new QHBoxLayout(dialog);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
layout->addWidget(viewer);
|
||||||
|
|
||||||
|
// Load last dialog geometry
|
||||||
|
{
|
||||||
|
QSettings settings(profiler_gui::ORGANAZATION_NAME, profiler_gui::APPLICATION_NAME);
|
||||||
|
settings.beginGroup("ArbitraryValuesWidgetWindow");
|
||||||
|
auto geometry = settings.value("dialog/geometry").toByteArray();
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
if (!geometry.isEmpty())
|
||||||
|
dialog->restoreGeometry(geometry);
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
void ArbitraryValuesWidget::buildTree(profiler::thread_id_t _threadId, profiler::block_index_t _blockIndex, profiler::block_id_t _blockId)
|
void ArbitraryValuesWidget::buildTree(profiler::thread_id_t _threadId, profiler::block_index_t _blockIndex, profiler::block_id_t _blockId)
|
||||||
{
|
{
|
||||||
m_treeWidget->clear();
|
m_treeWidget->clear();
|
||||||
@ -2637,14 +2820,6 @@ void ArbitraryValuesWidget::loadSettings()
|
|||||||
QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME);
|
QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME);
|
||||||
settings.beginGroup("ArbitraryValuesWidget");
|
settings.beginGroup("ArbitraryValuesWidget");
|
||||||
|
|
||||||
auto geometry = settings.value("hsplitter/geometry").toByteArray();
|
|
||||||
if (!geometry.isEmpty())
|
|
||||||
m_splitter->restoreGeometry(geometry);
|
|
||||||
|
|
||||||
auto state = settings.value("hsplitter/state").toByteArray();
|
|
||||||
if (!state.isEmpty())
|
|
||||||
m_splitter->restoreState(state);
|
|
||||||
|
|
||||||
auto value = settings.value("chart/filterWindow");
|
auto value = settings.value("chart/filterWindow");
|
||||||
if (!value.isNull())
|
if (!value.isNull())
|
||||||
m_chart->setFilterWindowSize(value.toInt());
|
m_chart->setFilterWindowSize(value.toInt());
|
||||||
@ -2657,17 +2832,43 @@ void ArbitraryValuesWidget::loadSettings()
|
|||||||
if (!value.isNull())
|
if (!value.isNull())
|
||||||
m_chart->setChartType(static_cast<ChartType>(value.toInt()));
|
m_chart->setChartType(static_cast<ChartType>(value.toInt()));
|
||||||
|
|
||||||
|
if (!m_bMainWidget)
|
||||||
|
{
|
||||||
|
settings.endGroup();
|
||||||
|
settings.beginGroup("ArbitraryValuesWidgetWindow");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto geometry = settings.value("hsplitter/geometry").toByteArray();
|
||||||
|
if (!geometry.isEmpty())
|
||||||
|
m_splitter->restoreGeometry(geometry);
|
||||||
|
|
||||||
|
auto state = settings.value("hsplitter/state").toByteArray();
|
||||||
|
if (!state.isEmpty())
|
||||||
|
m_splitter->restoreState(state);
|
||||||
|
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArbitraryValuesWidget::saveSettings()
|
void ArbitraryValuesWidget::saveSettings()
|
||||||
{
|
{
|
||||||
QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME);
|
QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME);
|
||||||
|
|
||||||
|
if (!m_bMainWidget)
|
||||||
|
{
|
||||||
|
settings.beginGroup("ArbitraryValuesWidgetWindow");
|
||||||
|
settings.setValue("dialog/geometry", parentWidget()->saveGeometry());
|
||||||
|
settings.setValue("hsplitter/geometry", m_splitter->saveGeometry());
|
||||||
|
settings.setValue("hsplitter/state", m_splitter->saveState());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
settings.beginGroup("ArbitraryValuesWidget");
|
settings.beginGroup("ArbitraryValuesWidget");
|
||||||
settings.setValue("hsplitter/geometry", m_splitter->saveGeometry());
|
settings.setValue("hsplitter/geometry", m_splitter->saveGeometry());
|
||||||
settings.setValue("hsplitter/state", m_splitter->saveState());
|
settings.setValue("hsplitter/state", m_splitter->saveState());
|
||||||
settings.setValue("chart/type", static_cast<int>(m_chart->chartType()));
|
settings.setValue("chart/type", static_cast<int>(m_chart->chartType()));
|
||||||
settings.setValue("chart/filter", static_cast<int>(m_chart->filterType()));
|
settings.setValue("chart/filter", static_cast<int>(m_chart->filterType()));
|
||||||
settings.setValue("chart/filterWindow", m_chart->filterWindowSize());
|
settings.setValue("chart/filterWindow", m_chart->filterWindowSize());
|
||||||
|
}
|
||||||
|
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
@ -350,6 +350,16 @@ class ArbitraryValuesWidget : public QWidget
|
|||||||
class QSpinBox* m_filterWindowPicker;
|
class QSpinBox* m_filterWindowPicker;
|
||||||
class QAction* m_exportToCsvAction;
|
class QAction* m_exportToCsvAction;
|
||||||
ArbitraryTreeWidgetItem* m_boldItem;
|
ArbitraryTreeWidgetItem* m_boldItem;
|
||||||
|
profiler::thread_id_t m_threadId;
|
||||||
|
profiler::block_index_t m_blockIndex;
|
||||||
|
profiler::block_id_t m_blockId;
|
||||||
|
const bool m_bMainWidget;
|
||||||
|
|
||||||
|
explicit ArbitraryValuesWidget(bool _isMainWidget, profiler::thread_id_t _threadId
|
||||||
|
, profiler::block_index_t _blockIndex, profiler::block_id_t _blockId, QWidget* _parent);
|
||||||
|
explicit ArbitraryValuesWidget(const QList<ArbitraryTreeWidgetItem*>& _checkedItems
|
||||||
|
, QTreeWidgetItem* _currentItem, profiler::thread_id_t _threadId
|
||||||
|
, profiler::block_index_t _blockIndex, profiler::block_id_t _blockId, QWidget* _parent = nullptr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -362,11 +372,12 @@ public slots:
|
|||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
void rebuild();
|
void rebuild();
|
||||||
void rebuild(profiler::thread_id_t _threadId);
|
void rebuild(profiler::thread_id_t _threadId, profiler::block_index_t _blockIndex, profiler::block_id_t _blockId);
|
||||||
void select(const profiler::ArbitraryValue& _value, bool _resetOthers = true);
|
void select(const profiler::ArbitraryValue& _value, bool _resetOthers = true);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
void onSelectedThreadChanged(profiler::thread_id_t);
|
||||||
void onSelectedBlockChanged(uint32_t _block_index);
|
void onSelectedBlockChanged(uint32_t _block_index);
|
||||||
void onSelectedBlockIdChanged(profiler::block_id_t _id);
|
void onSelectedBlockIdChanged(profiler::block_id_t _id);
|
||||||
void onItemDoubleClicked(QTreeWidgetItem* _item, int _column);
|
void onItemDoubleClicked(QTreeWidgetItem* _item, int _column);
|
||||||
@ -378,6 +389,7 @@ private slots:
|
|||||||
void onFilterComboBoxChanged(int _index);
|
void onFilterComboBoxChanged(int _index);
|
||||||
void onFilterWindowSizeChanged(int _size);
|
void onFilterWindowSizeChanged(int _size);
|
||||||
void onExportToCsvClicked(bool);
|
void onExportToCsvClicked(bool);
|
||||||
|
void onOpenInNewWindowClicked(bool);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -1094,7 +1094,7 @@ void BlocksGraphicsView::mouseReleaseEvent(QMouseEvent* _event)
|
|||||||
}
|
}
|
||||||
else if (easyDescriptor(selectedBlock->tree.node->id()).type() == profiler::BlockType::Value)
|
else if (easyDescriptor(selectedBlock->tree.node->id()).type() == profiler::BlockType::Value)
|
||||||
{
|
{
|
||||||
emit EASY_GLOBALS.events.selectValue(selectedBlockThread, *selectedBlock->tree.value);
|
emit EASY_GLOBALS.events.selectValue(selectedBlockThread, EASY_GLOBALS.selected_block, *selectedBlock->tree.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1395,16 +1395,22 @@ void BlocksGraphicsView::initMode()
|
|||||||
connect(&m_flickerTimer, &QTimer::timeout, this, &This::onFlickerTimeout);
|
connect(&m_flickerTimer, &QTimer::timeout, this, &This::onFlickerTimeout);
|
||||||
connect(&m_idleTimer, &QTimer::timeout, this, &This::onIdleTimeout);
|
connect(&m_idleTimer, &QTimer::timeout, this, &This::onIdleTimeout);
|
||||||
|
|
||||||
|
using profiler_gui::GlobalSignals;
|
||||||
auto globalSignals = &EASY_GLOBALS.events;
|
auto globalSignals = &EASY_GLOBALS.events;
|
||||||
connect(globalSignals, &::profiler_gui::GlobalSignals::hierarchyFlagChanged, this, &This::onHierarchyFlagChange);
|
connect(globalSignals, &GlobalSignals::hierarchyFlagChanged, this, &This::onHierarchyFlagChange);
|
||||||
connect(globalSignals, &::profiler_gui::GlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChange);
|
connect(globalSignals, &GlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChange);
|
||||||
connect(globalSignals, &::profiler_gui::GlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange);
|
connect(globalSignals, &GlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange);
|
||||||
connect(globalSignals, &::profiler_gui::GlobalSignals::itemsExpandStateChanged, this, &This::onRefreshRequired);
|
connect(globalSignals, &GlobalSignals::itemsExpandStateChanged, this, &This::onRefreshRequired);
|
||||||
connect(globalSignals, &::profiler_gui::GlobalSignals::refreshRequired, this, &This::onRefreshRequired);
|
connect(globalSignals, &GlobalSignals::refreshRequired, this, &This::onRefreshRequired);
|
||||||
|
connect(globalSignals, &GlobalSignals::allDataGoingToBeDeleted, this, &This::clear);
|
||||||
|
|
||||||
connect(globalSignals, &::profiler_gui::GlobalSignals::selectedBlockIdChanged, [this](::profiler::block_id_t)
|
connect(globalSignals, &GlobalSignals::fileOpened, [this] {
|
||||||
|
setTree(EASY_GLOBALS.profiler_blocks);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(globalSignals, &GlobalSignals::selectedBlockIdChanged, [this](::profiler::block_id_t)
|
||||||
{
|
{
|
||||||
if (::profiler_gui::is_max(EASY_GLOBALS.selected_block_id))
|
if (profiler_gui::is_max(EASY_GLOBALS.selected_block_id))
|
||||||
{
|
{
|
||||||
if (EASY_GLOBALS.selected_thread != 0)
|
if (EASY_GLOBALS.selected_thread != 0)
|
||||||
{
|
{
|
||||||
@ -2253,10 +2259,13 @@ ThreadNamesWidget::ThreadNamesWidget(BlocksGraphicsView* _view, int _additionalH
|
|||||||
setFixedWidth(m_maxLength);
|
setFixedWidth(m_maxLength);
|
||||||
|
|
||||||
connect(&EASY_GLOBALS.events, &::profiler_gui::GlobalSignals::selectedThreadChanged, [this](::profiler::thread_id_t){ repaintScene(); });
|
connect(&EASY_GLOBALS.events, &::profiler_gui::GlobalSignals::selectedThreadChanged, [this](::profiler::thread_id_t){ repaintScene(); });
|
||||||
|
connect(&EASY_GLOBALS.events, &::profiler_gui::GlobalSignals::allDataGoingToBeDeleted, this, &This::clear);
|
||||||
|
|
||||||
connect(m_view, &BlocksGraphicsView::treeChanged, this, &This::onTreeChange);
|
connect(m_view, &BlocksGraphicsView::treeChanged, this, &This::onTreeChange);
|
||||||
connect(m_view, &BlocksGraphicsView::sceneUpdated, this, &This::repaintScene);
|
connect(m_view, &BlocksGraphicsView::sceneUpdated, this, &This::repaintScene);
|
||||||
connect(m_view->verticalScrollBar(), &QScrollBar::valueChanged, verticalScrollBar(), &QScrollBar::setValue, Qt::QueuedConnection);
|
connect(m_view->verticalScrollBar(), &QScrollBar::valueChanged, verticalScrollBar(), &QScrollBar::setValue, Qt::QueuedConnection);
|
||||||
connect(m_view->verticalScrollBar(), &QScrollBar::rangeChanged, this, &This::setVerticalScrollbarRange, Qt::QueuedConnection);
|
connect(m_view->verticalScrollBar(), &QScrollBar::rangeChanged, this, &This::setVerticalScrollbarRange, Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(&m_idleTimer, &QTimer::timeout, this, &This::onIdleTimeout);
|
connect(&m_idleTimer, &QTimer::timeout, this, &This::onIdleTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1142,6 +1142,9 @@ HierarchyWidget::HierarchyWidget(QWidget* _parent) : Parent(_parent)
|
|||||||
lay->addWidget(m_tree);
|
lay->addWidget(m_tree);
|
||||||
|
|
||||||
connect(m_searchBox, &QLineEdit::returnPressed, this, &This::onSeachBoxReturnPressed);
|
connect(m_searchBox, &QLineEdit::returnPressed, this, &This::onSeachBoxReturnPressed);
|
||||||
|
connect(&EASY_GLOBALS.events, &profiler_gui::GlobalSignals::allDataGoingToBeDeleted, [this] {
|
||||||
|
clear(true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
HierarchyWidget::~HierarchyWidget()
|
HierarchyWidget::~HierarchyWidget()
|
||||||
|
@ -841,6 +841,8 @@ BlockDescriptorsWidget::BlockDescriptorsWidget(QWidget* _parent) : Parent(_paren
|
|||||||
|
|
||||||
connect(m_searchBox, &QLineEdit::returnPressed, this, &This::onSeachBoxReturnPressed);
|
connect(m_searchBox, &QLineEdit::returnPressed, this, &This::onSeachBoxReturnPressed);
|
||||||
connect(&EASY_GLOBALS.events, &::profiler_gui::GlobalSignals::connectionChanged, refreshButton, &QAction::setEnabled);
|
connect(&EASY_GLOBALS.events, &::profiler_gui::GlobalSignals::connectionChanged, refreshButton, &QAction::setEnabled);
|
||||||
|
connect(&EASY_GLOBALS.events, &profiler_gui::GlobalSignals::allDataGoingToBeDeleted, this, &This::clear);
|
||||||
|
connect(&EASY_GLOBALS.events, &profiler_gui::GlobalSignals::fileOpened, this, &This::build);
|
||||||
|
|
||||||
loadSettings();
|
loadSettings();
|
||||||
caseSensitiveSwitch->setChecked(m_bCaseSensitiveSearch);
|
caseSensitiveSwitch->setChecked(m_bCaseSensitiveSearch);
|
||||||
|
@ -1167,6 +1167,8 @@ BlocksGraphicsScrollbar::BlocksGraphicsScrollbar(int _initialHeight, QWidget* _p
|
|||||||
|
|
||||||
connect(&EASY_GLOBALS.events, &profiler_gui::GlobalSignals::threadNameDecorationChanged, this, &This::onThreadViewChanged);
|
connect(&EASY_GLOBALS.events, &profiler_gui::GlobalSignals::threadNameDecorationChanged, this, &This::onThreadViewChanged);
|
||||||
connect(&EASY_GLOBALS.events, &profiler_gui::GlobalSignals::hexThreadIdChanged, this, &This::onThreadViewChanged);
|
connect(&EASY_GLOBALS.events, &profiler_gui::GlobalSignals::hexThreadIdChanged, this, &This::onThreadViewChanged);
|
||||||
|
|
||||||
|
connect(&EASY_GLOBALS.events, &profiler_gui::GlobalSignals::allDataGoingToBeDeleted, this, &This::clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlocksGraphicsScrollbar::~BlocksGraphicsScrollbar()
|
BlocksGraphicsScrollbar::~BlocksGraphicsScrollbar()
|
||||||
|
@ -73,6 +73,7 @@ namespace profiler_gui {
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
void allDataGoingToBeDeleted();
|
||||||
void fileOpened();
|
void fileOpened();
|
||||||
|
|
||||||
void selectedThreadChanged(::profiler::thread_id_t _id);
|
void selectedThreadChanged(::profiler::thread_id_t _id);
|
||||||
@ -102,7 +103,7 @@ namespace profiler_gui {
|
|||||||
void chartWheeled(qreal pos, int delta);
|
void chartWheeled(qreal pos, int delta);
|
||||||
void chartSliderChanged(qreal pos);
|
void chartSliderChanged(qreal pos);
|
||||||
|
|
||||||
void selectValue(::profiler::thread_id_t _threadId, const ::profiler::ArbitraryValue& _value);
|
void selectValue(::profiler::thread_id_t _thread_id, uint32_t _value_index, const ::profiler::ArbitraryValue& _value);
|
||||||
|
|
||||||
}; // END of class GlobalSignals.
|
}; // END of class GlobalSignals.
|
||||||
|
|
||||||
|
@ -44,3 +44,4 @@ default/arrow-right.svg - Icon made by Freepik from www.flaticon.com
|
|||||||
default/yx.svg - Icon made by Freepik from www.flaticon.com
|
default/yx.svg - Icon made by Freepik from www.flaticon.com
|
||||||
default/svg2.svg - Icon made by Freepik from www.flaticon.com
|
default/svg2.svg - Icon made by Freepik from www.flaticon.com
|
||||||
default/svg3.svg - Icon made by Freepik from www.flaticon.com
|
default/svg3.svg - Icon made by Freepik from www.flaticon.com
|
||||||
|
default/window.svg - Icon made by Freepik from www.flaticon.com
|
||||||
|
9
profiler_gui/images/default/window.svg
Normal file
9
profiler_gui/images/default/window.svg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="45px" height="45px" viewBox="0 0 45 45" style="enable-background:new 0 0 45 45;" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<path fill="#f44336" d="M11,6.5H6v5v22H0v-33h34v6H11z"/>
|
||||||
|
<path fill="#484848" d="M34,11.5H11v22v11h34v-33H34z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 514 B |
@ -1096,14 +1096,7 @@ void MainWindow::onSaveFileClicked(bool)
|
|||||||
|
|
||||||
void MainWindow::clear()
|
void MainWindow::clear()
|
||||||
{
|
{
|
||||||
static_cast<HierarchyWidget*>(m_treeWidget->widget())->clear(true);
|
emit EASY_GLOBALS.events.allDataGoingToBeDeleted();
|
||||||
static_cast<DiagramWidget*>(m_graphicsView->widget())->clear();
|
|
||||||
|
|
||||||
#if EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW != 0
|
|
||||||
static_cast<BlockDescriptorsWidget*>(m_descTreeWidget->widget())->clear();
|
|
||||||
#endif
|
|
||||||
if (m_dialogDescTree != nullptr)
|
|
||||||
m_dialogDescTree->clear();
|
|
||||||
|
|
||||||
EASY_GLOBALS.selected_thread = 0;
|
EASY_GLOBALS.selected_thread = 0;
|
||||||
::profiler_gui::set_max(EASY_GLOBALS.selected_block);
|
::profiler_gui::set_max(EASY_GLOBALS.selected_block);
|
||||||
@ -1821,7 +1814,7 @@ void MainWindow::onFileReaderTimeout()
|
|||||||
const auto nblocks = m_reader.size();
|
const auto nblocks = m_reader.size();
|
||||||
if (nblocks != 0)
|
if (nblocks != 0)
|
||||||
{
|
{
|
||||||
static_cast<HierarchyWidget*>(m_treeWidget->widget())->clear(true);
|
emit EASY_GLOBALS.events.allDataGoingToBeDeleted();
|
||||||
|
|
||||||
::profiler::SerializedData serialized_blocks;
|
::profiler::SerializedData serialized_blocks;
|
||||||
::profiler::SerializedData serialized_descriptors;
|
::profiler::SerializedData serialized_descriptors;
|
||||||
@ -1899,14 +1892,6 @@ void MainWindow::onFileReaderTimeout()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static_cast<DiagramWidget*>(m_graphicsView->widget())->view()->setTree(EASY_GLOBALS.profiler_blocks);
|
|
||||||
|
|
||||||
#if EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW != 0
|
|
||||||
static_cast<BlockDescriptorsWidget*>(m_descTreeWidget->widget())->build();
|
|
||||||
#endif
|
|
||||||
if (m_dialogDescTree != nullptr)
|
|
||||||
m_dialogDescTree->build();
|
|
||||||
|
|
||||||
m_saveAction->setEnabled(true);
|
m_saveAction->setEnabled(true);
|
||||||
m_deleteAction->setEnabled(true);
|
m_deleteAction->setEnabled(true);
|
||||||
}
|
}
|
||||||
@ -1936,9 +1921,9 @@ void MainWindow::onFileReaderTimeout()
|
|||||||
|
|
||||||
if (nblocks != 0)
|
if (nblocks != 0)
|
||||||
{
|
{
|
||||||
|
emit EASY_GLOBALS.events.fileOpened();
|
||||||
if (EASY_GLOBALS.all_items_expanded_by_default)
|
if (EASY_GLOBALS.all_items_expanded_by_default)
|
||||||
onExpandAllClicked(true);
|
onExpandAllClicked(true);
|
||||||
emit EASY_GLOBALS.events.fileOpened();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_progress != nullptr)
|
else if (m_progress != nullptr)
|
||||||
@ -2418,10 +2403,10 @@ void MainWindow::onBlockStatusChange(::profiler::block_id_t _id, ::profiler::Eas
|
|||||||
m_listener.send(profiler::net::BlockStatusMessage(_id, static_cast<uint8_t>(_status)));
|
m_listener.send(profiler::net::BlockStatusMessage(_id, static_cast<uint8_t>(_status)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onSelectValue(profiler::thread_id_t _threadId, const profiler::ArbitraryValue& _value)
|
void MainWindow::onSelectValue(profiler::thread_id_t _thread_id, uint32_t _value_index, const profiler::ArbitraryValue& _value)
|
||||||
{
|
{
|
||||||
onEditBlocksClicked(true);
|
onEditBlocksClicked(true);
|
||||||
m_dialogDescTree->dataViewer()->rebuild(_threadId);
|
m_dialogDescTree->dataViewer()->rebuild(_thread_id, _value_index, _value.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogWithGeometry::create()
|
void DialogWithGeometry::create()
|
||||||
|
@ -328,7 +328,7 @@ protected slots:
|
|||||||
|
|
||||||
void onBlockStatusChange(profiler::block_id_t _id, profiler::EasyBlockStatus _status);
|
void onBlockStatusChange(profiler::block_id_t _id, profiler::EasyBlockStatus _status);
|
||||||
|
|
||||||
void onSelectValue(profiler::thread_id_t _threadId, const profiler::ArbitraryValue& _value);
|
void onSelectValue(profiler::thread_id_t _thread_id, uint32_t _value_index, const profiler::ArbitraryValue& _value);
|
||||||
|
|
||||||
void checkFrameTimeReady();
|
void checkFrameTimeReady();
|
||||||
|
|
||||||
|
@ -52,5 +52,6 @@
|
|||||||
<file alias="yx-chart">images/default/yx.svg</file>
|
<file alias="yx-chart">images/default/yx.svg</file>
|
||||||
<file alias="big-o-chart">images/default/big-o.svg</file>
|
<file alias="big-o-chart">images/default/big-o.svg</file>
|
||||||
<file alias="csv">images/default/csv.svg</file>
|
<file alias="csv">images/default/csv.svg</file>
|
||||||
|
<file alias="window">images/default/window.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user