vmsglog.cpp

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

CPP
805
字号
/****************************************************************************
*
*                            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!
*
****************************************************************************/


extern "C" {
    #include <stdio.h>
    #include "rcdefs.h"

#ifdef __WINDOWS__
    #include "common.h"
    #include "link.h"
#endif
#define CONNECTION_TRIES        10
#define CONNECTION_INTERVAL     300
    static int _connectionTries = 0;
    #include "batcher.h"
};

#include "vpemain.hpp"
#include "vmsglog.hpp"
#include "mproject.hpp"
#include "mcommand.hpp"
#include "wstrlist.hpp"
#include "wlistbox.hpp"
#include "wstring.hpp"
#include "wstrlist.hpp"
#include "wtimer.hpp"
#include "wmsgdlg.hpp"
#include "wfiledlg.hpp"
#include "wfile.hpp"
#include "wfilenam.hpp"
#include "wmenu.hpp"
#include "wmenuitm.hpp"
#include "wmetrics.hpp"
#include "wprocess.hpp"
#include "wsystem.hpp"
#include "wpshbttn.hpp"

#include "mconfig.hpp"

#define LOG_HELP_KEY    GUI_KEY_F1
#define LOG_ESCAPE_KEY  GUI_KEY_ESCAPE

extern char _viperError[];
static WString lastCD;
static char sFilter[] = { "Listing Files(*.txt)\0*.txt\0All files(*.*)\0*.*\0\0" };

static char fortranGrpCodes[] = {
     'A','R'
    ,'B','D'
    ,'C','C'
    ,'C','M'
    ,'C','N'
    ,'C','O'
    ,'C','P'
    ,'C','V'
    ,'D','A'
    ,'D','M'
    ,'D','O'
    ,'E','C'
    ,'E','N'
    ,'E','Q'
    ,'E','V'
    ,'E','X'
    ,'E','Y'
    ,'F','M'
    ,'G','O'
    ,'H','O'
    ,'I','F'
    ,'I','L'
    ,'I','M'
    ,'I','O'
    ,'K','O'
    ,'L','I'
    ,'M','D'
    ,'M','O'
    ,'P','C'
    ,'P','R'
    ,'R','E'
    ,'S','A'
    ,'S','F'
    ,'S','M'
    ,'S','P'
    ,'S','R'
    ,'S','S'
    ,'S','T'
    ,'S','V'
    ,'S','X'
    ,'T','Y'
    ,'V','A'
    ,'\0','\0'
};

Define( VMsgLog )

WEXPORT VMsgLog::VMsgLog( VpeMain* parent )
    : WMdiChild( parent, "IDE Log" )
    , _parent( parent )
    , _batcher( NULL )
    , _connecting( FALSE )
    , _runQueued( FALSE )
    , _connectTimer( NULL )
    , _serverConnected( FALSE )
    , _maxLength( 0 )
    , _running( FALSE )
    , _batserv( TRUE )
    , _localBatserv( FALSE )
    , _vxdPresent( FALSE )
{
    if( _config->hostType() == HOST_WINDOWS ||
        _config->hostType() == HOST_NEC_WIN ||
        _config->hostType() == HOST_J_WIN ) {
        _batserv = FALSE;
    }
    setIcon( I_MsgLog );

    WRect sc;
    _parent->getClientRect( sc );
    sc.y( sc.h() * 2/3 );
    sc.h( sc.h() - sc.y() );
    move( sc );

    int yoff = 0;

    _batcher = new VListBox( this, WRect(0,yoff,-1,-1) );
    _batcher->onDblClick( this, (cbw)&VMsgLog::selected );
    _batcher->show();

    show();

    loadHelpList();

    clearData();

    _batcher->setPopup( _parent->logPopup() );

    addAccelKey( LOG_ESCAPE_KEY, this, (bcbk)&VMsgLog::kAccelKey );
    addAccelKey( LOG_HELP_KEY, this, (bcbk)&VMsgLog::kAccelKey );
}

void VMsgLog::startConnect()
{
    _connectTimer = new WTimer( this, (cbt)&VMsgLog::connectTimer, 32768 );
    if( !_batserv ) {
#ifdef __WINDOWS__
        _vxdPresent = (bool)VxDPresent();
        if( _vxdPresent ) {
            const char* res = VxDLink( LINK_NAME );
            if( !res ) {
                WSystemService::sysExecBackground( _config->batserv() );
                _connectionTries = CONNECTION_TRIES;
                _connecting = TRUE;
                _connectTimer->start( CONNECTION_INTERVAL );
                addLine( "Connecting..." );
            } else {
                WMessageDialog::info( this, "VxD: %s", res );
            }
        } else {
            WMessageDialog::info( this, "VxD: WDEBUG.386 not present" );
        }
#endif
    } else {
#ifdef __WINDOWS__
        const char* err = BatchLink( NULL );
        if( err ) {
            _localBatserv = TRUE;
            WSystemService::sysExecBackground( _config->batserv() );
            _connectionTries = CONNECTION_TRIES;
            _connecting = TRUE;
            _connectTimer->start( CONNECTION_INTERVAL );
            addLine( "Connecting..." );
        } else {
            _serverConnected = TRUE;
        }
#else
        const char* err = BatchLink( NULL );
        if( err ) {
            _localBatserv = TRUE;
            WSystemService::sysExecBackground( _config->batserv() );
            addLine( "Connecting..." );
            _connectionTries = CONNECTION_TRIES;
            while( err && _connectionTries > 0 ) {
                WSystemService::sysSleep( CONNECTION_INTERVAL );
                err = BatchLink( NULL );
                _connectionTries -= 1;
            }
        }
        if( err ) {
            WMessageDialog::info( this, err );
            _parent->deleteMsglog();
            //zombie code at this point!!!!!!!!!!!!!!
        } else {
            _serverConnected = TRUE;
        }
#endif
    }
}

