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.
366 lines
7.1 KiB
366 lines
7.1 KiB
/***************************************************************************
|
|
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;
|
|
|
|
TDEBufferCursor::TDEBufferCursor( const TDEBufferLayout *L )
|
|
: Layout( L ),
|
|
Index( 0 ),
|
|
Coord( 0, 0 ),
|
|
Behind( false ),
|
|
AppendPosEnabled( false )
|
|
{
|
|
}
|
|
|
|
TDEBufferCursor::~TDEBufferCursor()
|
|
{
|
|
}
|
|
|
|
|
|
bool TDEBufferCursor::operator==( const TDEBufferCursor &C ) const
|
|
{
|
|
return Index == C.Index && Behind == C.Behind ;
|
|
}
|
|
|
|
|
|
void TDEBufferCursor::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 TDEBufferCursor::gotoPreviousByte()
|
|
{
|
|
if( Behind )
|
|
Behind = false;
|
|
else if( Index > 0 )
|
|
{
|
|
--Index;
|
|
Coord.goCLeft( Layout->noOfBytesPerLine()-1 );
|
|
}
|
|
}
|
|
|
|
|
|
void TDEBufferCursor::gotoPreviousByte( int D )
|
|
{
|
|
if( Behind )
|
|
{
|
|
--D;
|
|
Behind = false;
|
|
}
|
|
if( D > Index )
|
|
{
|
|
if( Index == 0 )
|
|
return;
|
|
gotoStart();
|
|
}
|
|
gotoIndex( Index - D );
|
|
}
|
|
|
|
|
|
void TDEBufferCursor::gotoNextByte()
|
|
{
|
|
int Length = Layout->length();
|
|
|
|
if( Index < Length )
|
|
{
|
|
if( Index == Length-1 )
|
|
stepToEnd();
|
|
else
|
|
{
|
|
++Index;
|
|
Coord.goCRight( Layout->noOfBytesPerLine()-1 );
|
|
Behind = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void TDEBufferCursor::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 TDEBufferCursor::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 TDEBufferCursor::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 TDEBufferCursor::gotoDown()
|
|
{
|
|
if( Coord.isAbove(Layout->finalLine()) )
|
|
{
|
|
Coord.goDown();
|
|
// behind End?
|
|
if( Coord.isLaterInLineThan(Layout->final()) )
|
|
gotoEnd();
|
|
else
|
|
Index += Layout->noOfBytesPerLine();
|
|
}
|
|
}
|
|
|
|
|
|
void TDEBufferCursor::gotoLineStart()
|
|
{
|
|
int OldIndex = Index;
|
|
Index = Layout->indexAtLineStart( Coord.line() );
|
|
Coord.goLeft( OldIndex-Index );
|
|
Behind = false;
|
|
}
|
|
|
|
|
|
void TDEBufferCursor::gotoLineEnd()
|
|
{
|
|
if( Index < Layout->length() )
|
|
{
|
|
int OldIndex = Index;
|
|
Index = Layout->indexAtLineEnd( Coord.line() );
|
|
Coord.goRight( Index-OldIndex );
|
|
|
|
stepToEnd();
|
|
}
|
|
}
|
|
|
|
|
|
void TDEBufferCursor::gotoStart()
|
|
{
|
|
Index = 0;
|
|
Coord = Layout->start();
|
|
Behind = false;
|
|
}
|
|
|
|
|
|
void TDEBufferCursor::gotoEnd()
|
|
{
|
|
int Length = Layout->length();
|
|
if( Length > 0 )
|
|
{
|
|
Index = Length-1;
|
|
Coord = Layout->final();
|
|
|
|
stepToEnd();
|
|
}
|
|
else
|
|
gotoStart();
|
|
}
|
|
|
|
|
|
void TDEBufferCursor::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 TDEBufferCursor::gotoCCoord( const TDEBufferCoord &C )
|
|
{
|
|
if( Layout->length() > 0 )
|
|
{
|
|
Coord = Layout->correctCoord( C );
|
|
Index = Layout->indexAtCoord( Coord );
|
|
if( C > Coord )
|
|
stepToEnd();
|
|
else
|
|
Behind = false;
|
|
}
|
|
else
|
|
gotoStart();
|
|
}
|
|
|
|
|
|
void TDEBufferCursor::stepToEnd()
|
|
{
|
|
if( AppendPosEnabled && (Coord.pos() < Layout->noOfBytesPerLine()-1) )
|
|
{
|
|
++Index;
|
|
Coord.goRight();
|
|
Behind = false;
|
|
}
|
|
else
|
|
Behind = true;
|
|
}
|
|
|
|
|
|
void TDEBufferCursor::gotoIndex( int i )
|
|
{
|
|
Index = i;
|
|
Coord = Layout->coordOfIndex( Index );
|
|
Behind = false;
|
|
}
|
|
|
|
|
|
void TDEBufferCursor::gotoRealIndex()
|
|
{
|
|
if( Behind )
|
|
{
|
|
++Index;
|
|
Coord = Layout->coordOfIndex( Index );
|
|
Behind = false;
|
|
}
|
|
}
|
|
|
|
|
|
void TDEBufferCursor::gotoCoord( const TDEBufferCoord &C )
|
|
{
|
|
Index = Layout->indexAtCoord( C );
|
|
Coord = C;
|
|
Behind = false;
|
|
}
|
|
|
|
|
|
void TDEBufferCursor::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 TDEBufferCursor::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 TDEBufferCursor::gotoPageDown()
|
|
{
|
|
int NoOfLinesPerPage = Layout->noOfLinesPerPage();
|
|
int NewIndex = Index + NoOfLinesPerPage * Layout->noOfBytesPerLine();
|
|
if( NewIndex >= Layout->length() )
|
|
gotoEnd();
|
|
else
|
|
{
|
|
Index = NewIndex;
|
|
Coord.goDown( NoOfLinesPerPage );
|
|
}
|
|
}
|
|
|
|
|
|
int TDEBufferCursor::validIndex() const { return Index < Layout->length() ? Index : -1; }
|
|
int TDEBufferCursor::indexAtLineStart() const { return Layout->indexAtLineStart( Coord.line() ); }
|
|
int TDEBufferCursor::indexAtLineEnd() const { return Layout->indexAtLineEnd( Coord.line() ); }
|
|
|
|
|
|
bool TDEBufferCursor::atStart() const { return Index == 0; }
|
|
bool TDEBufferCursor::atEnd() const { return Index == Layout->length() - 1; }
|
|
bool TDEBufferCursor::atAppendPos() const { return realIndex() >= Layout->length(); }
|
|
|
|
|
|
bool TDEBufferCursor::atLineStart() const { return Layout->atLineStart( Coord ); }
|
|
bool TDEBufferCursor::atLineEnd() const { return Layout->atLineEnd( Coord ); }
|