help.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,490 行 · 第 1/3 页

C
1,490
字号
    if( *field == tabFilter.curr ) {
        tabFilter.curr = NULL;
    }
    if( changecurr && count < helpStack->cur ) {
        helpStack->cur -= 1;
    }
    next = (*field)->next;
    HelpMemFree( *field );
    *field = next;
    tabFilter.first = helpTab;
}

static void display_fields( void )
{
    a_field             *p;

    for( p = helpTab; p != NULL; p = p->next ) {
        uivattribute( &helpScreen, p->area, AT( ATTR_EDIT ) );
    }
}

static void free_fields( a_field **ht )
{
    while( *ht != NULL ) {
        del_field( *ht, ht, FALSE );
    }
}

static a_field *field_find( a_field *table, int count )
{
    for( ; count > 0  &&  table != NULL; --count, table = table->next )
        ;

    return( table );
}

static void vscroll_fields( a_field **ht, SAREA use, int incr )
{
    a_field             **p;
    a_field             **next;

    if( incr == 0 ) return;
    for( p=ht; *p && (*p)->area.row < use.row+use.height ; p = next ) {
        next = &((*p)->next);
        if( (*p)->area.row >= use.row ) {
            if((incr > 0  &&  (*p)->area.row < use.row + incr )
            || (incr < 0  &&  (*p)->area.row - incr >= use.row + use.height) ) {
                next = p;
                del_field( *ht, p, TRUE );
            } else {
                (*p)->area.row -= incr;
            }
        }
    }
}

a_tab_field *help_next_field( a_field *fld, a_field *table )
{
    _unused( table );
    if( fld != NULL ) {
        fld = fld->next;
    }
    return( fld );
}

static void nexttopic( char *word )
{
    a_hstackent         *h;
    unsigned            len;

    len = strlen( word );
    if( word == NULL ) {
        h = HelpMemAlloc( sizeof( a_hstackent ) + 1 );
    } else {
        h = HelpMemAlloc( sizeof( a_hstackent ) + strlen( word ) );
    }
    if( helpStack != NULL ) {
        helpStack->cur = field_count( helpTab, helpCur );
        helpStack->line = currLine;
    }
    h->next = helpStack;
    h->type = HSTCK_NAME;
    h->cur = 0;
    h->line = 0;
    strcpy( h->helpfname, curFile );
    if( word != NULL ) {
        strcpy( h->word, word );
        h->word[strlen( word )] = '\0';
    } else {
        h->word[0] = '\0';
    }
    helpStack = h;
    free_fields( &helpTab );
}

static void prevtopic( void )
{
    a_hstackent         *h;

    if( helpStack->next != NULL ) {
        h = helpStack;
        helpStack = helpStack->next;
        HelpMemFree( h );
    }
    free_fields( &helpTab );
}

static void replacetopic( char *word )
{
    if( helpStack->next == NULL ) {
        HelpMemFree( helpStack );
        helpStack = NULL;
    } else {
        prevtopic();
    }
    nexttopic( word );
}

void Free_Stack( void )
{
    while( helpStack->next != NULL ) {
        prevtopic();
    }
    HelpMemFree( helpStack );
}

unsigned help_in_tab( a_field *fld, void *dummy )
{
    _unused( fld );
    _unused( dummy );
    return( TRUE );
}

