home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / ehp14cs.zip / aus_3.c < prev    next >
C/C++ Source or Header  |  1995-09-09  |  74KB  |  1,727 lines

  1. /****************************************************************/
  2. /*                                                              */
  3. /*      MODUL:  aus_3.c                                         */
  4. /*                                                              */
  5. /*      FUNKTIONEN:                                             */
  6. /*              - do_control (Kontrollzeichen in Text einfg.)   */
  7. /*              - hndl_insert (Insert-Teil von do_inschar)      */
  8. /*              - hndl_overwrite (Overwrite-Teil von do_inschar)*/
  9. /*              - do_linebreak (automatischer Zeilenumbruch)    */
  10. /*              - do_inschar (Zeichen in Text einfuegen)        */
  11. /*              - do_tog_tkm (Tabkomprimierungsmodus togglen)   */
  12. /*              - do_tog_bak (Backupfileerzeugungsmodus togglen)*/
  13. /*              - do_tog_ai (Autoindentmodus togglen)           */
  14. /*              - do_tog_lb (Linebreakmodus togglen)            */
  15. /*              - do_togregex (Reguläre Ausdrücke togglen)      */
  16. /*              - do_movewin (Fensterbewegung kontrollieren)    */
  17. /*              - do_toggle_size (Fenster auf gespeicherte Gr.) */
  18. /*              - do_sizewin (Fenstergroessenanpassung kontr.)  */
  19. /*              - do_swnext (Zum "Nachfolger" des akt. Fensters)*/
  20. /*              - do_swprev (Zum Vorgaenger des akt. Fensters)  */
  21. /*              - do_swnum (Window absolut anspringen)          */
  22. /*              - do_repeat (Funktion mehrmals ausfuehren)      */
  23. /*              - do_blstart (Blockanfang setzen)               */
  24. /*              - do_blnormend (Blockende (normal) setzen)      */
  25. /*              - do_blrechtend (Blockende (Rechteck) setzen)   */
  26. /*              - do_blunmark (Blockmarkierung loeschen)        */
  27. /*              - do_blweg (Block loeschen)                     */
  28. /*              - do_blcopy (Block kopieren)                    */
  29. /*              - do_blmove (Block verschieben)                 */
  30. /*              - do_blcut (Block in PASTE-Puffer kopieren)     */
  31. /*              - do_blpaste (PASTE-Puffer in Text einfuegen)   */
  32. /*              - do_blindent (Block einruecken)                */
  33. /*              - do_blread (Block einlesen)                    */
  34. /*              - do_blwrite (Block schreiben)                  */
  35. /*              - do_goblend (Zum Blockende gehen)              */
  36. /*              - do_goblanf (Zum Blockanfang gehen)            */
  37. /*              - do_bltofil (Block an Filter uebergeben)       */
  38. /*              - do_toghbl (Blockhervorhebungsmodus togglen)   */
  39. /*              - do_shelltog (Shellflag invertieren)           */
  40. /*              - do_setmarker (Marker setzen)                  */
  41. /*              - do_jumpmarker (Marker anspringen)             */
  42. /*              - do_lastpos (Letzte Position anspringen)       */
  43. /*              - do_swname (Window gemaess Name suchen)        */
  44. /*              - do_newname (Datei unter neuem Namen speichern)*/
  45. /*              - do_macro (Macro definieren/ausfuehren)        */
  46. /*              - do_restline (gelöschte Zeile wiederherstellen)*/
  47. /*              - do_saveall (alle geänderten Dateien sichern)  */
  48. /*              - do_reflow (Absatz neu ausrichten)             */
  49. /*              - auswertung (Tastendruck auswerten)            */
  50. /****************************************************************/
  51.  
  52. #include "defs.h"
  53. #include "keys.h"
  54.  
  55. void do_inschar();
  56.  
  57. extern char backupflag,highblockflag,clear_buff,bufflag;
  58. extern int schreib_file(),to_shell(),save_all();
  59. extern short int letter,lastcode,aktcode,mc_index,taste();
  60. extern int save_delline(),rest_delline();
  61. extern int tst_overlap();
  62. extern char bufflag,*loadfile,regexflag;
  63. extern bzeil_typ *save_normal(),*save_rechteck();
  64. extern block_typ global_block,*dup_block();
  65. extern puff_typ macro[],puff_feld[];
  66. extern int ks_index;
  67. extern short int *keystack,*e_keystack,newwgetch();
  68. extern WINDOW *status;
  69. extern marker_typ marker[];
  70. extern char *on_off[], /* Hilfstexte */
  71.                /* fuer Togglen der globalen Flags */
  72.         helpflag;  /* Flag: Hilfstexte anzeigen       */
  73.  
  74. extern int  do_newline();
  75. extern void do_refresh(), do_bol(), do_eol(), do_halfup(), do_halfdn(),
  76.         do_delete(), do_backspace(), do_home(), do_nothome(), 
  77.         do_insovr(), do_textbeginn(), do_eot(), do_del_word(), 
  78.         do_wleft(), do_wright(), do_right(), do_left(), do_up(), 
  79.         do_down(), do_pgup(), do_pgdn(), do_delline(),
  80.         ueberschreiben(), do_schreib_file(),quit(), do_help(),laden(), 
  81.         do_win_zu(), do_goto(), do_ende(), do_find(), do_replace(), 
  82.         do_underline(), do_z_hoch(), do_z_runter(), do_z_oben(), 
  83.         do_z_mitte(), do_z_unten(), do_deleol(), do_repfr(), do_repfr(), 
  84.         do_join(), do_open(), do_tab(), do_settab(), do_hopen(), 
  85.         do_backtab(), do_endemit(),quitmit(), do_find(), do_repfr(), 
  86.         do_replace(), do_matchpar(), do_middle();
  87.  
  88.  
  89. /*****************************************************************************
  90. *
  91. *  Funktion       Kontrollzeichen in Text (do_control)
  92. *  --------
  93. *
  94. *  Beschreibung : Es wird ein Zeichen mit getch() eingelesen und ueber die
  95. *                 Funktion do_inschar in den Text plaziert.
  96. *
  97. *****************************************************************************/
  98.  
  99. void do_control()
  100. {
  101.   /* *** interne Daten, Initialisierung *** */
  102.  
  103.   if(letter = newwgetch(akt_winp->winp)) /* Ein Zeichen lesen. Nur wenn es */
  104.     do_inschar();                   /* nicht '\0' ist, wird es eingefuegt. */
  105. }
  106.  
  107.  
  108. /*****************************************************************************
  109. *
  110. *  Funktion       Insert-Teil von do_inschar behandeln (hndl_insert)
  111. *  --------
  112. *
  113. *  Paramater    : restn     :
  114. *                   Typ         : int *
  115. *                   Wertebereich: Pointer auf Integer
  116. *                   Bedeutung   : Anzahl der Zeichen, die noch einge-
  117. *                                 fuegt werden muessen
  118. *
  119. *  Ergebnis     :
  120. *                   Typ         : int
  121. *                   Wertebereich: TRUE, FALSE
  122. *                   Bedeutung   : TRUE: hat geklappt
  123. *                                 FALSE: hat nicht geklappt
  124. *
  125. *  Beschreibung : Es wird versucht, Platz fuer die einzufuegenden Zeichen
  126. *                 zu schaffen. Gelingt es nicht, ein einziges Zeichen ein-
  127. *                 zufuegen, wird eine neue Zeile eingefuegt. Je nachdem ob
  128. *                 die aktuelle Zeile am Ende aufgespalten wurde oder nicht
  129. *                 wird mit dem Einfuegen in der aktuellen oder der neuen
  130. *                 Zeile fortgefahren.
  131. *
  132. *****************************************************************************/
  133.  
  134. int hndl_insert(restn)
  135. int *restn;
  136. {
  137.   /* *** interne Daten *** */
  138.   int hilf;
  139.  
  140.   /* Anzahl eingefuegter Zeichen merken und von restn abziehen */
  141.   *restn -= (hilf = insert (*restn));
  142.   if (!hilf)        /* wenn keine Zeichen eingefuegt werden konnten   */
  143.   {
  144.     if (!new_line())     /* neue Zeile einfuegen */
  145.     {
  146.       print_err(T_SIZE_ERRTEXT); /* klappte das nicht, Meldung aus- */
  147.       return(FALSE);             /* geben und Funktion beenden      */
  148.     }
  149.     if (akt_winp->autoindflag)   /* Eventuell aufgespaltene Zeile   */
  150.       indent_line(TRUE);         /* korrekt einruecken              */
  151.     if (akt_winp->alinep->text)  /* neue Zeile nicht leer?  */
  152.     {
  153.       up();                 /* in alte Zeile, da dort noch Platz */
  154.       eol();                        /* ans Ende */
  155.       if(insert(1))         /* wirklich noch Platz (kann nur  */
  156.       {
  157.     sw_ohne_refresh(W_AKT);
  158.     (*restn)--;         /* Fehler ergeben bei unterstr.Zchn.) ? */
  159.       }                     /* wenn nicht, schlaegt enter_char */
  160.     }                       /* fehl und do_newline wird aufgerufen */
  161.     else                    /* Wenn neue Zeile doch leer, testen ob */
  162.     {                       /* sich Cursor aus Fenster bewegt hat. */
  163.       if(akt_winp->ws_col > akt_winp->screencol) /* gegebenenfalls */
  164.     akt_winp->ws_col = akt_winp->screencol;  /* anpassen */
  165.       (*restn)--;           /* Neue Zeile ist leer, also kann ein */
  166.       sw_ohne_refresh(W_AKT);    /* Zeichen eingefuegt werden. */
  167.     } /* Fensterinhalt muss aber wegen eingefuegter Zeile neu */
  168.   }   /* angezeigt werden.                                    */
  169.   return(TRUE);
  170. }
  171.  
  172. /*****************************************************************************
  173. *
  174. *  Funktion       Overwrite-Teil von do_inschar behandeln (hndl_overwrite)
  175. *  --------
  176. *
  177. *  Paramater    : restn     :
  178. *                   Typ         : int *
  179. *                   Wertebereich: Pointer auf Integer
  180. *                   Bedeutung   : Anzahl der Zeichen, die noch einge-
  181. *                                 setzt werden muessen
  182. *
  183. *  Ergebnis     :
  184. *                   Typ         : int
  185. *                   Wertebereich: TRUE, FALSE
  186. *                   Bedeutung   : TRUE: hat geklappt
  187. *                                 FALSE: hat nicht geklappt
  188. *
  189. *  Beschreibung : Es wird getestet, ob Platz fuer die zu schreibenden Zeichen
  190. *                 vorhanden ist. Steht man am Zeilenende, wird versucht, in
  191. *                 die naechste Zeile zu gehen. Ist das nicht moeglich, wird
  192. *                 falls die maxlimale Zeilenanzahl noch nicht erreicht ist,
  193. *                 eine Zeile angehaengt. In der Zeile geht man an den Anfang.
  194. *                 Unterscheidet sich eines der zu ueberschreibenden Zeichen
  195. *                 von dem dazugehörigen einzusetzenden Zeichen in der Laenge
  196. *                 (eins unterstrichen, das andere nicht), dann werden alle
  197. *                 zu überschreibenden Zeichen gelöscht und für die neuen
  198. *                 Zeichen mit insert() Platz geschaffen.
  199. *
  200. *****************************************************************************/
  201.  
  202. int hndl_overwrite(restn)
  203. int *restn;
  204. {
  205.   /* *** interne Daten und Initialisierung *** */
  206.   char swflag = FALSE; /* Flag, ob Fenster neu zu zeichnen ist */
  207.   char u_diff=FALSE;   /* Flag: Einzutragendes Zeichen und zu überschrei- */
  208.                /* bendes Zeichen unterschiedlichen Unterstrcih-Mode */
  209.   int  anz_del=0,      /* Anzahl löschbarer Zeichen */
  210.        old_sc,         /* Zwischenspeicher Screencol */
  211.        old_tc;         /* Zwischenspeicher Textcol */
  212.  
  213.   if(akt_winp->screencol == MAXLENGTH) /* Steht man hinter Zeilenende? */
  214.   {
  215.     if(!down())      /* Eine Zeile runter. Klappt das nicht, dann */
  216.     {                /* testen, ob neue Zeile angehaengt werden kann */
  217.       if(akt_winp->maxline >= MAX_ANZ_LINES-1)
  218.       {
  219.     print_err(T_SIZE_ERRTEXT); /* wenn nein, Meldung ausgeben und raus */
  220.     return(FALSE);
  221.       }
  222.       koppel_line(); /* neue Zeile anhaengen. */
  223.       swflag = TRUE; /* Fensterinhalt ist neu zu zeichnen */
  224.     }
  225.     else
  226.       bol();           /* An den Anfang der Zeile springen */
  227.     if(akt_winp->ws_col)    /* Wenn erste Spalte nicht sichtbar, */
  228.     {                       /* dann sichtbar machen */
  229.       akt_winp->ws_col = 0;
  230.       swflag = TRUE;        /* Fensterinhalt muss neu gezeichnet werden */
  231.     }
  232.     if(swflag)
  233.       sw_ohne_refresh(W_AKT);
  234.   }
  235.  
  236.   fill_buff(); /* Zeile falls noch nicht drin, in Puffer kopieren */
  237.   old_tc = akt_winp->textcol;   /* Textcol und Screencol merken */
  238.   old_sc = akt_winp->screencol;
  239.   do
  240.   {
  241.     if(akt_winp->underflag ^ ul_char()) /* falls Zeichen verschiedene */
  242.                     /* Laengen haben */
  243.       u_diff = TRUE;  /* Merken, daa 2 Zeichen unterschiedlich waren */
  244.     anz_del++;        /* Anzahl zu löschender Zeichen inkrementieren */
  245.   } while (--(*restn) && right()); /* Solange wiederholen, bis alle */
  246.                /* Zeichen geprüft oder Zeilenende erreicht */
  247.   akt_winp->textcol = old_tc;    /* Textcol und Screencol restaurieren */
  248.   akt_winp->screencol = old_sc;
  249.  
  250.   if(u_diff)  /* Hatten 2 Zeichen unterschiedliche Länge ? */
  251.   {
  252.     mdelete(anz_del);       /* Zu überschreibende Zeichen loeschen */
  253.     insert(anz_del);        /* platz fuer neue Zeichen schaffen */
  254.   }
  255.   return(TRUE);
  256. }
  257.  
  258. /*****************************************************************************
  259. *
  260. *  Funktion       Auto. Zeilenumbruch durchführen (do_linebreak)
  261. *  --------
  262. *
  263. *  Ergebnis     :
  264. *                   Typ         : int
  265. *                   Wertebereich: TRUE, FALSE
  266. *                   Bedeutung   : TRUE: hat geklappt
  267. *                                 FALSE: hat nicht geklappt
  268. *
  269. *  Beschreibung : Von der aktuellen Position aus wird das nächste
  270. *                 Leerzeichen links vom Cursor gesucht. Wenn kein
  271. *                 Leerzeichen gefunden wird, wird FALSE zurückgegeben
  272. *                 und der Cursor wieder an seine alte Position gestellt.
  273. *                 Ansonsten wird der Cursor rechts des gefundenen
  274. *                 Leerzeichens positioniert und ein Zeilenumbruch
  275. *                 durchgeführt. Falls Autoindent aktiv ist, wird die neue
  276. *                 Zeile wie bei Reflowing eingerückt.
  277. *
  278. *****************************************************************************/
  279.  
  280. int do_linebreak()
  281. {
  282.   int x_r = akt_winp->screencol,  /* alte Cursorspalte merken   */
  283.       result = TRUE,              /* Rückgabewert               */
  284.       new_sc = x_r,               /* neue Cursorspalte          */
  285.       old_sc;                     /* Cursorspalte am Wortanfang */
  286.  
  287.   /* das nächste Blank zur linken suchen. */
  288.   do
  289.     left();
  290.   while (akt_zeichen() != ' ' && akt_winp->screencol > 0);
  291.   if (akt_zeichen() != ' ')    /* am linken Rand angekommen, und       */
  292.     result = FALSE;            /* am Zeilenanfang kein Blank,          */
  293.                    /* Dann FALSE zurückgeben               */
  294.                    /* scrollen, falls nötig                */
  295.   else
  296.   { /* Cursor steht jetzt auf einem Blank, rechts davon beginnt Wort */
  297.     right();                     /* auf Wortanfang stellen */
  298.     old_sc = akt_winp->screencol;
  299.     if (old_sc < akt_winp->ws_col)  /* Cursor links vom Rand, dann scrollen */
  300.     {
  301.       akt_winp->ws_col = old_sc;
  302.       show_win (W_AKT);
  303.     }
  304.     if (do_newline())              /* klappt Zeileneinfügen? */
  305.     {
  306.       /* Dann neue Cursorspalte entsprechend anpassen, */
  307.       if (akt_winp->insflag)       /* falls Insert-Mode aktiv war */
  308.       {
  309.     akt_winp->screencol = new_sc - old_sc + akt_winp->screencol;
  310.     adapt_screen (1);
  311.       }
  312.     }
  313.     else  /* new_line schlug fehl */
  314.     {
  315.       akt_winp->screencol = x_r; /* Cursor an alte Position fahren */
  316.       result = FALSE;
  317.     }
  318.   }
  319.   return result;
  320. }
  321.  
  322. /*****************************************************************************
  323. *
  324. *  Funktion       Zeichen in Text einfuegen (do_inschar)
  325. *  --------
  326. *
  327. *  Beschreibung : Entsprechend dem insflag wird das in letter stehende Zeichen
  328. *                 in den Text eingefuegt oder ueber den Text geschrieben.
  329. *
  330. *****************************************************************************/
  331.  
  332. void do_inschar()
  333. {
  334.   /* *** interne Daten und Initialisierung *** */
  335.   short    int input [INS_BUFF_LEN]; /* lokaler Eingabepuffer        */
  336.   int          restn; /* Anzahl noch einzufuegender Zeichen          */
  337.   char         scrolled,       /* Gibt an, ob enter_char beim        */
  338.               /* Anzeigen gescrollt hat                      */
  339.            line_broken;    /* Gibt an, ob Linebreak stattfand    */
  340.   register int n=0,   /* Index in lokalen Eingabepuffer              */
  341.            nmax,  /* Anzahl eingelesener Zeichen                 */
  342.            hilf;  /* Zum Einlesen einer Tastenkombination        */
  343.  
  344.   nodelay (akt_winp->winp,TRUE); /* Tastatur soll -1 liefern, wenn keine */
  345.   do                             /* Taste gedrueckt wurde                */
  346.     input [n++] = letter;        /* Zeichen in Eingabepuffer uebernehmen */
  347.   while (n<INS_BUFF_LEN && (hilf=taste(akt_winp->winp)) == mc_index+1);
  348.   /* Wenn Puffer noch nicht voll, Tastenkombination lesen. Wenn es ein */
  349.   /* Zeichen ist, Aktion wiederholen.                                  */
  350.  
  351.   nodelay (akt_winp->winp,FALSE); /* Fkt. taste soll auf Taste warten  */
  352.   if (hilf != mc_index+1)  /* Falls 'zu weit' gelesen wurde:           */
  353.     lastcode = hilf;       /* Letzte gelesene Tastenkombination merken */
  354.   nmax = restn = n; /* Variablen anhand des "Pufferfuellstandes" initial. */
  355.   do
  356.   {
  357.     scrolled    = FALSE;
  358.     line_broken = FALSE;
  359.     if (akt_winp->insflag)      /* Nur im Insert-Mode einfuegen */
  360.     {
  361.       if(!hndl_insert(&restn))  /* Einfuegung durchfuehren */
  362.     return;
  363.     }
  364.     else                          /* Sonst Ueberschreiben durchfuehren     */
  365.       if(!hndl_overwrite(&restn)) /* Klappte Einfuegen oder Ueberschreiben */
  366.     return;                   /* nicht, dann Funktion verlassen        */
  367.     do
  368.     {
  369.       enter_char((char) input [nmax-n],      /* Zeichen in Zeile einsetzen */
  370.          &scrolled, 
  371.          scrolled || line_broken ? PUT
  372.                      : akt_winp->insflag?INSERT:PUT,
  373.          akt_winp->linebreak); /* bei akt. Linebreak soll     */
  374.                  /* enter_char nur melden, daß            */
  375.                  /* Scrolling nötig ist, nicht selbst scr.*/
  376.       if (akt_winp->linebreak && scrolled)
  377.       {
  378.     /* Beachte folgendes zum Thema scrolled und line_broken:
  379.        Es wird ein Zeilenumbruch durchgeführt. In der neuen Zeile sind,
  380.        falls mehrere Zeichen im Puffer standen, bereits die Stellen für
  381.        die einzufügenden Zeichen vorgesehen, werden also vom do_newline
  382.        in do_linebreak angezeigt. Diese müssen dann übeschrieben werden
  383.        und dürfen nicht nach rechts verschoben werden. Es muß also wie 
  384.        nach dem Scrollen PUT verwendet werden. Darum wird beim Aufruf von
  385.        enter_char auch line_broken berücksichtigt. scrolled kann also 
  386.        zurückgesetzt werden, was bewirkt, daß nicht erneut nach jedem 
  387.        eingetragenen Zeichen ein Zeilenumbruch durchgeführt wird. Erst
  388.        wenn tatsächlich das nächste mal gescrollt werden würde, wird ein
  389.        Zeilenumbruch ausgeführt.
  390.     */
  391.     line_broken = TRUE;
  392.     scrolled    = FALSE;
  393.     if (!do_linebreak())      /* Klappt Linebreaking nicht? Dann       */
  394.     {                         /* doch scrollen                         */
  395.       akt_winp->ws_col += EC_SCROLL_WIDTH < akt_winp->dx ?
  396.                   EC_SCROLL_WIDTH : akt_winp->dx / 4 + 1;
  397.       if(akt_winp->ws_col >= MAXLENGTH) /* Zu weit, dann eins zurueck */
  398.         akt_winp->ws_col = MAXLENGTH-1;
  399.       show_win(W_AKT);  /* Fensterinhalt neu anzeigen */
  400.       fill_buff(); /* aktuelle Zeile wieder in Puffer kopieren */
  401.     }
  402.       }
  403.     } while (--n>restn);  /* Index in input anpassen */
  404.   } while (restn); /* Falls noch Zeichen einzufuegen sind, Aktion wiederholen */
  405.   setz_cursor(W_AKT);   /* Cursor an richtige Position setzen */
  406. }
  407.  
  408. /*****************************************************************************
  409. *
  410. *  Funktion       Tab-Komprimierungs-modus toggeln (do_tog_tkm)
  411. *  --------
  412. *
  413. *  Beschreibung : Der Status des Tab-Komprimierungs-modus wird invertiert.
  414. *                 Auaerdem wird der Text als geändert markiert, damit er
  415. *                 abgespeichert wird. Das ist erforderlich, da sonst die
  416. *                 Datei evtl. das alte Format beibehält.
  417. *
  418. *****************************************************************************/
  419.  
  420. void do_tog_tkm()
  421. {
  422.   akt_winp->tabflag ^= TRUE;   /* Tabflagstatus togglen */
  423.   akt_winp->changeflag = TRUE; /* Text soll auf jeden Fall gespeichert werden */
  424.   setz_cursor(W_AKT);          /* Cursor wieder an richtige Position */
  425. }
  426.  
  427. /*****************************************************************************
  428. *
  429. *  Funktion       Backup-Funktion toggeln (do_tog_bak)
  430. *  --------
  431. *
  432. *  Beschreibung : Erzeugung eines .bak-Files wird aktiviert bzw. deaktiviert.
  433. *
  434. *****************************************************************************/
  435.  
  436. void do_tog_bak()
  437. {
  438.   print_stat(PROMPT_BACKUP);   /* Meldung ueber aktuellen Status */
  439.   print_stat(on_off[backupflag ^= TRUE]);  /* in der Statuszeile ausgeben    */
  440.   sleep(2);                                /* Warten, damit User Status lesen kann */
  441.   clear_stat();                            /* Statuszeile wieder loeschen */
  442.   setz_cursor(W_AKT);                           /* Cursor wieder an richtige Stelle */
  443. }
  444.  
  445. /*****************************************************************************
  446. *
  447. *  Funktion       Autoindent-modus toggeln (do_tog_ai)
  448. *  --------
  449. *
  450. *  Beschreibung : Der Status des Autoindent-modus wird invertiert.
  451. *
  452. *****************************************************************************/
  453.  
  454. void do_tog_ai()
  455. {
  456.   akt_winp->autoindflag ^= TRUE;  /* Autoindentflag togglen */
  457.   setz_cursor(W_AKT);                  /* Cursor wieder an richtige Position setzen */
  458. }
  459.  
  460. /*****************************************************************************
  461. *
  462. *  Funktion       Autoindent-modus toggeln (do_tog_lb)
  463. *  --------
  464. *
  465. *  Beschreibung : Der Status des Linebreak-modus wird invertiert.
  466. *
  467. *****************************************************************************/
  468.  
  469. void do_tog_lb()
  470. {
  471.   akt_winp->linebreak^= TRUE;
  472.   setz_cursor(W_AKT);          
  473. }
  474.  
  475. /*****************************************************************************
  476. *
  477. *  Funktion       Patternmatching-Flag toggeln (do_togregex)
  478. *  --------
  479. *
  480. *  Beschreibung : Der Status des Patternmatching-Modus wird invertiert.
  481. *
  482. *****************************************************************************/
  483.  
  484. void do_togregex()
  485. {
  486.   print_stat(PROMPT_REGEX);    /* Meldung ueber aktuellen Status */
  487.   print_stat(on_off[regexflag ^= TRUE]);   /* in der Statuszeile ausgeben    */
  488.   sleep(2);                                /* Warten, damit User Status lesen kann */
  489.   clear_stat();                            /* Statuszeile wieder loeschen */
  490.   setz_cursor(W_AKT);                      /* Cursor wieder an richtige Stelle */
  491. }
  492.  
  493. /*****************************************************************************
  494. *
  495. *  Funktion       Fensterbewegung kontrollieren (do_movewin)
  496. *  --------
  497. *
  498. *  Beschreibung : Es werden die Ecken des Fensters angezeigt. Anschliessend
  499. *                 wird eine Nutzereingabe ausgewertet, aus der die Bewe-
  500. *                 gunsrichtung entnommen wird. Beendet der Benutzer die
  501. *                 Bewegung, so wird do_refresh() aufgerufen, um das Fenster
  502. *                 an der neuen Position zu zeigen.
  503. *
  504. *****************************************************************************/
  505.  
  506. void do_movewin()
  507. {
  508.   /* *** interne Daten und Initialisierung *** */
  509.   register short int c,  /* Zum Einlesen einer Taste */
  510.              d;  /* Zum Einlesen einer '\0'.. Sequenz */
  511.   int step = SW_STEP,    /* Schrittweite beim Verschieben */
  512.       i;                 /* Zaehler fuer Verschieben mit step != 1 */
  513.  
  514.   werase (akt_winp->winp);  /* Fensterinhalt auf Bildschirm loeschen */
  515.   wrefresh(akt_winp->winp); /* damit kein Fehler beim Verschieben passiert */
  516.   cpwins2stdscr(); /* Alle Fenster ausser akt. nach stdscr kopieren */
  517.   do
  518.   {
  519.     mvprintw(LINES-1,0,PROMPT_WINMOVE,step);
  520.     eckenhw();                 /* Ecken des Fensters markieren         */
  521.     c = newwgetch(stdscr);     /* Ein Zeichen von Tastatur / Macro lesen */
  522.     eckenhw();                 /* Ecken vor Verschieben loeschen       */
  523.     if(c == 's')               /* Bei 's' Schrittweite anpassen */
  524.       step = step == SW_STEP ? 1 : SW_STEP; /* war's 1, dann SW_STEP und umgekehrt */
  525.     else                       /* Sonst <step> mal in angegebene Richtung */
  526. #ifdef OS2  /* Bei OS/2 kein zweites Zeichen lesen! */
  527.     {
  528.       d = c;
  529. #else
  530.       if(c==(short int) '\0')              /* "Escape"-Kombination ? */
  531.       {
  532.     d = newwgetch(stdscr); /* Dann nächstes Zeichen lesen */
  533. #endif
  534.     for(i=0;i<step;i++)      /* verschieben */
  535.       switch (d)
  536.       {
  537.         case KEY_RIGHT : win_right(1); break;
  538.         case KEY_LEFT  : win_left(1);  break;
  539.         case KEY_UP    : win_up(1);    break;
  540.         case KEY_DOWN  : win_down(1);  break;
  541.       }
  542.       } /* Achtung!!! Diese Klammer gehört zum else für OS2, zu if sonst */
  543.   } while (c != END_KEY);      /* Solange wiederholen, bis beendende Taste */
  544.   erase();refresh();           /* gedrueckt wurde (RETURN) */
  545.   mvwin (akt_winp->winp,akt_winp->y,akt_winp->x); /* Fenster verschieben */
  546.   do_refresh();                   /* Alle Fenster neu zeichnen              */
  547. }
  548.  
  549. /*****************************************************************************
  550. *
  551. *  Funktion       Fenster auf gespeicherte Groesse bringen (do_toggle_size)
  552. *  --------
  553. *
  554. *  Beschreibung : Die in der Windowstruktur gespeicherten alten Groessen
  555. *                 und Fensterposition werden mit den aktuellen vertauscht.
  556. *                 Die Cursorposition wird eventuell angepasst. Danach wird
  557. *                 ein do_refresh() ausgefuehrt.
  558. *
  559. *****************************************************************************/
  560.  
  561. void do_toggle_size()
  562. {
  563.   toggle_size();   /* Alte Fensterkoordinaten mit neuen besetzen und umgekehrt */
  564.   do_refresh();    /* Alle Fenster neu zeichnen */
  565. }
  566.  
  567. /*****************************************************************************
  568. *
  569. *  Funktion       Fenstergroessenanpassung kontrollieren (do_sizewin)
  570. *  --------
  571. *
  572. *  Beschreibung : Die Ecken des Fensters werden angezeigt. Dann wird eine
  573. *                 Nutzereingabe ausgewertet, aus der die Bewegungs-
  574. *                 richtung der rechten unteren Fensterecke entnommen wird.
  575. *                 Wird die Groessenanpassung beendet, werden alle Fenster
  576. *                 refresht (do_refresh()).
  577. *
  578. *****************************************************************************/
  579.  
  580. void do_sizewin()
  581. {
  582.   /* *** interne Daten *** */
  583.   register short int c, /* Zum Einlesen einer Taste */
  584.              d; /* Zum Einlesen einer '\0'.. Sequenz */
  585.   int step = SW_STEP,   /* Schrittweite beim Groessenveraendern */
  586.       i;                /* Zahler beim Veraendern mit step != 1 */
  587.  
  588.   werase (akt_winp->winp);  /* Fensterinhalt auf Bildschirm loeschen,     */
  589.   wrefresh(akt_winp->winp); /* damit keine Fehler beim Anpassen auftreten */
  590.   cpwins2stdscr(); /* Alle Fenster ausser akt. nach stdscr kopieren */
  591.   do
  592.   {
  593.     mvprintw(LINES-1,0,PROMPT_WINSIZE,step);
  594.     eckenhw();              /* Fenstereckpunkte merkieren */
  595.     c = newwgetch(stdscr);  /* Zeichen von Tastatur / Macro einlesen */
  596.     eckenhw();              /* Fenstereckpunkte vor Verschieben loeschen */
  597.     if(c == 's')            /* Bei 's' Schrittweite aendern : */
  598.       step = step == SW_STEP ? 1 : SW_STEP; /* war step 1, dann SW_STEP und */
  599.     else                                    /* umgekehrt                    */
  600. #ifdef OS2  /* Bei OS/2 kein zweites Zeichen lesen! */
  601.       d = c;
  602. #else
  603.       if(c==(short int) '\0')              /* "Escape"-Kombination ? */
  604.       {
  605.     d = newwgetch(stdscr); /* Dann nächstes Zeichen lesen */
  606. #endif
  607.     for(i=0;i<step;i++)   /* <step> mal in angegebene Richtung vergroessern */
  608.       switch (d)
  609.       {
  610.         case KEY_RIGHT : size_right(1); break;
  611.         case KEY_LEFT  : size_left(1);  break;
  612.         case KEY_UP    : size_up(1);    break;
  613.         case KEY_DOWN  : size_down(1);  break;
  614.       }
  615. #ifndef OS2
  616.       }
  617. #endif
  618.   } while (c != END_KEY);   /* Solange wiederholen, bis beendende Taste */
  619.   erase();                  /* gedrueckt wurde (RETURN) */
  620.   refresh();                /* Fensterinhalt loeschen */
  621.   delwin(akt_winp->winp);   /* Fenster mit Curses loeschen und neu anlegen */
  622.   akt_winp->winp=newwin(akt_winp->dy+2,akt_winp->dx+2,akt_winp->y,akt_winp->x);
  623.   init_win();               /* Fensterattribute setzen (raw etc.) */
  624.  
  625.   /* Falls Cursor jetzt ausserhalb des Fensters steht, Cursorposition anpassen */
  626.   if (akt_winp->ws_line+akt_winp->dy <= akt_winp->textline)
  627.     gotox(akt_winp->ws_line+akt_winp->dy-1);
  628.   if (akt_winp->ws_col+akt_winp->dx <= akt_winp->screencol)
  629.     akt_winp->screencol = akt_winp->ws_col+akt_winp->dx-1;
  630.   do_refresh();  /* Alle Fenster neu zeichnen */
  631. }
  632.  
  633. /*****************************************************************************
  634. *
  635. *  Funktion       Zum Nachfolger des aktuellen Fensters (do_swnext)
  636. *  --------
  637. *
  638. *  Beschreibung : Das Fenster, das hinter dem Dummyelement steht, wird
  639. *                 hinter dem aktuellen Fenster eingefuegt. Das Element hinter
  640. *                 dem aktuellen Fenster wird dann zum aktuellen Fenster.
  641. *
  642. *****************************************************************************/
  643.  
  644. void do_swnext()
  645. {
  646.   /* *** interne Daten *** */
  647.   win_typ *hilf,  /* Zeiger fuer erstes Fester in Liste */
  648.       *dummy; /* Zeiger fuer leeres Element in der Fensterliste */
  649.  
  650.   if (akt_winp->next->next == akt_winp) /* Test, ob nur ein Fenster */
  651.   {
  652.     print_err(PROMPT_ONEWINDOW); /* Wenn ja, Meldung und Ende */
  653.     return;
  654.   }
  655.   kopf(W_NOTAKT);   /* Altes Fenster als inaktiv markieren */
  656.   rahmen(W_NOTAKT);
  657.   wrefresh(akt_winp->winp);
  658.  
  659.   check_buff();              /* Sonst evtl. Pufferinhalt in Text eintragen */
  660.   dummy = akt_winp->next;    /* dummy auf leeres Element der Liste setzen  */
  661.   hilf = dummy->next;        /* hilf auf erstes Fenster in Liste setzen    */
  662.   dummy->next = hilf->next;
  663.   dummy->prev = hilf;        /* Dummyfenstereintrag vor hilf einkoppeln,   */
  664.   dummy->next->prev = dummy; /* da aktuelles Fenster immer am Listenende   */
  665.   akt_winp->next = hilf;     /* stehen muss.                               */
  666.   hilf->prev = akt_winp;
  667.   hilf->next = dummy;
  668.   akt_winp = hilf;           /* hilf wird zum aktuellen Fenster            */
  669.   show_win(W_AKT);           /* Aktuellen Fensterinhalt neu zeichnen       */
  670. }
  671.  
  672. /*****************************************************************************
  673. *
  674. *  Funktion       Zum Vorgaenger des aktuellen Fensters (do_swprev)
  675. *  --------
  676. *
  677. *  Beschreibung : Das aktuelle Fenster, das vor dem Dummyelement steht, wird
  678. *                 hinter dem Dummy-Element eingefuegt. Das Element vor dem
  679. *                 aktuellen Fenster wird dann zum aktuellen Fenster. Man
  680. *                 kommt also ueber diese Funktion in das Fenster, das un-
  681. *                 mittelbar vor dem aktuellen Fenster geoeffnet wurde.
  682. *
  683. *****************************************************************************/
  684.  
  685. void do_swprev()
  686. {
  687.   /* *** interne Daten *** */
  688.   win_typ *hilf,    /* zeigt auf Vorgaenger des aktuell werdenden Fensters */
  689.       *old_akt; /* Zeiger fuer Fenster, das beim Aufruf aktuell war */
  690.  
  691.   if (akt_winp->next->next == akt_winp) /* Test, ob nur ein Fenster da    */
  692.   {
  693.     print_err(PROMPT_ONEWINDOW); /* Wenn ja, Meldung und raus */
  694.     return;
  695.   }
  696.   kopf(W_NOTAKT);   /* Altes Fenster als inaktiv markieren */
  697.   rahmen(W_NOTAKT);
  698.   wrefresh(akt_winp->winp);
  699.  
  700.   check_buff();                          /* Pufferinhalt in Text sichern   */
  701.   akt_winp = (old_akt = akt_winp)->prev; /* old_akt und akt_winp setzen    */
  702.   akt_winp->next = old_akt->next;        /* Aktuelles Fenster wird mit dem */
  703.   hilf = akt_winp->prev;                 /* vor ihm stehenden vertauscht   */
  704.   akt_winp->prev = old_akt;
  705.   old_akt->prev = hilf;
  706.   hilf->next = old_akt;
  707.   akt_winp->next->prev = akt_winp;
  708.   old_akt->next = akt_winp;
  709.   show_win(W_AKT);                        /* Fensterinhalt neu zeichnen     */
  710. }
  711.  
  712. /*****************************************************************************
  713. *
  714. *  Funktion       Window absolut anspringen (do_swnum)
  715. *  --------
  716. *
  717. *  Beschreibung : Der Nutzer kann eine Fensternummer eingeben. Falls die
  718. *                 Nummer existiert, wird das Fenster mit dieser Nummer
  719. *                 zum aktuellen Fenster.
  720. *
  721. *****************************************************************************/
  722.  
  723. void do_swnum()
  724. {
  725.   /* *** interne Daten *** */
  726.   char num_str [21];  /* String fuer einzulesende Fensternummer */
  727.   int  num;           /* eingelesene Nummer als Integer         */
  728.  
  729.   print_stat (PROMPT_WINDOWNUM);
  730.   read_stat (num_str,20,GS_NUM);   /* Nummer einlesen, nur 2 Ziffern erlaubt */
  731.   clear_stat();                    /* Statuszeile wieder loeschen            */
  732.   check_buff();                    /* Pufferinhalt in Text uebernehmen       */
  733.   kopf(W_NOTAKT);   /* Altes Fenster als inaktiv markieren */
  734.   rahmen(W_NOTAKT);
  735.   wrefresh(akt_winp->winp);
  736.  
  737.   /* String in Integer umwandeln. Test, ob Nummer == 0 oder aktuelle Fnstnr. */
  738.   if ((num = atoi (num_str)) && num != akt_winp->wini)
  739.     if(make_akt_win(num)) /* Wenn alles in Ordnung, versuchen, gewuenschtes  */
  740.       show_win(W_AKT);         /* Fenster zum aktuellen zu machen. Klappte das,   */
  741.     else                  /* Fensterinhalt neu zeichnen, sonst Meldung       */
  742.     {
  743.       pe_or (PROMPT_WINNMNFND);
  744.       rahmen(W_AKT); /* Doch wieder aktiv, kopf kommt von setz_cursor */
  745.       setz_cursor(W_AKT);
  746.     }
  747.   else                    /* Fehler bei Nummer, dann nur Cursor plazieren    */
  748.     setz_cursor(W_AKT);
  749. }
  750.  
  751. void check_and_copy_repeat_buff (old_ksi, new_ksi)
  752. int old_ksi, *new_ksi;
  753. {
  754.    (*new_ksi)++;  /* new_ksi zeigt jetzt auf den zu füllenden Puffer */
  755.    if (old_ksi != *new_ksi-1)
  756.    {
  757.       /* get_comstr() hat beim Einlesen des Repeat-Kommandos wieder Puffer
  758.      freigegeben. Das eingelesene Repeat-Kommando muß entsprechend 
  759.      umgepointert werden.
  760.       */
  761.       puff_feld[*new_ksi].begin = puff_feld[old_ksi+1].begin;
  762.       puff_feld[*new_ksi].end   = puff_feld[old_ksi+1].end;
  763.    }
  764. }
  765.  
  766.  
  767. /*****************************************************************************
  768. *
  769. *  Funktion       Funktion mehrmals ausfuehren (do_repeat)
  770. *  --------
  771. *
  772. *  Beschreibung : Der User muss die Anzahl der Wiederholungen eingeben.
  773. *                 Anschliessend,falls die eingegebene Anzahl groesser 0 war,
  774. *                 wird ein Kommando eingelesen, welches dann von der Funktion
  775. *                 taste so oft zurueckgegeben wird, wie der User spezifizierte.
  776. *
  777. *****************************************************************************/
  778.  
  779. void do_repeat()
  780. {
  781.   /* *** interne Daten *** */
  782.   char zahl_str[6];        /* String fuer Anzahl der Wiederholungen */
  783.   int  i,                  /* Stringinhalt als Integer */
  784.        old_ksi = ks_index; /* Zwischenspeicher altes ks_index */
  785.  
  786.   if(ks_index < MACRO_NEST_DEPTH - 1) /* Testen, ob noch ein Puffer frei */
  787.   {                                   /* Wenn ja, Wiederholungsanzahl einlesen */
  788.     print_stat(PROMPT_REPEAT);
  789.     read_stat(zahl_str,5,GS_NUM);
  790.     clear_stat();                     /* Statuszeile wieder loeschen */
  791.     if ((i=atoi(zahl_str)) > 0)       /* String nach Integer, muss > 0 sein */
  792.     {
  793.       /* Mit get_comstr wird eine Befehlsfolge von der Tastatur eingelesen
  794.      und im ersten freien Puffer (ks_index+1) abgelegt. Nun kann es aber 
  795.      sein, daß nach dem Einlesen des letzten Repeat-Kommando-Zeichens 
  796.      andere Puffer freigegeben werden. ks_index nach get_comstr muß also 
  797.      nicht mit ks_index vor get_comstr übereinstimmen. Ggf. muß also der 
  798.      neue Puffer in einen mit kleinerem Index kopiert werden.
  799.       */
  800.       get_comstr(&puff_feld[old_ksi+1].begin,&puff_feld[old_ksi+1].end);
  801.       if(puff_feld[old_ksi+1].begin)    /* keine Leereingabe? */
  802.       {
  803.     if(ks_index >= 0)              /* Wenn noch ein Puffer aktiv, dann  */
  804.       puff_feld[ks_index].current = keystack; /* Position darin merken  */
  805.     check_and_copy_repeat_buff (old_ksi, &ks_index); /* Puf. evtl. kop. */
  806.                   /* Dabei ks_index auf neuen Puffer setzen */
  807.     keystack = puff_feld[ks_index].begin;   /* Position im neuen setzen */
  808.             /* Puffer soll nach Ausfuehrung der Wiederholung wieder */
  809.     puff_feld[ks_index].free_flag = TRUE;         /* freigegeben werden */
  810.     e_keystack = puff_feld[ks_index].end; /* Pufferende merken          */
  811.     puff_feld[ks_index].anz_rep = i - 1;  /* Anzahl der Wdh. eintragen  */
  812.       }
  813.     }
  814.     setz_cursor(W_AKT);  /* Cursor an seine richtige Position setzen */
  815.   }
  816.   else      /* falls kein Puffer mehr frei, Fehlermeldung ausgeben */
  817.   {
  818.     clear_buff = TRUE;  /* beim naechsten Aufruf von newwgetch() Puffer loeschen */
  819.     print_err(PROMPT_RECURSION);
  820.   }
  821. }
  822.  
  823. /*****************************************************************************
  824. *
  825. *  Funktion       Blockanfang an aktueller Position setzen (do_blstart)
  826. *  --------
  827. *
  828. *  Beschreibung : An der aktuellen Cursorposition wird - falls zulaessig, d.h.
  829. *                 falls der Blockanfang vor dem Blockende liegt oder noch
  830. *                 kein Blockende definiert wurde - der Blockstart festgelegt.
  831. *                 War schon ein Blockende vorhanden, so wird show_win(W_AKT)
  832. *                 aufgerufen.
  833. *
  834. *****************************************************************************/
  835.  
  836. void do_blstart()
  837. {
  838.   /* Ein noch gespeicherter Block wird durch Setzen der Position gelöscht. */
  839.   if (akt_winp->block.bstart)
  840.      block_free(&akt_winp->block.bstart);
  841.   akt_winp->block.s_line = akt_winp->textline;  /* Zeile und Spalte als Block- */
  842.   akt_winp->block.s_col = akt_winp->screencol;  /* eintragen */
  843.   if(highblockflag)                    /* Falls Block gehighlighted sein soll, */
  844.     show_win(W_AKT);                        /* markierten Block anzeigen */
  845. }
  846.  
  847. /*****************************************************************************
  848. *
  849. *  Funktion       Blockende (normal) an aktueller Position setzen (do_blnormend)
  850. *  --------
  851. *
  852. *  Beschreibung : An der aktuellen Cursorposition wird - falls zulaessig, d.h.
  853. *                 falls der Blockanfang vor dem Blockende liegt oder noch
  854. *                 kein Blockanfang definiert wurde - das Blockende festgelegt.
  855. *                 War schon ein Blockanfang vorhanden, so wird show_win(W_AKT)
  856. *                 aufgerufen.
  857. *
  858. *****************************************************************************/
  859.  
  860. void do_blnormend()
  861. {
  862.   /* Ein noch gespeicherter Block wird durch Setzen der Position gelöscht. */
  863.   if (akt_winp->block.bstart)
  864.      block_free(&akt_winp->block.bstart);
  865.   akt_winp->block.e_line = akt_winp->textline; /* Zeile und Spalte als Block- */
  866.   akt_winp->block.e_col = akt_winp->screencol; /* ende eintragen              */
  867.   akt_winp->block.typ = BT_NORMAL;             /* Blocktyp eintragen          */
  868.   if(highblockflag)  /* Falls Block gehighlighted dargestellt werden soll,    */
  869.     show_win(W_AKT);      /* Fenstrinhalt neu darstellen */
  870. }
  871.  
  872. /*****************************************************************************
  873. *
  874. *  Funktion       Blockende (Rechteck) an aktueller Position setzen (do_blrechtend)
  875. *  --------
  876. *
  877. *  Beschreibung : An der aktuellen Cursorposition wird - falls zulaessig, d.h.
  878. *                 falls der Blockanfang vor dem Blockende liegt oder noch
  879. *                 kein Blockanfang definiert wurde - das Blockende festgelegt.
  880. *                 War schon ein Blockanfang vorhanden, so wird show_win(W_AKT)
  881. *                 aufgerufen.
  882. *
  883. *****************************************************************************/
  884.  
  885. void do_blrechtend()
  886. {
  887.   /* Ein noch gespeicherter Block wird durch Setzen der Position gelöscht. */
  888.   if (akt_winp->block.bstart)
  889.      block_free(&akt_winp->block.bstart);
  890.   akt_winp->block.e_line = akt_winp->textline;  /* Aktuelle Zeile und Spalte */
  891.   akt_winp->block.e_col = akt_winp->screencol;  /* als Blockende eintragen   */
  892.   akt_winp->block.typ = BT_RECHTECK;            /* Blocktyp eintragen        */
  893.   if(highblockflag) /* Falls Block gehighlighted dargestellt werden soll,    */
  894.     show_win(W_AKT);     /* Fenstrinhalt neu darstellen */
  895. }
  896.  
  897. /*****************************************************************************
  898. *
  899. *  Funktion       Blockmarkierung loeschen (do_blunmark)
  900. *  --------
  901. *
  902. *  Beschreibung : Die Blockmarkierungen werden geloescht und ein show_win(W_AKT)
  903. *                 durchgefuehrt, um eventuelle Blockmarkierungen auf dem
  904. *                 Schirm zu loeschen.
  905. *
  906. *****************************************************************************/
  907.  
  908. void do_blunmark()
  909. {
  910.   if(block_defined())   /* Wenn ein Block markiert ist         */
  911.     if(tst_overlap())   /* und dieser im Fenster sichtbar ist, */
  912.     {                   /* Blockgrenzen loeschen und           */
  913.       akt_winp->block.e_line = akt_winp->block.s_line = -1;
  914.       show_win(W_AKT);       /* Fensterinhalt neu zeichnen          */
  915.     }
  916.     else    /* Ist der Block nicht im Fenster, dann nur die Grenzen loeschen */
  917.       akt_winp->block.e_line = akt_winp->block.s_line = -1;
  918. }
  919.  
  920. /*****************************************************************************
  921. *
  922. *  Funktion       Block loeschen (do_blweg)
  923. *  --------
  924. *
  925. *  Beschreibung : Falls ein Block markiert ist, wird in Abhaengigkeit vom Typ
  926. *                 der Block geloescht, die Cursor- und Bildschirmposition an-
  927. *                 gepasst und evtl. der Bildschirm neu gezeichnet. Vor dem
  928. *                 Löschen wird der Block mit save_{normal|rechteck} in
  929. *                 akt_winp->block->{bstart|laenge} eingetragen.
  930. *
  931. *****************************************************************************/
  932.  
  933. void do_blweg()
  934. {
  935.   if (block_defined())  /* Nur ausfuehren, wenn ein Block definiert ist */
  936.   {
  937.     /* In laenge wird die Differenz der letzten und der ersten Zeile */
  938.     /* eingetragen */
  939.     akt_winp->block.laenge = akt_winp->block.e_line-akt_winp->block.s_line;
  940.     if (akt_winp->block.typ == BT_RECHTECK)   /* Abhaengig vom Blocktyp wird */
  941.     {                                         /* entweder del_rechteck oder  */
  942.       akt_winp->block.bstart = save_rechteck(); /* del_normal aufgerufen     */
  943.       del_rechteck();                         
  944.     }
  945.     else                                      
  946.     {
  947.       akt_winp->block.bstart = save_normal();
  948.       del_normal();
  949.       if (akt_winp->textline < akt_winp->ws_line)  /* Falls Cursor durch das  */
  950.     akt_winp->ws_line = akt_winp->textline;    /* Loeschen des Blocks     */
  951.       if (akt_winp->screencol < akt_winp->ws_col)  /* ausserhalb des Fensters */
  952.     akt_winp->ws_col = akt_winp->screencol;    /* steht, Fenster anpassen */
  953.     }   /* Anschliessend die Blockgrenzen loeschen */
  954.     akt_winp->block.e_line = akt_winp->block.s_line = -1;
  955.     show_win(W_AKT); /* Fensterinhalt neu zeichnen */
  956.   }
  957. }
  958.  
  959. /*****************************************************************************
  960. *
  961. *  Funktion       Block kopieren (do_blcopy)
  962. *  --------
  963. *
  964. *  Beschreibung : Falls ein Block markiert ist, wird in Abhaengigkeit vom Typ
  965. *                 der Block in einen Puffer kopiert und dieser dann an der
  966. *                 aktuellen Position eingefuegt.  Danach wird der Puffer frei-
  967. *                 gegeben und evtl. der Bildschirm neu gezeichnet.
  968. *
  969. *****************************************************************************/
  970.  
  971. void do_blcopy()
  972. {
  973.   /* *** interne Daten *** */
  974.   int ok;  /* Zwischenspeicher fuer Rueckgabewert der Insert-Funktionen */
  975.  
  976.   /* Nur ausfuehren, falls ein Block markiert oder der Blocktext noch */
  977.   /* vorhanden ist */
  978.   if (block_defined() || akt_winp->block.bstart) 
  979.   {
  980.     if (akt_winp->block.typ == BT_RECHTECK)     /* Abhaengig vom Blocktyp */
  981.     {                                           /* entweder save_rechteck */
  982.       if (!akt_winp->block.bstart)              /* und ins_rechteck auf-  */
  983.     akt_winp->block.bstart = save_rechteck(); /* rufen oder           */
  984.       ok = ins_rechteck(&akt_winp->block);      
  985.     }
  986.     else
  987.     {                                           
  988.       if (!akt_winp->block.bstart)
  989.     akt_winp->block.bstart = save_normal(); /* save_normal und ins_normal */
  990.       ok = ins_normal(&akt_winp->block);        /* aufrufen */                 
  991.     }
  992.     block_free(&akt_winp->block.bstart);        /* Blocktext freigeben        */
  993.     show_win(W_AKT);                                 /* Fensterinhalt neu anzeigen */
  994.     if(!ok)                                     /* Falls beim Einfuegen ein   */
  995.       print_err(B_SIZE_ERRTEXT);                /* Fehler auftrat, Meldung    */
  996.   }
  997. }
  998.  
  999. /*****************************************************************************
  1000. *
  1001. *  Funktion       Block verschieben (do_blmove)
  1002. *  --------
  1003. *
  1004. *  Beschreibung : Falls ein Block markiert ist, wird er kopiert, geloescht
  1005. *                 und an der aktuellen Cursorposition wieder eingefuegt.
  1006. *
  1007. *****************************************************************************/
  1008.  
  1009. void do_blmove()
  1010. {
  1011.   /* *** interne Daten *** */
  1012.   int old_sc,  /* Zwischenspeicher fuer Spalte falls Einfuegen nicht klappt */
  1013.       old_tl;  /* Zwischenspeicher fuer Zeile falls Einfuegen nicht klappt */
  1014.  
  1015.   if (block_defined()) /* Nur ausfuehren, wenn ein Block markiert ist */
  1016.   {
  1017.     if (akt_winp->block.typ == BT_RECHTECK)  /* Blocktyp ermitteln */
  1018.     {
  1019.       akt_winp->block.bstart = save_rechteck();  /* Blocktext abspeichern    */
  1020.       del_rechteck();                            /* Block im Text loeschen   */
  1021.       if(!ins_rechteck(&akt_winp->block))        /* Block an aktueller       */
  1022.       {                                          /* Position einfuegen       */
  1023.     old_sc = akt_winp->screencol;            /* klappt das nicht, dann   */
  1024.     old_tl = akt_winp->textline;             /* Position merken,         */
  1025.     akt_winp->screencol = akt_winp->block.s_col; /* zum Anfang des alten */
  1026.     gotox(akt_winp->block.s_line);  /* Blocks gehen und dort wieder hin. */
  1027.     ins_rechteck(&akt_winp->block); /* Einfuegen an alter position muss  */
  1028.     akt_winp->screencol = old_sc;   /* funktionieren. Cursorposition     */
  1029.     gotox(old_tl);                  /* restaurieren                      */
  1030.     print_err(B_SIZE_ERRTEXT);      /* Fehlermeldung ausgeben            */
  1031.       }
  1032.       else
  1033.     show_win(W_AKT); /* Klappte Einfuegen, dann Fensterinhalt neu anzeigen */
  1034.       block_free(&akt_winp->block.bstart);       /* Blocktext freigeben */
  1035.     }
  1036.     else                                /* Normaler Block: */
  1037.       if (akt_winp->maxline + 2 < MAX_ANZ_LINES) /* Test ob genug Zeilen frei */
  1038.       {
  1039.     akt_winp->block.bstart = save_normal(); /* Wenn ja, Blocktext merken, */
  1040.     del_normal();                           /* Block im Text loeschen     */
  1041.     ins_normal(&akt_winp->block);           /* An aktueller Pos. einfuegen*/
  1042.     if (akt_winp->textline < akt_winp->ws_line)  /* Falls Cursor durch das  */
  1043.       akt_winp->ws_line = akt_winp->textline;    /* Verschieben des Blocks  */
  1044.     if (akt_winp->screencol < akt_winp->ws_col)  /* ausserhalb des Fensters */
  1045.       akt_winp->ws_col = akt_winp->screencol;    /* steht, Fenster anpassen */
  1046.     show_win(W_AKT);                             /* Fensterinhalt neu anzeigen */
  1047.     block_free(&akt_winp->block.bstart);         /* Blocktext freigeben        */
  1048.       }
  1049.       else       /* Waren nicht genuegend Zeilen frei, Fehlermeldung ausgeben */
  1050.     print_err(B_SIZE_ERRTEXT);
  1051.   }
  1052. }
  1053.  
  1054. /*****************************************************************************
  1055. *
  1056. *  Funktion       Block cutten (do_blcut)
  1057. *  --------
  1058. *
  1059. *  Beschreibung : Falls ein Block markiert ist, wird in Abhaengigkeit vom Typ
  1060. *                 der Block in einen Puffer, den sogenannten PASWTE-Puffer,
  1061. *                 kopiert. Dieser kann mit der Paste-Funktion ino einem belie-
  1062. *                 bigen Fenster eingefuegt werden.
  1063. *
  1064. *****************************************************************************/
  1065.  
  1066. void do_blcut()
  1067. {
  1068.   if (block_defined())      /* Nur ausfuehren, falls ein Block definiert ist */
  1069.   {
  1070.     if(global_block.bstart) /* Steht schon ein Block im Paste-Puffer, muss */
  1071.       block_free(&global_block.bstart);      /* dieser freigegeben werden. */
  1072.     if (akt_winp->block.typ == BT_RECHTECK)  /* abhaengig vom Blocktyp die */
  1073.       akt_winp->block.bstart = save_rechteck(); /* entsprechende Funktion zum */
  1074.     else                                        /* Abspeichern des Blockes    */
  1075.       akt_winp->block.bstart = save_normal();   /* verwenden                  */
  1076.     show_win(W_AKT);                                 /* Fenster neu anzeigen       */
  1077.     memcpy(&global_block,&akt_winp->block,sizeof(block_typ)); /* Daten des akt. */
  1078.     print_stat(PROMPT_CUT); /* Blocks kopieren  */
  1079.     sleep(1);                           /* Meldung ausgeben und 2 Sek. warten */
  1080.     clear_stat();                       /* Meldung wieder loeschen */
  1081.     setz_cursor(W_AKT);                      /* Cursor an richtige Position */
  1082.   }
  1083. }
  1084.  
  1085. /*****************************************************************************
  1086. *
  1087. *  Funktion       Block pasten (do_blpaste)
  1088. *  --------
  1089. *
  1090. *  Beschreibung : Falls mit der cut-Funktion ein Block in den PASTE-Puffer ko-
  1091. *                 piert wurde, wird dieser im aktuellen Fenster an der Cursor-
  1092. *                 position eingefuegt.
  1093. *
  1094. *****************************************************************************/
  1095.  
  1096. void do_blpaste()
  1097. {
  1098.   /* *** interne Daten *** */
  1099.   block_typ *hilf;  /* Zeiger fuer duplizierten Paste-Block */
  1100.   int       ok;     /* Rueckgabewert der Insert-Funktionen */
  1101.  
  1102.   if (global_block.bstart)              /* Nur, wenn Paste-Puffer belegt */
  1103.   {
  1104.     if (akt_winp->maxline == -1)        /* Falls Text leer, Eine Zeile anlegen, */
  1105.       koppel_line(IGNORE_COORS);        /* da sonst Dummy ueberschrieben wird.  */
  1106.     /* Marker und lastpos sind im leeren Text egal */
  1107.     hilf = dup_block(&global_block);    /* Blocktext duplizieren */
  1108.     if (global_block.typ == BT_RECHTECK) /* Abhaengig vom Typ ins_rechteck */
  1109.       ok = ins_rechteck(hilf);           /* oder ins_normal aufrufen       */
  1110.     else
  1111.       ok = ins_normal(hilf);
  1112.     if(ok) /* Wenn ins_normal bzw. ins_rechteck geklappt haben, */
  1113.       show_win(W_AKT);  /* Fensterinhalt neu anzeigen */
  1114.     else   /* Klappte des Einfuegen nicht, Fehlermeldung ausgeben. */
  1115.       print_err(B_SIZE_ERRTEXT);
  1116.     block_free(&hilf->bstart);    /* Blocktext des aktuellen Blocks freigeben */
  1117.     free (hilf);                  /* Hilfsblockstruktur freigeben */
  1118.   }
  1119. }
  1120.  
  1121. /*****************************************************************************
  1122. *
  1123. *  Funktion       Block einruecken (do_blindent)
  1124. *  --------
  1125. *
  1126. *  Beschreibung : Falls ein Block markiert wurde, werden alle Zeilen ab der
  1127. *                 Blockstartzeile bis zur Blockendezeile um einen vom Nutzer
  1128. *                 einzugebenden Wert eingerueckt. Dabei entscheidet das Vor-
  1129. *                 zeichen ueber die Einrueckungsrichtung.
  1130. *
  1131. *****************************************************************************/
  1132.  
  1133. void do_blindent()
  1134. {
  1135.   /* *** interne Daten *** */
  1136.   int  weite;         /* Eingelesene Weite als Integer */
  1137.   char weit_str[10];  /* Eingelesene Weite als String  */
  1138.  
  1139.   if (block_defined())  /* Nur ausfuehren, falls ein Block markiert ist */
  1140.   {
  1141.     print_stat(PROMPT_ASKINDENT);
  1142.     read_stat(weit_str,9,GS_ANY);  /* Weite als String einlesen              */
  1143.     clear_stat();                  /* Statuszeile wieder loeschen            */
  1144.     setz_cursor(W_AKT);                 /* Cursor wieder an richtige Position     */
  1145.     if (weite = atoi(weit_str))    /* String in int wandeln und auf 0 testen */
  1146.       if (indent_block(weite))     /* Weite != 0, dann Block einruecken      */
  1147.     show_win(W_AKT);                /* und Fensterinhalt neu anzeigen         */
  1148.   }
  1149.   else                             /* War kein Block markiert, Meldung ausgeben */
  1150.     print_err(PROMPT_NOBLOCK);
  1151. }
  1152.  
  1153. /*****************************************************************************
  1154. *
  1155. *  Funktion       Block einlesen (do_blread)
  1156. *  --------
  1157. *
  1158. *  Beschreibung : Eine vom Nutzer anzugebende Datei wird an der aktuellen
  1159. *                 Cursorposition in den Text eingefuegt und als Block mar-
  1160. *                 kiert.
  1161. *
  1162. *****************************************************************************/
  1163.  
  1164. void do_blread()
  1165. {
  1166.   /* *** interne Daten *** */
  1167.   char name[MAXLENGTH+1];  /* Array fuer einzulesenden Dateinamen */
  1168.   FILE *f;                 /* Filepointer fuer zu lesende Datei */
  1169.  
  1170.   print_stat(PROMPT_FILENAME);
  1171.   read_stat(name,MAXLENGTH,GS_ANY);  /* Dateiname einlesen */
  1172.   clear_stat();                      /* Statuszeile wieder loeschen */
  1173.   setz_cursor(W_AKT);                     /* Cursor an alte Position */
  1174.   if(name[0])                        /* Nur ausfuehren, wenn Name vorhanden */
  1175.     if (f=fopen(name,"r"))           /* Datei zum Lesen oeffnen */
  1176.     {
  1177.       akt_winp->block.typ = BT_NORMAL;     /* Blocktyp eintragen */
  1178.       if(lies_block(&akt_winp->block,f))   /* Block aus Datei lesen */
  1179.       {                                    /* Klappte das, dann Block in */
  1180.     if(!ins_normal(&akt_winp->block))  /* Text einfuegen. Falls Fehler */
  1181.       print_err(B_SIZE_ERRTEXT);       /* beim Einfuegen, dann Meldung */
  1182.     else                               /* Sonst Fensterinhalt neu */
  1183.       show_win(W_AKT);                      /* anzeigen */
  1184.     block_free(&akt_winp->block.bstart);/* Blocktext freigeben */
  1185.     fclose (f);
  1186.       }
  1187.       else                                 /* lies_block lieferte FALSE, */
  1188.     print_err(PROMPT_BLOCKEMPT);       /* Meldung, dass Block leer */
  1189.     }
  1190.     else                                   /* Falls Datei nicht geoeffnet */
  1191.       print_err(PROMPT_FILENOTFD);         /* werden konnte, Meldung */
  1192. }
  1193.  
  1194. /*****************************************************************************
  1195. *
  1196. *  Funktion       Block schreiben (do_blwrite)
  1197. *  --------
  1198. *
  1199. *  Beschreibung : Falls ein Block markiert ist, wird dieser in einer vom
  1200. *                 Nutzer anzugebenden Datei abgespeichert. Dabei wird ge-
  1201. *                 testet, ob die Datei bereits existiert. Falls ja, wird der
  1202. *                 Nutzer gefragt, ob er die Datei ueberschreiben moechte.
  1203. *
  1204. *****************************************************************************/
  1205.  
  1206. void do_blwrite()
  1207. {
  1208.   /* *** interne Daten *** */
  1209.   char name[MAXLENGTH+1]; /* Array fuer einzulesenden Filenamen */
  1210.   FILE *f;                /* Pointer fuer Datei, in die Block geschrieben */
  1211.               /* werden soll. */
  1212.   if (block_defined())    /* Nur, wenn Block markiert ist */
  1213.   {
  1214.     print_stat(PROMPT_FILENAME);
  1215.     read_stat(name,MAXLENGTH,GS_ANY); /* Filenamen einlesen */
  1216.     clear_stat();                     /* Statuszeile wieder loeschen */
  1217.     if(name[0])                       /* Name leer ? */
  1218.     {
  1219.       setz_cursor(W_AKT);                  /* Nein, Cursor plazieren */
  1220.  
  1221.       /* Falls Datei schon existiert, Sicherheitsabfrage vornehmen, ob    */
  1222.       /* der User die Datei ueberschreiben moechte. Existiert die Datei   */
  1223.       /* und der User moechte sie nicht ueberschreiben, wird die Funktion */
  1224.       /* beendet.                                                         */
  1225.  
  1226.       if(!access(name,0) && !ja_nein(PROMPT_FILEEXIST))
  1227.       {
  1228.     setz_cursor(W_AKT);
  1229.     return;
  1230.       }
  1231.       if (f = fopen (name,"w"))  /* Datei oeffnen */
  1232.       {                          /* Klappte das, Block mit save_... aus */
  1233.     if (akt_winp->block.typ == BT_RECHTECK) /* Text ausschneiden */
  1234.       akt_winp->block.bstart = save_rechteck();
  1235.     else
  1236.       akt_winp->block.bstart = save_normal();
  1237.     schr_block(akt_winp->block.bstart,f); /* Block in offene Datei */
  1238.     fclose (f);                  /* schreiben und Datei schliessen */
  1239.     block_free (&akt_winp->block.bstart);   /* Blocktext freigeben */
  1240.       }
  1241.       else     /* Konnte Datei nicht geoeffnet werden, Fehlermeldung */
  1242.       {
  1243.     print_stat (PROMPT_ERRWRITE);
  1244.     pe_or(name);
  1245.       }
  1246.     }
  1247.     setz_cursor(W_AKT);
  1248.   }
  1249. }
  1250.  
  1251. /*****************************************************************************
  1252. *
  1253. *  Funktion       Zum Blockende gehen (do_goblend)
  1254. *  --------
  1255. *
  1256. *  Beschreibung : Falls der Blockanfang markiert ist, wird der Cursor dorthin
  1257. *                 gesetzt.
  1258. *
  1259. *****************************************************************************/
  1260.  
  1261. void do_goblend()
  1262. {
  1263.   if(akt_winp->block.e_line != -1)           /* Ist Blockende gesetzt ? */
  1264.   {
  1265.     akt_winp->lastline = akt_winp->textline; /* Ja, dann aktuelle Position */
  1266.     akt_winp->lastcol = akt_winp->screencol; /* als letzte Position merken */
  1267.     gotox(akt_winp->block.e_line);           /* Blockende anspringen */
  1268.     akt_winp->screencol = akt_winp->block.e_col;
  1269.     adapt_screen(1);                         /* Fensterinhalt evtl. anpassen */
  1270.   }
  1271. }
  1272.  
  1273. /*****************************************************************************
  1274. *
  1275. *  Funktion       Zum Blockanfang (do_goblanf)
  1276. *  --------
  1277. *
  1278. *  Beschreibung : Falls der Blockanfang markiert ist, wird der Cursor dorthin
  1279. *                 gesetzt.
  1280. *
  1281. *****************************************************************************/
  1282.  
  1283. void do_goblanf()
  1284. {
  1285.   if(akt_winp->block.s_line != -1)           /* Blockanfang definiert ? */
  1286.   {
  1287.     akt_winp->lastline = akt_winp->textline; /* Aktuelle Position als   */
  1288.     akt_winp->lastcol = akt_winp->screencol; /* letzte Position merken  */
  1289.     gotox(akt_winp->block.s_line);           /* Blockanfang anspringen  */
  1290.     akt_winp->screencol = akt_winp->block.s_col;
  1291.     adapt_screen(1);                         /* Evtl. Fensterinhalt anpassen */
  1292.   }
  1293. }
  1294.  
  1295. /*****************************************************************************
  1296. *
  1297. *  Funktion       Blockhervorhebungsmodus togglen (do_toghbl)
  1298. *  --------
  1299. *
  1300. *  Beschreibung : Das highblockflag wird getoggled. Dadurch wird die Darstel-
  1301. *                 lung eines markierten Blocks beeinflusst (gehighlighted oder
  1302. *                 nicht gehighlighted).
  1303. *
  1304. *****************************************************************************/
  1305.  
  1306. void do_toghbl()
  1307. {
  1308.   print_stat(PROMPT_BLKHILGHT); /* Meldung ueber den neuen Zustand */
  1309.   print_stat(on_off[highblockflag ^= TRUE]); /* ausgeben */
  1310.   sleep(1);
  1311.   /* Wenn ein Block markiert ist und dieser im Fenster sichtbar ist, */
  1312.   /* wird der Fensterinhalt neu dargestellt.                         */
  1313.   if(block_defined() && tst_overlap())
  1314.     sw_ohne_refresh(W_AKT);
  1315.   else         /* anderenfalls wird ein sleep ausgefuehrt, damit in bei- */
  1316.     sleep(1);  /* den Faellen die Meldung gleichlange zu lesen ist.      */
  1317.   clear_stat();
  1318.   setz_cursor(W_AKT);
  1319. }
  1320.  
  1321. /*****************************************************************************
  1322. *
  1323. *  Funktion       Block an Filter uebergeben (do_bltofil)
  1324. *  --------
  1325. *
  1326. *  Beschreibung : Falls ein Block markiert ist, wird dieser an ein vom Nutzer
  1327. *                 anzugebendes Filterprogramm uebergeben. Die Ausgabe des Fil-
  1328. *                 ters wird ueber eine Pipe eingelesen und als Block in den
  1329. *                 Text eingefuegt.
  1330. *
  1331. *****************************************************************************/
  1332.  
  1333. void do_bltofil()
  1334. {
  1335.   if (block_defined() && bl_to_fil())
  1336.   {
  1337.     if (akt_winp->textline < akt_winp->ws_line)  /* Falls Cursor durch das  */
  1338.       akt_winp->ws_line = akt_winp->textline;    /* Filtern des Blocks      */
  1339.     if (akt_winp->screencol < akt_winp->ws_col)  /* ausserhalb des Fensters */
  1340.       akt_winp->ws_col = akt_winp->screencol;    /* steht, Fenster anpassen */
  1341.     show_win(W_AKT);
  1342.   }
  1343. }
  1344.  
  1345. /*****************************************************************************
  1346. *
  1347. *  Funktion       Shellflag invertieren (do_shelltog)
  1348. *  --------
  1349. *
  1350. *  Beschreibung : Das shellflag der aktuellen Windowstruktur wird invertiert.
  1351. *
  1352. *****************************************************************************/
  1353.  
  1354. void do_shelltog()
  1355. {
  1356.   akt_winp->shellflag ^= TRUE;
  1357.   setz_cursor(W_AKT);      /* Kopfzeile aktualisieren */
  1358. }
  1359.  
  1360.  
  1361. /*****************************************************************************
  1362. *
  1363. *  Funktion       Marker setzen (do_setmarker)
  1364. *  --------
  1365. *
  1366. *  Beschreibung : Falls der Text nicht leer ist, wird der Nutzer nach der
  1367. *                 Markernummer (0-9) gefragt. Fuer den angegebenen Marker
  1368. *                 werden dann Position und Fensternummer gespeichert.
  1369. *
  1370. *****************************************************************************/
  1371.  
  1372. void do_setmarker()
  1373. {
  1374.   /* *** interne Daten *** */
  1375.   int m;   /* Nummer des gewuenschten Markers */
  1376.  
  1377.   if(akt_winp->maxline >= 0)  /* Text nicht leer ? */
  1378.   {
  1379.     if(helpflag)
  1380.       print_stat(PROMPT_MARKER);
  1381.     m = newwgetch(status) - '0'; /* Markernummer einlesen */
  1382.     if(helpflag)
  1383.       clear_stat();
  1384.     if(m >= 0 && m <= 9)         /* Bereich ueberpruefen */
  1385.     {
  1386.       marker[m].col = akt_winp->screencol; /* aktuelle Position und */
  1387.       marker[m].line = akt_winp->textline; /* Fensternummer eintragen */
  1388.       marker[m].window = akt_winp->wini;
  1389.       setz_cursor(W_AKT);
  1390.     }
  1391.     else                         /* Bereichspruefung schlug fehl */
  1392.       print_err(PROMPT_ERRMARKER);
  1393.   }
  1394. }
  1395.  
  1396. /*****************************************************************************
  1397. *
  1398. *  Funktion       Marker anspringen (do_jumpmarker)
  1399. *  --------
  1400. *
  1401. *  Beschreibung : Der Nutzer wird nach der Nummer des anzuspringenden Markers
  1402. *                 gefragt. Existiert der Marker, oder das zu dem Marker gehoe-
  1403. *                 rende fenster nicht mehr, so wird eine Meldung ausgegeben.
  1404. *                 Sonst wird das zum Marker gehoerige Fenster zum aktuellen
  1405. *                 Fenster, und der Cursor wird richtig positioniert.
  1406. *
  1407. *****************************************************************************/
  1408.  
  1409. void do_jumpmarker()
  1410. {
  1411.   /* *** interne Daten *** */
  1412.   int     m;        /* Nummer des gewuenschten Markers */
  1413.   win_typ *old_win; /* Zwischenspeicher fuer beim Aufruf aktuelles Fenster */
  1414.  
  1415.   if(helpflag)
  1416.     print_stat(PROMPT_MARKER);
  1417.   m = newwgetch(status) - '0';  /* Markernummer einlesen */
  1418.   if(helpflag)
  1419.     clear_stat();
  1420.   if(m >= 0 && m <= 9)          /* Bereichspruefung fuer Markernummer */
  1421.     if(marker[m].window != -1)  /* Ist Marker gesetzt ? */
  1422.     {
  1423.       kopf(W_NOTAKT);   /* Altes Fenster als inaktiv markieren */
  1424.       rahmen(W_NOTAKT);
  1425.       wrefresh(akt_winp->winp);
  1426.  
  1427.       check_buff();             /* Pufferinhalt evtl. in Text eintragen */
  1428.       old_win = akt_winp;
  1429.       if(make_akt_win(marker[m].window)) /* zum Fenster gehen, in dem */
  1430.       {                                  /* der Marker gesetzt wurde  */
  1431.     akt_winp->lastcol  = akt_winp->screencol; /* aktuelle Position */
  1432.     akt_winp->lastline = akt_winp->textline; /*  als letzte merken */
  1433.  
  1434.     /* Steht der Marker hinter dem Textende, dann zur letzten Zeile  */
  1435.     /* gehen. Andernfalls die vom Marker angegebene Zeile anspringen */
  1436.     /* Falls Text leer, geht gotox richtig auf dummyp.               */
  1437.     gotox(akt_winp->maxline <= marker[m].line?akt_winp->maxline:marker[m].line);
  1438.     /* Falls Text leer, dann Spalte 0, sonst richtige Markerspalte */
  1439.     akt_winp->screencol = akt_winp->maxline>=0 ? marker[m].col : 0;
  1440.     if(old_win != akt_winp) /* Falls nicht aktuelles Fenster, dann */
  1441.       show_win(W_AKT);      /* Fensterkomplett neu zeichnen        */
  1442.     else
  1443.       rahmen(W_AKT);        /* Sonst Fenster wieder aktiv */
  1444.     adapt_screen(1);        /* Fensterinhalt anpassen              */
  1445.       }
  1446.       else /* Fenster konnte nicht angesprungen werden, Meldung ausgeben */
  1447.     print_err(PROMPT_STALEMARK);
  1448.     }
  1449.     else
  1450.       print_err(PROMPT_EMPTYMARK);
  1451.   else
  1452.     print_err(PROMPT_ERRINPUT);
  1453. }
  1454.  
  1455. /*****************************************************************************
  1456. *
  1457. *  Funktion       Letzte Position anspringen (do_lastpos)
  1458. *  --------
  1459. *
  1460. *  Beschreibung : Es wird die letzte Position vor einem Find/Replace/Goto/
  1461. *                 lastpos/Marker angesprungen. Diese Position ist Fenster-
  1462. *                 intern.
  1463. *
  1464. *****************************************************************************/
  1465.  
  1466. void do_lastpos()
  1467. {
  1468.   /* *** interne Daten und Initialisierung *** */
  1469.   int hilf = akt_winp->textline; /* Zwischenspeicher fuer Zeilennummer */
  1470.  
  1471.   if(akt_winp->lastline != -1)   /* Letzte Position gesetzt ? */
  1472.   {
  1473.     /* aktuelle Spalte als letzte Spalte merken, letzte Spalte zur */
  1474.     /* aktuellen machen                                            */
  1475.     swap_int(&akt_winp->screencol,&akt_winp->lastcol);
  1476.     gotox(akt_winp->lastline);  /* Letzte Zeile anspringen */
  1477.     akt_winp->lastline = hilf;  /* Vorher aktuelle Zeile wird Letzte Z. */
  1478.     adapt_screen(1);            /* Fensterinhalt anpassen */
  1479.   }
  1480. }
  1481.  
  1482. /*****************************************************************************
  1483. *
  1484. *  Funktion       Window gemaess Name anspringen (do_swname)
  1485. *  --------
  1486. *
  1487. *  Beschreibung : Der Nutzer kann einen Dateinamen eingeben. Falls die
  1488. *                 Nummer existiert, wird das Fenster mit diesem Namen
  1489. *                 zum aktuellen Fenster.
  1490. *
  1491. *****************************************************************************/
  1492.  
  1493. void do_swname()
  1494. {
  1495.   /* *** interne Daten und Initialisierung *** */
  1496.   char filename[MAXLENGTH+1]; /* Array fuer einzulesenden Filenamen    */
  1497.   int  wn = akt_winp->wini;   /* Zwischenspeicher fuer akt. Fensternr. */
  1498.  
  1499.   print_stat (PROMPT_FILENAME);
  1500.   read_stat (filename,MAXLENGTH,GS_ANY);  /* Filenamen einlesen */
  1501.   clear_stat();
  1502.   if(!filename[0])                        /* Filename leer ? */
  1503.   {
  1504.     setz_cursor(W_AKT);                        /* Dann verlassen */
  1505.     return;
  1506.   }
  1507.   kopf(W_NOTAKT);   /* Altes Fenster als inaktiv markieren */
  1508.   rahmen(W_NOTAKT);
  1509.   wrefresh(akt_winp->winp);
  1510.  
  1511.   check_buff();               /* sonst Pufferinhalt evtl. in Text eintragen, */
  1512.   if (sw_name(filename))      /* versuchen, gewuenschtes Fenster zum aktu- */
  1513.   {                           /* ellen zu machen. */
  1514.     if(akt_winp->wini == wn)  /* War es das aktuelle Fenster ? */
  1515.     {
  1516.       rahmen(W_AKT);          /* Fenster wird evtl. wieder aktiv */
  1517.       setz_cursor(W_AKT);          /* Dann nur Cursor setzen */
  1518.     }
  1519.     else                      /* Sonst komplettes Fenster neu zeichnen */
  1520.       show_win(W_AKT);
  1521.   }
  1522.   else                        /* Fenster nicht gefunden */
  1523.     /* Abfragen, ob Datei geladen werden soll */
  1524.     if(ja_nein(PROMPT_NEWWINDOW))
  1525.     {
  1526.       kopf(W_NOTAKT);   /* Altes Fenster als inaktiv markieren */
  1527.       rahmen(W_NOTAKT);
  1528.       wrefresh(akt_winp->winp);
  1529.  
  1530.       if (koppel_win())   /* Soll Datei neu geladen werden, */
  1531.       {                   /* dann neues Fenster erzeugen */
  1532.     akt_winp->filename = save_text(filename); /* Filenamen eintragen */
  1533.     akt_winp->block.bstart = (bzeil_typ*) NULL;
  1534.     if (!lies_file())  /* Datei in neues Fenster einlesen */
  1535.     {
  1536.       gb_win_frei();   /* Klappte das nicht, Fenster wieder loeschen, */
  1537.       rahmen(W_AKT);   /* Fenster highlighten */
  1538.       setz_cursor(W_AKT);   /* und Cursor an richtige Position */
  1539.     }
  1540.     else               /* Sonst Fensterwerte initialisieren */
  1541.       open_window();
  1542.       }
  1543.       else                 /* koppel_win klappte nicht */
  1544.       {
  1545.     pe_or("Zu viele Fenster! ");
  1546.     rahmen(W_AKT); /* Altes Fenster wieder aktiv */
  1547.     setz_cursor(); /* Cursor an richtige Position */
  1548.       }
  1549.     }
  1550.     else                   /* Fenster nicht gefunden, Datei soll aber */
  1551.     {
  1552.       rahmen(W_AKT);       /* Fenster highlighten */
  1553.       setz_cursor(W_AKT);       /* auch nicht neu geladen werden */
  1554.     }
  1555. }
  1556.  
  1557. /*****************************************************************************
  1558. *
  1559. *  Funktion       Datei unter neuem Namen abspeichern (do_newname)
  1560. *  --------
  1561. *
  1562. *  Beschreibung : Der Dateiname der Datei im aktuellen Fenster wird intern
  1563. *                 geaendert und der Text unter dem neuen Namen abgespeichert.
  1564. *
  1565. *****************************************************************************/
  1566.  
  1567. void do_newname()
  1568. {
  1569.   /* *** interne Daten *** */
  1570.   char name[MAXLENGTH+1];  /* Array fuer einzulesenden neuen Namen */
  1571.  
  1572.   print_stat(PROMPT_FILENAME);
  1573.   read_stat(name,MAXLENGTH,GS_ANY); /* Dateinamen einlesen */
  1574.   clear_stat();
  1575.   if(!name[0])                      /* Leerer Name, dann raus */
  1576.   {
  1577.     pos_cursor();
  1578.     return;
  1579.   }
  1580.   free(akt_winp->filename);         /* Sonst alten Namen freigeben       */
  1581.   akt_winp->attribs = STD_FATTR;    /* Attribute und read_only-Status    */
  1582.   akt_winp->read_only = FALSE;      /* initialisieren                    */
  1583.   akt_winp->filename = save_text(name); /* Neuen Namen abspeichern       */
  1584.   schreib_file();                   /* Datei unter neuem Namen speichern */
  1585.   setz_cursor(W_AKT);
  1586. }
  1587.  
  1588. /*****************************************************************************
  1589. *
  1590. *  Funktion       Macro definieren/ausfuehren (do_macro)
  1591. *  --------
  1592. *
  1593. *  Beschreibung : Nach Eingabe eines Grossbuchstabens kann der Benutzer
  1594. *                 einen Macro definieren, indem er die dem Macro zuzu-
  1595. *                 ordnenden Tasten drueckt. Beendet wird die Macrodefinition
  1596. *                 durch Druck der ESCAPE-Taste (get_comstr()).
  1597. *                 Nach Eingabe eines Kleinbuchstabens wird der entsprechende
  1598. *                 Macro - falls definiert - aufgerufen.
  1599. *
  1600. *****************************************************************************/
  1601.  
  1602. void do_macro()
  1603. {
  1604.   /* *** interne Daten *** */
  1605.   short int mnum;  /* Zum einlesen des Macrobuchstabens */
  1606.  
  1607.   if(helpflag)
  1608.     print_stat(PROMPT_MACRO);
  1609.   mnum = newwgetch(status);  /* Macrobuchstaben einlesen */
  1610.   if(helpflag)
  1611.     clear_stat();
  1612.   if(mnum>='A' && mnum<='Z') /* Macro definieren ? */
  1613.   {
  1614.     mnum -= 'A';
  1615.     line_free(macro[mnum].begin); /* vorherigen Macrotext freigeben */
  1616.     get_comstr(¯o[mnum].begin,¯o[mnum].end); /* und neuen einlesen */
  1617.   }
  1618.   else                       /* Macro ausfuehren */
  1619.     exec_macro(mnum);
  1620.   setz_cursor(W_AKT);
  1621. }
  1622.  
  1623. /*****************************************************************************
  1624. *
  1625. *  Funktion       Geloeschte Zeile wiederherstellen (do_restline)
  1626. *  --------
  1627. *
  1628. *  Beschreibung : Mittels rest_delline() wird die zuletzt geloeschte Zeile
  1629. *                 bzw. eine Leerzeile vor der aktuellen Zeile eingefuegt.
  1630. *
  1631. *****************************************************************************/
  1632.  
  1633. void do_restline()
  1634. {
  1635.   if(akt_winp->maxline < MAX_ANZ_LINES-1) /* noch Platz da? */
  1636.   {
  1637.     rest_delline();
  1638.     show_win(W_AKT);
  1639.   }
  1640.   else                /* Kein Platz mehr, Fehlermeldung ausgeben */
  1641.     print_err(T_SIZE_ERRTEXT);
  1642. }
  1643.  
  1644. /*****************************************************************************
  1645. *
  1646. *  Funktion       Alle modifizierten Files loeschen (do_saveall)
  1647. *  --------
  1648. *
  1649. *  Beschreibung : Ruft save_all auf, um alle geaenderten Dateien zu sichern.
  1650. *                 Anschliessend wird ein Refresh ausgefuehrt.
  1651. *
  1652. *****************************************************************************/
  1653.  
  1654. void do_saveall()
  1655. {
  1656.   save_all();
  1657.   show_win(W_AKT);
  1658. }
  1659.  
  1660. /*****************************************************************************
  1661. *
  1662. *  Funktion       Aktuellen Absatz reformatieren (do_reflow)
  1663. *  --------
  1664. *
  1665. *  Beschreibung : Der bis zur nächsten Leerzeile reichende Absatz wird
  1666. *                 reformatiert. Als rechter Rand wird der rechte Fenster-
  1667. *                 rand verwendet. Als linker Rand wird, wenn autoindent
  1668. *                 eingestellt ist, die Spalte der aktuellen Zeile, in der
  1669. *                 das erste Zeichen steht, verwendet. Sonst wird die erste
  1670. *                 Spalte als linker Rand verwendet.
  1671. *
  1672. *****************************************************************************/
  1673.  
  1674. void do_reflow()
  1675. {
  1676.   reflow_paragraph();
  1677.   show_win(W_AKT);
  1678. }
  1679.  
  1680. void (*funktion [])() = {do_refresh, do_bol, do_eol, do_halfup, do_halfdn,
  1681.              do_delete, do_backspace, do_home, do_nothome, 
  1682.              do_insovr, do_textbeginn, do_eot, do_del_word, 
  1683.              do_wleft, do_wright, do_right, do_left, do_up, 
  1684.              do_down, do_pgup, do_pgdn, (void (*)()) do_newline, 
  1685.              do_delline, ueberschreiben, do_schreib_file,quit, 
  1686.              do_control, do_help, do_movewin, do_sizewin, 
  1687.              do_swnext, do_swprev, do_swnum, laden, do_win_zu, 
  1688.              do_goto, do_ende, do_find, do_replace, 
  1689.              do_underline, do_z_hoch, do_z_runter, do_z_oben, 
  1690.              do_z_mitte, do_z_unten, do_deleol, do_toggle_size, 
  1691.              do_repfr, do_repeat, do_repfr, do_join, do_open, 
  1692.              do_tog_ai, do_tab, do_settab, do_tog_tkm, 
  1693.              do_blstart, do_blnormend, do_blrechtend, 
  1694.              do_blunmark, do_blweg, do_blcopy, do_blmove, 
  1695.              do_blcut, do_blpaste, do_blindent, do_blread, 
  1696.              do_blwrite, do_goblend, do_goblanf, do_toghbl, 
  1697.              do_bltofil, do_setmarker, do_jumpmarker, 
  1698.              do_lastpos, do_hopen, do_swname, do_newname, 
  1699.              do_backtab, do_tog_bak, do_macro, do_restline, 
  1700.              do_shelltog, do_endemit,quitmit, do_delete, 
  1701.              do_togregex, do_matchpar, do_middle, do_saveall, 
  1702.              do_reflow, do_tog_lb, do_inschar };
  1703.  
  1704. /*****************************************************************************
  1705. *
  1706. *  Funktion       Tastendruck auswerten (auswertung)
  1707. *  --------
  1708. *
  1709. *  Parameter    : t         :
  1710. *                   Typ          : int
  1711. *                   Wertebereich : 0-MAX_COMM_INDEX
  1712. *                   Bedeutung    : Nummer des Befehls. Ist t == BUCHSTABE,
  1713. *                                  dann steht der Buchstabe in letter.
  1714. *
  1715. *  Beschreibung : Anhand des Kommandos wird eine Funktion aufgerufen, die
  1716. *                 den Befehl ausfuehrt.
  1717. *
  1718. *****************************************************************************/
  1719.  
  1720. void auswertung (t)
  1721. int t;
  1722. {
  1723.   hide_show(MOUSE_HIDE);  /* Maus vor Ausführung der Operation verstecken */
  1724.   (*funktion[t])();
  1725.   hide_show(MOUSE_SHOW);  /* Maus nach der Operation wieder anzeigen */
  1726. }
  1727.