You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2041 lines
40 KiB
2041 lines
40 KiB
/*
|
|
* khexedit - Versatile hex editor
|
|
* Copyright (C) 1999-2000 Espen Sand, espensa@online.no
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
#ifndef _HEX_BUFFER_H_
|
|
#define _HEX_BUFFER_H_
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <iostream>
|
|
#include <time.h>
|
|
|
|
#include <tqbitarray.h>
|
|
#include <tqdatetime.h>
|
|
#include <tqfile.h>
|
|
#include <tqfont.h>
|
|
#include <tqptrlist.h>
|
|
#include <tqpainter.h>
|
|
#include <tqstring.h>
|
|
#include <tqtextstream.h>
|
|
|
|
#include <kapplication.h>
|
|
|
|
#include "conversion.h"
|
|
#include "hexeditstate.h"
|
|
#include "hexprinter.h"
|
|
#include "progress.h"
|
|
|
|
//
|
|
// Marco to simplify usage of function pointers
|
|
//
|
|
#define THIS_FPTR( func ) ((this->*func))
|
|
|
|
struct SSearchControl
|
|
{
|
|
TQByteArray key;
|
|
TQByteArray val;
|
|
uint keyType;
|
|
bool fromCursor;
|
|
bool inSelection;
|
|
bool forward;
|
|
bool ignoreCase;
|
|
bool match;
|
|
uint numReplace;
|
|
|
|
bool wrapValid;
|
|
bool wrapActive;
|
|
uint wrapMark;
|
|
};
|
|
|
|
|
|
struct SFilterControl
|
|
{
|
|
enum Operation
|
|
{
|
|
OperandAndData = 0,
|
|
OperandOrData,
|
|
OperandXorData,
|
|
InvertData,
|
|
ReverseData,
|
|
RotateData,
|
|
ShiftData,
|
|
SwapBits
|
|
};
|
|
|
|
int execute( uchar *dest, uchar *src, uint size );
|
|
|
|
|
|
TQByteArray operand;
|
|
int rotate[2];
|
|
Operation operation;
|
|
bool fromCursor;
|
|
bool inSelection;
|
|
bool forward;
|
|
};
|
|
|
|
|
|
struct SInsertData
|
|
{
|
|
uint size;
|
|
TQByteArray pattern;
|
|
uint offset;
|
|
bool repeatPattern;
|
|
bool onCursor;
|
|
};
|
|
|
|
|
|
struct SExportRange
|
|
{
|
|
enum EMode
|
|
{
|
|
All = 0,
|
|
Selection,
|
|
Range
|
|
};
|
|
|
|
EMode mode;
|
|
uint start;
|
|
uint stop;
|
|
};
|
|
|
|
|
|
struct SExportText
|
|
{
|
|
SExportRange range;
|
|
TQString destFile;
|
|
};
|
|
|
|
|
|
struct SExportHtml
|
|
{
|
|
SExportRange range;
|
|
TQString package;
|
|
TQString prefix;
|
|
uint linePerPage;
|
|
uint topCaption;
|
|
uint bottomCaption;
|
|
bool symLink;
|
|
bool navigator;
|
|
bool blackWhite;
|
|
};
|
|
|
|
|
|
struct SExportCArray
|
|
{
|
|
enum ElementType
|
|
{
|
|
Char = 0,
|
|
Uchar,
|
|
Short,
|
|
Ushort,
|
|
Int,
|
|
Uint,
|
|
Float,
|
|
Double
|
|
};
|
|
|
|
const char *printFormatted( const char *b, uint maxSize ) const;
|
|
TQString variableName( uint range ) const;
|
|
int elementSize( void ) const;
|
|
|
|
SExportRange range;
|
|
TQString destFile;
|
|
TQString arrayName;
|
|
int elementType;
|
|
uint elementPerLine;
|
|
bool unsignedAsHexadecimal;
|
|
};
|
|
|
|
|
|
struct SStatisticControl
|
|
{
|
|
SStatisticControl( void )
|
|
{
|
|
memset( occurrence, 0, sizeof(occurrence) );
|
|
documentSize = 0;
|
|
}
|
|
|
|
uint documentSize;
|
|
uint occurrence[256];
|
|
TQString documentName;
|
|
};
|
|
|
|
|
|
struct SPagePosition
|
|
{
|
|
SPagePosition( time_t now, uint numLine, uint linePerPage )
|
|
{
|
|
init( now, numLine, linePerPage );
|
|
}
|
|
|
|
SPagePosition( void )
|
|
{
|
|
init( 0, 1, 1 );
|
|
}
|
|
|
|
void init( time_t at, uint numLine, uint linePerPage )
|
|
{
|
|
if( linePerPage == 0 ) { linePerPage = 1; }
|
|
|
|
now = at;
|
|
curPage = 1;
|
|
maxPage = numLine / linePerPage + (numLine % linePerPage ? 1 : 0);
|
|
if( maxPage < curPage ) { maxPage = curPage; }
|
|
}
|
|
|
|
void step( uint stepSize=1 )
|
|
{
|
|
curPage += stepSize;
|
|
if( curPage > maxPage ) { curPage = maxPage; }
|
|
}
|
|
|
|
uint current( void )
|
|
{
|
|
return( curPage );
|
|
}
|
|
|
|
uint max( void )
|
|
{
|
|
return( maxPage );
|
|
}
|
|
|
|
uint curPage;
|
|
uint maxPage;
|
|
time_t now;
|
|
};
|
|
|
|
|
|
|
|
class CStringCollectControl
|
|
{
|
|
public:
|
|
CStringCollectControl( void )
|
|
{
|
|
mList.setAutoDelete( true );
|
|
}
|
|
|
|
int add( uint offset, const TQByteArray &a )
|
|
{
|
|
TQString *s = new TQString();
|
|
if( s == 0 )
|
|
{
|
|
return( Err_NoMemory );
|
|
}
|
|
|
|
if( decimalOffset == true )
|
|
{
|
|
s->sprintf( "%010u", offset );
|
|
}
|
|
else
|
|
{
|
|
s->sprintf( "%04x:%04x", offset>>16, offset&0x0000FFFF );
|
|
}
|
|
|
|
*s += TQString( a );
|
|
|
|
mList.append( s );
|
|
return( Err_Success );
|
|
}
|
|
|
|
uint offsetLen( void )
|
|
{
|
|
return( decimalOffset ? 10 : 9 );
|
|
}
|
|
|
|
void clear( void )
|
|
{
|
|
mList.clear();
|
|
}
|
|
|
|
const TQString *get( uint index )
|
|
{
|
|
return( mList.at( index ) );
|
|
}
|
|
|
|
int count( void )
|
|
{
|
|
return( mList.count() );
|
|
}
|
|
|
|
TQPtrList<TQString> &list( void )
|
|
{
|
|
return( mList );
|
|
}
|
|
|
|
public:
|
|
uint minLength;
|
|
bool decimalOffset;
|
|
bool allow8bit;
|
|
|
|
private:
|
|
TQPtrList<TQString> mList;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct SCursorConfig
|
|
{
|
|
SCursorConfig( void )
|
|
{
|
|
state = 0;
|
|
}
|
|
|
|
bool selectOn( void )
|
|
{
|
|
return( state & TQt::ShiftButton );
|
|
}
|
|
|
|
bool removeSelection( void )
|
|
{
|
|
return( state & TQt::ShiftButton ? false : true );
|
|
}
|
|
|
|
void setKeepSelection( bool val )
|
|
{
|
|
state = val == true ? state|TQt::ShiftButton : state&~TQt::ShiftButton;
|
|
}
|
|
|
|
bool controlButton( void )
|
|
{
|
|
return( state & TQt::ControlButton ? true : false );
|
|
}
|
|
|
|
bool shiftButton( void )
|
|
{
|
|
return( state & TQt::ShiftButton ? true : false );
|
|
}
|
|
|
|
bool altButton( void )
|
|
{
|
|
return( state & TQt::AltButton ? true : false );
|
|
}
|
|
|
|
|
|
void emulateControlButton( bool val )
|
|
{
|
|
state = val == true ? state|TQt::ControlButton : state&~TQt::ControlButton;
|
|
}
|
|
|
|
int state;
|
|
};
|
|
|
|
|
|
|
|
struct SCursorSpec
|
|
{
|
|
enum EShape
|
|
{
|
|
solid = 0,
|
|
frame,
|
|
thin
|
|
};
|
|
|
|
void reset( void )
|
|
{
|
|
offset = 0;
|
|
x1 = x2 = y = cell = maxCell = 0;
|
|
}
|
|
|
|
void setShape( EShape primaryShape, EShape secondaryShape, uint unitWidth,
|
|
uint numCell )
|
|
{
|
|
|
|
if( primaryShape == thin )
|
|
{
|
|
if( onlyBlock == true ) { primaryShape = solid; }
|
|
}
|
|
if( secondaryShape == thin )
|
|
{
|
|
if( onlyBlock == true ) { secondaryShape = solid; }
|
|
}
|
|
|
|
mPrimaryShape = primaryShape;
|
|
if( mPrimaryShape == solid )
|
|
{
|
|
drawWidth1 = unitWidth;
|
|
drawOffset1 = 0;
|
|
}
|
|
else if( mPrimaryShape == frame )
|
|
{
|
|
drawWidth1 = unitWidth * numCell;
|
|
drawOffset1 = 0;
|
|
}
|
|
else
|
|
{
|
|
mPrimaryShape = thin;
|
|
if( thickState == true )
|
|
{
|
|
drawWidth1 = 2;
|
|
drawOffset1 = -1;
|
|
}
|
|
else
|
|
{
|
|
drawWidth1 = 5;
|
|
drawOffset1 = -3;
|
|
}
|
|
}
|
|
|
|
mSecondaryShape = secondaryShape;
|
|
if( mSecondaryShape == solid )
|
|
{
|
|
drawWidth2 = unitWidth;
|
|
drawOffset2 = 0;
|
|
}
|
|
else if( mSecondaryShape == frame )
|
|
{
|
|
drawWidth2 = unitWidth * numCell;
|
|
drawOffset2 = 0;
|
|
}
|
|
else
|
|
{
|
|
mSecondaryShape = thin;
|
|
if( thickState == true )
|
|
{
|
|
drawWidth2 = 2;
|
|
drawOffset2 = -1;
|
|
}
|
|
else
|
|
{
|
|
drawWidth2 = 5;
|
|
drawOffset2 = -3;
|
|
}
|
|
}
|
|
}
|
|
|
|
void setShapeModifier( bool alwaysBlock, bool useThick )
|
|
{
|
|
onlyBlock = alwaysBlock;
|
|
thickState = useThick;
|
|
}
|
|
|
|
void dump( void )
|
|
{
|
|
std::cout << "offset: " << offset << " y: " << y << " x1: " << x1 << std::endl;
|
|
std::cout << "x2: " << x2 << " cell: " << cell << std::endl;
|
|
}
|
|
|
|
bool inside( uint min, uint max )
|
|
{
|
|
return( offset >= min && offset < max );
|
|
}
|
|
|
|
int drawX1( void )
|
|
{
|
|
return( x1 + drawOffset1 );
|
|
}
|
|
|
|
int drawX2( void )
|
|
{
|
|
return( x2 + drawOffset2 );
|
|
}
|
|
|
|
int width1( void )
|
|
{
|
|
return( drawWidth1 );
|
|
}
|
|
|
|
int width2( void )
|
|
{
|
|
return( drawWidth2 );
|
|
}
|
|
|
|
uint offset;
|
|
int y;
|
|
int x1;
|
|
int x2;
|
|
int cell;
|
|
int maxCell;
|
|
bool onlyBlock;
|
|
bool thickState;
|
|
|
|
char data;
|
|
|
|
int mPrimaryShape;
|
|
int mSecondaryShape;
|
|
int drawWidth1;
|
|
int drawWidth2;
|
|
int drawOffset1;
|
|
int drawOffset2;
|
|
};
|
|
|
|
|
|
struct SCursor
|
|
{
|
|
SCursor( void )
|
|
{
|
|
mLineSize = 1;
|
|
mDocumentSize = 0;
|
|
mFixedSizeMode = false;
|
|
mArea = 0;
|
|
}
|
|
|
|
void reset( void )
|
|
{
|
|
prev.reset();
|
|
curr.reset();
|
|
next.reset();
|
|
}
|
|
|
|
void setDocumentSize( uint documentSize )
|
|
{
|
|
mDocumentSize = documentSize;
|
|
}
|
|
|
|
void setFixedSizeMode( bool fixedSizeMode )
|
|
{
|
|
mFixedSizeMode = fixedSizeMode;
|
|
}
|
|
|
|
bool incCell( void )
|
|
{
|
|
if( curr.cell + 1 >= curr.maxCell )
|
|
{
|
|
addOffset( 1 );
|
|
return( true );
|
|
}
|
|
else
|
|
{
|
|
next.cell = curr.cell + 1;
|
|
return( false );
|
|
}
|
|
}
|
|
|
|
bool decCell( void )
|
|
{
|
|
if( curr.cell == 0 )
|
|
{
|
|
if( curr.offset > 0 )
|
|
{
|
|
decOffset( 1, true );
|
|
next.cell = curr.maxCell > 0 ? curr.maxCell - 1 : 0;
|
|
}
|
|
return( true );
|
|
}
|
|
else
|
|
{
|
|
next.cell = curr.cell - 1;
|
|
return( false );
|
|
}
|
|
}
|
|
|
|
void resetCell( void )
|
|
{
|
|
next.cell = 0;
|
|
}
|
|
|
|
|
|
void addOffset( uint val )
|
|
{
|
|
setOffset( curr.offset + val );
|
|
}
|
|
|
|
void decOffset( uint val, bool ignoreCell )
|
|
{
|
|
if( ignoreCell == true || curr.cell == 0 )
|
|
{
|
|
setOffset( val > curr.offset ? curr.offset%mLineSize : curr.offset-val);
|
|
}
|
|
else
|
|
{
|
|
setOffset( curr.offset );
|
|
}
|
|
}
|
|
|
|
void setOffset( uint offset )
|
|
{
|
|
/*
|
|
if( offset >= mDocumentSize )
|
|
{
|
|
if( mFixedSizeMode == true )
|
|
{
|
|
offset = mDocumentSize > 0 ? mDocumentSize - 1 : 0;
|
|
}
|
|
else
|
|
{
|
|
offset = mDocumentSize;
|
|
}
|
|
}
|
|
*/
|
|
|
|
next.offset = offset;
|
|
next.cell = 0;
|
|
}
|
|
|
|
uint getOffset( void )
|
|
{
|
|
return( curr.offset );
|
|
}
|
|
|
|
void setOffset( uint offset, uint bit, bool backward, bool fromCursor,
|
|
uint textSize )
|
|
{
|
|
if( fromCursor == true )
|
|
{
|
|
if( backward == true )
|
|
{
|
|
setOffset( offset > curr.offset ? 0 : curr.offset - offset );
|
|
}
|
|
else
|
|
{
|
|
setOffset( curr.offset + offset );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( backward == true )
|
|
{
|
|
setOffset( offset > textSize ? 0 : textSize - offset );
|
|
}
|
|
else
|
|
{
|
|
setOffset( offset > textSize ? textSize : offset );
|
|
}
|
|
}
|
|
setBit( bit );
|
|
}
|
|
|
|
|
|
void setBit( uint bit )
|
|
{
|
|
bit = (bit > 7) ? 0 : 7 - bit;
|
|
next.cell = bit / mCellWeight;
|
|
}
|
|
|
|
|
|
void home( bool toExtreme )
|
|
{
|
|
if( toExtreme == true )
|
|
{
|
|
setOffset( 0 );
|
|
}
|
|
else
|
|
{
|
|
setOffset( next.offset - curr.offset % mLineSize );
|
|
}
|
|
}
|
|
|
|
void end( bool toExtreme )
|
|
{
|
|
uint maxOffset;
|
|
if( mFixedSizeMode == true )
|
|
{
|
|
maxOffset = mDocumentSize > 0 ? mDocumentSize-1 : mDocumentSize;
|
|
}
|
|
else
|
|
{
|
|
maxOffset = mDocumentSize;
|
|
}
|
|
|
|
if( toExtreme == true )
|
|
{
|
|
setOffset( maxOffset );
|
|
}
|
|
else
|
|
{
|
|
uint newOffset = next.offset + (mLineSize-1) - curr.offset % mLineSize;
|
|
setOffset( newOffset > maxOffset ? maxOffset : newOffset );
|
|
}
|
|
|
|
}
|
|
|
|
void up( uint numLines )
|
|
{
|
|
decOffset( numLines * mLineSize, true );
|
|
}
|
|
|
|
void down( uint numLines )
|
|
{
|
|
addOffset( numLines * mLineSize );
|
|
}
|
|
|
|
bool changed( void )
|
|
{
|
|
return( prev.offset != curr.offset || prev.cell != curr.cell ||
|
|
prev.data != curr.data ? true : false );
|
|
}
|
|
|
|
uint bit( void )
|
|
{
|
|
uint bitValue = mCellWeight*(curr.maxCell - curr.cell) - 1;
|
|
return( bitValue > 7 ? 7 : bitValue );
|
|
}
|
|
|
|
uint cellWeight( void )
|
|
{
|
|
return( mCellWeight );
|
|
}
|
|
|
|
void setLineSize( uint lineSize )
|
|
{
|
|
mLineSize = lineSize < 1 ? 1 : lineSize;
|
|
}
|
|
|
|
void setCellWeight( uint cellWeight )
|
|
{
|
|
mCellWeight = cellWeight;
|
|
}
|
|
|
|
int area( void )
|
|
{
|
|
return( mArea );
|
|
}
|
|
|
|
void setArea( int area )
|
|
{
|
|
mArea = area;
|
|
}
|
|
|
|
void setShape( SCursorSpec::EShape primary, SCursorSpec::EShape secondary,
|
|
uint unitWidth, uint numCell )
|
|
{
|
|
curr.setShape( primary, secondary, unitWidth, numCell );
|
|
}
|
|
|
|
void setShapeModifier( bool alwaysBlock, bool useThick )
|
|
{
|
|
curr.setShapeModifier( alwaysBlock, useThick );
|
|
}
|
|
|
|
uint mLineSize;
|
|
uint mDocumentSize;
|
|
uint mCellWeight;
|
|
int mArea;
|
|
bool mFixedSizeMode;
|
|
SCursorSpec prev;
|
|
SCursorSpec curr;
|
|
SCursorSpec next;
|
|
};
|
|
|
|
|
|
struct SCursorPosition
|
|
{
|
|
int x;
|
|
int y;
|
|
int w;
|
|
int h;
|
|
};
|
|
|
|
struct SCursorOffset
|
|
{
|
|
uint offset;
|
|
uint bit;
|
|
};
|
|
|
|
|
|
struct SSelectSpec
|
|
{
|
|
void init( uint offset )
|
|
{
|
|
start = stop = anchor = offset;
|
|
}
|
|
|
|
void set( uint offset )
|
|
{
|
|
if( offset < anchor )
|
|
{
|
|
start = offset;
|
|
stop = anchor;
|
|
}
|
|
else
|
|
{
|
|
stop = offset;
|
|
start = anchor;
|
|
}
|
|
}
|
|
|
|
void expand( uint value )
|
|
{
|
|
if( anchor == stop ) { anchor +=value; }
|
|
stop += value;
|
|
//set( stop + value );
|
|
}
|
|
|
|
void shrink( uint value )
|
|
{
|
|
uint newVal = start + value > stop ? start : stop - value;
|
|
if( anchor == stop ) { anchor = newVal; }
|
|
stop = newVal;
|
|
/*
|
|
if( start + value > stop )
|
|
{
|
|
set( start );
|
|
}
|
|
else
|
|
{
|
|
set( stop - value );
|
|
}
|
|
*/
|
|
}
|
|
|
|
|
|
uint start;
|
|
uint stop;
|
|
uint anchor;
|
|
};
|
|
|
|
|
|
struct SSelect
|
|
{
|
|
SSelect( void )
|
|
{
|
|
reset();
|
|
}
|
|
|
|
bool init( uint offset )
|
|
{
|
|
curr.init( offset );
|
|
if( isValid == true )
|
|
{
|
|
isValid = false;
|
|
return( true );
|
|
}
|
|
else
|
|
{
|
|
return( false );
|
|
}
|
|
}
|
|
|
|
void reset( void )
|
|
{
|
|
curr.init( 0 );
|
|
isValid = false;
|
|
}
|
|
|
|
bool set( uint offset )
|
|
{
|
|
isValid = true;
|
|
|
|
curr.set( offset );
|
|
if( curr.start != prev.start || curr.stop != prev.stop )
|
|
{
|
|
return( true );
|
|
}
|
|
else
|
|
{
|
|
return( false );
|
|
}
|
|
}
|
|
|
|
void expand( uint value )
|
|
{
|
|
if( isValid == false )
|
|
{
|
|
return;
|
|
}
|
|
curr.expand( value );
|
|
}
|
|
|
|
void shrink( uint value )
|
|
{
|
|
if( isValid == false )
|
|
{
|
|
return;
|
|
}
|
|
curr.shrink( value );
|
|
}
|
|
|
|
|
|
void sync( void )
|
|
{
|
|
prev = curr;
|
|
}
|
|
|
|
bool inside( uint offset )
|
|
{
|
|
return( isValid == true && offset >= curr.start && offset < curr.stop );
|
|
}
|
|
|
|
bool inside( uint offset, uint range )
|
|
{
|
|
return( isValid == true && (offset + range) >= curr.start &&
|
|
offset < curr.stop );
|
|
}
|
|
|
|
bool verify( uint &start, uint &stop )
|
|
{
|
|
if( isValid == false )
|
|
{
|
|
return( false );
|
|
}
|
|
|
|
if( start < curr.start ) { start = curr.start; }
|
|
if( stop > curr.stop ) { stop = curr.stop; }
|
|
return( true );
|
|
}
|
|
|
|
uint start( uint offset )
|
|
{
|
|
//
|
|
// If 'curr.star' is smaller than 'offset' then the start is at
|
|
// the start of line.
|
|
//
|
|
return( curr.start < offset ? 0 : curr.start - offset );
|
|
}
|
|
|
|
uint start( void )
|
|
{
|
|
return( curr.start );
|
|
}
|
|
|
|
uint stop( uint offset, uint range )
|
|
{
|
|
return( curr.stop > offset + range ? range : curr.stop - offset );
|
|
}
|
|
|
|
uint stop( void )
|
|
{
|
|
return( curr.stop );
|
|
}
|
|
|
|
bool valid( void )
|
|
{
|
|
return( isValid );
|
|
}
|
|
|
|
uint size( void )
|
|
{
|
|
if( isValid == false )
|
|
{
|
|
return( 0 );
|
|
}
|
|
else
|
|
{
|
|
return( curr.start >= curr.stop ? 0 : curr.stop - curr.start );
|
|
}
|
|
}
|
|
|
|
void startChange( uint &first, uint &last )
|
|
{
|
|
if( curr.start <= prev.start )
|
|
{
|
|
first = curr.start;
|
|
last = prev.start;
|
|
}
|
|
else
|
|
{
|
|
first = prev.start;
|
|
last = curr.start;
|
|
}
|
|
}
|
|
|
|
void stopChange( uint &first, uint &last )
|
|
{
|
|
if( curr.stop <= prev.stop )
|
|
{
|
|
first = curr.stop;
|
|
last = prev.stop;
|
|
}
|
|
else
|
|
{
|
|
first = prev.stop;
|
|
last = curr.stop;
|
|
}
|
|
}
|
|
|
|
|
|
bool isValid;
|
|
SSelectSpec prev;
|
|
SSelectSpec curr;
|
|
};
|
|
|
|
|
|
|
|
class CHexAction
|
|
{
|
|
public:
|
|
enum HexAction
|
|
{
|
|
tqreplace
|
|
};
|
|
|
|
public:
|
|
CHexAction( HexAction action, uint offset );
|
|
~CHexAction( void );
|
|
void setData( uint size, char *data, uint dataSize );
|
|
|
|
public:
|
|
HexAction mAction;
|
|
uint mOffset;
|
|
uint mSize;
|
|
char *mData;
|
|
uint mDataSize;
|
|
CHexAction *mNext;
|
|
};
|
|
|
|
class CHexActionGroup
|
|
{
|
|
public:
|
|
CHexActionGroup( uint startOffset, uint startBit );
|
|
~CHexActionGroup( void );
|
|
void insertAction( CHexAction *hexAction );
|
|
|
|
public:
|
|
uint mStartOffset;
|
|
uint mStopOffset;
|
|
uint mStartBit;
|
|
uint mStopBit;
|
|
CHexAction *mHexAction;
|
|
};
|
|
|
|
|
|
|
|
struct SCursorState
|
|
{
|
|
bool valid;
|
|
uint selectionOffset;
|
|
uint selectionSize;
|
|
uint offset;
|
|
uint cell;
|
|
unsigned char data[8];
|
|
uint undoState;
|
|
bool charValid;
|
|
};
|
|
|
|
struct SFileState
|
|
{
|
|
bool valid;
|
|
uint size;
|
|
bool modified;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class CHexBuffer;
|
|
typedef int (CHexBuffer::*PrintCellFunc)( char *buf, unsigned char data );
|
|
typedef bool (CHexBuffer::*InputCellFunc)( unsigned char *dest, int value,
|
|
uint cell );
|
|
typedef void (CHexBuffer::*PrintOffsetFunc)( char *buf, uint offset );
|
|
|
|
|
|
class CHexBuffer : public TQByteArray
|
|
{
|
|
public:
|
|
enum EColumn
|
|
{
|
|
VisibleColumn = 0x0,
|
|
OffsetColumn = 0x1,
|
|
PrimaryColumn = 0x2,
|
|
SecondaryColumn = 0x4,
|
|
EveryColumn = 0x7
|
|
};
|
|
|
|
enum EEditArea
|
|
{
|
|
edit_none = 0,
|
|
edit_primary,
|
|
edit_secondary
|
|
};
|
|
|
|
enum ECursorMode
|
|
{
|
|
cursor_curr = 0,
|
|
cursor_prev
|
|
};
|
|
|
|
enum EEditMode
|
|
{
|
|
EditInsert = 0,
|
|
EditReplace
|
|
};
|
|
|
|
enum EUndoState
|
|
{
|
|
UndoOk = 1,
|
|
RedoOk = 2
|
|
};
|
|
|
|
public:
|
|
CHexBuffer( void );
|
|
~CHexBuffer( void );
|
|
|
|
int setLayout( SDisplayLayout &tqlayout );
|
|
void setColor( SDisplayColor &color );
|
|
void setInputMode( SDisplayInputMode &mode );
|
|
bool toggleEditor( void );
|
|
|
|
bool matchWidth( uint width );
|
|
|
|
void setNonPrintChar( TQChar nonPrintChar );
|
|
void setShowCursor( bool showCursor );
|
|
void setDisableCursor( bool disableCursor );
|
|
void settqCursorShapeModifier( bool alwaysBlock, bool thickInsert );
|
|
void setEditMode( EEditMode editMode );
|
|
void setEditMode( EEditMode editMode, bool alwaysBlock, bool thickInsert );
|
|
void setMaximumSize( uint size );
|
|
void setDocumentSize( uint size );
|
|
void setUndoLevel( uint level );
|
|
void setSoundState( bool inputSound, bool fatalSound );
|
|
void setBookmarkVisibility( bool showInColumn, bool showInEditor );
|
|
|
|
void setFont( const SDisplayFontInfo &fontInfo );
|
|
int setEncoding( CConversion::EMode mode, CProgress &p );
|
|
|
|
bool setCursorPosition( int x, int y, bool init, bool cellLevel );
|
|
|
|
int readFile( TQFile &file, const TQString &url, CProgress &p );
|
|
int insertFile( TQFile &file, CProgress &p );
|
|
int writeFile( TQFile &file, CProgress &p );
|
|
int newFile( const TQString &url );
|
|
void closeFile( void );
|
|
void registerDiskModifyTime( const TQFile &file );
|
|
|
|
bool changedOnDisk( void );
|
|
|
|
void drawText( TQPainter &paint, uint line, int sx, int x, int w );
|
|
void drawText( TQPainter &paint, uint line, int x1, int x2, int y,
|
|
bool useBlackWhite );
|
|
|
|
void drawHeader( TQPainter &paint, int sx, int width, int y, bool isFooter,
|
|
const SPageHeader &header,const SPagePosition &position );
|
|
int headerHeight( TQPainter &paint );
|
|
int headerMargin( TQPainter &paint );
|
|
|
|
bool inputAtCursor( TQChar c );
|
|
int inputAtCursor( const TQByteArray &buf, uint oldSize );
|
|
bool removeAtCursor( bool beforeCursor );
|
|
|
|
int locateRange( const SExportRange &range, uint &start, uint &stop );
|
|
int exportText( const SExportText &ex, CProgress &p );
|
|
int exportHtml( const SExportHtml &ex, CProgress &p );
|
|
int exportCArray( const SExportCArray &ex, CProgress &p );
|
|
int copySelectedText( TQByteArray &array, int columnSegment=VisibleColumn);
|
|
int copyAllText( TQByteArray &array );
|
|
int copyText( TQByteArray &array, const SExportRange &range,
|
|
int columnSegment );
|
|
int copySelectedData( TQByteArray &array );
|
|
|
|
uint numPage( CHexPrinter &printer );
|
|
int print( CHexPrinter &printer, CProgress &p );
|
|
|
|
uint printLine( char *dst, uint line );
|
|
uint printLine( char *dst, uint line, int columnSegment );
|
|
|
|
bool cutSelection( void );
|
|
bool undo( void );
|
|
bool redo( void );
|
|
int addBookmark( int position );
|
|
bool removeBookmark( int position );
|
|
void updateBookmarkMap( bool resize );
|
|
|
|
int findFirst( SSearchControl &sc );
|
|
int findNext( SSearchControl &sc );
|
|
int findWrap( SSearchControl &sc );
|
|
int replaceAll( SSearchControl &sc, bool init );
|
|
int replaceMarked( SSearchControl &sc );
|
|
int filter( SFilterControl &fc );
|
|
int collectStrings( CStringCollectControl &sc );
|
|
int collectStatistic( SStatisticControl &sc, CProgress &p );
|
|
|
|
void doActionGroup( CHexActionGroup *group );
|
|
void doAction( CHexAction *action );
|
|
|
|
inline SCursorState &cursorState( void );
|
|
inline void valueOnCursor( TQByteArray &buf, uint size );
|
|
inline SFileState &fileState( void );
|
|
inline const SDisplayLayout &tqlayout( void );
|
|
|
|
inline const SDisplayInputMode &inputMode( void );
|
|
inline TQPtrList<SCursorOffset> &bookmarkList( void );
|
|
|
|
inline bool documentPresent( void );
|
|
inline bool modified( void );
|
|
inline uint undoState( void );
|
|
inline uint documentSize( void );
|
|
inline EEditMode editMode( void );
|
|
inline const SEncodeState &encoding( void );
|
|
inline bool losslessEncoding( CConversion::EMode mode );
|
|
|
|
inline TQString &url( void );
|
|
bool hasFileName( void );
|
|
inline void setUrl( const TQString &url );
|
|
inline void setModified( bool modified );
|
|
inline const TQDateTime &diskModifyTime( void );
|
|
|
|
|
|
|
|
inline uint calculateLine( uint offset );
|
|
inline int lineSize( void );
|
|
inline int lineHeight( void );
|
|
inline int fontAscent( void );
|
|
inline int lineWidth( void );
|
|
inline int unitWidth( void );
|
|
inline int numLines( void );
|
|
inline int totalHeight( void );
|
|
inline const TQFont &font( void );
|
|
inline SCursor *textCursor( void );
|
|
inline const TQColor &backgroundColor( void );
|
|
inline int startX( void );
|
|
inline int startY( void );
|
|
inline void setStartX( int val );
|
|
inline void setStartY( int val );
|
|
|
|
inline bool selectionSet( uint offset, bool init );
|
|
inline void selectionSyncronize( void );
|
|
inline void selectionStartChange( uint &offset1, uint &offset2 );
|
|
inline void selectionStopChange( uint &offset1, uint &offset2 );
|
|
inline bool cursorInsideSelection( void );
|
|
|
|
inline void markSet( uint offset, uint size );
|
|
inline bool markSet( uint offset, bool init );
|
|
inline bool markRemove( void );
|
|
inline void markSyncronize( void );
|
|
inline void markStartChange( uint &offset1, uint &offset2 );
|
|
inline void markStopChange( uint &offset1, uint &offset2 );
|
|
|
|
inline uint cursorOffset( void );
|
|
inline uint cursorBit( void );
|
|
inline uint cursorLine( void );
|
|
inline uint prevCursorLine( void );
|
|
inline SCursor &cursor( void );
|
|
|
|
inline void currCursor( EEditArea editArea, SCursorPosition &p );
|
|
inline void prevCursor( EEditArea editArea, SCursorPosition &p );
|
|
|
|
inline void cursorUp( uint lines );
|
|
inline void cursorDown( uint lines );
|
|
inline void cursorRight( bool cellLevel );
|
|
inline void cursorLeft( bool cellLevel );
|
|
inline void cursorStep( uint size, bool forward, bool modulo );
|
|
inline void cursorHome( bool toExtreme );
|
|
inline void cursorEnd( bool toExtreme );
|
|
inline void cursorGoto( uint offset, uint bit );
|
|
inline void cursorGoto( uint offset, uint bit, bool backward,
|
|
bool fromCursor );
|
|
inline bool cursorChanged( void );
|
|
inline void cursorResetEditArea( void );
|
|
inline bool cursorPrimaryEdit( void );
|
|
inline int cursorFixedPosition( int position, int height );
|
|
inline int cursorChangePosition( int position, int height );
|
|
void cursorReset( void );
|
|
|
|
private:
|
|
enum { BookmarkOnLine = 0x01, BookmarkOnCursor = 0x02 };
|
|
|
|
void computeLineWidth( void );
|
|
void computeNumLines( void );
|
|
void cursorCompute( void );
|
|
|
|
void drawSelection( TQPainter &paint, TQColor &color, uint start, uint stop,
|
|
int sx );
|
|
int drawBookmarks(TQPainter &paint, uint line, int startx);
|
|
void drawCursor( TQPainter &paint, uint line, int startx, bool onBookmark );
|
|
|
|
void recordStart( SCursor &cursor );
|
|
void recordReplace( SCursor &cursor, uint size, char *data, uint dataSize);
|
|
void recordEnd( SCursor &cursor );
|
|
void doReplace( CHexAction *hexAction, bool removeData );
|
|
int scanData( SSearchControl &sc, bool init );
|
|
int initScanData( SSearchControl &sc );
|
|
|
|
inline const TQColor &foregroundColor( uint column );
|
|
inline int printDummyCell( char *buf, unsigned char data );
|
|
inline int printHexadecimalBigCell( char *buf, unsigned char data );
|
|
inline int printHexadecimalSmallCell( char *buf, unsigned char data );
|
|
inline int printDecimalCell( char *buf, unsigned char data );
|
|
inline int printOctalCell( char *buf, unsigned char data );
|
|
inline int printBinaryCell( char *buf, unsigned char data );
|
|
inline int printAsciiCell( char *buf, unsigned char data );
|
|
inline void printDummyOffset( char *buf, uint offset );
|
|
inline void printHexadecimalBigOffset( char *buf, uint offset );
|
|
inline void printHexadecimalSmallOffset( char *buf, uint offset );
|
|
inline void printDecimalOffset( char *buf, uint offset );
|
|
|
|
bool inputDummy( unsigned char *dest, int value, uint cell );
|
|
bool inputHexadecimal( unsigned char *dest, int value, uint cell );
|
|
bool inputDecimal( unsigned char *dest, int value, uint cell );
|
|
bool inputOctal( unsigned char *dest, int value, uint cell );
|
|
bool inputBinary( unsigned char *dest, int value, uint cell );
|
|
bool inputAscii( unsigned char *dest, int value, uint cell );
|
|
|
|
int moveBuffer( uint destOffset, uint srcOffset );
|
|
int resizeBuffer( uint offset );
|
|
|
|
void inputSound( void );
|
|
void fatalSound( void );
|
|
|
|
int printHtmlDataPage( const TQString &tocName,
|
|
const TQStringList &fileNames, uint index,
|
|
const SExportHtml &ex, uint line, uint numLine );
|
|
void printHtmlCaption( TQTextStream &os, uint captionType, uint curPage,
|
|
uint numPage );
|
|
void printHtmlNavigator( TQTextStream &os, const TQString *next,
|
|
const TQString *prev, const TQString *toc );
|
|
void printHtmlTocPage( const TQString &tocName,
|
|
const TQString &linkName,
|
|
const TQStringList &fileNames,
|
|
const TQStringList &offsets, uint numPage );
|
|
int printHtmlHeader( TQTextStream &os, bool isFront );
|
|
int printHtmlTable( TQTextStream &os, uint line, uint numLine, bool bw );
|
|
int printHtmlLine( TQTextStream &os, uint offset, bool isPrimary, bool bw );
|
|
|
|
signals:
|
|
void fileSize( uint size );
|
|
|
|
private:
|
|
TQString mUrl;
|
|
TQDateTime mDiskModifyTime;
|
|
SDisplayLayout mLayout;
|
|
SDisplayColor mColor;
|
|
SDisplayFontInfo mFontInfo;
|
|
CConversion mEncode;
|
|
bool mCharValid[256];
|
|
|
|
unsigned char *mColorIndex;
|
|
char *mPrintBuf;
|
|
bool mLoadingData;
|
|
int mStartX;
|
|
int mStartY;
|
|
|
|
int mFontHeight;
|
|
int mFontAscent;
|
|
int mLineWidth;
|
|
int mFixedWidth;
|
|
int mUnitWidth;
|
|
int mSplitWidth;
|
|
int mNumLines;
|
|
int mTextStart1;
|
|
int mTextStart2;
|
|
int mNumCell;
|
|
|
|
uint mDocumentSize;
|
|
uint mMaximumSize;
|
|
bool mFixedSizeMode;
|
|
bool mDocumentModified;
|
|
EEditMode mEditMode;
|
|
SDisplayInputMode mInputMode;
|
|
|
|
int mOffsetSize;
|
|
int mOffsetIndex;
|
|
int mPrimaryWidth;
|
|
int mSecondaryWidth;
|
|
int mActiveEditor;
|
|
|
|
SSelect mSelect;
|
|
SSelect mMark;
|
|
|
|
SCursor mCursor;
|
|
bool mShowCursor;
|
|
bool mDisableCursor;
|
|
|
|
bool mInputErrorSound;
|
|
bool mFatalErrorSound;
|
|
|
|
bool mShowBookmarkInOffsetColumn;
|
|
bool mShowBookmarkInEditor;
|
|
|
|
uint mUndoLimit;
|
|
uint mUndoIndex;
|
|
TQPtrList<CHexActionGroup> mUndoList;
|
|
TQPtrList<SCursorOffset> mBookmarkList;
|
|
TQBitArray mBookmarkMap;
|
|
|
|
PrintCellFunc printCell;
|
|
PrintOffsetFunc printOffset;
|
|
InputCellFunc inputCell;
|
|
|
|
static char mHexBigBuffer[16];
|
|
static char mHexSmallBuffer[16];
|
|
static char mDecBuffer[10];
|
|
static char mOctBuffer[8];
|
|
static SCursorState mCursorState;
|
|
static SFileState mFileState;
|
|
};
|
|
|
|
|
|
|
|
inline SCursorState &CHexBuffer::cursorState( void )
|
|
{
|
|
if( size() == 0 )
|
|
{
|
|
mCursorState.valid = false;
|
|
mCursorState.selectionOffset = 0;
|
|
mCursorState.selectionSize = 0;
|
|
mCursorState.offset = 0;
|
|
mCursorState.cell = 0;
|
|
mCursorState.undoState = 0;
|
|
memset( mCursorState.data, 0, sizeof(mCursorState.data) );
|
|
mCursorState.charValid = false;
|
|
}
|
|
else
|
|
{
|
|
mCursorState.valid = true;
|
|
mCursorState.selectionOffset = mSelect.start();
|
|
mCursorState.selectionSize = mSelect.size();
|
|
mCursorState.offset = cursorOffset();
|
|
mCursorState.cell = cursorBit();
|
|
mCursorState.undoState = undoState();
|
|
|
|
for( uint i = 0; i < sizeof( mCursorState.data ); i++ )
|
|
{
|
|
mCursorState.data[i] = (mCursorState.offset+i >= mDocumentSize) ? 0 :
|
|
(unsigned char)data()[mCursorState.offset+i];
|
|
}
|
|
|
|
mCursorState.charValid = mCharValid[ mCursorState.data[0] ];
|
|
}
|
|
return( mCursorState );
|
|
}
|
|
|
|
|
|
inline void CHexBuffer::valueOnCursor( TQByteArray &buf, uint size )
|
|
{
|
|
int offset = cursorOffset();
|
|
if( offset + size >= mDocumentSize )
|
|
{
|
|
size = mDocumentSize - offset;
|
|
}
|
|
|
|
buf.resize(size);
|
|
for( uint i=0; i<buf.size(); i++)
|
|
{
|
|
buf[i] = (unsigned char)data()[offset+i];
|
|
}
|
|
}
|
|
|
|
|
|
inline const SDisplayLayout &CHexBuffer::tqlayout( void )
|
|
{
|
|
return( mLayout );
|
|
}
|
|
|
|
|
|
|
|
inline const SDisplayInputMode &CHexBuffer::inputMode( void )
|
|
{
|
|
return( mInputMode );
|
|
}
|
|
|
|
inline TQPtrList<SCursorOffset> &CHexBuffer::bookmarkList( void )
|
|
{
|
|
return( mBookmarkList );
|
|
}
|
|
|
|
|
|
|
|
|
|
inline SFileState &CHexBuffer::fileState( void )
|
|
{
|
|
if( size() == 0 )
|
|
{
|
|
mFileState.valid = false;
|
|
mFileState.size = 0;
|
|
mFileState.modified = false;
|
|
|
|
}
|
|
else
|
|
{
|
|
mFileState.valid = true;
|
|
mFileState.size = mDocumentSize;
|
|
mFileState.modified = mDocumentModified;
|
|
}
|
|
|
|
return( mFileState );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline bool CHexBuffer::modified( void )
|
|
{
|
|
return( mDocumentModified );
|
|
}
|
|
|
|
inline void CHexBuffer::setModified( bool modified )
|
|
{
|
|
mDocumentModified = modified;
|
|
}
|
|
|
|
inline uint CHexBuffer::undoState( void )
|
|
{
|
|
return( (mUndoIndex > 0 ? UndoOk : 0) |
|
|
(mUndoIndex < mUndoList.count() ? RedoOk : 0) );
|
|
}
|
|
|
|
|
|
inline uint CHexBuffer::documentSize( void )
|
|
{
|
|
return( mDocumentSize );
|
|
}
|
|
|
|
|
|
inline CHexBuffer::EEditMode CHexBuffer::editMode( void )
|
|
{
|
|
return( mEditMode );
|
|
}
|
|
|
|
|
|
inline const SEncodeState &CHexBuffer::encoding( void )
|
|
{
|
|
return( mEncode.state() );
|
|
}
|
|
|
|
inline bool CHexBuffer::losslessEncoding( CConversion::EMode mode )
|
|
{
|
|
return( mEncode.lossless(mode) );
|
|
}
|
|
|
|
inline TQString &CHexBuffer::url( void )
|
|
{
|
|
return( mUrl );
|
|
}
|
|
|
|
inline bool CHexBuffer::documentPresent( void )
|
|
{
|
|
return( size() == 0 ? false : true );
|
|
}
|
|
|
|
inline void CHexBuffer::setUrl( const TQString &url )
|
|
{
|
|
mUrl = url;
|
|
}
|
|
|
|
inline const TQDateTime &CHexBuffer::diskModifyTime( void )
|
|
{
|
|
return( mDiskModifyTime );
|
|
}
|
|
|
|
inline uint CHexBuffer::calculateLine( uint offset )
|
|
{
|
|
return( mLayout.lineSize == 0 ? 0 : offset / mLayout.lineSize );
|
|
}
|
|
|
|
inline const TQColor &CHexBuffer::foregroundColor( uint column )
|
|
{
|
|
if( column > mLayout.lineSize )
|
|
{
|
|
return( TQt::black );
|
|
}
|
|
else
|
|
{
|
|
return( mColor.primaryFg[ mColorIndex[ column ] ] );
|
|
}
|
|
}
|
|
|
|
inline bool CHexBuffer::selectionSet( uint offset, bool init )
|
|
{
|
|
if( offset >= size() ) { offset = size() > 0 ? size() - 1 : 0; }
|
|
|
|
if( init == true )
|
|
{
|
|
return( mSelect.init( offset ) );
|
|
}
|
|
else
|
|
{
|
|
return( mSelect.set( offset ) );
|
|
}
|
|
}
|
|
|
|
inline void CHexBuffer::selectionSyncronize( void )
|
|
{
|
|
mSelect.sync();
|
|
}
|
|
|
|
inline void CHexBuffer::selectionStartChange( uint &offset1, uint &offset2 )
|
|
{
|
|
mSelect.startChange( offset1, offset2 );
|
|
}
|
|
|
|
inline void CHexBuffer::selectionStopChange( uint &offset1, uint &offset2 )
|
|
{
|
|
mSelect.stopChange( offset1, offset2 );
|
|
}
|
|
|
|
inline bool CHexBuffer::cursorInsideSelection( void )
|
|
{
|
|
return( mSelect.inside( cursorOffset() ) );
|
|
}
|
|
|
|
inline void CHexBuffer::markSet( uint offset, uint size )
|
|
{
|
|
markSet( offset, true );
|
|
markSet( offset+size, false );
|
|
mMark.sync();
|
|
}
|
|
|
|
inline bool CHexBuffer::markSet( uint offset, bool init )
|
|
{
|
|
if( offset >= size() ) { offset = size() > 0 ? size() - 1 : 0; }
|
|
|
|
if( init == true )
|
|
{
|
|
return( mMark.init( offset ) );
|
|
}
|
|
else
|
|
{
|
|
return( mMark.set( offset ) );
|
|
}
|
|
}
|
|
|
|
inline bool CHexBuffer::markRemove( void )
|
|
{
|
|
return( mMark.init( mMark.start() ) );
|
|
}
|
|
|
|
|
|
inline void CHexBuffer::markSyncronize( void )
|
|
{
|
|
mMark.sync();
|
|
}
|
|
|
|
inline void CHexBuffer::markStartChange( uint &offset1, uint &offset2 )
|
|
{
|
|
mMark.startChange( offset1, offset2 );
|
|
}
|
|
|
|
inline void CHexBuffer::markStopChange( uint &offset1, uint &offset2 )
|
|
{
|
|
mMark.stopChange( offset1, offset2 );
|
|
}
|
|
|
|
|
|
inline uint CHexBuffer::cursorOffset( void )
|
|
{
|
|
return( mCursor.curr.offset );
|
|
}
|
|
|
|
inline uint CHexBuffer::cursorBit( void )
|
|
{
|
|
return( mCursor.bit() );
|
|
}
|
|
|
|
|
|
inline uint CHexBuffer::cursorLine( void )
|
|
{
|
|
return( mCursor.curr.y / lineHeight() );
|
|
}
|
|
|
|
inline uint CHexBuffer::prevCursorLine( void )
|
|
{
|
|
return( mCursor.prev.y / lineHeight() );
|
|
}
|
|
|
|
inline SCursor &CHexBuffer::cursor( void )
|
|
{
|
|
return( mCursor );
|
|
}
|
|
|
|
|
|
inline void CHexBuffer::currCursor( EEditArea editArea, SCursorPosition &p )
|
|
{
|
|
if( editArea == edit_primary )
|
|
{
|
|
if( mActiveEditor == edit_primary )
|
|
{
|
|
p.x = mCursor.curr.drawX1();
|
|
p.w = mCursor.curr.width1();
|
|
}
|
|
else
|
|
{
|
|
p.x = mCursor.curr.drawX2();
|
|
p.w = mUnitWidth;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( mActiveEditor == edit_primary )
|
|
{
|
|
p.x = mCursor.curr.drawX2();
|
|
p.w = mUnitWidth;
|
|
}
|
|
else
|
|
{
|
|
p.x = mCursor.curr.drawX1();
|
|
p.w = mUnitWidth * mNumCell;
|
|
}
|
|
}
|
|
|
|
p.x -= mStartX;
|
|
p.y = mCursor.curr.y - mStartY;
|
|
p.h = lineHeight();
|
|
|
|
}
|
|
|
|
inline void CHexBuffer::prevCursor( EEditArea editArea, SCursorPosition &p )
|
|
{
|
|
if( editArea == edit_primary )
|
|
{
|
|
if( mActiveEditor == edit_primary )
|
|
{
|
|
p.x = mCursor.prev.drawX1();
|
|
p.w = mUnitWidth * mNumCell;
|
|
}
|
|
else
|
|
{
|
|
p.x = mCursor.prev.drawX2();
|
|
p.w = mUnitWidth;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( mActiveEditor == edit_primary )
|
|
{
|
|
p.x = mCursor.prev.drawX2();
|
|
p.w = mUnitWidth;
|
|
}
|
|
else
|
|
{
|
|
p.x = mCursor.prev.drawX1();
|
|
p.w = mUnitWidth * mNumCell;
|
|
}
|
|
}
|
|
|
|
p.x -= mStartX;
|
|
p.y = mCursor.prev.y - mStartY;
|
|
p.h = lineHeight();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline void CHexBuffer::cursorUp( uint lines )
|
|
{
|
|
mCursor.up( lines );
|
|
cursorCompute();
|
|
}
|
|
|
|
inline void CHexBuffer::cursorDown( uint lines )
|
|
{
|
|
mCursor.down( lines );
|
|
cursorCompute();
|
|
}
|
|
|
|
|
|
inline void CHexBuffer::cursorRight( bool cellLevel )
|
|
{
|
|
if( cellLevel == true && mActiveEditor == edit_primary )
|
|
{
|
|
mCursor.incCell();
|
|
}
|
|
else
|
|
{
|
|
mCursor.addOffset( 1 );
|
|
}
|
|
cursorCompute();
|
|
}
|
|
|
|
|
|
inline void CHexBuffer::cursorStep( uint size, bool forward, bool modulo )
|
|
{
|
|
if( forward == true )
|
|
{
|
|
if( modulo == true )
|
|
{
|
|
uint offset = mCursor.getOffset() + size;
|
|
mCursor.setOffset( offset - offset % size );
|
|
}
|
|
else
|
|
{
|
|
mCursor.addOffset( size );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( modulo == true )
|
|
{
|
|
uint offset = mCursor.getOffset();
|
|
if( offset % size )
|
|
{
|
|
mCursor.decOffset( offset % size, false );
|
|
}
|
|
else
|
|
{
|
|
mCursor.setOffset( offset < size ? 0 : offset - size );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mCursor.decOffset( size, false );
|
|
}
|
|
}
|
|
cursorCompute();
|
|
}
|
|
|
|
|
|
inline void CHexBuffer::cursorLeft( bool cellLevel )
|
|
{
|
|
if( cellLevel == true && mActiveEditor == edit_primary )
|
|
{
|
|
mCursor.decCell();
|
|
}
|
|
else
|
|
{
|
|
mCursor.decOffset( 1, false );
|
|
}
|
|
cursorCompute();
|
|
}
|
|
|
|
inline void CHexBuffer::cursorHome( bool toExtreme )
|
|
{
|
|
mCursor.home( toExtreme );
|
|
cursorCompute();
|
|
}
|
|
|
|
inline void CHexBuffer::cursorEnd( bool toExtreme )
|
|
{
|
|
mCursor.end( toExtreme );
|
|
cursorCompute();
|
|
}
|
|
|
|
|
|
inline void CHexBuffer::cursorGoto( uint offset, uint bit, bool backward,
|
|
bool fromCursor )
|
|
{
|
|
uint maxOffset = mFixedSizeMode == true ? mMaximumSize-1 : documentSize();
|
|
mCursor.setOffset( offset, bit, backward, fromCursor, maxOffset );
|
|
cursorCompute();
|
|
}
|
|
|
|
inline void CHexBuffer::cursorGoto( uint offset, uint bit )
|
|
{
|
|
mCursor.setOffset( offset );
|
|
mCursor.setBit( bit );
|
|
cursorCompute();
|
|
}
|
|
|
|
inline bool CHexBuffer::cursorChanged( void )
|
|
{
|
|
return( mCursor.changed() );
|
|
}
|
|
|
|
inline void CHexBuffer::cursorResetEditArea( void )
|
|
{
|
|
mCursor.setArea( edit_none );
|
|
}
|
|
|
|
inline bool CHexBuffer::cursorPrimaryEdit( void )
|
|
{
|
|
return( mActiveEditor == edit_primary ? true : false );
|
|
}
|
|
|
|
inline int CHexBuffer::cursorFixedPosition( int position, int height )
|
|
{
|
|
position += mCursor.curr.y - mCursor.prev.y;
|
|
if( position < 0 )
|
|
{
|
|
return( 0 );
|
|
}
|
|
else if( position + height > totalHeight() )
|
|
{
|
|
return( height > totalHeight() ? 0 : totalHeight() - height );
|
|
}
|
|
else
|
|
{
|
|
if( mCursor.curr.y < position )
|
|
{
|
|
return( mCursor.curr.y );
|
|
}
|
|
else if( mCursor.curr.y > position + height )
|
|
{
|
|
return( mCursor.curr.y - height + lineHeight() );
|
|
}
|
|
else
|
|
{
|
|
return( position );
|
|
}
|
|
}
|
|
}
|
|
|
|
inline int CHexBuffer::cursorChangePosition( int position, int height )
|
|
{
|
|
if( mCursor.curr.y < position || mCursor.curr.y > position + height )
|
|
{
|
|
// When cursor is at top of window
|
|
position = mCursor.curr.y;
|
|
}
|
|
else if( mCursor.curr.y > position + height - lineHeight() )
|
|
{
|
|
// When cursor is at bottom of window
|
|
position = mCursor.curr.y - height + lineHeight();
|
|
}
|
|
|
|
return( position );
|
|
}
|
|
|
|
inline int CHexBuffer::printDummyCell( char *buf, unsigned char )
|
|
{
|
|
buf[0] = 0;
|
|
return( 0 );
|
|
}
|
|
|
|
inline int CHexBuffer::printHexadecimalBigCell( char *buf, unsigned char data )
|
|
{
|
|
buf[0] = mHexBigBuffer[ (data>>4)&0x0F ];
|
|
buf[1] = mHexBigBuffer[ data&0x0F ];
|
|
return( 0 );
|
|
}
|
|
|
|
inline int CHexBuffer::printHexadecimalSmallCell( char *buf,
|
|
unsigned char data )
|
|
{
|
|
buf[0] = mHexSmallBuffer[ (data>>4)&0x0F ];
|
|
buf[1] = mHexSmallBuffer[ data&0x0F ];
|
|
return( 0 );
|
|
}
|
|
|
|
|
|
inline int CHexBuffer::printDecimalCell( char *buf, unsigned char data )
|
|
{
|
|
buf[0] = mDecBuffer[ data/100 ];
|
|
data -= (data/100) * 100;
|
|
buf[1] = mDecBuffer[ data/10 ];
|
|
data -= (data/10) * 10;
|
|
buf[2] = mDecBuffer[ data ];
|
|
return( 0 );
|
|
}
|
|
|
|
inline int CHexBuffer::printOctalCell( char *buf, unsigned char data )
|
|
{
|
|
buf[0] = mOctBuffer[ (data>>6)&0x07 ];
|
|
buf[1] = mOctBuffer[ (data>>3)&0x07 ];
|
|
buf[2] = mOctBuffer[ data&0x07 ];
|
|
return( 0 );
|
|
}
|
|
|
|
inline int CHexBuffer::printBinaryCell( char *buf, unsigned char data )
|
|
{
|
|
for( int i = 0; i < 8; i++ )
|
|
{
|
|
buf[7-i] = (data&(1<<i)) ? '1' : '0';
|
|
}
|
|
return( 0 );
|
|
}
|
|
|
|
inline int CHexBuffer::printAsciiCell( char *buf, unsigned char data )
|
|
{
|
|
if( mCharValid[data] == 0 )
|
|
{
|
|
buf[0] = mFontInfo.nonPrintChar;
|
|
return( 1 );
|
|
}
|
|
else
|
|
{
|
|
buf[0] = data;
|
|
return( 0 );
|
|
}
|
|
}
|
|
|
|
inline void CHexBuffer::printDummyOffset( char *buf, uint /*offset*/ )
|
|
{
|
|
buf[0] = 0;
|
|
}
|
|
|
|
inline void CHexBuffer::printHexadecimalBigOffset( char *buf, uint offset )
|
|
{
|
|
sprintf( buf, "%04X:%04X", offset>>16, offset&0x0000FFFF );
|
|
}
|
|
|
|
inline void CHexBuffer::printHexadecimalSmallOffset( char *buf, uint offset )
|
|
{
|
|
sprintf( buf, "%04x:%04x", offset>>16, offset&0x0000FFFF );
|
|
}
|
|
|
|
inline void CHexBuffer::printDecimalOffset( char *buf, uint offset )
|
|
{
|
|
sprintf( buf, "%010u", offset );
|
|
}
|
|
|
|
inline int CHexBuffer::lineSize( void )
|
|
{
|
|
return( mLayout.lineSize );
|
|
}
|
|
|
|
inline int CHexBuffer::lineHeight( void )
|
|
{
|
|
return( mFontHeight + mLayout.horzGridWidth );
|
|
}
|
|
|
|
inline int CHexBuffer::fontAscent( void )
|
|
{
|
|
return( mFontAscent );
|
|
}
|
|
|
|
inline int CHexBuffer::lineWidth( void )
|
|
{
|
|
return( mLineWidth );
|
|
}
|
|
|
|
inline int CHexBuffer::unitWidth( void )
|
|
{
|
|
return( mUnitWidth );
|
|
}
|
|
|
|
inline int CHexBuffer::numLines( void )
|
|
{
|
|
return( mNumLines );
|
|
}
|
|
|
|
inline int CHexBuffer::totalHeight( void )
|
|
{
|
|
return( mNumLines * (mFontHeight+mLayout.horzGridWidth) );
|
|
}
|
|
|
|
inline const TQFont &CHexBuffer::font( void )
|
|
{
|
|
return( mFontInfo.font );
|
|
}
|
|
|
|
inline SCursor *CHexBuffer::textCursor( void )
|
|
{
|
|
return( &mCursor );
|
|
}
|
|
|
|
inline const TQColor &CHexBuffer::backgroundColor( void )
|
|
{
|
|
return( documentPresent() == true ? mColor.textBg : mColor.inactiveBg );
|
|
}
|
|
|
|
inline int CHexBuffer::startX( void )
|
|
{
|
|
return( mStartX );
|
|
}
|
|
|
|
inline int CHexBuffer::startY( void )
|
|
{
|
|
return( mStartY );
|
|
}
|
|
|
|
inline void CHexBuffer::setStartX( int val )
|
|
{
|
|
mStartX = val;
|
|
}
|
|
|
|
inline void CHexBuffer::setStartY( int val )
|
|
{
|
|
mStartY = val;
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|