outline.cpp

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 730 行 · 第 1/2 页

CPP
730
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <whotspot.hpp>
#include <wkeydefs.hpp>
#include <wcvector.h>

#include "assure.h"
#include "browse.h"
#include "busyntc.h"
#include "dtview.h"
#include "gtbase.h"
#include "gtrootpk.h"
#include "hotspots.h"
#include "keysym.h"
#include "menuids.h"
#include "outline.h"
#include "symbol.h"
#include "screendv.h"
#include "viewmgr.h"
#include "querycfg.h"
#include "wbrwin.h"

// FIXME -- out of general paranoia, too many resets are being done

//-------------------------- OutlineElement ----------------------------------

static MemoryPool OutlineElement::_pool( sizeof( OutlineElement ),
                                         "OutlineElement", 100 );

OutlineElement::OutlineElement()
            : _sibling( NULL )
            , _child( NULL )
            , _state( ESLeaf )
            , _symbol( NULL )
            , _lastSib( FALSE )
            , _name( NULL )
//------------------------------
// create a sentinel node
{
}

OutlineElement::OutlineElement( int level, TreeNode * node, OutlineElement * next )
            : _sibling( next )
            , _child( NULL )
            , _symbol( node->makeSymbol() )
            , _lastSib( FALSE )
            , _level( (uint) level )
            , _name( NULL )
//---------------------------------------------------------------------------------
{
    int                 i;
    int                 numChildren;
    OutlineElement *    prevChild = next;
    OutlineElement *    lastChild = NULL;

    _name = new char[ strlen( node->name() ) + 1 ];
    strcpy( _name, node->name() );

    numChildren = node->getCount( TreeNode::ChildList );

    for( i = numChildren; i > 0; i -= 1 ) {
        _child = new OutlineElement( level + 1, node->getNode( TreeNode::ChildList, i - 1 ),
                                    prevChild );
        if( i == numChildren ) {
            lastChild = _child;
        }

        prevChild = _child;
    }

    if( lastChild ) {
        lastChild->_lastSib = TRUE;
        lastChild->_sibling = next;
    }

    if( numChildren > 0 ) {
        _state = ESCollapsed;
    } else {
        _state = ESLeaf;
    }
}

OutlineElement::~OutlineElement()
//-------------------------------
{
    delete _symbol;
    delete _child;
    delete [] _name;

    if( !_lastSib ) {
        delete _sibling;
    }
}

void OutlineElement::toggleExpand()
//---------------------------------
{
    if( _state == ESExpanded ) {
        collapse();
    } else {
        expand();
    }
}

void OutlineElement::expand( bool all )
//-------------------------------------
{
    OutlineElement * elm;

    if( _state != ESLeaf ) {
        _state = ESExpanded;

        if( all ) {
            for( elm = _child; elm != NULL; elm = elm->_sibling ) {
                elm->expand( all );
                if( elm->_lastSib ) {
                    break;
                }
            }
        }
    }
}

void OutlineElement::collapse( bool all )
//---------------------------------------
{
    OutlineElement * elm;

    if( _state != ESLeaf ) {
        _state = ESCollapsed;
        if( all ) {
            for( elm = _child; elm != NULL; elm = elm->_sibling ) {
                elm->collapse( all );
                if( elm->_lastSib ) {
                    break;
                }
            }
        }
    }
}

void OutlineElement::setEnable( bool en )
//---------------------------------------
{
    if( en ) {
        _state &= ~ESHidden;
    } else {
        _state |= ESHidden;
    }
}


void * OutlineElement::operator new( size_t )
//-------------------------------------------
{
    return _pool.alloc();
}

void OutlineElement::operator delete( void * ptr )
//------------------------------------------------
{
    _pool.free( ptr );
}

