home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tv20os2.zip / src / TEditor.cpp < prev    next >
C/C++ Source or Header  |  1999-06-07  |  33KB  |  1,187 lines

  1. /*
  2.  * TEditor.cc
  3.  *
  4.  * Turbo Vision - Version 2.0
  5.  *
  6.  * Copyright (c) 1994 by Borland International
  7.  * All Rights Reserved.
  8.  *
  9.  * Modified by Sergio Sigala <ssigala@globalnet.it>
  10.  * Modified again by Dmitrij Korovkin <tkf@glasnet.ru>
  11.  */
  12.  
  13. #define Uses_TKeys
  14. #define Uses_TEditor
  15. #define Uses_TIndicator
  16. #define Uses_TEvent
  17. #define Uses_TScrollBar
  18. #define Uses_TFindDialogRec
  19. #define Uses_TReplaceDialogRec
  20. #define Uses_opstream
  21. #define Uses_ipstream
  22. #include <tvision/tv.h>
  23.  
  24. #include <ctype.h>
  25. #include <string.h>
  26.  
  27. /*
  28.  * SS: declarations fixed.  See `asm.cc'.
  29.  */
  30. int countLines( void *buf, size_t count );
  31. size_t scan( const void *block, size_t size, const char *str );
  32. size_t iScan( const void *block, size_t size, const char *str );
  33.  
  34. inline int isWordChar( int ch )
  35. {
  36. #ifndef __UNPATCHED
  37.     return isalnum((uchar)ch) || ch == '_';
  38. //                  ^^^^^- correction for extended ASCII.
  39. #else
  40.     return isalnum(ch) || ch == '_';
  41. #endif
  42. }
  43.  
  44. const ushort firstKeys[] =
  45. {
  46.     37,
  47.     kbCtrlA, cmWordLeft,
  48.     kbCtrlC, cmPageDown,
  49.     kbCtrlD, cmCharRight,
  50.     kbCtrlE, cmLineUp,
  51.     kbCtrlF, cmWordRight,
  52.     kbCtrlG, cmDelChar,
  53.     kbCtrlH, cmBackSpace,
  54.     kbCtrlK, 0xFF02,
  55.     kbCtrlL, cmSearchAgain,
  56.     kbCtrlM, cmNewLine,
  57.     kbCtrlO, cmIndentMode,
  58.     kbCtrlQ, 0xFF01,
  59.     kbCtrlR, cmPageUp,
  60.     kbCtrlS, cmCharLeft,
  61.     kbCtrlT, cmDelWord,
  62.     kbCtrlU, cmUndo,
  63.     kbCtrlV, cmInsMode,
  64.     kbCtrlX, cmLineDown,
  65.     kbCtrlY, cmDelLine,
  66.     kbLeft, cmCharLeft,
  67.     kbRight, cmCharRight,
  68.     kbCtrlLeft, cmWordLeft,
  69.     kbCtrlRight, cmWordRight,
  70.     kbHome, cmLineStart,
  71.     kbEnd, cmLineEnd,
  72.     kbUp, cmLineUp,
  73.     kbDown, cmLineDown,
  74.     kbPgUp, cmPageUp,
  75.     kbPgDn, cmPageDown,
  76.     kbCtrlPgUp, cmTextStart,
  77.     kbCtrlPgDn, cmTextEnd,
  78.     kbIns, cmInsMode,
  79.     kbDel, cmDelChar,
  80.     kbShiftIns, cmPaste,
  81.     kbShiftDel, cmCut,
  82.     kbCtrlIns, cmCopy,
  83.     kbCtrlDel, cmClear
  84. };
  85.  
  86. const ushort quickKeys[] =
  87. {   8,
  88.     'A', cmReplace,
  89.     'C', cmTextEnd,
  90.     'D', cmLineEnd,
  91.     'F', cmFind,
  92.     'H', cmDelStart,
  93.     'R', cmTextStart,
  94.     'S', cmLineStart,
  95.     'Y', cmDelEnd
  96. };
  97.  
  98. const ushort blockKeys[] =
  99. {   5,
  100.     'B', cmStartSelect,
  101.     'C', cmPaste,
  102.     'H', cmHideSelect,
  103.     'K', cmCopy,
  104.     'Y', cmCut
  105. };
  106.  
  107. const ushort *keyMap[] = { firstKeys, quickKeys, blockKeys };
  108.  
  109. ushort defEditorDialog( int, ... );
  110.  
  111. ushort scanKeyMap( const void *keyMap, ushort keyCode )
  112. {
  113.     register ushort *kM = (ushort *)keyMap;
  114.     uchar codeLow = keyCode & 0xff;
  115.     uchar codeHi  = keyCode >> 8;
  116.  
  117.     int n;
  118.  
  119.     for (n = *kM++; n--; kM++)
  120.     {
  121.         uchar  mapLow  = *kM & 0xff;
  122.         uchar  mapHi   = *kM >> 8;
  123.         kM++;
  124.         ushort command = *kM;
  125.  
  126.         if ((mapLow == codeLow) && ((mapHi == 0) || (mapHi == codeHi)))
  127.             return command;
  128.     };
  129.     return 0;
  130. }
  131.  
  132. #define cpEditor    "\x06\x07"
  133.  
  134. TEditor::TEditor( const TRect& bounds,
  135.                   TScrollBar *aHScrollBar,
  136.                   TScrollBar *aVScrollBar,
  137.                   TIndicator *aIndicator,
  138. //                  ushort aBufSize ) :    /* XXX */
  139.           uint aBufSize ) :    /* XXX */
  140.     TView( bounds ),
  141.     hScrollBar( aHScrollBar ),
  142.     vScrollBar( aVScrollBar ),
  143.     indicator( aIndicator ),
  144.     bufSize( aBufSize ),
  145.     canUndo( True ),
  146.     selecting( False ),
  147.     overwrite( False ),
  148.     autoIndent( False ) ,
  149.     lockCount( 0 ),
  150.     keyState( 0 )
  151. {
  152.     growMode = gfGrowHiX | gfGrowHiY;
  153.     options |= ofSelectable;
  154.     eventMask = evMouseDown | evKeyDown | evCommand | evBroadcast;
  155.     showCursor();
  156.     initBuffer();
  157.     if( buffer != 0 )
  158.         isValid = True;
  159.     else
  160.     {
  161.         editorDialog( edOutOfMemory );
  162.         bufSize = 0;
  163.         isValid = False;
  164.     }
  165.     setBufLen(0);
  166.     setWidth( maxLineLength );
  167. }
  168.  
  169. TEditor::~TEditor()
  170. {
  171. }
  172.  
  173. void TEditor::shutDown()
  174. {
  175.     doneBuffer();
  176.     TView::shutDown();
  177. }
  178.  
  179. void TEditor::changeBounds( const TRect& bounds )
  180. {
  181.     setBounds(bounds);
  182.     delta.x = max(0, min(delta.x, limit.x - size.x));
  183.     delta.y = max(0, min(delta.y, limit.y - size.y));
  184.     update(ufView);
  185. }
  186.  
  187. //int TEditor::charPos( ushort p, ushort target )    /* XXX */
  188. uint TEditor::charPos( uint p, uint target )        /* XXX */
  189. {
  190. //    int pos = 0;    /* XXX */
  191.     uint pos = 0;    /* XXX */
  192.     while( p < target )
  193.     {
  194.         if( bufChar(p) == '\x9' )
  195.             pos |= 7;
  196.         pos++;
  197.         p++;
  198.     }
  199.     return pos;
  200. }
  201.  
  202. //ushort TEditor::charPtr( ushort p, int target )    /* XXX */
  203. uint TEditor::charPtr( uint p, uint target )        /* XXX */
  204. {
  205. //  int pos = 0;    /* XXX */
  206.     uint pos = 0;    /* XXX */
  207.   /* SS: changed */
  208.   while( (pos < target) && (p < bufLen) && (bufChar(p) != '\n') )
  209. //  while( (pos < target) && (p < bufLen) && (bufChar(p) != '\x0D') )
  210.     {
  211.     if( bufChar(p) == '\x09' )
  212.         pos |= 7;
  213.     pos++;
  214.     p++;
  215.     }
  216.   if( pos > target )
  217.     p--;
  218.   return p;
  219. }
  220.  
  221. Boolean TEditor::clipCopy()
  222. {
  223.     Boolean res = False;
  224.     if( (clipboard != 0) && (clipboard != this) )
  225.         {
  226.         res = clipboard->insertFrom(this);
  227.         selecting = False;
  228.         update(ufUpdate);
  229.         }
  230.     return res;
  231. }
  232.  
  233. void TEditor::clipCut()
  234. {
  235.     if( clipCopy() == True )
  236.         deleteSelect();
  237. }
  238.  
  239. void TEditor::clipPaste()
  240. {
  241.     if( (clipboard != 0) && (clipboard != this) )
  242.         insertFrom(clipboard);
  243. }
  244.  
  245. void TEditor::convertEvent( TEvent& event )
  246. {
  247.     if( event.what == evKeyDown )
  248.         {
  249.         if( (event.keyDown.controlKeyState & kbShift) != 0 &&
  250.             event.keyDown.charScan.scanCode >= 0x47 &&
  251.             event.keyDown.charScan.scanCode <= 0x51
  252.           )
  253.             event.keyDown.charScan.charCode = 0;
  254.  
  255.         ushort key = event.keyDown.keyCode;
  256.         if( keyState != 0 )
  257.             {
  258.             if( (key & 0xFF) >= 0x01 && (key & 0xFF) <= 0x1A )
  259.                 key += 0x40;
  260.             if( (key & 0xFF) >= 0x61 && (key & 0xFF) <= 0x7A )
  261.                 key -= 0x20;
  262.             }
  263.         key = scanKeyMap(keyMap[keyState], key);
  264.         keyState = 0;
  265.         if( key != 0 )
  266.             if( (key & 0xFF00) == 0xFF00 )
  267.                 {
  268.                 keyState = (key & 0xFF);
  269.                 clearEvent(event);
  270.                 }
  271.             else
  272.                 {
  273.                 event.what = evCommand;
  274.                 event.message.command = key;
  275.                 }
  276.         }
  277. }
  278.  
  279. Boolean TEditor::cursorVisible()
  280. {
  281.   return Boolean((curPos.y >= delta.y) && (curPos.y < delta.y + size.y));
  282. }
  283.  
  284. //void TEditor::deleteRange( ushort startPtr,    /* XXX */
  285. //                           ushort endPtr,    /* XXX */
  286. void TEditor::deleteRange( uint startPtr,    /* XXX */
  287.                            uint endPtr,        /* XXX */
  288.                            Boolean delSelect
  289.                          )
  290. {
  291.     if( hasSelection() == True && delSelect == True )
  292.         deleteSelect();
  293.     else
  294.         {
  295.         setSelect(curPtr, endPtr, True);
  296.         deleteSelect();
  297.         setSelect(startPtr, curPtr, False);
  298.         deleteSelect();
  299.         }
  300. }
  301.  
  302. void TEditor::deleteSelect()
  303. {
  304.     insertText( 0, 0, False );
  305. }
  306.  
  307. void TEditor::doneBuffer()
  308. {
  309.     delete buffer;
  310. }
  311.  
  312. void TEditor::doSearchReplace()
  313. {
  314.     int i;
  315.     do  {
  316.         i = cmCancel;
  317.         if( search(findStr, editorFlags) == False )
  318.             {
  319.             if( (editorFlags & (efReplaceAll | efDoReplace)) !=
  320.                 (efReplaceAll | efDoReplace) )
  321.                     editorDialog( edSearchFailed );
  322.             }
  323.         else
  324.             if( (editorFlags & efDoReplace) != 0 )
  325.                 {
  326.                 i = cmYes;
  327.                 if( (editorFlags & efPromptOnReplace) != 0 )
  328.                     {
  329.                     TPoint c = makeGlobal( cursor );
  330.                     i = editorDialog( edReplacePrompt, &c );
  331.                     }
  332.                 if( i == cmYes )
  333.                     {
  334.                     lock();
  335.                     insertText( replaceStr, strlen(replaceStr), False);
  336.                     trackCursor(False);
  337.                     unlock();
  338.                     }
  339.                 }
  340.         } while( i != cmCancel && (editorFlags & efReplaceAll) != 0 );
  341. }
  342.  
  343. void TEditor::doUpdate()
  344. {
  345.     if( updateFlags != 0 )
  346.         {
  347.         setCursor(curPos.x - delta.x, curPos.y - delta.y);
  348.         if( (updateFlags & ufView) != 0 )
  349.             drawView();
  350.         else
  351.             if( (updateFlags & ufLine) != 0 )
  352.                 drawLines( curPos.y-delta.y, 1, lineStart(curPtr) );
  353.         if( hScrollBar != 0 )
  354.             hScrollBar->setParams(delta.x, 0, limit.x - size.x, size.x / 2, 1);
  355.         if( vScrollBar != 0 )
  356.             vScrollBar->setParams(delta.y, 0, limit.y - size.y, size.y - 1, 1);
  357.         if( indicator != 0 )
  358.             indicator->setValue(curPos, modified);
  359.         if( (state & sfActive) != 0 )
  360.             updateCommands();
  361.         updateFlags = 0;
  362.         }
  363. }
  364.  
  365. void TEditor::draw()
  366. {
  367.     if( drawLine != delta.y )
  368.         {
  369.         drawPtr = lineMove( drawPtr, delta.y - drawLine );
  370.         drawLine = delta.y;
  371.         }
  372.     drawLines( 0, size.y, drawPtr );
  373. }
  374.  
  375. /*Added again as a such a plug for backward compatibility with an old 
  376. application*/
  377. #ifdef __RUSSIAN_LETTERS
  378. //static unsigned char KoiTable[128] =    /* XXX */
  379. static unsigned KoiTable[128] =        /* XXX */
  380. {
  381.         192, 193, 194, 195, 196, 197, 198, 199, /* 0x80 - 0x87 */
  382.         200, 201, 202, 203, 204, 205 ,206, 207, /* 0x88 - 0x8f */
  383.         208, 209, 210, 211, 212, 213, 214, 215, /* 0x90 - 0x97 */
  384.         216, 217, 218, 219, 220, 221, 222, 223, /* 0x98 - 0x9f */
  385.         240, 241, 242, 243, 244, 245, 246, 247, /* 0xa0 - 0xa7 */
  386.         248, 249, 250, 251, 252, 253, 254, 255, /* 0xa8 - 0xaf */
  387.         176, 177, 178, 179, 180, 181, 182, 183, /* 0xb0 - 0xb7 */
  388.         184, 185, 186, 187, 188, 189, 190, 191, /* 0xb8 - 0xbf */
  389.         238, 160, 161, 230, 164, 165, 228, 163, /* 0xc0 - 0xc7 */
  390.         229, 168, 169, 170, 171, 172, 173, 174, /* 0xc8 - 0xcf */
  391.         175, 239, 224, 225, 226, 227, 166, 162, /* 0xd0 - 0xd7 */
  392.         236, 235, 167, 232, 237, 233, 231, 234, /* 0xd8 - 0xdf */
  393.         158, 128, 129, 150, 132, 133, 148, 131, /* 0xe0 - 0xe7 */
  394.         149, 136, 137, 138, 139, 140, 141, 142, /* 0xe8 - 0xef */
  395.         143, 159, 144, 145, 146, 147, 134, 130, /* 0xf0 - 0xf7 */
  396.         156, 155, 135, 152, 157, 153, 151, 154  /* 0xf8 - 0xff */
  397. };
  398. #endif
  399.  
  400. //void TEditor::drawLines( int y, int count, ushort linePtr )    /* XXX */
  401. void TEditor::drawLines( int y, uint count, uint linePtr )    /* XXX */
  402. {
  403.     ushort color = getColor(0x0201);
  404.     while( count-- > 0 )
  405.         {
  406.         ushort b[maxLineLength];
  407. //        int mpos = delta.x;
  408. //        while( mpos <= size.x )
  409. //        {
  410.             formatLine( b, linePtr, delta.x+size.x, color );
  411.             writeBuf(0, y, size.x, 1, &b[ delta.x ]);
  412. //            mpos += widthSize; ++y;
  413. //         }
  414.         linePtr = nextLine(linePtr);
  415.         y++;
  416.         }
  417. }
  418.  
  419. void TEditor::find()
  420. {
  421.     TFindDialogRec findRec( findStr, editorFlags );
  422.     if( editorDialog( edFind, &findRec ) != cmCancel )
  423.         {
  424.         strcpy( findStr, findRec.find );
  425.         editorFlags = findRec.options & ~efDoReplace;
  426.         doSearchReplace();
  427.         }
  428. }
  429.  
  430. //ushort TEditor::getMousePtr( TPoint m )    /* XXX */
  431. uint TEditor::getMousePtr( TPoint m )        /* XXX */
  432. {
  433.     TPoint mouse = makeLocal( m );
  434.     mouse.x = max(0, min(mouse.x, size.x - 1));
  435.     mouse.y = max(0, min(mouse.y, size.y - 1));
  436.     return charPtr(lineMove(drawPtr, mouse.y + delta.y - drawLine),
  437.         mouse.x + delta.x);
  438. }
  439.  
  440. TPalette& TEditor::getPalette() const
  441. {
  442.     static TPalette palette( cpEditor, sizeof( cpEditor )-1 );
  443.     return palette;
  444. }
  445.  
  446. void TEditor::checkScrollBar( const TEvent& event,
  447.                               TScrollBar *p,
  448.                               int& d
  449.                             )
  450. {
  451.     if( (event.message.infoPtr == p) && (p->value != d) )
  452.         {
  453.         d = p->value;
  454.         update( ufView );
  455.         }
  456. }
  457.  
  458. void TEditor::handleEvent( TEvent& event )
  459. {
  460.     TView::handleEvent( event );
  461.  
  462.     Boolean centerCursor = Boolean(!cursorVisible());
  463.     uchar selectMode = 0;
  464.  
  465.     if( selecting == True ||
  466.         (event.what & evMouse && (event.mouse.controlKeyState & kbShift) != 0) ||
  467.         (event.what & evKeyboard && (event.keyDown.controlKeyState & kbShift ) != 0)
  468.       )
  469.         selectMode = smExtend;
  470.  
  471.     convertEvent( event );
  472.  
  473.     switch( event.what )
  474.         {
  475.  
  476.         case evMouseDown:
  477.             if( event.mouse.eventFlags & meDoubleClick )
  478.                 selectMode |= smDouble;
  479.  
  480.             do  {
  481.                 lock();
  482.                 if( event.what == evMouseAuto )
  483.                     {
  484.                     TPoint mouse = makeLocal( event.mouse.where );
  485.                     TPoint d = delta;
  486.                     if( mouse.x < 0 )
  487.                         d.x--;
  488.                     if( mouse.x >= size.x )
  489.                         d.x++;
  490.                     if( mouse.y < 0 )
  491.                         d.y--;
  492.                     if( mouse.y >= size.y )
  493.                         d.y++;
  494.                     scrollTo(d.x, d.y);
  495.                     }
  496.                 setCurPtr(getMousePtr(event.mouse.where), selectMode);
  497.                 selectMode |= smExtend;
  498.                 unlock();
  499.                 } while( mouseEvent(event, evMouseMove + evMouseAuto) );
  500.             break;
  501.  
  502.         case evKeyDown:
  503.             if( event.keyDown.charScan.charCode == 9 ||
  504.                 ( event.keyDown.charScan.charCode >= 32 && event.keyDown.charScan.charCode < 255 ) )
  505.                     {
  506.                     lock();
  507.                     if( overwrite == True && hasSelection() == False )
  508.                         if( curPtr != lineEnd(curPtr) )
  509.                             selEnd = nextChar(curPtr);
  510.                           if( curPos.x >= widthSize ){ 
  511.                                 newLine();    //Orlik
  512.                                 }
  513.                     insertText( &event.keyDown.charScan.charCode, 1, False);
  514.                     trackCursor(centerCursor);
  515.                     unlock();
  516.                     }
  517.             else
  518.                 return;
  519.             break;
  520.  
  521.         case evCommand:
  522.             switch( event.message.command )
  523.                 {
  524.                 case cmFind:
  525.                     find();
  526.                     break;
  527.                 case cmReplace:
  528.                     replace();
  529.                     break;
  530.                 case cmSearchAgain:
  531.                     doSearchReplace();
  532.                     break;
  533.                 default:
  534.                     lock();
  535.                     switch( event.message.command )
  536.                         {
  537.                         case cmCut:
  538.                             clipCut();
  539.                             break;
  540.                         case cmCopy:
  541.                             clipCopy();
  542.                             break;
  543.                         case cmPaste:
  544.                             clipPaste();
  545.                             break;
  546.                         case cmUndo:
  547.                             undo();
  548.                             break;
  549.                         case cmClear:
  550.                             deleteSelect();
  551.                             break;
  552.                         case cmCharLeft:
  553.                             setCurPtr(prevChar(curPtr), selectMode);
  554.                             break;
  555.                         case cmCharRight:
  556.                             setCurPtr(nextChar(curPtr), selectMode);
  557.                             break;
  558.                         case cmWordLeft:
  559.                             setCurPtr(prevWord(curPtr), selectMode);
  560.                             break;
  561.                         case cmWordRight:
  562.                             setCurPtr(nextWord(curPtr), selectMode);
  563.                             break;
  564.                         case cmLineStart:
  565.                             setCurPtr(lineStart(curPtr), selectMode);
  566.                             break;
  567.                         case cmLineEnd:
  568.                             setCurPtr(lineEnd(curPtr), selectMode);
  569.                             break;
  570.                         case cmLineUp:
  571.                             setCurPtr(lineMove(curPtr, -1), selectMode);
  572.                             break;
  573.                         case cmLineDown:
  574.                             setCurPtr(lineMove(curPtr, 1), selectMode);
  575.                             break;
  576.                         case cmPageUp:
  577.                             setCurPtr(lineMove(curPtr, -(size.y-1)), selectMode);
  578.                             break;
  579.                         case cmPageDown:
  580.                             setCurPtr(lineMove(curPtr, size.y-1), selectMode);
  581.                             break;
  582.                         case cmTextStart:
  583.                             setCurPtr(0, selectMode);
  584.                             break;
  585.                         case cmTextEnd:
  586.                             setCurPtr(bufLen, selectMode);
  587.                             break;
  588.                         case cmNewLine:
  589.                             newLine();
  590.                             break;
  591.                         case cmBackSpace:
  592.                             deleteRange(prevChar(curPtr), curPtr, True);
  593.                             break;
  594.                         case cmDelChar:
  595.                             deleteRange(curPtr, nextChar(curPtr), True);
  596.                             break;
  597.                         case cmDelWord:
  598.                             deleteRange(curPtr, nextWord(curPtr), False);
  599.                             break;
  600.                         case cmDelStart:
  601.                             deleteRange(lineStart(curPtr), curPtr, False);
  602.                             break;
  603.                         case cmDelEnd:
  604.                             deleteRange(curPtr, lineEnd(curPtr), False);
  605.                             break;
  606.                         case cmDelLine:
  607.                             deleteRange(lineStart(curPtr), nextLine(curPtr), False);
  608.                             break;
  609.                         case cmInsMode:
  610.                             toggleInsMode();
  611.                             break;
  612.                         case cmStartSelect:
  613.                             startSelect();
  614.                             break;
  615.                         case cmHideSelect:
  616.                             hideSelect();
  617.                             break;
  618.                         case cmIndentMode:
  619.                             autoIndent = Boolean(!autoIndent);
  620.                             break;
  621.                         default:
  622.                             unlock();
  623.                             return;
  624.                         }
  625.                     trackCursor(centerCursor);
  626.                     unlock();
  627.                     break;
  628.                 }
  629. #ifndef __UNPATCHED
  630.                 break;
  631. #endif
  632.         case evBroadcast:
  633.             switch( event.message.command )
  634.                 {
  635.                 case cmScrollBarChanged:
  636.             if ((event.message.infoPtr == hScrollBar) ||
  637.                 (event.message.infoPtr == vScrollBar))
  638.             {
  639.                         checkScrollBar( event, hScrollBar, delta.x );
  640.                         checkScrollBar( event, vScrollBar, delta.y );
  641.             }
  642.             else
  643.                 return;
  644.                     break;
  645.                 default:
  646.                     return;
  647.                 }
  648.         }
  649.     clearEvent(event);
  650. }
  651.  
  652. Boolean TEditor::hasSelection()
  653. {
  654.     return Boolean(selStart != selEnd);
  655. }
  656.  
  657. void TEditor::hideSelect()
  658. {
  659.     selecting = False;
  660.     setSelect(curPtr, curPtr, False);
  661. }
  662.  
  663. void TEditor::initBuffer()
  664. {
  665.     buffer = new char[bufSize];
  666. }
  667.  
  668. Boolean TEditor::insertBuffer( char *p,
  669. //                               ushort offset,    /* XXX */
  670. //                               ushort length,    /* XXX */
  671.                                uint offset,    /* XXX */
  672.                                uint length,    /* XXX */
  673.                                Boolean allowUndo,
  674.                                Boolean selectText
  675.                              )
  676. {
  677.     selecting = False;
  678.     uint selLen = selEnd - selStart;        /* XXX */
  679.     if( selLen == 0 && length == 0 )
  680.         return True;
  681.  
  682.     uint delLen = 0;        /* XXX */
  683.     if( allowUndo == True )
  684.         if( curPtr == selStart )
  685.             delLen = selLen;
  686.         else
  687.             if( selLen > insCount )
  688.                 delLen = selLen - insCount;
  689.  
  690. //    long newSize = long(bufLen + delCount - selLen + delLen) + length; /* XXX */
  691.     uint newSize = uint(bufLen + delCount - selLen + delLen) + length; /* XXX */
  692.  
  693. //    if( newSize > bufLen + delCount )    /* XXX */
  694. //        if( newSize > 0xFFE0l || setBufSize(ushort(newSize)) == False ) /* XXX */
  695.     if( newSize > bufLen + delCount && setBufSize(newSize) == False ) /* XXX */
  696.             {
  697.             editorDialog( edOutOfMemory );
  698.         selEnd = selStart;
  699.             return False;
  700.             }
  701.  
  702. //    ushort selLines = countLines( &buffer[bufPtr(selStart)], selLen ); /* XXX */
  703.     uint selLines = countLines( &buffer[bufPtr(selStart)], selLen ); /* XXX */
  704.     if( curPtr == selEnd )
  705.         {
  706.         if( allowUndo == True )
  707.             {
  708.             if( delLen > 0 )
  709.                 memmove(
  710.                          &buffer[curPtr + gapLen - delCount - delLen],
  711.                          &buffer[selStart],
  712.                          delLen
  713.                        );
  714.             insCount -= selLen - delLen;
  715.             }
  716.         curPtr = selStart;
  717.         curPos.y -= selLines;
  718.         }
  719.     if( delta.y > curPos.y )
  720.         {
  721.         delta.y -= selLines;
  722.         if( delta.y < curPos.y )
  723.             delta.y = curPos.y;
  724.         }
  725.  
  726.     if( length > 0 )
  727.         memmove(
  728.                 &buffer[curPtr],
  729.                 &p[offset],
  730.                 length
  731.                );
  732.  
  733. //    ushort lines = countLines( &buffer[curPtr], length ); /* XXX */
  734.     uint lines = countLines( &buffer[curPtr], length ); /* XXX */
  735.     curPtr += length;
  736.     curPos.y += lines;
  737.     drawLine = curPos.y;
  738.     drawPtr = lineStart(curPtr);
  739.     curPos.x = charPos(drawPtr, curPtr);
  740.     if( selectText == False )
  741.         selStart = curPtr;
  742.     selEnd = curPtr;
  743.     bufLen += length - selLen;
  744.     gapLen -= length - selLen;
  745.     if( allowUndo == True )
  746.         {
  747.         delCount += delLen;
  748.         insCount += length;
  749.         }
  750.     limit.y += lines - selLines;
  751.     delta.y = max(0, min(delta.y, limit.y - size.y));
  752.     if( isClipboard() == False )
  753.         modified = True;
  754.     setBufSize(bufLen + delCount);
  755.     if( selLines == 0 && lines == 0 )
  756.         update(ufLine);
  757.     else
  758.         update(ufView);
  759.     return True;
  760. }
  761.  
  762. Boolean TEditor::insertFrom( TEditor *editor )
  763. {
  764.     uint pt = editor->bufPtr(editor->selStart);    /* XXX */
  765.     return insertBuffer( editor->buffer,
  766. //                         editor->bufPtr(editor->selStart),    /* XXX */
  767.              pt,                    /* XXX */
  768.                          editor->selEnd - editor->selStart,
  769.                          canUndo,
  770.                          isClipboard()
  771.                         );
  772. }
  773.  
  774. //Boolean TEditor::insertText( const void *text, ushort length, Boolean selectText ) /* XXX */
  775. Boolean TEditor::insertText( const void *text, uint length, Boolean selectText ) /* XXX */
  776. {
  777.   return insertBuffer( (char *)text, 0, length, canUndo, selectText);
  778. }
  779.  
  780. Boolean TEditor::isClipboard()
  781. {
  782.     return Boolean(clipboard == this);
  783. }
  784.  
  785. //ushort TEditor::lineMove( ushort p, int count )    /* XXX */
  786. uint TEditor::lineMove( uint p, int count )    /* XXX */
  787. {
  788. //    ushort i = p;    /* XXX */
  789.     uint i = p;        /* XXX */
  790.     p = lineStart(p);
  791. //    int pos = charPos(p, i);    /* XXX */
  792.     uint pos = charPos(p, i);    /* XXX */
  793.     while( count != 0 )
  794.         {
  795.         i = p;
  796.         if( count < 0 )
  797.             {
  798.             p = prevLine(p);
  799.             count++;
  800.             }
  801.         else
  802.             {
  803.             p = nextLine(p);
  804.             count--;
  805.             }
  806.         }
  807.     if( p != i )
  808.         p = charPtr(p, pos);
  809.     return p;
  810. }
  811.  
  812. void TEditor::lock()
  813. {
  814.     lockCount++;
  815. }
  816.  
  817. void TEditor::newLine()
  818. {
  819.     /* SS: changed */
  820.     const char nl[] = "\n";
  821. //    const char crlf[] = "\x0D\x0A";
  822. //    ushort p = lineStart(curPtr);    /* XXX */
  823. //    ushort i = p;            /* XXX */
  824.     uint p = lineStart(curPtr);    /* XXX */
  825.     uint i = p;            /* XXX */
  826.     while( i < curPtr &&
  827.            ( (buffer[i] == ' ') || (buffer[i] == '\x9'))
  828.          )
  829.          i++;
  830.     insertText(nl, 1, False);
  831. //    insertText(crlf, 2, False);
  832.     if( autoIndent == True )
  833.         insertText( &buffer[p], i - p, False);
  834. }
  835.  
  836. //ushort TEditor::nextLine( ushort p )    /* XXX */
  837. uint TEditor::nextLine( uint p )    /* XXX */
  838. {
  839.     return nextChar(lineEnd(p));
  840. }
  841.  
  842. //ushort TEditor::nextWord( ushort p )    /* XXX */
  843. uint TEditor::nextWord( uint p )    /* XXX */
  844. {
  845.     while( p < bufLen && isWordChar(bufChar(p)) != 0 )
  846.         p = nextChar(p);
  847.     while( p < bufLen && isWordChar(bufChar(p)) == 0 )
  848.         p = nextChar(p);
  849.     return p;
  850. }
  851.  
  852. //ushort TEditor::prevLine( ushort p )    /* XXX */
  853. uint TEditor::prevLine( uint p )    /* XXX */
  854. {
  855.   return lineStart(prevChar(p));
  856. }
  857.  
  858. //ushort TEditor::prevWord( ushort p )    /* XXX */
  859. uint TEditor::prevWord( uint p )    /* XXX */
  860. {
  861.     while( p > 0 && isWordChar(bufChar(prevChar(p))) == 0 )
  862.         p = prevChar(p);
  863.     while( p > 0 && isWordChar(bufChar(prevChar(p))) != 0 )
  864.         p = prevChar(p);
  865.     return p;
  866. }
  867.  
  868. void TEditor::replace()
  869. {
  870.     TReplaceDialogRec replaceRec( findStr, replaceStr, editorFlags );
  871.     if( editorDialog( edReplace, &replaceRec ) != cmCancel )
  872.         {
  873.         strcpy( findStr, replaceRec.find );
  874.         strcpy( replaceStr, replaceRec.replace );
  875.         editorFlags = replaceRec.options | efDoReplace;
  876.         doSearchReplace();
  877.         }
  878.  
  879. }
  880.  
  881. void TEditor::scrollTo( int x, int y )
  882. {
  883.     x = max(0, min(x, limit.x - size.x));
  884.     y = max(0, min(y, limit.y - size.y));
  885.     if( x != delta.x || y != delta.y )
  886.         {
  887.         delta.x = x;
  888.         delta.y = y;
  889.         update(ufView);
  890.         }
  891. }
  892.  
  893. Boolean TEditor::search( const char *findStr, ushort opts )
  894. {
  895. //    ushort pos = curPtr;    /* XXX */
  896. //    ushort i;            /* XXX */ 
  897.     ulong pos = curPtr;    /* XXX */
  898.     ulong i;        /* XXX */ 
  899.     do  {
  900.         if( (opts & efCaseSensitive) != 0 )
  901.             i = scan( &buffer[bufPtr(pos)], bufLen - pos, findStr);
  902.         else
  903.             i = iScan( &buffer[bufPtr(pos)], bufLen - pos, findStr);
  904.  
  905.         if( i != sfSearchFailed )
  906.             {
  907.             i += pos;
  908.             if( (opts & efWholeWordsOnly) == 0 ||
  909.                 !(
  910.                     ( i != 0 && isWordChar(bufChar(i - 1)) != 0 ) ||
  911.                     ( i + strlen(findStr) != bufLen &&
  912.                         isWordChar(bufChar(i + strlen(findStr)))
  913.                     )
  914.                  ))
  915.                 {
  916.                 lock();
  917.                 setSelect(i, i + strlen(findStr), False);
  918.                 trackCursor(Boolean(!cursorVisible()));
  919.                 unlock();
  920.                 return True;
  921.                 }
  922.             else
  923.                 pos = i + 1;
  924.             }
  925.         } while( i != sfSearchFailed );
  926.     return False;
  927. }
  928.  
  929. //void TEditor::setBufLen( ushort length )    /* XXX */
  930. void TEditor::setBufLen( uint length )    /* XXX */
  931. {
  932.     bufLen = length;
  933.     gapLen = bufSize - length;
  934.     selStart = 0;
  935.     selEnd = 0;
  936.     curPtr = 0;
  937.     delta.x = 0;
  938.     delta.y = 0;
  939.     curPos = delta;
  940.     limit.x = maxLineLength;
  941.     limit.y = countLines( &buffer[gapLen], bufLen ) + 1;
  942.     drawLine = 0;
  943.     drawPtr = 0;
  944.     delCount = 0;
  945.     insCount = 0;
  946.     modified = False;
  947.     update(ufView);
  948. }
  949.  
  950. //Boolean TEditor::setBufSize( ushort newSize )    /* XXX */
  951. Boolean TEditor::setBufSize( uint newSize )    /* XXX */
  952. {
  953.     return Boolean(newSize <= bufSize);
  954. }
  955.  
  956. void TEditor::setCmdState( ushort command, Boolean enable )
  957. {
  958.     TCommandSet s;
  959.     s += command;
  960.     if( enable == True && (state & sfActive) != 0 )
  961.         enableCommands(s);
  962.     else
  963.         disableCommands(s);
  964. }
  965.  
  966. //void TEditor::setCurPtr( ushort p, uchar selectMode )    /* XXX */
  967. void TEditor::setCurPtr( uint p, uchar selectMode )    /* XXX */
  968. {
  969. //    ushort anchor;    /* XXX */
  970.     uint anchor;    /* XXX */
  971.     if( (selectMode & smExtend) == 0 )
  972.         anchor = p;
  973.     else if( curPtr == selStart )
  974.         anchor = selEnd;
  975.     else
  976.         anchor = selStart;
  977.  
  978.     if( p < anchor )
  979.         {
  980.         if( (selectMode & smDouble) != 0 )
  981.             {
  982.             p = prevLine(nextLine(p));
  983.             anchor = nextLine(prevLine(anchor));
  984.             }
  985.         setSelect(p, anchor, True);
  986.         }
  987.     else
  988.         {
  989.         if( (selectMode & smDouble) != 0 )
  990.             {
  991.             p = nextLine(p);
  992.             anchor = prevLine(nextLine(anchor));
  993.             }
  994.         setSelect(anchor, p, False);
  995.         }
  996. }
  997.  
  998. //void TEditor::setSelect( ushort newStart, ushort newEnd, Boolean curStart ) /* XXX */
  999. void TEditor::setSelect( uint newStart, uint newEnd, Boolean curStart ) /* XXX */
  1000. {
  1001. //    ushort p;    /* XXX */
  1002.     uint p;    /* XXX */
  1003.     if( curStart != 0 )
  1004.         p = newStart;
  1005.     else
  1006.         p = newEnd;
  1007.  
  1008.     uchar flags = ufUpdate;
  1009.  
  1010.     if( newStart != selStart || newEnd != selEnd )
  1011.         if( newStart != newEnd || selStart != selEnd )
  1012.             flags = ufView;
  1013.  
  1014.     if( p != curPtr )
  1015.         {
  1016.         if( p > curPtr )
  1017.             {
  1018. //            ushort l = p - curPtr;    /* XXX */
  1019.             uint l = p - curPtr;    /* XXX */
  1020.             memmove( &buffer[curPtr], &buffer[curPtr + gapLen], l);
  1021.             curPos.y += countLines(&buffer[curPtr], l);
  1022.             curPtr = p;
  1023.             }
  1024.         else
  1025.             {
  1026. //            ushort l = curPtr - p;    /* XXX */
  1027.             uint l = curPtr - p;    /* XXX */
  1028.             curPtr = p;
  1029.             curPos.y -= countLines(&buffer[curPtr], l);
  1030.             memmove( &buffer[curPtr + gapLen], &buffer[curPtr], l);
  1031.             }
  1032.         drawLine = curPos.y;
  1033.         drawPtr = lineStart(p);
  1034.         curPos.x = charPos(drawPtr, p);
  1035.         delCount = 0;
  1036.         insCount = 0;
  1037.         setBufSize(bufLen);
  1038.     }
  1039.     selStart = newStart;
  1040.     selEnd = newEnd;
  1041.     update(flags);
  1042. }
  1043.  
  1044. void TEditor::setState( ushort aState, Boolean enable )
  1045. {
  1046.     TView::setState(aState, enable);
  1047.     switch( aState )
  1048.         {
  1049.         case sfActive:
  1050.             if( hScrollBar != 0 )
  1051.                 hScrollBar->setState(sfVisible, enable);
  1052.             if( vScrollBar != 0 )
  1053.                 vScrollBar->setState(sfVisible, enable);
  1054.             if( indicator != 0 )
  1055.                 indicator->setState(sfVisible, enable);
  1056.             updateCommands();
  1057.             break;
  1058.  
  1059.         case sfExposed:
  1060.             if( enable == True )
  1061.                 unlock();
  1062.         }
  1063. }
  1064.  
  1065. void TEditor::startSelect()
  1066. {
  1067.     hideSelect();
  1068.     selecting = True;
  1069. }
  1070.  
  1071. void TEditor::toggleInsMode()
  1072. {
  1073.     overwrite = Boolean(!overwrite);
  1074.     setState(sfCursorIns, Boolean(!getState(sfCursorIns)));
  1075. }
  1076.  
  1077. void TEditor::trackCursor( Boolean center )
  1078. {
  1079.     if( center == True )
  1080.         scrollTo( curPos.x - size.x + 1, curPos.y - size.y / 2);
  1081.     else
  1082.         scrollTo( max(curPos.x - size.x + 1, min(delta.x, curPos.x)),
  1083.                   max(curPos.y - size.y + 1, min(delta.y, curPos.y)));
  1084. }
  1085.  
  1086. void TEditor::undo()
  1087. {
  1088.     if( delCount != 0 || insCount != 0 )
  1089.         {
  1090.         selStart = curPtr - insCount;
  1091.         selEnd = curPtr;
  1092.         ushort length = delCount;
  1093.         delCount = 0;
  1094.         insCount = 0;
  1095.         insertBuffer(buffer, curPtr + gapLen - length, length, False, True);
  1096.         }
  1097. }
  1098.  
  1099. void TEditor::unlock()
  1100. {
  1101.     if( lockCount > 0 )
  1102.         {
  1103.         lockCount--;
  1104.         if( lockCount == 0 )
  1105.             doUpdate();
  1106.         }
  1107. }
  1108.  
  1109. void TEditor::update( uchar aFlags )
  1110. {
  1111.     updateFlags |= aFlags;
  1112.     if( lockCount == 0 )
  1113.         doUpdate();
  1114. }
  1115.  
  1116. void TEditor::updateCommands()
  1117. {
  1118.     setCmdState( cmUndo, Boolean( delCount != 0 || insCount != 0 ) );
  1119.     if( isClipboard() == False )
  1120.         {
  1121.         setCmdState(cmCut, hasSelection());
  1122.         setCmdState(cmCopy, hasSelection());
  1123.         setCmdState(cmPaste,
  1124.                     Boolean(clipboard != 0 && (clipboard->hasSelection())) );
  1125.         }
  1126.     setCmdState(cmClear, hasSelection());
  1127.     setCmdState(cmFind, True);
  1128.     setCmdState(cmReplace, True);
  1129.     setCmdState(cmSearchAgain, True);
  1130. }
  1131.  
  1132. Boolean TEditor::valid( ushort )
  1133. {
  1134.   return isValid;
  1135. }
  1136.  
  1137. void TEditor::setWidth( int Size )
  1138. {
  1139.     widthSize = Size;
  1140. }
  1141.  
  1142. #if !defined(NO_STREAMABLE)
  1143.  
  1144. void TEditor::write( opstream& os )
  1145. {
  1146.     TView::write( os );
  1147.     os << hScrollBar << vScrollBar << indicator
  1148.        << bufSize << (int)canUndo;
  1149. }
  1150.  
  1151. void *TEditor::read( ipstream& is )
  1152. {
  1153.     TView::read( is );
  1154.     int temp;
  1155.     is >> hScrollBar >> vScrollBar >> indicator
  1156.        >> bufSize >> temp;
  1157.     canUndo = Boolean(temp);
  1158.     selecting = False;
  1159.     overwrite = False;
  1160.     autoIndent = False;
  1161.     lockCount = 0;
  1162.     keyState = 0;
  1163.     initBuffer();
  1164.     if( buffer != 0 )
  1165.         isValid = True;
  1166.     else
  1167.         {
  1168.         TEditor::editorDialog( edOutOfMemory, 0 );
  1169.         bufSize = 0;
  1170.         }
  1171.     lockCount = 0;
  1172.     lock();
  1173.     setBufLen( 0 );
  1174.     return this;
  1175. }
  1176.  
  1177. TStreamable *TEditor::build()
  1178. {
  1179.     return new TEditor( streamableInit );
  1180. }
  1181.  
  1182. TEditor::TEditor( StreamableInit ) : TView( streamableInit )
  1183. {
  1184. }
  1185.  
  1186. #endif
  1187.