home *** CD-ROM | disk | FTP | other *** search
/ M.u.C.S. Disc 2000 / MUCS2000.iso / anwend / qed453 / src / edit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-03  |  54.2 KB  |  2,420 lines

  1. #include <support.h>
  2. #include <time.h>
  3.  
  4. #include "global.h"
  5. #include "ausgabe.h"
  6. #include "av.h"
  7. #include "block.h"
  8. #include "clipbrd.h"
  9. #include "comm.h"
  10. #include "dd.h"
  11. #include "event.h"
  12. #include "error.h"
  13. #include "file.h"
  14. #include "find.h"
  15. #include "icon.h"
  16. #include "kurzel.h"
  17. #include "makro.h"
  18. #include "memory.h"
  19. #include "menu.h"
  20. #include "olga.h"
  21. #include "options.h"
  22. #include "poslist.h"
  23. #include "printer.h"
  24. #include "projekt.h"
  25. #include "rsc.h"
  26. #include "set.h"
  27. #include "sort.h"
  28. #include "tasten.h"
  29. #include "text.h"
  30. #include "umbruch.h"
  31. #include "window.h"
  32. #include "edit.h"
  33.  
  34. /* Exportierte Variablen ***************************************************/
  35. int    edit_type;
  36.  
  37. /****** DEFINES ************************************************************/
  38.  
  39. #define KIND    (NAME|INFO|CLOSER|FULLER|MOVER|SIZER|UPARROW|DNARROW|VSLIDE|LFARROW|RTARROW|HSLIDE|SMALLER)
  40. #define FLAGS    (WI_TEXT|WI_FONTSIZE|WI_REDRAW)
  41.  
  42. /* Anzahl der Änderungen in allen Texten bis zum restore_edit */
  43. #define MAX_CHG 30
  44.  
  45. #define TEMP_LINK 101
  46.  
  47. /****** TYPES **************************************************************/
  48.  
  49. typedef struct
  50. {
  51.     int    link;         /* Nummer von Text und Window */
  52.     int    c;         /* Art der Änderung */
  53.     long    y;         /* y-Position */
  54. } TCHANGE;
  55.  
  56. /* lokale Variablen ********************************************************/
  57. static SET            used_info;
  58. static int            chg_anz, find_erg, ascii_wert;
  59. static TCHANGE     chg[MAX_CHG];
  60. static SET            chg_links;
  61. static POSENTRY    *lastpos_list = NULL;
  62.  
  63. /* lokale Prototypen *******************************************************/
  64.  
  65. static void     e_icon_exist    (int icon, SET actions);
  66. static bool     e_icon_test        (int icon, int action);
  67. static int        e_icon_edit        (int icon, int action);
  68. static bool     e_icon_drag        (int icon, int source);
  69. static void     wi_draw            (WINDOWP window, GRECT *d);
  70. static void     wi_click         (WINDOWP window, int m_x, int m_y, int bstate, int kstate, int breturn);
  71. static bool     wi_key            (WINDOWP window, int kstate, int kreturn);
  72. static void     wi_top            (WINDOWP window);
  73. static void        wi_iconify        (WINDOWP window);
  74. static void        wi_uniconify    (WINDOWP window);
  75. static void     destruct         (int icon);
  76.  
  77. static void     lz2tab            (TEXTP t_ptr);
  78. static void     tab2lz            (TEXTP t_ptr);
  79. static void     goto_line        (TEXTP t_ptr, int x, long y);
  80. static void     make_undo        (TEXTP t_ptr);
  81. static void     print_edit        (TEXTP t_ptr);
  82. static bool     open_edit        (int icon);
  83. static void     crt_edit         (WINDOWP window);
  84. static int      crt_new_text    (char *filename, bool bin);
  85.  
  86. /***************************************************************************/
  87.  
  88. static int col_lz2tab(ZEILEP col, char *t, int tab_size)
  89. {
  90.     char    *str, c;
  91.     int    i, tabH, lz, len;
  92.     bool    changes;
  93.  
  94.     str = TEXT(col);
  95.     changes = FALSE;
  96.     tabH = tab_size;
  97.     lz = 0;
  98.     len = 0;
  99.     for (i=col->len; (--i)>=0; )
  100.     {
  101.         c = *str++;
  102.         if (c==' ')
  103.         {
  104.             if ((--tabH)==0)
  105.             {
  106.                 if (lz>0)            /* Leerzeichen ersetzen */
  107.                 {
  108.                     c = '\t';
  109.                     t -= lz;
  110.                     len -= lz;
  111.                     changes = TRUE;
  112.                 }
  113.                 tabH = tab_size;
  114.                 lz = 0;
  115.             }
  116.             else
  117.                 lz++;
  118.         }
  119.         else
  120.         {
  121.             lz = 0;
  122.             if ((--tabH)==0) tabH = tab_size;
  123.         }
  124.         *t++ = c;
  125.         len++;
  126.     }
  127.     *t = EOS;
  128.     if (changes)
  129.         return (len);
  130.     return (-1);
  131. }
  132.  
  133. static void lz2tab(TEXTP t_ptr)
  134. {
  135.     ZEILEP     lauf;
  136.     int        x, i, tabsize;
  137.     char        str[MAX_LINE_LEN + 1];
  138.  
  139.     graf_mouse(HOURGLASS, NULL);
  140.     tabsize = t_ptr->loc_opt->tabsize;
  141.     x = bild_pos(t_ptr->xpos,t_ptr->cursor_line,TRUE,tabsize);
  142.     lauf = FIRST(&t_ptr->text);
  143.     while (!IS_TAIL(lauf))
  144.     {
  145.         i = col_lz2tab(lauf, str, tabsize);
  146.         if (i != -1)                                    /* Zeile verändert */
  147.         {
  148.             REALLOC (&lauf, 0, i-lauf->len);
  149.             memcpy(TEXT(lauf), str, (int) strlen(str));
  150.             t_ptr->moved++;
  151.         }
  152.         NEXT(lauf);
  153.     }
  154.     t_ptr->cursor_line = get_line(&t_ptr->text,t_ptr->ypos);
  155.     t_ptr->xpos = inter_pos(x,t_ptr->cursor_line,TRUE,tabsize);
  156.     make_chg(t_ptr->link,POS_CHANGE,0);     /* immer: Damit Infozeile einen '*' bekommt */
  157.     restore_edit();
  158.     graf_mouse(ARROW, NULL);
  159. }
  160.  
  161. static int col_tab2lz(ZEILEP col, char *t, int tab_size)
  162. {
  163.     bool    with_tab = FALSE;
  164.     int    tabH, len, i;
  165.     char    *str, c;
  166.  
  167.     str = TEXT(col);
  168.     tabH = tab_size;
  169.     for (i = col->len,len = 0; (--i) >= 0 && (len < (MAX_LINE_LEN+1)); )
  170.     {
  171.         c = *str++;
  172.         if (c == '\t')
  173.         {
  174.             with_tab = TRUE;
  175.             len += tabH;
  176.             if (len > (MAX_LINE_LEN+1))
  177.                 tabH -= (len - (MAX_LINE_LEN+1));
  178.             do
  179.             {
  180.                 *t++ = ' ';
  181.             }
  182.             while (--tabH);
  183.             tabH = tab_size;
  184.         }
  185.         else
  186.         {
  187.             *t++ = c;
  188.             if ((--tabH)==0)
  189.                 tabH = tab_size;
  190.             len++;
  191.         }
  192.     }
  193.     *t = EOS;
  194.     if (with_tab)
  195.         return(len);
  196.     else
  197.         return(-1);
  198. }
  199.  
  200. static void tab2lz(TEXTP t_ptr)
  201. {
  202.     ZEILEP     lauf;
  203.     int        i, x, tabsize;
  204.     char        str[MAX_LINE_LEN + 1];
  205.  
  206.     graf_mouse(HOURGLASS, NULL);
  207.     tabsize = t_ptr->loc_opt->tabsize;
  208.     x = bild_pos(t_ptr->xpos,t_ptr->cursor_line,TRUE,tabsize);
  209.     lauf = FIRST(&t_ptr->text);
  210.     while (!IS_TAIL(lauf))
  211.     {
  212.         i = col_tab2lz (lauf,str,tabsize);
  213.         if (i != -1)                                    /* Zeile verändert */
  214.         {
  215.             REALLOC (&lauf, 0, i-lauf->len);
  216.             memcpy(TEXT(lauf), str, (int)strlen(str));
  217.             t_ptr->moved++;
  218.         }
  219.         NEXT(lauf);
  220.     }
  221.     t_ptr->cursor_line = get_line(&t_ptr->text,t_ptr->ypos);
  222.     t_ptr->xpos = inter_pos(x,t_ptr->cursor_line,TRUE,tabsize);
  223.     make_chg(t_ptr->link,POS_CHANGE,0);     /* immer: Damit Infozeile einen '*' bekommt */
  224.     restore_edit();
  225.     graf_mouse(ARROW, NULL);
  226. }
  227.  
  228. static void goto_line(TEXTP t_ptr, int x, long y)
  229. {
  230.     if (x < 0)
  231.         x = 0;
  232.     if (y < 0)
  233.         y = 0;
  234.     if (y >= t_ptr->text.lines)
  235.         y = t_ptr->text.lines - 1L;
  236.     t_ptr->cursor_line = get_line(&t_ptr->text, y);
  237.     t_ptr->ypos = y;
  238.     t_ptr->xpos = inter_pos(x,t_ptr->cursor_line,t_ptr->loc_opt->tab,t_ptr->loc_opt->tabsize);
  239.     make_chg(t_ptr->link,POS_CHANGE, 0);
  240. }
  241.  
  242. static void make_undo(TEXTP t_ptr)
  243. {
  244.     int undo;
  245.  
  246.     undo = get_undo();
  247.     if (undo == NO_UNDO) 
  248.         return;
  249.  
  250.     /*
  251.      * Vorher an undo_pos springen
  252.      * Weil sonst u.U. restore zu schwierig
  253.      * Wird auch von do_undo_col vorausgesetzt
  254.     */
  255.     t_ptr->cursor_line = get_line(&t_ptr->text,undo_y);
  256.     t_ptr->ypos = undo_y;
  257.     t_ptr->xpos = 0;
  258.     make_chg(t_ptr->link,POS_CHANGE,0);
  259.     restore_edit();
  260.  
  261.     do
  262.     {
  263.         if (undo == COL_ANDERS)
  264.         {
  265.             do_undo_col(t_ptr,undo);
  266.             restore_edit();
  267.         }
  268.         else
  269.         {
  270.             blk_undo(t_ptr,undo);
  271.             restore_edit();
  272.         }
  273.         undo = get_undo();
  274.     }
  275.     while (undo != NO_UNDO);
  276. }
  277.  
  278. /***************************************************************************/
  279.  
  280. static void do_absatz(WINDOWP window)
  281. {
  282.     if (window->flags & WI_TEXT)                     /* Text-Fenster */
  283.     {
  284.         TEXTP    t_ptr = get_text(window->handle);
  285.         
  286.         make_absatz(t_ptr);
  287.         get_longestline(t_ptr);
  288.         if (window->doc.w != t_ptr->max_line->exp_len)
  289.         {
  290.             window->doc.w = t_ptr->max_line->exp_len;
  291.             set_sliders(window, HORIZONTAL, SLPOS+SLSIZE);
  292.         }    
  293.         redraw_window(window, &window->work);
  294.     }
  295. }
  296.  
  297.  
  298. /*
  299.  * Es wurde Zeilenumbruch ein oder ausgeschaltet und/oder Tab geändert 
  300. */
  301. void absatz_edit(void)
  302. {
  303.     do_all_window(CLASS_EDIT, do_absatz);
  304. }
  305.  
  306.  
  307. /***************************************************************************/
  308.  
  309. static void chg_edit_name(int icon)
  310. {
  311.     WINDOWP    window = get_window(icon);
  312.     TEXTP     t_ptr = get_text(icon);
  313.  
  314.     set_wtitle(window, t_ptr->filename);
  315. }
  316.  
  317. /***************************************************************************/
  318. /* Anlegen einer neuen Textdatei                                                         */
  319. /***************************************************************************/
  320.  
  321. int new_edit(void)
  322. {
  323.     int    icon;
  324.     TEXTP t_ptr;
  325.  
  326.     icon = crt_new_text("", FALSE);
  327.     if (icon < 0)
  328.     {
  329.         note(1, 0, NOTEXT);
  330.         return -1;
  331.     }
  332.     t_ptr = get_text(icon);
  333.     if (t_ptr->loc_opt->umbrechen)
  334.         make_absatz(t_ptr);
  335.     if (do_icon(icon,DO_OPEN) < 0)
  336.     {
  337.         note(1, 0, NOWINDOW);
  338.         icon_edit(icon, DO_DELETE);
  339.         icon = -3;
  340.     }
  341.     return icon;
  342. } /* new_edit */
  343.  
  344. /***************************************************************************/
  345.  
  346. int load_edit(char *name, bool bin)
  347. /* return: <=0 wurde nicht geladen */
  348. /*           =0    weitere Texte versuchen sinnvoll */
  349. /*           <0    weiter Texte versuchen nicht sinnvoll */
  350. {
  351.     WINDOWP     window;
  352.     TEXTP     t_ptr;
  353.     FILENAME    datei;
  354.     PATH        path;
  355.     int        err, icon;
  356.  
  357.     store_path(name);
  358.  
  359.     if (!bin && is_bin_name(name))
  360.         bin = TRUE;
  361.  
  362.     split_filename(name, path, datei);
  363.     if ((icon = text_still_loaded(name)) > 0)            /* schon geladen */
  364.     {
  365.         if (do_icon(icon, DO_OPEN) < 0)                    /* nur Fenster auf */
  366.             note(1, 0, NOWINDOW);
  367.         return icon;
  368.     }
  369.  
  370.     icon = crt_new_text(name, bin);                        /* neuen Text anlegen */
  371.     if (icon < 0)
  372.     {
  373.         note(1, 0, NOTEXT);
  374.         return -1;                                                /* hat keinen Zweck mehr */
  375.     }
  376.     t_ptr = get_text(icon);
  377.     
  378.     if ((err = load(t_ptr, TRUE)) == -33)                /* File not Found */
  379.     {
  380.         if (path_exists(path))
  381.         {
  382.             if (snote(1, 2, NEWTEXT, datei) == 2)        /* neue Datei anlegen */
  383.             {
  384.                 icon_edit(icon, DO_DELETE);
  385.                 return 0;                                        /* naechsten versuche */
  386.             }
  387.         }
  388.         else
  389.         {
  390.             snote(1, 0, READERR, datei);
  391.             icon_edit(icon, DO_DELETE);
  392.             return 0;                                            /* naechsten versuchen */
  393.         }
  394.     }
  395.     else if (err)                                                /* anderer Fehler */
  396.     {
  397.         snote(1, 0, READERR, datei);
  398.         icon_edit(icon, DO_DELETE);
  399.         return 0;
  400.     }
  401.     if (t_ptr->loc_opt->umbrechen)
  402.     {
  403.         make_absatz(t_ptr);
  404.         if (t_ptr->loc_opt->format_by_load)
  405.             total_format(t_ptr);
  406.     }
  407.     window = get_window(icon);
  408.     window->doc.x = 0;
  409.     window->doc.y = 0;
  410.     window->doc.w = get_longestline(t_ptr);
  411.     window->doc.h = t_ptr->text.lines;
  412.     if (do_icon(icon, DO_OPEN) < 0)
  413.     {
  414.         note(1, 0, NOWINDOW);
  415.         icon_edit(icon, DO_DELETE);
  416.         icon = -2;
  417.     }
  418.     if (t_ptr->moved)                                         
  419.     {
  420.         if (t_ptr->loc_opt->umbrechen)                    /* format_by_load */
  421.             set_info(t_ptr, rsc_string(UMBRUCHSTR));
  422.         else                                                        /*    Nullbytes */
  423.         {
  424.             make_chg(t_ptr->link,TOTAL_CHANGE,0);
  425.             set_info(t_ptr, rsc_string(NULLBYTESTR));
  426.         }
  427.         change_window(window, t_ptr->filename, TRUE);
  428.         restore_edit();
  429.         Bconout(2, 7);
  430.     }
  431.  
  432.     if (find_poslist(lastpos_list, name, &desire_x, &desire_y) != NULL)
  433.         icon_edit(icon, DO_GOTO);
  434.     else
  435.         insert_poslist(&lastpos_list, name, 0, 0);
  436.  
  437.     return icon;
  438. }
  439.  
  440. /***************************************************************************/
  441.  
  442. static void print_edit (TEXTP t_ptr)
  443. {
  444.     FILENAME name;
  445.     bool        print_block;
  446.     
  447.     if (t_ptr->namenlos)
  448.         strcpy(name, t_ptr->filename);
  449.     else
  450.         file_name(t_ptr->filename, name, FALSE);
  451.     print_block = t_ptr->block;
  452.     if (prn_start_dial(&print_block))
  453.     {
  454.         if (print_block)
  455.             blk_drucken(name, t_ptr);
  456.         else
  457.             txt_drucken(name, t_ptr);
  458.     }
  459. } /* print_edit */
  460.  
  461.  
  462. void close_edit(char *mask, int flag)
  463. {
  464.     int i, min;
  465.     
  466.     min = setmin(used_info);
  467.     for (i = setmax(used_info); i >= min; i--)
  468.     {
  469.         if (setin(used_info, i))
  470.         {
  471.             TEXTP t_ptr = get_text(i);
  472.  
  473.             if (filematch(t_ptr->filename, mask, t_ptr->filesys))
  474.             {
  475.                 switch (flag)
  476.                 {
  477.                     case 0 :                            /* sichern ohne schlie₧en */
  478.                         if (t_ptr->moved)            /* nur wenn nötig! */
  479.                             do_icon(i, DO_SAVE);
  480.                         break;
  481.  
  482.                     case 1 :                            /* sichern und schlie₧en */
  483.                         do_icon(i, DO_DELETE);
  484.                         break;
  485.  
  486.                     case 2 :                            /* schlie₧en ohne sichern */
  487.                         t_ptr->moved = 0;
  488.                         do_icon(i, DO_DELETE);
  489.                         break;
  490.  
  491.                     default:
  492.                         debug("close_edit: Unknown SE_CLOSE Flag %d\n", flag);
  493.                         break;
  494.                 }
  495.             }
  496.         }
  497.     }
  498. }
  499.  
  500.  
  501. static bool delete_edit(int icon, TEXTP t_ptr)
  502. {
  503.     int    antw;
  504.     FILENAME    name;
  505.  
  506.     if (t_ptr->moved != 0)
  507.     {
  508.         if (quick_close)
  509.             antw = 1;
  510.         else
  511.         {
  512.             if (t_ptr->namenlos)
  513.                 strcpy(name, t_ptr->filename);
  514.             else
  515.                 file_name(t_ptr->filename, name, FALSE);
  516.             antw = snote(1, 3, MOVED, name);
  517.         }
  518.         if (antw == 1)
  519.         {
  520.             if (do_icon(icon,DO_SAVE) < 0)
  521.                 return (FALSE);
  522.         }
  523.         if (antw == 3)
  524.             return(FALSE);
  525.     }
  526.     return (TRUE);
  527. }
  528.  
  529. /***************************************************************************/
  530. /* Fenster angeclickt                                                                        */
  531. /***************************************************************************/
  532.  
  533. /* Ermittelt aus einer Mauspos (mx,my) die zugehörige Position im Text */
  534. static void get_pos(WINDOWP window, int mx, int my, int *xpos, long *ypos)
  535. {
  536.     TEXTP        t_ptr = get_text(window->handle);
  537.     long        y;
  538.     int        x;
  539.     ZEILEP    col;
  540.     
  541.     y = (my - window->work.g_y);
  542.     if (y < 0)
  543.         y -= font_hcell;
  544.     y /= font_hcell;
  545.     y += window->doc.y;
  546.     if (y >= t_ptr->text.lines)
  547.         y = t_ptr->text.lines-1;
  548.     else if (y < 0)
  549.         y = 0;
  550.  
  551.     col = get_line(&t_ptr->text, y);
  552.  
  553.     if (font_prop)
  554.     {
  555.         int    i, x_soll, s, e, xl; 
  556.         int    save_xpos;
  557.         
  558.         save_xpos = t_ptr->xpos;
  559.         
  560.         x_soll = (mx - window->work.g_x) + ((int) window->doc.x * font_wcell);
  561.  
  562.         /* Zur groben Positionierung machen wir "Halbierungs-Algorithmus" */
  563.         s = 0;
  564.         e = col->len;
  565.         xl = -1;
  566.         while (TRUE)
  567.         {
  568.             x = s + ((e - s) / 2);
  569.             if (x == xl)
  570.                 break;
  571.             t_ptr->xpos = x;
  572.             i = cursor_xpos(t_ptr, t_ptr->xpos);
  573.             if (i > x_soll)
  574.                 e = x;            /* in linker Hälfte */
  575.             else
  576.                 s = x;            /* in rechter Hälfte */
  577.             xl = x;                
  578.         }
  579.         /* jetzt Fein-Positionierung zeichenweise heranbewegen */
  580.         for (x = s; x <= e; x++)
  581.         {
  582.             t_ptr->xpos = x;
  583.             i = cursor_xpos(t_ptr, t_ptr->xpos);
  584.             if (i > x_soll) 
  585.                 break;
  586.         }
  587.         x--;
  588.  
  589.         t_ptr->xpos = save_xpos;
  590.     }
  591.     else
  592.     {
  593.  
  594.         x = mx - window->work.g_x;
  595.         if (x > 0)
  596.         {
  597.             x /= font_wcell;
  598.             x += (int) window->doc.x;
  599.         }
  600.         else if (window->doc.x > 0)
  601.             x = (int) window->doc.x - 1;
  602.         else
  603.             x = 0;
  604.  
  605.         x = inter_pos(x, col, t_ptr->loc_opt->tab, t_ptr->loc_opt->tabsize);
  606.     }
  607.     
  608.     if (xpos != NULL)
  609.         *xpos = x;
  610.     if (ypos != NULL)
  611.         *ypos = y;
  612. }
  613.  
  614. static void set_cursor(WINDOWP window, int mx, int my)
  615. {
  616.     TEXTP     t_ptr = get_text(window->handle);
  617.     int        x;
  618.     long        y;
  619.     ZEILEP    col;
  620.  
  621.     get_pos(window, mx, my, &x, &y);
  622.     col = get_line(&t_ptr->text, y);
  623.  
  624.     t_ptr->xpos = x;
  625.     t_ptr->ypos = y;
  626.     t_ptr->cursor_line = col;
  627.  
  628.     y -= window->doc.y;
  629.     if (y > 0)
  630.     {
  631.         if (y > window->w_height)
  632.             make_chg(t_ptr->link,MOVE_UP, y-window->w_height);
  633.     }
  634.     else
  635.         make_chg(t_ptr->link,MOVE_DOWN, -y);
  636.     make_chg(t_ptr->link,POS_CHANGE, 0);
  637. }
  638.  
  639. /*
  640.  * Prüft, ob Mauspos (x,y) innerhalb der Blockselektion liegt.
  641. */
  642. static bool click_in_blk(WINDOWP window, int x, int y)
  643. {
  644.     TEXTP    t_ptr = get_text(window->handle);
  645.     long    line;
  646.     int    col;
  647.     
  648.     if (!t_ptr->block)
  649.         return FALSE;
  650.  
  651.     get_pos(window, x, y, &col, &line);
  652.  
  653.     if (line == t_ptr->z1 && line == t_ptr->z2)            /* nur eine Zeile */
  654.     {
  655.         if (col >= t_ptr->x1 && col < t_ptr->x2)
  656.             return TRUE;
  657.         else
  658.             return FALSE;
  659.     }
  660.     else
  661.     {
  662.         if ((line == t_ptr->z1 && col >= t_ptr->x1) ||    /* rechts vom Anfang */
  663.             (line == t_ptr->z2 && col < t_ptr->x2) ||        /* links vom Ende */
  664.             (line > t_ptr->z1 && line < t_ptr->z2))        /* zwischen Anfang und Ende (Zeilen) */
  665.             return TRUE;
  666.         else
  667.             return FALSE;
  668.     }
  669. }
  670.  
  671.  
  672. #define LINE_MODE        1
  673. #define WORD_MODE        2
  674. #define KEY_MODE        3
  675. #define BRACE_MODE    4
  676.  
  677. static void wi_click(WINDOWP window, int m_x, int m_y, int bstate, int kstate, int breturn)
  678. {
  679.     int        event, mode, kreturn;
  680.     TEXTP     t_ptr = get_text(window->handle);
  681.     GRECT        *s = &window->work;
  682.     
  683.     /* Infomeldung löschen */
  684.     clear_info(t_ptr);
  685.  
  686.     if (bstate & 2)                                             /* Rechtsclick */
  687.     {
  688.         if (strlen(error[0]) > 0)
  689.         {
  690.             blk_demark(t_ptr);
  691.             set_cursor(window, m_x, m_y);
  692.             restore_edit();
  693.             handle_error(t_ptr);
  694.         }
  695.         return;                                                    /* und wech... */
  696.     }
  697.  
  698.     if (!inside(m_x, m_y, s))
  699.         return;
  700.     t_ptr->blk_mark_mode = FALSE;
  701.     unclick_window();
  702.     if (breturn == 2)                                            /* Doppelklick */
  703.     {
  704.         blk_demark(t_ptr);
  705.         set_cursor(window, m_x, m_y);
  706.         restore_edit();
  707.         if (kstate & (K_RSHIFT|K_LSHIFT) ||                /* Ganze Zeile markieren */
  708.              t_ptr->xpos==t_ptr->cursor_line->len)
  709.         {
  710.             t_ptr->xpos = 0;
  711.             blk_mark(t_ptr, 0);
  712.             if (IS_LAST(t_ptr->cursor_line))
  713.                 t_ptr->xpos = t_ptr->cursor_line->len;
  714.             else
  715.             {
  716.                 NEXT(t_ptr->cursor_line);
  717.                 t_ptr->ypos++;
  718.             }
  719.             blk_mark(t_ptr, 1);
  720.             restore_edit();
  721.             mode = LINE_MODE;
  722.         }
  723.         else if (blk_mark_brace(t_ptr))                    /* Klammer-Selektion */
  724.         {
  725.             restore_edit();
  726.             mode = BRACE_MODE;
  727.         }
  728.         else                                                        /* wortweise */
  729.         {
  730.             blk_mark_word(t_ptr);
  731.             mode = WORD_MODE;
  732.         }
  733.     }
  734.     else                                                            /* Einfachklick */
  735.     {
  736.         if (kstate & (K_RSHIFT|K_LSHIFT))
  737.         {
  738.             if (!t_ptr->block)
  739.                 blk_mark(t_ptr,0);                            /* Anfang = alte Cursorpos */
  740.             set_cursor(window, m_x, m_y);
  741.             blk_mark(t_ptr, 1);
  742.             restore_edit();
  743.         }
  744.         else                                                        /* Zieh-Aktion auf Block?  */
  745.         {
  746.             graf_mkstate(&m_x, &m_y, &bstate, &kstate);
  747.  
  748.             if (click_in_blk(window, m_x, m_y) && bstate & 1)
  749.             {
  750.                 int        win_id;
  751.                 WINDOWP    qed_win;
  752.                 RING        t;
  753.                 int        x, y, w, h, d;
  754.                 GRECT        r;
  755.                 
  756.                 /* Rahmen ermitteln */
  757.                 r = window->work;
  758.                 if (t_ptr->z1 == t_ptr->z2)    /* Spezialfall: nur eine Zeile */
  759.                 {
  760.                     if (font_prop)
  761.                     {
  762.                         extern int line_to_str(char *str, int anz);    /* ausgabe.c */
  763.  
  764.                         char    str[MAX_LINE_LEN+1];
  765.                         int    pxy[8];
  766.                                             
  767.                         strcpy(str, TEXT(t_ptr->cursor_line));
  768.                         
  769.                         str[t_ptr->x2] = EOS;
  770.                         line_to_str(str, (int)strlen(str));
  771.                         vqt_extent(vdi_handle, str, pxy);
  772.                         x = r.g_x + pxy[2] - pxy[0];
  773.  
  774.                         str[t_ptr->x1] = EOS;
  775.                         line_to_str(str, (int)strlen(str));
  776.                         vqt_extent(vdi_handle, str, pxy);
  777.                         w = r.g_x + (pxy[2] - pxy[0] - x);
  778.                     }
  779.                     else
  780.                     {
  781.                         x = r.g_x + t_ptr->x1 * font_wcell;
  782.                         w = r.g_x + t_ptr->x2 * font_wcell - x;
  783.                     }
  784.                 }
  785.                 else
  786.                 {
  787.                     x = r.g_x;
  788.                     w = r.g_w;
  789.                 }
  790.                 y = (short)((t_ptr->z1 - window->doc.y) * font_hcell) + r.g_y;
  791.                 if (t_ptr->x2 == 0)
  792.                     h = ((int)(t_ptr->z2 - t_ptr->z1)) * font_hcell;
  793.                 else
  794.                     h = ((int)(t_ptr->z2 - t_ptr->z1) + 1) * font_hcell;
  795.                 
  796.                 /* Clipping auf Fenstergrö₧e */
  797.                 if (y < r.g_y)
  798.                 {
  799.                     h -= (r.g_y - y); 
  800.                     y = r.g_y;
  801.                 }
  802.                 if (y + h > (r.g_y + r.g_h - 1))
  803.                     h = (r.g_y + r.g_h - 1) - y;
  804.                 
  805.                 /* Box verschieben */
  806.                 graf_mouse(TEXT_CRSR/*FLAT_HAND*/, NULL);
  807.                 graf_dragbox(w, h, x, y, gl_desk.g_x, gl_desk.g_y, gl_desk.g_w, gl_desk.g_h, &d, &d);
  808.                 graf_mouse(ARROW, NULL);
  809.                 graf_mkstate(&m_x, &m_y, &bstate, &kstate);
  810.  
  811.                 /* markierten Text merken */
  812.                 init_textring(&t);
  813.                 block_copy(t_ptr, &t);
  814.  
  815.                 /* wohin wurde gezogen? */
  816.                 win_id = wind_find(m_x, m_y);
  817.                 qed_win = get_window(win_id);
  818.  
  819.                 if (qed_win)                                            /* eigenes Fenster */
  820.                 {
  821.                     /* Ziel mu₧ Textfenster sein */
  822.                     if (qed_win->class == CLASS_EDIT)
  823.                     {
  824.                         if (qed_win != window)                        /* ein anderes */
  825.                         {
  826.                             t_ptr = get_text(qed_win->handle);
  827.                             blk_paste(t_ptr, &t);
  828.                         }
  829.                         else                                                /* das selbe */
  830.                         {
  831.                             Bconout(2, 7);
  832. #if 0
  833.                             blk_delete(t_ptr);
  834.                             set_cursor(window, m_x, m_y);
  835.                             blk_paste(t_ptr, &t);
  836. #endif
  837.                         }
  838.                         restore_edit();
  839.                     }
  840.                     else
  841.                         Bconout(2, 7);
  842.                 }
  843.                 else                                                        /* fremdes Fenster */
  844.                     send_dd(win_id, m_x, m_y, kstate, &t);                
  845.                 kill_textring(&t);
  846.             }
  847.             else
  848.             {
  849.                 blk_demark(t_ptr);
  850.                 set_cursor(window, m_x, m_y);
  851.                 blk_mark(t_ptr, 0);
  852.                 restore_edit();
  853.             }
  854.         }
  855.         mode = KEY_MODE;
  856.     }
  857.     graf_mkstate(&m_x, &m_y, &bstate, &kstate);
  858.     if (bstate & 1)                                                    /* immernoch gedrückt */
  859.     {
  860.         graf_mouse(POINT_HAND, NULL);
  861.         wind_update(BEG_MCTRL);
  862.         while(TRUE)
  863.         {
  864.             event = evnt_multi((MU_BUTTON | MU_M1 | MU_M2),
  865.                                       1, 0x01, 0x00,
  866.                                       TRUE, m_x, m_y, 1, 1,
  867.                                       TRUE, s->g_x, s->g_y, s->g_w, s->g_h,
  868.                                       NULL, 0L,
  869.                                       &m_x, &m_y, &bstate, &kstate, &kreturn, &breturn);
  870.  
  871.             if (event & MU_BUTTON) 
  872.                 break;
  873.             if (event & (MU_M1 | MU_M2))
  874.             {
  875.                 set_cursor(window, m_x, m_y);
  876.                 if (mode == WORD_MODE)
  877.                 {
  878.                     long    y;
  879.                     int    x, pos,len;
  880.                     char    *str;
  881.  
  882.                     pos = t_ptr->xpos;
  883.                     str = TEXT(t_ptr->cursor_line) + pos;
  884.                     len = t_ptr->cursor_line->len;
  885.                     get_blk_mark(t_ptr, &y, &x);
  886.                     if (t_ptr->ypos > y || t_ptr->xpos > x)         /* nach rechts */
  887.                     {
  888.                         while(pos<=len && setin(t_ptr->loc_opt->wort_set,*str))
  889.                         {
  890.                             pos++;
  891.                             str++;
  892.                         }
  893.                     }
  894.                     else                                                        /* nach links */
  895.                     {
  896.                         while(pos>=0 && setin(t_ptr->loc_opt->wort_set,*str))
  897.                         {
  898.                             pos--;
  899.                             str--;
  900.                         }
  901.                         str++; pos++;
  902.                     }
  903.                     t_ptr->xpos = pos;
  904.                 }
  905.                 else if (mode == LINE_MODE)
  906.                 {
  907.                     long    y;
  908.                     int    x;
  909.  
  910.                     get_blk_mark(t_ptr, &y, &x);
  911.                     t_ptr->xpos = 0;
  912.                     if (y == t_ptr->ypos && !IS_LAST(t_ptr->cursor_line))
  913.                     {
  914.                         NEXT(t_ptr->cursor_line);
  915.                         t_ptr->ypos++;
  916.                     }
  917.                 }
  918.                 blk_mark(t_ptr, 1);
  919.                 restore_edit();
  920.             }
  921.         }
  922.         wind_update(END_MCTRL);
  923.         graf_mouse(ARROW, NULL);
  924.     }
  925. }
  926.  
  927.  
  928. static bool wi_key (WINDOWP window, int kstate, int kreturn)
  929. {
  930.     TEXTP t_ptr = get_text(window->handle);
  931.  
  932.     /* Infomeldung löschen */
  933.     clear_info(t_ptr);
  934.  
  935.     if (edit_key(t_ptr, window, kstate, kreturn))
  936.     {
  937.         restore_edit();
  938.         return TRUE;
  939.     }
  940.     return FALSE;
  941. }
  942.  
  943.  
  944. static void wi_draw(WINDOWP window, GRECT *d)
  945. {
  946.     TEXTP t_ptr = get_text(window->handle);
  947.  
  948.     set_clip(TRUE, d);
  949.     if (d->g_x == window->work.g_x && d->g_w == window->work.g_w)
  950.     {
  951.         if (d->g_y == window->work.g_y + window->work.g_h - window->yfac &&
  952.              d->g_h == window->yfac)
  953.         {
  954.             /* Letzte Zeile */
  955.             line_out(window, t_ptr, window->w_height - 1);
  956.         }
  957.         else if (d->g_y == window->work.g_y && d->g_h == window->yfac)
  958.         {
  959.             /* Erste Zeile */
  960.             line_out(window, t_ptr, 0);
  961.         }
  962.         else
  963.             bild_out(window, t_ptr);
  964.     }
  965.     else
  966.         bild_out(window,t_ptr);
  967. }
  968.  
  969.  
  970. static void wi_top(WINDOWP window)
  971. {
  972.     /* Kürzel/Schreibschutz ändern */
  973.     do_icon(window->handle, DO_UPDATE);
  974. }
  975.  
  976. static    void wi_iconify(WINDOWP window)
  977. {
  978.     TEXTP     t_ptr = get_text(window->handle);
  979.     FILENAME    short_name;
  980.  
  981.     make_shortpath(t_ptr->filename, short_name, 8);
  982.     set_wtitle(window, short_name);
  983. }
  984.  
  985. static    void wi_uniconify(WINDOWP window)
  986. {
  987.     TEXTP t_ptr = get_text(window->handle);
  988.  
  989.     set_wtitle(window, t_ptr->filename);
  990. }
  991.  
  992. /***************************************************************************/
  993. /* Operation vorhanden ?                                                                    */
  994. /***************************************************************************/
  995.  
  996. static void e_icon_exist(int icon, SET actions)
  997. {
  998.     TEXTP        t_ptr = get_text(icon);
  999.     WINDOWP    window = get_window(icon);
  1000.  
  1001.     setclr(actions);
  1002.  
  1003.     if ((window->flags & WI_ICONIFIED) || (window->flags & WI_SHADED))
  1004.     {
  1005.         /* Einzige mögliche Aktion: */
  1006.         setincl(actions, DO_DELETE);
  1007.         return;
  1008.     }
  1009.  
  1010.     if (any_undo())
  1011.         setincl(actions, DO_UNDO);
  1012.     if (t_ptr->block)
  1013.     {
  1014.         setincl(actions, DO_CUT);
  1015.         setincl(actions, DO_COPY);
  1016.         setincl(actions, DO_LEFT);
  1017.         setincl(actions, DO_RIGHT);
  1018.         setincl(actions, DO_BIG2SMALL);
  1019.         setincl(actions, DO_SMALL2BIG);
  1020.         setincl(actions, DO_CHNG_SMBG);
  1021.         setincl(actions, DO_CAPS);
  1022.         setincl(actions, DO_SORT);
  1023.     }
  1024.     else
  1025.     {
  1026.         setincl(actions, DO_LINECOPY);
  1027.         setincl(actions, DO_SWAPCHAR);
  1028.     }
  1029.     if (t_ptr->loc_opt->tab)
  1030.     {
  1031.         setincl(actions, DO_TAB2LZ);
  1032.         setincl(actions, DO_LZ2TAB);
  1033.     }
  1034.     if (t_ptr->loc_opt->umbrechen)
  1035.         setincl(actions, DO_FORMAT);
  1036.     else
  1037.         setincl(actions, DO_STRIPLINES);
  1038.     if (window->flags & WI_OPEN)
  1039.         setincl(actions, DO_CLOSE);
  1040.     setincl(actions, DO_DELETE);
  1041.     setincl(actions, DO_PASTE);
  1042.     setincl(actions, DO_SELALL);
  1043.     setincl(actions, DO_OPEN);
  1044.     setincl(actions, DO_INFO);
  1045.     setincl(actions, DO_HELP);
  1046.     setincl(actions, DO_PRINT);
  1047.     if (!t_ptr->namenlos)
  1048.         setincl(actions,DO_ABAND);
  1049.     setincl(actions, DO_SAVE);
  1050.     setincl(actions, DO_SAVENEW);
  1051.     setincl(actions, DO_FIND);
  1052.     setincl(actions, DO_FINDNEXT);
  1053.     setincl(actions, DO_GOTO);
  1054.     setincl(actions, DO_ADD);
  1055.     setincl(actions, DO_UPDATE);
  1056.     setincl(actions, DO_ZEICHTAB);
  1057.     setincl(actions, DO_UMLAUT);
  1058.     if (t_ptr->moved)
  1059.         setincl(actions, DO_AUTOSAVE);
  1060.     setincl(actions, DO_FEHLER);
  1061.     if ((t_ptr->ypos - window->doc.y) > 0)
  1062.         setincl(actions, DO_TOPLINE);
  1063. }
  1064.  
  1065. /***************************************************************************/
  1066. /* Operation testen                                                                            */
  1067. /***************************************************************************/
  1068.  
  1069. static bool e_icon_test(int icon, int action)
  1070. {
  1071.     bool    erg;
  1072.     TEXTP     t_ptr = get_text(icon);
  1073.     FILENAME    name;
  1074.  
  1075.     switch(action)
  1076.     {
  1077.         case DO_UNDO    :
  1078.             erg = any_undo();
  1079.             break;
  1080.         case DO_CUT     :
  1081.             erg = t_ptr->block;
  1082.              break;
  1083.         case DO_COPY    :
  1084.             erg = t_ptr->block;
  1085.             break;
  1086.         case DO_LINECOPY:
  1087.             erg = !(t_ptr->block);
  1088.             break;
  1089.         case DO_PASTE    :
  1090.             erg = TRUE;
  1091.             break;
  1092.         case DO_SELALL :
  1093.             erg = TRUE;
  1094.             break;
  1095.         case DO_CLOSE    :
  1096.         case DO_DELETE    :
  1097.             erg = delete_edit(icon, t_ptr);
  1098.             break;
  1099.         case DO_OPEN    :
  1100.             erg = TRUE;
  1101.             break;
  1102.         case DO_INFO    :
  1103.             erg = TRUE;
  1104.             break;
  1105.         case DO_HELP    :
  1106.             erg = TRUE;
  1107.             break;
  1108.         case DO_LEFT    :
  1109.         case DO_RIGHT    :
  1110.         case DO_BIG2SMALL    :
  1111.         case DO_SMALL2BIG    :
  1112.         case DO_CHNG_SMBG    :
  1113.         case DO_CAPS        :
  1114.         case DO_SORT         :
  1115.             erg = t_ptr->block;
  1116.             break;
  1117.         case DO_FORMAT :
  1118.             erg = t_ptr->loc_opt->umbrechen;
  1119.             break;
  1120.         case DO_PRINT    :
  1121.             erg = TRUE;
  1122.             break;
  1123.         case DO_ABAND    :
  1124.             if (t_ptr->namenlos)
  1125.                 erg = FALSE;
  1126.             else
  1127.             {
  1128.                 erg = TRUE;
  1129.                 if (!ist_leer(&t_ptr->text) && t_ptr->moved!=0)
  1130.                 {
  1131.                     if (t_ptr->namenlos)
  1132.                         strcpy(name, t_ptr->filename);
  1133.                     else
  1134.                         file_name(t_ptr->filename, name, FALSE);
  1135.                     erg = (snote(1, 2, ABANDON, name) == 1);
  1136.                 }
  1137.             }
  1138.             break;
  1139.         case DO_SAVE    :
  1140.             erg = TRUE;
  1141.             break;
  1142.         case DO_SAVENEW:
  1143.             erg = TRUE;
  1144.             break;
  1145.         case DO_FIND :
  1146.             if (t_ptr->block)
  1147.             {
  1148.                 RING    r;
  1149.     
  1150.                 /* copy to R_STR */
  1151.                 block_copy(t_ptr, &r);
  1152.                 if (strlen(TEXT(FIRST(&r))) > 0)
  1153.                 {
  1154.                     strncpy(s_str, TEXT(FIRST(&r)), HIST_LEN);
  1155.                     kill_textring(&r);
  1156.                     s_str[HIST_LEN] = EOS;
  1157.                 }
  1158.             }
  1159.             find_erg = replace_dial();
  1160.             erg = (find_erg!=0);
  1161.             break;
  1162.         case DO_FINDNEXT:
  1163.             erg = TRUE;
  1164.             break;
  1165.         case DO_ADD     :
  1166.             erg = TRUE;
  1167.             break;
  1168.         case DO_GOTO    :
  1169.             erg = goto_line_dial();
  1170.             break;
  1171.         case DO_STRIPLINES:
  1172.             erg = !t_ptr->loc_opt->umbrechen;
  1173.             break;
  1174.         case DO_TAB2LZ :
  1175.             erg = t_ptr->loc_opt->tab;
  1176.             break;
  1177.         case DO_LZ2TAB :
  1178.             erg = t_ptr->loc_opt->tab;
  1179.             break;
  1180.         case DO_UPDATE    :
  1181.             erg = TRUE;
  1182.             break;
  1183.         case DO_ZEICHTAB:
  1184.             ascii_wert = ascii_table(font_id, 13);
  1185.             erg = (ascii_wert != -1);
  1186.             break;
  1187.         case DO_UMLAUT:
  1188.             erg = umlaut_dial();
  1189.             break;
  1190.         case DO_SWAPCHAR:
  1191.             erg = !t_ptr->block;
  1192.             break;
  1193.         case DO_AUTOSAVE :
  1194.             if (as_text && t_ptr->moved)
  1195.             {
  1196.                 long    min;
  1197.                 int    btn;
  1198.  
  1199.                 min = (int)((time(NULL) - t_ptr->asave) / 60L);
  1200.                 if (min >= as_text_min)
  1201.                 {
  1202.                     if (as_text_ask)                /* Nachfrage ? */
  1203.                     {
  1204.                         FILENAME        name;
  1205.  
  1206.                         if (t_ptr->namenlos)
  1207.                             strcpy(name, t_ptr->filename);
  1208.                         else
  1209.                             file_name(t_ptr->filename, name, FALSE);
  1210.                         Bconout(2, 7);
  1211.                         btn = snote(2, 3, ASAVEASK, name);
  1212.                         if (btn == 1)
  1213.                             as_text = FALSE;
  1214.                     }
  1215.                     else
  1216.                         btn = 2;
  1217.  
  1218.                     t_ptr->asave = time(NULL);
  1219.                     erg = (btn == 2);
  1220.                 }
  1221.                 else
  1222.                     erg = FALSE;
  1223.             }
  1224.             else
  1225.             {
  1226.                 t_ptr->asave = time(NULL);
  1227.                 erg = FALSE;
  1228.             }
  1229.             break;
  1230.         case DO_FEHLER :
  1231.             erg = TRUE;
  1232.             break;
  1233.         case DO_TOPLINE :
  1234.             erg = TRUE;
  1235.             break;
  1236.         default    :
  1237.             erg = FALSE;
  1238.     }
  1239.     return erg;
  1240. }
  1241.  
  1242. /***************************************************************************/
  1243. /* Operation durchführen                                                                    */
  1244. /***************************************************************************/
  1245.  
  1246. static int e_icon_edit(int icon, int action)
  1247. {
  1248.     PATH        name = "";
  1249.     TEXTP        t_ptr = get_text(icon);
  1250.     RING        r;
  1251.     WINDOWP    window;
  1252.     int        erg;
  1253.     bool        ok, bin, shift;
  1254.     ZEILEP    lauf;
  1255.  
  1256.     shift = shift_pressed();
  1257.     window = get_window(icon);
  1258.     erg = 0;
  1259.     switch(action)
  1260.     {
  1261.         case DO_UNDO    :
  1262.             t_ptr->blk_mark_mode = FALSE;
  1263.             blk_demark(t_ptr);
  1264.             make_undo(t_ptr);
  1265.             erg = 1;
  1266.             break;
  1267.         case DO_CUT     :
  1268.             t_ptr->blk_mark_mode = FALSE;
  1269.             blk_cut(t_ptr);
  1270.             restore_edit();
  1271.             erg = 1;
  1272.             break;
  1273.         case DO_COPY    :
  1274.             t_ptr->blk_mark_mode = FALSE;
  1275.             blk_copy(t_ptr);
  1276.             restore_edit();
  1277.             erg = 1;
  1278.             break;
  1279.         case DO_LINECOPY:
  1280.             line_copy(t_ptr);
  1281.             restore_edit();
  1282.             erg = 1;
  1283.             break;
  1284.         case DO_PASTE    :
  1285.             t_ptr->blk_mark_mode = FALSE;
  1286.             load_clip();
  1287.             if (!ist_leer(&clip_text))
  1288.             {
  1289.                 blk_paste(t_ptr, &clip_text);
  1290.                 if (t_ptr->loc_opt->umbrechen && t_ptr->loc_opt->format_by_paste)
  1291.                     format(t_ptr);
  1292.                 restore_edit();
  1293.             }
  1294.             erg = 1;
  1295.             break;
  1296.         case DO_SELALL :
  1297.             t_ptr->blk_mark_mode = FALSE;
  1298.             blk_mark_all(t_ptr);
  1299.             restore_edit();
  1300.             erg = 1;
  1301.             break;
  1302.         case DO_CLOSE    :
  1303.         case DO_DELETE    :
  1304.             t_ptr->blk_mark_mode = FALSE;
  1305.             destruct(icon);
  1306.             erg = 1;
  1307.             break;
  1308.         case DO_OPEN    :
  1309.             t_ptr->blk_mark_mode = FALSE;
  1310.             if (!open_edit(icon))
  1311.                 erg = -1;
  1312.             else
  1313.                 erg = 1;
  1314.             break;
  1315.         case DO_INFO    :
  1316.             t_ptr->blk_mark_mode = FALSE;
  1317.             if (t_ptr->block)
  1318.                 block_info(t_ptr);
  1319.             else
  1320.                 info_edit(icon);
  1321.             erg = 1;
  1322.             break;
  1323.         case DO_HELP    :
  1324.             t_ptr->blk_mark_mode = FALSE;
  1325.             if (!t_ptr->block)
  1326.                 blk_mark_word(t_ptr);
  1327.             if (t_ptr->block)
  1328.             {
  1329.                 block_copy(t_ptr, &r);
  1330.                 if (strlen(TEXT(FIRST(&r))) > 0)
  1331.                     erg = call_help(TEXT(FIRST(&r)));
  1332.                 else
  1333.                     erg = call_hyp("main");
  1334.                 kill_textring(&r);
  1335.             }
  1336.             else
  1337.                 erg = call_hyp("main");
  1338.             break;
  1339.         case DO_LEFT    :
  1340.             t_ptr->blk_mark_mode = FALSE;
  1341.             blk_left(t_ptr);
  1342.             restore_edit();
  1343.             erg = 1;
  1344.             break;
  1345.         case DO_RIGHT    :
  1346.             t_ptr->blk_mark_mode = FALSE;
  1347.             blk_right(t_ptr);
  1348.             restore_edit();
  1349.             erg = 1;
  1350.             break;
  1351.         case DO_SMALL2BIG    :
  1352.             t_ptr->blk_mark_mode = FALSE;
  1353.             blk_upplow(t_ptr, BLK_UPPER);
  1354.             restore_edit();
  1355.             erg = 1;
  1356.             break;
  1357.         case DO_BIG2SMALL    :
  1358.             t_ptr->blk_mark_mode = FALSE;
  1359.             blk_upplow(t_ptr, BLK_LOWER);
  1360.             restore_edit();
  1361.             erg = 1;
  1362.             break;
  1363.         case DO_CHNG_SMBG    :
  1364.             t_ptr->blk_mark_mode = FALSE;
  1365.             blk_upplow(t_ptr, BLK_CH_UPLO);
  1366.             restore_edit();
  1367.             erg = 1;
  1368.             break;
  1369.         case DO_CAPS    :
  1370.             t_ptr->blk_mark_mode = FALSE;
  1371.             blk_upplow(t_ptr, BLK_CAPS);
  1372.             restore_edit();
  1373.             erg = 1;
  1374.             break;
  1375.         case DO_FORMAT :
  1376.             t_ptr->blk_mark_mode = FALSE;
  1377.             blk_demark(t_ptr);
  1378.             if (shift)
  1379.                 total_format(t_ptr);
  1380.             else
  1381.                 format(t_ptr);
  1382.             restore_edit();
  1383.             erg = 1;
  1384.             break;
  1385.         case DO_PRINT    :
  1386.             t_ptr->blk_mark_mode = FALSE;
  1387.             print_edit(t_ptr);
  1388.             erg = 1;
  1389.             break;
  1390.         case DO_ABAND    :
  1391. abandon:    strcpy(name, t_ptr->filename);
  1392.             bin = (t_ptr->text.ending == binmode);
  1393.             destruct(icon);
  1394.             icon = load_edit(name, bin);
  1395.             if (icon > 0)
  1396.             {
  1397.                 t_ptr = get_text(icon);
  1398.                 erg = -1;
  1399.                 if (t_ptr != NULL)
  1400.                 {
  1401.                     if (open_edit(icon))
  1402.                     {
  1403.                         memset(msgbuff, 0, (int) sizeof(msgbuff));
  1404.                         msgbuff[0] = WM_TOPPED;
  1405.                         msgbuff[3] = window->handle;
  1406.                         send_msg(gl_apid);
  1407.                         erg = 1;
  1408.                     }
  1409.                 }
  1410.             }
  1411.             clr_undo();
  1412.             break;
  1413.         case DO_SAVE    :
  1414.             if (!t_ptr->namenlos)
  1415.             {
  1416.                 t_ptr->blk_mark_mode = FALSE;
  1417.                 if (t_ptr->loc_opt->umbrechen)
  1418.                     save_absatz(t_ptr);                    /* Zeilenende korrigieren */
  1419.                 if (save(t_ptr)<0)
  1420.                     erg = -1;
  1421.                 else
  1422.                     erg = 1;
  1423.  
  1424.                 make_chg(icon, WT_CHANGE, 0);            /* nur Fenstertitel schreiben */
  1425.                 restore_edit();
  1426.                 break;
  1427.             }
  1428.             /* Bei Namenlos zu DO_SAVENEW */
  1429.         case DO_SAVENEW:
  1430.             t_ptr->blk_mark_mode = FALSE;
  1431.             if (t_ptr->block)
  1432.             {
  1433.                 strcpy(name, "");
  1434.                 if (save_new(name, "", rsc_string(SAVEBLKSTR)))
  1435.                 {
  1436.                     TEXTP temp_ptr;
  1437.  
  1438.                     temp_ptr = new_text(TEMP_LINK);
  1439.                     if (t_ptr->loc_opt->umbrechen)    /* Zeilenende korrigieren */
  1440.                         save_absatz(t_ptr);
  1441.                     block_copy(t_ptr,&temp_ptr->text);    /* Block rauskopieren */
  1442.                     temp_ptr->cursor_line = FIRST(&t_ptr->text);
  1443.                     temp_ptr->loc_opt = t_ptr->loc_opt;
  1444.                     erg = save_as(temp_ptr,name);
  1445.                     destruct_text(temp_ptr);
  1446.                     if (erg==0)
  1447.                         erg = 1;
  1448.                 }
  1449.                 else
  1450.                     erg = -1;
  1451.             }
  1452.             else
  1453.             {
  1454.                 strcpy(name, t_ptr->filename);
  1455.                 if (save_new(name, "", rsc_string(SAVEASSTR)))
  1456.                 {
  1457.                     bool umb_old = t_ptr->loc_opt->umbrechen;
  1458.                     
  1459.                     if (t_ptr->loc_opt->umbrechen)    /* Zeilenende korrigieren */
  1460.                         save_absatz(t_ptr);
  1461.                     if (save_as(t_ptr, name) == 0)
  1462.                     {
  1463.                         if (t_ptr->namenlos || note(1, 2, GETNAME) == 1)
  1464.                         {
  1465.                             /* OLGA informieren */
  1466.                             do_olga(OLGA_RENAME, t_ptr->filename, name);
  1467.                             do_olga(OLGA_UPDATE, name, NULL);
  1468.  
  1469.                             set_text_name(t_ptr, name, FALSE);
  1470.                             chg_edit_name(icon);
  1471.                             t_ptr->moved = 0;
  1472.                             t_ptr->file_date_time = file_time(name,NULL,NULL);
  1473.                             t_ptr->readonly = file_readonly(name);
  1474.                         }
  1475.                         make_chg(icon, TOTAL_CHANGE, 0); /* ggf. neue lok. Optionen! */
  1476.                         make_chg(icon, WT_CHANGE, 0);        /* Headline schreiben */
  1477.                         ch_kurzel(t_ptr->loc_opt->kurzel, FALSE);
  1478.                         if (umb_old != t_ptr->loc_opt->umbrechen)
  1479.                             make_absatz(t_ptr);
  1480.                         restore_edit();
  1481.                         erg = 1;
  1482.                     }
  1483.                     else
  1484.                         erg = -1;
  1485.                 }
  1486.                 else
  1487.                     erg = -1;
  1488.             }
  1489.             break;
  1490.         case DO_FIND    :
  1491.             t_ptr->blk_mark_mode = FALSE;
  1492.             if (find_erg == 1)
  1493.             {
  1494.                 if (start_find(t_ptr,FALSE)==0)
  1495.                 {
  1496.                     Bconout(2, 7);
  1497.                     end_play();
  1498.                 }
  1499.             }
  1500.             else
  1501.             {
  1502.                 if (find_erg == 2)
  1503.                 {
  1504.                     if (start_replace(t_ptr) == 0)
  1505.                     {
  1506.                         Bconout(2, 7);
  1507.                         end_play();
  1508.                     }
  1509.                 }
  1510.             }
  1511.             erg = 1;
  1512.             break;
  1513.         case DO_FINDNEXT:
  1514.             t_ptr->blk_mark_mode = FALSE;
  1515.             if (t_ptr->block)
  1516.                 find_selection(t_ptr);
  1517.             else
  1518.             {
  1519.                 if (do_next(t_ptr) != 1)
  1520.                 {
  1521.                     Bconout(2, 7);
  1522.                     end_play();
  1523.                 }
  1524.             }
  1525.             erg = 1;
  1526.             break;
  1527.         case DO_GOTO    :
  1528.             t_ptr->blk_mark_mode = FALSE;
  1529.             blk_demark(t_ptr);
  1530.             goto_line(t_ptr, desire_x, desire_y);
  1531.             restore_edit();
  1532.             erg = 1;
  1533.             break;
  1534.         case DO_STRIPLINES:
  1535.             t_ptr->blk_mark_mode = FALSE;
  1536.             blk_demark(t_ptr);
  1537.             graf_mouse(HOURGLASS, NULL);
  1538.             if (strip_endings(t_ptr))
  1539.             {
  1540.                 t_ptr->max_line = NULL;
  1541.                 lauf = t_ptr->cursor_line = get_line(&t_ptr->text, t_ptr->ypos);
  1542.                 if (t_ptr->xpos > lauf->len)
  1543.                     t_ptr->xpos = lauf->len;
  1544.                 make_chg(t_ptr->link, POS_CHANGE, 0);        /* '*' in Titel */
  1545.             }
  1546.             graf_mouse(ARROW, NULL);
  1547.             restore_edit();
  1548.             erg = 1;
  1549.             break;
  1550.         case DO_TAB2LZ :
  1551.             t_ptr->blk_mark_mode = FALSE;
  1552.             blk_demark(t_ptr);
  1553.             tab2lz(t_ptr);
  1554.             erg = 1;
  1555.             break;
  1556.         case DO_LZ2TAB :
  1557.             t_ptr->blk_mark_mode = FALSE;
  1558.             blk_demark(t_ptr);
  1559.             lz2tab(t_ptr);
  1560.             erg = 1;
  1561.             break;
  1562.         case DO_ADD     :
  1563.             if (shift)
  1564.                 ok = select_single(name, "", rsc_string(INSNAMESTR));
  1565.             else
  1566.                 ok = select_single(name, "", rsc_string(MERGESTR));
  1567.             if (ok)
  1568.             {
  1569.                 if (shift)                /* Dateinamen einfügen */
  1570.                 {
  1571.                     RING        temp_ring;
  1572.                     ZEILEP    col;
  1573.  
  1574.                     init_textring(&temp_ring);
  1575.                     col = new_col(name, (int)strlen(name));
  1576.                     col_insert(&(temp_ring.head), col);
  1577.                     blk_paste(t_ptr, &temp_ring);
  1578.                     restore_edit();
  1579.                     kill_textring(&temp_ring);
  1580.                 }
  1581.                 else                                /* Dateiinhalt einfügen */
  1582.                 {
  1583.                     TEXTP temp_ptr = new_text(TEMP_LINK);
  1584.                     int    antw;
  1585.                     
  1586.                     if (temp_ptr!=NULL)
  1587.                     {
  1588.                         set_text_name(temp_ptr, name, FALSE);
  1589.                         antw = load(temp_ptr, TRUE);
  1590.                         if (antw == 0)
  1591.                         {
  1592.                             if (t_ptr->loc_opt->umbrechen)
  1593.                             {
  1594.                                 temp_ptr->loc_opt = t_ptr->loc_opt;
  1595.                                 make_absatz(temp_ptr);
  1596.                                 if (temp_ptr->loc_opt->format_by_load)
  1597.                                     total_format(temp_ptr);
  1598.                             }
  1599.                             blk_paste(t_ptr,&(temp_ptr->text));
  1600.                             restore_edit();
  1601.                         }
  1602.                         else
  1603.                             open_error(name, antw);
  1604.                         destruct_text(temp_ptr);
  1605.                     }
  1606.                 }
  1607.             }
  1608.             erg = 1;
  1609.             break;
  1610.         case DO_UPDATE    :
  1611.             /* Schreibschutz oder Datei verändert? */
  1612.             if (file_exists(t_ptr->filename))
  1613.             {
  1614.                 bool    read_only = file_readonly(t_ptr->filename);
  1615.  
  1616.                 if (read_only!=t_ptr->readonly)
  1617.                 {
  1618.                     t_ptr->readonly = read_only;
  1619.                     make_chg(icon,POS_CHANGE,0);        /* Headline schreiben */
  1620.                     restore_edit();
  1621.                 }
  1622.                 if (t_ptr->file_date_time!=-1L)
  1623.                 {
  1624.                     long date_time = file_time(t_ptr->filename,NULL,NULL);
  1625.  
  1626.                     if (date_time!=t_ptr->file_date_time)
  1627.                     {
  1628.                         FILENAME    name;
  1629.  
  1630.                         file_name(t_ptr->filename, name, FALSE);
  1631.                         if (snote(1, 2, MOVED3, name) == 1)
  1632.                             goto abandon;
  1633.                         else
  1634.                             t_ptr->file_date_time = date_time;
  1635.                     }
  1636.                 }
  1637.             }
  1638.             /* Kürzel updaten */
  1639.             ch_kurzel(t_ptr->loc_opt->kurzel, FALSE);
  1640.             erg = 1;
  1641.             break;
  1642.         case DO_ZEICHTAB:
  1643.             if (ascii_wert != -1 )
  1644.                 char_insert(t_ptr, ascii_wert);
  1645.             restore_edit();
  1646.             erg = 1;
  1647.             break;
  1648.         case DO_UMLAUT:
  1649.             change_umlaute(t_ptr);
  1650.             erg = 1;
  1651.             break;
  1652.         case DO_SWAPCHAR:
  1653.             char_swap(t_ptr);
  1654.             restore_edit();
  1655.             break;
  1656.         case DO_AUTOSAVE:
  1657.             e_icon_edit(icon, DO_SAVE);
  1658.             break;
  1659.         case DO_FEHLER :
  1660.             if (error[0][0] != EOS)
  1661.             {
  1662.                 blk_demark(t_ptr);
  1663.                 restore_edit();
  1664.                 handle_error(t_ptr);
  1665.             }
  1666.             break;
  1667.         case DO_TOPLINE :
  1668.             arrow_window(window, WA_DNLINE, t_ptr->ypos - window->doc.y);
  1669.             break;
  1670.         case DO_SORT :
  1671.             sort_block(t_ptr);
  1672.             break;
  1673.     }
  1674.     return erg;
  1675. }
  1676.  
  1677. /***************************************************************************/
  1678. /* Es wurde etwas auf ein Textfenster geschoben                                        */
  1679. /***************************************************************************/
  1680.  
  1681. static bool e_icon_drag(int icon, int source)
  1682. {
  1683.     WINDOWP    w = get_window(icon);
  1684.     TEXTP     t_ptr;
  1685.     bool        ret = FALSE;
  1686.  
  1687.      if ((w->flags & WI_ICONIFIED) || (w->flags & WI_SHADED))
  1688.          return FALSE;
  1689.  
  1690.     switch (source)
  1691.     {
  1692.         case DRAGDROP_FILE :                        /* Inhalt von drag_filename einfügen */
  1693.             t_ptr = get_text(icon);
  1694.             if (drag_filename[0] != EOS && t_ptr != NULL)
  1695.             {
  1696.                 TEXTP temp_ptr = new_text(TEMP_LINK);
  1697.                 int    antw;
  1698.                 
  1699.                 if (temp_ptr!=NULL)
  1700.                 {
  1701.                     set_text_name(temp_ptr, drag_filename, FALSE);
  1702.                     antw = load(temp_ptr, TRUE);
  1703.                     if (antw == 0)
  1704.                     {
  1705.                         blk_paste(t_ptr,&(temp_ptr->text));
  1706.                         restore_edit();
  1707.                     }
  1708.                     else
  1709.                         open_error(drag_filename, antw);
  1710.                     destruct_text(temp_ptr);
  1711.                     ret = TRUE;
  1712.                 }
  1713.             }
  1714.             drag_filename[0] = EOS;
  1715.             break;
  1716.  
  1717.         case DRAGDROP_PATH :                        /* Text aus drag_filename einfügen */
  1718.             t_ptr = get_text(icon);
  1719.             if (drag_filename[0] != EOS && t_ptr != NULL)
  1720.             {
  1721.                 if ((t_ptr->cursor_line->len + (int)strlen(drag_filename)) < MAX_LINE_LEN)
  1722.                 {
  1723.                     RING        temp_ring;
  1724.                     ZEILEP    col;
  1725.                         
  1726.                     init_textring(&temp_ring);
  1727.                     col = new_col(drag_filename, (int)strlen(drag_filename));
  1728.                     col_insert(&(temp_ring.head), col);
  1729.                     if (drag_data_size > 1)
  1730.                     {
  1731.                         /* mehr als ein ARGS -> Zeilenvorschub */
  1732.                         col = new_col("", 0);
  1733.                         col_append(&temp_ring, col);
  1734.                     }
  1735.                     blk_paste(t_ptr, &temp_ring);
  1736.                     restore_edit();
  1737.                     kill_textring(&temp_ring);
  1738.                     ret = TRUE;
  1739.                 }
  1740.                 else
  1741.                     inote(1, 0, TOOLONG, MAX_LINE_LEN);
  1742.             }
  1743.             drag_filename[0] = EOS;
  1744.             break;
  1745.  
  1746.         case DRAGDROP_DATA :                        /* Textdaten einfügen */
  1747.             if (drag_data_size == DDS_RINGP)
  1748.             {
  1749.                 RINGP    t;
  1750.                 
  1751.                 t_ptr = get_text(icon);
  1752.                 t = (RINGP)drag_data;
  1753.                 blk_paste(t_ptr, t);
  1754.                 restore_edit();
  1755.                 kill_textring(t);
  1756.                 drag_data = NULL;
  1757.                 drag_data_size = 0;
  1758.             }
  1759.             else
  1760.             if (drag_data_size > 0 && drag_data != NULL)
  1761.             {
  1762.                 RING        temp_ring;
  1763.                 ZEILEP    col;
  1764.                 char        *p1, *p2, *zeile;
  1765.                 long        delta;
  1766.                 ZEILEP    lauf;
  1767.  
  1768. debug("hier ist edit.DragDrop_DATA!!!\n");
  1769.                 t_ptr = get_text(icon);
  1770.                 init_textring(&temp_ring);
  1771.                 lauf = &temp_ring.head;
  1772.                 p1 = drag_data;
  1773.                 p2 = strchr(p1, '\r');
  1774.                 if (p2 != NULL)                            /* mehrere Zeilen? */
  1775.                 {
  1776.                     zeile = (char *) malloc(MAX_LINE_LEN);
  1777.                     while (p2 != NULL)
  1778.                     {
  1779.                         delta = p2 - p1;
  1780.                         strncpy(zeile, p1, delta);
  1781.                         zeile[delta] = EOS;
  1782.                         col = new_col(zeile, (int)strlen(zeile));
  1783.                         col_insert(lauf, col);
  1784.                         NEXT(lauf);
  1785.                         p1 = p2 + 2;                        /* \r\n überspringen */
  1786.                         p2 = strchr(p1, '\r');
  1787.                         temp_ring.lines++;
  1788.                     }
  1789.                     free(zeile);
  1790.                 }
  1791.                 else                                            /* nur eine Zeile ohne \r\n */
  1792.                 {
  1793.                     col = new_col(drag_data, (int)strlen(drag_data));
  1794.                     col_insert(lauf, col);
  1795.                 }
  1796.                 blk_paste(t_ptr, &temp_ring);
  1797.                 restore_edit();
  1798.                 kill_textring(&temp_ring);
  1799.                 free(drag_data);                            /* Speicher wieder freigeben */
  1800.                 drag_data_size = 0L;
  1801.                 ret = TRUE;
  1802.             }
  1803.             break;
  1804.  
  1805.         default:
  1806.             if (debug_level)
  1807.                 debug("edit.e_icon_drag(): Unbekannter Mode %d\n", source);
  1808.     }
  1809.  
  1810.     return ret;
  1811. }
  1812.  
  1813. /***************************************************************************/
  1814.  
  1815. void blink_edit(void)
  1816. {
  1817.     WINDOWP    window;
  1818.     TEXTP     t_ptr;
  1819.  
  1820.     window = winlist_top();
  1821.     if (window!=NULL && window->class==CLASS_EDIT)
  1822.     {
  1823.         t_ptr = get_text(window->handle);
  1824.         if (t_ptr->cursor)
  1825.         {
  1826.             if (t_ptr->blink)         /* gerade wg. Blinken aus */
  1827.                 t_ptr->blink = FALSE;
  1828.             else
  1829.                 t_ptr->blink = TRUE;
  1830.             cursor(window,t_ptr);
  1831.         }
  1832.     }
  1833. }
  1834.  
  1835. void onblink_edit(void)
  1836. {
  1837.     WINDOWP    window;
  1838.     TEXTP     t_ptr;
  1839.  
  1840.     window = winlist_top();
  1841.     if (window!=NULL && window->class==CLASS_EDIT)
  1842.     {
  1843.         t_ptr = get_text(window->handle);
  1844.         if (t_ptr->cursor)
  1845.         {
  1846.             cursor(window,t_ptr);
  1847.             t_ptr->blink = FALSE;
  1848.         }
  1849.     }
  1850. }
  1851.  
  1852. void offblink_edit(void)
  1853. {
  1854.     WINDOWP    window;
  1855.     TEXTP     t_ptr;
  1856.  
  1857.     window = winlist_top();
  1858.     if (window!=NULL && window->class==CLASS_EDIT)
  1859.     {
  1860.         t_ptr = get_text(window->handle);
  1861.         if (t_ptr->cursor && !t_ptr->blink)
  1862.         {
  1863.             cursor(window,t_ptr);
  1864.         }
  1865.     }
  1866. }
  1867.  
  1868. /***************************************************************************/
  1869. /* Tastenverarbeitung                                                                        */
  1870. /***************************************************************************/
  1871. void make_chg (int link, int change, long ypos)
  1872. {
  1873. /*
  1874.     SCROLL_UP         Alles unter der aktuellen Zeile wird hochgescrollt,
  1875.                         die letzte Zeile wird natürlich neu geschrieben.
  1876.                           (Cntrl-Y, und Delete am Ende der Zeile).
  1877.     SCROLL_DOWN        Alles unterhalb der aktuellen Zeile und diese Zeile werden
  1878.                         nach unten gescrollt, die aktuelle Zeile wird neu
  1879.                         geschrieben. Ist auch LINE_CHANGE gesetzt wird auch die
  1880.                         Zeile vor der aktuellen Zeile neu geschrieben.
  1881.                         (RETURN, last_out_klemm)
  1882.     MOVE_UP,
  1883.     MOVE_DOWN        Das Fenster wird hoch und runter gescrollt um anz Zeilen
  1884.     BLK_CHANGE        Die Blockmarkierung wurde geändert.
  1885.     WT_CHANGE        Fenstertitel ('*') löschen (nach save).
  1886. */
  1887.     int i;
  1888.  
  1889.     if (change==TOTAL_CHANGE)
  1890.     {
  1891.         for (i=chg_anz; (--i)>=0; )            /* unnützte Änderung */
  1892.             if (chg[i].link==link)
  1893.             {
  1894.                 if (chg[i].c==LINE_CHANGE && chg[i].y>=ypos)
  1895.                     chg[i].c = NOP_CHANGE;
  1896.                 else if (chg[i].c==SCROLL_DOWN && chg[i].y>=ypos)
  1897.                     chg[i].c = NOP_CHANGE;
  1898.                 else if (chg[i].c==SCROLL_UP && chg[i].y>=ypos)
  1899.                     chg[i].c = NOP_CHANGE;
  1900.                 else if (chg[i].c==TOTAL_CHANGE && chg[i].y>=ypos)
  1901.                 {
  1902.                     chg[i].y = ypos;
  1903.                     break;
  1904.                 }
  1905.             }
  1906.     }
  1907.     if (change==LINE_CHANGE)
  1908.     {
  1909.         for (i=chg_anz; (--i)>=0; )            /* gleiche Änderung */
  1910.             if (chg[i].link==link && chg[i].c==change && chg[i].y==ypos)
  1911.                 return;
  1912.     }
  1913.     if (change==POS_CHANGE)
  1914.     {
  1915.         for (i=chg_anz; (--i)>=0; )
  1916.             if (chg[i].link==link && chg[i].c==change)
  1917.                 return;
  1918.     }
  1919.     if (chg_anz>=MAX_CHG)
  1920.     {
  1921.         inote(1, 0, FATALERR,0);
  1922.         return;
  1923.     }
  1924.     chg[chg_anz].link = link;
  1925.     chg[chg_anz].c = change;
  1926.     chg[chg_anz].y = ypos;
  1927.     setincl(chg_links,link);
  1928.     chg_anz++;
  1929. }
  1930.  
  1931. void pos_korr(WINDOWP window, TEXTP t_ptr)
  1932. {
  1933.     int    x_new;
  1934.     long    y_new;
  1935.  
  1936.     y_new = t_ptr->ypos - window->doc.y;
  1937.     if (y_new < 0L)
  1938.     {
  1939.         if (y_new == -1L)
  1940.             arrow_window(window, WA_UPLINE, 1);
  1941.         else
  1942.             arrow_window(window, WA_UPLINE, window->w_height/2-y_new);
  1943.     }
  1944.     else if (y_new >= window->w_height)
  1945.     {
  1946.         if (y_new == window->w_height)
  1947.             arrow_window(window, WA_DNLINE, 1);
  1948.         else
  1949.             arrow_window(window, WA_DNLINE, y_new-window->w_height/2);
  1950.     }
  1951.  
  1952.     x_new = cursor_xpos(t_ptr, t_ptr->xpos) - (int) window->doc.x * font_wcell;
  1953.     if (x_new < 0)
  1954.         arrow_window(window, WA_LFLINE, -(x_new/font_wcell) + window->w_width/2);
  1955.     else if (x_new >= window->work.g_w)
  1956.         arrow_window(window, WA_RTLINE, (x_new-window->work.g_w)/font_wcell + window->w_width/2);
  1957. }
  1958.  
  1959. /*
  1960.  * Neuzeichnen, wenn Fenster teilweise verdeckt.
  1961.  * z.B. bei D&D
  1962. */
  1963. static void restore_offdesk(WINDOWP window, TCHANGE *c, int c_anz, TEXTP t_ptr)
  1964. {
  1965.     int        y_screen;
  1966.     bool    done = FALSE;
  1967.     GRECT        a;
  1968.  
  1969.     for (; (--c_anz)>=0; c++)
  1970.     {
  1971.         switch (c->c)
  1972.         {
  1973.             case WT_CHANGE :    /* für save(): nur '*' löschen, sonst nix */
  1974.                 change_window(window, t_ptr->filename, (t_ptr->moved!=0));
  1975.                 break;
  1976.  
  1977.             case POS_CHANGE     :
  1978.                 if (window->class==CLASS_EDIT)
  1979.                 {
  1980.                     a = window->work;
  1981.                     a.g_h = gl_hchar;
  1982.                     redraw_window(window, &a);
  1983.                 }
  1984.                 change_window(window, t_ptr->filename, (t_ptr->moved!=0));
  1985.                 pos_korr(window, t_ptr);
  1986.                 break;
  1987.  
  1988.             case LINE_CHANGE:
  1989.                 y_screen = (int) (c->y - window->doc.y);
  1990.                 if (y_screen>=0 && y_screen<window->w_height)
  1991.                 {
  1992.                     a = window->work;
  1993.                     a.g_y += y_screen * window->yfac;
  1994.                     a.g_h = window->yfac;
  1995.                     redraw_window(window, &a);
  1996.                 }
  1997.                 break;
  1998.  
  1999.             case TOTAL_CHANGE  :
  2000.             case BLK_CHANGE     :
  2001.             case SCROLL_UP      :
  2002.             case SCROLL_DOWN :
  2003.                 if (!done)
  2004.                     redraw_window(window, &window->work);
  2005.                 done = TRUE;
  2006.                 break;
  2007.  
  2008.             case MOVE_UP:
  2009.                 arrow_window(window, WA_DNLINE, c->y);
  2010.                 break;
  2011.  
  2012.             case MOVE_DOWN:
  2013.                 arrow_window(window, WA_UPLINE, c->y);
  2014.                 break;
  2015.         }
  2016.     }
  2017. }
  2018.  
  2019. /*
  2020.  * Neuzeichnen, wenn Fenster komplett frei.
  2021. */
  2022. static void restore_indesk(WINDOWP window, TCHANGE *c, int c_anz, TEXTP t_ptr)
  2023. {
  2024.     GRECT    a;
  2025.     int    y_screen, help;
  2026.     long    z1,z2;
  2027.  
  2028.     for (; (--c_anz)>=0; c++)
  2029.     {
  2030.         set_clip(TRUE, &(window->work));
  2031.         switch (c->c)
  2032.         {
  2033.             case WT_CHANGE:                /* nur '*' ändern, sonst nix */
  2034.                 change_window(window, t_ptr->filename, (t_ptr->moved!=0));
  2035.                 break;
  2036.  
  2037.             case POS_CHANGE:
  2038.                 if (window->class == CLASS_EDIT)
  2039.                     head_out(window, t_ptr);
  2040.                 change_window(window, t_ptr->filename, (t_ptr->moved!=0));
  2041.                 pos_korr(window, t_ptr);
  2042.                 break;
  2043.  
  2044.             case LINE_CHANGE:
  2045.                 y_screen = (int)(c->y - window->doc.y);
  2046.                 if (y_screen < window->w_height)
  2047.                     line_out(window, t_ptr, y_screen);
  2048.                 break;
  2049.  
  2050.             case TOTAL_CHANGE:
  2051.                 y_screen = (int) (c->y - window->doc.y);
  2052.                 bild_out(window,t_ptr);
  2053.                 break;
  2054.  
  2055.             case SCROLL_UP:
  2056.                 y_screen = (int) (c->y - window->doc.y);
  2057.                 if (y_screen < window->w_height-1)
  2058.                 {
  2059.                     help = window->yfac*(y_screen+1);
  2060.                     a = window->work;
  2061.                     a.g_h -= help;
  2062.                     a.g_y += help;
  2063.                     scroll_vertical (&a, window->yfac);
  2064.                 }
  2065.                 if (y_screen < window->w_height)
  2066.                     line_out(window, t_ptr, window->w_height-1);
  2067.                 break;
  2068.  
  2069.             case SCROLL_DOWN:
  2070.                 y_screen = (int) (c->y - window->doc.y);
  2071.                 if (y_screen < window->w_height-1)
  2072.                 {
  2073.                     a = window->work;
  2074.                     a.g_h -= window->yfac * (y_screen + 1);
  2075.                     a.g_y += window->yfac * y_screen;
  2076.                     scroll_vertical (&a, -window->yfac);
  2077.                 }
  2078.                 /* Die neue Zeile wird mit LINE_CHANGE gezeichnet */
  2079.                 break;
  2080.  
  2081.             case MOVE_UP:
  2082.                 arrow_window(window, WA_DNLINE, c->y);
  2083.                 break;
  2084.  
  2085.             case MOVE_DOWN:
  2086.                 arrow_window(window, WA_UPLINE, c->y);
  2087.                 break;
  2088.  
  2089.             case BLK_CHANGE:
  2090.                 z1 = c->y;
  2091.                 c++; c_anz--;
  2092.                 z2 = c->y;
  2093.                 bild_blkout(window,t_ptr,z1,z2);
  2094.                 break;
  2095.         }
  2096.     }
  2097. }
  2098.  
  2099. void restore_edit(void)
  2100. {
  2101.     WINDOWP    window;
  2102.     TEXTP     t_ptr;
  2103.     int        i, c_anz, link, max;
  2104.     TCHANGE    c[MAX_CHG], *c_ptr;
  2105.     
  2106.     if (!chg_anz) 
  2107.         return;
  2108.  
  2109.     hide_mouse();
  2110.     max = setmax(chg_links);
  2111.     for (link = setmin(chg_links); link <= max; link++) 
  2112.     {
  2113.         if(setin(chg_links,link))
  2114.         {
  2115.             window = get_window(link);
  2116.             if (window == NULL) 
  2117.                 continue;                                /* Kommt vor (Prj_Text mit 10001) */
  2118.             c_anz = 0;
  2119.             c_ptr = chg;
  2120.             for (i=chg_anz; (--i)>=0; c_ptr++)
  2121.                 if (c_ptr->link==link && c_ptr->c!=NOP_CHANGE)
  2122.                     c[c_anz++] = *c_ptr;
  2123.     
  2124.             t_ptr = get_text(window->handle);
  2125.  
  2126.             /* Slider anpassen */
  2127.             if (window->doc.h != t_ptr->text.lines)
  2128.             {
  2129.                 window->doc.h = t_ptr->text.lines;
  2130.                 set_sliders(window, VERTICAL, SLPOS+SLSIZE);
  2131.             }
  2132.  
  2133.             get_longestline(t_ptr);
  2134.             if (window->doc.w != t_ptr->max_line->exp_len)
  2135.             {
  2136.                 window->doc.w = t_ptr->max_line->exp_len;
  2137.                 set_sliders(window, HORIZONTAL, SLPOS+SLSIZE);
  2138.             }    
  2139.  
  2140.             if ((window->flags & WI_OPEN) || (window->flags & WI_ICONIFIED))
  2141.             {
  2142.                 if (free_for_draw(window))
  2143.                     restore_indesk(window, c, c_anz, t_ptr);
  2144.                 else
  2145.                     restore_offdesk(window, c, c_anz, t_ptr);
  2146.             }
  2147.         }
  2148.     }
  2149.     show_mouse();
  2150.     chg_anz = 0;            /* Keine Änderungen mehr */
  2151.     setclr(chg_links);
  2152. }
  2153.  
  2154. /***************************************************************************/
  2155. static void destruct(int icon)
  2156. {
  2157.     TEXTP t_ptr = get_text(icon);
  2158.     WINDOWP window = get_window(icon);
  2159.  
  2160.     insert_poslist(&lastpos_list, t_ptr->filename, t_ptr->xpos, t_ptr->ypos);
  2161.  
  2162.     /* Text war Error-Datei */
  2163.     if (t_ptr == last_errtext)
  2164.         last_errtext = NULL;
  2165.  
  2166.     close_window(window);
  2167.     destruct_text(t_ptr);
  2168.     del_icon(icon);
  2169.     setexcl(used_info,icon);
  2170.     clr_undo();
  2171.     do_all_icon(prj_type, DO_UPDATE);        /* Projekte updaten */
  2172. }
  2173.  
  2174. /***************************************************************************/
  2175.  
  2176. static int crt_new_text(char *filename, bool bin)
  2177. {
  2178.     TEXTP         t_ptr;
  2179.     WINDOWP        win;
  2180.     PATH            name;
  2181.     bool        namenlos;
  2182.  
  2183.     if (filename[0] == EOS)
  2184.     {
  2185.         strcpy(name, rsc_string(NAMENLOS));
  2186.         namenlos = TRUE;
  2187.     }
  2188.     else
  2189.     {
  2190.         strcpy(name, filename);
  2191.         namenlos = FALSE;
  2192.     }
  2193.     
  2194.     /* Fenster anlegen */
  2195.     win = create_window(KIND, CLASS_EDIT, crt_edit);
  2196.     if (win == NULL)
  2197.         return -1;
  2198.     if (!add_icon(edit_type, win->handle))
  2199.         return -1;
  2200.  
  2201.     /* Text kreiern */
  2202.     t_ptr = new_text(win->handle);
  2203.     if (t_ptr == NULL)
  2204.     {
  2205.         del_icon(win->handle);
  2206.         return -1;
  2207.     }
  2208.  
  2209.     if (bin)
  2210.     {
  2211.         t_ptr->text.ending = binmode;
  2212.         t_ptr->text.max_line_len = bin_line_len;
  2213.     }
  2214.     else
  2215.         t_ptr->text.max_line_len = MAX_LINE_LEN;
  2216.  
  2217.     set_text_name(t_ptr, name, namenlos);
  2218.     setincl(used_info, win->handle);
  2219.  
  2220.     set_wtitle(win, name);
  2221.     set_winfo(win, "");
  2222.     
  2223.     if (!namenlos)
  2224.         do_all_icon(prj_type, DO_UPDATE);                /* Projekte updaten */
  2225.  
  2226.     t_ptr->asave = time(NULL);
  2227.  
  2228.     return win->handle;
  2229. }
  2230.  
  2231. /***************************************************************************/
  2232. /* Kreieren eines Fensters                                                                 */
  2233. /***************************************************************************/
  2234. static void crt_edit(WINDOWP window)
  2235. {
  2236.     int        initw, inith;
  2237.  
  2238.     if (window->work.g_w == 0 || window->work.g_h == 0)
  2239.     {
  2240.         /* Keine Grö₧e bekannt. */
  2241.         initw  = min ((gl_desk.g_w / font_wcell) * font_wcell - 7 * font_wcell, 80 * font_wcell);
  2242.         inith  = (gl_desk.g_h / font_hcell) * font_hcell - 7 * font_hcell;
  2243.     
  2244.         window->work.g_x    = gl_wchar + 2 * 8;
  2245.         window->work.g_y    = 60;
  2246.         window->work.g_w    = initw;
  2247.         window->work.g_h    = inith;
  2248.     }
  2249.     
  2250.     window->flags        = FLAGS;
  2251.     window->doc.w        = 0;
  2252.     window->doc.h        = 0;
  2253.     window->xfac        = font_wcell;
  2254.     window->yfac        = font_hcell;
  2255.     window->w_width    = initw/font_wcell;
  2256.     window->w_height    = inith/font_hcell;
  2257.     window->draw        = wi_draw;
  2258.     window->click        = wi_click;
  2259.     window->key         = wi_key;
  2260.     window->top            = wi_top;
  2261.     window->ontop        = wi_top;
  2262.     window->iconify    = wi_iconify;
  2263.     window->uniconify    = wi_uniconify;
  2264.     window->close        = NULL;
  2265. }
  2266.  
  2267. /***************************************************************************/
  2268. /* Öffnen des Objekts                                                                        */
  2269. /***************************************************************************/
  2270. static bool open_edit(int icon)
  2271. {
  2272.     bool    ok;
  2273.     WINDOWP    window = get_window(icon);
  2274.  
  2275.     ok = TRUE;
  2276.  
  2277.     if (window->flags & WI_ICONIFIED)
  2278.         uniconify_window(window, NULL);
  2279.     else if (window->flags & WI_SHADED)
  2280.         shade_window(window, -1);
  2281.     else if (window->flags & WI_OPEN)
  2282.         top_window(window);
  2283.     else
  2284.     {
  2285.         TEXTP t_ptr = get_text(window->handle);
  2286.  
  2287.         window->doc.x = 0;
  2288.         window->doc.y = 0;
  2289.         window->doc.h = t_ptr->text.lines;
  2290.         pos_korr(window, t_ptr);
  2291.         ok = open_window (window);
  2292.         ch_kurzel(t_ptr->loc_opt->kurzel, FALSE);
  2293.     }
  2294.     return ok;
  2295. }
  2296.  
  2297. /***************************************************************************/
  2298. /* Info des Objekts                                                                            */
  2299. /***************************************************************************/
  2300. bool info_edit (int icon)
  2301. {
  2302.     char            str[32], date[11];
  2303.     TEXTP         t_ptr = get_text(icon);
  2304.     int            erg;
  2305.     LINEENDING    ending;
  2306.     bool            b;
  2307.     
  2308.     set_long(textinfo, INFBYTES, textring_bytes(&t_ptr->text));
  2309.     if (t_ptr->text.ending != binmode)
  2310.         set_long(textinfo, INFZEILE, t_ptr->text.lines);
  2311.     else
  2312.         set_string(textinfo, INFZEILE, "--");        /* Binär: keine Zeilen */
  2313.  
  2314.     make_shortpath(t_ptr->filename, str, 30);
  2315.     set_string (textinfo, INFNAME, str);        /* Name mit Pfad */
  2316.     if (t_ptr->namenlos)
  2317.     {
  2318.         strcpy(str, "");
  2319.         strcpy(date, "--");
  2320.     }
  2321.     else
  2322.         file_time (t_ptr->filename, date, str);
  2323.     set_string(textinfo, INFDATUM, date);     /* Datum */
  2324.     set_string(textinfo, INFZEIT, str);        /* Uhrzeit */
  2325.  
  2326.     set_state(textinfo, INFTOS, SELECTED, (t_ptr->text.ending == tos));
  2327.     set_state(textinfo, INFUNIX, SELECTED, (t_ptr->text.ending == unix));
  2328.     set_state(textinfo, INFMAC, SELECTED, (t_ptr->text.ending == apple));
  2329.     ending = t_ptr->text.ending;
  2330.  
  2331.     /* Dateien aus einem Projekt oder Binär -> kein Zeilenende */
  2332.     b = (!setin(used_info, icon) || (t_ptr->text.ending == binmode));
  2333.     set_state(textinfo, INFTOS, DISABLED, b);
  2334.     set_state(textinfo, INFUNIX, DISABLED, b);
  2335.     set_state(textinfo, INFMAC, DISABLED, b);
  2336.  
  2337.     erg = simple_mdial(textinfo, 0) & 0x7fff;
  2338.     if (erg == INFOK)
  2339.     {
  2340.         if (get_state(textinfo, INFTOS, SELECTED))
  2341.             t_ptr->text.ending = tos;
  2342.         if (get_state(textinfo, INFUNIX, SELECTED))
  2343.             t_ptr->text.ending = unix;
  2344.         if (get_state(textinfo, INFMAC, SELECTED))
  2345.             t_ptr->text.ending = apple;
  2346.  
  2347.         if (t_ptr->text.ending != ending)
  2348.         {
  2349.             t_ptr->moved++;
  2350.             make_chg(t_ptr->link, POS_CHANGE, 0);     /* Damit Infozeile einen '*' bekommt */
  2351.             restore_edit();
  2352.         }
  2353.     }
  2354.     return TRUE;
  2355. }
  2356.  
  2357. void init_edit(void)
  2358. {
  2359.     setclr(chg_links);
  2360.     setclr(used_info);
  2361.     drag_filename[0] = EOS;
  2362.     edit_type = decl_icon_type(e_icon_test, e_icon_edit, e_icon_exist, e_icon_drag);
  2363. }
  2364.  
  2365. void    cursor_off(int wHandle)
  2366. {
  2367.     WINDOWP    window;
  2368.     TEXTP     t_ptr;
  2369.  
  2370.     window = get_window(wHandle);
  2371.     if (window!=NULL && window->class==CLASS_EDIT)
  2372.     {
  2373.         t_ptr = get_text(window->handle);
  2374.         if (t_ptr->cursor)
  2375.             t_ptr->cursor = FALSE;
  2376.     }
  2377. }
  2378.  
  2379. void    cursor_on(int wHandle)
  2380. {
  2381.     WINDOWP    window;
  2382.     TEXTP     t_ptr;
  2383.  
  2384.     window = get_window(wHandle);
  2385.     if (window!=NULL && window->class==CLASS_EDIT)
  2386.     {
  2387.         t_ptr = get_text(window->handle);
  2388.         if (!t_ptr->cursor)
  2389.             t_ptr->cursor = TRUE;
  2390.     }
  2391. }
  2392.  
  2393. void set_info(TEXTP t_ptr, char *str)
  2394. {
  2395.     strcpy(t_ptr->info_str, str);
  2396. }
  2397.  
  2398. void clear_info(TEXTP t_ptr)
  2399. {
  2400.     if (t_ptr->info_str[0] != EOS)
  2401.         strcpy(t_ptr->info_str, "");
  2402. }
  2403.  
  2404. /***************************************************************************/
  2405. static void do_color_change(WINDOWP w)
  2406. {
  2407.     redraw_window(w, &w->work);
  2408. }
  2409.  
  2410. void color_change(void)
  2411. {
  2412.     vsf_color(vdi_handle, bg_color);
  2413.     vst_color(vdi_handle, fg_color);
  2414.     fill_color = bg_color;
  2415.     set_drawmode();
  2416.     
  2417.     /* Alle Fenster updaten */
  2418.     do_all_window(CLASS_ALL, do_color_change);
  2419. }
  2420.