OutlineElement * OutlineElement::next() const
//-------------------------------------------
{
    OutlineElement * next = (state() == ESExpanded) ? _child : _sibling;

    while( next && !next->enabled() ) {
        if( next->state() == ESExpanded ) {
            next = next->_child;
        } else {
            next = next->_sibling;
        }
    }

    return next;
}

OutlineElement * OutlineElement::visibleSib()
//-------------------------------------------
{
    OutlineElement * sib;

    for( sib = _sibling; sib && !sib->enabled(); sib = sib->_sibling );

    return sib;
}

const char * OutlineElement::string() const
//-----------------------------------------
{
    return NULL;
}

void OutlineElement::drawLine( WWindow * win, int & idx,
                                int width, int height )
//----------------------------------------------------------------
{
    OutlineElement * elm;
    WPoint           start( width * _level + width / 2, height * (idx + 1) );
    WPoint           end( start );
    WOrdinal         maxY = height * win->getRows();

    idx += 1;

    if( _state == ESExpanded ) {

        for( elm = _child; elm != NULL && idx < win->getRows() + 1;
            elm = elm->visibleSib() ) {

            end = WPoint( width * elm->_level,
                          height * idx + height / 2 );

            if( end.y() < maxY ) {
                win->drawLine( WPoint( start.x(), end.y() ), end, ColorBlack );
                elm->drawLine( win, idx, width, height );
            }

            if( elm->_lastSib ) {
                break;
            }
        }

        end.x( start.x() );
        end.y( minInt( end.y(), maxY ) );

        if( start.y() < maxY ) {
            win->drawLine( start, end, ColorBlack );
        }
    }
}


//------------------------------ Outline -------------------------------------

Outline::Outline( const char * text )
        : HotWindowList( text )
        , GlobalViewTree( menuManager() )
        , _findStack( NULL )
//----------------------------------------------------------------
{
    _sentinel = new OutlineElement;
    _queryConfig = new QueryConfig( this, "Find" );
    _findFilter = new KeySymbol;
    _loadFilter = new KeySymbol( WBRWinBase::optManager()->getQueryFilt() );

    onHotPress( this, (cbw) &Outline::toggleExpand );
    onDblClick( this, (cbw) &Outline::detailView );
    onChanged( this, (cbw) &Outline::changed );

    menuManager()->trackPopup( this, MMTree );
    viewManager()->registerForEvents( this );

    resetCache();
}

Outline::~Outline()
//-----------------
{
    delete _sentinel;       // deletes all children too
    delete _queryConfig;
    delete _loadFilter;
    delete _findFilter;
}

void Outline::resetOutline()
//--------------------------
// reset to initial state
{
    delete _sentinel;       // kill all elements
    _sentinel = new OutlineElement;
    resetCache();
    if( _findStack ) {
        _findStack->clear();
    }
}

bool Outline::paint()
//-------------------
{
    OutlineElement * elm;
    int              maxRows = getRows();
    int              index = -1 * _topIndex;
    WPoint           hotSize;
    WPoint           avg;
    WPoint           max;

    textMetrics( avg, max );

    if( count() ) {
        GlobalHotSpots->hotSpotSize( OutlineLeafUp, hotSize );  // rely on all being same size

        for( elm = element( 0 ); elm != NULL; elm = elm->visibleSib() ) {
            elm->drawLine( this, index, hotSize.x(), max.y() );

            if( index >= maxRows ) {
                break;
            }
        }

        return HotWindowList::paint();
    } else {
        ScreenDev dev;

        dev.open( this );
        dev.drawText( WPoint( 0, 0 ), emptyText() );
        dev.close();

        return TRUE;
    }
}

void Outline::resetCache()
//------------------------
{
    _cacheElement = _sentinel;
    _cacheIndex = -1;
}

int Outline::count()
//------------------
{
    OutlineElement * elm;
    int              num = 0;

    for( elm = _sentinel->next(); elm != NULL; elm = elm->next() ) {
        num += 1;
    }

    return num;
}

const char * Outline::getString( int index )

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?