Example #1
0
/*****************************************************************************
Collapses all levels of a branch -- not just 1 level.   Using this in
conjunction with TreeDataExpandOneLevel will get a tree grid that performs like
VC++ watch window.   Windows explorer tree differs:  it "remembers" last
expansion.

Note that it doesn't check whether adjacent nodes are properply represented, it
just does the collapse.

*****************************************************************************/
void CTreeColumn::TreeDataCollapseAllSubLevels( int aiGridRow)
{
    ASSERT( m_iColumnWithTree >= 0);
    ASSERT( m_pGrid != NULL);

    ASSERT( aiGridRow >= m_iFixedRowCount
            && aiGridRow < m_iRowCount);

    // display desired node and save its level and make visible
    CGridTreeCell* pGridTreeCell = (CGridTreeCell*)m_pGrid->GetCell( aiGridRow, m_iColumnWithTree);
    if( pGridTreeCell == NULL)
        return;

    unsigned char ucLevelCurrent = pGridTreeCell->GetLevel();
    if( ucLevelCurrent <= 0)
        return; // don't expand or collapse items not part of the tree
    pGridTreeCell->SetViewable( TRUE);

    unsigned char ucLevel;
    int i1;
    for( i1 = aiGridRow + 1; i1 < m_iRowCount; i1++)
    {
        CGridTreeCell* pGridTreeCell = (CGridTreeCell*)m_pGrid->GetCell( i1, m_iColumnWithTree);
        if( pGridTreeCell == NULL)
            return;

        ucLevel = pGridTreeCell->GetLevel();
        if( ucLevel <= ucLevelCurrent)
            break;

        pGridTreeCell->SetViewable( FALSE);

    }
}
CString CVariablesGrid::GetFullName( int row )
{
	// Get the full name.
	CString fullName = GetItemText( row, 0 );
	CGridTreeCell* treeCell = (CGridTreeCell*)GetCell( row, 0 );
	int curLevel = treeCell->GetLevel();
	if (curLevel > 1)
	{
		for (int i = row - 1; i >= 1; --i)
		{
			if (curLevel <= 1)
				break;
			CGridTreeCell* treeCell = (CGridTreeCell*)GetCell(i, 0);
			int level = treeCell->GetLevel();
			if (level == curLevel - 1)
			{
				// Found a new part to tack on.
				fullName = GetItemText(i, 0) + "." + fullName;
				curLevel--;
			}
		}
	}

	return fullName;
}
Example #3
0
/*****************************************************************************
Toggles tree expansion and collapsing.  Intended to be connected to a user
event

*****************************************************************************/
void CTreeColumn::TreeExpandCollapseToggle( int aiGridRow) // Grid row of node to toggle
{
    ASSERT( m_pGrid != NULL);
	m_pGrid->m_bLMouseButtonDown = FALSE;
    ASSERT( aiGridRow >= m_iFixedRowCount
            && aiGridRow < m_iRowCount);
    ASSERT( m_bAllowDraw);
    ASSERT( m_iColumnWithTree >= 0);
    if( m_iColumnWithTree < 0)
        return;

    // if last element, forget it
    if( aiGridRow + 1 >= m_iRowCount)
        return;

    // see if it needs to be expanded by looking at hide/show state of first neighbor.
    //  If first neighbor is hidden, should expand
    CGridTreeCell* pGridTreeCell = (CGridTreeCell*)m_pGrid->GetCell( aiGridRow + 1, m_iColumnWithTree);
    if( pGridTreeCell == NULL)
        return;

    if( pGridTreeCell->IsViewable() )
    {
        TreeDataCollapseAllSubLevels( aiGridRow);
		TreeRefreshRows();
    }
    else
    {
        TreeDataExpandOneLevel( aiGridRow);
		TreeRefreshRows();

		// Make sure bottom expanded row is visible (or as many of the expanded rows as possible)
		CGridTreeCell* pGridTreeCell = (CGridTreeCell*)m_pGrid->GetCell(aiGridRow, m_iColumnWithTree);
		if( pGridTreeCell == NULL)
			return;
		UCHAR lev = pGridTreeCell->GetLevel();
		int ii;
		for (ii = aiGridRow + 1; ii < m_iRowCount; ii++)
		{
			pGridTreeCell = (CGridTreeCell*)m_pGrid->GetCell(ii, m_iColumnWithTree);
			if (pGridTreeCell == NULL || pGridTreeCell->GetLevel() <= lev)
				break;
		}

		m_pGrid->EnsureVisible(ii-1, m_iColumnWithTree);
		m_pGrid->EnsureVisible(aiGridRow, m_iColumnWithTree);
    }
}
int CVariablesGrid::FindWatchActualIndex( int row )
{
	CString name = GetItemText( row, 0 );
	int actualIndex = -1;
	int lastCheckRow = row;
	if (!name.IsEmpty()  &&  row == GetRowCount() - 1)
	{
		actualIndex++;
		lastCheckRow--;
	}

	// Determine the true index.
	for (int i = 1; i <= lastCheckRow; ++i)
	{
		CGridTreeCell* treeCell = (CGridTreeCell*)GetCell(i, 0);
		if (treeCell->IsKindOf(RUNTIME_CLASS(CGridTreeCell)))
		{
			int level = treeCell->GetLevel();
			if (level == 1)
				actualIndex++;
		}
		else
			actualIndex++;
	}

	return actualIndex;
}
void CVariablesGrid::SaveExpandInfo(bool extraRow)
{
	m_expandInfo.RemoveAll();

	// Get the full name.
	CString fullName;

	int numRows = GetRowCount();
	if (extraRow)
		numRows--;
	for (int i = 1; i < numRows; ++i)
	{
		CGridTreeCell* treeCell = (CGridTreeCell*)GetCell(i, 0);
		int level = treeCell->GetLevel();
		if (level == 1)
		{
			fullName = GetItemText(i, 0);
		}
		else
		{
			fullName += "." + GetItemText(i, 0);
		}

		if (treeCell->IsViewable())
		{
			ExpandInfo info;
			info.m_fullName = fullName;
			m_expandInfo.Add(info);
		}
	}
}
void CVariablesGrid::FixupRows(bool readOnly)
{
	// Nothing here...
//	if (m_titleList.GetSize() == 0)
//		return;

	int numRows = GetRowCount();
	if (readOnly  &&  numRows == 1)
		return;

	GV_ITEM Item;

	m_treeColumn.TreeSetup( this, NAME_COL, readOnly ? numRows - 1 : numRows, 1, m_treeLevelArray.GetData(), TRUE, FALSE);
	m_treeColumn.SetTreeLineColor( RGB( 0, 0, 0xFF) );
//	m_treeColumn.SetDefTreeIndent( 8 );
//	m_treeColumn.TreeDisplayOutline(100);

	int curWatchIndex = -1;
	for (int i = 1; i < numRows; i++)
	{
		CGridTreeCell* treeCell = (CGridTreeCell*)GetCell(i, 0);
		treeCell->SetForcePlus( m_treeForcePlusArray[ i - 1 ] );
		int curLevel = treeCell->GetLevel();
		if (curLevel == 1)
		{
			curWatchIndex++;
		}

		Item.mask = GVIF_TEXT|GVIF_FORMAT|GVIF_FONT|GVIF_PARAM;
		Item.row = i;
		Item.col = NAME_COL;

		Item.mask = GVIF_TEXT|GVIF_FORMAT|GVIF_STATE;
		Item.nFormat = DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS;
		Item.nState = (readOnly || curLevel > 1) ? GVIS_READONLY : 0;
		m_titleFont.GetLogFont(&Item.lfFont);
		Item.lParam = curWatchIndex;

		SetItem(&Item);
	}

	for (int i = 1; i  <= m_titleList.GetSize(); ++i)
	{
//		SetFont(&m_titleFont);
		SetItemText(i, NAME_COL, m_titleList[i - 1]);
	}

//	for (i = 0; i < numRows; ++i)
//		m_treeColumn.TreeDataCollapseAllSubLevels(i);
}
Example #7
0
unsigned char CTreeColumn::GetTreeLevel(  int aiRow)  // row
// returns:  tree level, =0 if invalid input
{
    ASSERT( m_pGrid != NULL);
    ASSERT( aiRow >= 0
            && aiRow < m_iRowCount );
    ASSERT( m_iColumnWithTree >= 0);

    CGridTreeCell* pGridTreeCell = (CGridTreeCell*)m_pGrid->GetCell( aiRow, m_iColumnWithTree);
    if( pGridTreeCell != NULL)
        return pGridTreeCell->GetLevel();

    return 0;
}
Example #8
0
/*****************************************************************************
Callable by class consumer to prepare one's own data array of tree info to
display something reasonable.   High order Bits of the tree display data are
modified.

*****************************************************************************/
void CTreeColumn::TreeDataPrepOutline(unsigned char aucLevel, // level to display >= 0x80 displays all
                                    int aiIndex,            // Index to tree display data to modify
                                    int aiNbrElements)      // nbr of elements in tree display data
{
    ASSERT( aucLevel > 0);
    ASSERT( m_iColumnWithTree >= 0);
    ASSERT( aiIndex >= 0 );
    ASSERT( aiNbrElements > 0);
    ASSERT( m_pGrid != NULL);
    ASSERT( aiIndex + aiNbrElements <= m_iRowCount - m_iFixedRowCount );

    int i1;

    if( aucLevel >= 0x80)
    {
        for( i1=0; i1 < aiNbrElements; i1++)
        {
            int iCellRow = m_iFixedRowCount + aiIndex + i1;

            CGridTreeCell* pGridTreeCell = (CGridTreeCell*)m_pGrid->GetCell( iCellRow, m_iColumnWithTree);
            if( pGridTreeCell == NULL)
                return;

            pGridTreeCell->SetViewable( TRUE);
        }
    }
    else
    {
        for( i1=0; i1 < aiNbrElements; i1++)
        {
            int iCellRow = m_iFixedRowCount + aiIndex + i1;

            CGridTreeCell* pGridTreeCell = (CGridTreeCell*)m_pGrid->GetCell( iCellRow, m_iColumnWithTree);
            if( pGridTreeCell == NULL)
                return;

            if( pGridTreeCell->GetLevel() <= aucLevel)
                pGridTreeCell->SetViewable( TRUE);
            else
                pGridTreeCell->SetViewable( FALSE);
        }
    }
}
void CVariablesGrid::RestoreExpandInfo(bool extraRow)
{
	if (m_expandInfo.GetSize() == 0)
		return;

	// Get the full name.
	CString fullName;

	int curExpandPos = 0;
	int numRows = GetRowCount();
	if (extraRow)
		numRows--;
	for (int i = 1; i < numRows; ++i)
	{
		CGridTreeCell* treeCell = (CGridTreeCell*)GetCell(i, 0);
		int level = treeCell->GetLevel();
		if (level == 1)
		{
			fullName = GetItemText(i, 0);
		}
		else
		{
			fullName += "." + GetItemText(i, 0);
		}

		if (m_expandInfo[curExpandPos].m_fullName == fullName)
		{
//			m_treeColumn.TreeDataExpandOneLevel(i);
			treeCell->SetViewable(TRUE);
			curExpandPos++;
			if (curExpandPos == m_expandInfo.GetSize())
			{
				m_treeColumn.TreeRefreshRows();
				return;
			}
		}
	}

	m_treeColumn.TreeRefreshRows();
}
Example #10
0
/*****************************************************************************
Should the cell identified by the row have a "+" or "-" graphic?

*****************************************************************************/
BOOL CTreeColumn::TreeCellHasPlusMinus(   int aiRow,          // row of Cell to check
                                        BOOL* apbIsPlus,    // returns:  T=Is a plus
                                        BOOL* apbIsMinus,   // returns:  T=Is a minus
                                        BOOL* apbIsLastLeaf)// returns:  T=Is Last Leaf
