2013-10-08 15:07:03 +08:00
/* treemodel.cpp
2015-01-31 22:00:00 +08:00
Copyright ( c ) 2015 , Nikolaj Schlej . All rights reserved .
2013-12-29 23:13:46 +08:00
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution . The full text of the license may be found at
http : //opensource.org/licenses/bsd-license.php
2013-10-08 15:07:03 +08:00
2013-12-29 23:13:46 +08:00
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN " AS IS " BASIS ,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND , EITHER EXPRESS OR IMPLIED .
2013-10-08 15:07:03 +08:00
*/
# include "treemodel.h"
2016-11-03 03:40:38 +08:00
# include "stack"
2016-07-07 13:57:45 +08:00
# if defined(QT_CORE_LIB)
2016-06-26 11:54:21 +08:00
QVariant TreeModel : : data ( const UModelIndex & index , int role ) const
2013-10-08 15:07:03 +08:00
{
if ( ! index . isValid ( ) )
return QVariant ( ) ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
2017-10-12 13:59:23 +08:00
if ( role = = Qt : : DisplayRole ) {
2018-08-02 08:41:11 +08:00
return item - > data ( index . column ( ) ) . toLocal8Bit ( ) ;
2017-10-12 13:59:23 +08:00
}
2017-12-11 09:56:00 +08:00
# if defined (QT_GUI_LIB)
2017-10-12 13:59:23 +08:00
else if ( role = = Qt : : BackgroundRole ) {
2017-12-11 09:56:00 +08:00
if ( markingEnabledFlag & & marking ( index ) > 0 ) {
2017-10-12 13:59:23 +08:00
return QBrush ( ( Qt : : GlobalColor ) marking ( index ) ) ;
}
}
2017-12-11 09:56:00 +08:00
# endif
2017-10-12 13:59:23 +08:00
else if ( role = = Qt : : UserRole ) {
2018-08-02 08:41:11 +08:00
return item - > info ( ) . toLocal8Bit ( ) ;
2017-10-12 13:59:23 +08:00
}
return QVariant ( ) ;
2013-10-08 15:07:03 +08:00
}
2016-06-26 11:54:21 +08:00
Qt : : ItemFlags TreeModel : : flags ( const UModelIndex & index ) const
2013-10-08 15:07:03 +08:00
{
if ( ! index . isValid ( ) )
2021-04-04 17:09:23 +08:00
return Qt : : NoItemFlags ;
2013-10-08 15:07:03 +08:00
return Qt : : ItemIsEnabled | Qt : : ItemIsSelectable ;
}
QVariant TreeModel : : headerData ( int section , Qt : : Orientation orientation ,
2014-07-25 07:59:51 +08:00
int role ) const
2013-10-08 15:07:03 +08:00
{
2013-12-12 19:28:39 +08:00
if ( orientation = = Qt : : Horizontal & & role = = Qt : : DisplayRole ) {
2017-12-11 09:56:00 +08:00
switch ( section ) {
case 0 : return tr ( " Name " ) ;
case 1 : return tr ( " Action " ) ;
case 2 : return tr ( " Type " ) ;
case 3 : return tr ( " Subtype " ) ;
case 4 : return tr ( " Text " ) ;
2013-12-29 23:13:46 +08:00
}
}
2013-10-08 15:07:03 +08:00
return QVariant ( ) ;
}
2016-07-06 00:19:04 +08:00
# else
UString TreeModel : : data ( const UModelIndex & index , int role ) const
{
if ( ! index . isValid ( ) )
return UString ( ) ;
if ( role ! = 0 & & role ! = 0x0100 )
return UString ( ) ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
if ( role = = 0 )
return item - > data ( index . column ( ) ) ;
else
return item - > info ( ) ;
}
UString TreeModel : : headerData ( int section , int orientation ,
int role ) const
{
if ( orientation = = 1 & & role = = 0 ) {
switch ( section )
{
2017-12-11 09:56:00 +08:00
case 0 : return UString ( " Name " ) ;
case 1 : return UString ( " Action " ) ;
case 2 : return UString ( " Type " ) ;
case 3 : return UString ( " Subtype " ) ;
case 4 : return UString ( " Text " ) ;
2016-07-06 00:19:04 +08:00
}
}
return UString ( ) ;
}
# endif
int TreeModel : : columnCount ( const UModelIndex & parent ) const
{
if ( parent . isValid ( ) )
return static_cast < TreeItem * > ( parent . internalPointer ( ) ) - > columnCount ( ) ;
else
return rootItem - > columnCount ( ) ;
}
2013-10-08 15:07:03 +08:00
2016-06-26 11:54:21 +08:00
UModelIndex TreeModel : : index ( int row , int column , const UModelIndex & parent ) const
2013-10-08 15:07:03 +08:00
{
if ( ! hasIndex ( row , column , parent ) )
2016-06-26 11:54:21 +08:00
return UModelIndex ( ) ;
2013-10-08 15:07:03 +08:00
TreeItem * parentItem ;
if ( ! parent . isValid ( ) )
parentItem = rootItem ;
else
parentItem = static_cast < TreeItem * > ( parent . internalPointer ( ) ) ;
TreeItem * childItem = parentItem - > child ( row ) ;
if ( childItem )
return createIndex ( row , column , childItem ) ;
else
2016-06-26 11:54:21 +08:00
return UModelIndex ( ) ;
2013-10-08 15:07:03 +08:00
}
2016-06-26 11:54:21 +08:00
UModelIndex TreeModel : : parent ( const UModelIndex & index ) const
2013-10-08 15:07:03 +08:00
{
if ( ! index . isValid ( ) )
2016-06-26 11:54:21 +08:00
return UModelIndex ( ) ;
2013-10-08 15:07:03 +08:00
TreeItem * childItem = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
2013-11-15 18:48:14 +08:00
if ( childItem = = rootItem )
2016-06-26 11:54:21 +08:00
return UModelIndex ( ) ;
2013-12-29 23:13:46 +08:00
2013-10-08 15:07:03 +08:00
TreeItem * parentItem = childItem - > parent ( ) ;
if ( parentItem = = rootItem )
2016-06-26 11:54:21 +08:00
return UModelIndex ( ) ;
2013-10-08 15:07:03 +08:00
return createIndex ( parentItem - > row ( ) , 0 , parentItem ) ;
}
2016-06-26 11:54:21 +08:00
int TreeModel : : rowCount ( const UModelIndex & parent ) const
2013-10-08 15:07:03 +08:00
{
TreeItem * parentItem ;
if ( parent . column ( ) > 0 )
return 0 ;
if ( ! parent . isValid ( ) )
parentItem = rootItem ;
else
parentItem = static_cast < TreeItem * > ( parent . internalPointer ( ) ) ;
return parentItem - > childCount ( ) ;
}
2019-01-07 21:05:57 +08:00
UINT32 TreeModel : : base ( const UModelIndex & current ) const
{
// TODO: rewrite this as loop if we ever see an image that is too deep for this naive implementation
if ( ! current . isValid ( ) )
return 0 ;
UModelIndex parent = current . parent ( ) ;
if ( ! parent . isValid ( ) )
return offset ( current ) ;
else {
return offset ( current ) + base ( parent ) ;
}
}
2016-10-28 00:31:15 +08:00
UINT32 TreeModel : : offset ( const UModelIndex & index ) const
{
if ( ! index . isValid ( ) )
return 0 ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > offset ( ) ;
}
2016-06-26 11:54:21 +08:00
UINT8 TreeModel : : type ( const UModelIndex & index ) const
2013-12-29 23:13:46 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2013-12-29 23:13:46 +08:00
return 0 ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > type ( ) ;
}
2016-06-26 11:54:21 +08:00
UINT8 TreeModel : : subtype ( const UModelIndex & index ) const
2013-12-29 23:13:46 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2013-12-29 23:13:46 +08:00
return 0 ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
2015-02-06 16:47:19 +08:00
return item - > subtype ( ) ;
2013-12-29 23:13:46 +08:00
}
2017-10-12 13:59:23 +08:00
UINT8 TreeModel : : marking ( const UModelIndex & index ) const
{
if ( ! index . isValid ( ) )
return 0 ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > marking ( ) ;
}
2016-06-26 11:54:21 +08:00
UByteArray TreeModel : : header ( const UModelIndex & index ) const
2013-12-29 23:13:46 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2016-06-26 11:54:21 +08:00
return UByteArray ( ) ;
2013-12-29 23:13:46 +08:00
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > header ( ) ;
}
2016-06-26 11:54:21 +08:00
bool TreeModel : : hasEmptyHeader ( const UModelIndex & index ) const
2013-12-29 23:13:46 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2013-12-29 23:13:46 +08:00
return true ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > hasEmptyHeader ( ) ;
}
2016-06-26 11:54:21 +08:00
UByteArray TreeModel : : body ( const UModelIndex & index ) const
2013-12-29 23:13:46 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2016-06-26 11:54:21 +08:00
return UByteArray ( ) ;
2013-12-29 23:13:46 +08:00
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > body ( ) ;
}
2016-06-26 11:54:21 +08:00
bool TreeModel : : hasEmptyBody ( const UModelIndex & index ) const
2013-12-29 23:13:46 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2013-12-29 23:13:46 +08:00
return true ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > hasEmptyBody ( ) ;
}
2016-06-26 11:54:21 +08:00
UByteArray TreeModel : : tail ( const UModelIndex & index ) const
2016-04-21 04:41:18 +08:00
{
if ( ! index . isValid ( ) )
2016-06-26 11:54:21 +08:00
return UByteArray ( ) ;
2016-04-21 04:41:18 +08:00
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > tail ( ) ;
}
2016-06-26 11:54:21 +08:00
bool TreeModel : : hasEmptyTail ( const UModelIndex & index ) const
2016-04-21 04:41:18 +08:00
{
if ( ! index . isValid ( ) )
return true ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > hasEmptyTail ( ) ;
}
2016-06-26 11:54:21 +08:00
UString TreeModel : : name ( const UModelIndex & index ) const
2013-12-29 23:13:46 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2016-06-26 11:54:21 +08:00
return UString ( ) ;
2013-12-29 23:13:46 +08:00
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
2015-01-31 22:00:00 +08:00
return item - > name ( ) ;
2013-12-29 23:13:46 +08:00
}
2016-06-26 11:54:21 +08:00
UString TreeModel : : text ( const UModelIndex & index ) const
2013-12-29 23:13:46 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2016-06-26 11:54:21 +08:00
return UString ( ) ;
2013-12-29 23:13:46 +08:00
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
2015-01-31 22:00:00 +08:00
return item - > text ( ) ;
2013-12-29 23:13:46 +08:00
}
2016-06-26 11:54:21 +08:00
UString TreeModel : : info ( const UModelIndex & index ) const
2013-12-29 23:13:46 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2016-06-26 11:54:21 +08:00
return UString ( ) ;
2013-12-29 23:13:46 +08:00
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > info ( ) ;
}
2016-06-26 11:54:21 +08:00
UINT8 TreeModel : : action ( const UModelIndex & index ) const
2013-12-29 23:13:46 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2014-02-27 17:14:41 +08:00
return Actions : : NoAction ;
2013-12-29 23:13:46 +08:00
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > action ( ) ;
}
2016-06-26 11:54:21 +08:00
bool TreeModel : : fixed ( const UModelIndex & index ) const
2015-12-30 06:39:43 +08:00
{
if ( ! index . isValid ( ) )
return false ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > fixed ( ) ;
}
2016-06-26 11:54:21 +08:00
bool TreeModel : : compressed ( const UModelIndex & index ) const
2015-12-30 06:39:43 +08:00
{
if ( ! index . isValid ( ) )
return false ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > compressed ( ) ;
}
2016-06-26 11:54:21 +08:00
void TreeModel : : setFixed ( const UModelIndex & index , const bool fixed )
2015-12-30 06:39:43 +08:00
{
if ( ! index . isValid ( ) )
return ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
item - > setFixed ( fixed ) ;
if ( ! item - > parent ( ) )
return ;
if ( fixed ) {
2019-01-04 03:53:31 +08:00
// Special handling for uncompressed to compressed boundary
2015-12-30 06:39:43 +08:00
if ( item - > compressed ( ) & & item - > parent ( ) - > compressed ( ) = = FALSE ) {
item - > setFixed ( item - > parent ( ) - > fixed ( ) ) ;
return ;
}
2019-01-04 03:53:31 +08:00
// Propagate fixed flag until root
2019-01-07 21:05:57 +08:00
setFixed ( index . parent ( ) , true ) ;
2015-12-30 06:39:43 +08:00
}
emit dataChanged ( index , index ) ;
}
2016-06-26 11:54:21 +08:00
void TreeModel : : setCompressed ( const UModelIndex & index , const bool compressed )
2015-12-30 06:39:43 +08:00
{
if ( ! index . isValid ( ) )
return ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
item - > setCompressed ( compressed ) ;
emit dataChanged ( index , index ) ;
}
2021-10-07 23:51:39 +08:00
void TreeModel : : TreeModel : : setMarkingEnabled ( const bool enabled )
{
2017-12-11 09:56:00 +08:00
markingEnabledFlag = enabled ;
emit dataChanged ( UModelIndex ( ) , UModelIndex ( ) ) ;
2017-11-06 15:10:06 +08:00
}
2017-10-12 13:59:23 +08:00
void TreeModel : : setMarking ( const UModelIndex & index , const UINT8 marking )
{
if ( ! index . isValid ( ) )
return ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
item - > setMarking ( marking ) ;
emit dataChanged ( index , index ) ;
}
2016-10-28 00:31:15 +08:00
void TreeModel : : setOffset ( const UModelIndex & index , const UINT32 offset )
{
if ( ! index . isValid ( ) )
return ;
2015-12-30 06:39:43 +08:00
2016-10-28 00:31:15 +08:00
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
item - > setOffset ( offset ) ;
emit dataChanged ( index , index ) ;
}
void TreeModel : : setType ( const UModelIndex & index , const UINT8 data )
2014-01-11 17:20:58 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2014-01-11 17:20:58 +08:00
return ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
2016-10-28 00:31:15 +08:00
item - > setType ( data ) ;
2014-01-11 17:20:58 +08:00
emit dataChanged ( index , index ) ;
}
2016-10-28 00:31:15 +08:00
void TreeModel : : setSubtype ( const UModelIndex & index , const UINT8 subtype )
2013-10-08 15:07:03 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2013-12-29 23:13:46 +08:00
return ;
2013-10-08 15:07:03 +08:00
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
2016-10-28 00:31:15 +08:00
item - > setSubtype ( subtype ) ;
2013-10-08 15:07:03 +08:00
emit dataChanged ( index , index ) ;
}
2016-10-28 00:31:15 +08:00
void TreeModel : : setName ( const UModelIndex & index , const UString & data )
2013-12-29 23:13:46 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2013-12-29 23:13:46 +08:00
return ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
2016-10-28 00:31:15 +08:00
item - > setName ( data ) ;
2013-12-29 23:13:46 +08:00
emit dataChanged ( index , index ) ;
}
2016-06-26 11:54:21 +08:00
void TreeModel : : setText ( const UModelIndex & index , const UString & data )
2013-10-08 15:07:03 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2013-12-29 23:13:46 +08:00
return ;
2013-10-08 15:07:03 +08:00
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
item - > setText ( data ) ;
emit dataChanged ( index , index ) ;
}
2016-06-26 11:54:21 +08:00
void TreeModel : : setInfo ( const UModelIndex & index , const UString & data )
2015-03-13 14:48:53 +08:00
{
if ( ! index . isValid ( ) )
return ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
item - > setInfo ( data ) ;
emit dataChanged ( index , index ) ;
}
2016-06-26 11:54:21 +08:00
void TreeModel : : addInfo ( const UModelIndex & index , const UString & data , const bool append )
2015-03-13 14:48:53 +08:00
{
if ( ! index . isValid ( ) )
return ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
2016-07-05 23:22:03 +08:00
item - > addInfo ( data , append ) ;
2015-03-13 14:48:53 +08:00
emit dataChanged ( index , index ) ;
}
2016-06-26 11:54:21 +08:00
void TreeModel : : setAction ( const UModelIndex & index , const UINT8 action )
2013-12-29 23:13:46 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2015-02-06 16:47:19 +08:00
return ;
2013-12-29 23:13:46 +08:00
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
2015-02-06 16:47:19 +08:00
item - > setAction ( action ) ;
2015-12-30 06:39:43 +08:00
emit dataChanged ( index , index ) ;
2015-02-06 16:47:19 +08:00
}
2013-12-29 23:13:46 +08:00
2016-10-28 00:31:15 +08:00
UByteArray TreeModel : : parsingData ( const UModelIndex & index ) const
{
if ( ! index . isValid ( ) )
return UByteArray ( ) ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > parsingData ( ) ;
}
bool TreeModel : : hasEmptyParsingData ( const UModelIndex & index ) const
{
if ( ! index . isValid ( ) )
return true ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > hasEmptyParsingData ( ) ;
}
2016-06-26 11:54:21 +08:00
void TreeModel : : setParsingData ( const UModelIndex & index , const UByteArray & data )
2013-10-08 15:07:03 +08:00
{
2014-07-25 07:59:51 +08:00
if ( ! index . isValid ( ) )
2013-12-29 23:13:46 +08:00
return ;
2013-11-07 21:46:28 +08:00
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
2015-02-06 16:47:19 +08:00
item - > setParsingData ( data ) ;
2014-07-25 07:59:51 +08:00
emit dataChanged ( this - > index ( 0 , 0 ) , index ) ;
2013-11-18 23:23:59 +08:00
}
2022-08-25 04:17:51 +08:00
UByteArray TreeModel : : uncompressedData ( const UModelIndex & index ) const
{
if ( ! index . isValid ( ) )
return UByteArray ( ) ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > uncompressedData ( ) ;
}
bool TreeModel : : hasEmptyUncompressedData ( const UModelIndex & index ) const
{
if ( ! index . isValid ( ) )
return true ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
return item - > hasEmptyUncompressedData ( ) ;
}
void TreeModel : : setUncompressedData ( const UModelIndex & index , const UByteArray & data )
{
if ( ! index . isValid ( ) )
return ;
TreeItem * item = static_cast < TreeItem * > ( index . internalPointer ( ) ) ;
item - > setUncompressedData ( data ) ;
emit dataChanged ( this - > index ( 0 , 0 ) , index ) ;
}
2016-10-28 00:31:15 +08:00
UModelIndex TreeModel : : addItem ( const UINT32 offset , const UINT8 type , const UINT8 subtype ,
2016-06-26 11:54:21 +08:00
const UString & name , const UString & text , const UString & info ,
const UByteArray & header , const UByteArray & body , const UByteArray & tail ,
2016-10-28 00:31:15 +08:00
const ItemFixedState fixed ,
2016-06-26 11:54:21 +08:00
const UModelIndex & parent , const UINT8 mode )
2013-11-07 21:46:28 +08:00
{
2013-11-20 09:19:48 +08:00
TreeItem * item = 0 ;
TreeItem * parentItem = 0 ;
2013-10-15 23:19:15 +08:00
int parentColumn = 0 ;
2013-10-08 15:07:03 +08:00
2013-12-29 23:13:46 +08:00
if ( ! parent . isValid ( ) )
2013-10-15 23:19:15 +08:00
parentItem = rootItem ;
else
{
2013-12-12 19:28:39 +08:00
if ( mode = = CREATE_MODE_BEFORE | | mode = = CREATE_MODE_AFTER ) {
2013-12-29 23:13:46 +08:00
item = static_cast < TreeItem * > ( parent . internalPointer ( ) ) ;
2013-11-07 21:46:28 +08:00
parentItem = item - > parent ( ) ;
2013-12-29 23:13:46 +08:00
parentColumn = parent . parent ( ) . column ( ) ;
2013-11-07 21:46:28 +08:00
}
2013-11-14 18:40:39 +08:00
else {
2013-12-29 23:13:46 +08:00
parentItem = static_cast < TreeItem * > ( parent . internalPointer ( ) ) ;
parentColumn = parent . column ( ) ;
2013-11-14 18:40:39 +08:00
}
2013-10-15 23:19:15 +08:00
}
2013-12-29 23:13:46 +08:00
2016-10-28 00:31:15 +08:00
TreeItem * newItem = new TreeItem ( offset , type , subtype , name , text , info , header , body , tail , Movable , this - > compressed ( parent ) , parentItem ) ;
2015-12-30 06:39:43 +08:00
2013-12-12 19:28:39 +08:00
if ( mode = = CREATE_MODE_APPEND ) {
2013-11-07 21:46:28 +08:00
emit layoutAboutToBeChanged ( ) ;
parentItem - > appendChild ( newItem ) ;
}
2013-12-12 19:28:39 +08:00
else if ( mode = = CREATE_MODE_PREPEND ) {
2013-11-07 21:46:28 +08:00
emit layoutAboutToBeChanged ( ) ;
parentItem - > prependChild ( newItem ) ;
}
2013-12-12 19:28:39 +08:00
else if ( mode = = CREATE_MODE_BEFORE ) {
2013-11-07 21:46:28 +08:00
emit layoutAboutToBeChanged ( ) ;
parentItem - > insertChildBefore ( item , newItem ) ;
}
2013-12-12 19:28:39 +08:00
else if ( mode = = CREATE_MODE_AFTER ) {
2013-11-07 21:46:28 +08:00
emit layoutAboutToBeChanged ( ) ;
parentItem - > insertChildAfter ( item , newItem ) ;
}
2014-04-18 20:18:11 +08:00
else {
delete newItem ;
2016-06-26 11:54:21 +08:00
return UModelIndex ( ) ;
2014-04-18 20:18:11 +08:00
}
2013-12-29 23:13:46 +08:00
2013-10-15 23:19:15 +08:00
emit layoutChanged ( ) ;
2013-12-29 23:13:46 +08:00
2016-06-26 11:54:21 +08:00
UModelIndex created = createIndex ( newItem - > row ( ) , parentColumn , newItem ) ;
2017-01-14 08:24:56 +08:00
setFixed ( created , ( bool ) fixed ) ; // Non-trivial logic requires additional call
2015-12-30 06:39:43 +08:00
return created ;
2013-11-07 21:46:28 +08:00
}
2013-12-29 23:13:46 +08:00
2016-06-26 11:54:21 +08:00
UModelIndex TreeModel : : findParentOfType ( const UModelIndex & index , UINT8 type ) const
2013-12-29 23:13:46 +08:00
{
2017-10-12 13:59:23 +08:00
if ( ! index . isValid ( ) | | ! index . parent ( ) . isValid ( ) )
2016-06-26 11:54:21 +08:00
return UModelIndex ( ) ;
2013-12-29 23:13:46 +08:00
TreeItem * item ;
2017-10-12 13:59:23 +08:00
UModelIndex parent = index . parent ( ) ;
2013-12-29 23:13:46 +08:00
2014-07-25 07:59:51 +08:00
for ( item = static_cast < TreeItem * > ( parent . internalPointer ( ) ) ;
2013-12-29 23:13:46 +08:00
item ! = NULL & & item ! = rootItem & & item - > type ( ) ! = type ;
item = static_cast < TreeItem * > ( parent . internalPointer ( ) ) )
2016-04-21 04:41:18 +08:00
parent = parent . parent ( ) ;
2013-12-29 23:13:46 +08:00
if ( item ! = NULL & & item ! = rootItem )
return parent ;
2016-06-26 11:54:21 +08:00
return UModelIndex ( ) ;
2016-11-03 03:40:38 +08:00
}
2017-10-12 13:59:23 +08:00
UModelIndex TreeModel : : findLastParentOfType ( const UModelIndex & index , UINT8 type ) const
{
if ( ! index . isValid ( ) )
return UModelIndex ( ) ;
UModelIndex lastParentOfType = findParentOfType ( index , type ) ;
if ( ! lastParentOfType . isValid ( ) )
return UModelIndex ( ) ;
UModelIndex currentParentOfType = findParentOfType ( lastParentOfType , type ) ;
while ( currentParentOfType . isValid ( ) ) {
lastParentOfType = currentParentOfType ;
currentParentOfType = findParentOfType ( lastParentOfType , type ) ;
}
return lastParentOfType ;
}
2019-01-07 21:05:57 +08:00
UModelIndex TreeModel : : findByBase ( UINT32 base ) const
2016-11-03 03:40:38 +08:00
{
UModelIndex parentIndex = index ( 0 , 0 ) ;
goDeeper :
int n = rowCount ( parentIndex ) ;
for ( int i = 0 ; i < n ; i + + ) {
2021-04-04 17:09:23 +08:00
UModelIndex currentIndex = parentIndex . model ( ) - > index ( i , 0 , parentIndex ) ;
2019-01-07 21:05:57 +08:00
UINT32 currentBase = this - > base ( currentIndex ) ;
2021-04-04 17:09:23 +08:00
UINT32 fullSize = ( UINT32 ) ( header ( currentIndex ) . size ( ) + body ( currentIndex ) . size ( ) + tail ( currentIndex ) . size ( ) ) ;
2019-01-07 21:05:57 +08:00
if ( ( compressed ( currentIndex ) = = false | | ( compressed ( currentIndex ) = = true & & compressed ( currentIndex . parent ( ) ) = = false ) ) // Base is meaningful only for true uncompressed items
& & currentBase < = base & & base < currentBase + fullSize ) { // Base must be in range [currentBase, currentBase + fullSize)
2016-11-03 03:40:38 +08:00
// Found a better candidate
parentIndex = currentIndex ;
goto goDeeper ;
}
}
return ( parentIndex = = index ( 0 , 0 ) ? UModelIndex ( ) : parentIndex ) ;
2018-08-02 08:41:11 +08:00
}