home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 9.ddi / TVSRC.ZIP / TEDITOR1.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  17.3 KB  |  613 lines

  1. /*------------------------------------------------------------*/
  2. /* filename - teditor1.cpp                                    */
  3. /*                                                            */
  4. /* function(s)                                                */
  5. /*            TEditor member functions                        */
  6. /*------------------------------------------------------------*/
  7.  
  8. /*------------------------------------------------------------*/
  9. /*                                                            */
  10. /*    Turbo Vision -  Version 1.0                             */
  11. /*                                                            */
  12. /*                                                            */
  13. /*    Copyright (c) 1991 by Borland International             */
  14. /*    All Rights Reserved.                                    */
  15. /*                                                            */
  16. /*------------------------------------------------------------*/
  17.  
  18. #define Uses_TKeys
  19. #define Uses_TEditor
  20. #define Uses_TIndicator
  21. #define Uses_TEvent
  22. #define Uses_TScrollBar
  23. #define Uses_TFindDialogRec
  24. #define Uses_TReplaceDialogRec
  25. #define Uses_opstream
  26. #define Uses_ipstream
  27. #include <tv.h>
  28.  
  29. #if !defined( __STRING_H )
  30. #include <string.h>
  31. #endif  // __STRING_H
  32.  
  33. #if !defined( __CTYPE_H )
  34. #include <ctype.h>
  35. #endif  // __CTYPE_H
  36.  
  37. #if !defined( __DOS_H )
  38. #include <Dos.h>
  39. #endif  // __DOS_H
  40.  
  41. inline int isWordChar( int ch )
  42. {
  43.     return isalnum(ch) || ch == '_';
  44. }
  45.  
  46. const ushort firstKeys[] =
  47. {
  48.     37,
  49.     kbCtrlA, cmWordLeft,
  50.     kbCtrlC, cmPageDown,
  51.     kbCtrlD, cmCharRight,
  52.     kbCtrlE, cmLineUp,
  53.     kbCtrlF, cmWordRight,
  54.     kbCtrlG, cmDelChar,
  55.     kbCtrlH, cmBackSpace,
  56.     kbCtrlK, 0xFF02,
  57.     kbCtrlL, cmSearchAgain,
  58.     kbCtrlM, cmNewLine,
  59.     kbCtrlO, cmIndentMode,
  60.     kbCtrlQ, 0xFF01,
  61.     kbCtrlR, cmPageUp,
  62.     kbCtrlS, cmCharLeft,
  63.     kbCtrlT, cmDelWord,
  64.     kbCtrlU, cmUndo,
  65.     kbCtrlV, cmInsMode,
  66.     kbCtrlX, cmLineDown,
  67.     kbCtrlY, cmDelLine,
  68.     kbLeft, cmCharLeft,
  69.     kbRight, cmCharRight,
  70.     kbCtrlLeft, cmWordLeft,
  71.     kbCtrlRight, cmWordRight,
  72.     kbHome, cmLineStart,
  73.     kbEnd, cmLineEnd,
  74.     kbUp, cmLineUp,
  75.     kbDown, cmLineDown,
  76.     kbPgUp, cmPageUp,
  77.     kbPgDn, cmPageDown,
  78.     kbCtrlPgUp, cmTextStart,
  79.     kbCtrlPgDn, cmTextEnd,
  80.     kbIns, cmInsMode,
  81.     kbDel, cmDelChar,
  82.     kbShiftIns, cmPaste,
  83.     kbShiftDel, cmCut,
  84.     kbCtrlIns, cmCopy,
  85.     kbCtrlDel, cmClear
  86. };
  87.  
  88. const ushort quickKeys[] =
  89. {   8,
  90.     'A', cmReplace,
  91.     'C', cmTextEnd,
  92.     'D', cmLineEnd,
  93.     'F', cmFind,
  94.     'H', cmDelStart,
  95.     'R', cmTextStart,
  96.     'S', cmLineStart,
  97.     'Y', cmDelEnd
  98. };
  99.  
  100. const ushort blockKeys[] =
  101. {   5,
  102.     'B', cmStartSelect,
  103.     'C', cmPaste,
  104.     'H', cmHideSelect,
  105.     'K', cmCopy,
  106.     'Y', cmCut
  107. };
  108.  
  109. const ushort *keyMap[] = { firstKeys, quickKeys, blockKeys };
  110.  
  111. ushort defEditorDialog( int, ... );
  112.  
  113. #pragma warn -asc
  114.  
  115. ushort scanKeyMap( const void *keyMap, int keyCode )
  116. {
  117. asm {
  118.     PUSH DS
  119.     LDS SI,keyMap
  120.     MOV DX,keyCode
  121.     CLD
  122.     LODSW
  123.     MOV CX,AX
  124.     }
  125. __1:
  126. asm {
  127.     LODSW
  128.     MOV BX,AX
  129.     LODSW
  130.     CMP BL,DL
  131.     JNE __3
  132.     OR  BH,BH
  133.     JE  __4
  134.     CMP BH,DH
  135.     JE  __4
  136.     }
  137. __3:
  138. asm {
  139.     LOOP    __1
  140.     XOR AX,AX
  141.     }
  142. __4:
  143. asm POP DS
  144.     return _AX;
  145. }
  146.  
  147. #pragma warn .asc
  148.  
  149. #define cpEditor    "\x06\x07"
  150.  
  151. TEditor::TEditor( const TRect& bounds,
  152.                   TScrollBar *aHScrollBar,
  153.                   TScrollBar *aVScrollBar,
  154.                   TIndicator *aIndicator,
  155.                   ushort aBufSize ) :
  156.     TView( bounds ),
  157.     hScrollBar( aHScrollBar ),
  158.     vScrollBar( aVScrollBar ),
  159.     indicator( aIndicator ),
  160.     bufSize( aBufSize ),
  161.     canUndo( True ),
  162.     selecting( False ),
  163.     overwrite( False ),
  164.     autoIndent( False ) ,
  165.     lockCount( 0 ),
  166.     keyState( 0 )
  167. {
  168.     growMode = gfGrowHiX | gfGrowHiY;
  169.     options |= ofSelectable;
  170.     eventMask = evMouseDown | evKeyDown | evCommand | evBroadcast;
  171.     showCursor();
  172.     initBuffer();
  173.     if( buffer != 0 )
  174.         isValid = True;
  175.     else
  176.     {
  177.         editorDialog( edOutOfMemory );
  178.         bufSize = 0;
  179.         isValid = False;
  180.     }
  181.     setBufLen(0);
  182. }
  183.  
  184. TEditor::~TEditor()
  185. {
  186. }
  187.  
  188. void TEditor::shutDown()
  189. {
  190.     doneBuffer();
  191.     TView::shutDown();
  192. }
  193.  
  194. void TEditor::changeBounds( const TRect& bounds )
  195. {
  196.     setBounds(bounds);
  197.     delta.x = max(0, min(delta.x, limit.x - size.x));
  198.     delta.y = max(0, min(delta.y, limit.y - size.y));
  199.     update(ufView);
  200. }
  201.  
  202. int TEditor::charPos( ushort p, ushort target )
  203. {
  204.     int pos = 0;
  205.     while( p < target )
  206.     {
  207.         if( bufChar(p) == '\x9' )
  208.             pos |= 7;
  209.         pos++;
  210.         p++;
  211.     }
  212.     return pos;
  213. }
  214.  
  215. ushort TEditor::charPtr( ushort p, int target )
  216. {
  217.   int pos = 0;
  218.   while( (pos < target) && (p < bufLen) && (bufChar(p) != '\x0D') )
  219.     {
  220.     if( bufChar(p) == '\x09' )
  221.         pos |= 7;
  222.     pos++;
  223.     p++;
  224.     }
  225.   if( pos > target )
  226.     p--;
  227.   return p;
  228. }
  229.  
  230. Boolean TEditor::clipCopy()
  231. {
  232.     Boolean res = False;
  233.     if( (clipboard != 0) && (clipboard != this) )
  234.         {
  235.         res = clipboard->insertFrom(this);
  236.         selecting = False;
  237.         update(ufUpdate);
  238.         }
  239.     return res;
  240. }
  241.  
  242. void TEditor::clipCut()
  243. {
  244.     if( clipCopy() == True )
  245.         deleteSelect();
  246. }
  247.  
  248. void TEditor::clipPaste()
  249. {
  250.     if( (clipboard != 0) && (clipboard != this) )
  251.         insertFrom(clipboard);
  252. }
  253.  
  254. void TEditor::convertEvent( TEvent& event )
  255. {
  256.     if( event.what == evKeyDown )
  257.         {
  258.         const uchar far *const shiftState = (uchar far *)MK_FP( 0x40, 0x17 );
  259.         if( (*shiftState & 0x03) != 0 &&
  260.             event.keyDown.charScan.scanCode >= 0x47 &&
  261.             event.keyDown.charScan.scanCode <= 0x51
  262.           )
  263.             event.keyDown.charScan.charCode = 0;
  264.  
  265.         ushort key = event.keyDown.keyCode;
  266.         if( keyState != 0 )
  267.             {
  268.             if( (key & 0xFF) >= 0x01 && (key & 0xFF) <= 0x1A )
  269.                 key += 0x40;
  270.             if( (key & 0xFF) >= 0x61 && (key & 0xFF) <= 0x7A )
  271.                 key -= 0x20;
  272.             }
  273.         key = scanKeyMap(keyMap[keyState], key);
  274.         keyState = 0;
  275.         if( key != 0 )
  276.             if( (key & 0xFF00) == 0xFF00 )
  277.                 {
  278.                 keyState = (key & 0xFF);
  279.                 clearEvent(event);
  280.                 }
  281.             else
  282.                 {
  283.                 event.what = evCommand;
  284.                 event.message.command = key;
  285.                 }
  286.         }
  287. }
  288.  
  289. Boolean TEditor::cursorVisible()
  290. {
  291.   return Boolean((curPos.y >= delta.y) && (curPos.y < delta.y + size.y));
  292. }
  293.  
  294. void TEditor::deleteRange( ushort startPtr,
  295.                            ushort endPtr,
  296.                            Boolean delSelect
  297.                          )
  298. {
  299.     if( hasSelection() == True && delSelect == True )
  300.         deleteSelect();
  301.     else
  302.         {
  303.         setSelect(curPtr, endPtr, True);
  304.         deleteSelect();
  305.         setSelect(startPtr, curPtr, False);
  306.         deleteSelect();
  307.         }
  308. }
  309.  
  310. void TEditor::deleteSelect()
  311. {
  312.     insertText( 0, 0, False );
  313. }
  314.  
  315. void TEditor::doneBuffer()
  316. {
  317.     delete buffer;
  318. }
  319.  
  320. void TEditor::doSearchReplace()
  321. {
  322.     int i;
  323.     do  {
  324.         i = cmCancel;
  325.         if( search(findStr, editorFlags) == False )
  326.             {
  327.             if( (editorFlags & (efReplaceAll | efDoReplace)) !=
  328.                 (efReplaceAll | efDoReplace) )
  329.                     editorDialog( edSearchFailed );
  330.             }
  331.         else
  332.             if( (editorFlags & efDoReplace) != 0 )
  333.                 {
  334.                 i = cmYes;
  335.                 if( (editorFlags & efPromptOnReplace) != 0 )
  336.                     {
  337.                     TPoint c = makeGlobal( cursor );
  338.                     i = editorDialog( edReplacePrompt, &c );
  339.                     }
  340.                 if( i == cmYes )
  341.                     {
  342.                     lock();
  343.                     insertText( replaceStr, strlen(replaceStr), False);
  344.                     trackCursor(False);
  345.                     unlock();
  346.                     }
  347.                 }
  348.         } while( i != cmCancel && (editorFlags & efReplaceAll) != 0 );
  349. }
  350.  
  351. void TEditor::doUpdate()
  352. {
  353.     if( updateFlags != 0 )
  354.         {
  355.         setCursor(curPos.x - delta.x, curPos.y - delta.y);
  356.         if( (updateFlags & ufView) != 0 )
  357.             drawView();
  358.         else
  359.             if( (updateFlags & ufLine) != 0 )
  360.                 drawLines( curPos.y-delta.y, 1, lineStart(curPtr) );
  361.         if( hScrollBar != 0 )
  362.             hScrollBar->setParams(delta.x, 0, limit.x - size.x, size.x / 2, 1);
  363.         if( vScrollBar != 0 )
  364.             vScrollBar->setParams(delta.y, 0, limit.y - size.y, size.y - 1, 1);
  365.         if( indicator != 0 )
  366.             indicator->setValue(curPos, modified);
  367.         if( (state & sfActive) != 0 )
  368.             updateCommands();
  369.         updateFlags = 0;
  370.         }
  371. }
  372.  
  373. void TEditor::draw()
  374. {
  375.     if( drawLine != delta.y )
  376.         {
  377.         drawPtr = lineMove( drawPtr, delta.y - drawLine );
  378.         drawLine = delta.y;
  379.         }
  380.     drawLines( 0, size.y, drawPtr );
  381. }
  382.  
  383. void TEditor::drawLines( int y, int count, ushort linePtr )
  384. {
  385.     ushort color = getColor(0x0201);
  386.     while( count-- > 0 )
  387.         {
  388.         ushort b[maxLineLength];
  389.         formatLine( b, linePtr, delta.x+size.x, color );
  390.         writeBuf(0, y, size.x, 1, &b[delta.x]);
  391.         linePtr = nextLine(linePtr);
  392.         y++;
  393.         }
  394. }
  395.  
  396. void TEditor::find()
  397. {
  398.     TFindDialogRec findRec( findStr, editorFlags );
  399.     if( editorDialog( edFind, &findRec ) != cmCancel )
  400.         {
  401.         strcpy( findStr, findRec.find );
  402.         editorFlags = findRec.options & ~efDoReplace;
  403.         doSearchReplace();
  404.         }
  405. }
  406.  
  407. ushort TEditor::getMousePtr( TPoint m )
  408. {
  409.     TPoint mouse = makeLocal( m );
  410.     mouse.x = max(0, min(mouse.x, size.x - 1));
  411.     mouse.y = max(0, min(mouse.y, size.y - 1));
  412.     return charPtr(lineMove(drawPtr, mouse.y + delta.y - drawLine),
  413.         mouse.x + delta.x);
  414. }
  415.  
  416. TPalette& TEditor::getPalette() const
  417. {
  418.     static TPalette palette( cpEditor, sizeof( cpEditor )-1 );
  419.     return palette;
  420. }
  421.  
  422. void TEditor::checkScrollBar( const TEvent& event,
  423.                               TScrollBar *p,
  424.                               int& d
  425.                             )
  426. {
  427.     if( (event.message.infoPtr == p) && (p->value != d) )
  428.         {
  429.         d = p->value;
  430.         update( ufView );
  431.         }
  432. }
  433.  
  434. void TEditor::handleEvent( TEvent& event )
  435. {
  436.     TView::handleEvent( event );
  437.     convertEvent( event );
  438.     Boolean centerCursor = Boolean(!cursorVisible());
  439.     uchar selectMode = 0;
  440.     uchar far *shiftState = (uchar far *)MK_FP( 0x40, 0x17 );
  441.  
  442.     if( selecting == True || (*shiftState & 0x03) != 0 )
  443.         selectMode = smExtend;
  444.  
  445.     switch( event.what )
  446.         {
  447.  
  448.         case evMouseDown:
  449.             if( event.mouse.doubleClick == True )
  450.                 selectMode |= smDouble;
  451.  
  452.             do  {
  453.                 lock();
  454.                 if( event.what == evMouseAuto )
  455.                     {
  456.                     TPoint mouse = makeLocal( event.mouse.where );
  457.                     TPoint d = delta;
  458.                     if( mouse.x < 0 )
  459.                         d.x--;
  460.                     if( mouse.x >= size.x )
  461.                         d.x++;
  462.                     if( mouse.y < 0 )
  463.                         d.y--;
  464.                     if( mouse.y >= size.y )
  465.                         d.y++;
  466.                     scrollTo(d.x, d.y);
  467.                     }
  468.                 setCurPtr(getMousePtr(event.mouse.where), selectMode);
  469.                 selectMode |= smExtend;
  470.                 unlock();
  471.                 } while( mouseEvent(event, evMouseMove + evMouseAuto) );
  472.             break;
  473.  
  474.         case evKeyDown:
  475.             if( event.keyDown.charScan.charCode == 9 ||
  476.                 ( event.keyDown.charScan.charCode >= 32 && event.keyDown.charScan.charCode < 255 ) )
  477.                     {
  478.                     lock();
  479.                     if( overwrite == True && hasSelection() == False )
  480.                         if( curPtr != lineEnd(curPtr) )
  481.                             selEnd = nextChar(curPtr);
  482.                     insertText( &event.keyDown.charScan.charCode, 1, False);
  483.                     trackCursor(centerCursor);
  484.                     unlock();
  485.                     }
  486.             else
  487.                 return;
  488.             break;
  489.  
  490.         case evCommand:
  491.             switch( event.message.command )
  492.                 {
  493.                 case cmFind:
  494.                     find();
  495.                     break;
  496.                 case cmReplace:
  497.                     replace();
  498.                     break;
  499.                 case cmSearchAgain:
  500.                     doSearchReplace();
  501.                     break;
  502.                 default:
  503.                     lock();
  504.                     switch( event.message.command )
  505.                         {
  506.                         case cmCut:
  507.                             clipCut();
  508.                             break;
  509.                         case cmCopy:
  510.                             clipCopy();
  511.                             break;
  512.                         case cmPaste:
  513.                             clipPaste();
  514.                             break;
  515.                         case cmUndo:
  516.                             undo();
  517.                             break;
  518.                         case cmClear:
  519.                             deleteSelect();
  520.                             break;
  521.                         case cmCharLeft:
  522.                             setCurPtr(prevChar(curPtr), selectMode);
  523.                             break;
  524.                         case cmCharRight:
  525.                             setCurPtr(nextChar(curPtr), selectMode);
  526.                             break;
  527.                         case cmWordLeft:
  528.                             setCurPtr(prevWord(curPtr), selectMode);
  529.                             break;
  530.                         case cmWordRight:
  531.                             setCurPtr(nextWord(curPtr), selectMode);
  532.                             break;
  533.                         case cmLineStart:
  534.                             setCurPtr(lineStart(curPtr), selectMode);
  535.                             break;
  536.                         case cmLineEnd:
  537.                             setCurPtr(lineEnd(curPtr), selectMode);
  538.                             break;
  539.                         case cmLineUp:
  540.                             setCurPtr(lineMove(curPtr, -1), selectMode);
  541.                             break;
  542.                         case cmLineDown:
  543.                             setCurPtr(lineMove(curPtr, 1), selectMode);
  544.                             break;
  545.                         case cmPageUp:
  546.                             setCurPtr(lineMove(curPtr, -(size.y-1)), selectMode);
  547.                             break;
  548.                         case cmPageDown:
  549.                             setCurPtr(lineMove(curPtr, size.y-1), selectMode);
  550.                             break;
  551.                         case cmTextStart:
  552.                             setCurPtr(0, selectMode);
  553.                             break;
  554.                         case cmTextEnd:
  555.                             setCurPtr(bufLen, selectMode);
  556.                             break;
  557.                         case cmNewLine:
  558.                             newLine();
  559.                             break;
  560.                         case cmBackSpace:
  561.                             deleteRange(prevChar(curPtr), curPtr, True);
  562.                             break;
  563.                         case cmDelChar:
  564.                             deleteRange(curPtr, nextChar(curPtr), True);
  565.                             break;
  566.                         case cmDelWord:
  567.                             deleteRange(curPtr, nextWord(curPtr), False);
  568.                             break;
  569.                         case cmDelStart:
  570.                             deleteRange(lineStart(curPtr), curPtr, False);
  571.                             break;
  572.                         case cmDelEnd:
  573.                             deleteRange(curPtr, lineEnd(curPtr), False);
  574.                             break;
  575.                         case cmDelLine:
  576.                             deleteRange(lineStart(curPtr), nextLine(curPtr), False);
  577.                             break;
  578.                         case cmInsMode:
  579.                             toggleInsMode();
  580.                             break;
  581.                         case cmStartSelect:
  582.                             startSelect();
  583.                             break;
  584.                         case cmHideSelect:
  585.                             hideSelect();
  586.                             break;
  587.                         case cmIndentMode:
  588.                             autoIndent = Boolean(!autoIndent);
  589.                             break;
  590.                         default:
  591.                             unlock();
  592.                             return;
  593.                         }
  594.                     trackCursor(centerCursor);
  595.                     unlock();
  596.                     break;
  597.                 }
  598.  
  599.         case evBroadcast:
  600.             switch( event.message.command )
  601.                 {
  602.                 case cmScrollBarChanged:
  603.                     checkScrollBar( event, hScrollBar, delta.x );
  604.                     checkScrollBar( event, vScrollBar, delta.y );
  605.                     break;
  606.                 default:
  607.                     return;
  608.                 }
  609.         }
  610.     clearEvent(event);
  611. }
  612.  
  613.