home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / powervww / pveditor.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-05  |  85.3 KB  |  2,927 lines

  1. //  ____________________________________________________
  2. // |                                                    |
  3. // |  Project:     POWER VIEW INTERFACE                 |
  4. // |  File:        PVEDITOR.CPP                         |
  5. // |  Compiler:    WPP386 (10.6)                        |
  6. // |                                                    |
  7. // |  Subject:     Text editor implementation           |
  8. // |                                                    |
  9. // |  Author:      Emil Dotchevski                      |
  10. // |____________________________________________________|
  11. //
  12. // E-mail: zajo@geocities.com
  13. // URL:    http://www.geocities.com/SiliconValley/Bay/3577
  14.  
  15. #define uses_fcntl
  16. #define uses_io
  17. #define uses_stdio
  18. #define uses_string
  19. #define uses_app
  20. #define uses_check
  21. #define uses_ctype
  22. #define uses_dc
  23. #define uses_desk
  24. #define uses_dialog
  25. #define uses_errno
  26. #define uses_editor
  27. #define uses_help
  28. #define uses_label
  29. #define uses_lbox
  30. #define uses_icons
  31. #define uses_input
  32. #define uses_stddlg
  33. #define uses_system
  34.  
  35. #define DECLARE_PVEDITOR
  36. #include "PVuses.h"
  37. #undef DECLARE_PVEDITOR
  38.  
  39. #define smEXTEND                        0x01
  40. #define smDOUBLE                        0x02
  41.  
  42. #define sfSEARCH_FAILED                 ((uint)-1)
  43.  
  44. #ifdef SYNTAXHILIGHT
  45. #define MAX_RESERVED_WORD_LENGTH        16
  46. #else
  47. #define MAX_RESERVED_WORD_LENGTH        0
  48. #endif
  49.  
  50. /*
  51. STATIC DATA
  52. */
  53.   static uint first_keys[] =
  54.   {
  55.     50,
  56.     kCTRL_A,      cmeWORD_LEFT,
  57.     kCTRL_C,      cmePAGE_DOWN,
  58.     kCTRL_D,      cmeCHAR_RIGHT,
  59.     kCTRL_E,      cmeLINE_UP,
  60.     kCTRL_F,      cmeWORD_RIGHT,
  61.     kCTRL_G,      cmeDEL_CHAR,
  62.     kCTRL_H,      cmeBACK_SPACE,
  63.     kCTRL_J,      cmeGOTO_LINE,
  64.     kCTRL_K,      0xFF02,
  65.     kCTRL_L,      cmeSEARCH_AGAIN,
  66.     kCTRL_M,      cmeNEW_LINE,
  67.     kCTRL_O,      cmeINDENT_MODE,
  68.     kCTRL_Q,      0xFF01,
  69.     kCTRL_R,      cmePAGE_UP,
  70.     kCTRL_S,      cmeCHAR_LEFT,
  71.     kCTRL_T,      cmeDEL_WORD,
  72.     kALT_BS,      cmUNDO,
  73.     kCTRL_V,      cmeINS_MODE,
  74.     kCTRL_W,      cmeSCROLL_UP,
  75.     kCTRL_X,      cmeLINE_DOWN,
  76.     kCTRL_Y,      cmeDEL_LINE,
  77.     kCTRL_Z,      cmeSCROLL_DOWN,
  78.     kLEFT,        cmeCHAR_LEFT,
  79.     kSHIFT_LEFT,  cmeCHAR_LEFT,
  80.     kRIGHT,       cmeCHAR_RIGHT,
  81.     kSHIFT_RIGHT, cmeCHAR_RIGHT,
  82.     kCTRL_LEFT,   cmeWORD_LEFT,
  83.     kCTRL_RIGHT,  cmeWORD_RIGHT,
  84.     kHOME,        cmeLINE_START,
  85.     kSHIFT_HOME,  cmeLINE_START,
  86.     kEND,         cmeLINE_END,
  87.     kSHIFT_END,   cmeLINE_END,
  88.     kUP,          cmeLINE_UP,
  89.     kSHIFT_UP,    cmeLINE_UP,
  90.     kDOWN,        cmeLINE_DOWN,
  91.     kSHIFT_DOWN,  cmeLINE_DOWN,
  92.     kPG_UP,       cmePAGE_UP,
  93.     kSHIFT_PG_UP, cmePAGE_UP,
  94.     kPG_DN,       cmePAGE_DOWN,
  95.     kSHIFT_PG_DN, cmePAGE_DOWN,
  96.     kCTRL_PG_UP,  cmeTEXT_START,
  97.     kCTRL_PG_DN,  cmeTEXT_END,
  98.     kCTRL_HOME,   cmeSCREEN_TOP,
  99.     kCTRL_END,    cmeSCREEN_BOTTOM,
  100.     kTAB,         cmeTAB,
  101.     kINS,         cmeINS_MODE,
  102.     kDEL,         cmeDEL_CHAR,
  103.     kSHIFT_INS,   cmPASTE,
  104.     kSHIFT_DEL,   cmCUT,
  105.     kCTRL_INS,    cmCOPY
  106.   };
  107.   static uint quick_keys[] =
  108.   {
  109.     20,
  110.     'A',          cmeREPLACE,
  111.     'C',          cmeTEXT_END,
  112.     'D',          cmeLINE_END,
  113.     'E',          cmeSCREEN_TOP,
  114.     'F',          cmeFIND,
  115.     'H',          cmeDEL_START,
  116.     'R',          cmeTEXT_START,
  117.     'S',          cmeLINE_START,
  118.     'X',          cmeSCREEN_BOTTOM,
  119.     'Y',          cmeDEL_END,
  120.     '0',          cmeGMARK0,
  121.     '1',          cmeGMARK1,
  122.     '2',          cmeGMARK2,
  123.     '3',          cmeGMARK3,
  124.     '4',          cmeGMARK4,
  125.     '5',          cmeGMARK5,
  126.     '6',          cmeGMARK6,
  127.     '7',          cmeGMARK7,
  128.     '8',          cmeGMARK8,
  129.     '9',          cmeGMARK9
  130.   };
  131.   static uint block_keys[] =
  132.   {
  133.     18,
  134.     'B',          cmeSTART_SELECT,
  135.     'C',          cmPASTE,
  136.     'H',          cmeHIDE_SELECT,
  137.     'K',          cmCOPY,
  138.     'Y',          cmCUT,
  139.     'I',          cmeINDENT,
  140.     'U',          cmeUNINDENT,
  141.     'S',          cmSAVE,
  142.     '0',          cmeMARK0,
  143.     '1',          cmeMARK1,
  144.     '2',          cmeMARK2,
  145.     '3',          cmeMARK3,
  146.     '4',          cmeMARK4,
  147.     '5',          cmeMARK5,
  148.     '6',          cmeMARK6,
  149.     '7',          cmeMARK7,
  150.     '8',          cmeMARK8,
  151.     '9',          cmeMARK9
  152.   };
  153.   static uint *key_map[] =
  154.   {
  155.     first_keys,
  156.     quick_keys,
  157.     block_keys
  158.   };
  159. #ifdef CPPHILIGHT
  160.  static Tset cpp_symbols;
  161. #endif
  162. #ifdef ASMHILIGHT
  163.  static Tset asm_symbols;
  164. #endif
  165. #ifdef A51HILIGHT
  166.  static Tset a51_symbols;
  167. #endif
  168.  
  169.  
  170. /*
  171. STATIC FUNCTIONS
  172. */
  173.   static int count_lines( char *buf, uint count )
  174.   {
  175.     uint cnt;
  176.  
  177.     cnt = 0;
  178.     count++;
  179.     while( --count )
  180.       if( *( buf++ ) == '\r' ) cnt++;
  181.     return cnt;
  182.   }
  183.  
  184.   static uint scan_key_map( uint *key_map, uint key_code )
  185.   {
  186.     uint count, key, cmd;
  187.  
  188.     count = *( key_map++ ) + 1;
  189.     while( --count )
  190.     {
  191.       key = *( key_map++ );
  192.       cmd = *( key_map++ );
  193.       if( key == key_code ) return cmd;
  194.     }
  195.     return 0;
  196.   }
  197.  
  198.   static uint scan( char *block, uint size, char *str )
  199.   {
  200.     uint length, counter;
  201.  
  202.     length = strlen( str );
  203.     if( size >= length )
  204.     {
  205.       counter = size - length + 1;
  206.       while( --counter )
  207.       {
  208.         if( memcmp( block, str, length ) == 0 ) return size - length - counter;
  209.         block++;
  210.       }
  211.     }
  212.     return sfSEARCH_FAILED;
  213.   }
  214.  
  215.   static uint iscan( char *block, uint size, char *str )
  216.   {
  217.     char s[256], *_s, *_block;
  218.     uint length, _length, counter;
  219.  
  220.     length = strlen( str );
  221.     if( size >= length )
  222.     {
  223.       strcpy( s, str );
  224.       strupr( s );
  225. #ifdef CYR
  226.       cyr_strupr( s );
  227. #endif
  228.       counter = size - length + 1;
  229.       while( --counter )
  230.       {
  231.         _length = length + 1; _block = block; _s = s;
  232.         while( --_length )
  233.         {
  234. #ifdef CYR
  235.           char c=cyr_toupper(toupper(*(_block++)));
  236. #else
  237.           char c=toupper(*(_block++));
  238. #endif
  239.           if( c!=*(_s++) ) goto differrent;
  240.         }
  241.         return size - length - counter;
  242.       differrent:
  243.         block++;
  244.       }
  245.     }
  246.     return sfSEARCH_FAILED;
  247.   }
  248.  
  249. #ifdef SYNTAXHILIGHT
  250.   static boolean must_hilight( char *file_name, char *extensions )
  251.   {
  252.     if( extensions!=NULL )
  253.     {
  254.       char ext[_MAX_EXT];
  255.       _splitpath( file_name, NULL, NULL, NULL, ext );
  256.       int l=strlen( ext );
  257.       if( l<2 ) return 0;
  258.       for( char *c=extensions; *c; c++ )
  259.         if( *c=='.' && !memcmp( ext, c, l ) && !isalnum(*(c+l)) )
  260.           return 1;
  261.     }
  262.     return 0;
  263.   }
  264. #endif //SYNTAXHILIGHT
  265.  
  266.  
  267. /*
  268. Ttext_editor
  269. */
  270.  
  271. //public:
  272.  
  273.   static init_text_editor( Ttext_editor *text_editor, Teditor *editor )
  274.   {
  275.     text_editor->date = text_editor->time = 0;
  276.     text_editor->file_name = STRDUP("");
  277.     text_editor->booleans = ebCAN_UNDO;
  278.     text_editor->assoc_number = 0;
  279.     text_editor->editor = editor;
  280.     if( text_editor->edit_buffer == NULL )
  281.     {
  282.       text_editor->editor_dialog( edOUT_OF_MEMORY, NULL );
  283.       text_editor->buf_size = 0;
  284.     }
  285.     text_editor->set_buf_len( 0 );
  286.     ~text_editor->valid_chars;
  287.     text_editor->valid_chars << 9;
  288.     for( int i=32; i<256; i++ ) text_editor->valid_chars << i;
  289.   }
  290.  
  291.   Ttext_editor::Ttext_editor( uint _buf_size, Teditor *_editor )
  292.   {
  293.     buf_size = _buf_size;
  294.     edit_buffer = (char *) MALLOC( buf_size+1 );
  295.     edit_buffer[buf_size]=0;
  296.     init_text_editor( this, _editor );
  297.     booleans |= ( ebDISPOSE_BUFFER + ebCAN_GROW );
  298.   }
  299.  
  300.   Ttext_editor::Ttext_editor( char *_edit_buffer, uint _buf_size, Teditor *_editor )
  301.   {
  302.     buf_size = _buf_size;
  303.     edit_buffer = _edit_buffer;
  304.     init_text_editor( this, _editor );
  305.   }
  306.  
  307.   Ttext_editor::~Ttext_editor( void )
  308.   {
  309.     if( booleans & ebDISPOSE_BUFFER ) FREE( edit_buffer );
  310.     FREE( file_name );
  311.     edit_buffer = NULL;
  312.   }
  313.  
  314.   boolean Ttext_editor::set_buf_size( uint new_size )
  315.   {
  316.     uint n;
  317.     void *new_pos;
  318.  
  319.     if( !( booleans & ebCAN_GROW ) ) return new_size <= buf_size;
  320.     if( !new_size )
  321.       new_size = 0x1000;
  322.     else
  323. #ifndef __386__
  324.       if( new_size > 0xF000 )
  325.         new_size = 0xFFF0;
  326.       else
  327. #endif
  328. #ifdef __386__
  329.         new_size = ( new_size + 0x0FFF ) & 0xFFFFF000;
  330. #else
  331.         new_size = ( new_size + 0x0FFF ) & 0xF000;
  332. #endif
  333.     if( new_size != buf_size )
  334.     {
  335.       if( new_size > buf_size )
  336.       {
  337.         if( ( new_pos = REALLOC( edit_buffer, new_size+1 ) ) == NULL ) return 0;
  338.         edit_buffer = (char *) new_pos;
  339.         edit_buffer[new_size]=0;
  340.       }
  341.       n = buf_len - cur_ptr + del_count;
  342.       memmove( edit_buffer + new_size - n, edit_buffer + buf_size - n, n );
  343.       buf_size = new_size;
  344.       gap_len = buf_size - buf_len;
  345.     }
  346.     return 1;
  347.   }
  348.  
  349.   void Ttext_editor::set_buf_len( uint length )
  350.   {
  351.     sel_start     = 0;
  352.     sel_end       = 0;
  353.     cur_after_eol = 0;
  354.     cur_ptr       = 0;
  355.     cur_pos_x     = 0;
  356.     cur_pos_y     = 0;
  357.     del_count     = 0;
  358.     ins_count     = 0;
  359.     booleans     &= ~( ebMODIFIED + ebSELECTING );
  360.     booleans     |= ebDIRTY;
  361.     buf_len       = length;
  362.     gap_len       = buf_size - length;
  363.     limit_xl      = MAX_LINE_LENGTH;
  364.     limit_yl      = count_lines( edit_buffer+gap_len, buf_len ) + 1;
  365.     update( 0, 0, 0 );
  366.   }
  367.  
  368.   void Ttext_editor::set_cur_ptr( uint p, char select_mode )
  369.   {
  370.     uint anchor;
  371.  
  372.     if( !( select_mode & smEXTEND ) )
  373.       anchor = p;
  374.     else
  375.       if( cur_ptr == sel_start )
  376.         anchor = sel_end;
  377.       else
  378.         anchor = sel_start;
  379.     if( p < anchor )
  380.     {
  381.       if( select_mode & smDOUBLE )
  382.       {
  383.         p = prev_line( next_line( p ) );
  384.         anchor = next_line( prev_line( anchor ) );
  385.       }
  386.       set_select( p, anchor, 1 );
  387.     }
  388.     else
  389.     {
  390.       if( select_mode & smDOUBLE )
  391.       {
  392.         p = next_line( p );
  393.         anchor = prev_line( next_line( anchor ) );
  394.       }
  395.       set_select( anchor, p, 0 );
  396.     }
  397.   }
  398.  
  399.   void Ttext_editor::set_cur_xy( int _x, uint _y, char select_mode )
  400.   {
  401.     uint p, le;
  402.     int n;
  403.  
  404.     set_cur_ptr( line_move( cur_ptr, _y - cur_pos_y ), select_mode );
  405.     p = line_start( cur_ptr );
  406.     le = line_end( cur_ptr );
  407.     _x = max( 0, _x );
  408.     n = 0;
  409.     while( ( p < le ) && ( n < _x ) )
  410.       n += ( buf_char( p++ ) == '\t' )? ( tab_size - ( n % tab_size ) ) : 1;
  411.     set_cur_ptr( p, select_mode );
  412.     if( n < _x ) cur_after_eol = _x - n;
  413.     update( 0, 0, 0 );
  414.   }
  415.  
  416.   void Ttext_editor::set_select( uint new_start, uint new_end, int cur_start )
  417.   {
  418.     uint p, l, beg, end;
  419.  
  420.     if( cur_start ) p = new_start; else p = new_end;
  421.     beg = sel_start;
  422.     end = sel_end;
  423.     if( p != cur_ptr )
  424.     {
  425.       if( p > cur_ptr )
  426.       {
  427.         l = p - cur_ptr;
  428.         memmove( edit_buffer+cur_ptr, edit_buffer+cur_ptr+gap_len, l );
  429.         cur_pos_y += count_lines( edit_buffer+cur_ptr, l );
  430.         cur_ptr = p;
  431.       }
  432.       else
  433.       {
  434.         l = cur_ptr - p;
  435.         cur_ptr = p;
  436.         cur_pos_y -= count_lines( edit_buffer+cur_ptr, l );
  437.         memmove( edit_buffer+cur_ptr+gap_len, edit_buffer+cur_ptr, l );
  438.       }
  439.       cur_pos_x = char_pos( line_start( cur_ptr ), p );
  440.       del_count = 0;
  441.       ins_count = 0;
  442.       set_buf_size( buf_len );
  443.     }
  444.     sel_start = new_start;
  445.     sel_end = new_end;
  446.     cur_after_eol = 0;
  447.     if( ( ( beg != sel_start ) || ( end != sel_end ) ) &&
  448.         ( ( beg != end ) || ( sel_start != sel_end ) ) ) booleans |= ebDIRTY;
  449.     update( 0, 0, 0 );
  450.   }
  451.  
  452.   void Ttext_editor::hide_select( void )
  453.   {
  454.     set_select( cur_ptr, cur_ptr, 0 );
  455.     booleans &= ~ebSELECTING;
  456.   }
  457.  
  458.   boolean Ttext_editor::has_selection( void )
  459.   {
  460.     return sel_start != sel_end;
  461.   }
  462.  
  463.   uint Ttext_editor::lines_selected( void )
  464.   {
  465.     if( !has_selection() ) return 0;
  466.     return count_lines( edit_buffer+buf_ptr( sel_start ), sel_end-sel_start ) + 1;
  467.   }
  468.  
  469.   void Ttext_editor::undo( void )
  470.   {
  471.     uint length;
  472.  
  473.     if( del_count || ins_count )
  474.     {
  475.       sel_start = cur_ptr - ins_count;
  476.       sel_end = cur_ptr;
  477.       length = del_count;
  478.       del_count = 0;
  479.       ins_count = 0;
  480.       insert_buffer( edit_buffer, cur_ptr + gap_len - length, length, 0, 1 );
  481.     }
  482.   }
  483.  
  484.   boolean Ttext_editor::insert_text( char *text, uint length, int select_text )
  485.   {
  486.     return insert_buffer( text, 0, length, booleans & ebCAN_UNDO, select_text );
  487.   }
  488.  
  489.   boolean Ttext_editor::insert_string( char *text, int select_text )
  490.   {
  491.     return insert_text( text, strlen( text ), select_text );
  492.   }
  493.  
  494.   boolean Ttext_editor::insert_from( Ttext_editor *text_editor )
  495.   {
  496.     return insert_buffer( text_editor->edit_buffer,
  497.       text_editor->buf_ptr( text_editor->sel_start ),
  498.       text_editor->sel_end - text_editor->sel_start,
  499.       booleans & ebCAN_UNDO,
  500.       (Ttext_editor *) clipboard == this );
  501.   }
  502.  
  503.   int Ttext_editor::smart_tab( void )
  504.   {
  505.     uint p, pe, i, cp;
  506.  
  507.     p = prev_line( line_start( cur_ptr ) );
  508.     pe = line_end( p );
  509.     cp = char_pos( line_start( cur_ptr ), cur_ptr ) + cur_after_eol;
  510.     i = 0;
  511.     while( ( p < pe ) && ( i < cp ) )
  512.     {
  513.       if( edit_buffer[p] == '\t' )
  514.         i += tab_size - ( i % tab_size );
  515.       else
  516.         i++;
  517.       p++;
  518.     }
  519.     while( ( p < pe ) &&
  520.            ( edit_buffer[p] != ' ' ) && ( ( edit_buffer[p] != '\t' ) ) )
  521.     {
  522.       i++;
  523.       p++;
  524.     }
  525.     while( p < pe )
  526.     {
  527.       if( edit_buffer[p] == ' ' )
  528.         i++;
  529.       else
  530.         if( edit_buffer[p] == '\t' )
  531.           i += tab_size - ( i % tab_size );
  532.         else
  533.           break;
  534.       p++;
  535.     }
  536.     if( p >= pe )  return cp + tab_size - ( cp % tab_size );
  537.     return i;
  538.   }
  539.  
  540.   void Ttext_editor::new_line( void )
  541.   {
  542.     static char cr_lf[2] = { 13, 10 };
  543.     uint i;
  544.  
  545.     if( !has_selection() )
  546.     {
  547.       i = cur_ptr;
  548.       while( i && ( buf_char( i - 1 ) == ' ' ) ) i--;
  549.       delete_range( i, cur_ptr, 0 );
  550.     }
  551.     cur_after_eol = 0;
  552.     insert_text( cr_lf, 2, 0 );
  553.     if( editor_flags & efAUTO_INDENT )
  554.     {
  555.       i = prev_line( line_start( cur_ptr ) );
  556.       if( ( edit_buffer[i] != ' ' ) && ( edit_buffer[i] != '\t' ) ) return;
  557.       cur_after_eol = smart_tab();
  558.       if( cur_ptr < line_end( cur_ptr ) ) insert_text( NULL, 0, 0 );
  559.     }
  560.   }
  561.  
  562.   void Ttext_editor::delete_select( void )
  563.   {
  564.     insert_text( NULL, 0, 0 );
  565.   }
  566.  
  567.   void Ttext_editor::delete_range( uint start_ptr, uint end_ptr, int del_select )
  568.   {
  569.     if( !has_selection() || !del_select )
  570.     {
  571.       set_select( cur_ptr, end_ptr, 1 );
  572.       delete_select();
  573.       set_select( start_ptr, cur_ptr, 0 );
  574.     }
  575.     delete_select();
  576.   }
  577.  
  578.   boolean Ttext_editor::clip_copy( void )
  579.   {
  580.     if( ( clipboard != NULL ) && ( clipboard != this ) )
  581.     {
  582.       booleans &= ~ebSELECTING;
  583.       return clipboard->insert_from( this );
  584.     }
  585.     return 0;
  586.   }
  587.  
  588.   void Ttext_editor::clip_cut( void )
  589.   {
  590.     if( clip_copy() )
  591.     {
  592.       delete_select();
  593.       clear_eol_spaces();
  594.     }
  595.   }
  596.  
  597.   void Ttext_editor::clip_paste( void )
  598.   {
  599.     if( ( clipboard != NULL ) && ( clipboard != this ) )
  600.       insert_from( clipboard );
  601.   }
  602.  
  603.   void Ttext_editor::get_text( char *text, uint ofs, uint length )
  604.   {
  605.     length++;
  606.     while( --length )
  607.       *text++ = buf_char( ofs++ );
  608.   }
  609.  
  610.   void Ttext_editor::get_line_str( char *str, uint length )
  611.   {
  612.     uint s, l;
  613.  
  614.     s = line_start( cur_ptr );
  615.     l = min( length, line_end( cur_ptr ) - s );
  616.     get_text( str, s, l ); str[l] = 0;
  617.   }
  618.  
  619.   void Ttext_editor::get_word_str( char *str, uint length )
  620.   {
  621.     uint s;
  622.  
  623.     if( buf_char( cur_ptr ) & word_chars )
  624.     {
  625.       s = prev_word( next_word( cur_ptr ) );
  626.       length++;
  627.       while( --length && ( s < buf_len ) &&
  628.              ( ( ( *str = buf_char( s++ ) ) & word_chars ) || ( *str == '.' ) ) )
  629.         str++;
  630.     }
  631.     *str = 0;
  632.   }
  633.  
  634.   uint Ttext_editor::next_char( uint p )
  635.   {
  636.     char *n;
  637.  
  638.     if( ( p == buf_len ) || ( ++p == buf_len ) ) return p;
  639.     n = edit_buffer;
  640.     if( p >= cur_ptr ) n += gap_len;
  641.     if( *( (word *) ( n + p - 1 ) ) == 0x0A0D ) p++;
  642.     return p;
  643.   }
  644.  
  645.   uint Ttext_editor::next_line( uint p )
  646.   {
  647.     return next_char( line_end( p ) );
  648.   }
  649.  
  650.   uint Ttext_editor::next_word( uint p )
  651.   {
  652.     while( ( p < buf_len ) && ( buf_char( p ) & word_chars ) )
  653.       p = next_char( p );
  654.     while( ( p < buf_len ) && !( buf_char( p ) & word_chars ) )
  655.       p = next_char( p );
  656.     return p;
  657.   }
  658.  
  659.   uint Ttext_editor::prev_char( uint p )
  660.   {
  661.     char *n;
  662.  
  663.     if( ( p == 0 ) || ( --p == 0 ) ) return p;
  664.     n = edit_buffer;
  665.     if( p >= cur_ptr ) n += gap_len;
  666.     if( *( (word *) ( n + p - 1 ) ) == 0x0A0D ) p--;
  667.     return p;
  668.   }
  669.  
  670.   uint Ttext_editor::prev_line( uint p )
  671.   {
  672.     return line_start( prev_char( p ) );
  673.   }
  674.  
  675.   uint Ttext_editor::prev_word( uint p)
  676.   {
  677.     while( ( p > 0 ) && !( buf_char( prev_char( p ) ) & word_chars ) )
  678.       p = prev_char( p );
  679.     while( ( p > 0 ) && ( buf_char( prev_char( p ) ) & word_chars ) )
  680.       p = prev_char( p );
  681.     return p;
  682.   }
  683.  
  684.   uint Ttext_editor::line_start( uint p )
  685.   {
  686.     while( ( p-- > 0 ) && ( buf_char( p ) != 0x0D ) );
  687.     if( buf_char( ++p ) == '\n' ) p++;
  688.     return p;
  689.   }
  690.  
  691.   uint Ttext_editor::line_end( uint p )
  692.   {
  693.     while( ( p < buf_len ) && ( buf_char( p ) != 0x0D ) )
  694.       p++;
  695.     return p;
  696.   }
  697.  
  698.   uint Ttext_editor::line_move( uint p, int count )
  699.   {
  700.     int pos;
  701.     uint i;
  702.  
  703.     i = p;
  704.     p = line_start( p );
  705.     pos = char_pos( p, i );
  706.     while( count )
  707.     {
  708.       i = p;
  709.       if( count < 0 )
  710.       {
  711.         p = prev_line( p );
  712.         count++;
  713.       }
  714.       else
  715.       {
  716.         p = next_line( p );
  717.         count--;
  718.       }
  719.     }
  720.     if( p != i ) p = char_ptr( p, pos );
  721.     return p;
  722.   }
  723.  
  724.   char Ttext_editor::buf_char( uint p )
  725.   {
  726.     if( p >= cur_ptr ) p += gap_len;
  727.     return *( edit_buffer + p );
  728.   }
  729.  
  730.   uint Ttext_editor::buf_ptr( uint p )
  731.   {
  732.     if( p >= cur_ptr ) p += gap_len;
  733.     return p;
  734.   }
  735.  
  736.   boolean Ttext_editor::search( char *find_str, uint options )
  737.   {
  738.     uint i, pos;
  739.  
  740.     pos = cur_ptr;
  741.     do
  742.     {
  743.       if( options & efCASE_SENSITIVE )
  744.         i = scan( edit_buffer + buf_ptr( pos ), buf_len - pos + 1, find_str );
  745.       else
  746.         i = iscan( edit_buffer + buf_ptr( pos ), buf_len - pos + 1, find_str );
  747.       if( ( i != sfSEARCH_FAILED ) )
  748.       {
  749.         i += pos;
  750.         if( !( options & efWHOLE_WORDS_ONLY ) ||
  751.             !( ( i && ( word_chars & buf_char( i - 1 ) ) ) ||
  752.              ( ( i + strlen( find_str ) != buf_len ) &&
  753.                ( word_chars & buf_char( i + strlen( find_str ) ) ) ) ) )
  754.         {
  755.           set_select( i, i + strlen( find_str ), 0 );
  756.           return 1;
  757.         }
  758.         else
  759.           pos = i + 1;
  760.       }
  761.     }
  762.     while( i != sfSEARCH_FAILED );
  763.     return 0;
  764.   }
  765.  
  766.   static char *__edit_buffer;
  767.   static word *__draw_buffer;
  768.   static uint __from;
  769.   static int __ready;
  770.   static int __width;
  771.  
  772.   static boolean format_to( uint to, word ch )
  773.   {
  774.     register uint count;
  775.     char *source;
  776.  
  777.     if( to < __from ) return 1;
  778.     count = to - __from;
  779.     source = __edit_buffer + __from;
  780.     loop:
  781.       while( count && ( ( __from++, lo( ch ) = *source++ ) >= ' ' ) )
  782.       {
  783.         count--;
  784.         *__draw_buffer++ = ch;
  785.         if( ++__ready >= __width ) return 0;
  786.       }
  787.       if( !count ) return 1;
  788.       if( lo( ch ) == 13 ) return 0;
  789.       count--;
  790.       if( lo( ch ) == '\t' )
  791.       {
  792.         lo( ch ) = ' ';
  793.         do
  794.         {
  795.           *__draw_buffer++ = ch;
  796.           if( ++__ready >= __width ) return 0;
  797.         }
  798.         while( __ready % tab_size );
  799.         goto loop;
  800.       }
  801.       lo( ch ) = ' ';
  802.       *__draw_buffer++ = ch;
  803.       if( ++__ready >= __width ) return 0;
  804.       goto loop;
  805.   }
  806.  
  807.   void Ttext_editor::format_line( word *draw_buf, uint line_ptr, int width, char normal, char selected )
  808.   {
  809.     word color, __normal, __selected;
  810.  
  811.     __edit_buffer = edit_buffer;
  812.     __draw_buffer = draw_buf;
  813.     __from = line_ptr;
  814.     __ready = 0;
  815.     __width = width;
  816.     __normal = normal << 8;
  817.     __selected = selected << 8;
  818.     if( format_to( sel_start, color = __normal ) &&
  819.         format_to( cur_ptr, color = __selected ) &&
  820.         ( __from += gap_len, format_to( sel_end + gap_len, color = __selected ) ) &&
  821.         format_to( buf_size, color = __normal ) );
  822.     __width -= __ready;
  823.     lo( color ) = ' ';
  824.     while( __width-- > 0 )
  825.       *(__draw_buffer++) = color;
  826.   }
  827.  
  828.   void Ttext_editor::set_name( char *_file_name )
  829.   {
  830.     char buffer[_MAX_PATH];
  831.     fexpand( strcpy(buffer,_file_name) );
  832.     FREE( file_name );
  833.     file_name=STRDUP(buffer);
  834.   }
  835.  
  836.   boolean Ttext_editor::load( void )
  837.   {
  838.     uint length;
  839.     long fsize;
  840.     int handle;
  841.     unsigned num_read;
  842.     char ctrl_z = 0;
  843.     boolean result = 0;
  844.  
  845.     if( file_name==NULL ) return 0;
  846.     length = 0;
  847.     switch( _dos_open( file_name, O_RDONLY, &handle) )
  848.     {
  849.       case 2:
  850.         result = 1;
  851.         break;
  852.       case 0:
  853.         fsize = filelength( handle );
  854.         if( fsize )
  855.         {
  856.           lseek( handle, fsize-1, 0 );
  857.           if( _dos_read( handle, &ctrl_z, 1, &num_read ) )
  858.             editor_dialog( edREAD_ERROR, file_name );
  859.           else
  860.             if( ctrl_z == 0x1A ) fsize--;
  861.           lseek( handle, 0, 0 );
  862.         }
  863.         if(
  864. #ifndef __386__
  865.             ( fsize > 0xFFF0 ) ||
  866. #endif
  867.             !set_buf_size( (uint) fsize ) )
  868.           editor_dialog( edOUT_OF_MEMORY, NULL );
  869.         else
  870.         {
  871.           if( _dos_read( handle, edit_buffer+buf_size-(uint)fsize, (uint)fsize, &num_read ) )
  872.             editor_dialog( edREAD_ERROR, file_name );
  873.           else
  874.           {
  875.             result = 1;
  876.             length = (uint) fsize;
  877.           }
  878.         }
  879.         _dos_close( handle );
  880.         break;
  881.       default:
  882.         editor_dialog( edREAD_ERROR, file_name );
  883.     }
  884.     set_buf_len( length );
  885.     return result;
  886.   }
  887.  
  888.   boolean Ttext_editor::save( void )
  889.   {
  890.     int handle;
  891.     unsigned num_written;
  892.     char drive[_MAX_DRIVE];
  893.     char dir[_MAX_DIR];
  894.     char fname[_MAX_FNAME];
  895.     char ext[_MAX_EXT];
  896.     char bak[_MAX_PATH];
  897.  
  898.     if( file_name==NULL ) return 0;
  899.     boolean result = 0;
  900.     if( editor_flags & efBACKUP_FILES )
  901.     {
  902.       _splitpath( file_name, drive, dir, fname, ext );
  903.       _makepath( bak, drive, dir, fname, ".BAK" );
  904.       remove( bak );
  905.       rename( file_name, bak );
  906.     }
  907.     if( _dos_creat( file_name, _A_NORMAL, &handle ) )
  908.       editor_dialog( edCREATE_ERROR, file_name );
  909.     else
  910.     {
  911.       if( _dos_write( handle, edit_buffer, cur_ptr, &num_written ) ||
  912.           ( num_written != cur_ptr ) ||
  913.           _dos_write( handle, edit_buffer+cur_ptr+gap_len, buf_len - cur_ptr, &num_written ) ||
  914.           ( num_written != buf_len - cur_ptr ) )
  915.         editor_dialog( edWRITE_ERROR, file_name );
  916.       else
  917.       {
  918.         booleans &= ~ebMODIFIED;
  919.         booleans |= ebDIRTY;
  920.         update( 0, 0, 0 );
  921.         result = 1;
  922.       }
  923.       _dos_close( handle );
  924.     }
  925.     if( result )
  926.     {
  927.       get_date_time( file_name, date, time );
  928.       broadcast( cmSTAMP_CHECK );
  929.     }
  930.     return result;
  931.   }
  932.  
  933. //protected:
  934.  
  935.   int Ttext_editor::char_pos( uint p, uint target )
  936.   {
  937.     int pos;
  938.  
  939.     pos = 0;
  940.     while( p < target )
  941.     {
  942.       if( buf_char( p ) == '\t' )
  943.         pos += tab_size - ( pos % tab_size );
  944.       else
  945.         pos++;
  946.       p++;
  947.     }
  948.     return pos;
  949.   }
  950.  
  951.   uint Ttext_editor::char_ptr( uint p, int target )
  952.   {
  953.     int pos;
  954.  
  955.     pos = 0;
  956.     while( ( pos < target ) && ( p < buf_len ) && ( buf_char( p ) != 13 ) )
  957.     {
  958.       if( buf_char( p ) == '\t' )
  959.         pos += tab_size - ( pos % tab_size );
  960.       else
  961.         pos++;
  962.       p++;
  963.     }
  964.     if( pos > target ) p--;
  965.     return p;
  966.   }
  967.  
  968.   boolean Ttext_editor::insert_buffer( char *p, uint offset, uint length, int allow_undo, int select_text )
  969.   {
  970.     uint sel_len, del_len, sel_lines, lines, new_size;
  971.     uint cur_ptr_inserted;
  972.     int lines_inserted;
  973.     int bytes_inserted;
  974.  
  975.     booleans &= ~ebSELECTING;
  976.     sel_len = sel_end - sel_start;
  977.     if( ( !sel_len ) && ( !length ) && ( !cur_after_eol ) ) return 1;
  978.     del_len = 0;
  979.     if( allow_undo )
  980.       if( cur_ptr == sel_start )
  981.         del_len = sel_len;
  982.       else
  983.         if( sel_len > ins_count ) del_len = sel_len - ins_count;
  984.     new_size = ( buf_len + del_count - sel_len + del_len ) + length + cur_after_eol;
  985.     if( new_size > buf_len + del_count )
  986.       if(
  987. #ifndef __386__
  988.           ( new_size > 0xFFF0 ) ||
  989. #endif
  990.           !set_buf_size( new_size ) )
  991.       {
  992.         editor_dialog( edOUT_OF_MEMORY, NULL );
  993.         sel_end = sel_start;
  994.         return 0;
  995.       }
  996.     sel_lines = count_lines( edit_buffer+buf_ptr( sel_start ), sel_len );
  997.     if( cur_ptr == sel_end )
  998.     {
  999.       if( allow_undo )
  1000.       {
  1001.         if( del_len > 0 )
  1002.           memmove( edit_buffer+cur_ptr+gap_len-del_count-del_len, edit_buffer+sel_start, del_len );
  1003.         ins_count -= ( sel_len - del_len );
  1004.       }
  1005.       cur_ptr = sel_start;
  1006.       cur_pos_y -= sel_lines;
  1007.     }
  1008.     if( cur_after_eol > 0 )
  1009.       memset( edit_buffer+cur_ptr, ' ', cur_after_eol );
  1010.     if( length > 0 )
  1011.       memmove( edit_buffer+cur_ptr+cur_after_eol, p+offset, length );
  1012.     length += cur_after_eol;
  1013.     cur_after_eol = 0;
  1014.     lines = count_lines( edit_buffer + cur_ptr, length );
  1015.     cur_ptr_inserted = cur_ptr;
  1016.     lines_inserted = lines - sel_lines;
  1017.     bytes_inserted = length - sel_len;
  1018.     cur_ptr += length;
  1019.     cur_pos_y += lines;
  1020.     limit_yl += lines_inserted;
  1021.     if( editor != NULL )
  1022.       editor->scroll_to( editor->delta_x, max( 0, min( editor->delta_y, limit_yl - editor->yl ) ) );
  1023.     cur_pos_x = char_pos( line_start( cur_ptr ), cur_ptr );
  1024.     if( !select_text ) sel_start = cur_ptr;
  1025.     sel_end = cur_ptr;
  1026.     buf_len += bytes_inserted;
  1027.     gap_len -= bytes_inserted;
  1028.     if( allow_undo )
  1029.     {
  1030.       del_count += del_len;
  1031.       ins_count += length;
  1032.     }
  1033.     if( clipboard != this ) booleans |= ebMODIFIED;
  1034.     set_buf_size( buf_len + del_count );
  1035.     booleans |= ebDIRTY;
  1036.     update( cur_ptr_inserted, bytes_inserted, lines_inserted );
  1037.     return 1;
  1038.   }
  1039.  
  1040.   void Ttext_editor::clear_eol_spaces( void )
  1041.   {
  1042.     uint p, xx;
  1043.  
  1044.     if( cur_ptr == line_end( cur_ptr ) )
  1045.     {
  1046.       p = cur_ptr;
  1047.       while( p && ( buf_char( p - 1 ) == ' ' ) ) p--;
  1048.       xx = cur_ptr - p;
  1049.       delete_range( p, cur_ptr, 1 );
  1050.       cur_after_eol = xx;
  1051.     }
  1052.   }
  1053.  
  1054.   void Ttext_editor::start_select( void )
  1055.   {
  1056.     hide_select();
  1057.     booleans |= ebSELECTING;
  1058.   }
  1059.  
  1060.   void Ttext_editor::update( uint cur_ptr_inserted, int bytes_inserted, int lines_inserted )
  1061.   {
  1062.     Tfile_editor *e;
  1063.  
  1064.     if( editor == NULL ) return;
  1065.     if( assoc_number == 1 )
  1066.       editor->update( cur_ptr_inserted, bytes_inserted, lines_inserted );
  1067.     else
  1068.       for( e=open_editors; e!=NULL; e=e->next_editor )
  1069.         if( e->text_editor == this )
  1070.           e->update( cur_ptr_inserted, bytes_inserted, lines_inserted );
  1071.     booleans &= ~ebDIRTY;
  1072.   }
  1073.  
  1074. #pragma off( unreferenced )
  1075.   uint Ttext_editor::editor_dialog( int dialog, void *info )
  1076.   {
  1077.     if( editor == NULL ) return cmCANCEL;
  1078.     return editor->editor_dialog( dialog, info );
  1079.   }
  1080. #pragma on( unreferenced )
  1081.  
  1082.  
  1083. #ifdef SYNTAXHILIGHT
  1084.  
  1085. /*
  1086. Tsyntax_editor
  1087. */
  1088.  
  1089. //public:
  1090.  
  1091.   Tsyntax_editor::Tsyntax_editor( uint _buf_size, Teditor *_editor ):
  1092.     Ttext_editor( _buf_size, _editor )
  1093.   {
  1094.   }
  1095.  
  1096.   Tsyntax_editor::Tsyntax_editor( char *_edit_buffer, uint _buf_size, Teditor *_editor ):
  1097.     Ttext_editor( _edit_buffer, _buf_size, _editor )
  1098.   {
  1099.   }
  1100.  
  1101.   void Tsyntax_editor::set_name( char *_file_name )
  1102.   {
  1103.     Ttext_editor::set_name( _file_name );
  1104.     syntax_type=0;
  1105. #ifdef CPPHILIGHT
  1106.     if( must_hilight(file_name,cpp_hilight_extensions) ) syntax_type=syCPP;
  1107. #endif
  1108. #ifdef ASMHILIGHT
  1109.     if( must_hilight(file_name,asm_hilight_extensions) ) syntax_type=syASM;
  1110. #endif
  1111. #ifdef A51HILIGHT
  1112.     if( must_hilight(file_name,a51_hilight_extensions) ) syntax_type=syA51;
  1113. #endif
  1114.   }
  1115.  
  1116. #ifdef CPPHILIGHT
  1117.   #define RW_NUM (sizeof(rw)/sizeof(*rw))
  1118.   static void syntax_cpp( word *draw_buf, int width )
  1119.   {
  1120.     static char *rw[] = {
  1121.       "asm", "auto", "break", "case", "catch", "char", "class", "const",
  1122.       "continue",  "default", "delete", "do", "double", "else", "enum",
  1123.       "extern", "float", "for", "friend", "goto", "if", "inline", "int",
  1124.       "long", "new", "operator", "private", "protected", "public",
  1125.       "register", "return", "short", "signed", "sizeof", "static", "struct",
  1126.       "switch", "template", "this", "throw", "try", "typedef", "union",
  1127.       "unsigned", "virtual", "void", "volatile", "while"
  1128.     };
  1129.     int len = ++width;
  1130.     word *b;
  1131.     { //initialize the buffer
  1132.       int i=len;
  1133.       for( word *b=draw_buf; --i; hi(*b++) &= 0xF0 );
  1134.     }
  1135.     { //skip ending blank space
  1136.       char c = cpp_syntax_colors[cppWHITE];
  1137.       for( word *b=draw_buf+len-1; lo(*--b)==' '; )
  1138.         if( --len ) hi(*b) |= c; else return;
  1139.     }
  1140.     { //skip leading blank space
  1141.       char c = cpp_syntax_colors[cppWHITE];
  1142.       for( b=draw_buf; lo(*b)==' ' && --len; hi(*b++) |= c );
  1143.     }
  1144.     if( lo(*b)=='#' )
  1145.     { //preprocessor
  1146.       char c = cpp_syntax_colors[cppPREPROCESSOR];
  1147.       while( --len )
  1148.       {
  1149.         if( lo(*b)=='/' )
  1150.           switch( lo(*(b+1)) )
  1151.           {
  1152.             case '*':
  1153.             { /* comment */
  1154.               char c = cpp_syntax_colors[cppCOMMENTS], old=0;
  1155.               ++len;
  1156.               while( --len )
  1157.               {
  1158.                 hi(*b++) |= c;
  1159.                 if( old=='*' && lo(*(b-1))=='/' ) break;
  1160.                 old = lo(*(b-1));
  1161.               }
  1162.               if( !len ) return;
  1163.               continue;
  1164.             }
  1165.             case '/':
  1166.               c = cpp_syntax_colors[cppCOMMENTS];
  1167.           }
  1168.         hi(*b++) |= c;
  1169.       }
  1170.       return;
  1171.     }
  1172.     while( len>1 )
  1173.     { //until the end of the buffer
  1174.       if( lo(*b)=='/' && lo(*(b+1))=='/' )
  1175.       { //comment
  1176.         char c = cpp_syntax_colors[cppCOMMENTS];
  1177.         while( --len ) hi(*b++) |= c;
  1178.         return;
  1179.       }
  1180.       if( lo(*b)=='/' && lo(*(b+1))=='*' )
  1181.       { /* comment */
  1182.         char c = cpp_syntax_colors[cppCOMMENTS], old=0;
  1183.         while( --len )
  1184.         {
  1185.           hi(*b++) |= c;
  1186.           if( old=='*' && lo(*(b-1))=='/' ) break;
  1187.           old = lo(*(b-1));
  1188.         }
  1189.         continue;
  1190.       }
  1191.       if( lo(*b)=='"' || lo(*b)=='\'' )
  1192.       { //string
  1193.         char ch=lo(*b);
  1194.         char c = cpp_syntax_colors[cppSTRINGS];
  1195.         do
  1196.         {
  1197.           if( lo(*b)=='\\' )
  1198.             if( --len ) hi(*b++) |= c; else return;
  1199.           if( --len ) hi(*b++) |= c; else return;
  1200.         } while( lo(*b)!=ch );
  1201.         if( --len ) hi(*b++) |= c; else return;
  1202.         continue;
  1203.       }
  1204.       if( isdigit(lo(*b)) )
  1205.       { //number
  1206.         char c = cpp_syntax_colors[cppNUMBERS];
  1207.         while( (isalnum(lo(*b))||lo(*b)=='.') && --len ) hi(*b++) |= c;
  1208.         continue;
  1209.       }
  1210.       if( __iscsymf(lo(*b)) )
  1211.       { //reserved word or identifier
  1212.         int i=0, l=len;
  1213.         char ch, wrd[MAX_RESERVED_WORD_LENGTH] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
  1214.         for( int n=0; --l && __iscsym(wrd[n]=ch=b[n]); n++ )
  1215.         {
  1216.           for( ; i<RW_NUM && rw[i][n]!=wrd[n]; i++ );
  1217.           if( i==RW_NUM || memcmp(wrd,rw[i],n) ) break;
  1218.         }
  1219.         if( i<RW_NUM && !rw[i][n] )
  1220.         {
  1221.           char c = cpp_syntax_colors[cppRESERVED_WORDS];
  1222.           for( n++; --n && --len; hi(*b++) |= c );
  1223.         }
  1224.         else
  1225.         {
  1226.           char c = cpp_syntax_colors[cppIDENTIFIERS];
  1227.           while( __iscsym(lo(*b)) && --len ) hi(*b++) |= c;
  1228.         }
  1229.         continue;
  1230.       }
  1231.       if( cpp_symbols&lo(*b) )
  1232.         //symbols
  1233.         hi(*b++) |= cpp_syntax_colors[cppSYMBOLS];
  1234.       else
  1235.         //white space
  1236.         hi(*b++) |= cpp_syntax_colors[cppWHITE];
  1237.       --len;
  1238.     }
  1239.   }
  1240.   #undef RW_NUM
  1241. #endif //CPPHILIGHT
  1242.  
  1243. #ifdef ASMHILIGHT
  1244.   #define RW_NUM (sizeof(rw)/sizeof(*rw))
  1245.   static void syntax_asm( word *draw_buf, int width )
  1246.   {
  1247.     static char *rw[] = {
  1248.       "AAA", "AAD", "AAM", "AAS", "ABS", "ADC", "ADD", "AH", "AL", "ALIGN",
  1249.       "ALN", "AND", "ARG", "ARPL", "ASS", "ASSUME", "AT", "AX", "BASIC",
  1250.       "BH", "BL", "BOUND", "BP", "BRK", "BSF", "BSR", "BSS", "BSWAP", "BT",
  1251.       "BTC", "BTR", "BTS", "BX", "BYTE", "CALL", "CALLMETHOD", "CALLPROC",
  1252.       "CATSTR", "CBW", "CDQ", "CH", "CL", "CLC", "CLD", "CLI", "CLTS",
  1253.       "CMC", "CMP", "CMPS", "CMPSB", "CMPSD", "CMPSW", "CMPXCHG", "CODE",
  1254.       "CODEPTR", "CODESEG", "COMM", "COMMENT", "COMMON", "COMPACT", "CONST",
  1255.       "CPP", "CR0", "CR2", "CR3", "CS", "CWD", "CWDE", "CX", "DAA", "DAS",
  1256.       "DATA", "DATAPTR", "DATASEG", "DB", "DD", "DEC", "DF", "DGROUP", "DH",
  1257.       "DI", "DISPLAY", "DIV", "DL", "DOS", "DOSSEG", "DP", "DQ", "DR0",
  1258.       "DR1", "DR2", "DR3", "DR6", "DR7", "DS", "DT", "DUP", "DW", "DWORD",
  1259.       "DX", "EAX", "EBP", "EBX", "ECX", "EDI", "EDX", "ELSE", "ELSEIF",
  1260.       "ELSEIF1", "ELSEIF2", "ELSEIFB", "ELSEIFDEF", "ELSEIFDIF",
  1261.       "ELSEIFDIFI", "ELSEIFE", "ELSEIFIDN", "ELSEIFIDNI", "ELSEIFNB",
  1262.       "ELSEIFNDEF", "EMUL", "END", "ENDIF", "ENDM", "ENDP", "ENDS", "ENTER",
  1263.       "ENTERD", "ENTERW", "ENUM", "EQ", "EQU", "ERR", "ERRIF", "ERRIF1",
  1264.       "ERRIF2", "ERRIFB", "ERRIFDEF", "ERRIFDIF", "ERRIFDIFI", "ERRIFE",
  1265.       "ERRIFIDN", "ERRIFIDNI", "ERRIFNB", "ERRIFNDEF", "ES", "ESC", "ESI",
  1266.       "ESP", "EVEN", "EVENDATA", "EXECONLY", "EXECREAD", "EXIT", "EXITCODE",
  1267.       "EXITM", "EXTRN", "F2XM1", "FABS", "FADD", "FADDP", "FAR", "FARDATA",
  1268.       "FARSTACK", "FAR_BSS", "FAR_DATA", "FASTIMUL", "FBLD", "FBSTP",
  1269.       "FCHS", "FCLEX", "FCOM", "FCOMP", "FCOMPP", "FCOS", "FDECSTP",
  1270.       "FDISI", "FDIV", "FDIVP", "FDIVR", "FDIVRP", "FENI", "FFREE", "FIADD",
  1271.       "FIARQQ", "FICOM", "FICOMP", "FICRQQ", "FIDIV", "FIDIVR", "FIDRQQ",
  1272.       "FIERQQ", "FIFRQQ", "FIGRQQ", "FILD", "FIMUL", "FINCSTP", "FINIT",
  1273.       "FISRQQ", "FIST", "FISTP", "FISUB", "FISUBR", "FIWRQQ", "FJARQQ",
  1274.       "FJCRQQ", "FJFRQQ", "FJGRQQ", "FJSRQQ", "FLAT", "FLD", "FLD1",
  1275.       "FLDCW", "FLDENV", "FLDL2E", "FLDL2T", "FLDLG2", "FLDLN2", "FLDPI",
  1276.       "FLDZ", "FLIPFLAG", "FMUL", "FMULP", "FNCLEX", "FNDISI", "FNENI",
  1277.       "FNINIT", "FNOP", "FNSAVE", "FNSTCW", "FNSTENV", "FNSTSW", "FORTRAN",
  1278.       "FPATAN", "FPREM", "FPREM1", "FPTAN", "FRNDINT", "FRSTOR", "FS",
  1279.       "FSAVE", "FSCALE", "FSETPM", "FSIN", "FSINCOS", "FSQRT", "FST",
  1280.       "FSTCW", "FSTENV", "FSTP", "FSTSW", "FSUB", "FSUBP", "FSUBR",
  1281.       "FSUBRP", "FTST", "FUCOM", "FUCOMP", "FUCOMPP", "FWAIT", "FWORD",
  1282.       "FXAM", "FXCH", "FXTRACT", "FYL2X", "FYL2XP1", "GE", "GETFIELD",
  1283.       "GLOBAL", "GOTO", "GROUP", "GS", "GT", "GTP", "HIGH", "HLT", "HUGE",
  1284.       "ICG", "IDEAL", "IDIV", "IF", "IF1", "IF2", "IFB", "IFDEF", "IFDIF",
  1285.       "IFDIFI", "IFE", "IFIDN", "IFIDNI", "IFNB", "IFNDEF", "IMUL", "IN",
  1286.       "INC", "INCLUDE", "INCLUDELIB", "INS", "INSB", "INSD", "INSTR",
  1287.       "INSW", "INT", "INTO", "INVD", "INVLPG", "IRET", "IRETD", "IRETW",
  1288.       "IRP", "IRPC", "JA", "JAE", "JB", "JBE", "JC", "JCXZ", "JE", "JECXZ",
  1289.       "JG", "JGE", "JL", "JLE", "JMP", "JMPMETHOD", "JNA", "JNAE", "JNB",
  1290.       "JNBE", "JNC", "JNE", "JNG", "JNGE", "JNL", "JNLE", "JNO", "JNP",
  1291.       "JNS", "JNZ", "JO", "JP", "JPE", "JPO", "JS", "JUMPS", "JZ", "LABEL",
  1292.       "LABEL", "LAHF", "LAR", "LARGE", "LARGESTACK", "LCO", "LDS", "LE",
  1293.       "LEA", "LEAVE", "LEAVED", "LEAVEW", "LENGTH", "LES", "LFS", "LGDT",
  1294.       "LGS", "LIDT", "LLDT", "LMSW", "LOCAL", "LOCALS", "LOCK", "LODS",
  1295.       "LODSB", "LODSD", "LODSW", "LOOP", "LOOPD", "LOOPDE", "LOOPDNE",
  1296.       "LOOPDNZ", "LOOPDZ", "LOOPE", "LOOPNE", "LOOPNZ", "LOOPW", "LOOPWE",
  1297.       "LOOPWNE", "LOOPWNZ", "LOOPWZ", "LOOPZ", "LOW", "LSL", "LSS", "LT",
  1298.       "LTR", "M400", "M500", "M510", "M520", "MACRO", "MASK", "MASKFLAG",
  1299.       "MASM", "MASM51", "MCP", "MEDIUM", "MEMORY", "MEMPAGE", "METHOD",
  1300.       "MOD", "MODEL", "MOV", "MOVS", "MOVSB", "MOVSD", "MOVSW", "MOVSX",
  1301.       "MOVZX", "MUL", "MULTERRS", "NAME", "NE", "NEAR", "NEARSTACK", "NEG",
  1302.       "NOEMUL", "NOJUMPS", "NOLANGUAGE", "NOLOCALS", "NOMASM51",
  1303.       "NOMULTERRS", "NOP", "NORMAL", "NOSMART", "NOT", "NOTHING", "NOWARN",
  1304.       "OBJDEF", "OBJEND", "ODDFAR", "ODDNEAR", "OFFSET", "OPI", "OPP",
  1305.       "OPS", "OR", "ORG", "OS2", "OS_DOS", "OS_OS2", "OUT", "OUTS", "OUTSB",
  1306.       "OUTSD", "OUTSW", "OVF", "P186", "P286", "P286N", "P287", "P386",
  1307.       "P386N", "P387", "P486", "P486N", "P487", "P8086", "P8087", "PAGE",
  1308.       "PARA", "PASCAL", "PDC", "PNO87", "POP", "POPA", "POPAD", "POPAW",
  1309.       "POPF", "POPFD", "POPFW", "POPSTATE", "PQK", "PRIVATE", "PRO", "PROC",
  1310.       "PROC", "PROCBEG", "PROCDESC", "PROCEND", "PROCTYPE", "PROLOG", "PTR",
  1311.       "PUBLIC", "PUBLICDLL", "PURGE", "PUSH", "PUSHA", "PUSHAD", "PUSHAW",
  1312.       "PUSHF", "PUSHFD", "PUSHFW", "PUSHSTATE", "PWORD", "QUIRKS", "QWORD",
  1313.       "RADIX", "RCL", "RCR", "READONLY", "READWRITE", "RECORD", "REP",
  1314.       "REPE", "REPNE", "REPNZ", "REPT", "REPZ", "REQ", "RES", "REST", "RET",
  1315.       "RETCODE", "RETF", "RETN", "RETURNS", "ROL", "ROR", "SAHF", "SAL",
  1316.       "SAR", "SBB", "SCAS", "SCASB", "SCASD", "SCASW", "SEG", "SEGCS",
  1317.       "SEGDS", "SEGES", "SEGFS", "SEGGS", "SEGMENT", "SEGSS", "SETA",
  1318.       "SETAE", "SETB", "SETBE", "SETC", "SETE", "SETFIELD", "SETFLAG",
  1319.       "SETG", "SETGE", "SETL", "SETLE", "SETNA", "SETNAE", "SETNB",
  1320.       "SETNBE", "SETNC", "SETNE", "SETNG", "SETNGE", "SETNL", "SETNLE",
  1321.       "SETNO", "SETNP", "SETNS", "SETNZ", "SETO", "SETP", "SETPE", "SETPO",
  1322.       "SETS", "SETZ", "SGDT", "SHL", "SHLD", "SHORT", "SHR", "SHRD", "SI",
  1323.       "SIDT", "SIZE", "SIZESTR", "SLDT", "SMALL", "SMALLSTACK", "SMART",
  1324.       "SMSW", "SP", "SS", "ST", "STACK", "STARTUP", "STARTUPCODE", "STC",
  1325.       "STD", "STDCALL", "STI", "STOS", "STOSB", "STOSD", "STOSW", "STR",
  1326.       "STRUC", "STRUC", "SUB", "SUB", "SUBSTR", "SUBTTL", "SYMTYPE",
  1327.       "SYSCALL", "T100", "T101", "T200", "T250", "T300", "T310", "T320",
  1328.       "TABLE", "TBLINIT", "TBLINST", "TBLPTR", "TBYTE", "TCHUGE", "TEST",
  1329.       "TESTFLAG", "THIS", "TINY", "TITLE", "TPASCAL", "TPI", "TR3", "TR4",
  1330.       "TR5", "TR6", "TR7", "TYPE", "TYPEDEF", "UDATASEG", "UFARDATA", "UNI",
  1331.       "UNINIT", "UNION", "UNKNOWN", "USE16", "USE32", "USES", "VARARG",
  1332.       "VERR", "VERSION", "VERW", "VIRTUAL", "WAIT", "WARN", "WBINVD",
  1333.       "WHILE", "WIDTH", "WINDOWS", "WORD", "XADD", "XCHG", "XLAT", "XLATB",
  1334.       "XOR", "_BSS", "_DATA", "_TEXT"
  1335.     };
  1336.     int len = ++width;
  1337.     word *b;
  1338.     { //initialize the buffer
  1339.       int i=len;
  1340.       for( word *b=draw_buf; --i; hi(*b++) &= 0xF0 );
  1341.     }
  1342.     { //skip ending blank space
  1343.       char c = asm_syntax_colors[asmWHITE];
  1344.       for( word *b=draw_buf+len-1; lo(*--b)==' '; )
  1345.         if( --len ) hi(*b) |= c; else return;
  1346.     }
  1347.     { //skip leading blank space
  1348.       char c = asm_syntax_colors[asmWHITE];
  1349.       for( b=draw_buf; lo(*b)==' ' && --len; hi(*b++) |= c );
  1350.     }
  1351.     while( len>1 )
  1352.     { //until the end of the buffer
  1353.       if( lo(*b)==';' )
  1354.       { //comment
  1355.         char c = asm_syntax_colors[asmCOMMENTS];
  1356.         while( --len ) hi(*b++) |= c;
  1357.         return;
  1358.       }
  1359.       if( lo(*b)=='\'' )
  1360.       { //string
  1361.         char c = asm_syntax_colors[asmSTRINGS];
  1362.         hi(*b++) |= c; if( !--len ) continue;
  1363.         while( lo(*b)!='\'' && --len ) hi(*b++) |= c;
  1364.         if( len ) hi(*b++) |= c;
  1365.         continue;
  1366.       }
  1367.       if( isdigit(lo(*b)) )
  1368.       { //number
  1369.         uint l=len; word *s=b; char c;
  1370.         while( isalnum(lo(*b)) && --len ) c=lo(*b++);
  1371.         switch( toupper(c) )
  1372.         {
  1373.           case 'H': c=asm_syntax_colors[asmHEXADECIMALS]; break;
  1374.           case 'B': c=asm_syntax_colors[asmBINARIES];     break;
  1375.           default:  c=asm_syntax_colors[asmDECIMALS];
  1376.         }
  1377.         for( l-=len-1; --l; hi(*s++)|=c );
  1378.       }
  1379.       if( __iscsymf(lo(*b)) )
  1380.       { //reserved word or identifier
  1381.         int i=0, l=len;
  1382.         char ch, wrd[MAX_RESERVED_WORD_LENGTH] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
  1383.         for( int n=0; --l && __iscsym(wrd[n]=ch=toupper(lo(b[n]))); n++ )
  1384.         {
  1385.           for( ; i<RW_NUM && rw[i][n]!=wrd[n]; i++ );
  1386.           if( i==RW_NUM || memcmp(wrd,rw[i],n) ) break;
  1387.         }
  1388.         if( i<RW_NUM && !rw[i][n] )
  1389.         {
  1390.           char c = asm_syntax_colors[asmRESERVED_WORDS];
  1391.           for( n++; --n && --len; hi(*b++) |= c );
  1392.         }
  1393.         else
  1394.         {
  1395.           char c = asm_syntax_colors[asmIDENTIFIERS];
  1396.           while( __iscsym(lo(*b)) && --len ) hi(*b++) |= c;
  1397.         }
  1398.         continue;
  1399.       }
  1400.       if( asm_symbols&lo(*b) )
  1401.         //symbols
  1402.         hi(*b++) |= asm_syntax_colors[asmSYMBOLS];
  1403.       else
  1404.         //white space
  1405.         hi(*b++) |= asm_syntax_colors[asmWHITE];
  1406.       --len;
  1407.     }
  1408.   }
  1409.   #undef RW_NUM
  1410. #endif //ASMHILIGHT
  1411.  
  1412. #ifdef A51HILIGHT
  1413.   #define RW_NUM (sizeof(rw)/sizeof(*rw))
  1414.   static void syntax_a51( word *draw_buf, int width )
  1415.   {
  1416.     static char *rw[] = {
  1417.       "A", "AB", "ACALL", "ADD", "ADDC", "AJMP", "AND", "ANL", "AR0",
  1418.       "AR1", "AR2", "AR3", "AR4", "AR5", "AR6", "AR7", "AT", "BIT",
  1419.       "BITADDRESSABLE", "BSEG", "C", "CALL", "CJNE", "CLR", "CODE", "CPL",
  1420.       "CSEG", "DA", "DATA", "DB", "DBIT", "DEC", "DIV", "DJNZ", "DPTR",
  1421.       "DS", "DSEG", "DW", "END", "EQ", "EQU", "EXTI0", "EXTI1", "EXTRN",
  1422.       "GE", "GT", "HIGH", "IDATA", "INBLOCK", "INC", "INPAGE", "ISEG", "JB",
  1423.       "JBC", "JC", "JMP", "JNB", "JNC", "JNZ", "JZ", "LCALL", "LE", "LJMP",
  1424.       "LOW", "LT", "MOD", "MOV", "MOVC", "MOVX", "MUL", "NAME", "NE", "NOP",
  1425.       "NOT", "NUMBER", "OR", "ORG", "ORL", "PAGE", "PC", "POP", "PUBLIC",
  1426.       "PUSH", "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "RESET",
  1427.       "RET", "RETI", "RL", "RLC", "RR", "RRC", "RSEG", "SEGMENT", "SET",
  1428.       "SETB", "SHL", "SHR", "SINT", "SJMP", "SUBB", "SWAP", "TIMER0",
  1429.       "TIMER1", "UNIT", "USING", "XCH", "XCHD", "XDATA", "XOR", "XRL",
  1430.       "XSEG"
  1431.     };
  1432.     int len = ++width;
  1433.     word *b;
  1434.     { //initialize the buffer
  1435.       int i=len;
  1436.       for( word *b=draw_buf; --i; hi(*b++) &= 0xF0 );
  1437.     }
  1438.     { //skip ending blank space
  1439.       char c = a51_syntax_colors[a51WHITE];
  1440.       for( word *b=draw_buf+len-1; lo(*--b)==' '; )
  1441.         if( --len ) hi(*b) |= c; else return;
  1442.     }
  1443.     { //skip leading blank space
  1444.       char c = a51_syntax_colors[a51WHITE];
  1445.       for( b=draw_buf; lo(*b)==' ' && --len; hi(*b++) |= c );
  1446.     }
  1447.     while( len>1 )
  1448.     { //until the end of the buffer
  1449.       if( lo(*b)==';' )
  1450.       { //comment
  1451.         char c = a51_syntax_colors[a51COMMENTS];
  1452.         while( --len ) hi(*b++) |= c;
  1453.         return;
  1454.       }
  1455.       if( lo(*b)=='\'' )
  1456.       { //string
  1457.         char c = a51_syntax_colors[a51STRINGS];
  1458.         hi(*b++) |= c; if( !--len ) continue;
  1459.         while( lo(*b)!='\'' && --len ) hi(*b++) |= c;
  1460.         if( len ) hi(*b++) |= c;
  1461.         continue;
  1462.       }
  1463.       if( isdigit(lo(*b)) )
  1464.       { //number
  1465.         uint l=len; word *s=b; char c;
  1466.         while( isalnum(lo(*b)) && --len ) c=lo(*b++);
  1467.         switch( toupper(c) )
  1468.         {
  1469.           case 'H': c=a51_syntax_colors[a51HEXADECIMALS]; break;
  1470.           case 'B': c=a51_syntax_colors[a51BINARIES];     break;
  1471.           default:  c=a51_syntax_colors[a51DECIMALS];
  1472.         }
  1473.         for( l-=len-1; --l; hi(*s++)|=c );
  1474.       }
  1475.       if( __iscsymf(lo(*b)) )
  1476.       { //reserved word or identifier
  1477.         int i=0, l=len;
  1478.         char ch, wrd[MAX_RESERVED_WORD_LENGTH] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
  1479.         for( int n=0; --l && __iscsym(wrd[n]=ch=toupper(lo(b[n]))); n++ )
  1480.         {
  1481.           for( ; i<RW_NUM && rw[i][n]!=wrd[n]; i++ );
  1482.           if( i==RW_NUM || memcmp(wrd,rw[i],n) ) break;
  1483.         }
  1484.         if( i<RW_NUM && !rw[i][n] )
  1485.         {
  1486.           char c = a51_syntax_colors[a51RESERVED_WORDS];
  1487.           for( n++; --n && --len; hi(*b++) |= c );
  1488.         }
  1489.         else
  1490.         {
  1491.           char c = a51_syntax_colors[a51IDENTIFIERS];
  1492.           while( __iscsym(lo(*b)) && --len ) hi(*b++) |= c;
  1493.         }
  1494.         continue;
  1495.       }
  1496.       if( a51_symbols&lo(*b) )
  1497.         //symbols
  1498.         hi(*b++) |= a51_syntax_colors[a51SYMBOLS];
  1499.       else
  1500.         //white space
  1501.         hi(*b++) |= a51_syntax_colors[a51WHITE];
  1502.       --len;
  1503.     }
  1504.   }
  1505.   #undef RW_NUM
  1506. #endif //A51HILIGHT
  1507.  
  1508.   void Tsyntax_editor::format_line( word *draw_buf, uint line_ptr, int width, char normal, char selected )
  1509.   {
  1510.     Ttext_editor::format_line( draw_buf, line_ptr, width, normal, selected );
  1511.     switch( syntax_type )
  1512.     {
  1513. #ifdef CPPHILIGHT
  1514.       case syCPP:
  1515.         syntax_cpp( draw_buf, width );
  1516.         break;
  1517. #endif
  1518. #ifdef ASMHILIGHT
  1519.       case syASM:
  1520.         syntax_asm( draw_buf, width );
  1521.         break;
  1522. #endif
  1523. #ifdef A51HILIGHT
  1524.       case syA51:
  1525.         syntax_a51( draw_buf, width );
  1526.         break;
  1527. #endif
  1528.     }
  1529.   }
  1530.  
  1531. #endif //SYNTAXHILIGHT
  1532.  
  1533.  
  1534. /*
  1535. Teditor
  1536. */
  1537. #define __file_name             text_editor->file_name
  1538. #define __date                  text_editor->date
  1539. #define __time                  text_editor->time
  1540. #define __assoc_number          text_editor->assoc_number
  1541. #define __edit_buffer           text_editor->edit_buffer
  1542. #define __buf_size              text_editor->buf_size
  1543. #define __buf_len               text_editor->buf_len
  1544. #define __gap_len               text_editor->gap_len
  1545. #define __cur_ptr               text_editor->cur_ptr
  1546. #define __sel_start             text_editor->sel_start
  1547. #define __sel_end               text_editor->sel_end
  1548. #define __cur_pos_x             text_editor->cur_pos_x
  1549. #define __cur_pos_y             text_editor->cur_pos_y
  1550. #define __cur_after_eol         text_editor->cur_after_eol
  1551. #define __limit_xl              text_editor->limit_xl
  1552. #define __limit_yl              text_editor->limit_yl
  1553. #define __del_count             text_editor->del_count
  1554. #define __ins_count             text_editor->ins_count
  1555. #define __valid_chars           text_editor->valid_chars
  1556. #define __booleans              text_editor->booleans
  1557.  
  1558. #define __set_buf_size          text_editor->set_buf_size
  1559. #define __set_buf_len           text_editor->set_buf_len
  1560. #define __set_cur_ptr           text_editor->set_cur_ptr
  1561. #define __set_cur_xy            text_editor->set_cur_xy
  1562. #define __set_select            text_editor->set_select
  1563. #define __hide_select           text_editor->hide_select
  1564. #define __has_selection         text_editor->has_selection
  1565. #define __lines_selected        text_editor->lines_selected
  1566. #define __undo                  text_editor->undo
  1567. #define __insert_text           text_editor->insert_text
  1568. #define __insert_string         text_editor->insert_string
  1569. #define __insert_from           text_editor->insert_from
  1570. #define __new_line              text_editor->new_line
  1571. #define __smart_tab             text_editor->smart_tab
  1572. #define __delete_select         text_editor->delete_select
  1573. #define __delete_range          text_editor->delete_range
  1574. #define __clip_copy             text_editor->clip_copy
  1575. #define __clip_cut              text_editor->clip_cut
  1576. #define __clip_paste            text_editor->clip_paste
  1577. #define __get_text              text_editor->get_text
  1578. #define __get_line_str          text_editor->get_line_str
  1579. #define __get_word_str          text_editor->get_word_str
  1580. #define __next_char             text_editor->next_char
  1581. #define __next_line             text_editor->next_line
  1582. #define __next_word             text_editor->next_word
  1583. #define __prev_char             text_editor->prev_char
  1584. #define __prev_line             text_editor->prev_line
  1585. #define __prev_word             text_editor->prev_word
  1586. #define __line_start            text_editor->line_start
  1587. #define __line_end              text_editor->line_end
  1588. #define __line_move             text_editor->line_move
  1589. #define __buf_char              text_editor->buf_char
  1590. #define __buf_ptr               text_editor->buf_ptr
  1591. #define __search                text_editor->search
  1592. #define __format_line           text_editor->format_line
  1593. #define __set_name              text_editor->set_name
  1594. #define __load                  text_editor->load
  1595. #define __save                  text_editor->save
  1596. #define __char_pos              text_editor->char_pos
  1597. #define __char_ptr              text_editor->char_ptr
  1598. #define __insert_buffer         text_editor->insert_buffer
  1599. #define __clear_eol_spaces      text_editor->clear_eol_spaces
  1600. #define __start_select          text_editor->start_select
  1601.  
  1602. //public:
  1603.  
  1604.   Teditor::Teditor( Ttext_editor *_text_editor, int _xl, int _yl ):
  1605.     Titem( _xl, _yl )
  1606.   {
  1607.     int i;
  1608.  
  1609.     text_editor = _text_editor;
  1610.     __assoc_number++;
  1611.     indicator = NULL;
  1612.     cur_ptr_svd   = 0;
  1613.     cur_pos_x_svd = 0;
  1614.     cur_pos_y_svd = 0;
  1615.     draw_ptr      = 0;
  1616.     draw_line     = 0;
  1617.     delta_x       = 0;
  1618.     delta_y       = 0;
  1619.     for( i = 0; i < 10; i++ )
  1620.       marks[i] = (uint) -1;
  1621. #ifndef NOMOUSE
  1622.     set_events_mask( evMOUSE_REP, 1 );
  1623. #endif
  1624.     ~__valid_chars;
  1625.     __valid_chars << 9;
  1626.     for( i = 32; i < 256; i++ )
  1627.       __valid_chars << i;
  1628.     ~word_chars;
  1629.     for( i = '0'; i <= '9'; i++ )
  1630.       word_chars << i;
  1631.     for( i = 'A'; i <= 'Z'; i++ )
  1632.       word_chars << i;
  1633.     for( i = 'a'; i <= 'z'; i++ )
  1634.       word_chars << i;
  1635.     word_chars << '_';
  1636. #ifdef CYR
  1637.     for( i = 'Ç'; i <= 'ƒ'; i++ )
  1638.       word_chars << i;
  1639.     for( i = 'á'; i <= '┐'; i++ )
  1640.       word_chars << i;
  1641. #endif
  1642.   }
  1643.  
  1644.   Teditor::~Teditor( void )
  1645.   {
  1646.     if( --__assoc_number == 0 ) DELETE( text_editor );
  1647.   }
  1648.  
  1649.   boolean Teditor::cursor_visible( void )
  1650.   {
  1651.     return ( __cur_pos_y >= delta_y ) && ( __cur_pos_y < delta_y + yl );
  1652.   }
  1653.  
  1654.   void Teditor::track_cursor( boolean center )
  1655.   {
  1656.     uint cpx;
  1657.  
  1658.     cpx = __cur_pos_x + __cur_after_eol;
  1659.     if( center )
  1660.       scroll_to( cpx - xl, __cur_pos_y - ( yl >> 1 ) );
  1661.     else
  1662.       scroll_to( max( cpx         - xl + 1, min( delta_x, cpx         ) ),
  1663.                  max( __cur_pos_y - yl + 1, min( delta_y, __cur_pos_y ) ) );
  1664.   }
  1665.  
  1666.   void Teditor::scroll_to( int _x, int _y )
  1667.   {
  1668.     _x = max( 0, min( _x, __limit_xl - xl ) );
  1669.     _y = max( 0, min( _y, __limit_yl - yl ) );
  1670.     if( ( _x != delta_x ) || ( _y != delta_y ) )
  1671.     {
  1672.       delta_x = _x;
  1673.       delta_y = _y;
  1674.       if( abs( delta_y - draw_line ) > abs( delta_y - __cur_pos_y ) )
  1675.         draw_ptr = __line_move( __cur_ptr, delta_y - __cur_pos_y );
  1676.       else
  1677.         draw_ptr = __line_move( draw_ptr,  delta_y - draw_line );
  1678.       draw_line = delta_y;
  1679.       __booleans |= ebDIRTY;
  1680.       update( 0, 0, 0 );
  1681.     }
  1682.   }
  1683.  
  1684.   uint Teditor::get_mouse_ptr( int local_x, int local_y )
  1685.   {
  1686.     local_x = max( 0, min( local_x, xl - 1 ) );
  1687.     local_y = max( 0, min( local_y, yl - 1 ) );
  1688.     return __char_ptr( __line_move( draw_ptr, local_y + delta_y - draw_line ),
  1689.              local_x + delta_x );
  1690.   }
  1691.  
  1692.   void Teditor::find( void )
  1693.   {
  1694.     if( editor_dialog( edFIND, NULL ) == cmCANCEL ) return;
  1695.     editor_flags &= ~efDO_REPLACE;
  1696.     do_search_replace();
  1697.   }
  1698.  
  1699.   void Teditor::replace( void )
  1700.   {
  1701.     if( editor_dialog( edREPLACE, NULL ) == cmCANCEL ) return;
  1702.     editor_flags |= efDO_REPLACE;
  1703.     do_search_replace();
  1704.   }
  1705.  
  1706. //protected:
  1707.  
  1708.   void Teditor::get_focused( void )
  1709.   {
  1710.     Titem::get_focused();
  1711.     current_editor = text_editor;
  1712.     if( ( text_editor == clipboard ) ||
  1713.         ( ( __cur_pos_y == cur_pos_y_svd ) &&
  1714.           ( __cur_pos_x + __cur_after_eol == cur_pos_x_svd ) ) )
  1715.       update_commands();
  1716.     else
  1717.     {
  1718.       __set_cur_ptr( cur_ptr_svd, 0 );
  1719.       __set_cur_xy( cur_pos_x_svd, cur_pos_y_svd, 0 );
  1720.     }
  1721.   }
  1722.  
  1723.   boolean Teditor::release_focus( void )
  1724.   {
  1725.     if( !Titem::release_focus() ) return 0;
  1726.     current_editor = NULL;
  1727.     return 1;
  1728.   }
  1729.  
  1730.   void Teditor::calc_bounds( int delta_xl, int delta_yl )
  1731.   {
  1732.     Titem::calc_bounds( delta_xl, delta_yl );
  1733.     if( ( grow_mode & gmGROW_HOR ) &&
  1734.         ( delta_x + xl > __limit_xl ) &&
  1735.         ( __limit_xl > xl ) ) delta_x = ( __limit_xl - xl );
  1736.     if( ( grow_mode & gmGROW_VER ) &&
  1737.         ( delta_y + yl > __limit_yl ) &&
  1738.         ( __limit_yl > yl ) ) delta_y = ( __limit_yl - yl );
  1739.   }
  1740.  
  1741.   void Teditor::draw( void )
  1742.   {
  1743.     int dx, dy, dxl, dyl;
  1744.     uint line_ptr, i, length;
  1745.     word buf[MAX_LINE_LENGTH+MAX_RESERVED_WORD_LENGTH];
  1746.     char normal, selected;
  1747.  
  1748.     curs_type = ( editor_flags & efOVERWRITE )? 2 : 1;
  1749.     curs_x = ( __cur_pos_x + __cur_after_eol ) - delta_x;
  1750.     curs_y = __cur_pos_y - delta_y;
  1751.     get_clip_rect( dx, dy, dxl, dyl );
  1752.     if( state( isDISABLED ) )
  1753.       normal = selected = disabled_attr;
  1754.     else
  1755.     {
  1756.       normal = text_attr;
  1757.       selected = selected_attr;
  1758.     }
  1759.     i = dy + delta_y;
  1760.     if( i >= __limit_yl ) return;
  1761.     draw_ptr = __line_start( __line_move( draw_ptr, i - draw_line ) );
  1762.     draw_line = i;
  1763.     line_ptr = draw_ptr;
  1764.     length = delta_x + xl;
  1765.     for( i = 0; i < dyl; i++, dy++ )
  1766.     {
  1767.       __format_line( buf, line_ptr, length+MAX_RESERVED_WORD_LENGTH, normal, selected );
  1768.       goto_xy( -delta_x, dy );
  1769.       print( buf, length );
  1770.       line_ptr = __next_line( line_ptr );
  1771.     }
  1772.   }
  1773.  
  1774.   void Teditor::event_handler( Tevent &ev )
  1775.   {
  1776.     char select_mode;
  1777.     uint line_num, p, end, s_start, s_end;
  1778.  
  1779.     Titem::event_handler( ev );
  1780.     if( !state( isFOCUSED ) ) return;
  1781.     convert_event( ev );
  1782.     select_mode = 0;
  1783.     if( ( __booleans & ebSELECTING ) || ( get_shifts() & smSHIFT ) ) select_mode = smEXTEND;
  1784.     switch( ev.code )
  1785.     {
  1786. #ifndef NOMOUSE
  1787.       int dx, dy;
  1788.       case evMOUSE_DOWN:
  1789.         if( ev.INSIDE )
  1790.         {
  1791.           if( ev.CLICKS ) select_mode |= smDOUBLE;
  1792.           do
  1793.           {
  1794.             if( ev.code == evMOUSE_REP )
  1795.             {
  1796.               dx = delta_x; dy = delta_y;
  1797.               if( ev.LOCAL_X < 0 ) dx--;
  1798.               if( ev.LOCAL_X >= xl ) dx++;
  1799.               if( ev.LOCAL_Y < 0 ) dy--;
  1800.               if( ev.LOCAL_Y >= yl ) dy++;
  1801.               scroll_to( dx, dy );
  1802.             }
  1803.             __set_cur_ptr( get_mouse_ptr( ev.LOCAL_X, ev.LOCAL_Y ), select_mode );
  1804.             select_mode |= smEXTEND;
  1805.             handled( ev );
  1806.           }
  1807.           while( get_mouse( ev, evMOUSE_DRAG | evMOUSE_REP ) );
  1808.           handled( ev );
  1809.         }
  1810.         break;
  1811. #endif
  1812.       case evKEY_PRESS:
  1813.         if( ev.ASCII < 256 )
  1814.         {
  1815.           if( ev.ASCII >= ' ' ) handled( ev );
  1816.           if( __valid_chars & ev.ASCII )
  1817.           {
  1818.             if( __cur_ptr == __line_end( __cur_ptr ) )
  1819.             {
  1820.               if( ev.ASCII == ' ' )
  1821.               {
  1822.                 __cur_after_eol++;
  1823.                 goto done;
  1824.               }
  1825.             }
  1826.             else
  1827.               if( ( editor_flags & efOVERWRITE ) && !__has_selection() ) __sel_end = __next_char( __cur_ptr );
  1828.             __insert_text( (char *) &ev.ASCII, 1, 0 );
  1829.             item_acted = this;
  1830.             goto done;
  1831.           }
  1832.         }
  1833.         break;
  1834.       case evCOMMAND:
  1835.         switch( ev.CMD_CODE )
  1836.         {
  1837.           case cmeFIND:
  1838.             find();
  1839.             break;
  1840.           case cmeREPLACE:
  1841.             replace();
  1842.             break;
  1843.           case cmeSEARCH_AGAIN:
  1844.             do_search_replace();
  1845.             break;
  1846.           case cmeGOTO_LINE:
  1847.             line_num = editor_dialog( edGOTO_LINE, &__limit_yl );
  1848.             if( line_num )
  1849.               __set_cur_xy( 0, line_num - 1, select_mode );
  1850.             break;
  1851.           case cmCUT:
  1852.             __clip_cut();
  1853.             item_acted = this;
  1854.             break;
  1855.           case cmCOPY:
  1856.             __clip_copy();
  1857.             item_acted = this;
  1858.             break;
  1859.           case cmPASTE:
  1860.             __clip_paste();
  1861.             item_acted = this;
  1862.             break;
  1863.           case cmUNDO:
  1864.             __undo();
  1865.             item_acted = this;
  1866.             break;
  1867.           case cmCLEAR:
  1868.             __delete_select();
  1869.             __clear_eol_spaces();
  1870.             item_acted = this;
  1871.             break;
  1872.           case cmeSCREEN_TOP:
  1873.             __set_cur_xy( __cur_pos_x, delta_y, select_mode );
  1874.             break;
  1875.           case cmeSCREEN_BOTTOM:
  1876.             __set_cur_xy( __cur_pos_x, delta_y + yl - 1, select_mode );
  1877.             break;
  1878.           case cmeSCROLL_UP:
  1879.             scroll_to( delta_x, delta_y - 1 );
  1880.             goto ret;
  1881.           case cmeSCROLL_DOWN:
  1882.             scroll_to( delta_x, delta_y + 1 );
  1883.             goto ret;
  1884.           case cmeCHAR_LEFT:
  1885.             if( __cur_after_eol > 0 )
  1886.               __cur_after_eol--;
  1887.             else
  1888.               if( __cur_ptr > __line_start( __cur_ptr ) )
  1889.                 __set_cur_ptr( __prev_char( __cur_ptr ), select_mode );
  1890.             break;
  1891.           case cmeCHAR_RIGHT:
  1892.             if( __cur_ptr == __line_end( __cur_ptr ) )
  1893.               __cur_after_eol++;
  1894.             else
  1895.               __set_cur_ptr( __next_char( __cur_ptr ), select_mode );
  1896.             break;
  1897.           case cmeWORD_LEFT:
  1898.             __set_cur_ptr( __prev_word( __cur_ptr ), select_mode );
  1899.             break;
  1900.           case cmeWORD_RIGHT:
  1901.             __set_cur_ptr( __next_word( __cur_ptr ), select_mode );
  1902.             break;
  1903.           case cmeLINE_START:
  1904.             __set_cur_ptr( __line_start( __cur_ptr ), select_mode );
  1905.             break;
  1906.           case cmeLINE_END:
  1907.             __set_cur_ptr( __line_end( __cur_ptr ), select_mode );
  1908.             break;
  1909.           case cmeLINE_UP:
  1910.             __set_cur_xy( __cur_pos_x + __cur_after_eol, __cur_pos_y - 1, select_mode );
  1911.             break;
  1912.           case cmeLINE_DOWN:
  1913.             __set_cur_xy( __cur_pos_x + __cur_after_eol, __cur_pos_y + 1, select_mode );
  1914.             break;
  1915.           case cmePAGE_UP:
  1916.             scroll_to( delta_x, delta_y - ( yl - 1 ) );
  1917.             __set_cur_xy( __cur_pos_x + __cur_after_eol, __cur_pos_y - ( yl - 1 ), select_mode );
  1918.             break;
  1919.           case cmePAGE_DOWN:
  1920.             scroll_to( delta_x, delta_y + ( yl - 1 ) );
  1921.             __set_cur_xy( __cur_pos_x + __cur_after_eol, __cur_pos_y + ( yl - 1 ), select_mode );
  1922.             break;
  1923.           case cmeTEXT_START:
  1924.             __set_cur_ptr( 0, select_mode );
  1925.             break;
  1926.           case cmeTEXT_END:
  1927.             __set_cur_ptr( __buf_len, select_mode );
  1928.             break;
  1929.           case cmeTAB:
  1930.             if( editor_flags & efHARD_TABS )
  1931.               __insert_text( "\t", 1, 0 );
  1932.             else
  1933.             {
  1934.               __cur_after_eol = __smart_tab() - __cur_pos_x;
  1935.               if( __cur_ptr < __line_end( __cur_ptr ) ) __insert_text( NULL, 0, 0 );
  1936.             }
  1937.             break;
  1938.           case cmeNEW_LINE:
  1939.             __new_line();
  1940.             item_acted = this;
  1941.             break;
  1942.           case cmeBACK_SPACE:
  1943.             if( __has_selection() )
  1944.             {
  1945.               __delete_select();
  1946.               __clear_eol_spaces();
  1947.             }
  1948.             else
  1949.               if( __cur_after_eol > 0 )
  1950.                 __cur_after_eol--;
  1951.               else
  1952.               {
  1953.                 __delete_range( __prev_char( __cur_ptr ), __cur_ptr, 1 );
  1954.                 __clear_eol_spaces();
  1955.               }
  1956.             item_acted = this;
  1957.             break;
  1958.           case cmeDEL_CHAR:
  1959.             if( __has_selection() )
  1960.               __delete_select();
  1961.             else
  1962.             {
  1963.               __insert_text( NULL, 0, 0 );
  1964.               __delete_range( __cur_ptr, __next_char( __cur_ptr ), 0 );
  1965.             }
  1966.             __clear_eol_spaces();
  1967.             item_acted = this;
  1968.             break;
  1969.           case cmeDEL_WORD:
  1970.             if( __has_selection() )
  1971.               __delete_select();
  1972.             else
  1973.             {
  1974.               if( __cur_ptr == __buf_len ) break;
  1975.               __insert_text( NULL, 0, 0 );
  1976.               p = __next_char( __cur_ptr );
  1977.               while( ( p < __buf_len ) &&
  1978.                      ( __buf_char( p ) & word_chars ) )
  1979.                 p = __next_char( p );
  1980.               while( ( p < __buf_len ) && ( __buf_char( p ) == ' ' ) )
  1981.                 p = __next_char( p );
  1982.               __delete_range( __cur_ptr, p, 0 );
  1983.             }
  1984.             __clear_eol_spaces();
  1985.             item_acted = this;
  1986.             break;
  1987.           case cmeDEL_START:
  1988.             __delete_range( __line_start( __cur_ptr ), __cur_ptr, 0 );
  1989.             item_acted = this;
  1990.             break;
  1991.           case cmeDEL_END:
  1992.             __delete_range( __cur_ptr, __line_end( __cur_ptr ), 0 );
  1993.             __clear_eol_spaces();
  1994.             item_acted = this;
  1995.             break;
  1996.           case cmeDEL_LINE:
  1997.             __delete_range( __line_start( __cur_ptr ), __next_line( __cur_ptr ), 0 );
  1998.             item_acted = this;
  1999.             break;
  2000.           case cmeINS_MODE:
  2001.             editor_flags ^= efOVERWRITE;
  2002.             break;
  2003.           case cmeSTART_SELECT:
  2004.             __start_select();
  2005.             break;
  2006.           case cmeHIDE_SELECT:
  2007.             __hide_select();
  2008.             break;
  2009.           case cmeINDENT_MODE:
  2010.             editor_flags ^= efAUTO_INDENT;
  2011.             break;
  2012.           case cmeINDENT:
  2013.             p = __line_start( __sel_start );
  2014.             end = __line_start( __sel_end );
  2015.             s_start = __sel_start; s_end = end;
  2016.             while( p < end )
  2017.             {
  2018.               if( __buf_char( p ) != '\r' )
  2019.               {
  2020.                 __set_cur_ptr( p, 0 );
  2021.                 __insert_text( " ", 1, 0 );
  2022.                 s_end++;
  2023.                 end++;
  2024.               }
  2025.               p = __next_line( p );
  2026.             }
  2027.             __set_select( s_start, s_end, 1 );
  2028.             break;
  2029.           case cmeUNINDENT:
  2030.             p = __line_start( __sel_start );
  2031.             end = __line_start( __sel_end );
  2032.             s_start = __sel_start; s_end = end;
  2033.             while( p < end )
  2034.             {
  2035.               if( __buf_char( p ) == ' ' )
  2036.               {
  2037.                 __set_cur_ptr( p, 0 );
  2038.                 __delete_range( p, p + 1, 0 );
  2039.                 s_end--;
  2040.                 end--;
  2041.               }
  2042.               p = __next_line( p );
  2043.             }
  2044.             __set_select( s_start, s_end, 1 );
  2045.             break;
  2046.           case cmeMARK0: case cmeMARK1: case cmeMARK2: case cmeMARK3: case cmeMARK4:
  2047.           case cmeMARK5: case cmeMARK6: case cmeMARK7: case cmeMARK8: case cmeMARK9:
  2048.             marks[ev.CMD_CODE - cmeMARK0] = __cur_ptr;
  2049.             break;
  2050.           case cmeGMARK0: case cmeGMARK1: case cmeGMARK2: case cmeGMARK3: case cmeGMARK4:
  2051.           case cmeGMARK5: case cmeGMARK6: case cmeGMARK7: case cmeGMARK8: case cmeGMARK9:
  2052.             if( marks[ev.CMD_CODE - cmeGMARK0] != (uint) -1 )
  2053.               __set_cur_ptr( marks[ev.CMD_CODE - cmeGMARK0], select_mode );
  2054.             track_cursor( !cursor_visible() );
  2055.             break;
  2056.           default:
  2057.             return;
  2058.         }
  2059.       done:
  2060.         track_cursor( 0 );
  2061.       ret:
  2062.         update( 0, 0, 0 );
  2063.         handled( ev );
  2064.     }
  2065.   }
  2066.  
  2067.   void Teditor::convert_event( Tevent &ev )
  2068.   {
  2069.     static int key_state = 0;
  2070.     uint key;
  2071.  
  2072.     if( ev.code == evKEY_PRESS )
  2073.     {
  2074.       key = ev.ASCII;
  2075.       if( key_state )
  2076.       {
  2077.         if( ( lo( key ) >= 0x01 ) && ( lo( key ) <= 0x1A ) ) key += 0x40;
  2078.         if( ( lo( key ) >= 'a' ) && ( lo( key ) <= 'z' ) ) key -= ( 'a' - 'A' );
  2079.       }
  2080.       key = scan_key_map( key_map[ key_state ], key );
  2081.       key_state = 0;
  2082.       if( key )
  2083.         if( key >= 0xFF00 )
  2084.         {
  2085.           key_state = lo( key );
  2086.           handled( ev );
  2087.         }
  2088.         else
  2089.           if( cdisabled( key ) )
  2090.             handled( ev );
  2091.           else
  2092.           {
  2093.             ev.code = evCOMMAND;
  2094.             ev.CMD_CODE = key;
  2095.           }
  2096.     }
  2097.   }
  2098.  
  2099.   void Teditor::update( uint cur_ptr_inserted, int bytes_inserted, int lines_inserted )
  2100.   {
  2101.     uint p;
  2102.  
  2103.     curs_type = ( editor_flags & efOVERWRITE )? 2 : 1;
  2104.     curs_x = ( __cur_pos_x + __cur_after_eol ) - delta_x;
  2105.     curs_y = __cur_pos_y - delta_y;
  2106.     if( owner == NULL ) return;
  2107.     if( state( isFOCUSED ) )
  2108.     {
  2109.       update_commands();
  2110.       cur_pos_x_svd = __cur_pos_x + __cur_after_eol;
  2111.       cur_pos_y_svd = __cur_pos_y;
  2112.       cur_ptr_svd   = __cur_ptr;
  2113.     }
  2114.     if( bytes_inserted != 0 )
  2115.     {
  2116.       if( !state( isFOCUSED ) && ( draw_ptr >= cur_ptr_inserted ) )
  2117.       {
  2118.         draw_ptr      = max( 0, draw_ptr      + bytes_inserted );
  2119.         draw_line     = max( 0, draw_line     + lines_inserted );
  2120.         delta_y       = max( 0, delta_y       + lines_inserted );
  2121.         cur_ptr_svd   = max( 0, cur_ptr_svd   + bytes_inserted );
  2122.         cur_pos_y_svd = max( 0, cur_pos_y_svd + lines_inserted );
  2123.       }
  2124.       for( p = 0; p < 10; p++ )
  2125.         if( ( marks[p] != (uint) -1 ) && ( marks[p] >= cur_ptr_inserted ) )
  2126.           marks[p] = max( cur_ptr_inserted, marks[p] + bytes_inserted );
  2127.     }
  2128.     if( __booleans & ebDIRTY )
  2129.       redraw();
  2130.     else
  2131.       if( indicator != NULL ) indicator->redraw();
  2132.   }
  2133.  
  2134.   void Teditor::update_commands( void )
  2135.   {
  2136.     boolean hs, clp;
  2137.  
  2138.     clp = ( ( clipboard != NULL ) && ( clipboard != text_editor ) );
  2139.     hs = __has_selection();
  2140.     cstate( cmCUT, clp && hs );
  2141.     cstate( cmCOPY, clp && hs );
  2142.     cstate( cmPASTE, clp && clipboard->has_selection() );
  2143.     cstate( cmUNDO, __del_count || __ins_count );
  2144.     cstate( cmCLEAR, hs );
  2145.     cstate( cmeINDENT, hs );
  2146.     cstate( cmeUNINDENT, hs );
  2147.     for( uint i = cmUSER50; i <= cmUSER99; i++ )
  2148.       cenable( i );
  2149.     cenable( cmeFIND );
  2150.     cenable( cmeREPLACE );
  2151.     cenable( cmeSEARCH_AGAIN );
  2152.     cenable( cmeGOTO_LINE );
  2153.     cenable( cmPRINT );
  2154.   }
  2155.  
  2156.   #pragma off( unreferenced )
  2157.   uint Teditor::editor_dialog( int dialog, void *info )
  2158.   {
  2159.     return cmCANCEL;
  2160.   }
  2161.   #pragma on( unreferenced )
  2162.  
  2163.   void Teditor::do_search_replace( void )
  2164.   {
  2165.     uint i;
  2166.     int xx, yy;
  2167.  
  2168.     if( *find_str == 0 ) return;
  2169.     do
  2170.     {
  2171.       i = cmCANCEL;
  2172.       if( !__search( find_str, editor_flags ) )
  2173.       {
  2174.         if( ( editor_flags & ( efREPLACE_ALL + efDO_REPLACE ) ) != ( efREPLACE_ALL + efDO_REPLACE ) )
  2175.           editor_dialog( edSEARCH_FAILED, find_str );
  2176.       }
  2177.       else
  2178.       {
  2179.         track_cursor( !cursor_visible() );
  2180.         if( editor_flags & efDO_REPLACE )
  2181.         {
  2182.           i = cmYES;
  2183.           if( editor_flags & efPROMPT_ON_REPLACE )
  2184.           {
  2185.             xx = (int) ( __cur_pos_x - delta_x );
  2186.             yy = (int) ( __cur_pos_y - delta_y );
  2187.             make_global( xx, yy, xx, yy );
  2188.             i = editor_dialog( edREPLACE_PROMPT, &yy );
  2189.           }
  2190.           if( i == cmYES )
  2191.           {
  2192.             __insert_string( replace_str, 0 );
  2193.             track_cursor( 0 );
  2194.             item_acted = this;
  2195.           }
  2196.         }
  2197.       }
  2198.     }
  2199.     while( ( i != cmCANCEL ) && ( editor_flags & efREPLACE_ALL ) );
  2200.   }
  2201.  
  2202.  
  2203. /*
  2204. Tmemo
  2205. */
  2206.  
  2207. //public:
  2208.  
  2209.   Tmemo::Tmemo( char *_buffer, uint buf_size, int _xl, int _yl ):
  2210.     Teditor( NEW( Ttext_editor( buf_size - 1, this ) ), _xl, _yl )
  2211.   {
  2212.     buffer = _buffer;
  2213.     __booleans &= ~( ebCAN_UNDO | ebCAN_GROW );
  2214.     __insert_string( buffer, 0 );
  2215.     __set_cur_ptr( 0, 0 );
  2216.   }
  2217.  
  2218.   Tmemo *memo( char *title, char *buffer, uint buf_size, int _xl, int _yl )
  2219.   {
  2220.     Tmemo *m;
  2221.     Thscroll_bar *hbar;
  2222.     Tvscroll_bar *vbar;
  2223.     Tbox *b;
  2224.  
  2225.     m = NEW( Tmemo( buffer, buf_size, _xl, _yl ) );
  2226.     vbar = NEW( Tvscroll_bar( m->yl, m->text_editor->limit_yl, m->delta_y ) );
  2227.     vbar->set_flags( sfHIDEABLE+sfHANDLE_KEYBOARD, 0 );
  2228.     vbar->icon_up  ->shortcut = kCTRL_W;
  2229.     vbar->icon_down->shortcut = kCTRL_Z;
  2230.     hbar = NEW( Thscroll_bar( m->xl+1, m->text_editor->limit_xl, m->delta_x ) );
  2231.     hbar->set_flags( sfHIDEABLE+sfHANDLE_KEYBOARD, 0 );
  2232.     hbar->delta = 1;
  2233.     m->put_in( vbar, m->xl, 0 );
  2234.     m->put_in( hbar, -1, m->yl );
  2235.     b = NEW( Tbox( title, m ) );
  2236.     b->resize( b->xl-2, b->yl-1 );
  2237.     m->put_in( b, -1, -1 );
  2238.     hspace(); vspace();
  2239.     put_item( m, b->xl, b->yl-1 );
  2240.     return m;
  2241.   }
  2242.  
  2243. //protected:
  2244.  
  2245.   void Tmemo::ok_item( void )
  2246.   {
  2247.     __get_text( buffer, 0, __buf_len );
  2248.     buffer[__buf_len] = 0;
  2249.   }
  2250.  
  2251.  
  2252. /*
  2253. Tfile_editor
  2254. */
  2255.  
  2256. //public:
  2257.  
  2258.   static Ttext_editor *registrate_editor( Teditor *_this, char *file_name )
  2259.   {
  2260.     if( *file_name )
  2261.     {
  2262.       char fn[_MAX_PATH];
  2263.       fexpand( strcpy( fn, file_name ) );
  2264.       for( Tfile_editor *e=open_editors; e!=NULL; e=e->next_editor )
  2265.         if( !strcmp( e->__file_name, fn ) )
  2266.           return e->text_editor;
  2267.     }
  2268. #ifdef SYNTAXHILIGHT
  2269.     Tsyntax_editor *t = NEW( Tsyntax_editor( 0x1000, _this ) );
  2270. #else
  2271.     Ttext_editor *t = NEW( Ttext_editor( 0x1000, _this ) );
  2272. #endif
  2273.     t->set_name( file_name );
  2274.     return t;
  2275.   }
  2276.  
  2277.   Tfile_editor::Tfile_editor( char *_file_name, int _xl, int _yl ):
  2278.     Teditor( registrate_editor( this, _file_name ), _xl, _yl )
  2279.   {
  2280.     next_editor = open_editors;
  2281.     open_editors = this;
  2282.     if( *_file_name )
  2283.     {
  2284.       get_date_time( _file_name, __date, __time );
  2285.       if( *__file_name && (__assoc_number==1) && state( isVALID ) )
  2286.         set_state( isVALID, __load() );
  2287.     }
  2288.   }
  2289.  
  2290.   Tfile_editor::~Tfile_editor( void )
  2291.   {
  2292.     Tfile_editor *e = open_editors;
  2293.     if( e == this )
  2294.       open_editors = next_editor;
  2295.     else
  2296.     {
  2297.       while( e->next_editor != this )
  2298.         e = e->next_editor;
  2299.       e->next_editor = next_editor;
  2300.     }
  2301.     if( __assoc_number>1 )
  2302.       for( e=open_editors; e!=NULL; e=e->next_editor )
  2303.         if( e->text_editor==text_editor )
  2304.         {
  2305.           text_editor->editor = e;
  2306.           break;
  2307.         }
  2308.   }
  2309.  
  2310.   boolean Tfile_editor::valid( uint command )
  2311.   {
  2312.     int d;
  2313.  
  2314.     if( !Teditor::valid( command ) ) return 0;
  2315.     if( command==cmVALID ) return 1;
  2316.     if( (__booleans&ebMODIFIED) && (__assoc_number==1 || command!=cmDONE) )
  2317.     {
  2318.       if( *__file_name==0 ) d = edSAVE_UNTITLED; else d = edSAVE_MODIFY;
  2319.       switch( editor_dialog( d, __file_name ) )
  2320.       {
  2321.         case cmYES:
  2322.           return save();
  2323.         case cmNO:
  2324.           __booleans &= ~ebMODIFIED;
  2325.           return 1;
  2326.         case cmCANCEL:
  2327.           return 0;
  2328.       }
  2329.     }
  2330.     return 1;
  2331.   }
  2332.  
  2333.   boolean Tfile_editor::save( void )
  2334.   {
  2335.     if( *__file_name==0 ) return save_as();
  2336.     return __save();
  2337.   }
  2338.  
  2339.   boolean Tfile_editor::save_as( void )
  2340.   {
  2341.     char buf[_MAX_PATH];
  2342.     strcpy( buf, __file_name );
  2343.     if( editor_dialog( edSAVE_AS, buf )==cmCANCEL ) return 0;
  2344.     if( strcmp( buf, __file_name ) )
  2345.     {
  2346.       if( __assoc_number>1 )
  2347.       {
  2348.         Ttext_editor *old = text_editor;
  2349.         __assoc_number--;
  2350. #ifdef SYNTAXHILIGHT
  2351.         text_editor = NEW( Tsyntax_editor( old->buf_size, this ) );
  2352. #else
  2353.         text_editor = NEW( Ttext_editor( old->buf_size, this ) );
  2354. #endif
  2355.         __assoc_number++;
  2356.         __insert_text( old->edit_buffer, old->cur_ptr, 0 );
  2357.         __insert_text( old->edit_buffer+old->cur_ptr+old->gap_len, old->buf_len-old->cur_ptr, 0 );
  2358.         __set_cur_ptr( old->cur_ptr, 0 );
  2359.         scroll_to( delta_x, delta_y );
  2360.         if( !old->assoc_number ) DELETE( old );
  2361.       }
  2362.       __set_name( buf );
  2363.       if( owner!=NULL && text_editor!=clipboard )
  2364.       {
  2365.         ((Tedit_window *)owner)->set_title( __file_name );
  2366.         ((Tedit_window *)owner)->vbar->count = &__limit_yl;
  2367.         ((Tedit_window *)owner)->vbar->beg_print = &delta_y;
  2368.         ((Tedit_window *)owner)->hbar->count = &__limit_xl;
  2369.         ((Tedit_window *)owner)->hbar->beg_print = &delta_x;
  2370.       }
  2371.     }
  2372.     boolean result = __save();
  2373.     if( text_editor==clipboard ) __set_name( "" );
  2374.     return result;
  2375.   }
  2376.  
  2377. //protected:
  2378.  
  2379.   void Tfile_editor::event_handler( Tevent &ev )
  2380.   {
  2381.     uint d, t;
  2382.     char s[_MAX_PATH];
  2383.  
  2384.     Teditor::event_handler( ev );
  2385.     if( ev.code == evCOMMAND )
  2386.       switch( ev.CMD_CODE )
  2387.       {
  2388.         case cmSAVE:
  2389.           save();
  2390.           handled( ev );
  2391.           break;
  2392.         case cmSAVE_ALL:
  2393.           if( __booleans & ebMODIFIED ) save();
  2394.           break;
  2395.         case cmSAVE_AS:
  2396.           save_as();
  2397.           handled( ev );
  2398.         case cmSTAMP_CHECK:
  2399.           if( __date && *__file_name )
  2400.           {
  2401.             if( get_date_time(__file_name,d,t) && (__date!=d || __time!=t) )
  2402.             {
  2403.               min_path( strcpy( s, __file_name ) );
  2404.               short_path( s, 30 );
  2405. #ifdef CYR
  2406.               if( ynh( "äá▓á▓á/╖á▒║▓ ¡á ┤á⌐½á \"%s\" ▒á »░«¼Ñ¡Ñ¡¿.\n\näá í║ñÑ ½¿ »░Ѻá░ÑñÑ¡?", s ) )
  2407. #else
  2408.               if( ynh( "Date/time stamp has been changed for file \"%s\".\n\nReload from disk?", s ) )
  2409. #endif
  2410.               {
  2411.                 __load();
  2412.                 redraw();
  2413.                 track_cursor( 0 );
  2414.               }
  2415.               __date = d;
  2416.               __time = t;
  2417.             }
  2418.           }
  2419.       }
  2420.   }
  2421.  
  2422. #ifndef NOHIST
  2423.   static void *_find_history = NULL;
  2424. #endif
  2425.   static uint find_dialog( void )
  2426.   {
  2427. #ifndef NOHELP
  2428.     _help( htD_FIND );
  2429. #endif
  2430. #ifdef CYR
  2431.     dialog( "Æ║░▒Ñ¡Ñ" );
  2432. #else
  2433.     dialog( "Find" );
  2434. #endif
  2435. #ifndef NOHIST
  2436.     if( _find_history ) _history( _find_history ); else _find_history = _history( find_dialog );
  2437. #endif
  2438. #ifdef CYR
  2439.     input( "|~ÆѬ▒▓ ºá ▓║░▒Ñ¡Ñ:", find_str, 80, 20 );
  2440.     check( "|~æ║ó»áñÑ¡¿Ñ ¡á ¼á½¬¿/ú«½Ñ¼¿ í│¬ó¿", editor_flags, efCASE_SENSITIVE );
  2441.     check( "æἫ ╢ѽ¿ |~ñ│¼¿", editor_flags, efWHOLE_WORDS_ONLY );
  2442. #else
  2443.     input( "|~Find what:", find_str, 80, 20 );
  2444.     check( "|~Case sensitive", editor_flags, efCASE_SENSITIVE );
  2445.     check( "|~Whole words only", editor_flags, efWHOLE_WORDS_ONLY );
  2446. #endif
  2447.     if( bkch() && *find_str ) return cmOK;
  2448.     return cmCANCEL;
  2449.   }
  2450.  
  2451.   static uint replace_dialog( void )
  2452.   {
  2453. #ifndef NOHELP
  2454.     _help( htD_REPLACE );
  2455. #endif
  2456. #ifdef CYR
  2457.     dialog( "çá¼┐¡á" );
  2458. #else
  2459.     dialog( "Replace" );
  2460. #endif
  2461. #ifndef NOHIST
  2462.     if( _find_history ) _history( _find_history ); else _find_history = _history( replace_dialog );
  2463. #endif
  2464. #ifdef CYR
  2465.     input( "ÆѬ▒▓ ºá |~▓║░▒Ñ¡Ñ:", find_str, 80, 20 );
  2466. #else
  2467.     input( "|~Find what:   ", find_str, 80, 20 );
  2468. #endif
  2469. #ifndef NOHIST
  2470.     _history( (char *) replace_dialog + 1 );
  2471. #endif
  2472. #ifdef CYR
  2473.     input( "ÆѬ▒▓ ºá |~ºá¼┐¡á: ", replace_str, 80, 20 );
  2474.     check( "|~æ║ó»áñÑ¡¿Ñ ¡á ¼á½¬¿/ú«½Ñ¼¿ í│¬ó¿", editor_flags, efCASE_SENSITIVE );
  2475.     check( "æἫ ╢ѽ¿ |~ñ│¼¿", editor_flags, efWHOLE_WORDS_ONLY );
  2476.     check( "çá¼┐¡á ¡á |~ó▒¿╖¬¿ ▒║ó»áñÑ¡¿┐", editor_flags, efREPLACE_ALL );
  2477.     check( "|~Å«▓ó║░ªñÑ¡¿Ñ »░¿ ºá¼┐¡á", editor_flags, efPROMPT_ON_REPLACE );
  2478. #else
  2479.     input( "|~Replace with:", replace_str, 80, 20 );
  2480.     check( "|~Case sensitive", editor_flags, efCASE_SENSITIVE );
  2481.     check( "|~Whole words only", editor_flags, efWHOLE_WORDS_ONLY );
  2482.     check( "Replace |~all occurences", editor_flags, efREPLACE_ALL );
  2483.     check( "|~Prompt on replace", editor_flags, efPROMPT_ON_REPLACE );
  2484. #endif
  2485.     if( bkch() && *find_str ) return cmOK;
  2486.     return cmCANCEL;
  2487.   }
  2488.  
  2489.   static int goto_dialog( int max_line )
  2490.   {
  2491.     static int line_num = 1;
  2492.  
  2493. #ifndef NOHELP
  2494.     _help( htD_GOTO_LINE_NUMBER );
  2495. #endif
  2496. #ifdef CYR
  2497.     dialog( "Ä▓¿ñ¿ ¡á ░Ññ ¡«¼Ñ░" );
  2498. #else
  2499.     dialog( "Go to line number" );
  2500. #endif
  2501. #ifndef NOHIST
  2502.     _history( goto_dialog );
  2503. #endif
  2504. #ifdef CYR
  2505.     iinput( "é║óÑñÑ▓Ñ ¡«¼Ñ░ ¡á ░Ññ:", line_num, 1, max_line );
  2506. #else
  2507.     iinput( "Enter new line number:", line_num, 1, max_line );
  2508. #endif
  2509.     if( bkch() ) return line_num;
  2510.     return 0;
  2511.   }
  2512.  
  2513.   void Tfile_editor::update_commands( void )
  2514.   {
  2515.     Teditor::update_commands();
  2516.     cenable( cmSAVE );
  2517.     cenable( cmSAVE_AS );
  2518.   }
  2519.  
  2520.   void Tfile_editor::update( uint cur_ptr_inserted, int bytes_inserted, int lines_inserted )
  2521.   {
  2522.     Teditor::update( cur_ptr_inserted, bytes_inserted, lines_inserted );
  2523.     if( editors_supervisor!=NULL && text_editor!=clipboard )
  2524.       editors_supervisor( __file_name, cur_ptr_inserted, bytes_inserted, lines_inserted );
  2525.   }
  2526.  
  2527.   uint Tfile_editor::editor_dialog( int dialog, void *info )
  2528.   {
  2529.     char s[256];
  2530.  
  2531.     if( ( dialog == edREAD_ERROR ) ||
  2532.         ( dialog == edWRITE_ERROR ) ||
  2533.         ( dialog == edCREATE_ERROR ) ||
  2534.         ( dialog == edSAVE_MODIFY ) ||
  2535.         ( dialog == edSAVE_UNTITLED ) )
  2536.     {
  2537.       strcpy( s, (char *) info );
  2538.       min_path( s );
  2539.       short_path( s, 30 );
  2540.     }
  2541.     switch( dialog )
  2542.     {
  2543.       case edOUT_OF_MEMORY:
  2544.         _terror();
  2545. #ifdef CYR
  2546.         ok( "ì┐¼á ñ«▒▓á▓║╖¡« »á¼Ñ▓ ºá ▓ế «»Ñ░á╢¿┐." );
  2547. #else
  2548.         ok( "Not enough memory for this operation." );
  2549. #endif
  2550.         return cmCANCEL;
  2551.       case edREAD_ERROR:
  2552.         _terror();
  2553. #ifdef CYR
  2554.         ok( "ìÑ│▒»Ñ╕¡« »░«╖Ñ▓Ñ¡ ┤á⌐½ %s", s );
  2555. #else
  2556.         ok( "Can't read file %s", s );
  2557. #endif
  2558.         return cmCANCEL;
  2559.       case edWRITE_ERROR:
  2560.         _terror();
  2561. #ifdef CYR
  2562.         ok( "ìÑ│▒»Ñ╕Ñ¡ ºá»¿▒ ¡á ┤á⌐½á %s", s );
  2563. #else
  2564.         ok( "Can't write file %s", s );
  2565. #endif
  2566.         return cmCANCEL;
  2567.       case edCREATE_ERROR:
  2568.         _terror();
  2569. #ifdef CYR
  2570.         ok( "ìÑ│▒»Ñ╕¡« ▒║ºñáóá¡Ñ ¡á ┤á⌐½á %s",s );
  2571. #else
  2572.         ok( "Can't create file %s",s );
  2573. #endif
  2574.         return cmCANCEL;
  2575.       case edSAVE_MODIFY:
  2576.         _tconfirm(); _iwarning();
  2577. #ifdef CYR
  2578.         return ync( "öá⌐½║▓ %s Ñ í¿½ »░«¼Ñ¡Ñ¡.\n\näá í║ñá▓ ½¿ ºá»áºÑ¡¿ »░«¼Ñ¡¿▓Ñ?", s );
  2579. #else
  2580.         return ync( "File %s has been modified.\n\nSave changes?", s );
  2581. #endif
  2582.       case edSAVE_UNTITLED:
  2583.         _tconfirm(); _iwarning();
  2584. #ifdef CYR
  2585.         return ync( "äá í║ñÑ ½¿ ºá»¿▒á¡ íѺ¿¼Ñ¡¡¿┐ ┤á⌐½?" );
  2586. #else
  2587.         return ync( "Do you want to save untitled file?" );
  2588. #endif
  2589.       case edSAVE_AS:
  2590.         _new_file();
  2591.         if( filter_str != NULL ) _filters( filter_str );
  2592. #ifdef CYR
  2593.         return get_file( "çỿ▒ ¬á▓«", (char *) info );
  2594. #else
  2595.         return get_file( "Save file as", (char *) info );
  2596. #endif
  2597.       case edFIND:
  2598.         __get_word_str( find_str, 80 );
  2599.         return find_dialog();
  2600.       case edSEARCH_FAILED:
  2601. #ifdef CYR
  2602.         ok( "ÆѬ▒▓║▓ \"%s\" ¡Ñ íÑ╕Ñ ¡á¼Ñ░Ñ¡.", info );
  2603. #else
  2604.         ok( "String \"%s\" not found.", info );
  2605. #endif
  2606.         return cmCANCEL;
  2607.       case edREPLACE:
  2608.         __get_word_str( find_str, 80 );
  2609.         return replace_dialog();
  2610.       case edREPLACE_PROMPT:
  2611.         _pstandard(); _iquestion();
  2612.         if( *( (int *) info ) > desktop_y + ( desktop_yl>>1 ) )
  2613.           _dialog_xy( xCENTER, ( desktop_yl>>2 ) - 4 );
  2614.         else
  2615.           _dialog_xy( xCENTER, desktop_yl - ( desktop_yl>>2 ) - 5 );
  2616. #ifdef CYR
  2617.         return ync( "äá í║ñÑ ½¿ ºá¼Ñ¡Ñ¡« ▓«óá ▒║ó»áñÑ¡¿Ñ?" );
  2618. #else
  2619.         return ync( "Replace this occurence?" );
  2620. #endif
  2621.       case edGOTO_LINE:
  2622.         return goto_dialog( *( (uint *) info ) );
  2623.     }
  2624.     return cmCANCEL;
  2625.   }
  2626.  
  2627.  
  2628. /*
  2629. Tindicator
  2630. */
  2631.  
  2632. //public:
  2633.  
  2634.   class Tindicator: public Titem
  2635.   {
  2636.     public:
  2637.       Tindicator( void );
  2638.  
  2639.     protected:
  2640.       virtual void draw( void );
  2641.   };
  2642.  
  2643.   Tindicator::Tindicator( void ):
  2644.     Titem( 1, 1 )
  2645.   {
  2646.     char s[256];
  2647.  
  2648.     set_flags( ifSELECTABLE, 0 );
  2649.     ltoa( MAX_LINE_LENGTH, s, 10 );
  2650.     resize( 9 + strlen( s ), 1 );
  2651.     set_events_mask( ~evCOMMAND, 0 );
  2652.     drag_mode = dmDRAG_VER;
  2653.   }
  2654.  
  2655. //protected:
  2656.  
  2657.   void Tindicator::draw( void )
  2658.   {
  2659.     char c, m;
  2660.     Teditor *editor;
  2661.  
  2662.     editor = (Teditor *) owner;
  2663.     if( editor->__booleans & ebMODIFIED ) m = '*'; else m = ' ';
  2664.     if( owner->state( isACTIVE ) ) c = '1'; else c = '0';
  2665.     txtf( "|%c|i %c%5u:%u      ", c, m, editor->cur_pos_y_svd + 1, editor->cur_pos_x_svd + 1 );
  2666.   }
  2667.  
  2668.  
  2669. /*
  2670. Tedit_window
  2671. */
  2672.   static Tindicator *indicator;
  2673.  
  2674.   Tedit_window::Tedit_window( char *fn, int _xl, int _yl ):
  2675.     Tfile_window( editor->delta_x, editor->__limit_xl,
  2676.                   editor->delta_y, editor->__limit_yl,
  2677.                   ( indicator = NEW( Tindicator ), indicator->xl ),
  2678.                   fn, editor = NEW( Tfile_editor( fn, _xl-i_sb_up_len-1, _yl-2 ) ) )
  2679.   {
  2680.     if( *editor->__file_name==0 )
  2681. #ifdef CYR
  2682.       set_title( "[üàç êîà]" );
  2683. #else
  2684.       set_title( "[Untitled]" );
  2685. #endif
  2686.     editor->grow_mode = gmGROW_BOTH;
  2687.     editor->put_in( indicator, -1, editor->yl );
  2688.     editor->indicator = indicator;
  2689.     hbar->set_flags( sfHANDLE_KEYBOARD, 0 );
  2690.     vbar->set_flags( sfHANDLE_KEYBOARD, 0 );
  2691.   }
  2692.  
  2693.   Tedit_window::~Tedit_window( void )
  2694.   {
  2695.     _command_info( this, 0 );
  2696.     broadcast( cmeEDITOR_CLOSE );
  2697.   }
  2698.  
  2699.   void Tedit_window::save_status( Tedit_window_status &st )
  2700.   {
  2701.     if( state( isICONIZED ) )
  2702.     {
  2703.       st.icon_x = x;
  2704.       st.icon_y = y;
  2705.     }
  2706.     else
  2707.     {
  2708.       st.icon_x = icon_x;
  2709.       st.icon_y = icon_y;
  2710.     }
  2711.     if( state( isICONIZED|wsMAXIMIZED ) )
  2712.     {
  2713.       st.x  = x_saved;
  2714.       st.y  = y_saved;
  2715.       st.xl = xl_saved;
  2716.       st.yl = yl_saved;
  2717.     }
  2718.     else
  2719.     {
  2720.       st.x  = x;
  2721.       st.y  = y;
  2722.       st.xl = xl;
  2723.       st.yl = yl;
  2724.     }
  2725.     st.state = state_word;
  2726.     st.cur_pos_y = editor->__cur_pos_y;
  2727.     st.cur_pos_x = editor->__cur_pos_x + editor->__cur_after_eol;
  2728.     st.delta_x = editor->delta_x;
  2729.     st.delta_y = editor->delta_y;
  2730.     for( int i = 0; i < 10; i++ )
  2731.       st.marks[i] = editor->marks[i];
  2732.     strcpy( st.file_name, editor->__file_name );
  2733.   }
  2734.  
  2735.   void Tedit_window::restore_status( Tedit_window_status &st )
  2736.   {
  2737.     set_state( st.state, 0 );
  2738.     drag( st.x, st.y );
  2739.     resize( st.xl, st.yl );
  2740.     icon_x = st.icon_x;
  2741.     icon_y = st.icon_y;
  2742.     set_state( st.state, 1 );
  2743.     editor->scroll_to( st.delta_x, st.delta_y );
  2744.     editor->__set_cur_xy( st.cur_pos_x, st.cur_pos_y, 0 );
  2745.     for( int i = 0; i < 10; i++ )
  2746.       editor->marks[i] = st.marks[i];
  2747.     editor->cur_ptr_svd   = editor->__cur_ptr;
  2748.     editor->cur_pos_x_svd = editor->__cur_pos_x;
  2749.     editor->cur_pos_y_svd = editor->__cur_pos_y;
  2750.   }
  2751.  
  2752.   Tedit_window *edit_file( char *fn )
  2753.   {
  2754.     Tfile_editor *f;
  2755.     char buf[_MAX_PATH];
  2756.  
  2757.     fexpand( strcpy( buf, fn ) );
  2758.     f = open_editors;
  2759.     while( f != NULL )
  2760.     {
  2761.       if( !strcmp(buf,f->__file_name) )
  2762.       {
  2763. #ifndef NOHELP
  2764.         __help();
  2765. #endif
  2766.         f->owner->focus();
  2767.         f->owner->set_state( isICONIZED, 0 );
  2768.         return (Tedit_window *) f->owner;
  2769.       }
  2770.       f = f->next_editor;
  2771.     }
  2772.     return open_file( fn );
  2773.   }
  2774.  
  2775.   Tedit_window *open_file( char *fn )
  2776.   {
  2777.     Tedit_window *ew;
  2778.  
  2779.     _context( cxEDITOR );
  2780.     ew = NEW( Tedit_window( fn, desktop->xl, desktop->yl ) );
  2781.     if( !is_valid( ew ) ) return NULL;
  2782.     insert_window( ew, 0, 0 );
  2783.     return ew;
  2784.   }
  2785.  
  2786.   Tedit_window *open_file( Tedit_window_status &st )
  2787.   {
  2788.     Tedit_window *ew=open_file( st.file_name );
  2789.     if( ew != NULL ) ew->restore_status( st );
  2790.     return ew;
  2791.   }
  2792.  
  2793. //protected:
  2794.  
  2795.   void Tedit_window::initialize( void )
  2796.   {
  2797.     Tfile_window::initialize();
  2798.     _command_info( this, 0 );
  2799.     broadcast( cmeEDITOR_OPEN );
  2800.   }
  2801.  
  2802.  
  2803. /*
  2804. Tclipboard_window
  2805. */
  2806.   class Tclipboard_window: public Tscroll_window
  2807.   {
  2808.     public:
  2809.       Tclipboard_window( void );
  2810.       virtual void set_state( uint _state_word, char enable );
  2811.       virtual boolean valid( uint command );
  2812.   };
  2813.  
  2814.   Tclipboard_window *clipboard_window;
  2815.   static Tfile_editor *tmp_clipboard;
  2816.  
  2817.   Tclipboard_window::Tclipboard_window( void ):
  2818.     Tscroll_window( tmp_clipboard->delta_x, tmp_clipboard->__limit_xl,
  2819.                     tmp_clipboard->delta_y, tmp_clipboard->__limit_yl,
  2820.                     ( indicator = NEW( Tindicator ), indicator->xl - 1 ),
  2821.                     "Clipboard",
  2822.                     tmp_clipboard = NEW( Tfile_editor( "", desktop->xl-i_sb_up_len-1, desktop->yl-2 ) ) )
  2823.   {
  2824.     clipboard = tmp_clipboard->text_editor;
  2825.     set_state( isHIDDEN, 1 );
  2826.     commands<<cmSAVE_AS;
  2827.     clipboard->booleans &= ~ebCAN_UNDO;
  2828.     tmp_clipboard->grow_mode = gmGROW_BOTH;
  2829.     tmp_clipboard->put_in( indicator, -1, tmp_clipboard->yl );
  2830.     tmp_clipboard->indicator = indicator;
  2831.     hbar->set_flags( sfHANDLE_KEYBOARD, 0 );
  2832.     vbar->set_flags( sfHANDLE_KEYBOARD, 0 );
  2833.   }
  2834.  
  2835.   void Tclipboard_window::set_state( uint _state_word, char enable )
  2836.   {
  2837.     Tscroll_window::set_state( _state_word, enable );
  2838.     if( _state_word & isHIDDEN )
  2839.       if( enable )
  2840.       {
  2841.         if( state( isSELECTED ) ) owner->tab_next( -1 );
  2842.         if( state( isSELECTED ) ) set_state( isSELECTED, 0 );
  2843.       }
  2844.       else
  2845.         focus();
  2846.   }
  2847.  
  2848.   boolean Tclipboard_window::valid( uint command )
  2849.   {
  2850.     if( command == cmDONE )
  2851.     {
  2852.       set_state( isHIDDEN, 1 );
  2853.       return 0;
  2854.     }
  2855.     return Tscroll_window::valid( command );
  2856.   }
  2857.  
  2858.   void show_clipboard( void )
  2859.   {
  2860.     if( clipboard_window != NULL )
  2861.     {
  2862.       clipboard_window->set_state( isHIDDEN, 0 );
  2863.       clipboard_window->set_state( isICONIZED, 0 );
  2864.     }
  2865.   }
  2866.  
  2867.  
  2868. void __init_editors( void )
  2869. {
  2870.   int i;
  2871.  
  2872.   *find_str = 0;
  2873.   *replace_str = 0;
  2874.   ~word_chars;
  2875.   for( i = '0'; i <= '9'; i++ )
  2876.     word_chars << i;
  2877.   for( i = 'A'; i <= 'Z'; i++ )
  2878.     word_chars << i;
  2879.   for( i = 'a'; i <= 'z'; i++ )
  2880.     word_chars << i;
  2881.   word_chars << '_';
  2882. #ifdef CYR
  2883.   for( i = 'Ç'; i <= 'ƒ'; i++ )
  2884.     word_chars << i;
  2885.   for( i = 'á'; i <= '┐'; i++ )
  2886.     word_chars << i;
  2887. #endif
  2888. #ifdef SYNTAXHILIGHT
  2889.     if( scr_bw )
  2890.     {
  2891. #ifdef CPPHILIGHT
  2892.       static char bw_cpp_colors[16] = { 7,7,15,7,15,7,7,7 };
  2893.       memcpy( cpp_syntax_colors, bw_cpp_colors, sizeof(cpp_syntax_colors) );
  2894. #endif
  2895. #ifdef ASMHILIGHT
  2896.       static char bw_asm_colors[16] = { 7,7,15,7,15,7,7,7,7 };
  2897.       memcpy( asm_syntax_colors, bw_asm_colors, sizeof(asm_syntax_colors) );
  2898. #endif
  2899. #ifdef A51HILIGHT
  2900.       static char bw_a51_colors[16] = { 7,7,15,7,15,7,7,7,7 };
  2901.       memcpy( a51_syntax_colors, bw_a51_colors, sizeof(a51_syntax_colors) );
  2902. #endif
  2903.     }
  2904. #endif
  2905. #ifdef CPPHILIGHT
  2906.   ~cpp_symbols;
  2907.   cpp_symbols << '{' << '}' << '[' << ']' << '(' << ')' << ';' << ','
  2908.               << '.' << '<' << '>' << '=' << '&' << '|' << '^' << '~'
  2909.               << '!' << '+' << '-' << '*' << '/' << '?' << ':' << '%';
  2910. #endif
  2911. #ifdef ASMHILIGHT
  2912.   ~asm_symbols;
  2913.   asm_symbols << '[' << ']' << '{' << '|' << '}' << '$' << '%' << '('
  2914.               << ')' << '*' << '+' << ',' << '-' << '.' << '/' << ':'
  2915.               << '<' << '=' << '>' << '?' << '@';
  2916. #endif
  2917. #ifdef A51HILIGHT
  2918.   ~a51_symbols;
  2919.   a51_symbols << '[' << ']' << '{' << '|' << '}' << '$' << '%' << '('
  2920.               << ')' << '*' << '+' << ',' << '-' << '.' << '/' << ':'
  2921.               << '<' << '=' << '>' << '?' << '@' << '#';
  2922. #endif
  2923.   _context( cxEDITOR );
  2924.   clipboard_window = NEW( Tclipboard_window );
  2925.   desktop->put_in( clipboard_window, 0, 0 );
  2926. }
  2927.