2000-02-25 11:04:07 +00:00
// ------------------------------------------------------------------
// GoldED+
// Copyright (C) 1990-1999 Odinn Sorensen
// Copyright (C) 1999-2000 Alexander S. Aganichev
// ------------------------------------------------------------------
// 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., 59 Temple Place, Suite 330, Boston,
// MA 02111-1307 USA
// ------------------------------------------------------------------
// $Id$
// ------------------------------------------------------------------
// The Internal Editor (IE), part 1.
// ------------------------------------------------------------------
# ifdef __GNUG__
# pragma implementation "geedit.h"
# endif
// ------------------------------------------------------------------
# include <golded.h>
# include <geedit.h>
2005-10-06 17:50:55 +00:00
gkey kbxget_raw ( int mode ) ;
2000-02-25 11:04:07 +00:00
// ------------------------------------------------------------------
// Globals
Line * Edit__killbuf = NULL ;
Line * Edit__pastebuf = NULL ;
Path Edit__exportfilename = { " " } ;
UndoItem * * UndoItem : : last_item ;
// ------------------------------------------------------------------
# ifndef NDEBUG
void IEclass : : debugtest ( char * __test , int __a , int __b , char * __file , int __line , int __values ) {
# if defined(GFTRK_ENABLE)
int _tmp = __gftrk_on ;
__gftrk_on = false ;
# endif
savefile ( MODE_UPDATE ) ;
# if defined(GFTRK_ENABLE)
__gftrk_on = _tmp ;
# endif
if ( __values )
w_infof ( " Range check: (%s) <%i,%i> [%s,%u] " , __test , __a , __b , __file , __line ) ;
else
w_infof ( " Range check: (%s) [%s,%u] " , __test , __file , __line ) ;
update_statusline ( LNG - > EscOrContinue ) ;
SayBibi ( ) ;
while ( kbxhit ( ) )
kbxget ( ) ;
gkey _key = kbxget ( ) ;
w_info ( NULL ) ;
if ( _key = = Key_Esc ) {
LOG . errtest ( __file , __line ) ;
LOG . printf ( " ! An internal editor range check failed. " ) ;
if ( __values )
LOG . printf ( " : Details: (%s) <%i,%i>. " , __test , __a , __b ) ;
2003-01-04 10:16:47 +00:00
else {
2000-02-25 11:04:07 +00:00
LOG . printf ( " : Details: (%s). " , __test ) ;
LOG . printf ( " : Details: r%u,c%u,mr%u,mc%u,i%u,dm%u,qm%u,eqm%u. " ,
2003-01-04 10:16:47 +00:00
row , col , maxrow , maxcol , insert ,
CFG - > dispmargin , CFG - > quotemargin , EDIT - > QuoteMargin ( ) ) ;
}
2000-02-25 11:04:07 +00:00
LOG . printf ( " + Advice: Report to the Author. " ) ;
TestErrorExit ( ) ;
}
}
# endif
2005-11-28 20:06:38 +00:00
// ------------------------------------------------------------------
2006-03-11 17:04:06 +00:00
# if defined(GCFG_SPELL_INCLUDED)
2005-11-28 20:06:38 +00:00
inline bool isscchar ( int c )
{
return isxalnum ( c ) | | ( c = = ' - ' ) | | ( c = = ' \' ' ) | | ( c = = ' . ' ) ;
}
# endif
2000-02-25 11:04:07 +00:00
// ------------------------------------------------------------------
// Make sure line type is correct
void IEclass : : setlinetype ( Line * __line ) {
_test_halt ( __line = = NULL ) ;
2001-10-17 04:04:19 +00:00
__line - > type & = ~ ( GLINE_ALL | GLINE_TEAR | GLINE_ORIG | GLINE_TAGL ) ;
2005-10-16 03:41:29 +00:00
if ( is_quote ( __line - > txt . c_str ( ) ) & &
is_quote2 ( __line , __line - > txt . c_str ( ) ) )
{
__line - > type | = GLINE_QUOT ;
}
else if ( __line - > txt [ 0 ] = = CTRL_A )
{
__line - > type | = GLINE_HIDD ;
}
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
// Insert character in string at position
// ------------------------------------------------------------------
// Zero-based
2006-01-13 14:26:31 +00:00
vattr IEclass : : dispchar ( vchar __ch , vattr attr ) {
2000-02-25 11:04:07 +00:00
2001-01-27 11:52:13 +00:00
if ( __ch = = NUL ) // possible if line empty
2000-05-22 17:17:43 +00:00
__ch = ' ' ;
2001-05-20 12:23:00 +00:00
if ( __ch = = ' \n ' ) {
2000-02-25 11:04:07 +00:00
__ch = EDIT - > CharPara ( ) ;
}
2001-05-20 12:23:00 +00:00
else if ( __ch = = ' ' ) {
__ch = EDIT - > CharSpace ( ) ;
}
2000-02-25 11:04:07 +00:00
2006-01-13 14:26:31 +00:00
vattr atr ;
2000-02-25 11:04:07 +00:00
vchar chr ;
editwin . getc ( crow , ccol , & atr , & chr ) ;
2006-01-13 14:26:31 +00:00
editwin . printc ( crow , ccol , attr = = DEFATTR ? atr : attr , __ch ) ;
2000-02-25 11:04:07 +00:00
return atr ;
}
// ------------------------------------------------------------------
2006-01-14 23:48:53 +00:00
void IEclass : : cursoroff ( ) {
2000-02-25 11:04:07 +00:00
vcurhide ( ) ;
}
// ------------------------------------------------------------------
2006-01-14 23:48:53 +00:00
void IEclass : : cursoron ( ) {
2000-02-25 11:04:07 +00:00
vcurshow ( ) ;
}
// ------------------------------------------------------------------
// Zero-based
void IEclass : : scrollup ( int __scol , int __srow , int __ecol , int __erow , int __lines ) {
editwin . scroll_box_up ( __srow , __scol , __erow , __ecol , __lines ) ;
}
// ------------------------------------------------------------------
// Zero-based
void IEclass : : scrolldown ( int __scol , int __srow , int __ecol , int __erow , int __lines ) {
editwin . scroll_box_down ( __srow , __scol , __erow , __ecol , __lines ) ;
}
// ------------------------------------------------------------------
// Zero-based
2006-01-13 14:26:31 +00:00
void IEclass : : prints ( int wrow , int wcol , vattr atr , const char * str ) {
2000-02-25 11:04:07 +00:00
editwin . prints ( wrow , wcol , atr , str ) ;
}
// ------------------------------------------------------------------
Line * IEclass : : findfirstline ( ) {
GFTRK ( " Editfindfirstline " ) ;
if ( not currline )
return NULL ;
// Rewind to the first line
Line * _firstline = currline ;
while ( _firstline - > prev )
_firstline = _firstline - > prev ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
return _firstline ;
}
// ------------------------------------------------------------------
// Find out what number the current line is and put it in "thisrow"
void IEclass : : getthisrow ( Line * __currline ) {
GFTRK ( " Editgetthisrow " ) ;
Line * _templine = findfirstline ( ) ;
thisrow = 0 ;
while ( ( _templine ! = __currline ) and _templine - > next ) {
_templine = _templine - > next ;
thisrow + + ;
}
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
// Zero-based
void IEclass : : gotorowcol ( uint __col , uint __row ) {
GFTRK ( " Editgotorowcol " ) ;
_test_haltab ( __col > maxcol , __col , maxcol ) ;
_test_haltab ( __row > maxrow , __row , maxrow ) ;
editwin . move_cursor ( __row , __col ) ;
ccol = __col ;
crow = __row ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
2005-11-28 20:06:38 +00:00
// ------------------------------------------------------------------
2006-03-11 17:04:06 +00:00
# if defined(GCFG_SPELL_INCLUDED)
2005-11-28 20:06:38 +00:00
void IEclass : : dispstringsc ( char * __buf , uint __beg , uint __end , uint __row , uint __col , char endchar )
{
char scbuf [ EDIT_BUFLEN ] ;
2006-01-14 23:48:53 +00:00
2005-11-28 20:06:38 +00:00
uint bbeg = __beg ;
uint bend = __beg ;
uint bpos = __beg ;
if ( ( bbeg > 0 ) & & isscchar ( __buf [ bbeg ] ) & & isscchar ( __buf [ bbeg - 1 ] ) )
{
for ( ; ( bpos < __end ) & & isscchar ( __buf [ bpos ] ) ; bpos + + ) ;
bend = bpos ;
}
while ( bpos < __end )
{
for ( ; ( bpos < __end ) & & ! isscchar ( __buf [ bpos ] ) ; bpos + + ) ;
bend = bpos ;
uint scpos = 0 ;
for ( ; ( bpos < __end ) & & isscchar ( __buf [ bpos ] ) ; bpos + + , scpos + + )
scbuf [ scpos ] = __buf [ bpos ] ;
if ( ( scpos = = 0 ) | | ( ( bpos = = __end ) & & isscchar ( endchar ) ) )
{
bend = bpos ;
break ;
}
scbuf [ scpos ] = NUL ;
2006-01-14 23:48:53 +00:00
2005-11-28 20:06:38 +00:00
if ( schecker . Check ( scbuf ) )
bend = bpos ;
else
{
char savechar = __buf [ bend ] ;
__buf [ bend ] = NUL ;
2006-01-13 14:26:31 +00:00
StyleCodeHighlight ( __buf + bbeg , __row , __col + bbeg - __beg , false , DEFATTR ) ;
2005-11-28 20:06:38 +00:00
__buf [ bend ] = savechar ;
bbeg = bend ; bend + = scpos ;
bool oldusestylies = AA - > adat - > usestylies ;
bool oldhighlighturls = CFG - > highlighturls ;
AA - > adat - > usestylies = false ;
CFG - > highlighturls = false ;
savechar = __buf [ bend ] ;
__buf [ bend ] = NUL ;
StyleCodeHighlight ( __buf + bbeg , __row , __col + bbeg - __beg , false , C_SCERROR ) ;
__buf [ bend ] = savechar ;
AA - > adat - > usestylies = oldusestylies ;
CFG - > highlighturls = oldhighlighturls ;
bbeg = bend ;
}
}
if ( bbeg < bend )
2006-01-13 14:26:31 +00:00
StyleCodeHighlight ( __buf + bbeg , __row , __col + bbeg - __beg , false , DEFATTR ) ;
2005-11-28 20:06:38 +00:00
}
// ------------------------------------------------------------------
void IEclass : : dispstring ( Line * line , uint __row )
{
GFTRK ( " Editdispstring " ) ;
// Get string length
uint _length = strlen ( line - > txt . c_str ( ) ) ;
// String longer than window width?
_test_haltab ( _length > ( maxcol + 1 ) , _length , ( maxcol + 1 ) ) ;
_length = MinV ( _length , ( maxcol + 1 ) ) ;
// Buffer for translation to visual representation
char _buf [ EDIT_BUFLEN ] ;
// Space-pad and nul-terminate the buffer
memset ( _buf , ' ' , maxcol + 1 ) ;
_buf [ maxcol + 1 ] = NUL ;
// Copy/translate string into buffer
for ( uint _pos = 0 ; _pos < _length ; _pos + + )
{
char chr = line - > txt [ _pos ] ;
switch ( chr )
{
case ' ' : _buf [ _pos ] = EDIT - > CharSpace ( ) ; break ;
case ' \n ' : _buf [ _pos ] = EDIT - > CharPara ( ) ; break ;
default : _buf [ _pos ] = chr ;
}
}
int selected = 0 ;
uint begblock = 0 ;
uint endblock = 0 ;
Line * fbline = NULL ;
Line * lbline = NULL ;
if ( blockcol ! = - 1 )
{
for ( Line * ln = findfirstline ( ) ; ln ; ln = ln - > next )
{
if ( ln = = currline )
{
if ( selected ) { lbline = ln ; selected ^ = 1 ; endblock = col ; }
else { fbline = ln ; selected ^ = 1 ; begblock = col ; }
}
if ( ln - > type & GLINE_BLOK )
{
if ( selected ) { lbline = ln ; selected ^ = 1 ; endblock = blockcol ; }
else { fbline = ln ; selected ^ = 1 ; begblock = blockcol ; }
}
if ( ln = = line ) { if ( ln = = lbline ) selected = 1 ; break ; }
if ( lbline ) break ;
}
if ( selected )
{
if ( fbline = = lbline )
{
if ( begblock > endblock )
{
int temp = begblock ;
begblock = endblock ;
endblock = temp ;
}
else if ( begblock = = endblock )
begblock = endblock = 0 ;
}
else if ( line = = fbline )
endblock = maxcol + 1 ;
else if ( line = = lbline )
begblock = 0 ;
else
{
begblock = 0 ;
endblock = maxcol + 1 ;
}
}
else
begblock = endblock = 0 ;
}
if ( 0 < begblock )
{
char savechar = _buf [ begblock ] ;
_buf [ begblock ] = NUL ;
if ( ( CFG - > scheckerenabled = = GAUTO ) & & schecker . IsLoaded ( ) & &
! ( line - > type & ( GLINE_TAGL | GLINE_QUOT | GLINE_KLUD | GLINE_TEAR | GLINE_ORIG | GLINE_HIDD ) ) )
{
dispstringsc ( _buf , 0 , begblock , __row , mincol , savechar ) ;
}
else
2006-01-13 14:26:31 +00:00
StyleCodeHighlight ( _buf , __row , mincol , false , DEFATTR ) ;
2005-11-28 20:06:38 +00:00
_buf [ begblock ] = savechar ;
}
if ( begblock < endblock )
{
bool oldusestylies = AA - > adat - > usestylies ;
bool oldhighlighturls = CFG - > highlighturls ;
AA - > adat - > usestylies = false ;
CFG - > highlighturls = false ;
char savechar = _buf [ endblock ] ;
_buf [ endblock ] = NUL ;
StyleCodeHighlight ( _buf + begblock , __row , mincol + begblock , false , C_READA ) ;
_buf [ endblock ] = savechar ;
AA - > adat - > usestylies = oldusestylies ;
CFG - > highlighturls = oldhighlighturls ;
}
if ( endblock < ( maxcol + 1 ) )
{
if ( ( CFG - > scheckerenabled = = GAUTO ) & & schecker . IsLoaded ( ) & &
! ( line - > type & ( GLINE_TAGL | GLINE_QUOT | GLINE_KLUD | GLINE_TEAR | GLINE_ORIG | GLINE_HIDD ) ) )
{
dispstringsc ( _buf , endblock , maxcol + 1 , __row , mincol + endblock , 0 ) ;
}
else
2006-01-13 14:26:31 +00:00
StyleCodeHighlight ( _buf + endblock , __row , mincol + endblock , false , DEFATTR ) ;
2005-11-28 20:06:38 +00:00
}
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2005-11-28 20:06:38 +00:00
}
2006-03-11 17:04:06 +00:00
# else // #if defined(GCFG_SPELL_INCLUDED)
2005-11-28 20:06:38 +00:00
2000-02-25 11:04:07 +00:00
// ------------------------------------------------------------------
2000-03-22 17:59:18 +00:00
void IEclass : : dispstring ( const char * __string , uint __row , int attr , Line * line ) {
2000-02-25 11:04:07 +00:00
GFTRK ( " Editdispstring " ) ;
_test_halt ( __string = = NULL ) ;
_test_haltab ( __row > maxrow , __row , maxrow ) ;
// Get string length
uint _length = strlen ( __string ) ;
// String longer than window width?
_test_haltab ( _length > ( maxcol + 1 ) , _length , ( maxcol + 1 ) ) ;
_length = MinV ( _length , ( maxcol + 1 ) ) ;
// Buffer for translation to visual representation
char _buf [ EDIT_BUFLEN ] ;
// Space-pad and nul-terminate the buffer
memset ( _buf , ' ' , maxcol + 1 ) ;
_buf [ maxcol + 1 ] = NUL ;
// Copy/translate string into buffer
if ( attr = = - 1 ) {
char * _bufptr = _buf ;
uint _position = 0 ;
2000-03-22 17:59:18 +00:00
const char * __str = __string ;
2000-02-25 11:04:07 +00:00
while ( _position < _length ) {
switch ( * __str ) {
case ' ' : * _bufptr = EDIT - > CharSpace ( ) ; break ;
case ' \n ' : * _bufptr = EDIT - > CharPara ( ) ; break ;
default : * _bufptr = * __str ;
}
_position + + ;
_bufptr + + ;
__str + + ;
}
}
else {
2000-06-16 23:30:48 +00:00
if ( _length )
memcpy ( _buf , __string , _length ) ;
2000-02-25 11:04:07 +00:00
}
// mark selected block
if ( line and ( blockcol ! = - 1 ) ) {
int selected = 0 ;
for ( Line * ln = findfirstline ( ) ; ln and ln ! = line ; ln = ln - > next ) {
if ( ln = = currline )
selected ^ = 1 ;
if ( ln - > type & GLINE_BLOK )
selected ^ = 1 ;
}
if ( ( line - > type & GLINE_BLOK ) and ( line = = currline ) ) {
int begblock = ( ( col < blockcol ) ? col : blockcol ) - mincol ;
int endblock = ( ( col > blockcol ) ? col : blockcol ) - mincol ;
char savechar = _buf [ begblock ] ;
_buf [ begblock ] = NUL ;
StyleCodeHighlight ( _buf , __row , mincol , false , attr ) ;
_buf [ begblock ] = savechar ;
savechar = _buf [ endblock ] ;
_buf [ endblock ] = NUL ;
2005-10-03 16:55:00 +00:00
bool oldusestylies = AA - > adat - > usestylies ;
2002-10-11 05:54:11 +00:00
bool oldhighlighturls = CFG - > highlighturls ;
2005-10-03 16:55:00 +00:00
AA - > adat - > usestylies = false ;
2002-10-11 05:54:11 +00:00
CFG - > highlighturls = false ;
2000-02-25 11:04:07 +00:00
StyleCodeHighlight ( _buf + begblock , __row , mincol + begblock , false , C_READA ) ;
2005-10-03 16:55:00 +00:00
AA - > adat - > usestylies = oldusestylies ;
2002-10-11 05:54:11 +00:00
CFG - > highlighturls = oldhighlighturls ;
2000-02-25 11:04:07 +00:00
_buf [ endblock ] = savechar ;
StyleCodeHighlight ( _buf + endblock , __row , mincol + endblock , false , attr ) ;
}
else if ( ( line - > type & GLINE_BLOK ) or ( line = = currline ) ) {
int blockmark = ( ( line - > type & GLINE_BLOK ) ? blockcol : col ) - mincol ;
char savechar = _buf [ blockmark ] ;
_buf [ blockmark ] = NUL ;
2005-10-03 16:55:00 +00:00
bool oldusestylies = AA - > adat - > usestylies ;
2002-10-11 05:54:11 +00:00
bool oldhighlighturls = CFG - > highlighturls ;
if ( selected ) {
2005-10-03 16:55:00 +00:00
AA - > adat - > usestylies = false ;
2002-10-11 05:54:11 +00:00
CFG - > highlighturls = false ;
}
2000-02-25 11:04:07 +00:00
StyleCodeHighlight ( _buf , __row , mincol , false , selected ? C_READA : attr ) ;
2005-10-03 16:55:00 +00:00
AA - > adat - > usestylies = oldusestylies ;
2000-02-25 11:04:07 +00:00
_buf [ blockmark ] = savechar ;
2002-10-11 05:54:11 +00:00
if ( not selected ) {
2005-10-03 16:55:00 +00:00
AA - > adat - > usestylies = false ;
2002-10-11 05:54:11 +00:00
CFG - > highlighturls = false ;
}
2000-02-25 11:04:07 +00:00
StyleCodeHighlight ( _buf + blockmark , __row , mincol + blockmark , false , selected ? attr : C_READA ) ;
2005-10-03 16:55:00 +00:00
AA - > adat - > usestylies = oldusestylies ;
2002-10-11 05:54:11 +00:00
CFG - > highlighturls = oldhighlighturls ;
2000-02-25 11:04:07 +00:00
}
2001-11-04 21:37:03 +00:00
else {
2005-10-03 16:55:00 +00:00
bool oldusestylies = AA - > adat - > usestylies ;
2002-10-11 05:54:11 +00:00
bool oldhighlighturls = CFG - > highlighturls ;
if ( selected ) {
2005-10-03 16:55:00 +00:00
AA - > adat - > usestylies = false ;
2002-10-11 05:54:11 +00:00
CFG - > highlighturls = false ;
}
2000-02-25 11:04:07 +00:00
StyleCodeHighlight ( _buf , __row , mincol , false , selected ? C_READA : attr ) ;
2005-10-03 16:55:00 +00:00
AA - > adat - > usestylies = oldusestylies ;
2002-10-11 05:54:11 +00:00
CFG - > highlighturls = oldhighlighturls ;
2001-11-04 21:37:03 +00:00
}
2000-02-25 11:04:07 +00:00
}
else
StyleCodeHighlight ( _buf , __row , mincol , false , attr ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
2006-03-11 17:04:06 +00:00
# endif // #if defined(GCFG_SPELL_INCLUDED)
2000-02-25 11:04:07 +00:00
// ------------------------------------------------------------------
void IEclass : : setcolor ( Line * __line ) {
// Set window attribute
if ( __line - > type & GLINE_HIDD )
editwin . text_color ( C_READKH ) ;
else if ( __line - > type & GLINE_KLUD )
editwin . text_color ( C_READK ) ;
else if ( __line - > type & GLINE_TAGL )
editwin . text_color ( C_READG ) ;
else if ( __line - > type & GLINE_TEAR )
editwin . text_color ( C_READT ) ;
else if ( __line - > type & GLINE_ORIG )
editwin . text_color ( C_READO ) ;
else if ( __line - > type & GLINE_QUOT )
2000-03-22 17:59:18 +00:00
editwin . text_color ( quotecolor ( __line - > txt . c_str ( ) ) ) ;
2000-02-25 11:04:07 +00:00
else if ( __line - > type & GLINE_SIGN )
editwin . text_color ( C_READS ) ;
else
editwin . text_color ( C_READW ) ;
}
// ------------------------------------------------------------------
// Zero-based
void IEclass : : displine ( Line * __line , uint __row ) {
GFTRK ( " Editdispline " ) ;
_test_halt ( __line = = NULL ) ;
_test_haltab ( __row > maxrow , __row , maxrow ) ;
// Display line
setcolor ( __line ) ;
2006-03-11 17:04:06 +00:00
# if defined(GCFG_SPELL_INCLUDED)
2005-11-28 20:06:38 +00:00
dispstring ( __line , __row ) ;
# else
2000-03-22 17:59:18 +00:00
dispstring ( __line - > txt . c_str ( ) , __row , - 1 , __line ) ;
2005-11-28 20:06:38 +00:00
# endif
2000-02-25 11:04:07 +00:00
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
// Zero-based
void IEclass : : clreol ( int __col , int __row ) {
GFTRK ( " Editclreol " ) ;
if ( __col = = - 1 )
__col = ccol ;
if ( __row = = - 1 )
__row = crow ;
if ( ( uint ) __col < = maxcol )
editwin . fill ( __row , __col , __row , maxcol , ' ' , C_READW ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
// Zero-based
void IEclass : : refresh ( Line * __currline , uint __row ) {
GFTRK ( " Editrefresh " ) ;
_test_halt ( __currline = = NULL ) ;
cursoroff ( ) ;
// Display as many lines as we can
while ( __currline and ( __row < = maxrow ) ) {
displine ( __currline , __row + + ) ;
__currline = __currline - > next ;
}
// If we ran out of lines, blank the rest
2006-03-11 17:04:06 +00:00
# if defined(GCFG_SPELL_INCLUDED)
2005-11-28 20:06:38 +00:00
if ( __row < = maxrow )
editwin . fill ( __row , mincol , __row , maxcol , _box_table ( W_BREAD , 1 ) , C_READB | ACSET ) ;
if ( + + __row < = maxrow )
editwin . fill ( __row , mincol , maxrow , maxcol , ' ' , C_READW ) ;
# else
2000-02-25 11:04:07 +00:00
if ( __row < = maxrow ) {
vchar vbuf [ 256 ] ;
for ( int c = 0 ; c < maxcol + 1 ; c + + )
vbuf [ c ] = _box_table ( W_BREAD , 1 ) ;
vbuf [ maxcol + 1 ] = NUL ;
wprintvs ( __row + + , mincol , C_READB | ACSET , vbuf ) ;
while ( __row < = maxrow )
dispstring ( " " , __row + + ) ;
}
2005-11-28 20:06:38 +00:00
# endif
2000-02-25 11:04:07 +00:00
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
2000-03-22 17:59:18 +00:00
Line * IEclass : : insertlinebelow ( Line * __currline , const char * __text , long __batch_mode ) {
2000-02-25 11:04:07 +00:00
GFTRK ( " Editinsertlinebelow " ) ;
2000-03-22 17:59:18 +00:00
Line * _nextline = new Line ( __text ? __text : " " ) ;
throw_xnew ( _nextline ) ;
2000-02-25 11:04:07 +00:00
if ( __currline ) {
_nextline - > prev = __currline ;
_nextline - > next = __currline - > next ;
if ( _nextline - > next )
_nextline - > next - > prev = _nextline ;
__currline - > next = _nextline ;
}
2006-01-14 23:48:53 +00:00
2000-02-25 11:04:07 +00:00
Undo - > PushItem ( EDIT_UNDO_NEW_LINE | batch_mode | __batch_mode , _nextline ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
return _nextline ;
}
// ------------------------------------------------------------------
// Zero-based
int IEclass : : downoneline ( uint __row ) {
GFTRK ( " Editdownoneline " ) ;
_test_haltab ( __row > maxrow , __row , maxrow ) ;
thisrow + + ;
if ( __row = = maxrow )
scrollup ( mincol , minrow , maxcol , maxrow ) ;
else
__row + + ;
gotorowcol ( mincol , __row ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
return __row ;
}
// ------------------------------------------------------------------
2006-06-05 19:03:19 +00:00
void IEclass : : GoEOL ( )
{
2000-02-25 11:04:07 +00:00
GFTRK ( " EditGoEOL " ) ;
// Move cursor to the last char on the line
2006-06-05 19:03:19 +00:00
if ( mincol ! = ( col = currline - > txt . length ( ) ) )
{
if ( ( currline - > txt [ col - 1 ] = = ' \n ' ) | | ( currline - > txt [ col - 1 ] = = ' ' ) )
- - col ;
}
2000-02-25 11:04:07 +00:00
// String must not be longer than the window width
_test_haltab ( col > maxcol , col , maxcol ) ;
if ( blockcol ! = - 1 )
displine ( currline , row ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : GoUp ( ) {
GFTRK ( " EditGoUp " ) ;
_test_haltab ( row < minrow , row , minrow ) ;
if ( currline - > prev ) {
currline = currline - > prev ;
thisrow - - ;
if ( row = = minrow ) {
scrolldown ( mincol , row , maxcol , maxrow ) ;
if ( blockcol ! = - 1 )
displine ( currline - > next , row + 1 ) ;
displine ( currline , row ) ;
}
else {
row - - ;
if ( blockcol ! = - 1 ) {
displine ( currline - > next , row + 1 ) ;
displine ( currline , row ) ;
}
}
2000-03-22 17:59:18 +00:00
if ( ( col + 1 ) > currline - > txt . length ( ) )
2000-02-25 11:04:07 +00:00
GoEOL ( ) ;
}
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : GoDown ( ) {
GFTRK ( " EditGoDown " ) ;
_test_haltab ( row > maxrow , row , maxrow ) ;
if ( currline - > next ) {
currline = currline - > next ;
thisrow + + ;
if ( row = = maxrow ) {
scrollup ( mincol , minrow , maxcol , maxrow ) ;
if ( blockcol ! = - 1 )
displine ( currline - > prev , row - 1 ) ;
displine ( currline , row ) ;
}
else {
row + + ;
if ( blockcol ! = - 1 ) {
displine ( currline - > prev , row - 1 ) ;
displine ( currline , row ) ;
}
}
2000-03-22 17:59:18 +00:00
if ( ( col + 1 ) > currline - > txt . length ( ) )
2000-02-25 11:04:07 +00:00
GoEOL ( ) ;
}
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : GoLeft ( ) {
GFTRK ( " EditGoLeft " ) ;
_test_haltab ( col < mincol , col , mincol ) ;
if ( col = = mincol ) {
if ( currline - > prev ) {
GoUp ( ) ;
GoEOL ( ) ;
2001-05-20 12:23:00 +00:00
if ( ( col ! = mincol ) and ( currline - > txt . c_str ( ) [ col ] = = NUL ) )
col - - ;
2000-02-25 11:04:07 +00:00
}
}
else
col - - ;
if ( blockcol ! = - 1 )
displine ( currline , row ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : GoRight ( ) {
GFTRK ( " EditGoRight " ) ;
_test_haltab ( col > maxcol , col , maxcol ) ;
2001-05-20 12:23:00 +00:00
if ( ( col = = maxcol ) or ( ( col + 1 ) > = currline - > txt . length ( ) ) ) {
2000-02-25 11:04:07 +00:00
if ( currline - > next ! = NULL ) {
GoDown ( ) ;
col = mincol ;
}
}
else
col + + ;
if ( blockcol ! = - 1 )
displine ( currline , row ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
2001-03-09 14:40:06 +00:00
Line * IEclass : : wrapit ( Line * * __currline , uint * __curr_col , uint * __curr_row , bool __display ) {
2000-02-25 11:04:07 +00:00
_test_halt ( __currline = = NULL ) ;
_test_halt ( * __currline = = NULL ) ;
2001-05-20 12:23:00 +00:00
int scroll = 0 ;
2000-02-25 11:04:07 +00:00
uint _quotelen ;
2001-05-09 20:45:13 +00:00
char _quotebuf [ MAXQUOTELEN ] ;
* _quotebuf = NUL ;
2000-02-25 11:04:07 +00:00
uint _curscol = * __curr_col ;
uint _cursrow = * __curr_row ;
uint _thisrow = * __curr_row ;
Line * _thisline = * __currline ;
Line * _lastadded = _thisline ;
bool _wrapped_above = false ;
// Start wrapping from the current line onwards
while ( _thisline ) {
// Length of this line
2000-03-22 17:59:18 +00:00
uint _thislen = _thisline - > txt . length ( ) ;
2000-02-25 11:04:07 +00:00
2005-10-16 03:41:29 +00:00
setlinetype ( _thisline ) ;
2000-02-25 11:04:07 +00:00
uint _wrapmargin = ( _thisline - > type & GLINE_QUOT ) ? marginquotes : margintext ;
// Does this line need wrapping?
2001-05-20 12:23:00 +00:00
if ( ( _thislen > _wrapmargin ) or ( ( _thislen = = _wrapmargin ) and not ( ( _thisline - > txt [ _thislen - 1 ] = = ' ' ) or ( _thisline - > txt [ _thislen - 1 ] = = ' \n ' ) ) ) ) {
2000-02-25 11:04:07 +00:00
// Reset quote string length
_quotelen = 0 ;
// Is this line quoted?
2001-03-20 05:21:46 +00:00
if ( _thisline - > type & GLINE_QUOT ) {
2000-02-25 11:04:07 +00:00
// Get quote string and length
2000-03-22 17:59:18 +00:00
GetQuotestr ( _thisline - > txt . c_str ( ) , _quotebuf , & _quotelen ) ;
2000-02-25 11:04:07 +00:00
}
// wrapmargin = 40
// 1111111111222222222233333333334444444444
// 01234567890123456789012345678901234567890123456789
// --------------------------------------------------
// v- wrapptr
// Case 1: this is another test with a bit of text to wrap.
// Case 2: this is a test with a line that need wrapping.
// Case 3: thisxisxaxtestxwithxaxlinexthatxneedxwrapping.
// Case 4: >thisxisxaxtestxwithxaxlinexthatxneedxwrapping.
// Point to the last char inside the margin
2000-03-22 17:59:18 +00:00
int _wrappos = _wrapmargin - 1 ;
2000-02-25 11:04:07 +00:00
// Locate the word to be wrapped
// Did we find a space?
2000-03-22 17:59:18 +00:00
if ( _thisline - > txt [ _wrappos ] = = ' ' ) {
2000-02-25 11:04:07 +00:00
// Case 1: A space was found as the last char inside the margin
//
// Now we must locate the first word outside the margin.
// NOTE: Leading spaces to this word will be nulled out!
// Begin at the first char outside the margin
2001-05-20 12:23:00 +00:00
if ( _wrappos < = maxcol )
2001-03-09 14:40:06 +00:00
_wrappos + + ;
2000-02-25 11:04:07 +00:00
}
else {
// Case 2: A non-space was found as the last char inside the margin
//
// Now we must locate the beginning of the word we found.
// Keep copy of original pointer
2000-03-22 17:59:18 +00:00
int _atmargin = _wrappos ;
2000-02-25 11:04:07 +00:00
2006-01-14 23:48:53 +00:00
// Search backwards until a space or the beginning of the line is found
2001-11-03 15:04:16 +00:00
while ( ( _wrappos > _quotelen ) and ( _thisline - > txt [ _wrappos - 1 ] ! = ' ' ) )
2000-03-22 17:59:18 +00:00
_wrappos - - ;
2000-02-25 11:04:07 +00:00
// Check if we hit leading spaces
2000-03-22 17:59:18 +00:00
int _spacepos = _wrappos ;
2000-10-24 05:02:25 +00:00
while ( _spacepos > 0 ) {
_spacepos - - ;
2001-02-19 22:53:24 +00:00
if ( _thisline - > txt [ _spacepos ] ! = ' ' )
2000-10-24 05:02:25 +00:00
break ;
2000-02-25 11:04:07 +00:00
}
// Did we search all the way back to the beginning of the line?
2001-11-03 15:04:16 +00:00
if ( ( _wrappos = = _quotelen ) or ( _thisline - > txt [ _spacepos ] = = ' ' ) ) {
2000-02-25 11:04:07 +00:00
// Case 3: There are no spaces within the margin or we hit leading spaces
// We have to break it up at the margin
2000-03-22 17:59:18 +00:00
_wrappos = _atmargin ;
2000-02-25 11:04:07 +00:00
}
}
2001-05-20 12:23:00 +00:00
// The wrappos now points to the location to be wrapped or NUL
2000-02-25 11:04:07 +00:00
// Is the line hard-terminated?
2000-03-22 17:59:18 +00:00
if ( _thisline - > txt . find ( ' \n ' , _wrappos ) ! = _thisline - > txt . npos ) {
2000-02-25 11:04:07 +00:00
// The line is hard-terminated.
// Copy the quote string, if any, to the new line first
2001-07-16 20:35:42 +00:00
std : : string _wrapbuf = _quotebuf ;
2000-02-25 11:04:07 +00:00
// Copy/append the wrapped part to the new line
2001-05-09 20:45:13 +00:00
_wrapbuf + = _thisline - > txt . substr ( _wrappos ) ;
// The wrapped part must be placed on a new line below.
Line * _wrapline = _lastadded = insertlinebelow ( _thisline , _wrapbuf . c_str ( ) , BATCH_MODE ) ;
2000-02-25 11:04:07 +00:00
// Saves pointer to a line where from the wrapped part was copied, its begining
// and length. While in Undo, appends the copied part to previous line and deletes
// it on current, moving the rest over deleted.
2001-05-09 20:45:13 +00:00
Undo - > PushItem ( EDIT_UNDO_WRAP_TEXT | BATCH_MODE , _thisline , _quotelen , _wrapbuf . length ( ) - _quotelen ) ;
2001-03-03 20:35:09 +00:00
2000-02-25 11:04:07 +00:00
_wrapline - > type = _thisline - > type ;
// Make sure the type of the line is correct
setlinetype ( _wrapline ) ;
if ( __display ) {
// Is there at least one line below this one?
if ( _thisrow < maxrow ) {
// Scroll the lines below to make room for the new line
2001-05-20 12:23:00 +00:00
- - scroll ;
2000-02-25 11:04:07 +00:00
// Display the new line
2000-03-22 17:59:18 +00:00
if ( _wrapline - > txt . length ( ) < = ( maxcol + 1 ) )
2000-02-25 11:04:07 +00:00
displine ( _wrapline , _thisrow + 1 ) ;
}
}
}
else {
// The line is not hard-terminated
//
// The wrapped part must be inserted into the next line
// Indicate that one or more lines were wrapped in this way
_wrapped_above = true ;
// Pointer to the next line
Line * _nextline = _thisline - > next ;
2001-05-09 20:45:13 +00:00
// Copy the quote string, if any, to the new line first
2001-07-16 20:35:42 +00:00
std : : string _wrapbuf = _quotebuf ;
2001-05-09 20:45:13 +00:00
// Copy/append the wrapped part to the new line
_wrapbuf + = _thisline - > txt . substr ( _wrappos ) ;
2000-02-25 11:04:07 +00:00
// Flag to indicate if a new line was added below
bool _line_added_below = false ;
// Is there no next line or is the next line quoted?
if ( ( _nextline = = NULL ) or ( _nextline - > type & GLINE_QUOT ) ) {
// The wrapped part must be placed on a new line below
2001-05-09 20:45:13 +00:00
_lastadded = _nextline = insertlinebelow ( _thisline , _wrapbuf . c_str ( ) , BATCH_MODE ) ;
2000-02-25 11:04:07 +00:00
_line_added_below = true ;
2001-05-09 20:45:13 +00:00
Undo - > PushItem ( EDIT_UNDO_WRAP_TEXT | BATCH_MODE , _thisline , _quotelen , _wrapbuf . length ( ) - _quotelen ) ;
2000-02-25 11:04:07 +00:00
}
2001-05-09 20:45:13 +00:00
else {
2000-02-25 11:04:07 +00:00
2001-05-09 20:45:13 +00:00
_nextline - > txt . insert ( 0 , _wrapbuf ) ;
if ( _quotelen )
Undo - > PushItem ( EDIT_UNDO_INS_TEXT | BATCH_MODE , _nextline , 0 , _quotelen ) ;
Undo - > PushItem ( EDIT_UNDO_WRAP_TEXT | BATCH_MODE , _thisline , _quotelen , _wrapbuf . length ( ) - _quotelen ) ;
}
2000-02-25 11:04:07 +00:00
// Make sure the type of the line is correct
setlinetype ( _nextline ) ;
if ( __display ) {
// Is there at least one line below this one?
if ( _line_added_below and ( _thisrow < maxrow ) ) {
// Scroll the lines below to make room for the new line
2001-05-20 12:23:00 +00:00
- - scroll ;
2000-02-25 11:04:07 +00:00
}
// Display the new/wrapped line
2000-03-22 17:59:18 +00:00
if ( ( _thisrow + 1 ) < = maxrow and _nextline - > txt . length ( ) < = ( maxcol + 1 ) )
2000-02-25 11:04:07 +00:00
displine ( _nextline , _thisrow + 1 ) ;
}
}
2000-03-22 17:59:18 +00:00
// Truncate at the wrapping location
_thisline - > txt . erase ( _wrappos ) ;
2000-02-25 11:04:07 +00:00
// Was this line quoted?
2006-06-25 07:45:12 +00:00
if ( _quotelen )
{
2000-02-25 11:04:07 +00:00
// Trim spaces off the end of the line
2000-03-22 17:59:18 +00:00
int _trimpos = _wrappos - 1 ;
2006-06-25 07:45:12 +00:00
if ( isspace ( _thisline - > txt [ _trimpos ] ) )
{
while ( _trimpos > 0 and isspace ( _thisline - > txt [ _trimpos - 1 ] ) )
2000-03-22 17:59:18 +00:00
_trimpos - - ;
2000-12-24 19:47:06 +00:00
if ( _quotelen and ( _trimpos < _quotelen ) )
2000-03-22 17:59:18 +00:00
_trimpos + + ;
Undo - > PushItem ( EDIT_UNDO_OVR_CHAR | BATCH_MODE , _thisline , _trimpos ) ;
_thisline - > txt . erase ( _trimpos ) ;
2000-02-25 11:04:07 +00:00
}
2006-06-25 07:45:12 +00:00
else
{
Undo - > PushItem ( EDIT_UNDO_INS_CHAR | BATCH_MODE , _thisline , _trimpos + 1 ) ;
}
2000-02-25 11:04:07 +00:00
// Append a new linefeed
2000-03-22 17:59:18 +00:00
_thisline - > txt + = " \n " ;
2000-02-25 11:04:07 +00:00
}
// Make sure the line type still is correct
setlinetype ( _thisline ) ;
if ( __display ) {
// Display this line after wrapping
if ( _thisrow < = maxrow )
displine ( _thisline , _thisrow ) ;
}
2001-03-17 21:17:57 +00:00
_thislen = _thisline - > txt . length ( ) ;
2000-02-25 11:04:07 +00:00
// If we are on the cursor line, check if the cursor char was wrapped
2001-03-20 05:21:46 +00:00
if ( ( _thisrow = = _cursrow ) and ( _thislen < = _curscol ) ) {
2000-10-24 05:02:25 +00:00
_curscol = _quotelen + ( ( _curscol > _wrappos ) ? _curscol - _wrappos : 0 ) ;
_cursrow + + ;
2000-02-25 11:04:07 +00:00
UndoItem * i = Undo - > last_item ;
do { i = i - > prev ; } while ( i - > action & BATCH_MODE ) ;
2000-03-22 17:59:18 +00:00
if ( i - > col . num > = i - > line - > txt . length ( ) ) {
2000-02-25 11:04:07 +00:00
i - > action | = PREV_LINE ;
i - > col . sav = i - > col . num ;
i - > col . num = _curscol ;
}
}
}
// If this line is hard-terminated, we have finished wrapping
// Unless the next line has grown too large
2000-03-22 17:59:18 +00:00
if ( _thisline - > txt . find ( ' \n ' ) ! = _thisline - > txt . npos ) {
2000-02-25 11:04:07 +00:00
if ( _thisline - > next = = NULL )
break ;
_wrapmargin = ( _thisline - > next - > type & GLINE_QUOT ) ? marginquotes : margintext ;
2000-03-22 17:59:18 +00:00
if ( _thisline - > next - > txt . length ( ) < = _wrapmargin )
2000-02-25 11:04:07 +00:00
break ;
}
2001-05-09 20:45:13 +00:00
else if ( _thisline - > type & GLINE_QUOT ) {
Undo - > PushItem ( EDIT_UNDO_INS_TEXT | BATCH_MODE , _thisline , _thisline - > txt . length ( ) , 1 ) ;
_thisline - > txt + = ' \n ' ;
}
2000-02-25 11:04:07 +00:00
// Go to the next line
_thisline = _thisline - > next ;
_thisrow + + ;
}
if ( __display ) {
// Display the current line after wrapping
if ( * __curr_row < = maxrow )
displine ( * __currline , * __curr_row ) ;
// Was the line or lines above wrapped?
if ( _wrapped_above ) {
// Display the last line in the paragraph
if ( ( _thisrow < = maxrow ) and _thisline )
displine ( _thisline , _thisrow ) ;
}
}
// Move to the next line if the cursor was wrapped
if ( _cursrow ! = * __curr_row ) {
2000-10-24 05:02:25 +00:00
int i = * __curr_row ;
while ( ( i + + ! = _cursrow ) and ( __currline ! = NULL ) )
* __currline = ( * __currline ) - > next ;
2000-02-25 11:04:07 +00:00
if ( _cursrow > maxrow ) {
_cursrow = maxrow ;
2000-10-24 05:02:25 +00:00
if ( __display ) {
2001-05-20 12:23:00 +00:00
+ + scroll ;
if ( scroll > 0 ) {
scrollup ( mincol , minrow , maxcol , maxrow ) ;
scroll = 0 ;
}
2000-10-24 05:02:25 +00:00
displine ( * __currline , * __curr_row ) ;
}
2000-02-25 11:04:07 +00:00
}
}
2001-05-20 12:23:00 +00:00
if ( __display and ( scroll ! = 0 ) ) {
2001-06-12 17:31:12 +00:00
if ( ( * __currline ) - > next ! = NULL )
refresh ( ( * __currline ) - > next , _cursrow + 1 ) ;
else
refresh ( * __currline , _cursrow ) ;
2001-05-20 12:23:00 +00:00
}
2000-02-25 11:04:07 +00:00
// Update cursor position
* __curr_row = _cursrow ;
* __curr_col = _curscol ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
return _lastadded ;
}
// ------------------------------------------------------------------
2001-03-09 14:40:06 +00:00
Line * IEclass : : wrapdel ( Line * * __currline , uint * __curr_col , uint * __curr_row , bool __display ) {
2000-02-25 11:04:07 +00:00
GFTRK ( " Editwrapdel " ) ;
Line * tmp = wrapit ( __currline , __curr_col , __curr_row , __display ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
return tmp ;
}
// ------------------------------------------------------------------
2001-03-09 14:40:06 +00:00
Line * IEclass : : wrapins ( Line * * __currline , uint * __curr_col , uint * __curr_row , bool __display ) {
2000-02-25 11:04:07 +00:00
GFTRK ( " Editwrapins " ) ;
Line * tmp = wrapit ( __currline , __curr_col , __curr_row , __display ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
return tmp ;
}
// ------------------------------------------------------------------
void IEclass : : insertchar ( char __ch ) {
GFTRK ( " Editinsertchar " ) ;
2000-03-22 17:59:18 +00:00
uint _currline_len = currline - > txt . length ( ) ;
2001-02-19 22:53:24 +00:00
# ifndef NDEBUG
2000-03-22 17:59:18 +00:00
_test_haltab ( col > _currline_len , col , _currline_len ) ;
# endif
2000-02-25 11:04:07 +00:00
// Insert or overwrite the char, replacing the block if any
if ( ( selecting ? ( BlockCut ( true ) , batch_mode = BATCH_MODE ) : false ) or
2001-02-19 22:53:24 +00:00
( col > = _currline_len ) or ( currline - > txt [ col ] = = ' \n ' ) or insert ) {
2001-03-20 05:21:46 +00:00
if ( not isspace ( __ch ) and ( col = = mincol ) ) {
// if previous line was wrapped on non-space character
if ( currline - > prev and not currline - > prev - > txt . empty ( ) and
( currline - > prev - > txt . find ( ' \n ' ) = = currline - > prev - > txt . npos ) and
not isspace ( currline - > prev - > txt [ currline - > prev - > txt . length ( ) - 1 ] ) ) {
2001-11-20 15:04:04 +00:00
if ( not batch_mode ) {
Undo - > PushItem ( EDIT_UNDO_VOID ) ;
batch_mode = BATCH_MODE ;
}
2001-03-20 05:21:46 +00:00
GoUp ( ) ;
GoEOL ( ) ;
}
}
2000-02-25 11:04:07 +00:00
Undo - > PushItem ( EDIT_UNDO_INS_CHAR | batch_mode ) ;
2000-03-22 17:59:18 +00:00
currline - > txt . insert ( col , 1 , __ch ) ;
2000-02-25 11:04:07 +00:00
} else {
Undo - > PushItem ( EDIT_UNDO_OVR_CHAR | batch_mode ) ;
2000-03-22 17:59:18 +00:00
currline - > txt [ col ] = __ch ;
2000-02-25 11:04:07 +00:00
}
batch_mode = BATCH_MODE ;
// Make sure the line type still is correct
setlinetype ( currline ) ;
// Move cursor
col + + ;
wrapins ( & currline , & col , & row ) ;
// Adjust cursor position and display if necessary
if ( col > maxcol ) {
if ( currline - > next ) {
currline = currline - > next ;
col = mincol ;
row + + ;
if ( row > maxrow ) {
row = maxrow ;
scrollup ( mincol , minrow , maxcol , maxrow ) ;
displine ( currline , row ) ;
}
}
else {
col = maxcol ;
}
}
gotorowcol ( col , row ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
2006-06-05 19:03:19 +00:00
void IEclass : : DelChar ( )
{
2000-02-25 11:04:07 +00:00
GFTRK ( " EditDelChar " ) ;
Line * _thisline = currline ;
Line * _nextline = currline - > next ;
2000-03-22 17:59:18 +00:00
uint _thislen = _thisline - > txt . length ( ) ;
2000-02-25 11:04:07 +00:00
2006-06-05 19:03:19 +00:00
if ( ! _nextline & & ( col = = _thislen - 1 ) & & ( _thisline - > txt [ col ] = = ' \n ' ) )
{
GFTRK ( 0 ) ;
return ;
}
2000-02-25 11:04:07 +00:00
// Cannot delete at or beyond the nul-terminator
if ( col < _thislen ) {
Undo - > PushItem ( EDIT_UNDO_DEL_CHAR | batch_mode ) ;
2000-03-22 17:59:18 +00:00
_thisline - > txt . erase ( col , 1 ) ;
2000-02-25 11:04:07 +00:00
batch_mode = BATCH_MODE ;
}
2001-11-20 15:04:04 +00:00
else if ( col and ( col = = _thislen ) and _nextline ) {
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2001-11-20 15:04:04 +00:00
if ( not batch_mode ) {
Undo - > PushItem ( EDIT_UNDO_VOID ) ;
batch_mode = BATCH_MODE ;
}
2001-05-20 12:23:00 +00:00
GoRight ( ) ;
DelChar ( ) ;
return ;
}
2000-02-25 11:04:07 +00:00
// Did we delete the last char on the line or
// was the cursor at or beyond the nul-terminator?
// And is there a next line at all?
if ( ( ( col + 1 ) > = _thislen ) and _nextline ) {
// Join the next line to this line
// Is the next line quoted?
// And is the cursor column non-zero?
uint _quotelen = 0 ;
2001-03-20 05:21:46 +00:00
if ( ( _nextline - > type & GLINE_QUOT ) and col ) {
2000-02-25 11:04:07 +00:00
// Get quote string length
2001-05-09 20:45:13 +00:00
char _quotebuf [ MAXQUOTELEN ] ;
GetQuotestr ( _nextline - > txt . c_str ( ) , _quotebuf , & _quotelen ) ;
2000-02-25 11:04:07 +00:00
}
2001-03-17 21:17:57 +00:00
// Copy the next line's text to this line without quote string
const char * _nexttext = _nextline - > txt . c_str ( ) + _quotelen ;
2001-03-20 05:21:46 +00:00
_thisline - > txt + = _nexttext + ( col ? strspn ( _nexttext , " " ) : 0 ) ;
2000-02-25 11:04:07 +00:00
Undo - > PushItem ( EDIT_UNDO_CUT_TEXT | batch_mode , _thisline , col ) ;
// Relink this line
_thisline - > next = _nextline - > next ;
if ( _thisline - > next )
_thisline - > next - > prev = _thisline ;
Undo - > PushItem ( EDIT_UNDO_DEL_LINE | BATCH_MODE , _nextline ) ;
}
2001-03-09 14:40:06 +00:00
else if ( ( _thislen > 1 ) and ( _thisline - > txt . c_str ( ) [ _thislen - 2 ] ! = ' \n ' ) and _nextline and not ( _nextline - > type & GLINE_QUOT ) ) {
_thisline - > txt + = _nextline - > txt . c_str ( ) ;
Undo - > PushItem ( EDIT_UNDO_CUT_TEXT | batch_mode , _thisline , _thislen - 1 ) ;
// Relink this line
_thisline - > next = _nextline - > next ;
if ( _thisline - > next )
_thisline - > next - > prev = _thisline ;
2006-01-14 23:48:53 +00:00
Undo - > PushItem ( EDIT_UNDO_DEL_LINE | BATCH_MODE , _nextline ) ;
2001-03-09 14:40:06 +00:00
}
2000-02-25 11:04:07 +00:00
batch_mode = BATCH_MODE ;
// Make sure the line type still is correct
setlinetype ( _thisline ) ;
2006-02-03 11:25:19 +00:00
// Rewrap this line
bool display = make_bool_not ( row > maxrow / 2 ) ;
wrapdel ( & currline , & col , & row , display ) ;
if ( display ) {
2001-05-20 12:23:00 +00:00
refresh ( currline , row ) ;
2006-02-03 11:25:19 +00:00
}
else {
// Refresh the display
Line * _topline = findtopline ( ) ;
refresh ( _topline , minrow ) ;
}
2000-02-25 11:04:07 +00:00
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : DelLeft ( ) {
GFTRK ( " EditDelLeft " ) ;
// Cannot backspace from the first column on the first line in the msg
if ( currline - > prev = = NULL )
if ( col = = mincol ) {
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
return ;
}
// Go left(/up) and delete the character there
2001-11-20 15:04:04 +00:00
if ( not batch_mode ) {
2001-12-19 09:33:09 +00:00
if ( col = = mincol )
Undo - > PushItem ( EDIT_UNDO_VOID | PREV_LINE , currline - > prev ) ;
else
Undo - > PushItem ( EDIT_UNDO_VOID ) ;
2001-11-20 15:04:04 +00:00
batch_mode = BATCH_MODE ;
}
2000-02-25 11:04:07 +00:00
GoLeft ( ) ;
DelChar ( ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : GoWordLeft ( ) {
GFTRK ( " EditGoWordLeft " ) ;
if ( col = = 0 ) {
if ( currline - > prev ) {
GoUp ( ) ;
GoEOL ( ) ;
}
}
else {
2006-01-14 23:48:53 +00:00
2000-02-25 11:04:07 +00:00
col - - ;
2006-01-14 23:48:53 +00:00
2000-03-22 17:59:18 +00:00
if ( not isxalnum ( currline - > txt [ col ] ) ) {
while ( not isxalnum ( currline - > txt [ col ] ) and ( col > 0 ) )
2000-02-25 11:04:07 +00:00
col - - ;
2000-03-22 17:59:18 +00:00
while ( isxalnum ( currline - > txt [ col ] ) and ( col > 0 ) )
2000-02-25 11:04:07 +00:00
col - - ;
}
else {
2000-03-22 17:59:18 +00:00
while ( isxalnum ( currline - > txt [ col ] ) and ( col > 0 ) )
2000-02-25 11:04:07 +00:00
col - - ;
}
if ( col ! = 0 )
col + + ;
if ( blockcol ! = - 1 )
displine ( currline , row ) ;
}
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : GoWordRight ( ) {
GFTRK ( " EditGoWordRight " ) ;
2001-02-21 21:26:28 +00:00
if ( ( col > = currline - > txt . length ( ) ) or ( currline - > txt [ col ] = = ' \n ' ) ) {
2000-02-25 11:04:07 +00:00
if ( currline - > next ) {
GoDown ( ) ;
2005-10-06 17:50:55 +00:00
col = mincol ;
2000-02-25 11:04:07 +00:00
}
2001-02-21 21:26:28 +00:00
}
else {
2001-02-19 22:53:24 +00:00
size_t len = currline - > txt . length ( ) ;
2000-03-22 17:59:18 +00:00
if ( not isxalnum ( currline - > txt [ col ] ) ) {
2001-02-19 22:53:24 +00:00
while ( not isxalnum ( currline - > txt [ col ] ) and ( ( col + 1 ) < = len ) )
2000-02-25 11:04:07 +00:00
col + + ;
}
else {
2001-02-19 22:53:24 +00:00
while ( isxalnum ( currline - > txt [ col ] ) and ( ( col + 1 ) < = len ) )
2000-02-25 11:04:07 +00:00
col + + ;
2001-02-19 22:53:24 +00:00
while ( not isxalnum ( currline - > txt [ col ] ) and ( ( col + 1 ) < = len ) )
2000-02-25 11:04:07 +00:00
col + + ;
}
2000-03-22 17:59:18 +00:00
if ( currline - > txt [ col - 1 ] = = ' \n ' )
2000-02-25 11:04:07 +00:00
col - - ;
2001-02-19 22:53:24 +00:00
if ( len = = col ) {
2000-02-25 11:04:07 +00:00
if ( currline - > next ) {
GoDown ( ) ;
col = 0 ;
}
else
col - - ;
}
}
2005-10-06 17:50:55 +00:00
if ( blockcol ! = - 1 )
displine ( currline , row ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : Newline ( ) {
GFTRK ( " EditNewline " ) ;
// Pointer to the split position
2000-03-22 17:59:18 +00:00
int _splitpos = col ;
2000-02-25 11:04:07 +00:00
// Buffer for the second part of the split line
2001-07-16 20:35:42 +00:00
std : : string _splitbuf ;
2000-02-25 11:04:07 +00:00
// If the split line was quoted, get the quotestring
// But do not get it if the cursor points to a linefeed or is
2001-05-09 20:45:13 +00:00
uint _quotelen ;
2001-06-12 17:31:12 +00:00
char _quotebuf [ MAXQUOTELEN ] ;
2001-05-09 20:45:13 +00:00
GetQuotestr ( currline - > txt . c_str ( ) , _quotebuf , & _quotelen ) ;
2000-02-25 11:04:07 +00:00
// Eliminate the quotestring if
// - the cursor points to a linefeed or
// - the cursor is located inside the quotestring
2001-05-09 20:45:13 +00:00
if ( _quotelen and ( ( currline - > txt . length ( ) = = col ) or ( currline - > txt [ _splitpos ] = = ' \n ' ) or ( col < _quotelen ) ) ) {
* _quotebuf = NUL ;
_quotelen = 0 ;
}
2000-02-25 11:04:07 +00:00
// Append the second part to the split buffer
2001-05-09 20:45:13 +00:00
_splitbuf = _quotebuf ;
_splitbuf + = currline - > txt . substr ( _splitpos ) ;
2000-02-25 11:04:07 +00:00
Undo - > PushItem ( EDIT_UNDO_INS_TEXT | batch_mode , currline , col , 1 ) ;
batch_mode = BATCH_MODE ;
2006-01-14 23:48:53 +00:00
2000-02-25 11:04:07 +00:00
// Copy linefeed+nul to the split position
2000-03-22 17:59:18 +00:00
currline - > txt . erase ( _splitpos ) ;
currline - > txt + = " \n " ;
2000-02-25 11:04:07 +00:00
// Re-type and display the split line
setlinetype ( currline ) ;
displine ( currline , row ) ;
2001-06-12 17:31:12 +00:00
uint _quotelen1 = 0 ;
char _quotebuf1 [ MAXQUOTELEN ] = " " ;
if ( currline - > next ! = NULL ) {
GetQuotestr ( currline - > next - > txt . c_str ( ) , _quotebuf1 , & _quotelen1 ) ;
}
2000-02-25 11:04:07 +00:00
2001-06-12 17:31:12 +00:00
if ( ( _splitbuf . find ( ' \n ' ) ! = _splitbuf . npos ) or ( currline - > next = = NULL ) or not strieql ( _quotebuf , _quotebuf1 ) ) {
// Insert a new line below, set the line text to the split-off part
currline = insertlinebelow ( currline , _splitbuf . c_str ( ) ) ;
2000-02-25 11:04:07 +00:00
2001-06-12 17:31:12 +00:00
// --v--
// This line would be wrapped
// This line would be
// wrapped
2000-02-25 11:04:07 +00:00
2001-06-12 17:31:12 +00:00
Undo - > PushItem ( EDIT_UNDO_WRAP_TEXT | BATCH_MODE , currline - > prev , _quotelen , _splitbuf . length ( ) - _quotelen ) ;
}
else {
currline = currline - > next ;
currline - > txt . insert ( _quotelen1 , _splitbuf . substr ( _quotelen1 ) ) ;
Undo - > PushItem ( EDIT_UNDO_WRAP_TEXT | BATCH_MODE , currline - > prev , _quotelen1 , _splitbuf . length ( ) - _quotelen1 ) ;
}
2002-06-14 06:46:39 +00:00
setlinetype ( currline ) ;
2000-02-25 11:04:07 +00:00
// Move down the cursor
col = 0 ;
row = downoneline ( row ) ;
// Scroll the remaining lines if necessary
if ( row < maxrow )
scrolldown ( mincol , row , maxcol , maxrow ) ;
// Rewrap the split-off line
2001-06-12 17:31:12 +00:00
wrapdel ( & currline , & col , & row , true ) ;
refresh ( currline , row ) ;
2000-02-25 11:04:07 +00:00
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : CopyAboveChar ( ) {
GFTRK ( " EditCopyAboveChar " ) ;
char _ch = ' ' ;
if ( currline - > prev ) {
2000-03-22 17:59:18 +00:00
uint _len = currline - > prev - > txt . length ( ) ;
2000-02-25 11:04:07 +00:00
if ( _len and _len > col )
2000-03-22 17:59:18 +00:00
_ch = currline - > prev - > txt [ col ] ;
2000-02-25 11:04:07 +00:00
if ( _ch = = ' \n ' )
_ch = ' ' ;
}
insertchar ( _ch ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : DupLine ( ) {
GFTRK ( " EditDupLine " ) ;
Undo - > PushItem ( EDIT_UNDO_VOID ) ;
2001-11-20 15:04:04 +00:00
batch_mode = BATCH_MODE ;
2006-01-14 23:48:53 +00:00
2001-11-20 15:04:04 +00:00
Line * _nextline = insertlinebelow ( currline , currline - > txt . c_str ( ) , batch_mode ) ;
2000-02-25 11:04:07 +00:00
_nextline - > type = currline - > type & ~ GLINE_BLOK ;
_nextline - > color = currline - > color ;
_nextline - > kludge = currline - > kludge ;
refresh ( currline , row ) ;
GoDown ( ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
// PageUp behavior:
//
// ... The top line becomes the bottom line.
// ... Always remain at cursor row, except if we can't page up.
// ... If we can't page up, move the cursor row to the top line.
void IEclass : : GoPgUp ( ) {
GFTRK ( " EditGoPgUp " ) ;
// Not at the first line in msg?
if ( currline - > prev ) {
// Count lines
int _count = row ;
// Move to the top line currently displayed
Line * _topline = currline ;
while ( _count and _topline - > prev ) {
_topline = _topline - > prev ;
_count - - ;
}
// The count must be zero at this point!
_test_haltab ( _count , _count , _count ) ;
// At we already fully at the top?
if ( _topline - > prev = = NULL ) {
// Yes, so move the cursor row to the top line
row = minrow ;
currline = _topline ;
if ( blockcol ! = - 1 )
refresh ( currline , row ) ;
}
else {
// We are not at the top, so continue with paging
// Move a full page of lines, if possible
_count = maxrow ;
while ( _count and _topline - > prev ) {
_topline = _topline - > prev ;
_count - - ;
}
// Set the current line
_count = row ;
currline = _topline ;
while ( _count - - )
currline = currline - > next ;
// Refresh display
refresh ( _topline , minrow ) ;
}
}
else {
GoTopMsg ( ) ;
}
2000-03-22 17:59:18 +00:00
if ( col + 1 > currline - > txt . length ( ) )
2000-02-25 11:04:07 +00:00
GoEOL ( ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
// PageDown behavior:
//
// ... The bottom line becomes the top line.
// ... Always remain at cursor row, except if at the last line.
// ... If at the last line, move cursor to the last window line and
// display the lines above.
// ... If there are too few lines to display after the page down, the
// rest are displayed blank.
void IEclass : : GoPgDn ( ) {
GFTRK ( " EditGoPgDn " ) ;
// Not at the last line in the msg?
if ( currline - > next ) {
// Go down to the last displayed line in the window
uint _newrow = row , _oldrow = row ;
Line * oldcurrline = currline ;
while ( ( _newrow < maxrow ) and currline - > next ) {
currline = currline - > next ;
_newrow + + ;
}
// If there are more lines after the last line, start displaying from the top
if ( currline - > next ) {
Line * _topline = currline ;
// Set current line
_newrow = 0 ;
while ( ( _newrow < row ) and currline - > next ) {
currline = currline - > next ;
_newrow + + ;
}
// Move cursor row if necessary
if ( _newrow < row )
row = _newrow ;
refresh ( _topline , minrow ) ;
}
else {
row = _newrow ;
refresh ( oldcurrline , _oldrow ) ;
}
}
else {
GoBotMsg ( ) ;
}
2000-03-22 17:59:18 +00:00
if ( col + 1 > currline - > txt . length ( ) )
2000-02-25 11:04:07 +00:00
GoEOL ( ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : Tab ( ) {
GFTRK ( " EditTab " ) ;
int tabsz = CFG - > disptabsize ? CFG - > disptabsize : 1 ;
// Move to the next tab position
do {
if ( insert )
insertchar ( ' ' ) ;
2000-03-22 17:59:18 +00:00
else if ( currline - > txt [ col ] ! = ' \n ' )
2000-02-25 11:04:07 +00:00
GoRight ( ) ;
else
break ;
} while ( col % tabsz ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : ReTab ( ) {
GFTRK ( " EditTabReverse " )
int tabsz = CFG - > disptabsize ? CFG - > disptabsize : 1 ;
// Move to the next tab position
do {
if ( not col )
break ;
if ( insert )
DelLeft ( ) ;
else
GoLeft ( ) ;
} while ( col % tabsz ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : DeleteEOL ( ) {
GFTRK ( " EditDeleteEOL " ) ;
2005-10-25 06:11:09 +00:00
bool _has_linefeed = ( currline - > txt . find ( ' \n ' ) ! = currline - > txt . npos ) ;
2006-01-14 23:48:53 +00:00
2000-02-25 11:04:07 +00:00
Undo - > PushItem ( EDIT_UNDO_DEL_TEXT , currline ) ;
2000-03-22 17:59:18 +00:00
currline - > txt . erase ( col ) ;
2000-02-25 11:04:07 +00:00
2001-06-04 03:40:38 +00:00
if ( _has_linefeed ) {
Undo - > PushItem ( EDIT_UNDO_INS_CHAR | BATCH_MODE ) ;
2000-03-22 17:59:18 +00:00
currline - > txt + = " \n " ;
2001-06-04 03:40:38 +00:00
}
2000-02-25 11:04:07 +00:00
clreol ( ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
2001-08-31 14:14:27 +00:00
// ------------------------------------------------------------------
void IEclass : : DeleteSOL ( ) {
GFTRK ( " EditDeleteSOL " ) ;
if ( col = = 0 ) {
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2001-08-31 14:14:27 +00:00
return ;
}
int _oldcol = col ;
col = 0 ;
Undo - > PushItem ( EDIT_UNDO_DEL_TEXT , currline , col , _oldcol ) ;
currline - > txt . erase ( col , _oldcol ) ;
wrapdel ( & currline , & col , & row ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2001-08-31 14:14:27 +00:00
}
2000-02-25 11:04:07 +00:00
// ------------------------------------------------------------------
void IEclass : : deleteline ( bool zapquotesbelow ) {
GFTRK ( " Editdeleteline " ) ;
bool done = false ;
do {
2006-01-14 23:48:53 +00:00
2000-02-25 11:04:07 +00:00
// Break if need to zap quotes, but the current line is not quote and is not empty
2001-07-03 04:56:32 +00:00
if ( zapquotesbelow and not ( ( currline - > type & GLINE_QUOT ) or isempty ( currline ) ) )
break ;
2000-02-25 11:04:07 +00:00
// Pointer to the deleted line
Line * _deletedline = currline ;
// If last line to be deleted delete to EOL and exit
if ( currline - > next = = NULL ) {
2001-07-03 04:56:32 +00:00
if ( isempty ( currline ) )
2000-02-25 11:04:07 +00:00
break ;
insertlinebelow ( currline , " " , batch_mode ) ;
batch_mode = BATCH_MODE ;
done = true ;
}
// Pointers to the previous and next lines
Line * _prevline = currline - > prev ;
Line * _nextline = currline - > next ;
Undo - > PushItem ( EDIT_UNDO_PUSH_LINE | batch_mode ) ;
// Set the new current line to the next line (which may be NULL!)
currline = _nextline ;
if ( currline = = NULL ) {
currline = _prevline ;
currline - > next = NULL ;
_prevline = _prevline ? _prevline - > prev : NULL ;
}
// Link the new current line to the previous line
currline - > prev = _prevline ;
// Link the previous line to this line
if ( _prevline )
_prevline - > next = currline ;
if ( _deletedline - > type & GLINE_BLOK ) {
blockcol = - 1 ;
_deletedline - > type & = ~ GLINE_BLOK ;
}
// Link the deleted line to the killbuffer
if ( Edit__killbuf ) {
Edit__killbuf - > next = _deletedline ;
_deletedline - > prev = Edit__killbuf ;
Edit__killbuf = _deletedline ;
}
else {
Edit__killbuf = _deletedline ;
Edit__killbuf - > prev = NULL ;
}
Edit__killbuf - > next = NULL ;
// Move the cursor to EOL if necessary
2000-03-22 17:59:18 +00:00
if ( col + 1 > currline - > txt . length ( ) )
2000-02-25 11:04:07 +00:00
GoEOL ( ) ;
if ( not zapquotesbelow )
break ;
batch_mode = BATCH_MODE ;
} while ( not done ) ;
// Refresh display from cursor row
refresh ( currline , row ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : UnDelete ( bool before ) {
GFTRK ( " EditUnDelete " ) ;
// If there are deleted lines
if ( Edit__killbuf ) {
Line * _prevline = Edit__killbuf - > prev ;
bool down = false ;
if ( before ) {
Edit__killbuf - > prev = currline ? currline - > prev : NULL ;
Edit__killbuf - > next = currline ;
}
else {
Edit__killbuf - > prev = currline ;
Edit__killbuf - > next = currline ? currline - > next : NULL ;
if ( row = = maxrow )
down = true ;
else if ( ( row < maxrow ) and currline )
row + + ;
}
if ( Edit__killbuf - > prev )
Edit__killbuf - > prev - > next = Edit__killbuf ;
if ( Edit__killbuf - > next )
Edit__killbuf - > next - > prev = Edit__killbuf ;
currline = Edit__killbuf ;
Edit__killbuf = _prevline ;
if ( Edit__killbuf )
Edit__killbuf - > next = NULL ;
Undo - > PushItem ( EDIT_UNDO_POP_LINE ) ;
// Move the cursor to EOL if necessary
2000-03-22 17:59:18 +00:00
if ( col + 1 > currline - > txt . length ( ) )
2000-02-25 11:04:07 +00:00
GoEOL ( ) ;
if ( down )
GoDown ( ) ;
else
refresh ( currline , row ) ;
}
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : ZapQuoteBelow ( ) {
GFTRK ( " ZapQuoteBelow " ) ;
if ( currline - > prev )
Undo - > PushItem ( EDIT_UNDO_VOID | PREV_LINE | batch_mode , currline - > prev ) ;
else
Undo - > PushItem ( EDIT_UNDO_VOID | batch_mode , currline ) ;
batch_mode = BATCH_MODE ;
2001-07-03 04:56:32 +00:00
UndoItem * item_to_fix = Undo - > last_item ;
2000-02-25 11:04:07 +00:00
deleteline ( true ) ;
2001-07-03 04:56:32 +00:00
if ( row = = 0 ) {
item_to_fix - > line = currline ;
2000-02-25 11:04:07 +00:00
}
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
Line * IEclass : : findtopline ( ) {
GFTRK ( " Editfindtopline " ) ;
uint _toprow = row ;
Line * _topline = currline ;
while ( _topline - > prev and ( _toprow > minrow ) ) {
_topline = _topline - > prev ;
_toprow - - ;
}
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
return _topline ;
}
// ------------------------------------------------------------------
void IEclass : : savefile ( int __status ) {
Subj statbak ;
GFTRK ( " Editsavefile " ) ;
// Turn off cursor and put up a wait window
2005-08-09 12:26:08 +00:00
# if defined(__USE_NCURSES__) || !defined(__WIN32__) /* Fix after bugfix w9x console bug in gvidbase.cpp */
2000-02-25 11:04:07 +00:00
int wascursoron = not vcurhidden ( ) ;
cursoroff ( ) ;
2005-08-09 12:26:08 +00:00
# endif
2000-02-25 11:04:07 +00:00
strcpy ( statbak , information ) ;
update_statusline ( LNG - > Wait + 1 ) ;
// Open the save file
const char * editorfile = AddPath ( CFG - > goldpath , EDIT - > File ( ) ) ;
remove ( editorfile ) ;
2006-04-26 17:06:23 +00:00
gfile _fp ( editorfile , " wb " , CFG - > sharemode ) ;
2006-05-13 16:15:35 +00:00
if ( _fp . isopen ( ) )
2006-04-26 17:06:23 +00:00
{
2000-02-25 11:04:07 +00:00
// Find the first line
Line * _saveline = findfirstline ( ) ;
// First save the "unfinished" identifier
2006-04-26 17:06:23 +00:00
if ( __status = = MODE_UPDATE )
{
_fp . Fputs ( unfinished ) ;
_fp . Fputs ( " \r \n " ) ;
2000-02-25 11:04:07 +00:00
}
// Save as whole paragraphs
while ( _saveline ) {
// Copy the line to a buffer
char _buf [ EDIT_BUFLEN ] ;
2000-03-22 17:59:18 +00:00
strcpy ( _buf , _saveline - > txt . c_str ( ) ) ;
2000-02-25 11:04:07 +00:00
// If a LF was found, replace it with a CR/LF combo
char * _lfptr = strchr ( _buf , ' \n ' ) ;
if ( _lfptr )
strcpy ( _lfptr , " \r \n " ) ;
// Save the line
2006-04-26 17:06:23 +00:00
_fp . Fputs ( _buf ) ;
2000-02-25 11:04:07 +00:00
// Continue with the next line
_saveline = _saveline - > next ;
}
}
update_statusline ( statbak ) ;
2005-08-09 12:26:08 +00:00
# if defined(__USE_NCURSES__) || !defined(__WIN32__) /* Fix after bugfix w9x console bug in gvidbase.cpp */
2000-02-25 11:04:07 +00:00
if ( wascursoron )
cursoron ( ) ;
2005-08-09 12:26:08 +00:00
# endif
2000-02-25 11:04:07 +00:00
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : SaveFile ( ) {
GFTRK ( " EditSaveFile " ) ;
savefile ( MODE_UPDATE ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : SaveMsg ( ) {
GFTRK ( " EditSaveMsg " ) ;
done = MODE_SAVE ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
2005-11-28 20:06:38 +00:00
// ------------------------------------------------------------------
2006-03-11 17:04:06 +00:00
# if defined(GCFG_SPELL_INCLUDED)
2005-11-28 20:06:38 +00:00
void IEclass : : SCheckerMenu ( )
{
2011-03-14 02:56:12 +00:00
if ( ! schecker . IsInited ( ) )
2005-11-28 20:06:38 +00:00
return ;
const char * txt = currline - > txt . c_str ( ) ;
GMenuSChecker menu ;
int finaltag ;
if ( ! isscchar ( txt [ col ] ) )
finaltag = menu . Run ( schecker , " " ) ;
else
{
char buff [ EDIT_BUFLEN ] ;
size_t beg = col ;
size_t end = col ;
for ( ; ( beg > 0 ) & & isscchar ( txt [ beg - 1 ] ) ; beg - - ) ;
for ( ; isscchar ( txt [ end ] ) ; end + + ) ;
size_t len = end - beg ;
memcpy ( buff , & txt [ beg ] , len ) ;
buff [ len ] = 0 ;
finaltag = menu . Run ( schecker , buff ) ;
if ( finaltag > = 0 )
{
std : : string & str = schecker . GetSuggest ( ) [ finaltag ] . second ;
size_t len2 = str . length ( ) - 3 ;
txt = & str . c_str ( ) [ 2 ] ;
if ( ( buff [ len - 1 ] = = ' . ' ) & & ( txt [ len2 - 1 ] ! = ' . ' ) ) len - - ;
if ( col > ( beg + len2 - 1 ) ) col = beg + len2 - 1 ;
Undo - > PushItem ( EDIT_UNDO_DEL_TEXT , currline , beg , len ) ;
currline - > txt . erase ( beg , len ) ;
Undo - > PushItem ( EDIT_UNDO_INS_TEXT | BATCH_MODE , currline , beg , len2 ) ;
currline - > txt . insert ( beg , txt , len2 ) ;
wrapit ( & currline , & col , & row ) ;
}
}
if ( finaltag = = - 2 )
2005-11-30 11:17:42 +00:00
{
Line * line = currline ;
uint32_t _row = row ;
while ( line - > prev & & ( _row > minrow ) )
{
line = line - > prev ;
_row - - ;
}
refresh ( line , _row ) ;
}
2005-11-28 20:06:38 +00:00
}
# endif
2000-02-25 11:04:07 +00:00
// ------------------------------------------------------------------
int IEclass : : isempty ( Line * __line ) {
if ( __line = = NULL )
__line = currline ;
2000-03-22 17:59:18 +00:00
return ( __line - > txt . empty ( ) or __line - > txt [ 0 ] = = ' \n ' ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
int IEclass : : reflowok ( char * __qstr ) {
// Stop reflow if there is no next line
if ( currline - > next = = NULL )
return false ;
// Stop reflow if the next line is empty
if ( isempty ( currline - > next ) )
return false ;
// Stop reflow if the next line is a control line
if ( currline - > next - > type & ( GLINE_KLUDGE | GLINE_TEAR | GLINE_ORIG | GLINE_TAGL ) )
return false ;
// Stop reflow if the quotestring on the next line is not the same
uint _qlen2 ;
2001-05-09 20:45:13 +00:00
char _qstr2 [ MAXQUOTELEN ] ;
2000-03-22 17:59:18 +00:00
GetQuotestr ( currline - > next - > txt . c_str ( ) , _qstr2 , & _qlen2 ) ;
2001-05-09 20:45:13 +00:00
if ( not cmp_quotes ( __qstr , _qstr2 ) )
2000-02-25 11:04:07 +00:00
return false ;
return true ;
}
// ------------------------------------------------------------------
void IEclass : : Reflow ( ) {
GFTRK ( " EditReflow " ) ;
// Skip empty lines
while ( isempty ( ) ) {
2001-11-20 15:04:04 +00:00
if ( currline - > next ) {
if ( not batch_mode ) {
Undo - > PushItem ( EDIT_UNDO_VOID ) ;
batch_mode = BATCH_MODE ;
}
2000-02-25 11:04:07 +00:00
GoDown ( ) ;
2001-11-20 15:04:04 +00:00
}
2000-02-25 11:04:07 +00:00
else {
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
return ;
}
}
// Get the first quotestring
uint _qlen1 ;
2001-05-09 20:45:13 +00:00
char _qstr1 [ MAXQUOTELEN ] ;
2000-03-22 17:59:18 +00:00
GetQuotestr ( currline - > txt . c_str ( ) , _qstr1 , & _qlen1 ) ;
const char * _qlenptr = currline - > txt . c_str ( ) + _qlen1 ;
2000-02-25 11:04:07 +00:00
// Strip leading spaces from the first line
2000-09-01 16:23:15 +00:00
const char * ptr = _qlenptr ;
2001-02-19 22:53:24 +00:00
while ( * ptr and isspace ( * ptr ) and ( * ptr ! = ' \n ' ) ) ptr + + ;
2000-02-25 11:04:07 +00:00
if ( ptr ! = _qlenptr ) {
2001-11-20 15:04:04 +00:00
Undo - > PushItem ( EDIT_UNDO_DEL_TEXT | batch_mode , currline , _qlen1 , ptr - _qlenptr ) ;
2000-03-22 17:59:18 +00:00
currline - > txt . erase ( _qlen1 , ptr - _qlenptr ) ;
2000-02-25 11:04:07 +00:00
}
// Perform the reflow
while ( reflowok ( _qstr1 ) ) {
// Work on the current line until it is done
Line * _thisline = currline ;
while ( _thisline = = currline ) {
// Stop reflow?
if ( not reflowok ( _qstr1 ) )
break ;
// Go to the EOL, insert a space and delete the LF
GoEOL ( ) ;
if ( col + 1 < maxcol ) {
insertchar ( ' ' ) ;
DelChar ( ) ;
}
else {
GoDown ( ) ;
col = mincol ;
}
}
}
// Go to the next line
displine ( currline , row ) ;
GoDown ( ) ;
2005-10-28 04:59:49 +00:00
col = mincol ;
2000-02-25 11:04:07 +00:00
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : ExitMsg ( ) {
GFTRK ( " EditExitMsg " ) ;
done = MODE_QUIT ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : DelLine ( ) {
GFTRK ( " EditDelLine " ) ;
cursoroff ( ) ;
deleteline ( ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : ToUpper ( ) {
GFTRK ( " EditToUpper " ) ;
2001-02-19 22:53:24 +00:00
if ( col < currline - > txt . length ( ) ) {
Undo - > PushItem ( EDIT_UNDO_OVR_CHAR ) ;
2005-10-31 22:18:26 +00:00
currline - > txt [ col ] = g_toupper ( currline - > txt [ col ] ) ;
2001-02-19 22:53:24 +00:00
}
2000-02-25 11:04:07 +00:00
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : ToLower ( ) {
GFTRK ( " EditToLower " ) ;
2001-05-17 05:14:33 +00:00
if ( col < currline - > txt . length ( ) ) {
2001-02-19 22:53:24 +00:00
Undo - > PushItem ( EDIT_UNDO_OVR_CHAR ) ;
2005-10-31 22:18:26 +00:00
currline - > txt [ col ] = g_tolower ( currline - > txt [ col ] ) ;
2001-02-19 22:53:24 +00:00
}
2000-02-25 11:04:07 +00:00
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : ToggleCase ( ) {
GFTRK ( " EditToggleCase " ) ;
2005-11-01 02:31:41 +00:00
if ( col < currline - > txt . length ( ) )
{
2001-02-19 22:53:24 +00:00
Undo - > PushItem ( EDIT_UNDO_OVR_CHAR ) ;
2005-11-01 02:31:41 +00:00
char chr = currline - > txt [ col ] ;
if ( g_isupper ( chr ) )
currline - > txt [ col ] = g_tolower ( chr ) ;
2001-02-19 22:53:24 +00:00
else
2005-11-01 02:31:41 +00:00
currline - > txt [ col ] = g_toupper ( chr ) ;
2001-02-19 22:53:24 +00:00
}
2000-02-25 11:04:07 +00:00
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
2005-10-05 20:35:22 +00:00
// ------------------------------------------------------------------
void IEclass : : ToggleCaseChar ( gkey key ,
std : : string : : iterator it ,
Line * ln , int n )
{
int oldchar = * it ;
2005-11-03 11:58:16 +00:00
int newchar = 0 ;
2005-10-05 20:35:22 +00:00
switch ( key )
{
case KK_EditToLower :
2005-11-01 02:31:41 +00:00
newchar = g_tolower ( oldchar ) ;
2005-10-05 20:35:22 +00:00
break ;
case KK_EditToUpper :
2005-11-01 02:31:41 +00:00
newchar = g_toupper ( oldchar ) ;
2005-10-05 20:35:22 +00:00
break ;
case KK_EditToggleCase :
2005-11-01 02:31:41 +00:00
if ( g_isupper ( oldchar ) )
newchar = g_tolower ( oldchar ) ;
2005-10-05 20:35:22 +00:00
else
2005-11-01 02:31:41 +00:00
newchar = g_toupper ( oldchar ) ;
2005-10-05 20:35:22 +00:00
break ;
}
if ( newchar ! = oldchar )
{
currline = ln ; pcol = col = n ; getthisrow ( currline ) ; prow = thisrow ;
Undo - > PushItem ( EDIT_UNDO_OVR_CHAR ) ;
* it = newchar ;
}
}
// ------------------------------------------------------------------
void IEclass : : ToggleCaseBlock ( gkey key )
{
GFTRK ( " EditToggleCaseBlock " ) ;
// Find the anchor, if any
Line * _anchor = findanchor ( ) ;
// Did we find the anchor?
if ( _anchor )
{
Line * oldline = currline ;
int oldcol = col ;
Line * _firstline = currline ;
Line * _lastline = currline ;
int firstcol = col , lastcol = col ;
// Search below to find the anchor line
while ( _lastline - > next and ( _lastline ! = _anchor ) )
_lastline = _lastline - > next ;
// Was the anchor line above or on the current line?
if ( _lastline ! = _anchor )
{
// The last copy line is the current line
_lastline = currline ;
// Search above to find the anchor line
while ( _firstline - > prev and ( _firstline ! = _anchor ) )
_firstline = _firstline - > prev ;
firstcol = blockcol ;
}
else
{
if ( currline ! = _anchor or blockcol > col )
lastcol = blockcol ;
else
firstcol = blockcol ;
}
// The _firstline and _lastline pointers
// are now pointing where they should
int n ;
Line * ln = _firstline ;
std : : string : : iterator it1 , it2 ;
if ( ln = = _lastline )
{
it1 = ln - > txt . begin ( ) + firstcol ;
it2 = ln - > txt . begin ( ) + lastcol ;
for ( n = firstcol ; it1 < it2 ; it1 + + , n + + )
ToggleCaseChar ( key , it1 , ln , n ) ;
}
else
{
it1 = ln - > txt . begin ( ) + firstcol ;
it2 = ln - > txt . end ( ) ;
for ( n = firstcol ; it1 < it2 ; it1 + + , n + + )
ToggleCaseChar ( key , it1 , ln , n ) ;
for ( ln = ln - > next ; ln ! = _lastline ; ln = ln - > next )
{
it1 = ln - > txt . begin ( ) ;
it2 = ln - > txt . end ( ) ;
for ( n = 0 ; it1 < it2 ; it1 + + , n + + )
ToggleCaseChar ( key , it1 , ln , n ) ;
}
it1 = ln - > txt . begin ( ) ;
it2 = ln - > txt . begin ( ) + lastcol ;
for ( n = 0 ; it1 < it2 ; it1 + + , n + + )
ToggleCaseChar ( key , it1 , ln , n ) ;
}
currline = oldline ;
pcol = col = oldcol ;
getthisrow ( currline ) ;
prow = thisrow ;
}
// Refresh display
Line * _topline = findtopline ( ) ;
refresh ( _topline , minrow ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2005-10-05 20:35:22 +00:00
}
2005-09-27 18:30:31 +00:00
// ------------------------------------------------------------------
void IEclass : : SCodeChange ( gkey key )
{
GFTRK ( " EditSCodeChange " ) ;
char _ch = ' ' ;
switch ( key )
{
case KK_EditSCodeBold : _ch = ' * ' ; break ;
case KK_EditSCodeUnderline : _ch = ' _ ' ; break ;
case KK_EditSCodeItalic : _ch = ' / ' ; break ;
case KK_EditSCodeReverse : _ch = ' # ' ; break ;
}
2005-09-29 15:44:25 +00:00
const char * cltxt = currline - > txt . c_str ( ) ;
const char * punct = CFG - > stylecodepunct ;
if ( isspace ( cltxt [ col ] ) | | strchr ( punct , cltxt [ col ] ) )
2005-09-27 18:30:31 +00:00
{
2005-09-29 15:44:25 +00:00
if ( col & & ! isspace ( cltxt [ col - 1 ] ) & & ! strchr ( punct , cltxt [ col - 1 ] ) )
2005-09-27 18:30:31 +00:00
GoLeft ( ) ;
2005-09-29 15:44:25 +00:00
else if ( ! isspace ( cltxt [ col + 1 ] ) & & ! strchr ( punct , cltxt [ col + 1 ] ) )
2005-09-27 18:30:31 +00:00
GoRight ( ) ;
else
{
2005-09-29 15:44:25 +00:00
if ( isspace ( cltxt [ col ] ) & & ( key ! = KK_EditSCodeNormal ) )
2005-09-27 18:30:31 +00:00
{
2005-09-29 15:44:25 +00:00
if ( col & & ! isspace ( cltxt [ col - 1 ] ) )
2005-09-27 18:30:31 +00:00
insertchar ( ' ' ) ;
insertchar ( _ch ) ;
insertchar ( _ch ) ;
GoLeft ( ) ;
}
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2005-09-27 18:30:31 +00:00
return ;
}
}
uint beg = col ;
uint end = col ;
2005-09-29 15:44:25 +00:00
while ( beg & & ! isspace ( cltxt [ beg - 1 ] ) & & ! strchr ( punct , cltxt [ beg - 1 ] ) )
2005-09-27 18:30:31 +00:00
beg - - ;
2005-09-29 15:44:25 +00:00
while ( ! isspace ( cltxt [ end + 1 ] ) & & ! strchr ( punct , cltxt [ end + 1 ] ) )
2005-09-27 18:30:31 +00:00
end + + ;
bool replace = false ;
2005-09-29 15:44:25 +00:00
char c1 = cltxt [ beg ] ;
char c2 = cltxt [ end ] ;
2005-09-27 18:30:31 +00:00
if ( ( _ch = = c1 ) & & ( c1 = = c2 ) )
{
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2005-09-27 18:30:31 +00:00
return ;
}
2006-01-14 23:48:53 +00:00
if ( ( _ch ! = c1 ) & & ( c1 = = c2 ) & &
2005-09-27 18:30:31 +00:00
( ( c1 = = ' * ' ) | | ( c1 = = ' / ' ) | | ( c1 = = ' _ ' ) | | ( c1 = = ' # ' ) ) )
replace = true ;
2005-09-29 15:44:25 +00:00
while ( col & & ! isspace ( cltxt [ col - 1 ] ) & & ! strchr ( punct , cltxt [ col - 1 ] ) )
2005-09-27 18:30:31 +00:00
GoLeft ( ) ;
if ( replace ) DelChar ( ) ;
if ( _ch ! = ' ' ) insertchar ( _ch ) ;
2005-09-29 15:44:25 +00:00
cltxt = currline - > txt . c_str ( ) ;
2006-01-14 23:48:53 +00:00
while ( ! isspace ( cltxt [ col + 1 ] ) & & ! strchr ( punct , cltxt [ col + 1 ] ) )
2005-09-27 18:30:31 +00:00
GoRight ( ) ;
if ( replace ) DelChar ( ) ;
else GoRight ( ) ;
if ( _ch ! = ' ' ) insertchar ( _ch ) ;
GoLeft ( ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2005-09-27 18:30:31 +00:00
}
2000-02-25 11:04:07 +00:00
// ------------------------------------------------------------------
void IEclass : : LookupCursor ( ) {
GFTRK ( " EditLookupCursor " ) ;
2000-03-22 17:59:18 +00:00
LookupNode ( msgptr , currline - > txt . c_str ( ) + col , LOOK_NAME ) ;
2000-02-25 11:04:07 +00:00
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : LookupDest ( ) {
GFTRK ( " EditLookupDest " ) ;
LookupNode ( msgptr , " " , LOOK_DEST ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : LookupOrig ( ) {
GFTRK ( " EditLookupOrig " ) ;
LookupNode ( msgptr , " " , LOOK_ORIG ) ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void IEclass : : Soundkill ( ) {
HandleGEvent ( EVTT_STOPVOICE ) ;
}
// ------------------------------------------------------------------
void IEclass : : statusline ( ) {
if ( chartyped ) {
if ( EDIT - > Completion . First ( ) ) {
do {
const char * trig = EDIT - > Completion . Trigger ( ) ;
uint tlen = strlen ( trig ) ;
if ( col > = tlen ) {
2000-03-22 17:59:18 +00:00
if ( strneql ( trig , currline - > txt . c_str ( ) + col - tlen , tlen ) ) {
2003-03-26 16:05:36 +00:00
int saved_insert = insert ;
insert = true ;
batch_mode = BATCH_MODE ;
2000-02-25 11:04:07 +00:00
uint n ;
for ( n = 0 ; n < tlen ; n + + )
DelLeft ( ) ;
const char * cptr = EDIT - > Completion . Text ( ) ;
uint clen = strlen ( cptr ) ;
for ( n = 0 ; n < clen ; n + + )
insertchar ( * cptr + + ) ;
HandleGEvent ( EVTT_EDITCOMPLETION ) ;
2003-03-26 16:05:36 +00:00
insert = saved_insert ;
2000-02-25 11:04:07 +00:00
break ;
}
}
} while ( EDIT - > Completion . Next ( ) ) ;
}
}
char _buf [ EDIT_BUFLEN ] ;
* _buf = NUL ;
if ( EDIT - > Comment . First ( ) ) {
do {
const char * trig = EDIT - > Comment . Trigger ( ) ;
uint tlen = strlen ( trig ) ;
if ( col > = tlen ) {
2000-03-22 17:59:18 +00:00
if ( strnieql ( trig , currline - > txt . c_str ( ) + col - tlen , tlen ) ) {
2000-02-25 11:04:07 +00:00
strcpy ( _buf , EDIT - > Comment . Text ( ) ) ;
break ;
}
}
} while ( EDIT - > Comment . Next ( ) ) ;
}
2005-12-20 23:10:09 +00:00
uint chr = currline - > txt [ col ] ;
2006-01-10 23:53:52 +00:00
update_statuslinef ( LNG - > EditStatus , " ST_EDITSTATUS " , 1 + thisrow , 1 + col , chr , _buf ) ;
2000-02-25 11:04:07 +00:00
if ( * _buf and CFG - > switches . get ( beepcomment ) ) {
HandleGEvent ( EVTT_EDITCOMMENT ) ;
}
}
// ------------------------------------------------------------------
int IEclass : : handlekey ( gkey __key ) {
2000-12-24 19:47:06 +00:00
int rc = true ;
2000-02-25 11:04:07 +00:00
2006-04-05 15:56:53 +00:00
if ( drawlines )
2005-12-25 10:17:00 +00:00
{
2006-04-05 15:56:53 +00:00
switch ( __key )
{
case KK_EditBlockRight :
case KK_EditBlockLeft :
case KK_EditBlockUp :
case KK_EditBlockDown :
DrawLines ( __key ) ;
case KK_EditBlockHome :
case KK_EditBlockEnd :
case KK_EditBlockPgDn :
case KK_EditBlockPgUp :
case KK_EditBlockWordRight :
case KK_EditBlockWordLeft :
undo_ready = NO ;
return rc ;
default :
drawflag = true ;
}
2005-12-25 10:17:00 +00:00
}
switch ( __key )
{
2000-02-25 11:04:07 +00:00
case KK_EditBlockRight : __key = KK_EditGoRight ; break ;
case KK_EditBlockLeft : __key = KK_EditGoLeft ; break ;
case KK_EditBlockUp : __key = KK_EditGoUp ; break ;
case KK_EditBlockDown : __key = KK_EditGoDown ; break ;
case KK_EditBlockHome : __key = KK_EditGoBegLine ; break ;
case KK_EditBlockEnd : __key = KK_EditGoEOL ; break ;
case KK_EditBlockPgDn : __key = KK_EditGoPgDn ; break ;
case KK_EditBlockPgUp : __key = KK_EditGoPgUp ; break ;
2005-10-06 17:50:55 +00:00
case KK_EditBlockWordRight : __key = KK_EditGoWordRight ; break ;
case KK_EditBlockWordLeft : __key = KK_EditGoWordLeft ; break ;
2000-02-25 11:04:07 +00:00
case KK_EditCopy :
case KK_EditCut :
case KK_EditDelete : goto noselecting ;
case KK_EditDelChar :
case KK_EditDelLeft :
2002-10-26 16:28:01 +00:00
if ( selecting ) {
__key = KK_EditUndefine ;
}
// fall through
2000-02-25 11:04:07 +00:00
case KK_EditPaste :
2002-10-26 16:28:01 +00:00
case KK_EditNewline :
2000-02-25 11:04:07 +00:00
if ( selecting ) {
BlockCut ( true ) ;
batch_mode = BATCH_MODE ;
}
goto noselecting ;
break ;
2005-10-05 20:35:22 +00:00
case KK_EditToLower :
case KK_EditToUpper :
case KK_EditToggleCase :
if ( ! selecting ) goto noselecting ;
ToggleCaseBlock ( __key ) ;
undo_ready = NO ;
return rc ;
2000-02-25 11:04:07 +00:00
default :
2000-12-24 19:47:06 +00:00
rc = PlayMacro ( __key , KT_E ) ;
if ( rc = = true )
return rc ;
rc = true ;
2000-02-25 11:04:07 +00:00
if ( selecting ) {
Line * _line ;
selecting = NO ;
blockcol = - 1 ;
for ( _line = findfirstline ( ) ; _line ; _line = _line - > next )
_line - > type & = ~ GLINE_BLOK ;
// refresh screen
int r = row ;
for ( _line = currline ; _line and r ; _line = _line - > prev )
r - - ;
refresh ( _line , minrow ) ;
}
goto noselecting ;
}
if ( not selecting ) {
Line * _line ;
for ( _line = findfirstline ( ) ; _line ; _line = _line - > next )
_line - > type & = ~ GLINE_BLOK ;
currline - > type | = GLINE_BLOK ;
selecting = YES ;
blockcol = col ;
// refresh screen
int r = row ;
for ( _line = currline ; _line and r ; _line = _line - > prev )
r - - ;
refresh ( _line , minrow ) ;
}
noselecting :
switch ( __key ) {
case KK_EditAbort : Abort ( ) ; break ;
case KK_EditAskExit : AskExit ( ) ; break ;
case KK_EditClearDeleteBuf : ClearDeleteBuf ( ) ; break ;
case KK_EditClearPasteBuf : ClearPasteBuf ( ) ; break ;
case KK_EditCopyAboveChar : CopyAboveChar ( ) ; break ;
case KK_EditDelChar : DelChar ( ) ; break ;
case KK_EditDeleteEOL : DeleteEOL ( ) ; break ;
2001-08-31 14:14:27 +00:00
case KK_EditDeleteSOL : DeleteSOL ( ) ; break ;
2000-02-25 11:04:07 +00:00
case KK_EditDelLeft : DelLeft ( ) ; break ;
case KK_EditDelLine : DelLine ( ) ; break ;
case KK_EditDelLtWord : DelLtWord ( ) ; break ;
case KK_EditDelRtWord : DelRtWord ( ) ; break ;
case KK_EditDosShell : DosShell ( ) ; break ;
case KK_EditDupLine : DupLine ( ) ; break ;
case KK_EditExitMsg : ExitMsg ( ) ; break ;
case KK_EditExportText : ExportText ( ) ; break ;
case KK_EditGoBegLine : GoBegLine ( ) ; break ;
case KK_EditGoBotLine : GoBotLine ( ) ; break ;
case KK_EditGoBotMsg : GoBotMsg ( ) ; break ;
case KK_EditGoDown : GoDown ( ) ; break ;
case KK_EditGoEOL : GoEOL ( ) ; break ;
case KK_EditGoLeft : GoLeft ( ) ; break ;
case KK_EditGoPgDn : GoPgDn ( ) ; break ;
case KK_EditGoPgUp : GoPgUp ( ) ; break ;
case KK_EditGoRight : GoRight ( ) ; break ;
case KK_EditGoTopLine : GoTopLine ( ) ; break ;
case KK_EditGoTopMsg : GoTopMsg ( ) ; break ;
case KK_EditGoUp : GoUp ( ) ; break ;
case KK_EditGoWordLeft : GoWordLeft ( ) ; break ;
case KK_EditGoWordRight : GoWordRight ( ) ; break ;
case KK_EditHeader : Header ( ) ; break ;
case KK_EditImportQuotebuf : ImportQuotebuf ( ) ; break ;
case KK_EditImportText : ImportText ( ) ; break ;
case KK_EditLoadFile : LoadFile ( ) ; break ;
case KK_EditLookupCursor : LookupCursor ( ) ; break ;
case KK_EditLookupDest : LookupDest ( ) ; break ;
case KK_EditLookupOrig : LookupOrig ( ) ; break ;
case KK_EditNewline : Newline ( ) ; break ;
case KK_EditQuitNow : QuitNow ( ) ; break ;
case KK_EditReflow : Reflow ( ) ; break ;
case KK_EditSaveFile : SaveFile ( ) ; break ;
case KK_EditSaveMsg : SaveMsg ( ) ; break ;
2006-03-11 17:04:06 +00:00
# if defined(GCFG_SPELL_INCLUDED)
2005-11-28 20:06:38 +00:00
case KK_EditSCheckerMenu : SCheckerMenu ( ) ; break ;
# endif
2000-02-25 11:04:07 +00:00
case KK_EditSoundkill : Soundkill ( ) ; break ;
case KK_EditSpellCheck : SpellCheck ( ) ; break ;
case KK_EditTab : Tab ( ) ; break ;
case KK_EditTabReverse : ReTab ( ) ; break ;
case KK_EditToggleCase : ToggleCase ( ) ; break ;
case KK_EditToggleInsert : ToggleInsert ( ) ; break ;
case KK_EditToLower : ToLower ( ) ; break ;
case KK_EditToUpper : ToUpper ( ) ; break ;
case KK_EditUndefine : break ;
case KK_EditUnDelete : UnDelete ( ) ; break ;
case KK_EditUndo : Undo - > PlayItem ( ) ; break ;
case KK_EditZapQuoteBelow : ZapQuoteBelow ( ) ; break ;
2005-09-27 18:30:31 +00:00
case KK_EditSCodeNormal :
case KK_EditSCodeBold :
case KK_EditSCodeItalic :
case KK_EditSCodeUnderline :
case KK_EditSCodeReverse : SCodeChange ( __key ) ; break ;
2005-12-25 10:17:00 +00:00
case KK_EditDrawLines : ToggleDrawLines ( ) ; break ;
2000-02-25 11:04:07 +00:00
// Block functions
case KK_EditAnchor : BlockAnchor ( ) ; break ;
case KK_EditCopy : BlockCopy ( ) ; break ;
case KK_EditCut : BlockCut ( ) ; break ;
case KK_EditDelete : BlockCut ( true ) ; break ;
case KK_EditPaste : BlockPaste ( ) ; break ;
default :
2000-12-24 19:47:06 +00:00
rc = false ;
break ;
2000-02-25 11:04:07 +00:00
}
if ( __key ! = KK_EditUndo )
undo_ready = NO ;
2006-01-14 23:48:53 +00:00
2000-02-25 11:04:07 +00:00
return rc ;
}
// ------------------------------------------------------------------
int IEclass : : Start ( int __mode , uint * __position , GMsg * __msg ) {
GFTRK ( " EditStart " ) ;
thisrow = 0 ;
quitnow = NO ;
col = mincol ;
row = minrow ;
msgptr = __msg ;
msgmode = __mode ;
currline = __msg - > lin ;
2006-03-11 17:04:06 +00:00
# if defined(GCFG_SPELL_INCLUDED)
2005-11-28 20:06:38 +00:00
if ( CFG - > scheckerenabled )
{
2012-05-15 17:02:39 +00:00
int save_chartableno = LoadCharset ( NULL , NULL , 1 ) ; // Workaround: internal for LoadCharset() charset table number changed in the schecker.Load()
2006-03-11 17:04:06 +00:00
schecker . Init ( CFG - > xlatlocalset , CFG - > scheckerdicpath ) ;
2011-03-15 07:32:45 +00:00
char * str = strdup ( AA - > adat - > scheckerdeflang ) ;
2011-03-14 02:56:12 +00:00
char * token = strtok ( str , " " ) ;
while ( token ! = NULL )
{
schecker . Load ( token , CFG - > scheckeruserdic ) ;
/* Get next token: */
token = strtok ( NULL , " " ) ;
}
2011-03-15 07:32:45 +00:00
free ( str ) ;
2012-05-15 17:02:39 +00:00
if ( save_chartableno ! = - 1 ) // restore value of the default chaset table // workaround: internal for LoadCharset() charset table number changed in the schecker.Load()
LoadCharset ( CFG - > xlatcharset [ save_chartableno ] . imp , CFG - > xlatcharset [ save_chartableno ] . exp ) ;
else
LoadCharset ( " N/A " , " N/A " ) ;
2005-11-28 20:06:38 +00:00
}
# endif
2001-02-19 22:53:24 +00:00
if ( AA - > isinternet ( ) and ( CFG - > soupexportmargin < = CFG - > dispmargin ) )
2000-02-25 11:04:07 +00:00
margintext = CFG - > soupexportmargin ;
else
margintext = CFG - > dispmargin ;
2001-08-07 10:51:00 +00:00
marginquotes = EDIT - > QuoteMargin ( ) + 1 ; // Add one for CR
2000-02-25 11:04:07 +00:00
if ( marginquotes > margintext )
marginquotes = margintext ;
if ( currline = = NULL ) {
2000-03-22 17:59:18 +00:00
currline = new Line ( " \n " ) ;
throw_xnew ( currline ) ;
2000-02-25 11:04:07 +00:00
}
// Check if there is an unfinished backup message
2006-04-26 17:06:23 +00:00
gfile _fp ( AddPath ( CFG - > goldpath , EDIT - > File ( ) ) , " rt " , CFG - > sharemode ) ;
2006-05-13 16:15:35 +00:00
if ( _fp . isopen ( ) )
2006-04-26 17:06:23 +00:00
{
2000-02-25 11:04:07 +00:00
char _buf [ EDIT_BUFLEN ] ;
2006-04-26 17:06:23 +00:00
_fp . Fgets ( _buf , sizeof ( _buf ) ) ;
_fp . Fclose ( ) ;
if ( striinc ( unfinished , _buf ) )
{
2000-02-25 11:04:07 +00:00
w_info ( LNG - > UnfinishedMsg ) ;
update_statusline ( LNG - > LoadUnfinished ) ;
HandleGEvent ( EVTT_ATTENTION ) ;
gkey _ch = getxch ( ) ;
w_info ( NULL ) ;
if ( _ch ! = Key_Esc ) {
LoadFile ( ) ;
* __position = 0 ;
remove ( AddPath ( CFG - > goldpath , EDIT - > File ( ) ) ) ;
}
}
}
if ( * __position ) {
for ( uint _posrow = 0 ; _posrow < * __position ; _posrow + + ) {
if ( currline - > next ) {
currline = currline - > next ;
row + + ;
}
}
thisrow = row ;
}
done = NO ;
// If the starting line is outside the first screenful
if ( * __position > = ( maxrow + 1 ) ) {
refresh ( currline - > prev , minrow ) ;
row = 1 ;
}
else {
refresh ( findfirstline ( ) , minrow ) ;
}
gotorowcol ( mincol , minrow ) ;
dispins ( ) ;
2005-10-20 21:10:42 +00:00
time32_t _lasttime = gtime ( NULL ) ;
2000-02-25 11:04:07 +00:00
while ( not done ) {
statusline ( ) ;
gotorowcol ( col , row ) ;
batch_mode = 0 ;
2006-01-20 00:15:05 +00:00
vattr backattr = BLACK_ | _BLACK ;
2000-02-25 11:04:07 +00:00
if ( blockcol = = - 1 ) {
2000-05-22 17:17:43 +00:00
backattr = dispchar ( currline - > txt . c_str ( ) [ col ] , C_READC ) ;
2000-02-25 11:04:07 +00:00
gotorowcol ( col , row ) ;
}
cursoron ( ) ;
if ( insert )
vcursmall ( ) ;
else
vcurlarge ( ) ;
gkey _ch ;
2006-01-14 23:48:53 +00:00
# if defined(__WIN32__)
2005-10-06 17:50:55 +00:00
gkey keystatus = 0 ;
2006-01-14 23:48:53 +00:00
# endif
2000-02-25 11:04:07 +00:00
do {
_ch = getxchtick ( ) ;
2005-10-06 17:50:55 +00:00
// TO_PORT_TAG: kbxget_raw(3)
# if defined(__WIN32__)
keystatus = kbxget_raw ( 3 ) ;
# endif
2000-02-25 11:04:07 +00:00
if ( EDIT - > AutoSave ( ) ) {
2005-10-20 21:10:42 +00:00
time32_t _thistime = gtime ( NULL ) ;
2000-02-25 11:04:07 +00:00
if ( _thistime > = ( _lasttime + EDIT - > AutoSave ( ) ) ) {
_lasttime = _thistime ;
SaveFile ( ) ;
}
}
if ( _ch = = Key_Tick )
CheckTick ( KK_EditQuitNow ) ;
} while ( _ch = = Key_Tick ) ;
pcol = col ; getthisrow ( currline ) ; prow = thisrow ;
int ismacro = false ;
gkey _kk = SearchKey ( _ch , EditKey , EditKeys ) ;
if ( _kk ) {
_ch = _kk ;
2005-10-06 17:50:55 +00:00
// TO_PORT_TAG: kbxget_raw(3)
# if defined(__WIN32__)
if ( keystatus & SHIFT_PRESSED )
# else
if ( 0 )
# endif
{
switch ( _ch )
{
case KK_EditGoUp : _ch = KK_EditBlockUp ; break ;
case KK_EditGoDown : _ch = KK_EditBlockDown ; break ;
case KK_EditGoLeft : _ch = KK_EditBlockLeft ; break ;
case KK_EditGoWordLeft : _ch = KK_EditBlockWordLeft ; break ;
case KK_EditGoRight : _ch = KK_EditBlockRight ; break ;
case KK_EditGoWordRight : _ch = KK_EditBlockWordRight ; break ;
case KK_EditGoBegLine :
case KK_EditGoTopMsg : _ch = KK_EditBlockHome ; break ;
case KK_EditGoEOL :
case KK_EditGoBotMsg : _ch = KK_EditBlockEnd ; break ;
case KK_EditGoPgUp :
case KK_EditGoTopLine : _ch = KK_EditBlockPgUp ; break ;
case KK_EditGoPgDn :
case KK_EditGoBotLine : _ch = KK_EditBlockPgDn ; break ;
}
}
2000-02-25 11:04:07 +00:00
}
else {
ismacro = IsMacro ( _ch , KT_E ) ;
}
if ( blockcol = = - 1 )
2000-05-22 17:17:43 +00:00
dispchar ( currline - > txt . c_str ( ) [ col ] , backattr ) ;
2000-02-25 11:04:07 +00:00
chartyped = false ;
if ( ( _ch < KK_Commands ) and ( _ch & 0xFF ) and not ismacro ) {
2005-12-25 10:17:00 +00:00
drawflag = true ;
2000-02-25 11:04:07 +00:00
chartyped = true ;
_ch & = 0xFF ;
insertchar ( ( char ) _ch ) ;
undo_ready = YES ;
}
else if ( handlekey ( _ch ) ) {
getthisrow ( currline ) ;
}
}
cursoroff ( ) ;
msgptr - > lin = findfirstline ( ) ;
savefile ( quitnow ? MODE_UPDATE : MODE_SAVE ) ;
// Prune killbuffer
if ( Edit__killbuf ) {
Line * __line = Edit__killbuf ;
int _count = EDIT - > UnDelete ( ) ;
while ( __line and _count - - )
__line = __line - > prev ;
if ( __line )
if ( __line - > next )
__line - > next - > prev = NULL ;
while ( __line ) {
if ( Undo - > FixPushLine ( __line ) ) {
if ( __line - > prev ) {
__line = __line - > prev ;
__line - > next = NULL ;
}
else {
__line = NULL ;
}
}
else {
if ( __line - > prev ) {
__line = __line - > prev ;
2000-03-22 17:59:18 +00:00
throw_xdelete ( __line - > next ) ;
2000-02-25 11:04:07 +00:00
}
2000-03-22 17:59:18 +00:00
else
throw_xdelete ( __line ) ;
2000-02-25 11:04:07 +00:00
}
}
}
* __position = 1 + thisrow ;
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
return done ;
}
// ------------------------------------------------------------------
UndoStack : : UndoStack ( IEclass * this_editor ) :
editor ( this_editor ) ,
row ( editor - > row ) ,
col ( editor - > col ) ,
pcol ( editor - > pcol ) ,
prow ( editor - > prow ) ,
minrow ( editor - > minrow ) ,
maxrow ( editor - > maxrow ) ,
thisrow ( editor - > thisrow ) ,
2006-01-14 23:48:53 +00:00
currline ( editor - > currline ) ,
2000-02-25 11:04:07 +00:00
undo_ready ( editor - > undo_ready ) {
UndoItem : : last_item = & last_item ;
last_item = NULL ;
undo_enabled = YES ;
}
// ------------------------------------------------------------------
UndoStack : : ~ UndoStack ( ) {
while ( last_item ) {
switch ( last_item - > action & EDIT_UNDO_ACTION ) {
case EDIT_UNDO_DEL_TEXT :
2000-11-27 06:15:29 +00:00
case EDIT_UNDO_INS_TEXT :
2000-02-25 11:04:07 +00:00
case EDIT_UNDO_WRAP_TEXT :
2000-03-22 17:59:18 +00:00
throw_delete ( last_item - > data . text_ptr ) ;
2000-02-25 11:04:07 +00:00
break ;
case EDIT_UNDO_DEL_LINE :
2000-03-22 17:59:18 +00:00
throw_xdelete ( last_item - > data . line_ptr ) ;
2000-02-25 11:04:07 +00:00
}
delete last_item ;
}
}
// ------------------------------------------------------------------
bool UndoStack : : FixPushLine ( Line * __line ) {
UndoItem * item = last_item ;
while ( item ) {
if ( ( ( item - > action & EDIT_UNDO_ACTION ) = = EDIT_UNDO_PUSH_LINE ) and ( item - > data . line_ptr = = __line ) ) {
item - > action & = ~ EDIT_UNDO_ACTION ;
item - > action | = EDIT_UNDO_ORPHAN_LINE ;
return true ;
}
item = item - > prev ;
}
return false ;
}
// ------------------------------------------------------------------
void UndoStack : : PushItem ( uint action , Line * __line , uint __col , uint __len ) {
2000-11-12 22:34:28 +00:00
GFTRK ( " PushItem " ) ;
2000-02-25 11:04:07 +00:00
if ( undo_enabled ) {
throw_new ( last_item = new UndoItem ) ;
last_item - > col . num = ( __col ! = NO_VALUE ) ? __col : col ;
last_item - > col . sav = 0 ;
last_item - > action = action ;
last_item - > pcol = pcol ;
last_item - > prow = prow ;
switch ( action & EDIT_UNDO_ACTION ) {
case EDIT_UNDO_VOID :
case EDIT_UNDO_INS_CHAR :
last_item - > line = __line ? __line : currline ;
2001-10-21 17:44:12 +00:00
last_item - > data . char_int = NUL ;
2000-02-25 11:04:07 +00:00
break ;
case EDIT_UNDO_DEL_CHAR :
case EDIT_UNDO_OVR_CHAR :
last_item - > line = __line ? __line : currline ;
2000-03-22 17:59:18 +00:00
last_item - > data . char_int = last_item - > line - > txt [ last_item - > col . num ] ;
2000-02-25 11:04:07 +00:00
break ;
case EDIT_UNDO_DEL_TEXT :
last_item - > line = __line ;
2000-10-24 05:02:25 +00:00
__col = last_item - > col . num ;
2000-02-25 11:04:07 +00:00
if ( __len = = NO_VALUE )
2001-06-04 03:40:38 +00:00
__len = __line - > txt . length ( ) - __col ;
2000-02-25 11:04:07 +00:00
throw_new ( last_item - > data . text_ptr = new ( __len ) text_item ( __col , __len ) ) ;
2000-03-22 17:59:18 +00:00
memcpy ( last_item - > data . text_ptr - > text , __line - > txt . c_str ( ) + __col , __len ) ;
2000-02-25 11:04:07 +00:00
break ;
case EDIT_UNDO_CUT_TEXT :
last_item - > line = __line ;
2001-10-21 17:44:12 +00:00
last_item - > data . text_ptr = NULL ;
2000-02-25 11:04:07 +00:00
break ;
case EDIT_UNDO_INS_TEXT :
case EDIT_UNDO_WRAP_TEXT :
2000-06-16 23:30:48 +00:00
last_item - > line = __line ;
2001-02-20 21:29:42 +00:00
if ( __len = = NO_VALUE )
2001-05-09 20:45:13 +00:00
__len = __line - > txt . length ( ) - __col ;
2000-12-24 19:47:06 +00:00
throw_new ( last_item - > data . text_ptr = new text_item ( __col , __len ) ) ;
2000-02-25 11:04:07 +00:00
break ;
case EDIT_UNDO_NEW_LINE :
last_item - > line = last_item - > data . line_ptr = __line ;
break ;
case EDIT_UNDO_DEL_LINE :
last_item - > line = __line - > prev ? __line - > prev : __line - > next ;
last_item - > data . line_ptr = __line ;
break ;
case EDIT_UNDO_PUSH_LINE :
if ( currline - > next )
last_item - > line = currline - > next ;
else {
last_item - > action | = LAST_LINE ;
last_item - > line = currline - > prev ;
}
last_item - > data . line_ptr = currline ;
break ;
case EDIT_UNDO_POP_LINE :
last_item - > line = currline ;
2001-10-21 17:44:12 +00:00
last_item - > data . line_ptr = NULL ;
break ;
2006-01-14 23:48:53 +00:00
}
2000-02-25 11:04:07 +00:00
}
2000-11-12 22:34:28 +00:00
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------
void UndoStack : : PlayItem ( ) {
2000-11-12 22:34:28 +00:00
GFTRK ( " PlayItem " ) ;
2000-02-25 11:04:07 +00:00
if ( last_item ) {
UndoItem * item ;
// Don't save any new items while in Undo function
undo_enabled = NO ;
// Find first of the batch items
for ( item = last_item ; item - > action & BATCH_MODE ; item = item - > prev ) ;
uint curr_row_num = thisrow ;
uint curr_col_num = col ;
2002-11-23 16:06:53 +00:00
if ( ( item - > action & PREV_LINE ) and item - > line - > next )
currline = item - > line - > next ;
else
currline = item - > line ;
2000-02-25 11:04:07 +00:00
editor - > getthisrow ( currline ) ;
2002-11-23 16:06:53 +00:00
int _maxrow = maxrow ;
if ( ( item - > action & PREV_LINE ) and not item - > line - > next )
_maxrow - - ;
2000-02-25 11:04:07 +00:00
col = item - > col . num ;
if ( curr_row_num ! = thisrow ) {
// Let user to see the position before performing Undo, unless it's a
// neighbour line and the same column.
2000-11-12 22:34:28 +00:00
undo_ready = ( ( abs ( int ( curr_row_num - thisrow ) ) < 2 ) and ( ( curr_col_num = = col ) or ( col + 1 > currline - > txt . length ( ) ) ) ) ;
2000-02-25 11:04:07 +00:00
// Move cursor up or down depending on where the undo line is,
// then refresh window if the line is invisible.
do {
if ( curr_row_num > thisrow ) {
if ( row > minrow )
curr_row_num - - , row - - ;
else {
editor - > refresh ( currline , row ) ;
break ;
}
}
else {
2002-11-23 16:06:53 +00:00
if ( row < _maxrow )
2000-02-25 11:04:07 +00:00
curr_row_num + + , row + + ;
else {
Line * l = currline ;
for ( uint r = row ; r ; l = l - > prev , r - - ) { }
editor - > refresh ( l , minrow ) ;
break ;
}
}
} while ( curr_row_num ! = thisrow ) ;
}
else
2000-11-12 22:34:28 +00:00
undo_ready = ( ( abs ( int ( curr_col_num - col ) ) < 2 ) or ( col + 1 > currline - > txt . length ( ) ) ) ;
2000-02-25 11:04:07 +00:00
uint _pcol = item - > pcol ;
uint _prow = item - > prow ;
if ( undo_ready ) {
2002-11-23 16:06:53 +00:00
if ( ( item - > action & PREV_LINE ) and not item - > line - > next ) {
row + + ; thisrow + + ; curr_row_num + + ;
}
2000-02-25 11:04:07 +00:00
bool in_batch ;
// Keep undoing until item with no BATCH_MODE flag is reached.
do {
uint undo_type = last_item - > action & EDIT_UNDO_TYPE ;
uint undo_action = last_item - > action & EDIT_UNDO_ACTION ;
2005-10-22 02:45:18 +00:00
in_batch = make_bool ( last_item - > action & BATCH_MODE ) ;
2000-02-25 11:04:07 +00:00
currline = last_item - > line ;
if ( last_item - > action & PREV_LINE ) {
col = last_item - > col . num = last_item - > col . sav ;
if ( row > minrow )
row - - ;
}
switch ( undo_type ) {
case EDIT_UNDO_CHAR :
switch ( undo_action ) {
case EDIT_UNDO_INS_CHAR :
2001-10-21 17:44:12 +00:00
currline - > txt . erase ( last_item - > col . num , 1 ) ;
2000-02-25 11:04:07 +00:00
break ;
case EDIT_UNDO_DEL_CHAR :
2000-03-22 17:59:18 +00:00
currline - > txt . insert ( last_item - > col . num , 1 , last_item - > data . char_int ) ;
2000-02-25 11:04:07 +00:00
break ;
case EDIT_UNDO_OVR_CHAR :
2000-03-22 17:59:18 +00:00
currline - > txt [ last_item - > col . num ] = last_item - > data . char_int ;
2000-02-25 11:04:07 +00:00
break ;
}
editor - > setlinetype ( currline ) ;
break ;
case EDIT_UNDO_TEXT : {
text_item * text_data = last_item - > data . text_ptr ;
2001-07-16 20:35:42 +00:00
std : : string * txt = & currline - > txt ;
2000-02-25 11:04:07 +00:00
switch ( undo_action ) {
case EDIT_UNDO_DEL_TEXT :
2000-10-24 05:02:25 +00:00
txt - > insert ( text_data - > col , text_data - > text , text_data - > len ) ;
2000-03-22 17:59:18 +00:00
throw_delete ( text_data ) ;
2000-02-25 11:04:07 +00:00
break ;
case EDIT_UNDO_CUT_TEXT :
2000-10-24 05:02:25 +00:00
txt - > erase ( last_item - > col . num ) ;
2000-02-25 11:04:07 +00:00
break ;
case EDIT_UNDO_WRAP_TEXT :
2000-10-24 05:02:25 +00:00
txt - > append ( currline - > next - > txt . c_str ( ) + text_data - > col , text_data - > len ) ;
txt = & currline - > next - > txt ;
2000-02-25 11:04:07 +00:00
// fall through...
case EDIT_UNDO_INS_TEXT :
2000-10-24 05:02:25 +00:00
txt - > erase ( text_data - > col , text_data - > len ) ;
2000-03-22 17:59:18 +00:00
throw_delete ( text_data ) ;
2000-02-25 11:04:07 +00:00
break ;
}
2001-05-09 20:45:13 +00:00
editor - > setlinetype ( ( undo_action = = EDIT_UNDO_WRAP_TEXT ) ? currline - > next : currline ) ;
2000-02-25 11:04:07 +00:00
break ;
}
case EDIT_UNDO_LINE : {
Line * thisline = last_item - > data . line_ptr ;
switch ( undo_action ) {
case EDIT_UNDO_NEW_LINE :
if ( thisline - > next )
thisline - > next - > prev = thisline - > prev ;
if ( thisline - > prev ) {
thisline - > prev - > next = thisline - > next ;
currline = thisline - > prev ;
}
else
currline = thisline - > next ;
2000-03-22 17:59:18 +00:00
throw_xdelete ( thisline ) ;
2000-02-25 11:04:07 +00:00
break ;
case EDIT_UNDO_ORPHAN_LINE :
if ( last_item - > action & LAST_LINE ) {
thisline - > prev = currline ;
thisline - > next = currline ? currline - > next : NULL ;
2000-03-22 17:59:18 +00:00
if ( ( row < maxrow ) and currline )
2000-02-25 11:04:07 +00:00
row + + ;
}
else {
thisline - > prev = currline ? currline - > prev : NULL ;
thisline - > next = currline ;
}
// fall through...
case EDIT_UNDO_DEL_LINE :
if ( thisline - > prev )
thisline - > prev - > next = thisline ;
if ( thisline - > next )
thisline - > next - > prev = thisline ;
currline = thisline ;
break ;
case EDIT_UNDO_PUSH_LINE :
2005-10-25 06:11:09 +00:00
editor - > UnDelete ( make_bool_not ( last_item - > action & LAST_LINE ) ) ;
2000-02-25 11:04:07 +00:00
break ;
case EDIT_UNDO_POP_LINE :
editor - > DelLine ( ) ;
break ;
}
}
}
_pcol = last_item - > pcol ;
_prow = last_item - > prow ;
delete last_item ;
} while ( last_item and in_batch ) ;
undo_enabled = YES ;
2000-11-12 22:34:28 +00:00
2000-02-25 11:04:07 +00:00
editor - > getthisrow ( currline ) ;
2000-11-12 22:34:28 +00:00
uint temprow = row ;
Line * templine = currline ;
Line * topline = editor - > findfirstline ( ) ;
int delta = _prow - thisrow ;
if ( not in_range ( row + delta , minrow , maxrow ) ) {
// we need to fit thisrow into the screen boundaries
if ( delta > 0 ) {
2003-01-04 10:16:47 +00:00
for ( row + = delta ; row > maxrow ; row - - ) {
2001-02-19 22:53:24 +00:00
if ( templine ) // cause refresh() issue an error since templine should never be NULL
2003-01-04 10:16:47 +00:00
templine = templine - > prev ;
2000-11-12 22:34:28 +00:00
}
2003-01-04 10:16:47 +00:00
temprow = maxrow ;
2000-02-25 11:04:07 +00:00
}
else {
2003-01-04 10:16:47 +00:00
for ( row + = delta ; ( int ) row < ( int ) minrow ; row + + ) {
2001-02-19 22:53:24 +00:00
if ( templine ) // cause refresh() issue an error since templine should never be NULL
2003-01-04 10:16:47 +00:00
templine = templine - > next ;
2000-11-12 22:34:28 +00:00
}
2003-01-04 10:16:47 +00:00
temprow = minrow ;
2000-11-12 22:34:28 +00:00
}
// move pointer to the top of screen so we refresh scrolled area
while ( row ! = minrow ) {
2001-02-19 22:53:24 +00:00
if ( templine ) // cause refresh() issue an error since templine should never be NULL
2000-11-12 22:34:28 +00:00
templine = templine - > prev ;
- - row ;
2000-02-25 11:04:07 +00:00
}
}
2000-11-12 22:34:28 +00:00
else {
2001-02-19 22:53:24 +00:00
if ( delta < 0 ) {
2000-11-12 22:34:28 +00:00
templine = topline ;
for ( thisrow = 0 ; thisrow < _prow ; thisrow + + )
if ( templine ) // cause refresh() issue an error if thisrow != _prow
templine = templine - > next ;
}
temprow = row + delta ;
}
// refresh screen
editor - > refresh ( templine , row ) ;
// set cursor position
thisrow = _prow ;
col = _pcol ;
row = temprow ;
// set currline according to thisrow
currline = topline ;
for ( thisrow = 0 ; thisrow < _prow ; thisrow + + )
if ( currline )
currline = currline - > next ;
2000-02-25 11:04:07 +00:00
}
// Move the cursor to EOL if necessary
2000-03-22 17:59:18 +00:00
else if ( col + 1 > currline - > txt . length ( ) )
2000-02-25 11:04:07 +00:00
editor - > GoEOL ( ) ;
undo_ready = YES ;
}
2000-11-12 22:34:28 +00:00
2006-05-14 11:45:05 +00:00
GFTRK ( 0 ) ;
2000-02-25 11:04:07 +00:00
}
// ------------------------------------------------------------------