WMDiff.Mod 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. MODULE WMDiff; (** AUTHOR "Ingmar Nebel"; PURPOSE "The difference is in the file text-file!"; *)
  2. IMPORT
  3. Modules, WM := WMWindowManager, WMRestorable, WMStringGrids, WMGrids, WMGraphics, WMRectangles,
  4. WMComponents, WMStandardComponents, DiffLib, Streams, Commands, Strings, WMEvents, Raster,
  5. WMEditors, WMTextView, Texts, Files, UTF8Strings, WMMessages, WMScrollableComponents;
  6. CONST
  7. Width = 1024;
  8. Height = 768;
  9. ShowLineNumbers = TRUE;
  10. DiffStateEmpty = 0;
  11. DiffStateCommon = 1;
  12. DiffStateDifferent = 2;
  13. ScrollbarWidth = 15;
  14. OverviewWidth = 10;
  15. DarkGreen = 000C000FFH;
  16. DarkRed = LONGINT(0C00000FFH);
  17. DiffColorLeft = LONGINT(0FF000030H);
  18. DiffColorRight = 00000FF30H;
  19. EmptyLineColor = WMGraphics.White;
  20. LineNbrBgColor = LONGINT(0E0E0FFFFH);
  21. BgColor = LONGINT(0CCCCCCFFH);
  22. MouseWheelMultiplier = 3;
  23. NonDefaultFont = FALSE;
  24. (* Font to be used when NonDefaultFont = TRUE *)
  25. FontName = "Oberon";
  26. FontSize = 10;
  27. FontStyle = {};
  28. TYPE
  29. NoWheelGrid* = OBJECT(WMStringGrids.StringGrid);
  30. PROCEDURE WheelMove*(dz : LONGINT); (* do nothing *) END WheelMove;
  31. PROCEDURE &Init*;
  32. BEGIN
  33. Init^;
  34. SetNameAsString(StrNoWheelGrid);
  35. END Init;
  36. END NoWheelGrid;
  37. DiffState= OBJECT
  38. VAR state:LONGINT;
  39. END DiffState;
  40. DiffView = OBJECT (WMComponents.VisualComponent)
  41. VAR
  42. filenameEdit: WMEditors.Editor;
  43. lineNbr, grid: NoWheelGrid;
  44. colWidths : WMGrids.Spacings;
  45. commonLines, diffLines: LONGINT;
  46. diffColor, maxLineWidth, minLineWidth: LONGINT;
  47. curLine: LONGINT;
  48. font : WMGraphics.Font;
  49. onPropertyChange, onResized: WMEvents.EventSource;
  50. PROCEDURE CreateFilenamePanel() : WMStandardComponents.Panel;
  51. VAR panel : WMStandardComponents.Panel; label: WMStandardComponents.Label;
  52. BEGIN
  53. NEW(panel); panel.bounds.SetHeight(20); panel.alignment.Set(WMComponents.AlignTop);
  54. panel.fillColor.Set(WMGraphics.White);
  55. NEW(label); label.bounds.SetWidth(60); label.alignment.Set(WMComponents.AlignLeft);
  56. label.alignH.Set(WMComponents.AlignLeft);
  57. label.SetCaption("Filename:");
  58. label.textColor.Set(WMGraphics.Black);
  59. label.fillColor.Set(BgColor);
  60. NEW(filenameEdit);
  61. filenameEdit.alignment.Set(WMComponents.AlignClient);
  62. filenameEdit.tv.textAlignV.Set(WMGraphics.AlignCenter);
  63. filenameEdit.multiLine.Set(FALSE);
  64. filenameEdit.fillColor.Set(LONGINT(0FFFFFFFFH));
  65. filenameEdit.tv.borders.Set(WMRectangles.MakeRect(3,3,1,1));
  66. filenameEdit.tv.showBorder.Set(TRUE);
  67. filenameEdit.tv.SetExtDragOverHandler(FileNameEditDragOver);
  68. filenameEdit.tv.SetExtDragDroppedHandler(FileNameEditDragDropped);
  69. panel.AddContent(label);
  70. panel.AddContent(filenameEdit);
  71. RETURN panel;
  72. END CreateFilenamePanel;
  73. PROCEDURE CreateGrid() : NoWheelGrid;
  74. VAR grid : NoWheelGrid;
  75. BEGIN
  76. NEW(grid);
  77. grid.alignment.Set(WMComponents.AlignLeft);
  78. grid.clTextDefault.Set(WMGraphics.Black);
  79. grid.SetSelectionMode(WMGrids.GridSelectNone);
  80. grid.showScrollY.Set(FALSE);
  81. grid.showScrollX.Set(FALSE);
  82. grid.adjustFocusPosition.Set(FALSE);
  83. grid.defaultRowHeight.Set(15);
  84. grid.cellDist.Set(0);
  85. IF NonDefaultFont THEN
  86. grid.SetFont(WMGraphics.GetFont(FontName, FontSize, FontStyle));
  87. END;
  88. grid.model.Acquire;
  89. grid.model.SetNofCols(1);
  90. grid.model.Release;
  91. RETURN grid;
  92. END CreateGrid;
  93. PROCEDURE &Init*;
  94. VAR scrollPanel : WMScrollableComponents.ScrollableContainer; VAR dx, dy : LONGINT;
  95. BEGIN
  96. Init^;
  97. SetNameAsString(StrDiffView);
  98. NEW(onPropertyChange, SELF, NIL, NIL, NIL);
  99. NEW(onResized, SELF, NIL, NIL, NIL);
  100. lineNbr := CreateGrid();
  101. IF ~ShowLineNumbers THEN lineNbr.visible.Set(FALSE); END;
  102. grid := CreateGrid();
  103. NEW(colWidths, 1); colWidths[0] := 256;
  104. AddContent(CreateFilenamePanel());
  105. AddContent(lineNbr);
  106. NEW(scrollPanel); scrollPanel.alignment.Set(WMComponents.AlignClient);
  107. scrollPanel.AddContent(grid);
  108. AddContent(scrollPanel);
  109. font := grid.GetFont();
  110. font.GetStringSize("0000", dx, dy); INC(dx, 4);
  111. lineNbr.bounds.SetWidth(dx);
  112. onPropertyChange.Call(NIL);
  113. END Init;
  114. PROCEDURE ToggleLineNumbers;
  115. BEGIN {EXCLUSIVE}
  116. lineNbr.visible.Set(~lineNbr.visible.Get());
  117. Invalidate;
  118. END ToggleLineNumbers;
  119. PROCEDURE SetNofLines(nofLines: LONGINT);
  120. BEGIN
  121. lineNbr.model.Acquire;
  122. grid.model.Acquire;
  123. lineNbr.model.SetNofRows(nofLines);
  124. grid.model.SetNofRows(nofLines);
  125. grid.model.Release;
  126. lineNbr.model.Release;
  127. END SetNofLines;
  128. PROCEDURE FileNameEditDragOver(x, y : LONGINT; dragInfo : WM.DragInfo; VAR handled : BOOLEAN);
  129. BEGIN
  130. filenameEdit.tv.SelectAll;
  131. filenameEdit.tv.SetFocus;
  132. handled := TRUE;
  133. END FileNameEditDragOver;
  134. PROCEDURE FileNameEditDragDropped(x, y : LONGINT; dragInfo : WM.DragInfo; VAR handled : BOOLEAN);
  135. VAR dropTarget : WMTextView.TextDropTarget; p : Texts.TextPosition;
  136. BEGIN
  137. filenameEdit.SetAsString("");
  138. filenameEdit.text.AcquireRead;
  139. NEW(p, filenameEdit.text); p.SetPosition(0);
  140. NEW(dropTarget, filenameEdit.text, p);
  141. filenameEdit.text.ReleaseRead;
  142. IF ~filenameEdit.tv.hasFocus & ~filenameEdit.tv.alwaysShowCursor.Get() THEN filenameEdit.tv.cursor.SetVisible(FALSE) END;
  143. dragInfo.data := dropTarget;
  144. ConfirmDrag(TRUE, dragInfo);
  145. handled := TRUE;
  146. END FileNameEditDragDropped;
  147. PROCEDURE FillLines(nofRows, nofLines: LONGINT);
  148. VAR i: LONGINT;
  149. BEGIN
  150. grid.model.Acquire;
  151. FOR i := nofRows TO nofLines DO
  152. lineNbr.model.InsertEmptyRow(i);
  153. grid.model.InsertEmptyRow(i);
  154. END;
  155. grid.model.Release;
  156. END FillLines;
  157. PROCEDURE InsertLine (pos, line: LONGINT; string: Strings.String; out : Streams.Writer);
  158. VAR intStr: ARRAY 32 OF CHAR; nofRows: LONGINT; diffState : DiffState; lineWidth, dy: LONGINT;
  159. BEGIN
  160. font.GetStringSize(string^, lineWidth, dy); INC(lineWidth,4);
  161. maxLineWidth := MAX(lineWidth, maxLineWidth);
  162. lineNbr.model.Acquire;
  163. grid.model.Acquire;
  164. nofRows := grid.model.GetNofRows();
  165. IF nofRows <= curLine THEN
  166. FillLines(nofRows, curLine)
  167. END;
  168. (* line number *)
  169. Strings.IntToStr(line, intStr);
  170. lineNbr.model.SetCellText(0, curLine, Strings.NewString(intStr));
  171. lineNbr.model.SetTextAlign(0, curLine, WMGraphics.AlignCenter);
  172. lineNbr.model.SetCellColors(0, curLine, LineNbrBgColor, WMGraphics.Black);
  173. grid.model.SetCellText (0, curLine, string);
  174. grid.model.SetCellColors(0, curLine, diffColor, WMGraphics.Black);
  175. NEW(diffState); diffState.state := DiffStateDifferent;
  176. grid.model.SetCellData(0, curLine, diffState);
  177. grid.model.Release;
  178. lineNbr.model.Release;
  179. INC(curLine); INC(diffLines);
  180. END InsertLine;
  181. PROCEDURE InsertEmptyLine;
  182. VAR nofRows: LONGINT;
  183. BEGIN
  184. lineNbr.model.Acquire;
  185. grid.model.Acquire;
  186. nofRows := grid.model.GetNofRows();
  187. IF nofRows <= curLine THEN
  188. FillLines(nofRows, curLine)
  189. END;
  190. lineNbr.model.SetCellText(0, curLine, NIL);
  191. lineNbr.model.SetCellColors(0, curLine, LineNbrBgColor, WMGraphics.Black);
  192. grid.model.SetCellText(0, curLine, NIL);
  193. grid.model.SetCellData(0, curLine, NIL);
  194. grid.model.SetCellColors(0, curLine, EmptyLineColor, WMGraphics.Black);
  195. grid.model.Release;
  196. lineNbr.model.Release;
  197. INC(curLine);
  198. END InsertEmptyLine;
  199. PROCEDURE InsertCommonLine (pos, line: LONGINT; string: Strings.String; out : Streams.Writer);
  200. VAR intStr: ARRAY 32 OF CHAR; nofRows, lineWidth, dy: LONGINT;
  201. BEGIN
  202. font.GetStringSize(string^, lineWidth, dy); INC(lineWidth, 4);
  203. maxLineWidth := MAX(lineWidth, maxLineWidth);
  204. lineNbr.model.Acquire;
  205. grid.model.Acquire;
  206. nofRows := grid.model.GetNofRows();
  207. IF nofRows <= curLine THEN
  208. FillLines(nofRows, curLine)
  209. END;
  210. Strings.IntToStr(line, intStr);
  211. lineNbr.model.SetCellText(0, curLine, Strings.NewString(intStr));
  212. lineNbr.model.SetTextAlign(0, curLine, WMGraphics.AlignCenter);
  213. lineNbr.model.SetCellColors(0, curLine, LineNbrBgColor, WMGraphics.AlignCenter);
  214. grid.model.SetCellText (0, curLine, string);
  215. grid.model.SetCellData(0, curLine, NIL);
  216. grid.model.Release;
  217. lineNbr.model.Release;
  218. INC (commonLines); INC(curLine);
  219. END InsertCommonLine;
  220. PROCEDURE SetFileName(fileName: ARRAY OF CHAR);
  221. BEGIN
  222. filenameEdit.SetAsString(fileName);
  223. END SetFileName;
  224. PROCEDURE GetFileName(): Strings.String;
  225. VAR string, fileName: Files.FileName; count: LONGINT; sr: Streams.StringReader;
  226. BEGIN
  227. filenameEdit.GetAsString(string);
  228. count := UTF8Strings.UTF8toASCII(string, " ", fileName);
  229. (* parse filename *)
  230. NEW(sr, LEN(fileName)); sr.Set(fileName);
  231. sr.SkipWhitespace; sr.String(fileName);
  232. RETURN Strings.NewString(fileName);
  233. END GetFileName;
  234. PROCEDURE Setup;
  235. BEGIN
  236. filenameEdit.tv.defaultTextColor.Set(WMGraphics.Black);
  237. maxLineWidth := minLineWidth; commonLines := 0; diffLines := 0; curLine := 0;
  238. SetNofLines(1);
  239. END Setup;
  240. PROCEDURE Update;
  241. BEGIN
  242. IF diffLines > 0 THEN
  243. filenameEdit.tv.defaultTextColor.Set(DarkRed);
  244. ELSE
  245. filenameEdit.tv.defaultTextColor.Set(DarkGreen);
  246. END;
  247. colWidths[0] := maxLineWidth;
  248. grid.SetColSpacings(colWidths);
  249. grid.bounds.SetWidth(maxLineWidth);
  250. SetNofLines(curLine);
  251. Invalidate;
  252. END Update;
  253. PROCEDURE Resized*;
  254. BEGIN
  255. Resized^;
  256. onResized.Call(NIL);
  257. END Resized;
  258. END DiffView;
  259. TYPE
  260. Overview= OBJECT(WMComponents.VisualComponent)
  261. VAR
  262. view: DiffView;
  263. img: WMGraphics.Image;
  264. nofRows, pageStart, pageSize: LONGINT;
  265. showPage: BOOLEAN;
  266. diffColor : LONGINT;
  267. PROCEDURE &New*(view: DiffView);
  268. BEGIN
  269. Init;
  270. SetNameAsString(StrOverview);
  271. SELF.view:= view;
  272. END New;
  273. PROCEDURE SetPage(pageStart, pageSize: LONGINT);
  274. VAR barHeight: LONGINT;
  275. BEGIN
  276. IF nofRows < 1 THEN RETURN; END;
  277. showPage := TRUE;
  278. barHeight := bounds.GetHeight()- 2*ScrollbarWidth;
  279. pageStart := barHeight * pageStart DIV nofRows;
  280. pageSize := pageSize * barHeight DIV nofRows;
  281. SELF.pageStart := MAX(pageStart, 0);
  282. SELF.pageSize := MIN(barHeight-pageStart, MAX(pageSize, 1));
  283. Invalidate;
  284. END SetPage;
  285. PROCEDURE Resized*;
  286. VAR rect: WMRectangles.Rectangle;
  287. BEGIN
  288. Resized^;
  289. NEW(img);
  290. rect := GetClientRect();
  291. INC(rect.t, ScrollbarWidth); DEC(rect.b, ScrollbarWidth);
  292. IF ~WMRectangles.RectEmpty(rect) THEN
  293. Raster.Create(img, rect.r-rect.l, rect.b-rect.t, Raster.BGR565);
  294. Update;
  295. END;
  296. END Resized;
  297. PROCEDURE Setup;
  298. VAR c: WMGraphics.BufferCanvas; rect: WMRectangles.Rectangle;
  299. BEGIN
  300. IF img # NIL THEN
  301. NEW(c,img);
  302. rect := WMRectangles.MakeRect(0,0,img.width, img.height);
  303. c.Fill(rect, LONGINT(0808080FFH), WMGraphics.ModeCopy);
  304. Invalidate;
  305. END;
  306. END Setup;
  307. PROCEDURE Update;
  308. VAR pos: LONGINT; fact: REAL; c: WMGraphics.BufferCanvas;
  309. rect : WMRectangles.Rectangle;
  310. i: LONGINT;
  311. data:ANY;
  312. prev: BOOLEAN;
  313. BEGIN
  314. IF img = NIL THEN
  315. NEW(img);
  316. Raster.Create(img, bounds.GetWidth(), bounds.GetHeight()- 2* ScrollbarWidth, Raster.BGR565);
  317. END;
  318. NEW(c,img);
  319. rect := WMRectangles.MakeRect(0, 0,img.width, img.height);
  320. c.Fill(rect, LONGINT(0808080FFH), WMGraphics.ModeCopy);
  321. view.grid.model.Acquire;
  322. nofRows:= view.grid.model.GetNofRows();
  323. IF nofRows > 0 THEN
  324. fact := img.height / nofRows;
  325. WMRectangles.SetRect(rect, 0, 0, img.width, 1);
  326. (* draw different lines in left View *)
  327. prev := FALSE;
  328. FOR i := 1 TO nofRows-1 DO
  329. data := view.grid.model.GetCellData(0, i);
  330. IF data # NIL THEN
  331. pos := ENTIER(fact * i + 0.5);
  332. IF ~prev THEN rect.t := pos; rect.b := pos + 1; prev := TRUE
  333. ELSE
  334. rect.b := MAX(rect.b, pos+1);
  335. END;
  336. ELSE
  337. IF prev THEN
  338. c.Fill(rect, diffColor, WMGraphics.ModeCopy);
  339. prev := FALSE;
  340. END;
  341. END;
  342. END;
  343. IF prev THEN
  344. c.Fill(rect, diffColor, WMGraphics.ModeCopy);
  345. prev := FALSE;
  346. END;
  347. END;
  348. view.grid.model.Release;
  349. Invalidate;
  350. END Update;
  351. (** Is called before any sub-components are drawn *)
  352. PROCEDURE DrawBackground*(canvas : WMGraphics.Canvas);
  353. VAR rect: WMRectangles.Rectangle; (* x0, x1: LONGINT; *)
  354. BEGIN
  355. rect := GetClientRect();
  356. canvas.Fill(rect, LONGINT(0CCCCCCFFH), WMGraphics.ModeCopy);
  357. IF img # NIL THEN
  358. canvas.DrawImage(0,ScrollbarWidth,img, WMGraphics.ModeCopy);
  359. IF showPage THEN
  360. canvas.Fill(WMRectangles.MakeRect(rect.l, pageStart + ScrollbarWidth, rect.r, pageStart + pageSize + ScrollbarWidth), 040H, WMGraphics.ModeSrcOverDst);
  361. END
  362. END;
  363. END DrawBackground;
  364. END Overview;
  365. TYPE
  366. KillerMsg = OBJECT
  367. END KillerMsg;
  368. Window = OBJECT (WMComponents.FormWindow)
  369. VAR
  370. leftView, rightView: DiffView;
  371. lblcommonLines, lbldiffLinesLeft, lbldiffLinesRight : WMStandardComponents.Label;
  372. scrolly : WMStandardComponents.Scrollbar;
  373. leftOverview, rightOverview: Overview;
  374. pageSize: LONGINT;
  375. PROCEDURE &New *(c : WMRestorable.Context);
  376. VAR vc : WMComponents.VisualComponent;
  377. BEGIN
  378. vc := CreateForm();
  379. Init (vc.bounds.GetWidth(), vc.bounds.GetHeight(), FALSE);
  380. SetContent (vc);
  381. SetTitle (WM.NewString("Diff"));
  382. IF c # NIL THEN
  383. WMRestorable.AddByContext(SELF, c);
  384. ELSE
  385. WM.DefaultAddWindow(SELF);
  386. END;
  387. IncCount;
  388. END New;
  389. PROCEDURE CreateForm(): WMComponents.VisualComponent;
  390. VAR
  391. label: WMStandardComponents.Label;
  392. panel, status, middlePanel, scrollPanel: WMStandardComponents.Panel;
  393. diffBtn: WMStandardComponents.Button;
  394. BEGIN
  395. NEW(panel);
  396. panel.bounds.SetExtents (Width, Height); panel.alignment.Set(WMComponents.AlignClient);
  397. panel.fillColor.Set (WMGraphics.White);
  398. NEW(status); status.alignment.Set(WMComponents.AlignBottom); status.bounds.SetHeight(20);
  399. panel.AddContent(status); status.fillColor.Set(BgColor);
  400. NEW(label); label.bounds.SetWidth(100); label.caption.SetAOC("Common Lines: "); label.alignment.Set(WMComponents.AlignLeft);
  401. status.AddContent(label);
  402. NEW(lblcommonLines); lblcommonLines.bounds.SetWidth(100); lblcommonLines.caption.SetAOC("-");
  403. lblcommonLines.alignment.Set(WMComponents.AlignLeft);
  404. status.AddContent(lblcommonLines);
  405. NEW(label); label.bounds.SetWidth(150); label.caption.SetAOC("Different Lines Left File: ");
  406. label.alignment.Set(WMComponents.AlignLeft);
  407. status.AddContent(label);
  408. NEW(lbldiffLinesLeft); lbldiffLinesLeft.bounds.SetWidth(100); lbldiffLinesLeft.caption.SetAOC("-");
  409. lbldiffLinesLeft.alignment.Set(WMComponents.AlignLeft);
  410. status.AddContent(lbldiffLinesLeft);
  411. NEW(label); label.bounds.SetWidth(150); label.caption.SetAOC("Different Lines Right File: ");
  412. label.alignment.Set(WMComponents.AlignLeft);
  413. status.AddContent(label);
  414. NEW(lbldiffLinesRight); lbldiffLinesRight.bounds.SetWidth(100); lbldiffLinesRight.caption.SetAOC("-");
  415. lbldiffLinesRight.alignment.Set(WMComponents.AlignLeft);
  416. status.AddContent(lbldiffLinesRight);
  417. NEW(leftView);
  418. leftView.bounds.SetWidth ((Width - 2*OverviewWidth - ScrollbarWidth) DIV 2);
  419. leftView.alignment.Set(WMComponents.AlignLeft);
  420. leftView.onPropertyChange.Add(OnViewPropertyChange);
  421. leftView.onResized.Add(OnViewResized);
  422. leftView.diffColor := DiffColorLeft;
  423. panel.AddContent (leftView);
  424. NEW(rightView);
  425. rightView.bounds.SetWidth ((Width - 2*OverviewWidth - ScrollbarWidth) DIV 2);
  426. rightView.alignment.Set(WMComponents.AlignLeft);
  427. rightView.diffColor := DiffColorRight;
  428. rightView.onPropertyChange.Add(OnViewPropertyChange);
  429. rightView.onResized.Add(OnViewResized);
  430. leftView.filenameEdit.onEnter.Add(DiffHandler);
  431. rightView.filenameEdit.onEnter.Add(DiffHandler);
  432. NEW(middlePanel);
  433. middlePanel.bounds.SetWidth (2*OverviewWidth + ScrollbarWidth); middlePanel.alignment.Set(WMComponents.AlignLeft);
  434. middlePanel.fillColor.Set (LONGINT(0FFFFFFFFH));
  435. NEW(diffBtn); diffBtn.caption.SetAOC("Diff"); diffBtn.alignment.Set(WMComponents.AlignTop);
  436. diffBtn.onClick.Add(DiffHandler);
  437. diffBtn.bounds.SetHeight(20);
  438. middlePanel.AddContent(diffBtn);
  439. NEW(scrollPanel); scrollPanel.alignment.Set(WMComponents.AlignClient);
  440. scrollPanel.fillColor.Set (LONGINT(0FFFFFFFFH));
  441. NEW(leftOverview, leftView);
  442. leftOverview.bounds.SetWidth(OverviewWidth); leftOverview.alignment.Set(WMComponents.AlignLeft);
  443. leftOverview.diffColor := WMGraphics.Red;
  444. scrollPanel.AddContent(leftOverview);
  445. NEW(scrolly);
  446. scrolly.bounds.SetWidth(ScrollbarWidth); scrolly.alignment.Set(WMComponents.AlignLeft);
  447. scrolly.vertical.Set(TRUE);
  448. scrolly.onPositionChanged.Add(SELF.Scrolled);
  449. scrollPanel.AddContent(scrolly);
  450. NEW(rightOverview, rightView);
  451. rightOverview.bounds.SetWidth(OverviewWidth); rightOverview.alignment.Set(WMComponents.AlignLeft);
  452. rightOverview.diffColor := WMGraphics.Blue;
  453. scrollPanel.AddContent(rightOverview);
  454. middlePanel.AddContent(scrollPanel);
  455. panel.AddContent(middlePanel);
  456. panel.AddContent (rightView);
  457. RETURN panel
  458. END CreateForm;
  459. PROCEDURE Close*;
  460. BEGIN
  461. Close^;
  462. DecCount;
  463. END Close;
  464. PROCEDURE Load*(leftFilename, rightFilename : ARRAY OF CHAR);
  465. BEGIN
  466. leftView.SetFileName(leftFilename);
  467. rightView.SetFileName(rightFilename);
  468. IF (leftFilename # "") OR (rightFilename # "") THEN DiffHandler(NIL, NIL) END;
  469. Resized(Width, Height);
  470. END Load;
  471. PROCEDURE Resized*(width, height : LONGINT);
  472. VAR viewWidth: LONGINT;
  473. BEGIN
  474. Resized^(width, height);
  475. viewWidth := (width - 2*OverviewWidth - ScrollbarWidth) DIV 2;
  476. leftView.bounds.SetWidth(viewWidth);
  477. rightView.bounds.SetWidth(viewWidth);
  478. END Resized;
  479. PROCEDURE OnViewResized(sender, par: ANY);
  480. BEGIN
  481. SetScrollbarProperties;
  482. Scrolled(NIL, NIL)
  483. END OnViewResized;
  484. PROCEDURE Setup(nofLines: LONGINT);
  485. BEGIN
  486. leftView.SetNofLines(nofLines + 1);
  487. rightView.SetNofLines(nofLines + 1);
  488. END Setup;
  489. PROCEDURE SetScrollbarProperties;
  490. BEGIN
  491. pageSize := leftView.grid.bounds.GetHeight() DIV leftView.grid.defaultRowHeight.Get();
  492. scrolly.pageSize.Set(pageSize);
  493. scrolly.min.Set(0); scrolly.max.Set(MAX(leftView.curLine, rightView.curLine) - pageSize);
  494. END SetScrollbarProperties;
  495. PROCEDURE Update;
  496. VAR intStr: ARRAY 32 OF CHAR;
  497. BEGIN
  498. leftView.Update;
  499. rightView.Update;
  500. Strings.IntToStr(leftView.commonLines, intStr);
  501. lblcommonLines.caption.SetAOC(intStr);
  502. Strings.IntToStr(rightView.diffLines, intStr);
  503. IF rightView.diffLines > 0 THEN
  504. lbldiffLinesRight.textColor.Set(DarkRed);
  505. ELSE
  506. lbldiffLinesRight.textColor.Set(DarkGreen);
  507. END;
  508. lbldiffLinesRight.caption.SetAOC(intStr);
  509. IF leftView.diffLines > 0 THEN
  510. lbldiffLinesLeft.textColor.Set(DarkRed);
  511. ELSE
  512. lbldiffLinesLeft.textColor.Set(DarkGreen);
  513. END;
  514. Strings.IntToStr(leftView.diffLines, intStr);
  515. lbldiffLinesLeft.caption.SetAOC(intStr);
  516. leftOverview.Update;
  517. rightOverview.Update;
  518. SetScrollbarProperties;
  519. Scrolled(NIL, NIL);
  520. END Update;
  521. PROCEDURE DiffHandler(sender, par: ANY);
  522. VAR leftFile, rightFile: Strings.String;
  523. BEGIN
  524. lbldiffLinesLeft.textColor.Set(WMGraphics.Black); lbldiffLinesLeft.caption.SetAOC("-");
  525. lbldiffLinesRight.textColor.Set(WMGraphics.Black); lblcommonLines.caption.SetAOC("-");
  526. lbldiffLinesRight.caption.SetAOC("-");
  527. leftView.Setup; leftOverview.Setup;
  528. rightView.Setup; rightOverview.Setup;
  529. leftFile := leftView.GetFileName();
  530. rightFile := rightView.GetFileName();
  531. DisableUpdate;
  532. DiffLib.Diff (leftFile^, rightFile^, Setup, leftView.InsertLine, rightView.InsertLine, leftView.InsertCommonLine, rightView.InsertCommonLine, leftView.InsertEmptyLine, rightView.InsertEmptyLine, NIL);
  533. EnableUpdate;
  534. Update;
  535. END DiffHandler;
  536. PROCEDURE OnViewPropertyChange(sender, par: ANY);
  537. VAR ymax: LONGINT;
  538. BEGIN
  539. ymax := sender(DiffView).grid.nofRows.Get();
  540. scrolly.max.Set(ymax);
  541. END OnViewPropertyChange;
  542. PROCEDURE Scrolled(sender, data : ANY);
  543. VAR col, coll, row, rowl : LONGINT;
  544. BEGIN
  545. rightView.lineNbr.GetTopPosition(coll, rowl);
  546. rightView.grid.GetTopPosition(col, row);
  547. rightView.lineNbr.SetTopPosition(coll, scrolly.pos.Get(), FALSE);
  548. rightView.grid.SetTopPosition(col, scrolly.pos.Get(), FALSE);
  549. leftView.lineNbr.GetTopPosition(coll, rowl);
  550. leftView.grid.GetTopPosition(col, row);
  551. leftView.lineNbr.SetTopPosition(coll, scrolly.pos.Get(), FALSE);
  552. leftView.grid.SetTopPosition(col, scrolly.pos.Get(), FALSE);
  553. leftOverview.SetPage(scrolly.pos.Get(), pageSize);
  554. rightOverview.SetPage(scrolly.pos.Get(), pageSize);
  555. END Scrolled;
  556. PROCEDURE HandleKey(ucs : LONGINT; flags : SET; keysym : LONGINT) : BOOLEAN;
  557. VAR handled : BOOLEAN;
  558. BEGIN
  559. handled := TRUE;
  560. IF (ucs = 0A2H) THEN (* PgUp *)
  561. scrolly.PageUp(NIL, NIL);
  562. ELSIF (ucs = 0A3H) THEN (* PgDn *)
  563. scrolly.PageDown(NIL, NIL);
  564. ELSIF (ucs = 0A8H) THEN (* Home *)
  565. scrolly.pos.Set(scrolly.min.Get()); Scrolled(NIL, NIL);
  566. ELSIF (ucs = 0A9H) THEN (* End *)
  567. scrolly.pos.Set(scrolly.max.Get()); Scrolled(NIL, NIL);
  568. ELSIF (ucs = 0A0H) THEN (* Insert *)
  569. leftView.ToggleLineNumbers;
  570. rightView.ToggleLineNumbers;
  571. ELSIF (ucs = 0C1H) THEN (* Cursor Up *)
  572. scrolly.DecPos(NIL, NIL);
  573. ELSIF (ucs = 0C2H) THEN (* Cursor Down *)
  574. scrolly.IncPos(NIL, NIL);
  575. ELSE
  576. handled := FALSE;
  577. END;
  578. RETURN handled;
  579. END HandleKey;
  580. PROCEDURE Handle*(VAR m: WMMessages.Message);
  581. BEGIN
  582. IF (m.msgType = WMMessages.MsgKey) THEN
  583. IF ~HandleKey(m.x, m.flags, m.y) THEN
  584. Handle^(m);
  585. END;
  586. ELSIF (m.msgType = WMMessages.MsgExt) & (m.ext # NIL) THEN
  587. IF (m.ext IS KillerMsg) THEN Close
  588. ELSE Handle^(m)
  589. END
  590. ELSE Handle^(m)
  591. END
  592. END Handle;
  593. PROCEDURE WheelMove*(dz : LONGINT);
  594. VAR pos : LONGINT;
  595. BEGIN
  596. pos := scrolly.pos.Get() + MouseWheelMultiplier * dz;
  597. IF pos < scrolly.min.Get() THEN pos := scrolly.min.Get(); END;
  598. IF pos > scrolly.max.Get() THEN pos := scrolly.max.Get(); END;
  599. scrolly.pos.Set(pos);
  600. scrolly.onPositionChanged.Call(scrolly.pos)
  601. END WheelMove;
  602. END Window;
  603. VAR
  604. nofWindows : LONGINT;
  605. StrDiffView, StrOverview, StrNoWheelGrid : Strings.String;
  606. PROCEDURE InitStrings;
  607. BEGIN
  608. StrDiffView := Strings.NewString("DiffView");
  609. StrOverview := Strings.NewString("Overview");
  610. StrNoWheelGrid := Strings.NewString("NoWheelGrid");
  611. END InitStrings;
  612. PROCEDURE Open* (context : Commands.Context); (** [filename1 filename2] ~ *)
  613. VAR left, right : ARRAY 64 OF CHAR; window: Window;
  614. BEGIN
  615. context.arg.SkipWhitespace; context.arg.String(left);
  616. context.arg.SkipWhitespace; context.arg.String(right);
  617. NEW(window, NIL); window.Load(left, right);
  618. END Open;
  619. PROCEDURE IncCount;
  620. BEGIN {EXCLUSIVE}
  621. INC(nofWindows);
  622. END IncCount;
  623. PROCEDURE DecCount;
  624. BEGIN {EXCLUSIVE}
  625. DEC(nofWindows);
  626. END DecCount;
  627. PROCEDURE Cleanup;
  628. VAR die : KillerMsg;
  629. msg : WMMessages.Message;
  630. m : WM.WindowManager;
  631. BEGIN {EXCLUSIVE}
  632. NEW(die); msg.ext := die; msg.msgType := WMMessages.MsgExt;
  633. m := WM.GetDefaultManager();
  634. m.Broadcast(msg);
  635. AWAIT(nofWindows = 0);
  636. END Cleanup;
  637. BEGIN
  638. Modules.InstallTermHandler(Cleanup);
  639. InitStrings;
  640. END WMDiff.
  641. PC.Compile \s DiffLib.Mod XStandardComponents.Mod WMDiff.Mod~
  642. System.Free WMDiff DiffLib~
  643. Problem: When the overview bar is drawn, it is scaled for speedup. This may lead to the disappearance of marking for line differences.
  644. Therefore documents with different lines are marked additionally by a red filename.
  645. WMDiff.Open ~
  646. WMDiff.Open UsbEhci.Mod UsbEhci.Mod ~
  647. WMDiff.Open AosSetup.Text AosSetup.Text ~
  648. WMDiff.Open WMPerfMon.Mod WMPerfMon.Mod.Bak ~
  649. WMDiff.Open WMDiff.Mod WMDiff.Mod.Bak ~