// returns:  T=cell has a plus or minus;  F=not
{
    ASSERT( m_pGrid != NULL);
    ASSERT( aiRow >= m_iFixedRowCount
            && aiRow < m_iRowCount);
    ASSERT( m_iColumnWithTree >= 0);
    ASSERT( apbIsPlus != NULL);
    ASSERT( apbIsMinus != NULL);
    ASSERT( apbIsLastLeaf != NULL);

    *apbIsPlus = FALSE;
    *apbIsMinus = FALSE;
    *apbIsLastLeaf = FALSE;

    int iStartPt = aiRow + 1;
    int i1;

    // get current level
    CGridTreeCell* pGridTreeCell = (CGridTreeCell*)m_pGrid->GetCell( aiRow, m_iColumnWithTree);
    if( pGridTreeCell == NULL)
        return FALSE;
    unsigned char ucLevelCurrent = pGridTreeCell->GetLevel();
    if( ucLevelCurrent <= 0)
        return FALSE;     // no tree

    BOOL bIsNextShowing = FALSE;
    unsigned char ucLevelNext = 0;


    for( i1=iStartPt; i1 < m_iRowCount; i1++)
    {
        pGridTreeCell = (CGridTreeCell*)m_pGrid->GetCell( i1, m_iColumnWithTree);
        if( pGridTreeCell == NULL)
            return FALSE;

        bIsNextShowing = pGridTreeCell->IsViewable();
        ucLevelNext = pGridTreeCell->GetLevel();

        if( ucLevelCurrent >= ucLevelNext )
        {
            break;
        }

        if( !bIsNextShowing
            && ucLevelNext == ucLevelCurrent + 1)
        {
            *apbIsPlus = TRUE;
        }

    }

    // final attribute setting now that enough data has been examined
    if( i1 > iStartPt
        && !*apbIsPlus)
    {
        *apbIsMinus = TRUE;
    }

    if( !bIsNextShowing
        || ucLevelCurrent > ucLevelNext
        || i1 >= m_iRowCount )  // hit last element
        *apbIsLastLeaf = TRUE;

    return *apbIsMinus || *apbIsPlus;
}
Example #11
0
/*****************************************************************************
This may delete one or more rows depending on the makeup of the tree branch.
It's analagous to deleting a file directory with all files and sub-directories
deleted, too.

*****************************************************************************/
int CTreeColumn::DeleteTreeBranch( int aiRow,  // Row that the tree branch begins on
                                   BOOL abRedraw) // T=redraw; F=don't
