Revision | 259 (tree) |
---|---|
Zeit | 2015-02-02 19:57:57 |
Autor | twm |
started to add search functionality
@@ -5,7 +5,9 @@ | ||
5 | 5 | w_LargeTextViewer in 'w_LargeTextViewer.pas' {f_LargeTextViewer}, |
6 | 6 | u_TextFileIndexer in 'u_TextFileIndexer.pas', |
7 | 7 | u_Int64List in 'u_Int64List.pas', |
8 | - w_GotoLine in 'w_GotoLine.pas' {f_GotoLine}; | |
8 | + w_GotoLine in 'w_GotoLine.pas' {f_GotoLine}, | |
9 | + w_Search in 'w_Search.pas' {f_Search}, | |
10 | + JclUnicode in '..\libs\jcl\source\common\JclUnicode.pas'; | |
9 | 11 | |
10 | 12 | {$R *_version.res} |
11 | 13 | {$R *_icon.res} |
@@ -22,10 +22,10 @@ | ||
22 | 22 | <DCC_DcuOutput>..\dcu</DCC_DcuOutput> |
23 | 23 | <DCC_ObjOutput>..\dcu</DCC_ObjOutput> |
24 | 24 | <DCC_HppOutput>..\dcu</DCC_HppOutput> |
25 | - <DCC_UnitSearchPath>$(BDS)\lib\Debug;..\libs\dzlib\src;..\libs\dzlib\components;..\libs\dzlib\jedi_inc;..\libs\dzlib\templates</DCC_UnitSearchPath> | |
26 | - <DCC_ResourcePath>$(BDS)\lib\Debug;..\libs\dzlib\src;..\libs\dzlib\components;..\libs\dzlib\jedi_inc;..\libs\dzlib\templates</DCC_ResourcePath> | |
27 | - <DCC_ObjPath>$(BDS)\lib\Debug;..\libs\dzlib\src;..\libs\dzlib\components;..\libs\dzlib\jedi_inc;..\libs\dzlib\templates</DCC_ObjPath> | |
28 | - <DCC_IncludePath>$(BDS)\lib\Debug;..\libs\dzlib\src;..\libs\dzlib\components;..\libs\dzlib\jedi_inc;..\libs\dzlib\templates</DCC_IncludePath> | |
25 | + <DCC_UnitSearchPath>$(BDS)\lib\Debug;..\libs\dzlib\src;..\libs\dzlib\components;..\libs\dzlib\jedi_inc;..\libs\dzlib\templates;..\libs\jcl\source\common;..\libs\jcl\source\include;..\libs\jcl\source\include\jedi;..\libs\jcl\source\windows</DCC_UnitSearchPath> | |
26 | + <DCC_ResourcePath>$(BDS)\lib\Debug;..\libs\dzlib\src;..\libs\dzlib\components;..\libs\dzlib\jedi_inc;..\libs\dzlib\templates;..\libs\jcl\source\common;..\libs\jcl\source\include;..\libs\jcl\source\include\jedi;..\libs\jcl\source\windows</DCC_ResourcePath> | |
27 | + <DCC_ObjPath>$(BDS)\lib\Debug;..\libs\dzlib\src;..\libs\dzlib\components;..\libs\dzlib\jedi_inc;..\libs\dzlib\templates;..\libs\jcl\source\common;..\libs\jcl\source\include;..\libs\jcl\source\include\jedi;..\libs\jcl\source\windows</DCC_ObjPath> | |
28 | + <DCC_IncludePath>$(BDS)\lib\Debug;..\libs\dzlib\src;..\libs\dzlib\components;..\libs\dzlib\jedi_inc;..\libs\dzlib\templates;..\libs\jcl\source\common;..\libs\jcl\source\include;..\libs\jcl\source\include\jedi;..\libs\jcl\source\windows</DCC_IncludePath> | |
29 | 29 | <DCC_Define>DEBUG;NO_TRANSLATION;no_jvcl</DCC_Define> |
30 | 30 | <DCC_SYMBOL_PLATFORM>False</DCC_SYMBOL_PLATFORM> |
31 | 31 | <DCC_UNIT_PLATFORM>False</DCC_UNIT_PLATFORM> |
@@ -131,6 +131,7 @@ | ||
131 | 131 | <DelphiCompile Include="dzLargeTextViewer.dpr"> |
132 | 132 | <MainSource>MainSource</MainSource> |
133 | 133 | </DelphiCompile> |
134 | + <DCCReference Include="..\libs\jcl\source\common\JclUnicode.pas" /> | |
134 | 135 | <DCCReference Include="u_Int64List.pas" /> |
135 | 136 | <DCCReference Include="u_TextFileIndexer.pas" /> |
136 | 137 | <DCCReference Include="w_GotoLine.pas"> |
@@ -139,5 +140,8 @@ | ||
139 | 140 | <DCCReference Include="w_LargeTextViewer.pas"> |
140 | 141 | <Form>f_LargeTextViewer</Form> |
141 | 142 | </DCCReference> |
143 | + <DCCReference Include="w_Search.pas"> | |
144 | + <Form>f_Search</Form> | |
145 | + </DCCReference> | |
142 | 146 | </ItemGroup> |
143 | 147 | </Project> |
\ No newline at end of file |
@@ -1,6 +1,6 @@ | ||
1 | 1 | [Version Info] |
2 | 2 | AutoIncBuild=0 |
3 | -Build=21 | |
3 | +Build=97 | |
4 | 4 | MajorVer=1 |
5 | 5 | MinorVer=0 |
6 | 6 | Release=0 |
@@ -7,7 +7,7 @@ | ||
7 | 7 | Revision=0 |
8 | 8 | |
9 | 9 | [Version Info Keys] |
10 | -FileVersion=1.0.0.21 | |
10 | +FileVersion=1.0.0.97 | |
11 | 11 | ProductVersion={today} |
12 | 12 | FileDescription=Viewer for large text files |
13 | 13 | OriginalFilename=dzLargeTextViewer.exe |
@@ -14,6 +14,7 @@ | ||
14 | 14 | Dialogs, |
15 | 15 | StdCtrls, |
16 | 16 | u_dzTranslator, |
17 | + u_dzVclUtils, | |
17 | 18 | u_dzInputValidator; |
18 | 19 | |
19 | 20 | type |
@@ -38,8 +39,6 @@ | ||
38 | 39 | |
39 | 40 | {$R *.dfm} |
40 | 41 | |
41 | -uses | |
42 | - u_dzVclUtils; | |
43 | 42 | |
44 | 43 | { Tf_GotoLine } |
45 | 44 |
@@ -52,6 +52,8 @@ | ||
52 | 52 | mi_LineCopy: TMenuItem; |
53 | 53 | act_LineGoto: TAction; |
54 | 54 | mi_LineGoto: TMenuItem; |
55 | + act_LineFind: TAction; | |
56 | + mi_LineFind: TMenuItem; | |
55 | 57 | procedure sg_DisplayGetNonfixedCellData(_Sender: TObject; _DataCol, _DataRow: Integer; |
56 | 58 | _State: TGridDrawState; var _Text: string; var _HAlign: TAlignment; |
57 | 59 | var _VAlign: TdzCellVertAlign; _Font: TFont; var _Color: TColor); |
@@ -65,6 +67,7 @@ | ||
65 | 67 | procedure act_LineCopyExecute(Sender: TObject); |
66 | 68 | procedure sg_DisplaySelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); |
67 | 69 | procedure act_LineGotoExecute(Sender: TObject); |
70 | + procedure act_LineFindExecute(Sender: TObject); | |
68 | 71 | private |
69 | 72 | FIndexer: TTextFileIndexer; |
70 | 73 | FIndexThread: TIndexerThread; |
@@ -71,6 +74,7 @@ | ||
71 | 74 | FFile: TdzFile; |
72 | 75 | procedure OpenFile; |
73 | 76 | procedure UpdateCurrentLineNo; |
77 | + procedure OnFind(_Sender: TObject; const _Pattern: string); | |
74 | 78 | public |
75 | 79 | constructor Create(_Owner: TComponent); override; |
76 | 80 | destructor Destroy; override; |
@@ -87,7 +91,8 @@ | ||
87 | 91 | uses |
88 | 92 | ClipBrd, |
89 | 93 | u_dzClassUtils, |
90 | - w_GotoLine; | |
94 | + w_GotoLine, | |
95 | + w_Search; | |
91 | 96 | |
92 | 97 | { TIndexerThread } |
93 | 98 |
@@ -104,7 +109,7 @@ | ||
104 | 109 | FIndexer.Execute; |
105 | 110 | except |
106 | 111 | on EAbort do |
107 | - // itnore; | |
112 | + // ignore; | |
108 | 113 | else |
109 | 114 | raise; |
110 | 115 | end; |
@@ -158,6 +163,16 @@ | ||
158 | 163 | end; |
159 | 164 | end; |
160 | 165 | |
166 | +procedure Tf_LargeTextViewer.act_LineFindExecute(Sender: TObject); | |
167 | +begin | |
168 | + Tf_Search.Execute(Self, 'while', OnFind); | |
169 | +end; | |
170 | + | |
171 | +procedure Tf_LargeTextViewer.OnFind(_Sender: TObject; const _Pattern: string); | |
172 | +begin | |
173 | +// | |
174 | +end; | |
175 | + | |
161 | 176 | procedure Tf_LargeTextViewer.act_LineGotoExecute(Sender: TObject); |
162 | 177 | var |
163 | 178 | LineNo: Integer; |
@@ -0,0 +1,160 @@ | ||
1 | +unit w_Search; | |
2 | + | |
3 | +interface | |
4 | + | |
5 | +uses | |
6 | + Windows, | |
7 | + Messages, | |
8 | + SysUtils, | |
9 | + Variants, | |
10 | + Classes, | |
11 | + Graphics, | |
12 | + Controls, | |
13 | + Forms, | |
14 | + StdCtrls, | |
15 | + u_dzTranslator; | |
16 | + | |
17 | +type | |
18 | + TOnSearchEvent = procedure(_Sender: TObject; const _Pattern: string) of object; | |
19 | + | |
20 | +type | |
21 | + Tf_Search = class(TForm) | |
22 | + ed_Pattern: TEdit; | |
23 | + l_Pattern: TLabel; | |
24 | + m_Text: TMemo; | |
25 | + b_Find: TButton; | |
26 | + procedure b_FindClick(Sender: TObject); | |
27 | + private | |
28 | + FCallback: TOnSearchEvent; | |
29 | + procedure SetData(const _Pattern: string; _Callback: TOnSearchEvent); | |
30 | + public | |
31 | + class procedure Execute(_Owner: TWinControl; const _Pattern: string; _Callback: TOnSearchEvent); static; | |
32 | + constructor Create(_Owner: TComponent); override; | |
33 | + end; | |
34 | + | |
35 | +implementation | |
36 | + | |
37 | +{$R *.dfm} | |
38 | + | |
39 | +uses | |
40 | + StrUtils, | |
41 | + JclUnicode, | |
42 | + u_dzVclUtils; | |
43 | + | |
44 | +///<summary> | |
45 | +/// This is the Boyer-Moore-Horspool text searching algorithm taken from | |
46 | +/// http://users.dcc.uchile.cl/~rbaeza/handbook/algs/7/713b.srch.p.html | |
47 | +/// Modified to work with characters > chr(127) (It does not support unicode though.) | |
48 | +/// and take an offset where to start. | |
49 | +/// Also, it uses Exit rather than a boolean variable to terminate the while loop. | |
50 | +/// @param Pattern is the string to search for | |
51 | +/// @param Text is the string to search in </summary | |
52 | + | |
53 | +function BMHSearch(_Pattern: string; _Text: string; _Offset: Integer = 0): Integer; | |
54 | +const | |
55 | + MaxChar = Ord(High(Char)); | |
56 | +var | |
57 | + i: Integer; | |
58 | + PatternLen, TextLen: Integer; | |
59 | + PatternIdx, TextIdx: Integer; | |
60 | + skip: array of Integer; | |
61 | +begin | |
62 | + PatternLen := Length(_Pattern); | |
63 | + if PatternLen = 0 then begin | |
64 | + Result := 1; | |
65 | + Exit; //=> | |
66 | + end; | |
67 | + | |
68 | + Result := 0; | |
69 | + | |
70 | + SetLength(skip, MaxChar); | |
71 | + for i := 0 to MaxChar do | |
72 | + skip[i] := PatternLen; {*** Preprocessing ***} | |
73 | + for i := 1 to PatternLen - 1 do | |
74 | + skip[Ord(_Pattern[i])] := PatternLen - i; | |
75 | + | |
76 | + i := PatternLen + _Offset; | |
77 | + TextLen := Length(_Text); {*** Search ***} | |
78 | + while i <= TextLen do begin | |
79 | + TextIdx := i; | |
80 | + PatternIdx := PatternLen; | |
81 | + while (PatternIdx >= 1) do | |
82 | + if _Text[TextIdx] <> _Pattern[PatternIdx] then | |
83 | + PatternIdx := -1 | |
84 | + else begin | |
85 | + PatternIdx := PatternIdx - 1; | |
86 | + TextIdx := TextIdx - 1; | |
87 | + end; | |
88 | + if PatternIdx = 0 then begin | |
89 | + Result := TextIdx + 1; | |
90 | + Exit; //=> | |
91 | + end; | |
92 | + i := i + skip[Ord(_Text[i])]; | |
93 | + end; | |
94 | +end; | |
95 | + | |
96 | +var | |
97 | + frm: Tf_Search; | |
98 | + | |
99 | +{ Tf_Search } | |
100 | + | |
101 | +class procedure Tf_Search.Execute(_Owner: TWinControl; const _Pattern: string; | |
102 | + _Callback: TOnSearchEvent); | |
103 | +begin | |
104 | + if not Assigned(frm) then begin | |
105 | + frm := Tf_Search.Create(_Owner); | |
106 | + TForm_CenterOn(frm, _Owner); | |
107 | + end; | |
108 | + frm.SetData(_Pattern, _Callback); | |
109 | + frm.Show; | |
110 | +end; | |
111 | + | |
112 | +constructor Tf_Search.Create(_Owner: TComponent); | |
113 | +begin | |
114 | + inherited; | |
115 | + | |
116 | + TranslateComponent(Self); | |
117 | + | |
118 | + m_Text.SelStart := 0; | |
119 | + m_Text.SelLength := 0; | |
120 | +end; | |
121 | + | |
122 | +procedure Tf_Search.SetData(const _Pattern: string; _Callback: TOnSearchEvent); | |
123 | +begin | |
124 | + ed_Pattern.Text := _Pattern; | |
125 | + FCallback := _Callback; | |
126 | +end; | |
127 | + | |
128 | +procedure Tf_Search.b_FindClick(Sender: TObject); | |
129 | +var | |
130 | + Pattern: string; | |
131 | + Search: TUTBMSearch; | |
132 | + Offset: Integer; | |
133 | + Start: Integer; | |
134 | + Stop: Integer; | |
135 | + Text: WideString; | |
136 | + StartP: PWideChar; | |
137 | +begin | |
138 | + Pattern := ed_Pattern.Text; | |
139 | + Search := TUTBMSearch.Create(nil); | |
140 | + try | |
141 | + Search.FindPrepare(Pattern, [sfWholeWordOnly]); | |
142 | + Offset := m_Text.SelStart + m_Text.SelLength; | |
143 | + Text := m_Text.Lines.Text; | |
144 | + StartP := @Text[1]; | |
145 | + Inc(StartP, Offset); | |
146 | + if Search.FindFirst(StartP, Start, Stop) then begin | |
147 | + m_Text.SelStart := Start + Offset; | |
148 | + m_Text.SelLength := Length(Pattern); | |
149 | + end; | |
150 | + finally | |
151 | + FreeAndNil(Search); | |
152 | + end; | |
153 | + m_Text.SetFocus; | |
154 | + Exit; | |
155 | + | |
156 | + FCallback(Self, ed_Pattern.Text); | |
157 | +end; | |
158 | + | |
159 | +end. | |
160 | + |