| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520 |
- MODULE nanotext;
- FROM Storage IMPORT ALLOCATE , DEALLOCATE;
- IMPORT Lib,Str,IO,Window,FIO;
- TYPE t_ptr_t_element = POINTER TO t_element;
- t_element = CLASS
- ptr_suivant : t_ptr_t_element;
- ptr_precedent : t_ptr_t_element;
- PROCEDURE affiche_element () ; VIRTUAL;
- BEGIN
- (* … impl‚menter par les objets fils *)
- END affiche_element;
- PROCEDURE detruit_element () ; VIRTUAL;
- BEGIN
- (* … impl‚menter par les objets fils *)
- END detruit_element;
- END; (* CLASS t_element *)
- TYPE t_liste = CLASS
- debut : t_ptr_t_element;
- ptr_courant : t_ptr_t_element;
- PROCEDURE creer() ;
- BEGIN
- debut := NIL;
- ptr_courant := NIL;
- END creer;
- PROCEDURE premier () : t_ptr_t_element ;
- BEGIN
- RETURN debut;
- END premier;
- PROCEDURE au_debut () ;
- (* d‚place le pointeur courant au d‚but de la liste *)
- BEGIN
- ptr_courant := debut;
- END au_debut;
- PROCEDURE suivant () : t_ptr_t_element;
- BEGIN
- RETURN ptr_courant^.ptr_suivant;
- END suivant;
- PROCEDURE a_la_fin ();
- (* d‚place le pointeur courant en queue de liste *)
- BEGIN
- WHILE suivant() <> NIL DO
- ptr_courant := ptr_courant^.ptr_suivant;
- END;
- END a_la_fin;
- PROCEDURE au_suivant ();
- (* d‚place le pointeur courant au paragraphe suivant si possible *)
- BEGIN
- IF suivant() <> NIL THEN
- ptr_courant := suivant();
- END;
- END au_suivant;
- PROCEDURE precedent () : t_ptr_t_element;
- BEGIN
- RETURN ptr_courant^.ptr_precedent;
- END precedent;
- PROCEDURE au_precedent ();
- (* d‚place le pointeur courant au paragraphe precedent si possible *)
- BEGIN
- IF precedent() <> NIL THEN
- ptr_courant := precedent();
- END;
- END au_precedent;
- PROCEDURE dernier ():t_ptr_t_element;
- BEGIN
- au_debut();
- WHILE suivant() <> NIL DO
- au_suivant();
- END;
- RETURN ptr_courant;
- END dernier;
- PROCEDURE liste_vide():BOOLEAN ;
- BEGIN
- RETURN debut = NIL;
- END liste_vide;
- PROCEDURE ajouter ( VAR y : t_element);
- VAR l_ptr_element : t_ptr_t_element;
- (* on ajoute en fin de liste :
- 2 cas : liste vide
- : liste non vide
- *)
- BEGIN
- ALLOCATE(l_ptr_element,SIZE(y));
- Lib.Move(ADR(y),l_ptr_element,SIZE(y));
- IF liste_vide() THEN (* cas du debut de liste vide *)
- debut := l_ptr_element;
- ptr_courant := l_ptr_element ;
- ptr_courant^.ptr_precedent := NIL;
- ptr_courant^.ptr_suivant := NIL;
- ELSE (* ajout en fin de liste *)
- l_ptr_element^.ptr_suivant := NIL;
- l_ptr_element^.ptr_precedent := ptr_courant;
- ptr_courant^.ptr_suivant := l_ptr_element;
- ptr_courant := l_ptr_element;
- END;
- END ajouter;
- PROCEDURE inserer (VAR y : t_element);
- (* On insŠre AVANT le pointeur courant !!!!!!!!! *)
- (* 2 cas : insertion en d‚but de liste
- insertion au milieu de liste
- *)
- VAR l_ptr_element : t_ptr_t_element;
- BEGIN
- ALLOCATE(l_ptr_element,SIZE(y));
- Lib.Move(ADR(y),l_ptr_element,SIZE(y));
- IF ptr_courant^.ptr_precedent = NIL THEN (* cas du d‚but de liste non vide *)
- debut := l_ptr_element;
- l_ptr_element^.ptr_precedent := NIL;
- l_ptr_element^.ptr_suivant := ptr_courant;
- ptr_courant^.ptr_precedent := l_ptr_element;
- ptr_courant := debut^.ptr_suivant;
- ELSE (* cas du milieu de liste *)
- ptr_courant^.ptr_precedent^.ptr_suivant := l_ptr_element;
- l_ptr_element^.ptr_suivant := ptr_courant;
- l_ptr_element^.ptr_precedent := ptr_courant^.ptr_precedent;
- ptr_courant^.ptr_precedent := l_ptr_element;
- ptr_courant := l_ptr_element^.ptr_suivant;
- END; (* IF *)
- END inserer;
- PROCEDURE inserer_liste ( VAR x : t_liste);
- BEGIN
- END inserer_liste;
- PROCEDURE detruire ();
- (* on detruit l'element du pointeur courant *)
- VAR l_ptr_element,ll_ptr_element : t_ptr_t_element;
- BEGIN
- ptr_courant^.detruit_element;
- IF ptr_courant^.ptr_precedent = NIL THEN
- (* cas du premier element de la liste **)
- (* 2 cas : liste compos‚e d'un element
- : liste composee de plusieurs elements *)
- IF ptr_courant^.ptr_suivant = NIL THEN
- DEALLOCATE(ptr_courant,SIZE(ptr_courant^));
- debut := NIL;
- ptr_courant := NIL;
- ELSE
- ptr_courant := ptr_courant^.ptr_suivant;
- ptr_courant^.ptr_precedent := NIL;
- DEALLOCATE(debut,SIZE(debut^));
- debut := ptr_courant;
- END; (* IF *)
- ELSIF ptr_courant^.ptr_suivant = NIL THEN
- (* cas d'un ‚l‚ment en fin de liste *)
- ptr_courant := ptr_courant^.ptr_precedent;
- DEALLOCATE(ptr_courant^.ptr_suivant,SIZE(ptr_courant^.ptr_suivant^));
- ptr_courant^.ptr_suivant := NIL;
- ELSE
- (* cas g‚n‚ral d'un ‚l‚ment au milieu de liste *)
- l_ptr_element := ptr_courant^.ptr_suivant;
- l_ptr_element^.ptr_precedent := ptr_courant^.ptr_precedent;
- ptr_courant^.ptr_precedent^.ptr_suivant := l_ptr_element;
- DISPOSE(ptr_courant);
- ptr_courant := l_ptr_element;
- END ; (* IF *)
- END detruire;
- END; (* CLASS t_liste *)
- TYPE t_ptr_t_paragraphe = POINTER TO t_paragraphe;
- t_paragraphe = CLASS (t_element)
- longueur : CARDINAL;
- ptr_chaine : ADDRESS;
- PROCEDURE initialise_element ( VAR x : ARRAY OF CHAR);VIRTUAL;
- BEGIN
- longueur := Str.Length(x);
- ALLOCATE(ptr_chaine,longueur);
- Lib.Move(ADR(x),ptr_chaine,longueur);
- END initialise_element;
- PROCEDURE affiche_element (); VIRTUAL;
- VAR l_tampon : ARRAY[0..1023] OF CHAR;
- BEGIN
- Lib.Move(ptr_chaine,ADR(l_tampon),longueur);
- l_tampon[longueur] := CHR(0);
- IO.WrStr(l_tampon);
- IO.WrLn;
- END affiche_element;
- PROCEDURE detruit_element () ; VIRTUAL;
- BEGIN
- DEALLOCATE(ptr_chaine,SIZE(ptr_chaine^));
- END detruit_element;
- END; (* CLASS t_paragraphe *)
- (* le tampon est notre zone de travail : c'est dans lui que seront
- faites toutes les insertions et destructions , recherches ;
- donc le test des touches frapp‚es au clavier vont provoquer
- le transfert dans le tampon de notre paragraphe, et toutes les
- modifications se feront dans celui-ci; ceci nous procure en
- plus une fonction UNDO facile car le texte original n'est pas
- modifi‚ tant que le transfert inverse n'est pas r‚alis‚.
- Nous pourons sauvegarder toutes nos modifications dans une
- liste que nous pourrons ‚diter ou sauvegarder … souhait *)
- TYPE (* t_ptr_t_tampon = POINTER TO t_tampon;*)
- t_tampon = CLASS (t_paragraphe)
- position : CARDINAL;
- sauve_ptr_suivant : t_ptr_t_element;
- suve_ptr_precedent : t_ptr_t_element;
- la_liste : ADDRESS ; (* adresse de la liste *)
- PROCEDURE initialise_element ( VAR x : ARRAY OF CHAR ) ; VIRTUAL ;
- BEGIN
- (* notre tampon est un paragraphe particulier d'une taille
- de 32 Kilo-octets *)
- longueur := Str.Length(x);
- ALLOCATE(ptr_chaine,32*1024-1);
- Lib.Fill(ptr_chaine,32*1024-1,0);
- Lib.Move(ADR(x),ptr_chaine,longueur);
- END initialise_element;
- PROCEDURE insere ( x : ARRAY OF CHAR );
- VAR adresse1,adresse2 : ADDRESS;
- BEGIN
- adresse1 := Lib.AddAddr(ptr_chaine,position-1);
- IF position <= longueur THEN
- adresse2 := Lib.AddAddr(adresse1,Str.Length(x));
- Lib.Move(adresse1,adresse2,longueur-position+1);
- INC(longueur,Str.Length(x));
- Lib.Move(ADR(x),adresse1,Str.Length(x));
- ELSE
- adresse2 := Lib.AddAddr(ptr_chaine,longueur);
- Lib.Move(ADR(x),adresse1,Str.Length(x));
- Lib.Fill(adresse2,position-longueur-1,020H);
- longueur := position + Str.Length(x);
- END;
- END insere;
- PROCEDURE remplace ( x : ARRAY OF CHAR );
- VAR adresse : ADDRESS;
- BEGIN
- adresse := Lib.AddAddr(ptr_chaine,position-1);
- Lib.Move(ADR(x),adresse,Str.Length(x));
- END remplace;
- PROCEDURE detruit ( x : CARDINAL );
- VAR adresse1,adresse2 : ADDRESS;
- BEGIN
- adresse1 := Lib.AddAddr(ptr_chaine,position + x - 1);
- adresse2 := Lib.AddAddr(ptr_chaine,position-1);
- Lib.Move(adresse1,adresse2,longueur-position);
- adresse1 := Lib.AddAddr(ptr_chaine,longueur);
- Lib.Fill(adresse1,x,0);
- DEC(longueur,x);
- END detruit;
- END; (* CLASS t_tampon *)
- TYPE t_fenetre = Window.WinDef;
- t_parametres = RECORD
- longueur_page : CARDINAL;
- largeur_ligne : CARDINAL;
- marge_haute : CARDINAL;
- marge_basse : CARDINAL;
- marge_droite : CARDINAL;
- marge_gauche : CARDINAL;
- largeur_tabulation : CARDINAL;
- entete : BOOLEAN;
- bas_de_page : BOOLEAN;
- END;
- TYPE t_ptr_t_texte = POINTER TO t_texte;
- t_texte = CLASS (t_liste)
- tampon : t_tampon;
- fenetre : Window.WinDef;
- parametres : t_parametres;
- ptr_fenetre : Window.WinType;
- curseurx : CARDINAL;
- curseury : CARDINAL;
- pos_fen_ds_txt : CARDINAL;
- PROCEDURE initialise_texte( VAR x : Window.WinDef;
- VAR y : t_parametres);
- BEGIN
- creer();
- fenetre := x;
- parametres := y;
- ptr_fenetre := Window.Open(fenetre);
- END initialise_texte;
- PROCEDURE transfert_avant(); VIRTUAL;
- BEGIN
- END transfert_avant;
- PROCEDURE transfert_arriere(); VIRTUAL;
- BEGIN
- END transfert_arriere;
- PROCEDURE page_up(); VIRTUAL;
- BEGIN
- END page_up;
- PROCEDURE page_down(); VIRTUAL;
- BEGIN
- END page_down;
- PROCEDURE affiche_page(); VIRTUAL;
- BEGIN
- END affiche_page;
- END; (* CLASS t_texte *)
- TYPE t_ptr_t_paragraf= POINTER TO t_paragraf;
- t_paragraf = CLASS (t_paragraphe)
- la_liste : t_ptr_t_texte; (* adresse de la liste *)
- PROCEDURE init_adresse(VAR x : t_ptr_t_texte );
- BEGIN
- la_liste := x;
- END init_adresse;
- PROCEDURE affiche_element(); VIRTUAL ;
- (*le texte contenu dans notre paragraphe est d‚j… justifi‚ *)
- TYPE l_ptr_tampon = POINTER TO l_t_tampon;
- l_t_tampon = ARRAY[0..32*1024-1] OF CHAR;
- VAR l_tampon : l_ptr_tampon;
- l_chaine : ARRAY[0..255] OF CHAR;
- i,j : CARDINAL;
- BEGIN
- NEW(l_tampon);
- Lib.Move(ptr_chaine,l_tampon,longueur);
- l_tampon^[longueur] := CHR(0);
- i := 0;
- LOOP
- Str.Slice(l_chaine,l_tampon^,i,la_liste^.parametres.largeur_ligne);
- (* affichage de la marge *)
- IF la_liste^.parametres.marge_gauche >= la_liste^.pos_fen_ds_txt THEN
- IO.WrCharRep(" ",la_liste^.parametres.marge_gauche - la_liste^.pos_fen_ds_txt) ;
- IO.WrStr(l_chaine);
- ELSE
- Str.Slice(l_chaine,l_chaine,la_liste^.pos_fen_ds_txt,
- la_liste^.parametres.largeur_ligne - la_liste^.pos_fen_ds_txt);
- END;
- IO.WrCharRep(" ",la_liste^.parametres.marge_droite);
- IO.WrLn;
- IF Str.Length(l_chaine)< la_liste^.parametres.largeur_ligne THEN
- EXIT
- END;
- INC(i,30);
- END;
- DISPOSE(l_tampon);
- END affiche_element;
- END; (* class t_paragraf *)
- PROCEDURE attente;
- BEGIN
- REPEAT UNTIL IO.KeyPressed();
- END attente;
- VAR mon_texte : t_texte;
- ptr_mon_texte : t_ptr_t_texte;
- el : t_paragraf;
- a : Window.WinDef;
- b : t_parametres;
- VAR fichier : FIO.File;
- buffer : ARRAY[0..10000] OF CHAR;
- car : CHAR;
- PROCEDURE affiche;
- VAR g : t_ptr_t_paragraphe;
- BEGIN
- mon_texte.au_debut();
- REPEAT
- mon_texte.ptr_courant^.affiche_element();
- mon_texte.au_suivant();
- UNTIL mon_texte.suivant() = NIL;
- mon_texte.ptr_courant^.affiche_element();
- END affiche;
- PROCEDURE message (x : ARRAY OF CHAR);
- BEGIN
- Lib.Delay(5000);
- Window.Clear;
- IO.WrStr(x);
- IO.WrLn;
- END message;
- BEGIN (* principal *)
- WITH a DO
- X1 := 10;
- X2 := 50;
- Y1 := 1;
- Y2 := 25;
- Foreground := Window.Brown;
- Background := Window.Blue;
- CursorOn := TRUE;
- WrapOn := FALSE;
- Hidden := FALSE;
- FrameOn := TRUE;
- FrameDef := Window.DoubleFrame;
- FrameFore := Window.Blue;
- FrameBack := Window.Brown;
- END;
- WITH b DO
- longueur_page := 60;
- largeur_ligne := 40;
- marge_haute := 3;
- marge_basse := 3;
- marge_droite := 15;
- marge_gauche := 15;
- largeur_tabulation := 8;
- entete := TRUE;
- bas_de_page := TRUE;
- END;
- (************** CREATION DE LA LISTE ****************)
- mon_texte.initialise_texte(a,b);
- mon_texte.pos_fen_ds_txt := 10;
- ptr_mon_texte := ADR(mon_texte);
- (************** on remplit la liste *****************)
- message(" ON REMPLIT LA LISTE ");
- fichier := FIO.Open("c:\mii\mod.mod\texte1.MOD");
- FIO.EOF := FALSE;
- FIO.RdStr(fichier,buffer);
- WHILE NOT FIO.EOF DO
- el.initialise_element(buffer);
- el.init_adresse(ptr_mon_texte);
- mon_texte.ajouter(el);
- FIO.RdStr(fichier,buffer);
- END;
- (************ on parcoure la liste en avant **********)
- message(" ON parcoure LA LISTE en avant");
- affiche;
- attente;
- message(" Fin du programme");
- FIO.Close(fichier);
- END nanotext.
|