var_tree.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:10k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * var_tree.cpp
  3.  *****************************************************************************
  4.  * Copyright (C) 2005 the VideoLAN team
  5.  * $Id: a7454e5847514b80de34051248d59f022b358526 $
  6.  *
  7.  * Authors: Antoine Cellerier <dionoea@videolan.org>
  8.  *          Clément Stenac <zorglub@videolan.org>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. #include "var_tree.hpp"
  25. const string VarTree::m_type = "tree";
  26. VarTree::VarTree( intf_thread_t *pIntf )
  27.     : Variable( pIntf ), m_id( 0 ), m_selected( false ), m_playing( false ),
  28.     m_expanded( false ), m_deleted( false ),
  29.     m_pData( NULL ), m_pParent( NULL ), m_readonly( false )
  30. {
  31.     // Create the position variable
  32.     m_cPosition = VariablePtr( new VarPercent( pIntf ) );
  33.     getPositionVar().set( 1.0 );
  34. }
  35. VarTree::VarTree( intf_thread_t *pIntf, VarTree *pParent, int id,
  36.                   const UStringPtr &rcString, bool selected, bool playing,
  37.                   bool expanded, bool readonly,
  38.                   void *pData )
  39.     : Variable( pIntf ), m_id( id ), m_cString( rcString ),
  40.     m_selected( selected ), m_playing( playing ), m_expanded( expanded ),
  41.     m_deleted( false ), m_pData( pData ), m_pParent( pParent ),
  42.     m_readonly( readonly )
  43. {
  44.     // Create the position variable
  45.     m_cPosition = VariablePtr( new VarPercent( pIntf ) );
  46.     getPositionVar().set( 1.0 );
  47. }
  48. VarTree::~VarTree()
  49. {
  50. /// todo check that children are deleted
  51. }
  52. void VarTree::add( int id, const UStringPtr &rcString, bool selected,
  53.                    bool playing, bool expanded, bool readonly,
  54.                    void *pData )
  55. {
  56.     m_children.push_back( VarTree( getIntf(), this, id, rcString, selected,
  57.                                    playing, expanded, readonly,
  58.                                    pData ) );
  59. }
  60. void VarTree::delSelected()
  61. {
  62.     Iterator it = begin();
  63.     while( it != end() )
  64.     {
  65.         //dig down the tree
  66.         if( size() ) it->delSelected();
  67.         //stay on some level
  68.         if( it->m_selected )
  69.         {
  70.             Iterator oldIt = it;
  71.             it++;
  72.             m_children.erase( oldIt );
  73.         }
  74.         else
  75.         {
  76.             it++;
  77.         }
  78.     }
  79. }
  80. void VarTree::clear()
  81. {
  82.     m_children.clear();
  83. }
  84. VarTree::Iterator VarTree::operator[]( int n )
  85. {
  86.     Iterator it;
  87.     int i;
  88.     for( it = begin(), i = 0;
  89.          i < n && it != end();
  90.          it++, i++ );
  91.     return it;
  92. }
  93. VarTree::ConstIterator VarTree::operator[]( int n ) const
  94. {
  95.     ConstIterator it;
  96.     int i;
  97.     for( it = begin(), i = 0;
  98.          i < n && it != end();
  99.          it++, i++ );
  100.     return it;
  101. }
  102. VarTree::Iterator VarTree::getNextSibling( VarTree::Iterator current )
  103. {
  104.     VarTree *p_parent = current->parent();
  105.     if( p_parent  && current != p_parent->end() )
  106.     {
  107.         Iterator it = current->parent()->begin();
  108.         while( it != p_parent->end() && it != current ) it++;
  109.         if( it != p_parent->end() )
  110.         {
  111.             it++;
  112.         }
  113.         return root()->end();
  114.     }
  115.     return root()->end();
  116. }
  117. /* find iterator to next ancestor
  118.  * ... which means parent++ or grandparent++ or grandgrandparent++ ... */
  119. VarTree::Iterator VarTree::next_uncle()
  120. {
  121.     VarTree *p_parent = parent();
  122.     if( p_parent != NULL )
  123.     {
  124.         VarTree *p_grandparent = p_parent->parent();
  125.         while( p_grandparent != NULL )
  126.         {
  127.             Iterator it = p_grandparent->begin();
  128.             while( it != p_grandparent->end() && &(*it) != p_parent ) it++;
  129.             if( it != p_grandparent->end() )
  130.             {
  131.                 it++;
  132.                 if( it != p_grandparent->end() )
  133.                 {
  134.                     return it;
  135.                 }
  136.             }
  137.             if( p_grandparent->parent() )
  138.             {
  139.                 p_parent = p_grandparent;
  140.                 p_grandparent = p_parent->parent();
  141.             }
  142.             else
  143.                 p_grandparent = NULL;
  144.         }
  145.     }
  146.     /* if we didn't return before, it means that we've reached the end */
  147.     return root()->end();
  148. }
  149. VarTree::Iterator VarTree::prev_uncle()
  150. {
  151.     VarTree *p_parent = parent();
  152.     if( p_parent != NULL )
  153.     {
  154.         VarTree *p_grandparent = p_parent->parent();
  155.         while( p_grandparent != NULL )
  156.         {
  157.             Iterator it = p_grandparent->end();
  158.             while( it != p_grandparent->begin() && &(*it) != p_parent ) it--;
  159.             if( it != p_grandparent->begin() )
  160.             {
  161.                 it--;
  162.                 if( it != p_grandparent->begin() )
  163.                 {
  164.                     return it;
  165.                 }
  166.             }
  167.             if( p_grandparent->parent() )
  168.             {
  169.                 p_parent = p_grandparent;
  170.                 p_grandparent = p_parent->parent();
  171.             }
  172.             else
  173.                 p_grandparent = NULL;
  174.         }
  175.     }
  176.     /* if we didn't return before, it means that we've reached the end */
  177.     return root()->begin();
  178. }
  179. void VarTree::checkParents( VarTree *pParent )
  180. {
  181.     m_pParent = pParent;
  182.     Iterator it = begin();
  183.     while( it != end() )
  184.     {
  185.         it->checkParents( this );
  186.         it++;
  187.     }
  188. }
  189. int VarTree::visibleItems()
  190. {
  191.     int i_count = size();
  192.     Iterator it = begin();
  193.     while( it != end() )
  194.     {
  195.         if( it->m_expanded )
  196.         {
  197.             i_count += it->visibleItems();
  198.         }
  199.         it++;
  200.     }
  201.     return i_count;
  202. }
  203. VarTree::Iterator VarTree::getVisibleItem( int n )
  204. {
  205.     Iterator it = begin();
  206.     while( it != end() )
  207.     {
  208.         n--;
  209.         if( n <= 0 )
  210.             return it;
  211.         if( it->m_expanded )
  212.         {
  213.             int i;
  214.             i = n - it->visibleItems();
  215.             if( i <= 0 ) return it->getVisibleItem( n );
  216.             n = i;
  217.         }
  218.         it++;
  219.     }
  220.     return end();
  221. }
  222. VarTree::Iterator VarTree::getLeaf( int n )
  223. {
  224.     Iterator it = begin();
  225.     while( it != end() )
  226.     {
  227.         if( it->size() )
  228.         {
  229.             int i;
  230.             i = n - it->countLeafs();
  231.             if( i <= 0 ) return it->getLeaf( n );
  232.             n = i;
  233.         }
  234.         else
  235.         {
  236.             n--;
  237.             if( n <= 0 )
  238.                 return it;
  239.         }
  240.         it++;
  241.     }
  242.     return end();
  243. }
  244. VarTree::Iterator VarTree::getNextVisibleItem( Iterator it )
  245. {
  246.     if( it->m_expanded && it->size() )
  247.     {
  248.         it = it->begin();
  249.     }
  250.     else
  251.     {
  252.         VarTree::Iterator it_old = it;
  253.         it++;
  254.         // Was 'it' the last brother? If so, look for uncles
  255.         if( it_old->parent() && it_old->parent()->end() == it )
  256.         {
  257.             it = it_old->next_uncle();
  258.         }
  259.     }
  260.     return it;
  261. }
  262. VarTree::Iterator VarTree::getPrevVisibleItem( Iterator it )
  263. {
  264.     VarTree::Iterator it_old = it;
  265.     if( it == root()->begin() || it == ++(root()->begin()) ) return it;
  266.     /* Was it the first child of its parent ? */
  267.     if( it->parent() && it == it->parent()->begin() )
  268.     {
  269.         /* Yes, get previous uncle */
  270.         it = it_old->prev_uncle();
  271.     }
  272.     else
  273.         it--;
  274.     /* We have found an expanded uncle, take its last child */
  275.     while( it != root()->begin() && it->size() && it->m_expanded )
  276.     {
  277.             it = it->end();
  278.             it--;
  279.     }
  280.     return it;
  281. }
  282. VarTree::Iterator VarTree::getNextItem( Iterator it )
  283. {
  284.     if( it->size() )
  285.     {
  286.         it = it->begin();
  287.     }
  288.     else
  289.     {
  290.         VarTree::Iterator it_old = it;
  291.         it++;
  292.         // Was 'it' the last brother? If so, look for uncles
  293.         if( it_old->parent() && it_old->parent()->end() == it )
  294.         {
  295.             it = it_old->next_uncle();
  296.         }
  297.     }
  298.     return it;
  299. }
  300. VarTree::Iterator VarTree::getPrevItem( Iterator it )
  301. {
  302.     VarTree::Iterator it_old = it;
  303.     if( it == root()->begin() || it == ++(root()->begin()) ) return it;
  304.     /* Was it the first child of its parent ? */
  305.     if( it->parent() && it == it->parent()->begin() )
  306.     {
  307.         /* Yes, get previous uncle */
  308.         it = it_old->prev_uncle();
  309.     }
  310.     else
  311.         it--;
  312.     /* We have found an expanded uncle, take its last child */
  313.     while( it != root()->begin() && it->size() )
  314.     {
  315.             it = it->end();
  316.             it--;
  317.     }
  318.     return it;
  319. }
  320. VarTree::Iterator VarTree::getNextLeaf( Iterator it )
  321. {
  322.     do
  323.     {
  324.         it = getNextItem( it );
  325.     }
  326.     while( it != root()->end() && it->size() );
  327.     return it;
  328. }
  329. VarTree::Iterator VarTree::getPrevLeaf( Iterator it )
  330. {
  331.     do
  332.     {
  333.         it = getPrevItem( it );
  334.     }
  335.     while( it != root()->begin() && it->size() ); /* FIXME ? */
  336.     if( it == root()->begin() ) it = firstLeaf();
  337.     return it;
  338. }
  339. VarTree::Iterator VarTree::findById( int id )
  340. {
  341.     for (Iterator it = begin(); it != end(); ++it )
  342.     {
  343.         if( it->m_id == id )
  344.         {
  345.             return it;
  346.         }
  347.         Iterator result = it->findById( id );
  348.         if( result != it->end() ) return result;
  349.     }
  350.     return end();
  351. }
  352. void VarTree::ensureExpanded( VarTree::Iterator it )
  353. {
  354.     /// Don't expand ourselves, only our parents
  355.     VarTree *current = &(*it);
  356.     current = current->parent();
  357.     while( current->parent() != NULL )
  358.     {
  359.         current->m_expanded = true;
  360.         current = current->parent();
  361.     }
  362. }
  363. int VarTree::countLeafs()
  364. {
  365.     if( size() == 0 ) return 1;
  366.     int i_count = 0;
  367.     Iterator it = begin();
  368.     while( it != end() )
  369.     {
  370.         i_count += it->countLeafs();
  371.         it++;
  372.     }
  373.     return i_count;
  374. }
  375. VarTree::Iterator VarTree::firstLeaf()
  376. {
  377.     Iterator b = root()->begin();
  378.     if( b->size() ) return getNextLeaf( b );
  379.     return b;
  380. }