// returns:  nbr of rows deleted
{
    ASSERT( aiRow >= -1);
    ASSERT( m_pGrid != NULL);       // Must call TreeSetup(), first

    if( aiRow < m_iFixedRowCount 
        || aiRow >= m_iRowCount)
        return 0;

    int iRowDeleteCount = 0;
    m_bAllowDraw = FALSE;   // prevents crash during reset

    // get level of initial row to delete from tree
    CGridTreeCell* pGridTreeCell = (CGridTreeCell*)m_pGrid->GetCell( aiRow, m_iColumnWithTree);
    unsigned char ucLevelCurrent = CHAR_MAX;
    
    if( pGridTreeCell != NULL)
    {
        // delete just the parent
        ucLevelCurrent = pGridTreeCell->GetLevel();
        if( m_pGrid->DeleteRow( aiRow) )
        {
            iRowDeleteCount++;
            m_iRowCount--;
        }
    }

    // see if any children need to be deleted, too
    unsigned char ucLevel;
    while( aiRow < m_iRowCount)
    {
        pGridTreeCell = (CGridTreeCell*)m_pGrid->GetCell( aiRow, m_iColumnWithTree);
        if( pGridTreeCell == NULL)
            break;

        ucLevel = pGridTreeCell->GetLevel();
        if( ucLevel <= ucLevelCurrent)
            break;

        if( !m_pGrid->DeleteRow( aiRow) )
            break;

        iRowDeleteCount++;
        m_iRowCount--;
    }
    ASSERT( m_iRowCount == m_pGrid->GetRowCount() );
    
    // have to re-number all cells below deletion point
    if( iRowDeleteCount > 0)
    {
        int iRow;
        int iColumnCount = m_pGrid->GetColumnCount();
        for( iRow=aiRow; iRow < m_iRowCount; iRow++)
        {
            int iCol;
            for (iCol = 0; iCol < iColumnCount; iCol++)
            {
                CGridCellBase* pGridCellBase = m_pGrid->GetCell( iRow, iCol);
                if( pGridCellBase != NULL)
                {
                    pGridCellBase->SetCoords( iRow, iCol);
                }
            }
        }
    }
    
    m_bAllowDraw = TRUE;
    TreeRefreshRows();
    if( abRedraw)
        m_pGrid->Invalidate();

    return iRowDeleteCount;
}