WEXPORT VMsgLog::~VMsgLog()
{
    if( !_batserv ) {
#ifdef __WINDOWS__
        if( _vxdPresent ) {
            if( _serverConnected ) {
                VxDPut( TERMINATE_CLIENT_STR, sizeof( TERMINATE_CLIENT_STR )+1 );
            }
            for( int i=0; i<100 && VxDUnLink()!=0; i++ );
        }
#endif
    } else {
        if( _serverConnected ) {
            BatchUnlink( _localBatserv );
        }
    }
    delete _connectTimer;
    _data.deleteContents();
    _helpList.deleteContents();
}

#ifndef NOPERSIST
VMsgLog* WEXPORT VMsgLog::createSelf( WObjectFile& )
{
    return NULL;
}

void WEXPORT VMsgLog::readSelf( WObjectFile& )
{
}

void WEXPORT VMsgLog::writeSelf( WObjectFile& )
{
}
#endif

void VMsgLog::getState( bool& editOk, bool& helpOk )
{
    int index = _batcher->selected();
    if( index >= 0 ) {
        char file[101]; int line, offset; char help[51];
        if( matchLine( index, file, line, offset, help ) ) {
            if( strlen( file ) > 0 ) {
                editOk = TRUE;
            }
            int hcount = _config->logHelpFiles().count();
            if( hcount > 0 && strlen( help ) > 0 ) {
                helpOk = TRUE;
            }
        }
    }
}

bool VMsgLog::saveLogAs()
{
    bool ok = FALSE;
    WFileName fn( "log" );
    MProject* project = _parent->project();
    if( project ) {
        project->filename().noPath( fn );
    }
    fn.setExt( ".txt" );
    WFileDialog fd( this, sFilter );
    fn = fd.getOpenFileName( fn, "Save Log as", WFSaveDefault );
    if( fn.legal() ) {
//        fn.toLower();
        WFile f;
        if( !f.open( fn, OStyleWrite ) ) {
            WMessageDialog::messagef( this, MsgError, MsgOk, _viperError, "Unable to save log file '%s'", (const char*)fn );
        } else {
            int icount  = _data.count();
            for( int i=0; i<icount; i++ ) {
                f.puts( *(WString*)_data[i] );
                f.puts( "\n" );
            }
            f.close();
            ok = TRUE;
        }
    }
    return ok;
}

bool VMsgLog::kAccelKey( gui_key _key )
{
    int key = _key;

    switch( key ) {
        case LOG_ESCAPE_KEY: {
            stopRequest( NULL );
            break;
        }
        case LOG_HELP_KEY: {
            helpRequest( NULL );
            break;
        }
    }
    return TRUE;
}

void VMsgLog::stopRequest( WMenuItem* )
{
    if( _running ) {
        MsgRetType ret = WMessageDialog::messagef( this, MsgInfo, MsgOkCancel, NULL,
                "OK to interrupt the executing process?" );
        if( ret == MsgRetOk ) {
            if( !_batserv ) {
#ifdef __WINDOWS__
                VxDRaiseInterrupt( 0x1B );      //send ctrlBreak
                addLine( "Stop invoked..." );
#endif
            } else {
                if( BatchCancel() ) {
                    addLine( "Stop failed" );
                } else {
                    addLine( "Stop invoked..." );
                }
            }
        }
    }
}

void VMsgLog::killBatcher()
{
    if( _batserv ) {
        BatchAbort();
    }
}

void VMsgLog::connectTimer( WTimer* timer, DWORD )
{
    const char* err = "Unable to connect to batch server.";
    if( !_batserv ) {
#ifdef __WINDOWS__
        _serverConnected = (BOOL)VxDConnect();
#endif
    } else {
        err = BatchLink( NULL );
        if( !err ) {
            _serverConnected = TRUE;
        }
    }
    if( _serverConnected ) {
        timer->stop();
        _connecting = FALSE;
        if( _runQueued ) {
            _runQueued = FALSE;
            doRun();
        }
    } else if( _connectionTries == 0 ) {
        timer->stop();
        _connecting = FALSE;
        WMessageDialog::info( this, err );
        _parent->deleteMsglog();
        //zombie code at this point!!!!!!!!!!!!!!
    } else {
        _connectionTries -= 1;
    }
}

void WEXPORT VMsgLog::runCommand( const char* cmd )
{
    _command = cmd;
    if( _serverConnected ) {
        clearData();
        doRun();
    } else {
        _runQueued = TRUE;
    }
}

void VMsgLog::doRun()
{
    _running = TRUE;
    if( isIconic() ) {
        show( WWinStateShowNormal );
    } else {
        show();

⌨️ 快捷键说明

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