Liens multiples▲
Introduction▲
Les chapitres précédents ont donné accès à une liste considérable de mots français et permis de construire avec Lazarus un outil permettant :
- de parcourir la liste à volonté ;
- d'établir avec chaque mot un lien avec une information quelconque : texte, image, son, fichier.
Mais ce potentiel reste modeste. Il est limité en particulier par l'unicité du lien autorisé par les propriétés génériques Value ou Object du composant Liste.
Dans le présent chapitre, nous allons voir comment établir des liens multiples.
Environnement▲
Chapitre 6…
Créons un répertoire Lex6 et recopions dans ce nouveau répertoire tous les fichiers du répertoire Lex5 utilisé précédemment. Pour éviter toute difficulté ultérieure, suivez la check-list :
- ouvrir pLex5.lpi dans Lex6 avec Lazarus ;
- enregistrer uLex5.pas sous le nom uLex6.pas ;
- accepter la suppression des références à uLex5.pas ;
- enregistrer pLex5.pas sous le nom pLex6.pas ;
- renommer la fenêtre Form1 : Lex5 devient Lex6 ;
- dans le répertoire Lex6 supprimer les anciens fichiers contenant la mention Lex5.
Nous retrouvons le projet dans l'état où nous l'avions laissé, et les modifications que nous allons effectuer n'affecteront pas l'étape précédente consultable dans le répertoire Lex5.
Architecture▲
Chaque mot de la liste principale est affecté d'un numéro implicite qui correspond à sa place dans la liste. Au niveau du code, rappelons que connaissant le numéro, la fonction liste[numéro] donne accès à la chaîne de caractères, et inversement, la fonction liste.IndexOf(mot) explicite le numéro du mot ou retourne -1 si le mot n'existe pas.
Nous allons exploiter ces fonctions pour accéder à une table auxiliaire. Par exemple, le mot « a » possède le numéro 0 (zéro) en tant que premier de la liste.
Tableaux de liens▲
Nous créons un tableau de nombres entiers, de longueur variable, dont le premier élément, qui sera son identifiant, sera ce numéro. Si on décide, par exemple, de stocker les quatre valeurs 5555, 101, 100 et 6006 en liaison avec le mot « a », notre tableau aura une capacité (longueur) de cinq cases se présentant ainsi :
Numéro identifiant |
lien1 | lien2 | lien3 | lien4 |
0 | 5555 | 101 | 100 | 6006 |
Le premier entier, nous savons qu'il correspond au premier élément de la liste principale, donc au mot « a ».
Mais les autres, que représentent-ils ? C'est à nous de décider. On peut imaginer une structure dans laquelle le second entier est un index qui pointe dans une liste de textes, le troisième dans une liste de pdf, les trois suivants à des images, etc.
Mais nous arrivons vite à une usine à gaz, ce qui est passionnant assurément, mais d'un usage d'autant plus contestable que des quantités d'applications ont déjà été développées sous forme de bases de données adaptées à toutes sortes de besoins.
Pour rester simple, nous prendrons une option radicale : chaque entier du tableau représentera la position d'un mot de la liste principale. Nous obtenons alors un système qui autorise à la fois :
- les liens multiples ;
- la réflexivité.
Nous avons opté pour un identifiant numérique. Pourquoi ne pas avoir conservé le mot comme identifiant ? Essentiellement pour économiser de l'espace de stockage : un entier occupe moins de place qu'un mot complet. Mais gardons en tête cette option : nous aurons l'occasion d'y revenir.
Nettoyage de l'interface et du code▲
Avant de construire la nouvelle architecture, nous allons élaguer sérieusement notre projet, tout en conservant l'onglet Info pour un usage ultérieur :
- dans l'onglet Info de l'interface, on supprime les deux boutons ;
- dans l'éditeur de source, on supprime les deux procédures Button3Click et Button4Click correspondantes ;
- dans la procédure Balayage, on supprime les quatre dernières lignes ;
- dans l'onglet Balayage, on supprime les deux Memos ;
- dans le code, on supprime les procédures MAJObj, MAJInfo, regObj, la fonction chercheValue ;
- les référencements dans la classe Tform, au-dessus du mot-clé implementation, sont nettoyés.
Un essai d'exécution pour vérification.
Quelques scories subsistent… Nous y reviendrons.
Écriture de liens▲
Chaque mot de la liste principale est susceptible de posséder son propre tableau de liens.
Appelons Liens le tableau de tableaux d'entiers qui, avec son identifiant, reçoit les index des liens. Combien de tableaux d'entiers faut-il créer ? Pour fixer les idées, disons que 10 % des mots recevront des liens, soit en gros 34 000 tableaux. Cette approche superficielle montre qu'en fait il est illusoire de se fixer une limite, et la solution est d'adopter un tableau de longueur variable.
Méthode▲
La désignation Liens[0] correspond au premier tableau(16).
La désignation Liens[0, 0] correspond au premier entier du premier tableau(17).
Les tableaux à taille variable ont un inconvénient : avant d'affecter une valeur à un tableau, il est nécessaire de donner au tableau la taille requise. Cette taille est nulle à l'origine.
Donc pour affecter la valeur 0 à la première case du premier tableau, on écrira successivement :
SetLength(Liens, 1
) ;
//le tableau de tableaux peut recevoir son premier tableau
SetLength(Liens[0
], 1
) ;
//le premier tableau a une longueur fixée à 1
Liens[0
, 0
]:= 0
;
//la première case du premier tableau reçoit la valeur numérique 0
La procédure est un peu lourde mais autorise une grande souplesse dans l'édition des liens.
Premier essai▲
Dans l'interface graphique, nous allons ajouter un onglet appelé Édition. Pour cela, clic droit sur la ligne grisée, à droite de l'onglet Info. Dans le menu contextuel, choisissez Ajouter une page. Dans l'Inspecteur d'objets, onglet Propriétés, remplacez TabSheet3 par le mot « Édition » à la ligne Caption.
Dans ce nouvel onglet, nous plaçons un bouton et un label (propriété Font/Size portée à 14).
Double-clic sur le bouton, et dans la procédure ainsi créée dans l'Éditeur de source, nous plaçons le code suivant :
procedure
TForm1.Button3Click(Sender: TObject);
begin
SetLength(Liens, 1
);
SetLength(Liens[0
], 1
);
Liens[0
, 0
] := 0
;
Label4.Caption := IntToStr(Liens[0
, 0
])+ ' -> '
+ listeMots[Liens[0
, 0
]];
end
;
Les trois premières instructions ont été commentées plus haut. La dernière a une ambition modeste : elle se contente d'afficher le numéro stocké dans le nouveau tableau, et le mot correspondant.
La variable globale Liens doit être déclarée avant implementation :
var
Form1: TForm1;
listeMots, listeInfo : TStringList;
iMot, nMots : integer
;
AffListe : TListBox;
Liens : Array
of
Array
of
integer
;
implementation
{ TForm1 }
Clic sur le petit triangle vert pour notre premier essai…
Clic sur le nouveau bouton…
Voici le résultat pour l'indice 0 ; essayez avec différentes valeurs : 100, 1000, 100000…
Nous n'avons pas construit de lien, mais seulement initié le tableau susceptible d'en recevoir !
Création d'un lien▲
Sous le label de l'onglet Édition, nous ajoutons une zone de saisie sous forme d'un TEdit.
Nous ajoutons à droite un TListBox qui recevra les mots éventuellement liés.
Nous remplaçons le titre (caption) du bouton par « Lier ».
La démarche suivante :
- recopier dans le Label4 le mot-titre affiché dans l'onglet Balayage ; son index est iMot ;
- dans l'onglet Édition, saisie d'un mot Mot1 dans le TEdit, son index est iLien ;
- cliquer sur le bouton Lier pour créer le lien ;
- si Mot1 existe, le lien est créé, il est affiché dans la ListBox et la zone d'édition est nettoyée ; sinon un message d'erreur invite à saisir un autre mot.
La création du lien passe par plusieurs étapes :
- chercher le tableau de liens correspondant à chacun des mots à lier ;
- s'il n'existe pas, créer le tableau et inscrire le numéro du mot à lier dans la première case ;
- ensuite, ajouter le numéro du mot à lier dans une nouvelle case.
Voyons cela pas à pas.
Recherche du tableau de liens▲
Nous avons deux mots, connus par leurs index iMot et iLien. Pour savoir si un mot possède son propre tableau de liens, nous créons la fonction chercheTab qui renvoie la position du tableau(18). Rappelons que le tableau de liens commence (à la case 0) par un entier qui est précisément l'index du mot. Si le renvoi est négatif, c'est que le mot ne possède pas encore son tableau.
function
TForm1.chercheTab(iMot: integer
): integer
;
var
i : integer
;
begin
chercheTab := -1
;
i := 0
;
while
(i<Length(Liens)) and
(Liens[i, 0
]<>iMot) do
inc(i);
if
i<Length(Liens) then
chercheTab := i;
end
;
Création du lien▲
Pour lier le mot titre, d'index iMot, à un autre mot d'index iLien, nous créons la procédure Lier qui comprend deux parties :
- si iMot ne possède pas son tableau de liens (chercheTab(iMot) négatif), il faut créer ce tableau à la suite des autres. Par exemple, si aucun tableau n'existe (Length(Liens)=0), on augmente la taille de Liens d'une unité ; le tableau secondaire aura une taille égale à 1 et la première case du tableau secondaire sera remplie avec la valeur iMot ;
- la taille du tableau secondaire est augmentée d'une unité et la nouvelle case reçoit la valeur iLien.
Le code peut s'écrire ainsi :
procedure
TForm1.Lier(iMot, iLien: integer
);
var
k : integer
;
begin
k := chercheTab(iMot);
if
k < 0
then
begin
SetLength(Liens, Length(Liens)+1
); //extension du tableau principal
k := Length(Liens)-1
; //indice du nouveau tableau
SetLength(Liens[k], 1
);
Liens[k, 0
] := iMot; //identifiant
end
;
SetLength(Liens[k], Length(Liens[k])+1
); //extension du tableau secondaire
Liens[k, Length(Liens[k])-1
] := iLien; // lien
end
;
Comme le lien est réciproque, la procédure sera répétée en inversant les deux paramètres.
Exécution▲
Double-clic sur le bouton Lier pour retrouver la procédure Button3 qui sera modifiée ainsi :
procedure
TForm1.Button3Click(Sender: TObject);
var
iLien, k : integer
;
begin
iLien := listeMots.IndexOf(UTF8ToAnsi(Edit3.Caption));
if
iLien<0
then
ShowMessage('Ce mot n''existe pas, recommencez'
)
else
begin
Lier(iMot, iLien);
Lier(iLien, iMot);
AffLiens;
end
;
Edit3.Clear;
end
;
Le mot titre est issu de la liste principale, puisqu'il est obtenu à partir le l'onglet Balayage. Par contre, le mot entré dans la zone d'édition n'existe peut-être pas : un signal d'erreur invite à recommencer la saisie.
Ensuite, la construction du lien se fait dans un sens, puis dans l'autre.
La zone de saisie est effacée, prête à recevoir un nouveau mot à lier.
Mais avant, le ou les liens sont affichés dans le composant ListBox par les soins de la procédure AffLiens :
procedure
TForm1.AffLiens;
var
i, k : integer
;
begin
ListBox1.Clear;
k := chercheTab(iMot);
if
k>=0
then
for
i :=1
to
Length(Liens[k]) -1
do
ListBox1.Items.Add(AnsiToUTF8(listeMots[Liens[k, i]]));
end
;
Enfin, nous ajoutons dans la procédure MAJBalayage des instructions nécessaires pour afficher le mot titre dans l'onglet Édition, nettoyer la zone de saisie et afficher les liens éventuels :
procedure
TForm1.MAJBalayage;
var
i : integer
;
begin
Label2.Caption:=AnsiToUTF8(listeMots[iMot]);
Label3.Caption:= Label2.Caption;
Label4.Caption:= Label2.Caption;
Edit3.Clear;
TrackBar1.Position:= Round(iMot*1000
/nMots);
AffListe.Clear;
for
i := 0
to
10
do
AffListe.Items.Add(AnsiToUTF8(listeMots[(iMot-delta + i
+ nMots) mod
nMots]));
AffListe.Selected[delta] := True
;
AffLiens ;
end
;
Un clic sur le petit triangle vert pour nos essais.
Dans l'onglet Balayage, faites défiler les mots pour afficher le mot « couleur ».
Dans l'onglet Édition, écrivez le mot « vert »et cliquez sur le bouton Lier. Immédiatement, le mot « couleur » est lié au mot « vert », qui apparaît maintenant dans la zone des liens à droite.
Recommencez avec « blanc », « rouge »… Les liens s'ajoutent sans problème…
Le mot titre est « couleur ». Il possède trois liens qui sont affichés à droite.
Réciprocité▲
Le mot « couleur » est lié au mot « vert ». Mais comment vérifier que la réciproque est vraie ?
Il suffirait de cliquer sur le mot « vert » pour le faire basculer en titre, et la zone des liens présenterait alors les liens existants.
Pour coder cet événement, revenez en mode édition, cliquez sur le composant ListBox1, et dans l'onglet Événements, ligne OnClick, cliquez sur les trois points. La procédure s'écrit ainsi :
procedure
TForm1.ListBox1Click(Sender: TObject);
if
ListBox1.ItemIndex >= 0
then
begin
iMot := Liens[chercheTab(iMot), ListBox1.ItemIndex+1
];
Label4.Caption := AnsiToUTF8(listeMots[iMot]);
AffLiens;
end
;
end
;
La première ligne vérifie la présence d'un lien (index supérieur ou égal à zéro).
Relancez l'exécution. Onglet Édition, le mot titre est « a ». Créez un lien avec « avoir », avec « voyelle », avec « lettre »… Cliquez sur le mot « avoir », créez un lien avec « bien », avec « verbe »… Cliquez sur le mot « bien », qui passe en titre ; liez avec « mal », etc. C'est simple et… magique !
Enregistrement des liens▲
Inutile d'ajouter davantage de liens puisque la fonction d'enregistrement n'existe pas encore.
Nous allons créer un fichier de nombres entiers qui recevra un par un les tableaux secondaires.
Dans l'unité uDisque, nous écrivons avant implementation, sous la ligne procedure LireFichier, l'instruction procedure regLiens ;
Après appui sur les touches Ctrl+Maj+C, nous complétons le corps de la procédure par les instructions suivantes :
procedure
regLiens;
var
i, j, k : integer
;
fLiens : file
of
integer
;
begin
AssignFile(fLiens, 'fichLiens.bin'
);
ReWrite(fLiens);
for
i := 0
to
Length(Liens)-1
do
begin
j := Length(Liens[i]);
Write
(fLiens, j);
for
k:=0
to
j-1
do
Write
(fLiens, Liens[i, k]);
end
;
CloseFile(fLiens);
end
;
Le premier nombre écrit dans le fichier est la taille du premier tableau secondaire : Write(fLiens, j). Ensuite sont écrits tous les nombres situés dans le tableau depuis la case 0 (identifiant du tableau) jusqu'à la dernière case. L'opération est répétée autant de fois qu'il y a de tableaux secondaires.
L'unité utilise la variable Liens créée par l'unité uLex6 ; pour que le compilateur s'y retrouve, dans l'unité uDisque, sous le mot-clé implementation, nous ajoutons l'instruction
uses uLex6Â ;
Pour automatiser la sauvegarde de nos liens, nous ajoutons l'instruction regLiens dans la procédure Button1Click qui provoque la fin de l'application :
procedure
TForm1.Button1Click(Sender: TObject);
begin
regLiens;
listeMots.Free;
Application.Terminate;
end
;
Lecture des liens▲
Pour récupérer l'ensemble de nos liens au démarrage du programme, nous ajoutons la ligne lireLiens dans la procédure FormCreate.
Dans l'unité uDisque, nous ajoutons la ligne procedure lireLiens ; avant implementation, et après appui sur les touches Ctrl+Maj+C, nous complétons le code comme suit :
procedure
lireLiens;
var
j, m : integer
;
fLiens : file
of
integer
;
begin
nLiens := 0
; //nombre de mots liés
AssignFile(fLiens, 'fichLiens.bin'
);
{$I-}
Reset(fLiens);
{$I+}
if
IOResult<>0
then
ShowMessage('Fichier liens inexistant'
)
else
while
not
EOF(fLiens) do
begin
SetLength(Liens, nLiens+1
); //taille du tableau principal
Read
(fLiens, m);
SetLength(Liens[nLiens], m); //taille du tableau secondaire
for
j := 0
to
m-1
do
Read
(fLiens, Liens[nLiens, j]); //remplissage de tableau secondaire
inc(nLiens); //nombre de mots liés
end
;
CloseFile(fLiens);
end
;
Cette procédure utilise une fenêtre pour signaler l'absence du fichier : il faut déclarer l'unité Dialogs après SysUtils.
Le premier nombre lu, m, est la taille du premier tableau secondaire. Les lectures suivantes permettront de remplir toutes les cases de ce tableau. Puis on passe au tableau suivant avec inc(nLiens) jusqu'à la fin du fichier (détectée par EOF).
Nous avons ici introduit la variable nLiens qui totalise le nombre de mots liés. Mais il faudra la déclarer dans l'unité uLex6, à la suite des autres variables globales. L'affichage du nombre de liens sera intégré dans le titre de la fenêtre (propriété Caption) et actualisé lors de la création de liens.
Dans la procédure MAJBalayage, nous ajoutons l'instruction
Caption := IntToStr(nMots)+ ' mots dont '+IntToStr(nLiens)+' liés';
Pour essayer la nouvelle configuration, clic sur le petit triangle vert.
Balayage jusqu'au mot « couleur » ; dans l'onglet Édition, liez avec « vert », « blanc », « rouge »…
Pour quitter, passez par le bouton Arrêt (onglet Page1), de façon à provoquer l'enregistrement. Au redémarrage, vous retrouverez tous vos liens.
Filtre▲
La navigation reste laborieuse, et un filtrage permettrait de passer directement d'un mot lié au suivant. Pour cela, il suffit de reprendre la définition du filtrage en introduisant la valeur retournée par la fonction chercheTab : si elle est négative, la recherche continue.
procedure
TForm1.UpDown2Click(Sender: TObject; Button: TUDBtnType);
begin
if
CheckBox1.Checked then
repeat
inc(iMot);
until
(iMot=nMots) or
(chercheTab(iMot)>=0
)
else
if
Button=btNext then
Inc(iMot, UpDown2.Increment)
else
Dec(iMot, UpDown2.Increment);
iMot := (iMot + nMots) mod
nMots;
MAJBalayage;
end
;
Relancez l'exécution ; onglet Balayage, cliquez sur le filtre puis sur les flèches : tous les mots liés défilent instantanément. Un contrôle sur l'onglet Édition permet de vérifier que les liens sont correctement détectés et affichés.
Conclusion▲
Ouf ! Il a fallu mettre un peu les mains dans le cambouis des indices multiples, mais nous disposons maintenant des moyens nécessaires pour créer et sauvegarder facilement tous les liens que l'on souhaite.
Dans le prochain chapitre, nous verrons comment effectuer le tri des tableaux, la modification ou la suppression de liens, et nous aborderons le concept de mots « proches » du mot titre, fondamental dans la construction des mots croisés.
Mais la création de liens restera limitée aux mots de la liste principale : ce n'est qu'ensuite que nous envisagerons sa modification, problème que nous avons soigneusement éludé jusqu'à présent.
An : un élément du fardeau du vieillard.
Tristan Bernard.
Pour l'instant, les unités uLex6 et uDisque se présentent ainsi :
unit
uLex6;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls,
Graphics, Dialogs, StdCtrls, ComCtrls, uDisque;
type
{ TForm1 }
TForm1 = class
(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
CheckBox1: TCheckBox;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Label3: TLabel;
Label4: TLabel;
ListBox1: TListBox;
Memo2: TMemo;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
RadioButton3: TRadioButton;
RadioButton4: TRadioButton;
TabSheet2: TTabSheet;
TabSheet3: TTabSheet;
Zoom: TGroupBox;
Label1: TLabel;
Label2: TLabel;
AffListe: TListBox;
Memo1: TMemo;
PageControl1: TPageControl;
Page1: TTabSheet;
TabSheet1: TTabSheet;
TrackBar1: TTrackBar;
UpDown1: TUpDown;
UpDown2: TUpDown;
procedure
AffListeClick(Sender: TObject);
procedure
Button1Click(Sender: TObject);
procedure
Button2Click(Sender: TObject);
procedure
Button3Click(Sender: TObject);
procedure
CheckBox1Change(Sender: TObject);
procedure
FormCreate(Sender: TObject);
procedure
ListBox1Click(Sender: TObject);
procedure
Recherche(rechMot: string
);
procedure
TrackBar1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer
);
procedure
UpDown1Click(Sender: TObject; Button: TUDBtnType);
procedure
MAJAffichage;
procedure
MAJBalayage;
procedure
UpDown2Click(Sender: TObject; Button: TUDBtnType);
procedure
ZoomMouseLeave(Sender: TObject);
function
chercheTab(iMot : integer
) : integer
;
procedure
Lier(iMot, iLien: integer
);
procedure
AffLiens;
private
{ private declarations }
public
{ public declarations }
end
;
const
delta=5
;
var
Form1: TForm1;
listeMots, listeInfo, listeObj : TstringList;
iMot, nMots, nLiens : integer
;
Liens : Array
of
Array
of
integer
;
implementation
{$R *.lfm}
{ TForm1 }
procedure
TForm1.Button1Click(Sender: TObject);
begin
regLiens;
listeMots.Free;
Application.Terminate;
end
;
procedure
TForm1.AffListeClick(Sender: TObject);
begin
iMot := (iMot -delta + AffListe.ItemIndex + nMots) mod
nMots;
MAJBalayage;
end
;
procedure
TForm1.Button2Click(Sender: TObject);
begin
Recherche(Edit2.Caption);
end
;
procedure
TForm1.Button3Click(Sender: TObject);
var
iLien, k : integer
;
begin
iLien := listeMots.IndexOf(UTF8ToAnsi(Edit3.Caption));
if
iLien<0
then
ShowMessage('Ce mot n''existe pas, recommencez'
)
else
begin
Lier(iMot, iLien);
Lier(iLien, iMot);
AffLiens;
end
;
Edit3.Clear;
end
;
procedure
TForm1.CheckBox1Change(Sender: TObject);
begin
if
CheckBox1.Checked then
CheckBox1.Caption := 'Avec filtre'
else
CheckBox1.Caption := 'Sans filtre'
;
end
;
procedure
TForm1.FormCreate(Sender: TObject);
begin
listeMots := TStringList.Create;
LireFichier(listeMots);
nMots:= listeMots.Count;
lireLiens;
Memo1.Append('Premier mot : '
+listeMots[0
]);
Memo1.Append('Dernier mot : '
+listeMots[nMots-1
]);
iMot := 0
;
MAJAffichage;
MAJBalayage;
end
;
procedure
TForm1.ListBox1Click(Sender: TObject);
begin
if
ListBox1.ItemIndex >= 0
then
begin
iMot := Liens[chercheTab(iMot), ListBox1.ItemIndex+1
];
Label4.Caption := AnsiToUTF8(listeMots[iMot]);
AffLiens;
end
;
end
;
procedure
TForm1.MAJBalayage;
var
i : integer
;
begin
Label2.Caption:=AnsiToUTF8(listeMots[iMot]);
Label3.Caption:= Label2.Caption;
Label4.Caption:= Label2.Caption;
Edit3.Clear;
TrackBar1.Position:= Round(iMot*1000
/nMots);
AffListe.Clear;
for
i := 0
to
10
do
AffListe.Items.Add(AnsiToUTF8(listeMots[(iMot-delta + i
+ nMots) mod
nMots]));
AffListe.Selected[delta] := True
;
AffLiens;
Caption := IntToStr(nMots)+ ' mots dont '
+IntToStr(nLiens)+' liés'
;
end
;
procedure
TForm1.UpDown2Click(Sender: TObject; Button: TUDBtnType);
begin
if
CheckBox1.Checked then
repeat
inc(iMot);
until
(iMot=nMots) or
(chercheTab(iMot)>=0
)
else
if
Button=btNext then
Inc(iMot, UpDown2.Increment)
else
Dec(iMot, UpDown2.Increment);
iMot := (iMot + nMots) mod
nMots;
MAJBalayage;
end
;
procedure
TForm1.ZoomMouseLeave(Sender: TObject);
begin
if
RadioButton1.Checked then
UpDown2.Increment := 1
else
if
RadioButton2.Checked then
UpDown2.Increment := 10
else
if
RadioButton3.Checked then
UpDown2.Increment := 100
else
if
RadioButton4.Checked then
UpDown2.Increment := 1000
;
end
;
function
TForm1.chercheTab(iMot: integer
): integer
;
var
i : integer
;
begin
chercheTab := -1
;
i := 0
;
while
(i<Length(Liens)) and
(Liens[i, 0
]<>iMot) do
inc(i);
if
i<Length(Liens) then
chercheTab := i;
end
;
procedure
TForm1.Lier(iMot, iLien: integer
);
var
k : integer
;
begin
k := chercheTab(iMot);
if
k < 0
then
begin
SetLength(Liens, Length(Liens)+1
); //extension du tableau principal
k := Length(Liens)-1
; //indice du nouveau tableau
SetLength(Liens[k], 1
);
Liens[k, 0
] := iMot; //identifiant
end
;
SetLength(Liens[k], Length(Liens[k])+1
); //extension du tableau secondaire
Liens[k, Length(Liens[k])-1
] := iLien; // lien
end
;
procedure
TForm1.AffLiens;
var
i, k : integer
;
begin
ListBox1.Clear;
k := chercheTab(iMot);
if
k>=0
then
for
i :=1
to
Length(Liens[k]) -1
do
ListBox1.Items.Add(AnsiToUTF8(listeMots[Liens[k, i]]));
end
;
procedure
TForm1.TrackBar1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer
);
begin
iMot := Round(TrackBar1.Position*nMots/1000
);
iMot := (iMot + nMots) mod
nMots;
MAJBalayage;
end
;
procedure
TForm1.Recherche(rechMot: string
);
var
iMot : integer
;
begin
iMot := listeMots.IndexOf(rechMot);
if
iMot >= 0
then
Label1.Caption:= listeMots[iMot]
else
Label1.Caption:= 'échec'
;
Memo1.Append('Index '
+IntToStr(iMot));
end
;
procedure
TForm1.UpDown1Click(Sender: TObject; Button: TUDBtnType);
begin
if
Button=btNext then
Inc(iMot)
else
Dec(iMot);
iMot := iMot + nMots mod
nMots;
MAJAffichage;
end
;
procedure
TForm1.MAJAffichage;
begin
Label1.Caption:=listeMots[iMot];
Edit2.Caption:= ''
;
Memo1.Append('Index '
+IntToStr(iMot));
end
;
end
.
Et pour l'unité uDisque :
unit
uDisque;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Dialogs;
procedure
LireFichier(listeMots : TStringList);
procedure
regLiens;
procedure
lireLiens;
implementation
uses
uLex6;
procedure
LireFichier(listeMots: TStringList);
begin
listeMots.LoadFromFile('liste.de.mots.francais.frgut.txt'
);
end
;
procedure
regLiens;
var
i, j, k : integer
;
fLiens : file
of
integer
;
begin
AssignFile(fLiens, 'fichLiens.bin'
);
ReWrite(fLiens);
for
i := 0
to
Length(Liens)-1
do
begin
j := Length(Liens[i]);
Write
(fLiens, j);
for
k:=0
to
j-1
do
Write
(fLiens, Liens[i, k]);
end
;
CloseFile(fLiens);
end
;
procedure
lireLiens;
var
j, m : integer
;
fLiens : file
of
integer
;
begin
nLiens := 0
; //nombre de mots liés
AssignFile(fLiens, 'fichLiens.bin'
);
{$I-}
Reset(fLiens);
{$I+}
if
IOResult<>0
then
ShowMessage('Fichier liens inexistant'
)
else
while
not
EOF(fLiens) do
begin
SetLength(Liens, nLiens+1
); //taille du tableau principal
Read
(fLiens, m);
SetLength(Liens[nLiens], m); //taille du tableau secondaire
for
j := 0
to
m-1
do
Read
(fLiens, Liens[nLiens, j]); //remplissage de tableau secondaire
inc(nLiens); //nombre de mots liés
end
;
CloseFile(fLiens);
end
;
end
.