diff options
Diffstat (limited to 'khexedit/lib/kbuffercursor.cpp')
-rw-r--r-- | khexedit/lib/kbuffercursor.cpp | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/khexedit/lib/kbuffercursor.cpp b/khexedit/lib/kbuffercursor.cpp new file mode 100644 index 0000000..0255d2d --- /dev/null +++ b/khexedit/lib/kbuffercursor.cpp @@ -0,0 +1,365 @@ +/*************************************************************************** + kbuffercursor.cpp - description + ------------------- + begin : Don Mai 29 2003 + copyright : (C) 2003 by Friedrich W. H. Kossebau + email : Friedrich.W.H@Kossebau.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License version 2 as published by the Free Software Foundation. * + * * + ***************************************************************************/ + + +//#include <kdebug.h> + +// lib specific +#include "kbufferlayout.h" +#include "kbuffercursor.h" + +using namespace KHE; + +KBufferCursor::KBufferCursor( const KBufferLayout *L ) + : Layout( L ), + Index( 0 ), + Coord( 0, 0 ), + Behind( false ), + AppendPosEnabled( false ) +{ +} + +KBufferCursor::~KBufferCursor() +{ +} + + +bool KBufferCursor::operator==( const KBufferCursor &C ) const +{ + return Index == C.Index && Behind == C.Behind ; +} + + +void KBufferCursor::setAppendPosEnabled( bool APE ) +{ + if( AppendPosEnabled == APE ) + return; + + AppendPosEnabled = APE; + // reposition Cursor + int Length = Layout->length(); + // behind buffer end, not end of line and not empty? + if( realIndex() >= Length && Coord.pos() < Layout->noOfBytesPerLine()-1 && Length > 0 ) + { + if( AppendPosEnabled ) + { + ++Index; + Coord.goRight(); + Behind = false; + } + else + { + --Index; + Coord.goLeft(); + Behind = true; + } + } +} + + +void KBufferCursor::gotoPreviousByte() +{ + if( Behind ) + Behind = false; + else if( Index > 0 ) + { + --Index; + Coord.goCLeft( Layout->noOfBytesPerLine()-1 ); + } +} + + +void KBufferCursor::gotoPreviousByte( int D ) +{ + if( Behind ) + { + --D; + Behind = false; + } + if( D > Index ) + { + if( Index == 0 ) + return; + gotoStart(); + } + gotoIndex( Index - D ); +} + + +void KBufferCursor::gotoNextByte() +{ + int Length = Layout->length(); + + if( Index < Length ) + { + if( Index == Length-1 ) + stepToEnd(); + else + { + ++Index; + Coord.goCRight( Layout->noOfBytesPerLine()-1 ); + Behind = false; + } + } +} + + +void KBufferCursor::gotoNextByte( int D ) // TODO: think about consistency with gotoNextByte!!! +{ + if( Behind ) + { + ++D; + Behind = false; + } + // would we end behind the end? + if( Index+D >= Layout->length() ) + gotoEnd(); + else + gotoIndex( Index + D ); +} + + +void KBufferCursor::gotoNextByteInLine() +{ + int Length = Layout->length(); + + if( Index < Length ) + { + if( Index == Length-1 ) + stepToEnd(); + else + { + ++Index; + + if( Coord.pos() < Layout->noOfBytesPerLine()-1 ) + Coord.goRight(); + else + Behind = true; + } + } +} + + +void KBufferCursor::gotoUp() +{ + // can we even go up? + if( Coord.isBelow(Layout->startLine()) ) + { + Coord.goUp(); + if( Coord.isPriorInLineThan(Layout->start()) ) + { + Index = 0; + Coord.setPos( Layout->startPos() ); + Behind = false; + } + else + { + Index -= Layout->noOfBytesPerLine(); + if( Behind && !atLineEnd() ) + { + ++Index; + Coord.goRight(); + Behind = false; + } + } + } +} + + +void KBufferCursor::gotoDown() +{ + if( Coord.isAbove(Layout->finalLine()) ) + { + Coord.goDown(); + // behind End? + if( Coord.isLaterInLineThan(Layout->final()) ) + gotoEnd(); + else + Index += Layout->noOfBytesPerLine(); + } +} + + +void KBufferCursor::gotoLineStart() +{ + int OldIndex = Index; + Index = Layout->indexAtLineStart( Coord.line() ); + Coord.goLeft( OldIndex-Index ); + Behind = false; +} + + +void KBufferCursor::gotoLineEnd() +{ + if( Index < Layout->length() ) + { + int OldIndex = Index; + Index = Layout->indexAtLineEnd( Coord.line() ); + Coord.goRight( Index-OldIndex ); + + stepToEnd(); + } +} + + +void KBufferCursor::gotoStart() +{ + Index = 0; + Coord = Layout->start(); + Behind = false; +} + + +void KBufferCursor::gotoEnd() +{ + int Length = Layout->length(); + if( Length > 0 ) + { + Index = Length-1; + Coord = Layout->final(); + + stepToEnd(); + } + else + gotoStart(); +} + + +void KBufferCursor::gotoCIndex( int i ) +{ + if( Layout->length() > 0 ) + { + Index = Layout->correctIndex( i ); + Coord = Layout->coordOfIndex( Index ); + if( i > Index ) + stepToEnd(); + else + Behind = false; + } + else + gotoStart(); +} + + +void KBufferCursor::gotoCCoord( const KBufferCoord &C ) +{ + if( Layout->length() > 0 ) + { + Coord = Layout->correctCoord( C ); + Index = Layout->indexAtCoord( Coord ); + if( C > Coord ) + stepToEnd(); + else + Behind = false; + } + else + gotoStart(); +} + + +void KBufferCursor::stepToEnd() +{ + if( AppendPosEnabled && (Coord.pos() < Layout->noOfBytesPerLine()-1) ) + { + ++Index; + Coord.goRight(); + Behind = false; + } + else + Behind = true; +} + + +void KBufferCursor::gotoIndex( int i ) +{ + Index = i; + Coord = Layout->coordOfIndex( Index ); + Behind = false; +} + + +void KBufferCursor::gotoRealIndex() +{ + if( Behind ) + { + ++Index; + Coord = Layout->coordOfIndex( Index ); + Behind = false; + } +} + + +void KBufferCursor::gotoCoord( const KBufferCoord &C ) +{ + Index = Layout->indexAtCoord( C ); + Coord = C; + Behind = false; +} + + +void KBufferCursor::updateCoord() +{ + Coord = Layout->coordOfIndex( Index ); +} + +// page down should be: one page minus one line +// -> if in the very first line page down will put the cursor on the same page into the last line +void KBufferCursor::gotoPageUp() +{ + int NoOfLinesPerPage = Layout->noOfLinesPerPage(); + int NewIndex = Index - NoOfLinesPerPage * Layout->noOfBytesPerLine(); + if( NewIndex < 0 ) + gotoStart(); + else + { + Index = NewIndex; + Coord.goUp( NoOfLinesPerPage ); + if( Behind && !atLineEnd() ) + { + ++Index; + Coord.goRight(); + Behind = false; + } + } +} + + +void KBufferCursor::gotoPageDown() +{ + int NoOfLinesPerPage = Layout->noOfLinesPerPage(); + int NewIndex = Index + NoOfLinesPerPage * Layout->noOfBytesPerLine(); + if( NewIndex >= Layout->length() ) + gotoEnd(); + else + { + Index = NewIndex; + Coord.goDown( NoOfLinesPerPage ); + } +} + + +int KBufferCursor::validIndex() const { return Index < Layout->length() ? Index : -1; } +int KBufferCursor::indexAtLineStart() const { return Layout->indexAtLineStart( Coord.line() ); } +int KBufferCursor::indexAtLineEnd() const { return Layout->indexAtLineEnd( Coord.line() ); } + + +bool KBufferCursor::atStart() const { return Index == 0; } +bool KBufferCursor::atEnd() const { return Index == Layout->length() - 1; } +bool KBufferCursor::atAppendPos() const { return realIndex() >= Layout->length(); } + + +bool KBufferCursor::atLineStart() const { return Layout->atLineStart( Coord ); } +bool KBufferCursor::atLineEnd() const { return Layout->atLineEnd( Coord ); } |