1 | unit FormCompareSideBySide;
|
---|
2 |
|
---|
3 | interface
|
---|
4 |
|
---|
5 | uses
|
---|
6 | Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
|
---|
7 | VCard, Diff, LCLType, LCLIntf, ComCtrls, Buttons, Menus, ActnList, SynEdit,
|
---|
8 | SynEditMiscClasses, SynHighlighterPosition, SynEditHighlighter, Common,
|
---|
9 | SynEditEx, FormEx;
|
---|
10 |
|
---|
11 | type
|
---|
12 |
|
---|
13 | { TFormCompareSideBySide }
|
---|
14 |
|
---|
15 | TFormCompareSideBySide = class(TFormEx)
|
---|
16 | ASwitchSides: TAction;
|
---|
17 | AReloadFiles: TAction;
|
---|
18 | AFileOpenLeft: TAction;
|
---|
19 | AFileOpenRight: TAction;
|
---|
20 | ActionList1: TActionList;
|
---|
21 | EditLeftFileName: TEdit;
|
---|
22 | EditRightFileName: TEdit;
|
---|
23 | MainMenu1: TMainMenu;
|
---|
24 | MenuItem1: TMenuItem;
|
---|
25 | MenuItem2: TMenuItem;
|
---|
26 | MenuItem3: TMenuItem;
|
---|
27 | MenuItem4: TMenuItem;
|
---|
28 | MenuItem5: TMenuItem;
|
---|
29 | MenuItemClose: TMenuItem;
|
---|
30 | OpenDialogSide: TOpenDialog;
|
---|
31 | PanelLeft: TPanel;
|
---|
32 | PanelRight: TPanel;
|
---|
33 | SpeedButtonOpenLeft: TSpeedButton;
|
---|
34 | SpeedButtonOpenRight: TSpeedButton;
|
---|
35 | Splitter1: TSplitter;
|
---|
36 | SynEditLeft: TSynEditEx;
|
---|
37 | SynEditRight: TSynEditEx;
|
---|
38 | procedure AFileOpenLeftExecute(Sender: TObject);
|
---|
39 | procedure AFileOpenRightExecute(Sender: TObject);
|
---|
40 | procedure AReloadFilesExecute(Sender: TObject);
|
---|
41 | procedure ASwitchSidesExecute(Sender: TObject);
|
---|
42 | procedure FormActivate(Sender: TObject);
|
---|
43 | procedure FormCreate(Sender: TObject);
|
---|
44 | procedure FormDestroy(Sender: TObject);
|
---|
45 | procedure FormResize(Sender: TObject);
|
---|
46 | procedure FormShow(Sender: TObject);
|
---|
47 | procedure MenuItemCloseClick(Sender: TObject);
|
---|
48 | procedure SynEditLeftChange(Sender: TObject);
|
---|
49 | procedure SynEditLeftScroll(Sender: TObject);
|
---|
50 | procedure SynEditRightChange(Sender: TObject);
|
---|
51 | procedure SynEditRightScroll(Sender: TObject);
|
---|
52 | private
|
---|
53 | FLeftSide: string;
|
---|
54 | FRightSide: string;
|
---|
55 | Diff: TDiff;
|
---|
56 | HighlighterLeft: TSynPositionHighlighter;
|
---|
57 | HighlighterRight: TSynPositionHighlighter;
|
---|
58 | AttrAdded: TtkTokenKind;
|
---|
59 | AttrDeleted: TtkTokenKind;
|
---|
60 | AttrModified: TtkTokenKind;
|
---|
61 | LastWidth: Integer;
|
---|
62 | procedure SetLeftSide(AValue: string);
|
---|
63 | procedure SetRightSide(AValue: string);
|
---|
64 | procedure ReloadContent;
|
---|
65 | procedure UpdateInterface;
|
---|
66 | procedure UpdateHighlight;
|
---|
67 | function LoadFile(AFileName: string): string;
|
---|
68 | public
|
---|
69 | procedure LoadFileLeft(FileName: string);
|
---|
70 | procedure LoadFileRight(FileName: string);
|
---|
71 | property LeftSide: string read FLeftSide write SetLeftSide;
|
---|
72 | property RightSide: string read FRightSide write SetRightSide;
|
---|
73 | end;
|
---|
74 |
|
---|
75 |
|
---|
76 | implementation
|
---|
77 |
|
---|
78 | {$R *.lfm}
|
---|
79 |
|
---|
80 | uses
|
---|
81 | VCardFile;
|
---|
82 |
|
---|
83 | { TFormCompareSideBySide }
|
---|
84 |
|
---|
85 | procedure TFormCompareSideBySide.ASwitchSidesExecute(Sender: TObject);
|
---|
86 | var
|
---|
87 | TempFileName: string;
|
---|
88 | TempContent: string;
|
---|
89 | begin
|
---|
90 | TempContent := SynEditLeft.Text;
|
---|
91 | SynEditLeft.Text := SynEditRight.Text;
|
---|
92 | SynEditRight.Text := TempContent;
|
---|
93 |
|
---|
94 | TempFileName := EditLeftFileName.Text;
|
---|
95 | EditLeftFileName.Text := EditRightFileName.Text;
|
---|
96 | EditRightFileName.Text := TempFileName;
|
---|
97 |
|
---|
98 | UpdateInterface;
|
---|
99 | UpdateHighlight;
|
---|
100 | end;
|
---|
101 |
|
---|
102 | procedure TFormCompareSideBySide.FormActivate(Sender: TObject);
|
---|
103 | begin
|
---|
104 | if LastWidth = -1 then LastWidth := Width;
|
---|
105 | end;
|
---|
106 |
|
---|
107 | procedure TFormCompareSideBySide.AReloadFilesExecute(Sender: TObject);
|
---|
108 | begin
|
---|
109 | LoadFileLeft(EditLeftFileName.Text);
|
---|
110 | LoadFileRight(EditRightFileName.Text);
|
---|
111 | UpdateHighlight;
|
---|
112 | UpdateInterface;
|
---|
113 | end;
|
---|
114 |
|
---|
115 | procedure TFormCompareSideBySide.AFileOpenLeftExecute(Sender: TObject);
|
---|
116 | begin
|
---|
117 | OpenDialogSide.InitialDir := ExtractFileDir(EditLeftFileName.Text);
|
---|
118 | OpenDialogSide.FileName := ExtractFileName(EditLeftFileName.Text);
|
---|
119 | if OpenDialogSide.Execute then begin
|
---|
120 | EditLeftFileName.Text := OpenDialogSide.FileName;
|
---|
121 | SynEditLeft.Text := LoadFileToStr(OpenDialogSide.FileName);
|
---|
122 | end;
|
---|
123 | end;
|
---|
124 |
|
---|
125 | procedure TFormCompareSideBySide.AFileOpenRightExecute(Sender: TObject);
|
---|
126 | begin
|
---|
127 | OpenDialogSide.InitialDir := ExtractFileDir(EditRightFileName.Text);
|
---|
128 | OpenDialogSide.FileName := ExtractFileName(EditRightFileName.Text);
|
---|
129 | if OpenDialogSide.Execute then begin
|
---|
130 | EditRightFileName.Text := OpenDialogSide.FileName;
|
---|
131 | SynEditRight.Text := LoadFileToStr(OpenDialogSide.FileName);
|
---|
132 | end;
|
---|
133 | UpdateHighlight;
|
---|
134 | end;
|
---|
135 |
|
---|
136 | procedure TFormCompareSideBySide.FormCreate(Sender: TObject);
|
---|
137 | begin
|
---|
138 | Diff := TDiff.Create(Self);
|
---|
139 |
|
---|
140 | HighlighterLeft := TSynPositionHighlighter.Create(Self);
|
---|
141 | with HighlighterLeft do begin
|
---|
142 | AttrAdded := CreateTokenID('Added', clNone, clLightGreen, []);
|
---|
143 | AttrDeleted := CreateTokenID('Deleted', clNone, clLightBlue, []);
|
---|
144 | AttrModified := CreateTokenID('Modified', clNone, clLightRed, []);
|
---|
145 | end;
|
---|
146 | SynEditLeft.Highlighter := HighlighterLeft;
|
---|
147 |
|
---|
148 | HighlighterRight := TSynPositionHighlighter.Create(Self);
|
---|
149 | with HighlighterRight do begin
|
---|
150 | AttrAdded := CreateTokenID('Added', clNone, clLightGreen, []);
|
---|
151 | AttrDeleted := CreateTokenID('Deleted', clNone, clLightBlue, []);
|
---|
152 | AttrModified := CreateTokenID('Modified', clNone, clLightRed, []);
|
---|
153 | end;
|
---|
154 | SynEditRight.Highlighter := HighlighterRight;
|
---|
155 |
|
---|
156 | LastWidth := -1;
|
---|
157 | end;
|
---|
158 |
|
---|
159 | procedure TFormCompareSideBySide.FormDestroy(Sender: TObject);
|
---|
160 | begin
|
---|
161 | FreeAndNil(HighlighterLeft);
|
---|
162 | FreeAndNil(HighlighterRight);
|
---|
163 | FreeAndNil(Diff);
|
---|
164 | end;
|
---|
165 |
|
---|
166 | procedure TFormCompareSideBySide.FormResize(Sender: TObject);
|
---|
167 | var
|
---|
168 | LastHandler: TNotifyEvent;
|
---|
169 | NewPanelWidth: Integer;
|
---|
170 | const
|
---|
171 | MaxRatio = 0.8;
|
---|
172 | begin
|
---|
173 | if LastWidth <> -1 then begin
|
---|
174 | LastHandler := PanelLeft.OnResize;
|
---|
175 | try
|
---|
176 | PanelLeft.OnResize := nil;
|
---|
177 | NewPanelWidth := Round((PanelLeft.Width / LastWidth) * Width);
|
---|
178 | if NewPanelWidth > Round(Width * MaxRatio) then NewPanelWidth := Round(Width * MaxRatio);
|
---|
179 | PanelLeft.Width := NewPanelWidth;
|
---|
180 | finally
|
---|
181 | PanelLeft.OnResize := LastHandler;
|
---|
182 | end;
|
---|
183 | LastWidth := Width;
|
---|
184 | end;
|
---|
185 | end;
|
---|
186 |
|
---|
187 | procedure TFormCompareSideBySide.FormShow(Sender: TObject);
|
---|
188 | begin
|
---|
189 | UpdateInterface;
|
---|
190 | ReloadContent;
|
---|
191 | end;
|
---|
192 |
|
---|
193 | procedure TFormCompareSideBySide.MenuItemCloseClick(Sender: TObject);
|
---|
194 | begin
|
---|
195 | Close;
|
---|
196 | end;
|
---|
197 |
|
---|
198 | procedure TFormCompareSideBySide.SynEditLeftChange(Sender: TObject);
|
---|
199 | begin
|
---|
200 | UpdateHighlight;
|
---|
201 | end;
|
---|
202 |
|
---|
203 | procedure TFormCompareSideBySide.SynEditLeftScroll(Sender: TObject);
|
---|
204 | begin
|
---|
205 | SynEditRight.TopLine := SynEditLeft.TopLine;
|
---|
206 | end;
|
---|
207 |
|
---|
208 | procedure TFormCompareSideBySide.SynEditRightChange(Sender: TObject);
|
---|
209 | begin
|
---|
210 | UpdateHighlight;
|
---|
211 | end;
|
---|
212 |
|
---|
213 | procedure TFormCompareSideBySide.SynEditRightScroll(Sender: TObject);
|
---|
214 | begin
|
---|
215 | SynEditLeft.TopLine := SynEditRight.TopLine;
|
---|
216 | end;
|
---|
217 |
|
---|
218 | procedure TFormCompareSideBySide.SetLeftSide(AValue: string);
|
---|
219 | begin
|
---|
220 | if FLeftSide = AValue then Exit;
|
---|
221 | FLeftSide := AValue;
|
---|
222 | end;
|
---|
223 |
|
---|
224 | procedure TFormCompareSideBySide.SetRightSide(AValue: string);
|
---|
225 | begin
|
---|
226 | if FRightSide = AValue then Exit;
|
---|
227 | FRightSide := AValue;
|
---|
228 | end;
|
---|
229 |
|
---|
230 | procedure TFormCompareSideBySide.ReloadContent;
|
---|
231 | begin
|
---|
232 | UpdateHighlight;
|
---|
233 | end;
|
---|
234 |
|
---|
235 | procedure TFormCompareSideBySide.UpdateInterface;
|
---|
236 | begin
|
---|
237 | end;
|
---|
238 |
|
---|
239 | procedure TFormCompareSideBySide.UpdateHighlight;
|
---|
240 | var
|
---|
241 | LeftText: string;
|
---|
242 | RightText: string;
|
---|
243 | I: Integer;
|
---|
244 | LastKind: TChangeKind;
|
---|
245 | P1: TPoint;
|
---|
246 | P2: TPoint;
|
---|
247 | Rec: TCompareRec;
|
---|
248 | NextToken1: TtkTokenKind;
|
---|
249 | NextToken2: TtkTokenKind;
|
---|
250 | begin
|
---|
251 | LeftText := SynEditLeft.Lines.Text;
|
---|
252 | RightText := SynEditRight.Lines.Text;
|
---|
253 |
|
---|
254 | Diff.Execute(PChar(LeftText), PChar(RightText), Length(LeftText), Length(RightText));
|
---|
255 |
|
---|
256 | HighlighterLeft.ClearAllTokens;
|
---|
257 | HighlighterRight.ClearAllTokens;
|
---|
258 | LeftText := '';
|
---|
259 | RightText := '';
|
---|
260 | LastKind := ckNone;
|
---|
261 | P1 := Point(1, 0);
|
---|
262 | P2 := Point(1, 0);
|
---|
263 | NextToken1 := tkText;
|
---|
264 | NextToken2 := tkText;
|
---|
265 | for I := 0 to Diff.Count - 1 do
|
---|
266 | with Diff.Compares[I] do begin
|
---|
267 | Rec := Diff.Compares[I];
|
---|
268 | if Rec.Chr1 = LineEnding then begin
|
---|
269 | if NextToken1 <> tkText then begin
|
---|
270 | HighlighterLeft.AddToken(P1.Y, 0, NextToken1);
|
---|
271 | NextToken1 := tkText;
|
---|
272 | end;
|
---|
273 | Inc(P1.Y);
|
---|
274 | P1.X := 0;
|
---|
275 | LeftText := LeftText + Rec.Chr1;
|
---|
276 | end else begin
|
---|
277 | if Kind = ckAdd then LeftText := LeftText + ' '
|
---|
278 | else LeftText := LeftText + Rec.chr1;
|
---|
279 | if Kind <> LastKind then begin
|
---|
280 | HighlighterLeft.AddToken(P1.Y, P1.X, NextToken1);
|
---|
281 | if Kind = ckNone then NextToken1 := tkText
|
---|
282 | //else if Kind = ckAdd then NextToken1 := AttrAdded
|
---|
283 | else if Kind = ckDelete then NextToken1 := AttrDeleted
|
---|
284 | else if Kind = ckModify then NextToken1 := AttrModified;
|
---|
285 | end;
|
---|
286 | Inc(P1.X);
|
---|
287 | end;
|
---|
288 |
|
---|
289 | if Rec.Chr2 = LineEnding then begin
|
---|
290 | if NextToken2 <> tkText then begin
|
---|
291 | HighlighterRight.AddToken(P2.Y, 0, NextToken2);
|
---|
292 | NextToken2 := tkText;
|
---|
293 | end;
|
---|
294 | Inc(P2.Y);
|
---|
295 | P2.X := 0;
|
---|
296 | RightText := RightText + Rec.Chr2;
|
---|
297 | end else begin
|
---|
298 | if Kind = ckDelete then RightText := RightText + ' '
|
---|
299 | else RightText := RightText + Rec.Chr2;
|
---|
300 | if Kind <> LastKind then begin
|
---|
301 | HighlighterRight.AddToken(P2.Y, P2.X, NextToken2);
|
---|
302 | if Kind = ckNone then NextToken2 := tkText
|
---|
303 | else if Kind = ckAdd then NextToken2 := AttrAdded
|
---|
304 | //else if Kind = ckDelete then NextToken2 := AttrDeleted
|
---|
305 | else if Kind = ckModify then NextToken2 := AttrModified;
|
---|
306 | end;
|
---|
307 | Inc(P2.X);
|
---|
308 | end;
|
---|
309 |
|
---|
310 | LastKind := Kind;
|
---|
311 | end;
|
---|
312 |
|
---|
313 | //SynEditLeft.Lines.Text := LeftText;
|
---|
314 | //SynEditRight.Lines.Text := RightText;
|
---|
315 | end;
|
---|
316 |
|
---|
317 | function TFormCompareSideBySide.LoadFile(AFileName: string): string;
|
---|
318 | var
|
---|
319 | Ext: string;
|
---|
320 | begin
|
---|
321 | Ext := ExtractFileExt(AFileName);
|
---|
322 | if Ext = VCardFileExt then begin
|
---|
323 | with TVCardFile.Create(nil) do
|
---|
324 | try
|
---|
325 | LoadFromFile(AFileName);
|
---|
326 | Result := VCard.AsString;
|
---|
327 | finally
|
---|
328 | Free;
|
---|
329 | end;
|
---|
330 | end else Result := LoadFileToStr(AFileName);
|
---|
331 | end;
|
---|
332 |
|
---|
333 | procedure TFormCompareSideBySide.LoadFileLeft(FileName: string);
|
---|
334 | begin
|
---|
335 | EditLeftFileName.Text := FileName;
|
---|
336 | LeftSide := LoadFile(FileName);
|
---|
337 | SynEditLeft.Text := LeftSide;
|
---|
338 | end;
|
---|
339 |
|
---|
340 | procedure TFormCompareSideBySide.LoadFileRight(FileName: string);
|
---|
341 | begin
|
---|
342 | EditRightFileName.Text := FileName;
|
---|
343 | RightSide := LoadFile(FileName);
|
---|
344 | SynEditRight.Text := RightSide;
|
---|
345 | end;
|
---|
346 |
|
---|
347 | end.
|
---|
348 |
|
---|