/*************************************************************************** kbufferranges.cpp - description ------------------- begin : Sun Jun 22 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 // lib specific #include "kbufferranges.h" using namespace KHE; TDEBufferRanges::TDEBufferRanges( TDEBufferLayout *L ) : Modified( false ), Layout( L ) { } TDEBufferRanges::~TDEBufferRanges() { } void TDEBufferRanges::reset() { Selection.cancel(); FirstWordSelection.unset(); Marking.unset(); ChangedRanges.clear(); } void TDEBufferRanges::setMarking( KSection M ) { if( Marking == M ) return; Marking = M; addChangedRange( M ); } void TDEBufferRanges::removeFurtherSelections() { for( int i = 1; i < noOfSelections(); ++i ) removeSelection( i ); } void TDEBufferRanges::setSelection( KSection S ) { bool Changed = Selection.isValid(); if( Changed ) addChangedRange( Selection ); Selection = S; addChangedRange( Selection ); } void TDEBufferRanges::setSelectionStart( int StartIndex ) { bool Changed = Selection.isValid(); if( Changed ) addChangedRange( Selection ); Selection.setStart( StartIndex ); } void TDEBufferRanges::setSelectionEnd( int EndIndex ) { KSection OldSelection = Selection; Selection.setEnd( EndIndex ); // TODO: think about rather building a diff of the sections if( !OldSelection.isValid() ) { addChangedRange( Selection ); return; } if( !Selection.isValid() ) { addChangedRange( OldSelection ); return; } if( OldSelection == Selection ) return; int CS_; int CE_; // changes at the end? if( Selection.start() == OldSelection.start() ) { CS_ = OldSelection.end()+1; CE_ = Selection.end(); if( CE_ < CS_ ) { CS_ = Selection.end()+1; CE_ = OldSelection.end(); } } // changes at the start? else if( Selection.end() == OldSelection.end() ) { CS_ = OldSelection.start(); CE_ = Selection.start()-1; if( CE_ < CS_ ) { CS_ = Selection.start(); CE_ = OldSelection.start()-1; } } // change over the anchor else { CS_ = OldSelection.start(); CE_ = Selection.end(); if( CE_ < CS_ ) { CS_ = Selection.start(); CE_ = OldSelection.end(); } } KSection C( CS_, CE_ ); bool Changed = C.isValid(); if( Changed ) addChangedRange( C ); return; } void TDEBufferRanges::removeSelection( int id ) { if( id > 0 ) return; bool Changed = Selection.isValid(); if( Changed ) addChangedRange( Selection ); Selection.cancel(); FirstWordSelection.unset(); } bool TDEBufferRanges::overlapsSelection( int FirstIndex, int LastIndex, int *SI, int *EI ) const { if( Selection.overlaps(KSection(FirstIndex,LastIndex)) ) { *SI = Selection.start(); *EI = Selection.end(); return true; } return false; } bool TDEBufferRanges::overlapsMarking( int FirstIndex, int LastIndex, int *SI, int *EI ) const { if( Marking.overlaps(KSection(FirstIndex,LastIndex)) ) { *SI = Marking.start(); *EI = Marking.end(); return true; } return false; } const KSection *TDEBufferRanges::firstOverlappingSelection( KSection Range ) const { if( Selection.overlaps(Range) ) return &Selection; return 0L; } const KSection *TDEBufferRanges::overlappingMarking( KSection Range ) const { if( Marking.overlaps(Range) ) return &Marking; return 0L; } /* bool TDEBufferRanges::overlapsChanges( int FirstIndex, int LastIndex, int *SI, int *EI ) const { for( KCoordRangeList::const_iterator S=ChangedRanges.begin(); S!=ChangedRanges.end(); ++S ) { if( (*S).overlaps(KBuff(FirstIndex,LastIndex)) ) { *SI = (*S).start(); *EI = (*S).end(); return true; } } return false; } bool TDEBufferRanges::overlapsChanges( KSection Indizes, KSection *ChangedRange ) const { for( KSectionList::const_iterator S=ChangedRanges.begin(); S!=ChangedRanges.end(); ++S ) { if( (*S).overlaps(Indizes) ) { *ChangedRange = *S; return true; } } return false; } */ bool TDEBufferRanges::overlapsChanges( const KCoordRange &Range, KCoordRange *ChangedRange ) const { // TODO: add a lastusedrange pointer for quicker access for( KCoordRangeList::const_iterator R=ChangedRanges.begin(); R!=ChangedRanges.end(); ++R ) { if( (*R).overlaps(Range) ) { *ChangedRange = *R; return true; } } return false; } void TDEBufferRanges::addChangedRange( int SI, int EI ) { addChangedRange( KSection(SI,EI) ); } void TDEBufferRanges::addChangedRange( KSection S ) { addChangedRange( KCoordRange(Layout->coordOfIndex(S.start()),Layout->coordOfIndex(S.end())) ); } void TDEBufferRanges::addChangedRange( const KCoordRange &NewRange ) { ChangedRanges.addCoordRange( NewRange ); Modified = true; } void TDEBufferRanges::removeMarking() { bool Changed = Marking.isValid(); if( Changed ) addChangedRange( Marking ); Marking.unset(); } void TDEBufferRanges::resetChangedRanges() { ChangedRanges.clear(); Modified = false; } void TDEBufferRanges::setFirstWordSelection( KSection Section ) { FirstWordSelection = Section; setSelection( FirstWordSelection ); } void TDEBufferRanges::ensureWordSelectionForward( bool Forward ) { // in the anchor not on the right side? if( Selection.isForward() != Forward ) { if( Forward ) { setSelectionEnd( FirstWordSelection.start() ); Selection.setForward(); } else { setSelectionEnd( FirstWordSelection.end()+1 ); Selection.setBackward(); } } }