2016-06-26 22:34:51 +03:00
/************************************************************************
* file name : blocks_tree_widget . cpp
* - - - - - - - - - - - - - - - - - :
* creation time : 2016 / 06 / 26
* copyright : ( c ) 2016 Victor Zarubkin
* author : Victor Zarubkin
* email : v . s . zarubkin @ gmail . com
* - - - - - - - - - - - - - - - - - :
* description : The file contains implementation of TreeWidget and it ' s auxiliary classes
* : for displyaing easy_profiler blocks tree .
* - - - - - - - - - - - - - - - - - :
2016-06-27 22:11:26 +03:00
* change log : * 2016 / 06 / 26 Victor Zarubkin : Moved sources from tree_view . h
2016-06-26 22:34:51 +03:00
* : and renamed classes from My * to Prof * .
2016-06-30 02:57:57 +03:00
* :
2016-06-27 22:11:26 +03:00
* : * 2016 / 06 / 27 Victor Zarubkin : Added possibility to colorize rows
* : with profiler blocks ' colors .
* : Also added displaying frame statistics for blocks .
2016-06-27 23:24:04 +03:00
* : Disabled sorting by name to save order of threads displayed on graphics view .
2016-06-30 02:57:57 +03:00
* :
* : * 2016 / 06 / 29 Victor Zarubkin : Added clearSilent ( ) method .
* :
2016-06-27 22:11:26 +03:00
* : *
2016-06-26 22:34:51 +03:00
* - - - - - - - - - - - - - - - - - :
* license : TODO : add license text
2016-06-26 18:56:40 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-06-26 18:46:51 +03:00
# include <QMenu>
# include <QContextMenuEvent>
2016-06-27 22:11:26 +03:00
# include <QSignalBlocker>
2016-06-26 18:46:51 +03:00
# include "blocks_tree_widget.h"
//////////////////////////////////////////////////////////////////////////
2016-06-27 22:11:26 +03:00
enum ColumnsIndexes
{
COL_UNKNOWN = - 1 ,
COL_NAME = 0 ,
COL_BEGIN ,
2016-07-31 18:48:41 +03:00
COL_DURATION ,
2016-06-27 22:11:26 +03:00
COL_END ,
COL_MIN_TOTAL ,
COL_MAX_TOTAL ,
COL_AVERAGE_TOTAL ,
COL_NCALLS_TOTAL ,
COL_MIN ,
COL_MAX ,
COL_AVERAGE ,
COL_NCALLS ,
COL_COLUMNS_NUMBER
} ;
//////////////////////////////////////////////////////////////////////////
ProfTreeWidgetItem : : ProfTreeWidgetItem ( const BlocksTree * _treeBlock , Parent * _parent )
: Parent ( _parent )
, m_block ( _treeBlock )
2016-06-26 18:46:51 +03:00
{
}
2016-06-26 20:54:16 +03:00
ProfTreeWidgetItem : : ~ ProfTreeWidgetItem ( )
{
}
2016-06-27 22:11:26 +03:00
bool ProfTreeWidgetItem : : operator < ( const Parent & _other ) const
{
const auto col = treeWidget ( ) - > sortColumn ( ) ;
switch ( col )
{
2016-06-27 23:22:12 +03:00
// case COL_UNKNOWN:
2016-07-31 18:48:41 +03:00
case COL_NAME :
{
// column 0 - Name
if ( parent ( ) = = nullptr )
return false ; // Do not sort topLevelItems
return Parent : : operator < ( _other ) ;
}
2016-06-27 22:11:26 +03:00
case COL_NCALLS_TOTAL :
case COL_NCALLS :
{
// column 7 and 11 - N calls
return data ( col , Qt : : UserRole ) . toUInt ( ) < _other . data ( col , Qt : : UserRole ) . toUInt ( ) ;
}
default :
{
// columns [1; 6] and [8; 10] - durations
return data ( col , Qt : : UserRole ) . toULongLong ( ) < _other . data ( col , Qt : : UserRole ) . toULongLong ( ) ;
}
}
return false ;
}
2016-06-26 19:06:53 +03:00
const BlocksTree * ProfTreeWidgetItem : : block ( ) const
2016-06-26 18:46:51 +03:00
{
return m_block ;
}
2016-06-26 19:06:53 +03:00
void ProfTreeWidgetItem : : setTimeSmart ( int _column , const : : profiler : : timestamp_t & _time )
2016-06-26 18:46:51 +03:00
{
2016-06-26 21:14:15 +03:00
setData ( _column , Qt : : UserRole , ( quint64 ) _time ) ;
2016-06-26 18:46:51 +03:00
setToolTip ( _column , QString ( " %1 ns " ) . arg ( _time ) ) ;
if ( _time < 1e3 )
{
setText ( _column , QString ( " %1 ns " ) . arg ( _time ) ) ;
}
else if ( _time < 1e6 )
{
setText ( _column , QString ( " %1 us " ) . arg ( double ( _time ) * 1e-3 , 0 , ' f ' , 3 ) ) ;
}
else if ( _time < 1e9 )
{
setText ( _column , QString ( " %1 ms " ) . arg ( double ( _time ) * 1e-6 , 0 , ' f ' , 3 ) ) ;
}
else
{
setText ( _column , QString ( " %1 s " ) . arg ( double ( _time ) * 1e-9 , 0 , ' f ' , 3 ) ) ;
}
}
2016-06-26 19:06:53 +03:00
void ProfTreeWidgetItem : : setTimeMs ( int _column , const : : profiler : : timestamp_t & _time )
2016-06-26 18:46:51 +03:00
{
2016-06-26 21:14:15 +03:00
setData ( _column , Qt : : UserRole , ( quint64 ) _time ) ;
2016-06-26 18:46:51 +03:00
setToolTip ( _column , QString ( " %1 ns " ) . arg ( _time ) ) ;
setText ( _column , QString : : number ( double ( _time ) * 1e-6 , ' g ' , 9 ) ) ;
}
2016-06-27 22:11:26 +03:00
void ProfTreeWidgetItem : : setBackgroundColor ( const QColor & _color )
{
m_customBGColor = _color ;
}
void ProfTreeWidgetItem : : setTextColor ( const QColor & _color )
{
m_customTextColor = _color ;
}
void ProfTreeWidgetItem : : colorize ( bool _colorize )
{
if ( _colorize )
{
for ( int i = 0 ; i < COL_COLUMNS_NUMBER ; + + i )
{
setBackground ( i , m_customBGColor ) ;
setForeground ( i , m_customTextColor ) ;
}
}
else
{
const QBrush nobrush ;
for ( int i = 0 ; i < COL_COLUMNS_NUMBER ; + + i )
{
setBackground ( i , nobrush ) ;
setForeground ( i , nobrush ) ;
}
}
}
2016-07-31 18:48:41 +03:00
void ProfTreeWidgetItem : : collapseAll ( )
{
for ( int i = 0 , childrenNumber = childCount ( ) ; i < childrenNumber ; + + i )
{
static_cast < ProfTreeWidgetItem * > ( child ( i ) ) - > collapseAll ( ) ;
}
setExpanded ( false ) ;
}
void ProfTreeWidgetItem : : expandAll ( )
{
for ( int i = 0 , childrenNumber = childCount ( ) ; i < childrenNumber ; + + i )
{
static_cast < ProfTreeWidgetItem * > ( child ( i ) ) - > expandAll ( ) ;
}
setExpanded ( true ) ;
}
2016-06-26 18:46:51 +03:00
//////////////////////////////////////////////////////////////////////////
2016-07-31 18:48:41 +03:00
ProfTreeWidget : : ProfTreeWidget ( QWidget * _parent ) : Parent ( _parent ) , m_beginTime ( - 1 ) , m_bColorRows ( true )
2016-06-26 18:46:51 +03:00
{
2016-06-27 22:11:26 +03:00
setAutoFillBackground ( false ) ;
2016-06-26 18:46:51 +03:00
setAlternatingRowColors ( true ) ;
setItemsExpandable ( true ) ;
setAnimated ( true ) ;
setSortingEnabled ( false ) ;
2016-06-27 22:11:26 +03:00
setColumnCount ( COL_COLUMNS_NUMBER ) ;
2016-06-26 18:46:51 +03:00
auto header = new QTreeWidgetItem ( ) ;
2016-06-27 22:11:26 +03:00
header - > setText ( COL_NAME , " Name " ) ;
header - > setText ( COL_DURATION , " Duration " ) ;
header - > setText ( COL_BEGIN , " Begin, ms " ) ;
header - > setText ( COL_END , " End, ms " ) ;
header - > setText ( COL_MIN_TOTAL , " Min dur. total " ) ;
header - > setText ( COL_MAX_TOTAL , " Max dur. total " ) ;
header - > setText ( COL_AVERAGE_TOTAL , " Average dur. total " ) ;
header - > setText ( COL_NCALLS_TOTAL , " N Calls total " ) ;
header - > setText ( COL_MIN , " Min dur. " ) ;
header - > setText ( COL_MAX , " Max dur. " ) ;
header - > setText ( COL_AVERAGE , " Average dur. " ) ;
header - > setText ( COL_NCALLS , " N Calls " ) ;
2016-06-26 18:46:51 +03:00
setHeaderItem ( header ) ;
2016-06-26 20:54:16 +03:00
}
2016-06-26 18:46:51 +03:00
2016-06-27 22:11:26 +03:00
ProfTreeWidget : : ProfTreeWidget ( const unsigned int _blocksNumber , const thread_blocks_tree_t & _blocksTree , QWidget * _parent ) : This ( _parent )
2016-06-26 20:54:16 +03:00
{
2016-06-27 22:11:26 +03:00
setTreeInternal ( _blocksNumber , _blocksTree ) ;
2016-06-26 18:46:51 +03:00
setSortingEnabled ( true ) ;
2016-06-27 22:11:26 +03:00
sortByColumn ( COL_BEGIN , Qt : : AscendingOrder ) ;
2016-06-26 18:46:51 +03:00
2016-06-27 22:11:26 +03:00
connect ( this , & Parent : : itemExpanded , this , & This : : onItemExpand ) ;
2016-06-26 18:46:51 +03:00
}
2016-06-26 20:54:16 +03:00
ProfTreeWidget : : ~ ProfTreeWidget ( )
{
}
2016-07-31 18:48:41 +03:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2016-06-27 22:11:26 +03:00
void ProfTreeWidget : : setTree ( const unsigned int _blocksNumber , const thread_blocks_tree_t & _blocksTree )
2016-06-26 18:46:51 +03:00
{
2016-06-30 02:57:57 +03:00
clearSilent ( ) ;
2016-06-26 18:46:51 +03:00
2016-06-27 22:11:26 +03:00
setTreeInternal ( _blocksNumber , _blocksTree ) ;
2016-06-26 18:46:51 +03:00
setSortingEnabled ( true ) ;
2016-06-27 22:11:26 +03:00
sortByColumn ( COL_BEGIN , Qt : : AscendingOrder ) ;
2016-06-26 18:46:51 +03:00
2016-06-27 22:11:26 +03:00
connect ( this , & Parent : : itemExpanded , this , & This : : onItemExpand ) ;
2016-06-26 18:46:51 +03:00
}
2016-07-31 18:48:41 +03:00
void ProfTreeWidget : : setTreeBlocks ( const TreeBlocks & _blocks , : : profiler : : timestamp_t _begin_time )
{
clearSilent ( ) ;
m_beginTime = _begin_time ;
setTreeInternal ( _blocks ) ;
setSortingEnabled ( true ) ;
sortByColumn ( COL_BEGIN , Qt : : AscendingOrder ) ;
connect ( this , & Parent : : itemExpanded , this , & This : : onItemExpand ) ;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2016-06-30 02:57:57 +03:00
void ProfTreeWidget : : clearSilent ( )
{
m_beginTime = - 1 ;
setSortingEnabled ( false ) ;
disconnect ( this , & Parent : : itemExpanded , this , & This : : onItemExpand ) ;
m_items . clear ( ) ;
m_itemblocks . clear ( ) ;
const QSignalBlocker b ( this ) ;
clear ( ) ;
}
2016-07-31 18:48:41 +03:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2016-06-27 22:11:26 +03:00
void ProfTreeWidget : : setTreeInternal ( const unsigned int _blocksNumber , const thread_blocks_tree_t & _blocksTree )
2016-06-26 18:46:51 +03:00
{
2016-06-27 22:11:26 +03:00
m_items . reserve ( _blocksNumber + _blocksTree . size ( ) ) ; // _blocksNumber does not include Thread root blocks
2016-06-26 18:46:51 +03:00
for ( const auto & threadTree : _blocksTree )
{
const auto beginTime = threadTree . second . children . front ( ) . node - > block ( ) - > getBegin ( ) ;
if ( m_beginTime > beginTime )
{
m_beginTime = beginTime ;
}
}
2016-06-30 02:57:57 +03:00
const QSignalBlocker b ( this ) ;
2016-06-26 18:46:51 +03:00
for ( const auto & threadTree : _blocksTree )
{
2016-06-26 19:06:53 +03:00
auto item = new ProfTreeWidgetItem ( & threadTree . second ) ;
2016-06-27 22:11:26 +03:00
item - > setText ( COL_NAME , QString ( " Thread %1 " ) . arg ( threadTree . first ) ) ;
2016-07-31 18:48:41 +03:00
2016-06-27 22:11:26 +03:00
m_items . push_back ( item ) ;
2016-07-31 18:48:41 +03:00
2016-06-26 18:46:51 +03:00
setTreeInternal ( threadTree . second . children , item ) ;
2016-07-31 18:48:41 +03:00
2016-06-26 18:46:51 +03:00
addTopLevelItem ( item ) ;
2016-07-31 18:48:41 +03:00
if ( m_bColorRows )
{
item - > colorize ( m_bColorRows ) ;
}
}
}
void ProfTreeWidget : : setTreeInternal ( const TreeBlocks & _blocks )
{
if ( _blocks . empty ( ) )
{
return ;
}
size_t blocksNumber = 0 ;
for ( const auto & block : _blocks )
{
blocksNumber + = block . tree - > total_children_number ;
}
m_items . reserve ( blocksNumber + _blocks . size ( ) ) ; // blocksNumber does not include root blocks
typedef : : std : : unordered_map < : : profiler : : thread_id_t , ProfTreeWidgetItem * , : : btw : : do_no_hash < : : profiler : : thread_id_t > : : hasher_t > ThreadsMap ;
ThreadsMap threadsMap ;
const QSignalBlocker b ( this ) ;
for ( const auto & block : _blocks )
{
ProfTreeWidgetItem * thread_item = nullptr ;
auto thread_item_it = threadsMap . find ( block . thread_id ) ;
if ( thread_item_it ! = threadsMap . end ( ) )
{
thread_item = thread_item_it - > second ;
}
else
{
thread_item = new ProfTreeWidgetItem ( block . thread_tree ) ;
thread_item - > setText ( COL_NAME , QString ( " Thread %1 " ) . arg ( block . thread_id ) ) ;
m_items . push_back ( thread_item ) ;
threadsMap . insert ( : : std : : make_pair ( block . thread_id , thread_item ) ) ;
}
auto item = new ProfTreeWidgetItem ( block . tree , thread_item ) ;
item - > setText ( COL_NAME , block . tree - > node - > getBlockName ( ) ) ;
item - > setTimeSmart ( COL_DURATION , block . tree - > node - > block ( ) - > duration ( ) ) ;
item - > setTimeMs ( COL_BEGIN , block . tree - > node - > block ( ) - > getBegin ( ) - m_beginTime ) ;
item - > setTimeMs ( COL_END , block . tree - > node - > block ( ) - > getEnd ( ) - m_beginTime ) ;
if ( block . tree - > total_statistics )
{
item - > setTimeSmart ( COL_MIN_TOTAL , block . tree - > total_statistics - > min_duration ) ;
item - > setTimeSmart ( COL_MAX_TOTAL , block . tree - > total_statistics - > max_duration ) ;
item - > setTimeSmart ( COL_AVERAGE_TOTAL , block . tree - > total_statistics - > average_duration ( ) ) ;
item - > setData ( COL_NCALLS_TOTAL , Qt : : UserRole , block . tree - > total_statistics - > calls_number ) ;
item - > setText ( COL_NCALLS_TOTAL , QString : : number ( block . tree - > total_statistics - > calls_number ) ) ;
}
if ( block . tree - > frame_statistics )
{
item - > setTimeSmart ( COL_MIN , block . tree - > frame_statistics - > min_duration ) ;
item - > setTimeSmart ( COL_MAX , block . tree - > frame_statistics - > max_duration ) ;
item - > setTimeSmart ( COL_AVERAGE , block . tree - > frame_statistics - > average_duration ( ) ) ;
item - > setData ( COL_NCALLS , Qt : : UserRole , block . tree - > frame_statistics - > calls_number ) ;
item - > setText ( COL_NCALLS , QString : : number ( block . tree - > frame_statistics - > calls_number ) ) ;
}
const auto color = block . tree - > node - > block ( ) - > getColor ( ) ;
const auto bgColor = QColor ( toRgb ( profiler : : colors : : get_red ( color ) , profiler : : colors : : get_green ( color ) , profiler : : colors : : get_blue ( color ) ) ) ;
const auto fgColor = QColor ( QRgb ( 0x00ffffff - bgColor . rgb ( ) ) ) ;
item - > setBackgroundColor ( bgColor ) ;
item - > setTextColor ( fgColor ) ;
m_items . push_back ( item ) ;
m_itemblocks [ block . tree - > node ] = item ;
if ( ! block . tree - > children . empty ( ) )
{
setTreeInternal ( block . tree - > children , item ) ;
}
if ( m_bColorRows )
{
item - > colorize ( m_bColorRows ) ;
}
}
for ( auto it : threadsMap )
{
addTopLevelItem ( it . second ) ;
if ( m_bColorRows )
{
it . second - > colorize ( m_bColorRows ) ;
}
2016-06-26 18:46:51 +03:00
}
}
2016-06-26 19:06:53 +03:00
void ProfTreeWidget : : setTreeInternal ( const BlocksTree : : children_t & _children , ProfTreeWidgetItem * _parent )
2016-06-26 18:46:51 +03:00
{
for ( const auto & child : _children )
{
2016-06-26 19:06:53 +03:00
auto item = new ProfTreeWidgetItem ( & child , _parent ) ;
2016-06-27 22:11:26 +03:00
item - > setText ( COL_NAME , child . node - > getBlockName ( ) ) ;
item - > setTimeSmart ( COL_DURATION , child . node - > block ( ) - > duration ( ) ) ;
item - > setTimeMs ( COL_BEGIN , child . node - > block ( ) - > getBegin ( ) - m_beginTime ) ;
item - > setTimeMs ( COL_END , child . node - > block ( ) - > getEnd ( ) - m_beginTime ) ;
2016-06-26 18:46:51 +03:00
if ( child . total_statistics )
{
2016-06-27 22:11:26 +03:00
item - > setTimeSmart ( COL_MIN_TOTAL , child . total_statistics - > min_duration ) ;
item - > setTimeSmart ( COL_MAX_TOTAL , child . total_statistics - > max_duration ) ;
item - > setTimeSmart ( COL_AVERAGE_TOTAL , child . total_statistics - > average_duration ( ) ) ;
item - > setData ( COL_NCALLS_TOTAL , Qt : : UserRole , child . total_statistics - > calls_number ) ;
item - > setText ( COL_NCALLS_TOTAL , QString : : number ( child . total_statistics - > calls_number ) ) ;
}
if ( child . frame_statistics )
{
item - > setTimeSmart ( COL_MIN , child . frame_statistics - > min_duration ) ;
item - > setTimeSmart ( COL_MAX , child . frame_statistics - > max_duration ) ;
item - > setTimeSmart ( COL_AVERAGE , child . frame_statistics - > average_duration ( ) ) ;
item - > setData ( COL_NCALLS , Qt : : UserRole , child . frame_statistics - > calls_number ) ;
item - > setText ( COL_NCALLS , QString : : number ( child . frame_statistics - > calls_number ) ) ;
2016-06-26 18:46:51 +03:00
}
2016-06-27 22:11:26 +03:00
const auto color = child . node - > block ( ) - > getColor ( ) ;
2016-07-31 18:48:41 +03:00
const auto bgColor = QColor ( toRgb ( profiler : : colors : : get_red ( color ) , profiler : : colors : : get_green ( color ) , profiler : : colors : : get_blue ( color ) ) ) ;
2016-06-27 22:11:26 +03:00
const auto fgColor = QColor ( QRgb ( 0x00ffffff - bgColor . rgb ( ) ) ) ;
item - > setBackgroundColor ( bgColor ) ;
item - > setTextColor ( fgColor ) ;
m_items . push_back ( item ) ;
2016-06-26 18:46:51 +03:00
m_itemblocks [ child . node ] = item ;
if ( ! child . children . empty ( ) )
{
setTreeInternal ( child . children , item ) ;
}
2016-07-31 18:48:41 +03:00
if ( m_bColorRows )
{
item - > colorize ( m_bColorRows ) ;
}
2016-06-26 18:46:51 +03:00
}
}
2016-07-31 18:48:41 +03:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2016-06-26 19:06:53 +03:00
void ProfTreeWidget : : contextMenuEvent ( QContextMenuEvent * _event )
2016-06-26 18:46:51 +03:00
{
const auto col = currentColumn ( ) ;
2016-06-26 19:06:53 +03:00
auto item = static_cast < ProfTreeWidgetItem * > ( currentItem ( ) ) ;
2016-06-26 18:46:51 +03:00
if ( item = = nullptr | | col < 0 )
{
return ;
}
QMenu menu ;
auto action = new QAction ( " Expand all " , nullptr ) ;
2016-06-27 22:11:26 +03:00
connect ( action , & QAction : : triggered , this , & This : : onExpandAllClicked ) ;
2016-06-26 18:46:51 +03:00
menu . addAction ( action ) ;
action = new QAction ( " Collapse all " , nullptr ) ;
2016-06-27 22:11:26 +03:00
connect ( action , & QAction : : triggered , this , & This : : onCollapseAllClicked ) ;
menu . addAction ( action ) ;
menu . addSeparator ( ) ;
2016-07-31 18:48:41 +03:00
action = new QAction ( " Expand all children " , nullptr ) ;
connect ( action , & QAction : : triggered , this , & This : : onExpandAllChildrenClicked ) ;
menu . addAction ( action ) ;
action = new QAction ( " Collapse all children " , nullptr ) ;
connect ( action , & QAction : : triggered , this , & This : : onCollapseAllChildrenClicked ) ;
menu . addAction ( action ) ;
menu . addSeparator ( ) ;
2016-06-27 22:11:26 +03:00
action = new QAction ( " Color rows " , nullptr ) ;
action - > setCheckable ( true ) ;
action - > setChecked ( m_bColorRows ) ;
connect ( action , & QAction : : triggered , this , & This : : onColorizeRowsTriggered ) ;
2016-06-26 18:46:51 +03:00
menu . addAction ( action ) ;
switch ( col )
{
2016-06-27 22:11:26 +03:00
case COL_MIN_TOTAL :
case COL_MIN :
2016-06-26 18:46:51 +03:00
{
menu . addSeparator ( ) ;
2016-06-26 19:06:53 +03:00
auto itemAction = new ProfItemAction ( " Jump to such item " , item ) ;
2016-06-27 22:11:26 +03:00
connect ( itemAction , & ProfItemAction : : clicked , this , & This : : onJumpToMinItemClicked ) ;
2016-06-26 18:46:51 +03:00
menu . addAction ( itemAction ) ;
break ;
}
2016-06-27 22:11:26 +03:00
case COL_MAX_TOTAL :
case COL_MAX :
2016-06-26 18:46:51 +03:00
{
menu . addSeparator ( ) ;
2016-06-26 19:06:53 +03:00
auto itemAction = new ProfItemAction ( " Jump to such item " , item ) ;
2016-06-27 22:11:26 +03:00
connect ( itemAction , & ProfItemAction : : clicked , this , & This : : onJumpToMaxItemClicked ) ;
2016-06-26 18:46:51 +03:00
menu . addAction ( itemAction ) ;
break ;
}
}
menu . exec ( QCursor : : pos ( ) ) ;
_event - > accept ( ) ;
}
2016-07-31 18:48:41 +03:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2016-06-26 19:06:53 +03:00
void ProfTreeWidget : : onJumpToMinItemClicked ( ProfTreeWidgetItem * _item )
2016-06-26 18:46:51 +03:00
{
auto it = m_itemblocks . find ( _item - > block ( ) - > total_statistics - > min_duration_block ) ;
if ( it ! = m_itemblocks . end ( ) )
{
scrollToItem ( it - > second , QAbstractItemView : : PositionAtCenter ) ;
setCurrentItem ( it - > second ) ;
}
}
2016-06-26 19:06:53 +03:00
void ProfTreeWidget : : onJumpToMaxItemClicked ( ProfTreeWidgetItem * _item )
2016-06-26 18:46:51 +03:00
{
auto it = m_itemblocks . find ( _item - > block ( ) - > total_statistics - > max_duration_block ) ;
if ( it ! = m_itemblocks . end ( ) )
{
scrollToItem ( it - > second , QAbstractItemView : : PositionAtCenter ) ;
setCurrentItem ( it - > second ) ;
}
}
2016-06-26 19:06:53 +03:00
void ProfTreeWidget : : onCollapseAllClicked ( bool )
2016-06-26 18:46:51 +03:00
{
collapseAll ( ) ;
}
2016-06-26 19:06:53 +03:00
void ProfTreeWidget : : onExpandAllClicked ( bool )
2016-06-26 18:46:51 +03:00
{
2016-06-27 22:11:26 +03:00
disconnect ( this , & Parent : : itemExpanded , this , & This : : onItemExpand ) ;
2016-06-26 18:46:51 +03:00
expandAll ( ) ;
2016-06-27 22:11:26 +03:00
resizeColumnToContents ( COL_NAME ) ;
connect ( this , & Parent : : itemExpanded , this , & This : : onItemExpand ) ;
2016-06-26 18:46:51 +03:00
}
2016-07-31 18:48:41 +03:00
void ProfTreeWidget : : onCollapseAllChildrenClicked ( bool )
{
auto current = static_cast < ProfTreeWidgetItem * > ( currentItem ( ) ) ;
if ( current ! = nullptr )
{
current - > collapseAll ( ) ;
}
}
void ProfTreeWidget : : onExpandAllChildrenClicked ( bool )
{
auto current = static_cast < ProfTreeWidgetItem * > ( currentItem ( ) ) ;
if ( current ! = nullptr )
{
disconnect ( this , & Parent : : itemExpanded , this , & This : : onItemExpand ) ;
current - > expandAll ( ) ;
resizeColumnToContents ( COL_NAME ) ;
connect ( this , & Parent : : itemExpanded , this , & This : : onItemExpand ) ;
}
}
2016-06-26 19:06:53 +03:00
void ProfTreeWidget : : onItemExpand ( QTreeWidgetItem * )
2016-06-26 18:46:51 +03:00
{
2016-06-27 22:11:26 +03:00
resizeColumnToContents ( COL_NAME ) ;
}
void ProfTreeWidget : : onColorizeRowsTriggered ( bool _colorize )
{
const QSignalBlocker b ( this ) ;
m_bColorRows = _colorize ;
auto current = currentItem ( ) ;
collapseAll ( ) ; // Without collapseAll() changing items process is VERY VERY SLOW.
// TODO: Find the reason of such behavior. QSignalBlocker(this) does not help. QSignalBlocker(item) does not work, because items are not inherited from QObject.
for ( auto item : m_items )
{
item - > colorize ( m_bColorRows ) ;
}
// Scroll back to previously selected item
if ( current )
{
scrollToItem ( current , QAbstractItemView : : PositionAtCenter ) ;
setCurrentItem ( current ) ;
}
2016-06-26 18:46:51 +03:00
}
//////////////////////////////////////////////////////////////////////////