static EVENT hlpwait( VTAB *tab )
{
    int                 done;
    static EVENT        bumpev = EV_NO_EVENT;
    char                *next_name;
    unsigned            len1;
    unsigned            len2;

    helpCur = field_find( helpTab, helpStack->cur );
    if( helpTab != NULL  &&  helpCur == NULL ) {
        helpCur = helpTab;
    }
    tab->other = helpCur;
    tab->curr = helpCur;
    if( helpCur != NULL ) {
        tab->home = helpCur->area.col;
    }
    uipushlist( helpEventList );
    if( bumpev != EV_NO_EVENT ) {
        uitabfilter( bumpev, tab );
        helpCur = tab->curr;
        bumpev = EV_NO_EVENT;
    }
    done = FALSE;
    while( !done ) {
        if( helpTab != NULL ) {
            uivattribute( &helpScreen, helpCur->area, AT( ATTR_CURR_EDIT ) );
        }
        do {
            uipushlist( keyShift );
            curEvent = uivget( &helpScreen );
            if( curEvent == EV_MOUSE_PRESS ) {
                ignoreMouseRelease = FALSE;
            }
            uipoplist();
            curEvent = uigadgetfilter( curEvent, &vGadget );
            curEvent = uitabfilter( curEvent, tab );
        } while( curEvent == EV_NO_EVENT );
        if( eventMapFn != NULL ) {
            curEvent = (*eventMapFn)( curEvent );
        }
        curEvent = uihotspotfilter( &helpScreen, hotSpotFields, curEvent );
        if( helpTab != NULL ) {
            uivattribute( &helpScreen, helpCur->area, AT( ATTR_EDIT ) );
        }
        switch( curEvent ) {
        case EV_HELP:
            nexttopic( helpWord );
            done = TRUE;
            break;
        case EV_BOTTOM:
        case E_UP:
        case EV_PAGE_UP:
        case EV_PAGE_DOWN:
        case EV_CURSOR_UP:
        case EV_CURSOR_DOWN:
        case EV_TOP:
        case E_DOWN:
        case EV_SCROLL_VERTICAL:
            if( curEvent == EV_BOTTOM ) {
                bumpev = EV_CURSOR_DOWN;
            } else if( curEvent == EV_TOP ) {
                bumpev = EV_CURSOR_UP;
            }
            helpStack->cur = field_count( helpTab, helpCur );
            done = TRUE;
            break;
        case '-':
        case EV_MOUSE_RELEASE_R:
        case EV_ALT_B:
        case 'b':
        case 'B':
        case EV_FUNC(8):
        case EV_FUNC(4):
            prevtopic();
            if( strcmp( helpStack->helpfname, curFile ) ) {
                len1 = strlen( helpStack->word );
                len2 = strlen( helpStack->helpfname );
                helpCur = HelpMemAlloc( sizeof( a_field ) + len1 + len2 );
                memcpy( helpCur->keyword, helpStack->word, len1 );
                memcpy( helpCur->keyword + len1, helpStack->helpfname, len2 );
                helpCur->keyword[ len1 + len2 ] = '\0';
                helpCur->key1_len = len1;
                helpCur->key2_len = len2;
                helpCur->next = NULL;
//              prevtopic();
                helpTab = helpCur;
            }
            done = TRUE;
            break;
        case EV_ALT_S:
        case 'S':
        case 's':
            if( helpSearchHdl != NULL ) {
                uipoplist();
                next_name = HelpSearch( helpSearchHdl );
                if( next_name != NULL ) {
                    nexttopic( next_name );
                    HelpMemFree( next_name );
                    done = 1;
                }
                uipushlist( helpEventList );
            }
            break;
        case EV_FIELD_CHANGE:
            helpCur = tab->curr;
            break;
        case EV_MOUSE_RELEASE:
            if( tab->other == NULL ) break;
            if( ignoreMouseRelease ) {
                /* this mouse release is for a mouse press that occured
                 * before this help topic was opened */
                 ignoreMouseRelease = FALSE;
                 break;
            }
            tab->other = tab->curr;
            /* fall through */
        case EV_ENTER:  /*same as page-down if there are other topics*/
        case EV_FUNC(7):
        case '+':
            // DEN 90/04/12 - next line necessary for mouse release kludge
            helpCur = tab->curr;
            if( helpTab != NULL ) {
                if( helpCur->key2_len == 0 ) {
                    nexttopic( helpCur->keyword );
                }
                done = TRUE;
            }
            break;
        case EV_KILL_UI:
            uiforceevadd( EV_KILL_UI );
            /* fall through */
        case EV_ESCAPE:
            done = TRUE;
            break;
        }
    }
    uipoplist();
    return( curEvent );
}

static int getline( void )
{
    int                 l;

    if( helpGetString( helpInBuf, BUF_LEN, helpFileHdl ) == NULL ) {
        return( FALSE );
    }
    l = strlen( helpInBuf );
    if( l >= RSEP_LEN ) {
        helpInBuf[l - RSEP_LEN] = '\0'; /* ignore record sep */
    }
    return( TRUE );
}

static void clearline( void )
{
    helpInBuf[0] = '\0';
    helpOutBuf[0] = '\0';
}

