source: trunk/Forms/FormCheck.pas

Last change on this file was 227, checked in by chronos, 44 hours ago
  • Modified: Do not reference global Core object if possible.
File size: 23.7 KB
Line 
1unit FormCheck;
2
3interface
4
5uses
6 Classes, SysUtils, LazFileUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
7 ExtCtrls, ComCtrls, Menus, ActnList, Acronym, RegistryEx, Registry, Common,
8 Generics.Collections, FormEx;
9
10type
11 TReportType = (rtNone, rtNote, rtWarning, rtError);
12
13 TReportItem = class
14 Message: string;
15 Position: TPoint;
16 Kind: TReportType;
17 end;
18
19 { TReportItems }
20
21 TReportItems = class(TObjectList<TReportItem>)
22 function AddNew(Message: string; Position: TPoint;
23 Kind: TReportType = rtNone): TReportItem;
24 procedure SaveToCsv(FileName: string);
25 end;
26
27 { TFormCheck }
28
29 TFormCheck = class(TFormEx)
30 AGoToLocation: TAction;
31 ASaveToCsv: TAction;
32 ActionList1: TActionList;
33 ButtonLoadFromFile: TButton;
34 ButtonAcronymsContent: TButton;
35 ButtonAcronymsSummary: TButton;
36 ButtonCheck: TButton;
37 CheckBoxCaseSensitive: TCheckBox;
38 EditSummaryStart: TEdit;
39 EditSummaryEnd: TEdit;
40 GroupBox1: TGroupBox;
41 GroupBox2: TGroupBox;
42 Label1: TLabel;
43 Label2: TLabel;
44 LabelAcronymCountContent: TLabel;
45 LabelAcronymCountSummary: TLabel;
46 ListViewReport: TListView;
47 MemoDocument: TMemo;
48 MenuItem1: TMenuItem;
49 MenuItemGoTo: TMenuItem;
50 OpenDialog1: TOpenDialog;
51 PageControl1: TPageControl;
52 Panel1: TPanel;
53 Panel2: TPanel;
54 PopupMenuReport: TPopupMenu;
55 SaveDialog1: TSaveDialog;
56 Splitter1: TSplitter;
57 TabSheetSource: TTabSheet;
58 TabSheetReport: TTabSheet;
59 procedure AGoToLocationExecute(Sender: TObject);
60 procedure ASaveToCsvExecute(Sender: TObject);
61 procedure ButtonAcronymsSummaryClick(Sender: TObject);
62 procedure ButtonAcronymsContentClick(Sender: TObject);
63 procedure ButtonCheckClick(Sender: TObject);
64 procedure ButtonLoadFromFileClick(Sender: TObject);
65 procedure FormCreate(Sender: TObject);
66 procedure FormDestroy(Sender: TObject);
67 procedure FormShow(Sender: TObject);
68 procedure ListViewReportData(Sender: TObject; Item: TListItem);
69 private
70 AcronymDbSummary: TAcronymDb;
71 AcronymDbContent: TAcronymDb;
72 LastDocumentFileName: string;
73 function SearchLine(Lines: TStrings; Text: string; Start: Integer = 0): Integer;
74 function SearchLineReverse(Lines: TStrings; Text: string; Start: Integer = -1): Integer;
75 procedure FindInSummary;
76 procedure FindInContent;
77 function AllowedSideChar(Before, After: Char): Boolean;
78 function ParseMeaning(Acronym, Text: string; StartIndex: Integer;
79 out Meaning: string; DashSeparator: Boolean = False): Boolean;
80 function IsUppercaseAlpha(Text: string): Boolean;
81 function IsLowercaseAlpha(Text: string): Boolean;
82 function IsAlpha(Text: string): Boolean;
83 function IsAcronym(Text: string): Boolean;
84 function IsDigit(Text: Char): Boolean;
85 procedure ReportDifferencies;
86 function WordContainsLetters(Text, Letters: string): Boolean;
87 function StringEqual(Text1, Text2: string): Boolean;
88 procedure ReloadReport;
89 public
90 AcronymDb: TAcronymDb;
91 ReportItems: TReportItems;
92 procedure UpdateInterface;
93 procedure LoadConfig(RegistryContext: TRegistryContext);
94 procedure SaveConfig(RegistryContext: TRegistryContext);
95 end;
96
97const
98 ReportTypeString: array[TReportType] of string = ('', 'Note', 'Warning', 'Error');
99
100
101implementation
102
103{$R *.lfm}
104
105uses
106 FormAcronyms;
107
108resourcestring
109 SAcronymCountContent = 'Content acronym count:';
110 SAcronymCountSummary = 'Summary acronym count:';
111 SDuplicateAcronymContent = 'Duplicate acronym %s with "%s" in document body.';
112 SDuplicateAcronymSummary = 'Duplicate acronym %s with "%s" in acronym summary.';
113 SMissingAcronymContent = 'Document body acronym %s with meaning "%s" missing from acronym summary.';
114 SMissingAcronymSummary = 'Summary acronym %s with meaning "%s" missing from document body.';
115 SAcronymContentMultipleMeanings = 'Content acronym %s has multiple meanings: %s.';
116 SAcronymSummaryMultipleMeanings = 'Summary acronym %s has multiple meanings: %s.';
117 SAcronymWithDifferentMeaning = 'Acronym %s has different meaning for content "%s" and for summary "%s".';
118 SAcronymWithDifferentMeaningCount = 'Acronym %s has different meaning count for content (%d) and for summary (%d).';
119 SPluralAcronym = 'Acronym %s is defined as plural in document body.';
120 SPluralAcronymUsed = 'Acronym %s is used as plural in document body.';
121 SSummaryAcronyms = 'Summary acronyms';
122 SContentAcronyms = 'Content acronyms';
123 SAcronymUsedBeforeDefined = 'Acronym %s used before it was defined.';
124 SCSVFilter = 'CSV file (.csv)|*.csv|Any file|*.*';
125
126const
127 MinAcronymLength = 2;
128
129{ TReportItems }
130
131function TReportItems.AddNew(Message: string; Position: TPoint;
132 Kind: TReportType = rtNone): TReportItem;
133begin
134 Result := TReportItem.Create;
135 Result.Message := Message;
136 Result.Position := Position;
137 Result.Kind := Kind;
138 Add(Result);
139end;
140
141procedure TReportItems.SaveToCsv(FileName: string);
142var
143 I: Integer;
144 F: TStringList;
145 Line: TStringList;
146begin
147 F := TStringList.Create;
148 Line := TStringList.Create;
149 Line.StrictDelimiter := True;
150 try
151 Line.Clear;
152 for I := 0 to Count - 1 do
153 with TReportItem(Items[I]) do begin
154 Line.Clear;
155 if Position <> Point(0, 0) then
156 Line.Add(IntToStr(Position.X) + ', ' + IntToStr(Position.Y))
157 else Line.Add('');
158 Line.Add(ReportTypeString[Kind]);
159 Line.Add(Message);
160 F.Add(Line.CommaText);
161 end;
162 F.SaveToFile(FileName);
163 finally
164 F.Free;
165 Line.Free;
166 end;
167end;
168
169{ TFormCheck }
170
171procedure TFormCheck.ButtonCheckClick(Sender: TObject);
172begin
173 ReportItems.Clear;
174 UpdateInterface;
175 FindInSummary;
176 FindInContent;
177 ReportDifferencies;
178 UpdateInterface;
179 ReloadReport;
180 TabSheetReport.Show;
181end;
182
183procedure TFormCheck.ButtonLoadFromFileClick(Sender: TObject);
184begin
185 OpenDialog1.InitialDir := ExtractFileDir(LastDocumentFileName);
186 OpenDialog1.FileName := ExtractFileName(LastDocumentFileName);
187 if OpenDialog1.Execute then begin
188 LastDocumentFileName := OpenDialog1.FileName;
189 MemoDocument.Lines.LoadFromFile(OpenDialog1.FileName);
190 TabSheetSource.Show;
191 end;
192end;
193
194procedure TFormCheck.FormCreate(Sender: TObject);
195begin
196 AcronymDbSummary := TAcronymDb.Create;
197 AcronymDbContent := TAcronymDb.Create;
198 ReportItems := TReportItems.Create;
199end;
200
201procedure TFormCheck.FormDestroy(Sender: TObject);
202begin
203 FreeAndNil(ReportItems);
204 FreeAndNil(AcronymDbSummary);
205 FreeAndNil(AcronymDbContent);
206end;
207
208procedure TFormCheck.FormShow(Sender: TObject);
209begin
210 PageControl1.TabIndex := 0;
211 if FileExists(LastDocumentFileName) then
212 MemoDocument.Lines.LoadFromFile(LastDocumentFileName);
213 UpdateInterface;
214end;
215
216procedure TFormCheck.ListViewReportData(Sender: TObject; Item: TListItem);
217begin
218 if Item.Index < ReportItems.Count then
219 with ReportItems[Item.Index] do begin
220 if Position <> Point(0, 0) then
221 Item.Caption := IntToStr(Position.X) + ', ' + IntToStr(Position.Y)
222 else Item.Caption := '';
223 Item.Data := ReportItems[Item.Index];
224 Item.SubItems.Add(ReportTypeString[Kind]);
225 Item.SubItems.Add(Message);
226 end;
227end;
228
229procedure TFormCheck.ButtonAcronymsContentClick(Sender: TObject);
230var
231 FormAcronyms: TFormAcronyms;
232begin
233 FormAcronyms := TFormAcronyms.Create(Self);
234 try
235 FormAcronyms.AcronymDb := AcronymDb;
236 FormAcronyms.Acronyms := AcronymDbContent.Acronyms;
237 FormAcronyms.Caption := SContentAcronyms;
238 FormAcronyms.ShowModal;
239 finally
240 FreeAndNil(FormAcronyms);
241 end;
242end;
243
244procedure TFormCheck.ButtonAcronymsSummaryClick(Sender: TObject);
245var
246 FormAcronyms: TFormAcronyms;
247begin
248 FormAcronyms := TFormAcronyms.Create(Self);
249 try
250 FormAcronyms.AcronymDb := AcronymDb;
251 FormAcronyms.Acronyms := AcronymDbSummary.Acronyms;
252 FormAcronyms.Caption := SSummaryAcronyms;
253 FormAcronyms.ShowModal;
254 finally
255 FreeAndNil(FormAcronyms);
256 end;
257end;
258
259procedure TFormCheck.ASaveToCsvExecute(Sender: TObject);
260begin
261 SaveDialog1.InitialDir := ExtractFileDir(LastDocumentFileName);
262 SaveDialog1.DefaultExt := '.csv';
263 SaveDialog1.FileName := ExtractFileNameWithoutExt(ExtractFileName(LastDocumentFileName)) + SaveDialog1.DefaultExt;
264 SaveDialog1.Filter := SCSVFilter;
265 if SaveDialog1.Execute then begin
266 ReportItems.SaveToCsv(SaveDialog1.FileName);
267 end;
268end;
269
270procedure TFormCheck.AGoToLocationExecute(Sender: TObject);
271begin
272 if Assigned(ListViewReport.Selected) then
273 with TReportItem(ListViewReport.Selected.Data) do
274 if Position <> Point(0, 0) then begin
275 MemoDocument.CaretPos := Position;
276 TabSheetSource.Show;
277 end;
278end;
279
280function TFormCheck.SearchLine(Lines: TStrings; Text: string; Start: Integer = 0): Integer;
281begin
282 Result := Start;
283 while (Result < Lines.Count) and (Pos(Text, Lines[Result]) = 0) do Inc(Result);
284 if Result >= Lines.Count then Result := -1;
285end;
286
287function TFormCheck.SearchLineReverse(Lines: TStrings; Text: string;
288 Start: Integer = -1): Integer;
289begin
290 if Start = -1 then Result := Lines.Count - 1
291 else Result := Start;
292 while (Result >= 0) and (Pos(Text, Lines[Result]) = 0) do Dec(Result);
293end;
294
295procedure TFormCheck.FindInSummary;
296var
297 AcronymSectionStart: Integer;
298 AcronymSectionEnd: Integer;
299 I: Integer;
300 Line: string;
301 Acronym: string;
302 Meaning: string;
303 Index: Integer;
304begin
305 AcronymDbSummary.Acronyms.Clear;
306
307 AcronymSectionStart := SearchLineReverse(MemoDocument.Lines, EditSummaryStart.Text);
308 if AcronymSectionStart <> -1 then begin
309 AcronymSectionEnd := SearchLine(MemoDocument.Lines, EditSummaryEnd.Text, AcronymSectionStart + 1);
310 if AcronymSectionEnd <> -1 then begin
311 Acronym := '';
312 for I := AcronymSectionStart + 1 to AcronymSectionEnd - 1 do begin
313 Line := Trim(MemoDocument.Lines[I]);
314 Line := StringReplace(Line, #9, ' ', [rfReplaceAll]);
315 if Line <> '' then begin
316 if (Acronym <> '') and IsUppercaseAlpha(Acronym) then begin
317 Meaning := Line;
318 end else begin
319 Index := Pos(' ', Line);
320 if Index > 0 then begin
321 Acronym := Copy(Line, 1, Index - 1);
322 Meaning := Trim(Copy(Line, Index + 1, Length(Line)));
323 end else begin
324 if Acronym = '' then Acronym := Line
325 else Meaning := Line;
326 end;
327 end;
328 if (Acronym <> '') and IsUppercaseAlpha(Acronym) and (Meaning <> '') then begin
329 if Assigned(AcronymDbSummary.SearchAcronym(Acronym, Meaning)) then
330 ReportItems.AddNew(Format(SDuplicateAcronymSummary, [Acronym, Meaning]), Point(0, I), rtWarning)
331 else AcronymDbSummary.AddAcronym(Acronym, Meaning);
332 Acronym := '';
333 Meaning := '';
334 end;
335 end;
336 end;
337 end;
338 end;
339end;
340
341procedure TFormCheck.FindInContent;
342var
343 Text: string;
344 Index: Integer;
345 State: (stNone, stAcronymUsage, stAcronymDefinition);
346 Acronym: string;
347 AcronymCharBefore: Char;
348 AcronymCharAfter: Char;
349 Lines: TStringList;
350 HasUpperCase: Boolean;
351 HasLowerCase: Boolean;
352 I: Integer;
353 J: Integer;
354 Line: string;
355 Meaning: string;
356 Meaning1: string;
357 Meaning2: string;
358 HasMeaning1: Boolean;
359 HasMeaning2: Boolean;
360 Plural: Boolean;
361 StartIndex: Integer;
362 Acro: TAcronym;
363begin
364 AcronymDbContent.Acronyms.Clear;
365
366 // Make lowercase lines where all alpha characters are in uppercase
367 // These are usually first level chapter titles or first page text
368 Lines := TStringList.Create;
369 Lines.Assign(MemoDocument.Lines);
370 for I := 0 to Lines.Count - 1 do begin
371 HasLowerCase := False;
372 HasUpperCase := False;
373 Line := Lines[I];
374 for J := 1 to Length(Line) do begin
375 if IsUppercaseAlpha(Line[J]) then HasUpperCase := True;
376 if IsLowercaseAlpha(Line[J]) then HasLowerCase := True;
377 end;
378 if HasUpperCase and not HasLowerCase then
379 Lines[I] := LowerCase(Lines[I]);
380 end;
381
382 // Find acronyms usage in text
383 Text := Lines.Text;
384 Text := StringReplace(Text, #9, ' ', [rfReplaceAll]);
385 Text := StringReplace(Text, LineEnding, ' ', [rfReplaceAll]);
386 Index := 1;
387 AcronymCharBefore := ' ';
388 AcronymCharAfter := ' ';
389 State := stNone;
390 StartIndex := 0;
391 Acronym := '';
392 repeat
393 if State = stAcronymUsage then begin
394 if not IsUppercaseAlpha(Text[Index]) then begin
395 if Text[Index] = 's' then begin
396 Acronym := Acronym + Text[Index];
397 Inc(Index);
398 end;
399 if (Index) < Length(Text) then AcronymCharAfter := Text[Index]
400 else AcronymCharAfter := ' ';
401 State := stNone;
402
403 // Allow plural acronyms with ending 's' character
404 if (Length(Acronym) >= 1) and (Acronym[Length(Acronym)] = 's') then begin
405 Acronym := Copy(Acronym, 1, Length(Acronym) - 1);
406 Plural := True;
407 end else Plural := False;
408
409 // Acronyms should not contain numbers
410 if (Length(Acronym) >= MinAcronymLength) and
411 AllowedSideChar(AcronymCharBefore, AcronymCharAfter) then begin
412 // If plural acronym then try to remove ending 's' character from the meaning
413 if Plural then ReportItems.AddNew(Format(SPluralAcronymUsed, [Acronym]), Point(0, 0), rtNote);
414
415 Acro := AcronymDbContent.Acronyms.SearchByName(Acronym);
416 if not Assigned(Acro) then begin
417 ReportItems.AddNew(Format(SAcronymUsedBeforeDefined, [Acronym]), Point(0, 0), rtNote);
418 AcronymDbContent.AddAcronym(Acronym, '');
419 end;
420 end;
421 end else Acronym := Acronym + Text[Index];
422 end else
423 if State = stAcronymDefinition then begin
424 if Text[Index] = ')' then begin
425 // Allow plural acronyms with ending 's' character
426 if (Length(Acronym) >= 1) and (Acronym[Length(Acronym)] = 's') then begin
427 Acronym := Copy(Acronym, 1, Length(Acronym) - 1);
428 Plural := True;
429 end else Plural := False;
430 if IsAcronym(Acronym) then begin
431 HasMeaning1 := ParseMeaning(Acronym, Text, StartIndex - 1, Meaning1);
432 if HasMeaning1 then Meaning := Meaning1;
433 HasMeaning2 := ParseMeaning(Acronym, Text, StartIndex - 1, Meaning2, True);
434 if HasMeaning2 then Meaning := Meaning2;
435 if HasMeaning1 and HasMeaning2 then begin
436 if Length(Meaning1) > Length(Meaning2) then Meaning := Meaning1
437 else Meaning := Meaning2;
438 end;
439 if HasMeaning1 or HasMeaning2 then begin
440 // If plural acronym then try to remove ending 's' character from the meaning
441 if Plural then ReportItems.AddNew(Format(SPluralAcronym, [Acronym]), Point(0, 0), rtNote);
442 if Plural and (Length(Meaning) >= 1) and (Meaning[Length(Meaning)] = 's') then begin
443 Meaning := Copy(Meaning, 1, Length(Meaning) - 1);
444 end;
445 if Assigned(AcronymDbContent.SearchAcronym(Acronym, Meaning)) then
446 ReportItems.AddNew(Format(SDuplicateAcronymContent, [Acronym, Meaning]), Point(0, 0), rtWarning)
447 else AcronymDbContent.AddAcronym(Acronym, Meaning);
448 end;
449 end else
450 // No acronym inside parenthesis, continue with parsing inside
451 Index := StartIndex + 1;
452 State := stNone;
453 end else begin
454 Acronym := Acronym + Text[Index];
455 end;
456 end else begin
457 if Text[Index] = '(' then begin
458 State := stAcronymDefinition;
459 Acronym := '';
460 StartIndex := Index;
461 end else
462 if IsUppercaseAlpha(Text[Index]) then begin
463 State := stAcronymUsage;
464 Acronym := Text[Index];
465 if (Index - 1) >= 1 then AcronymCharBefore := Text[Index - 1]
466 else AcronymCharBefore := ' ';
467 end;
468 end;
469 Inc(Index);
470 until Index > Length(Text);
471 Lines.Free;
472end;
473
474function TFormCheck.AllowedSideChar(Before, After: Char): Boolean;
475begin
476 Result := ((Before = ' ') or (Before = #10) or (Before = #13) or (Before = ',') or
477 (Before = ';') or (Before = '(') or (Before = ')'))
478 and ((After = ' ') or (After = #10) or (After = #13) or (After = ',') or
479 (After = '.') or (After = ';') or (After = '(') or (After = ')'));
480end;
481
482function TFormCheck.ParseMeaning(Acronym, Text: string; StartIndex: Integer;
483 out Meaning: string; DashSeparator: Boolean): Boolean;
484var
485 StartIndex2: Integer;
486 StartIndex3: Integer;
487 StartIndex4: Integer;
488 LetterIndex: Integer;
489 OneWord: string;
490 WordLetterIndex: Integer;
491 WordCount: Integer;
492 WordCountWrong: Integer;
493begin
494 Result := True;
495 Meaning := '';
496 StartIndex2 := StartIndex;
497 LetterIndex := Length(Acronym);
498 WordCount := 0;
499 WordCountWrong := 0;
500 while Length(Acronym) > 0 do begin
501 StartIndex3 := PosFromIndexReverse(' ', Text, StartIndex2);
502 if DashSeparator then begin
503 StartIndex4 := PosFromIndexReverse('-', Text, StartIndex2);
504 if StartIndex4 > StartIndex3 then StartIndex3 := StartIndex4;
505 end;
506
507 if StartIndex3 = 0 then Break;
508 OneWord := Copy(Text, StartIndex3 + 1, StartIndex2 - StartIndex3);
509 if OneWord = '$' then begin
510 // Avoid parsing Bash variables
511 Result := False;
512 Exit;
513 end;
514 if Trim(OneWord) = '' then begin
515 StartIndex2 := StartIndex3 - 1;
516 Continue;
517 end;
518 // Is first letter capital?
519 if (Length(OneWord) > 0) and IsAlpha(OneWord[1]) then begin
520 WordLetterIndex := PosFromIndexReverse(LowerCase(OneWord[1]), LowerCase(Copy(Acronym, 1, LetterIndex)), LetterIndex);
521 if WordLetterIndex > 0 then begin
522 // First letter was found in acronym
523 if WordLetterIndex <= LetterIndex then begin
524 if not WordContainsLetters(LowerCase(OneWord), LowerCase(Copy(Acronym, WordLetterIndex, LetterIndex - WordLetterIndex + 1))) then begin
525 Result := False;
526 Exit;
527 end;
528 LetterIndex := WordLetterIndex - 1;
529 end else begin
530 Dec(LetterIndex);
531 end;
532 WordCountWrong := 0;
533 end else begin
534 Inc(WordCountWrong);
535 if WordCountWrong > 1 then begin
536 Result := False;
537 Exit;
538 end;
539 end;
540 end else begin
541 Inc(WordCountWrong);
542 if WordCountWrong > 1 then begin
543 Result := False;
544 Exit;
545 end;
546 end;
547 StartIndex2 := StartIndex3 - 1;
548 if LetterIndex < 1 then Break;
549 Inc(WordCount);
550 if WordCount > 2 * Length(Acronym) then begin
551 // False acronym in braces with too much words
552 Result := False;
553 Exit;
554 end;
555 end;
556 Meaning := Trim(Copy(Text, StartIndex2 + 1, StartIndex - StartIndex2));
557end;
558
559function TFormCheck.IsUppercaseAlpha(Text: string): Boolean;
560var
561 I: Integer;
562begin
563 I := 1;
564 Result := True;
565 while (I <= Length(Text)) do begin
566 if not (Text[I] in ['A'..'Z']) then begin
567 Result := False;
568 Break;
569 end;
570 Inc(I);
571 end;
572end;
573
574function TFormCheck.IsLowercaseAlpha(Text: string): Boolean;
575var
576 I: Integer;
577begin
578 I := 1;
579 Result := True;
580 while (I <= Length(Text)) do begin
581 if not (Text[I] in ['a'..'z']) then begin
582 Result := False;
583 Break;
584 end;
585 Inc(I);
586 end;
587end;
588
589function TFormCheck.IsAlpha(Text: string): Boolean;
590var
591 I: Integer;
592begin
593 I := 1;
594 Result := True;
595 while (I <= Length(Text)) do begin
596 if not (Text[I] in ['A'..'Z']) and not (Text[I] in ['a'..'z']) then begin
597 Result := False;
598 Break;
599 end;
600 Inc(I);
601 end;
602end;
603
604function TFormCheck.IsAcronym(Text: string): Boolean;
605const
606 MinAcronymLength = 2;
607begin
608 Result := (Length(Text) >= MinAcronymLength) and IsUppercaseAlpha(Text);
609end;
610
611function TFormCheck.IsDigit(Text: Char): Boolean;
612begin
613 Result := Text in ['0'..'9'];
614end;
615
616procedure TFormCheck.ReportDifferencies;
617var
618 I: Integer;
619 J: Integer;
620 Acronym: TAcronym;
621 Acronym2: TAcronym;
622 Meaning: TAcronymMeaning;
623 Meaning2: TAcronymMeaning;
624begin
625 // In content but not in summary
626 for I := 0 to AcronymDbContent.Acronyms.Count - 1 do begin
627 Acronym := TAcronym(AcronymDbContent.Acronyms[I]);
628 if Acronym.Meanings.Count > 1 then
629 ReportItems.AddNew(Format(SAcronymContentMultipleMeanings, [Acronym.Name,
630 Acronym.Meanings.GetNames]), Point(0, 0), rtWarning);
631 Acronym2 := AcronymDbSummary.Acronyms.SearchByName(Acronym.Name);
632 if not Assigned(Acronym2) then
633 for J := 0 to Acronym.Meanings.Count - 1 do begin
634 Meaning := TAcronymMeaning(Acronym.Meanings[J]);
635 if not Assigned(AcronymDbSummary.SearchAcronym(Acronym.Name, Meaning.Name, [sfCaseInsensitive])) then
636 ReportItems.AddNew(Format(SMissingAcronymContent, [Acronym.Name, Meaning.Name]), Point(0, 0), rtWarning);
637 end;
638 end;
639
640 // In summary but not in content
641 for I := 0 to AcronymDbSummary.Acronyms.Count - 1 do begin
642 Acronym := TAcronym(AcronymDbSummary.Acronyms[I]);
643 if Acronym.Meanings.Count > 1 then
644 ReportItems.AddNew(Format(SAcronymSummaryMultipleMeanings, [Acronym.Name, Acronym.Meanings.GetNames]), Point(0, 0), rtWarning);
645 Acronym2 := AcronymDbContent.Acronyms.SearchByName(Acronym.Name);
646 if not Assigned(Acronym2) then
647 for J := 0 to Acronym.Meanings.Count - 1 do begin
648 Meaning := TAcronymMeaning(Acronym.Meanings[J]);
649 if not Assigned(AcronymDbContent.SearchAcronym(Acronym.Name, Meaning.Name, [sfCaseInsensitive])) then
650 ReportItems.AddNew(Format(SMissingAcronymSummary, [Acronym.Name, Meaning.Name]), Point(0, 0), rtWarning);
651 end;
652 end;
653
654 // With different meaning
655 for I := 0 to AcronymDbSummary.Acronyms.Count - 1 do begin
656 Acronym := TAcronym(AcronymDbSummary.Acronyms[I]);
657 Acronym2 := AcronymDbContent.Acronyms.SearchByName(Acronym.Name);
658 if Assigned(Acronym2) then begin
659 if (Acronym.Meanings.Count = 1) and (Acronym2.Meanings.Count = 1) then begin
660 Meaning := TAcronymMeaning(Acronym.Meanings[0]);
661 Meaning2 := TAcronymMeaning(Acronym2.Meanings[0]);
662 if not StringEqual(Meaning.Name, Meaning2.Name) then
663 ReportItems.AddNew(Format(SAcronymWithDifferentMeaning, [Acronym.Name, Meaning2.Name, Meaning.Name]), Point(0, 0), rtWarning);
664 end else
665 ReportItems.AddNew(Format(SAcronymWithDifferentMeaningCount, [Acronym.Name, Acronym2.Meanings.Count, Acronym.Meanings.Count]), Point(0, 0), rtWarning);
666 end;
667 end;
668end;
669
670function TFormCheck.WordContainsLetters(Text, Letters: string): Boolean;
671var
672 I: Integer;
673 LetterIndex: Integer;
674begin
675 Result := True;
676 for I := 1 to Length(Letters) do begin
677 LetterIndex := Pos(Letters[I], Text);
678 if LetterIndex > 0 then begin
679 Text := Copy(Text, LetterIndex + 1, Length(Text));
680 end else begin
681 Result := False;
682 Break;
683 end;
684 end;
685end;
686
687function TFormCheck.StringEqual(Text1, Text2: string): Boolean;
688begin
689 if CheckBoxCaseSensitive.Checked then Result := Text1 = Text2
690 else Result := LowerCase(Text1) = LowerCase(Text2);
691end;
692
693procedure TFormCheck.ReloadReport;
694begin
695 ListViewReport.Items.Count := ReportItems.Count;
696 ListViewReport.Refresh;
697end;
698
699procedure TFormCheck.UpdateInterface;
700begin
701 LabelAcronymCountContent.Caption := SAcronymCountContent + ' ' + IntToStr(AcronymDbContent.GetMeaningsCount);
702 LabelAcronymCountSummary.Caption := SAcronymCountSummary + ' ' + IntToStr(AcronymDbSummary.GetMeaningsCount);
703end;
704
705procedure TFormCheck.LoadConfig(RegistryContext: TRegistryContext);
706begin
707 with TRegistryEx.Create do
708 try
709 RootKey := RegistryContext.RootKey;
710 OpenKey(RegistryContext.Key, True);
711 EditSummaryStart.Text := ReadStringWithDefault('SummaryStart', 'ACRONYMS AND ABBREVIATIONS');
712 EditSummaryEnd.Text := ReadStringWithDefault('SummaryEnd', 'Appendix');
713 LastDocumentFileName := ReadStringWithDefault('LastDocumentFileName', '');
714 CheckBoxCaseSensitive.Checked := ReadBoolWithDefault('CaseSensitiveComparison', False);
715 finally
716 Free;
717 end;
718end;
719
720procedure TFormCheck.SaveConfig(RegistryContext: TRegistryContext);
721begin
722 with TRegistryEx.Create do
723 try
724 RootKey := RegistryContext.RootKey;
725 OpenKey(RegistryContext.Key, True);
726 WriteString('SummaryStart', EditSummaryStart.Text);
727 WriteString('SummaryEnd', EditSummaryEnd.Text);
728 WriteString('LastDocumentFileName', LastDocumentFileName);
729 WriteBool('CaseSensitiveComparison', CheckBoxCaseSensitive.Checked);
730 finally
731 Free;
732 end;
733end;
734
735end.
736
Note: See TracBrowser for help on using the repository browser.