static void scanCallBack( TokenType type, void *info, ScanInfo *myinfo )
{
    TextInfo            *text;
    HyperLinkInfo       *link;
    TextInfoBlock       *block;
    bool                goofy;
    unsigned            cnt;
    a_field             *ht;

    goofy = TRUE;
    switch( type ) {
    case TK_TEXT:
        text = info;
        switch( text->type ) {
        case TT_LEFT_ARROW:
            myinfo->buf[0] = REAL_LEFT_ARROW;
            myinfo->buf++;
            myinfo->pos++;
            break;
        case TT_RIGHT_ARROW:
            myinfo->buf[0] = REAL_RIGHT_ARROW;
            myinfo->buf++;
            myinfo->pos++;
            break;
        case TT_END_OF_LINE:
            myinfo->buf[0] = '\0';
            myinfo->buf++;
            myinfo->pos++;
            break;
        case TT_CTRL_SEQ:
            memcpy( myinfo->buf, text->str, text->len );
            myinfo->buf += text->len;
            break;
        case TT_ESC_SEQ:
            memcpy( myinfo->buf, text->str, text->len );
            myinfo->buf += text->len;
            myinfo->pos += 1;
            break;
        default:
            memcpy( myinfo->buf, text->str, text->len );
            myinfo->buf += text->len;
            myinfo->pos += text->len;
            break;
        }
        break;
    case TK_PLAIN_LINK:
            myinfo->buf[0] = '<';
            myinfo->buf ++;
            myinfo->pos ++;
            goofy = FALSE;
            /* fall through */
    case TK_GOOFY_LINK:
        link = info;
        block = &( link->block1 );
        cnt = 0;
        ht = HelpMemAlloc( sizeof( a_field ) + link->topic_len
                           + link->hfname_len );
        ht->area.width = 0;
        ht->area.row = myinfo->line;
        ht->area.height = 1;
        ht->area.col = myinfo->pos;
        memcpy( ht->keyword, link->topic, link->topic_len );
        if( link->hfname_len != 0 ) {
            memcpy( ht->keyword + link->topic_len, link->hfname,
                    link->hfname_len );
            ht->keyword[ link->topic_len + link->hfname_len ] = '\0';
        } else {
            ht->keyword[ link->topic_len ] = '\0';
        }
        ht->key1_len = link->topic_len;
        ht->key2_len = link->hfname_len;
        while( block != NULL ) {
            while( cnt < block->cnt ) {
                text = &( block->info[cnt] );
                switch( text->type ) {
                case TT_ESC_SEQ:
                    memcpy( myinfo->buf, text->str, text->len );
                    myinfo->buf += text->len;
                    myinfo->pos ++;
                    ht->area.width ++;
                    break;
                case TT_PLAIN:
                    memcpy( myinfo->buf, text->str, text->len );
                    myinfo->buf += text->len;
                    myinfo->pos += text->len;
                    ht->area.width += text->len;
                    break;
                }
                cnt++;
            }
            block = block->next;
            cnt = 0;
        }
        if( ht->area.col + ht->area.width > helpScreen.area.width ) {
            ht->area.width = helpScreen.area.width - ht->area.col;
        }
        add_field( ht, myinfo->changecurr );
        if( !goofy ) {
            myinfo->buf[0] = '>';
            myinfo->buf ++;
            myinfo->pos ++;
        }
        break;
    }
}

/*
 * processLine
 */
static int processLine( char *bufin, char *bufout, int line, bool changecurr )
{
    ScanInfo    info;

    info.buf = bufout;
    info.line = line;
    info.changecurr = changecurr;
    info.pos = 0;
    ScanLine( bufin, scanCallBack, &info );
    return( TRUE );
}

/*
 * helpSet - set the help window title bar and its size
 *         - assumes helpInbuf contains the topic line for this topic
 */
static void helpSet( char *str, char *helpname, unsigned buflen )
{
    int         nums[5];
    int         i;
    char        *srcptr;
    char        *dstptr;

    helpScreen.name = NULL;
    helpLines = 0;
    if( str != NULL ) {
        strcpy( helpname, str );
        srcptr = str;
        dstptr = helpname;
        while( *srcptr != '\0' ) {
            if( *srcptr == HELP_ESCAPE ) srcptr ++;
            *dstptr = *srcptr;
            srcptr++;
            dstptr++;
            buflen--;
            if( buflen == 0 ) {
                dstptr --;
                *dstptr = '\0';
                break;
            }
        }
        *dstptr = '\0';
        helpScreen.name = helpname;
        scanTopic( helpInBuf, &str );
        str++;
        str = strtok( str, " " );
    }
    for( i = 0; i < 5; ++i ) {
        nums[i] = 0;
        if( str != NULL ) {
            nums[i] = atoi( str );
            str = strtok( NULL, " " );
        }
    }
    helpScreen.area.height = (nums[0] == 0) ? UIData->height - 3 : nums[0] + 3;
    helpScreen.area.width = (nums[1] == 0) ? UIData->width - 2 : nums[1];
    helpLines = nums[4];
    if( helpScreen.area.height > UIData->height - 2 ) {
        helpScreen.area.height = UIData->height - 2;
    }
    if( helpScreen.area.width > UIData->width - 2 ) {
        helpScreen.area.width = UIData->width - 2;
    } else if( helpScreen.area.width < HELP_MIN_WIDTH ) {
        helpScreen.area.width = HELP_MIN_WIDTH;
    }
    if( strlen( helpScreen.name ) > helpScreen.area.width ) {
        helpScreen.name[ helpScreen.area.width ] = '\0';
    }
    hlp_ut_position( &helpScreen.area, helpScreen.area.height, helpScreen.area.width,
                     nums[2], nums[3], TRUE );
}


static void putline( char *buffer, int line )
{
    int                 i;
    int                 start;

    helpScreen.col = 0;
    i = 0;
    while( buffer[i] && helpScreen.col < helpScreen.area.width ) {
        start = i;
        while( buffer[i] && buffer[i] != HELP_ESCAPE &&
               helpScreen.col+i-start<=helpScreen.area.width ) {
            if( buffer[i] == 0xFF )
                buffer[i] = 0x20;
            ++i;
        }
        if( i - start > 0 ) {
            uivtextput( &helpScreen, line, helpScreen.col, currentAttr,
                      &buffer[start], i - start );
        }
        helpScreen.col += i-start;
        if( buffer[i] == HELP_ESCAPE ) {

⌨️ 快捷键说明

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