Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Renamed AppSettings.pas to UAppSettings.pas so the global var can be named AppSettings. Added L_StoreFormPos, and made frmCommit a TRestorableForm, so it automatically remembers its position. History diffs now also support viewing with external diff tool. The diff viewer can now display exceptions via the SetException method. Made GetTempFilename more robust; if no filename was specified, it will generate a random filename; if one is specified, any invalid characters will be replaced by underscores. |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d118e46707ea9ccff39da54f866978fd |
User & Date: | MCO 2011-09-22 12:34:03.693 |
Context
2011-09-22
| ||
20:59 | Adjusted L_StoreFormPos so it compiles with Delphi XE2. Added GetUpdates method to TFossil, to retrieve list of pending updates. Added property RemoteURL to TFossil. RefreshFiles now also checks for pending updates, as per ticket [27fb0b4408]. check-in: d129f6bbb4 user: Martijn tags: trunk | |
12:34 | Renamed AppSettings.pas to UAppSettings.pas so the global var can be named AppSettings. Added L_StoreFormPos, and made frmCommit a TRestorableForm, so it automatically remembers its position. History diffs now also support viewing with external diff tool. The diff viewer can now display exceptions via the SetException method. Made GetTempFilename more robust; if no filename was specified, it will generate a random filename; if one is specified, any invalid characters will be replaced by underscores. check-in: d118e46707 user: MCO tags: trunk | |
2011-09-21
| ||
20:23 | Added separate project for Delphi XE2 check-in: d7787cc81b user: Martijn tags: trunk | |
Changes
Changes to src/FCommit.dfm.
︙ | ︙ | |||
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | item Header = 'Versioned files' GroupID = 0 State = [lgsNormal, lgsNoHeader] HeaderAlign = taLeftJustify FooterAlign = taLeftJustify TitleImage = -1 end item Header = 'Unversioned files' GroupID = 1 State = [lgsCollapsible] HeaderAlign = taLeftJustify FooterAlign = taLeftJustify TitleImage = -1 end> HideSelection = False MultiSelect = True GroupHeaderImages = imlFiles GroupView = True ReadOnly = True RowSelect = True | > > | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | item Header = 'Versioned files' GroupID = 0 State = [lgsNormal, lgsNoHeader] HeaderAlign = taLeftJustify FooterAlign = taLeftJustify TitleImage = -1 ExtendedImage = -1 end item Header = 'Unversioned files' GroupID = 1 State = [lgsCollapsible] HeaderAlign = taLeftJustify FooterAlign = taLeftJustify TitleImage = -1 ExtendedImage = -1 end> HideSelection = False MultiSelect = True GroupHeaderImages = imlFiles GroupView = True ReadOnly = True RowSelect = True |
︙ | ︙ | |||
208 209 210 211 212 213 214 215 216 217 218 219 220 221 | Height = 343 ActivePage = tsDiff Align = alClient TabOrder = 0 Visible = False object tsContents: TTabSheet Caption = 'Contents' end object tsDiff: TTabSheet Caption = 'Diff' ImageIndex = 1 OnShow = tsDiffShow end object tshHistory: TTabSheet | > > > > | 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | Height = 343 ActivePage = tsDiff Align = alClient TabOrder = 0 Visible = False object tsContents: TTabSheet Caption = 'Contents' ExplicitLeft = 0 ExplicitTop = 0 ExplicitWidth = 0 ExplicitHeight = 0 end object tsDiff: TTabSheet Caption = 'Diff' ImageIndex = 1 OnShow = tsDiffShow end object tshHistory: TTabSheet |
︙ | ︙ | |||
354 355 356 357 358 359 360 | end end object imlFiles: TImageList ColorDepth = cd32Bit Left = 24 Top = 256 Bitmap = { | | | 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | end end object imlFiles: TImageList ColorDepth = cd32Bit Left = 24 Top = 256 Bitmap = { 494C0101080028008C0010001000FFFFFFFF2110FFFFFFFFFFFFFFFF424D3600 0000000000003600000028000000400000003000000001002000000000000030 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 |
︙ | ︙ |
Changes to src/FCommit.pas.
1 2 3 4 5 6 | unit FCommit; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, | | > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | unit FCommit; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls, ImgList, Buttons, L_StoreFormPos, u_fossil, fviewcontents, fviewdiff; type TfrmCommit = class(TRestorableForm) pnlLeft: TPanel; pnlRight: TPanel; splLeftRight: TSplitter; pnlTop: TPanel; pnlBottom: TPanel; splTopBottom: TSplitter; lvwFiles: TListView; |
︙ | ︙ | |||
81 82 83 84 85 86 87 | implementation uses Math, FileCtrl, RichEdit, DateUtils, StrUtils, IOUtils, PNGImage, JPEG, GIFImg, RegExpr, L_SysParamInfo, FileIcon, Process, L_FileUtils, | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | implementation uses Math, FileCtrl, RichEdit, DateUtils, StrUtils, IOUtils, PNGImage, JPEG, GIFImg, RegExpr, L_SysParamInfo, FileIcon, Process, L_FileUtils, UAppSettings; {$R *.dfm} type TLauncherCleaner = class(TThread) private FProcess: TProcess; |
︙ | ︙ | |||
121 122 123 124 125 126 127 128 129 130 | FDiffViewer.Parent := tsDiff; FDiffViewer.OnExternalDiff := DiffExternal; FHistoryViewer := TfrmViewContents.Create(Self); FHistoryViewer.Parent := tshHistory; FHistoryDiff := TfrmViewDiff.Create(Self); FHistoryDiff.Parent := tshHistory; FHistoryDiff.Visible := False; lvwHistory.Clear; lvwHistory.Tag := lvwHistory.Height; | > | | | | | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | FDiffViewer.Parent := tsDiff; FDiffViewer.OnExternalDiff := DiffExternal; FHistoryViewer := TfrmViewContents.Create(Self); FHistoryViewer.Parent := tshHistory; FHistoryDiff := TfrmViewDiff.Create(Self); FHistoryDiff.Parent := tshHistory; FHistoryDiff.OnExternalDiff := DiffExternal; FHistoryDiff.Visible := False; lvwHistory.Clear; lvwHistory.Tag := lvwHistory.Height; btnViewFileRevision.Down := AppSettings.ShowHistoryContents; if AppSettings.FossilExePath = '' then FossilExePath := ChangeFilePath('fossil.exe', ExtractFilePath(GetDllOrExePath)); // TODO: get the target path from somewhere else CheckoutPath := ParamStr(1); if not DirectoryExists(CheckoutPath) then begin CheckoutPath := AppSettings.LastCheckoutFolder; if not SelectDirectory('Select the code path', '', CheckoutPath, [sdNewUI, sdShowEdit, sdValidateDir]) then begin PostMessage(Self.Handle, WM_CLOSE, 0, 0); Exit; end; end; AppSettings.LastCheckoutFolder := CheckoutPath; FFossil := TFossil.Create(FossilExePath, CheckoutPath); Self.Caption := 'Commit changes in ' + FFossil.RootDir; RefreshFiles; end; { ------------------------------------------------------------------------------------------------ } procedure TfrmCommit.FormDestroy(Sender: TObject); |
︙ | ︙ | |||
276 277 278 279 280 281 282 | procedure TfrmCommit.btnViewFileRevisionClick(Sender: TObject); begin if Assigned(lvwHistory.Selected) then begin lvwHistorySelectItem(lvwHistory, lvwHistory.Selected, lvwHistory.Selected.Selected); end else begin lvwHistorySelectItem(lvwHistory, lvwHistory.Selected, True); end; | | > > | > < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | procedure TfrmCommit.btnViewFileRevisionClick(Sender: TObject); begin if Assigned(lvwHistory.Selected) then begin lvwHistorySelectItem(lvwHistory, lvwHistory.Selected, lvwHistory.Selected.Selected); end else begin lvwHistorySelectItem(lvwHistory, lvwHistory.Selected, True); end; AppSettings.ShowHistoryContents := btnViewFileRevision.Down; end {TfrmCommit.btnViewFileRevisionClick}; { ------------------------------------------------------------------------------------------------ } procedure TfrmCommit.chkBranchClick(Sender: TObject); begin EnableControls; end {TfrmCommit.chkBranchClick}; { ------------------------------------------------------------------------------------------------ } procedure TfrmCommit.chkExtrasClick(Sender: TObject); begin RefreshFiles; end {TfrmCommit.chkExtrasClick}; { ------------------------------------------------------------------------------------------------ } procedure TfrmCommit.DiffExternal(Sender: TObject); var TempFiles: TStringList; OldFile, NewFile, DiffCommand: TFileName; SS: TStringStream; FS: TFileStream; Contents: string; P: TProcess; i: Integer; Item: TListItem; OlderArtifact, NewerArtifact: string; begin OldFile := ''; NewFile := ''; TempFiles := TStringList.Create; try if (Sender = FDiffViewer) then begin NewFile := FFossil.RootDir + lvwFiles.Selected.Caption; // create temp file name OldFile := GetTempFilename(ChangeFileExt(NewFile, '~' + ExtractFileExt(NewFile))); // Fetch the contents of the latest checked-in revision Contents := FFossil.Run('finfo --print "' + NewFile + '"'); Contents := StringReplace(Contents, #13#13#10, #13#10, [rfReplaceAll]); SS := TStringStream.Create(Contents, 0); try FS := TFileStream.Create(OldFile, fmCreate); try FS.CopyFrom(SS, SS.Size); finally FS.Free; TempFiles.Add(OldFile); end; TFile.SetAttributes(OldFile, [IOUtils.TFileAttribute.faReadOnly, IOUtils.TFileAttribute.faTemporary]); finally SS.Free; end; end else if (Sender = FHistoryDiff) then begin // Find out the first and last selected revisions; // then show a diff of those two revisions OlderArtifact := ''; NewerArtifact := ''; for i := 0 to lvwHistory.Items.Count - 1 do begin Item := lvwHistory.Items[i]; if Item.Selected then begin if NewerArtifact = '' then begin NewerArtifact := Item.Subitems[3]; NewFile := lvwFiles.Selected.Caption; NewFile := ChangeFileExt(NewFile, '-' + Item.SubItems[0] + '-' + Item.Caption + ExtractFileExt(NewFile)); end else begin OlderArtifact := Item.Subitems[3]; OldFile := lvwFiles.Selected.Caption; OldFile := ChangeFileExt(OldFile, '-' + Item.SubItems[0] + '-' + Item.Caption + ExtractFileExt(OldFile)); end; end; end; if (OlderArtifact <> '') and (NewerArtifact <> '') then begin // Fetch the contents of the older revision OldFile := GetTempFilename(OldFile); FFossil.Run('artifact ' + OlderArtifact + ' "' + OldFile + '"'); TempFiles.Add(OldFile); // Fetch the contents of the Newer revision NewFile := GetTempFilename(NewFile); FFossil.Run('artifact ' + NewerArtifact + ' "' + NewFile + '"'); TempFiles.Add(NewFile); end else begin OldFile := ''; NewFile := ''; end; end; // Go compare the two files if FileExists(NewFile) and FileExists(OldFile) then begin for i := 0 to TempFiles.Count - 1 do begin TFile.SetAttributes(TempFiles[i], [IOUtils.TFileAttribute.faReadOnly, IOUtils.TFileAttribute.faTemporary]); end; // TODO: if no external diff viewer is defined, use 'gdiff' DiffCommand := FFossil.Settings.Values['gdiff-command']; if not FileExists(DiffCommand) then begin // TODO: ask for executable MessageBeep(MB_ICONWARNING); TLauncherCleaner.Create(nil, TempFiles); Exit; end; // Launch external diff viewer P := TProcess.Create(nil); try P.CurrentDirectory := FFossil.CurrentDir; |
︙ | ︙ | |||
747 748 749 750 751 752 753 | if not tsDiff.TabVisible then Exit; if Length(FDiffViewer.rteDiff.Text) > 0 then Exit; if not Assigned(lvwFiles.Selected) then Exit; | > | | | | > > > > > | 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 | if not tsDiff.TabVisible then Exit; if Length(FDiffViewer.rteDiff.Text) > 0 then Exit; if not Assigned(lvwFiles.Selected) then Exit; try Output := FFossil.Run('diff -i -N "' + FFossil.RootDir + lvwFiles.Selected.Caption + '"'); Output := StringReplace(Output, #13#13#10, #13#10, [rfReplaceAll]); // Apply highlighting to the output FDiffViewer.SetContents(Output); except on E: Exception do begin FDiffViewer.SetException(E); end; end; end {TfrmCommit.tsDiffShow}; { ------------------------------------------------------------------------------------------------ } procedure TfrmCommit.tshHistoryShow(Sender: TObject); var rxHistory: TRegExpr; i: Integer; |
︙ | ︙ | |||
852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 | lvwHistory.Items.EndUpdate; end; end {TfrmCommit.tshHistoryShow}; { TLauncherCleaner } constructor TLauncherCleaner.Create(const Process: TProcess; const TempFiles: TStrings = nil); begin FreeOnTerminate := True; FTempFiles := TStringList.Create; FTempFiles.Assign(TempFiles); FProcess := Process; inherited Create(False); end {TLauncherCleaner.Create}; | > > | > | > | | 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 | lvwHistory.Items.EndUpdate; end; end {TfrmCommit.tshHistoryShow}; { ================================================================================================ } { TLauncherCleaner } { ------------------------------------------------------------------------------------------------ } constructor TLauncherCleaner.Create(const Process: TProcess; const TempFiles: TStrings = nil); begin FreeOnTerminate := True; FTempFiles := TStringList.Create; FTempFiles.Assign(TempFiles); FProcess := Process; inherited Create(False); end {TLauncherCleaner.Create}; { ------------------------------------------------------------------------------------------------ } destructor TLauncherCleaner.Destroy; begin if Assigned(FProcess) then FProcess.Free; FTempFiles.Free; inherited; end {TLauncherCleaner.Destroy}; { ------------------------------------------------------------------------------------------------ } procedure TLauncherCleaner.Execute; var i: Integer; begin // Now wait until either the thread or the process is terminated while Assigned(FProcess) and FProcess.Running and not Self.Terminated do begin Sleep(250); end; // Delete the temporary files for i := 0 to FTempFiles.Count - 1 do begin TFile.SetAttributes(FTempFiles[i], []); TFile.Delete(FTempFiles[i]); end; end {TLauncherCleaner.Execute}; end. |
Name change from src/AppSettings.pas to src/UAppSettings.pas.
|
| | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | unit UAppSettings; //////////////////////////////////////////////////////////////////////////////////////////////////// interface uses L_AppSettings; type TAppSettings = class(TCustomAppSettings) private FLastCheckoutFolder: string; FFossilExePath: string; FShowHistoryContents: boolean; published property FossilExePath: string read FFossilExePath write FFossilExePath; property LastCheckoutFolder: string read FLastCheckoutFolder write FLastCheckoutFolder; property ShowHistoryContents: boolean read FShowHistoryContents write FShowHistoryContents; end; var AppSettings: TAppSettings; //////////////////////////////////////////////////////////////////////////////////////////////////// implementation uses SysUtils, L_FileUtils; { TAppSettings } //////////////////////////////////////////////////////////////////////////////////////////////////// var Filename: string; initialization // TODO: use writeable SpecialFolder specific to current user AND machine Filename := ChangeFileExt(GetDllOrExePath, '.settings'); if FileExists(Filename) then begin AppSettings := TAppSettings.Create(Filename); end else begin AppSettings := TAppSettings.Create; end; finalization AppSettings.SaveToFile(Filename); FreeAndNil(AppSettings); end. |
Changes to src/fviewcontents.dfm.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 object pgcContentTypes: TPageControl Left = 0 Top = 0 Width = 434 Height = 320 ActivePage = tshText Align = alClient Style = tsFlatButtons TabOrder = 0 object tshText: TTabSheet Caption = 'Text' object mmoContents: TMemo AlignWithMargins = True Left = 3 Top = 3 Width = 420 Height = 283 Align = alClient | > > > > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False OnCreate = FormCreate ExplicitWidth = 320 ExplicitHeight = 240 PixelsPerInch = 96 TextHeight = 13 object pgcContentTypes: TPageControl Left = 0 Top = 0 Width = 434 Height = 320 ActivePage = tshText Align = alClient Style = tsFlatButtons TabOrder = 0 object tshText: TTabSheet Caption = 'Text' ExplicitLeft = 0 ExplicitTop = 0 ExplicitWidth = 0 ExplicitHeight = 0 object mmoContents: TMemo AlignWithMargins = True Left = 3 Top = 3 Width = 420 Height = 283 Align = alClient |
︙ | ︙ |
Changes to src/fviewcontents.pas.
︙ | ︙ | |||
100 101 102 103 104 105 106 107 108 109 110 111 112 113 | // Populate the controls mmoContents.Clear; imgContents.Picture := nil; mmoHexContents.Clear; // try reading the content as an image try FContent.Position := 0; // If it’s an existing file, try loading it from its original location if (FContent is TFileStream) then begin if SameText(ExtractFileExt(Filename), ExtractFileExt(TFileStream(FContent).FileName)) then begin imgContents.Picture.LoadFromFile(Filename); | > | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | // Populate the controls mmoContents.Clear; imgContents.Picture := nil; mmoHexContents.Clear; // try reading the content as an image TempFilename := ''; try FContent.Position := 0; // If it’s an existing file, try loading it from its original location if (FContent is TFileStream) then begin if SameText(ExtractFileExt(Filename), ExtractFileExt(TFileStream(FContent).FileName)) then begin imgContents.Picture.LoadFromFile(Filename); |
︙ | ︙ | |||
129 130 131 132 133 134 135 136 137 138 139 140 141 142 | end; tshImage.TabVisible := True; pgcContentTypes.ActivePage := tshImage; except imgContents.Picture := nil; tshImage.TabVisible := False; end; tshText.TabVisible := not tshImage.TabVisible; if tshText.TabVisible then begin mmoContents.Lines.BeginUpdate; try // Read the contents as text FContent.Position := 0; | > > | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | end; tshImage.TabVisible := True; pgcContentTypes.ActivePage := tshImage; except imgContents.Picture := nil; tshImage.TabVisible := False; end; if TempFilename <> '' then DeleteFile(TempFilename); tshText.TabVisible := not tshImage.TabVisible; if tshText.TabVisible then begin mmoContents.Lines.BeginUpdate; try // Read the contents as text FContent.Position := 0; |
︙ | ︙ |
Changes to src/fviewdiff.dfm.
︙ | ︙ | |||
27 28 29 30 31 32 33 | Font.Name = 'Consolas' Font.Style = [] ParentFont = False PlainText = True ReadOnly = True ScrollBars = ssBoth TabOrder = 1 | < < < < < < | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | Font.Name = 'Consolas' Font.Style = [] ParentFont = False PlainText = True ReadOnly = True ScrollBars = ssBoth TabOrder = 1 end object pnlButtons: TPanel Left = 0 Top = 0 Width = 434 Height = 41 Align = alTop BevelOuter = bvLowered TabOrder = 0 Visible = False object btnExternal: TButton Left = 16 Top = 8 Width = 121 Height = 25 Caption = 'E&xternal compare...' TabOrder = 0 |
︙ | ︙ |
Changes to src/fviewdiff.pas.
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 | { Private declarations } FOnExternalDiff: TNotifyEvent; procedure SetOnExternalDiff(const Value: TNotifyEvent); public { Public declarations } procedure SetContents(const DiffText: string); procedure ClearContents; property OnExternalDiff: TNotifyEvent read FOnExternalDiff write SetOnExternalDiff; end; implementation uses | > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | { Private declarations } FOnExternalDiff: TNotifyEvent; procedure SetOnExternalDiff(const Value: TNotifyEvent); public { Public declarations } procedure SetContents(const DiffText: string); procedure ClearContents; procedure SetException(const E: Exception); property OnExternalDiff: TNotifyEvent read FOnExternalDiff write SetOnExternalDiff; end; implementation uses |
︙ | ︙ | |||
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | SR.Free; end; finally rteDiff.Lines.EndUpdate; SS.Free; end; Visible := True; end {TfrmViewDiff.SetContents}; { ------------------------------------------------------------------------------------------------ } procedure TfrmViewDiff.SetOnExternalDiff(const Value: TNotifyEvent); begin FOnExternalDiff := Value; pnlButtons.Visible := Assigned(FOnExternalDiff); end {TfrmViewDiff.SetOnExternalDiff}; { ------------------------------------------------------------------------------------------------ } procedure TfrmViewDiff.btnExternalClick(Sender: TObject); begin if Assigned(FOnExternalDiff) then begin FOnExternalDiff(Self); end; end {TfrmViewDiff.btnExternalClick}; { ------------------------------------------------------------------------------------------------ } procedure TfrmViewDiff.ClearContents; begin rteDiff.Clear; Visible := False; end {TfrmViewDiff.ClearContents}; end. | > > > > > > > > > > > > | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | SR.Free; end; finally rteDiff.Lines.EndUpdate; SS.Free; end; pnlButtons.Visible := Assigned(FOnExternalDiff); Visible := True; end {TfrmViewDiff.SetContents}; { ------------------------------------------------------------------------------------------------ } procedure TfrmViewDiff.SetException(const E: Exception); begin rteDiff.Clear; rteDiff.SelAttributes.Color := clRed; rteDiff.SelText := E.Message; pnlButtons.Visible := False; Visible := True; end {TfrmViewDiff.SetException}; { ------------------------------------------------------------------------------------------------ } procedure TfrmViewDiff.SetOnExternalDiff(const Value: TNotifyEvent); begin FOnExternalDiff := Value; pnlButtons.Visible := Assigned(FOnExternalDiff); end {TfrmViewDiff.SetOnExternalDiff}; { ------------------------------------------------------------------------------------------------ } procedure TfrmViewDiff.btnExternalClick(Sender: TObject); begin if Assigned(FOnExternalDiff) then begin FOnExternalDiff(Self); end; rteDiff.SetFocus; end {TfrmViewDiff.btnExternalClick}; { ------------------------------------------------------------------------------------------------ } procedure TfrmViewDiff.ClearContents; begin rteDiff.Clear; Visible := False; end {TfrmViewDiff.ClearContents}; end. |
Changes to src/lib/L_FileUtils.pas.
1 2 3 4 5 6 7 8 9 10 11 12 | unit L_FileUtils; interface uses SysUtils; function GetExePath: string; function GetDllOrExePath: string; function GetModulePath(const HModule: HINST): string; function GetTempPath(const DllSpecific: Boolean = True): string; function CreateNewFilename(const Filename: TFilename): string; | > | > > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | unit L_FileUtils; //////////////////////////////////////////////////////////////////////////////////////////////////// interface uses SysUtils; function GetExePath: string; function GetDllOrExePath: string; function GetModulePath(const HModule: HINST): string; function GetTempPath(const DllSpecific: Boolean = True): string; function CreateNewFilename(const Filename: TFilename): string; function GetTempFilename(Filename: string = ''; const DllSpecific: Boolean = True): string; //////////////////////////////////////////////////////////////////////////////////////////////////// implementation uses Windows, IOUtils, Types, Classes; { ------------------------------------------------------------------------------------------------ } function GetExePath: string; begin Result := GetModulePath(0); end {GetExePath}; { ------------------------------------------------------------------------------------------------ } function GetDllOrExePath: string; begin Result := GetModulePath(HInstance); end {GetDllOrExePath}; { ------------------------------------------------------------------------------------------------ } function GetModulePath(const HModule: HINST): string; var PBuffer: PChar; BufferSize, RetVal: Cardinal; begin BufferSize := MAX_PATH; repeat |
︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | end else begin RaiseLastOSError; end; until False; end {GetModulePath}; function GetTempPath(const DllSpecific: Boolean = True): string; var HModule: HINST; begin if DllSpecific then begin HModule := HInstance; end else begin HModule := 0; end; Result := TPath.GetFileNameWithoutExtension(GetModulePath(HModule)); Result := TPath.Combine(TPath.GetTempPath, Result); ForceDirectories(Result); Result := IncludeTrailingPathDelimiter(Result); end {GetTempPath}; function CreateNewFilename(const Filename: TFilename): string; var Base, Ext, Seq: string; Sequence, Index: integer; begin Ext := TPath.GetExtension(Filename); Base := Copy(Filename, 1, Length(Filename) - Length(Ext)); | > > | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | end else begin RaiseLastOSError; end; until False; end {GetModulePath}; { ------------------------------------------------------------------------------------------------ } function GetTempPath(const DllSpecific: Boolean = True): string; var HModule: HINST; begin if DllSpecific then begin HModule := HInstance; end else begin HModule := 0; end; Result := TPath.GetFileNameWithoutExtension(GetModulePath(HModule)); Result := TPath.Combine(TPath.GetTempPath, Result); ForceDirectories(Result); Result := IncludeTrailingPathDelimiter(Result); end {GetTempPath}; { ------------------------------------------------------------------------------------------------ } function CreateNewFilename(const Filename: TFilename): string; var Base, Ext, Seq: string; Sequence, Index: integer; begin Ext := TPath.GetExtension(Filename); Base := Copy(Filename, 1, Length(Filename) - Length(Ext)); |
︙ | ︙ | |||
93 94 95 96 97 98 99 | while TFile.Exists(Result) do begin Inc(Sequence); Result := Base + ' (' + IntToStr(Sequence) + ')' + Ext; end; end {CreateNewFilename}; | > | > > > > > > > > > > > > | > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | while TFile.Exists(Result) do begin Inc(Sequence); Result := Base + ' (' + IntToStr(Sequence) + ')' + Ext; end; end {CreateNewFilename}; { ------------------------------------------------------------------------------------------------ } function GetTempFilename(Filename: string = ''; const DllSpecific: Boolean = True): string; var i: Integer; begin Filename := Trim(TPath.GetFileName(Filename)); if Length(Filename) = 0 then begin Filename := TPath.GetRandomFileName; end else begin for i := 1 to Length(Filename) do begin if not TPath.IsValidFileNameChar(Filename[i]) then Filename[i] := '_'; end; end; Result := TPath.Combine(GetTempPath(DllSpecific), Filename); Result := CreateNewFilename(Result); end {GetTempFilename}; { ------------------------------------------------------------------------------------------------ } procedure EmptyDirectory(const Path: string); var Entries: TStringDynArray; i: Integer; begin // Delete all the files Entries := TDirectory.GetFiles(Path, '*', TSearchOption.soAllDirectories); |
︙ | ︙ | |||
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | // Register the directory to be deleted on reboot MoveFileEx(PChar(Entries[i]), nil, MOVEFILE_DELAY_UNTIL_REBOOT); end; end; end {EmptyDirectory}; initialization finalization try EmptyDirectory(GetTempPath(True)); except on E: Exception do begin // Ignore the error OutputDebugString(PChar(E.Message + ' [' + E.ClassName + ']')); end; end; end. | > | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | // Register the directory to be deleted on reboot MoveFileEx(PChar(Entries[i]), nil, MOVEFILE_DELAY_UNTIL_REBOOT); end; end; end {EmptyDirectory}; //////////////////////////////////////////////////////////////////////////////////////////////////// initialization finalization try EmptyDirectory(GetTempPath(True)); except on E: Exception do begin // Ignore the error OutputDebugString(PChar(E.Message + ' [' + E.ClassName + ']')); end; end; end. |
Added src/lib/L_StoreFormPos.pas.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | unit L_StoreFormPos; interface uses Forms; function StoreFormPosition(AForm: TForm; const AInstanceName: string = ''): boolean; function StoreFormPositionShort(AForm: TForm; const AInstanceName: string = ''): boolean; function RestoreFormPosition(AForm: TForm; const AInstanceName: string = ''): boolean; function RestoreFormPositionShort(AForm: TForm; const AInstanceName: string = ''): boolean; function GetFormLongRegistryKey(const AForm: TForm; const AInstanceName: string = ''): string; function GetFormShortRegistryKey(const AForm: TForm; const AInstanceName: string = ''): string; type TRestorableForm = class (TForm) public procedure AfterConstruction; override; procedure BeforeDestruction; override; end; implementation uses Types, Registry, Windows, Math, L_Data; type TFormData = record public Key : String; NormalPosition : TRect; Maximized : Boolean; public function SaveToRegistry: Boolean; function LoadFromRegistry: Boolean; end; function TFormData.LoadFromRegistry: Boolean; var Registry: TRegistry; begin Result := False; Registry := TRegistry.Create; try Registry.RootKey := HKEY_CURRENT_USER; if Registry.OpenKey(Key, False) then begin NormalPosition.Left := Registry.ReadInteger('Left'); NormalPosition.Top := Registry.ReadInteger('Top'); NormalPosition.Right := Registry.ReadInteger('Right'); NormalPosition.Bottom := Registry.ReadInteger('Bottom'); Maximized := Registry.ReadBool('Maximized'); Result := True; end; finally Registry.Free; end; end; function TFormData.SaveToRegistry: Boolean; var Registry: TRegistry; begin Registry := TRegistry.Create; try Registry.RootKey := HKEY_CURRENT_USER; if Registry.OpenKey(Key, True) then begin Registry.WriteInteger('Left', NormalPosition.Left); Registry.WriteInteger('Top', NormalPosition.Top); Registry.WriteInteger('Right', NormalPosition.Right); Registry.WriteInteger('Bottom', NormalPosition.Bottom); Registry.WriteBool('Maximized', Maximized); end; Result := True; finally Registry.Free; end; end; /////////////////////////////////////////////////////////////////////////////// procedure TestFormPos(AForm :TForm); const MIN_PIXELS_VISIBLE = 150; var bValid :Boolean; begin bValid := (AForm.Left + AForm.Width - MIN_PIXELS_VISIBLE) >= (Screen.DesktopRect.Left); bValid := bValid and ((AForm.Left + MIN_PIXELS_VISIBLE) <= (Screen.DesktopRect.Right)); bValid := bValid and ((AForm.Top + MIN_PIXELS_VISIBLE) <= (Screen.DesktopRect.Bottom)); bValid := bValid and (AForm.Top >= Screen.DesktopRect.Top); if not bValid then begin AForm.Left := (Screen.Width div 2) - (AForm.Width div 2); AForm.Top := (Screen.Height div 2) - (AForm.Height div 2); end; {if} end; {TestFormPos} /////////////////////////////////////////////////////////////////////////////// function DoStoreFormPosition(AForm: TForm; const AKey: string): boolean; var FormData : TFormData; WindowPlacement : TWindowPlacement; begin Result := False; if not Assigned(AForm) then Exit; if not GetWindowPlacement(AForm.Handle, @WindowPlacement) then Exit; FormData.Key := AKey; FormData.NormalPosition := WindowPlacement.rcNormalPosition; FormData.Maximized := AForm.WindowState = wsMaximized; Result := FormData.SaveToRegistry; end; const cDefaultKey = '\Software\Dgmr\'; function GetFormRegistryKey(const AForm: TForm; const AProgramName, AInstanceName: string): string; begin Result := cDefaultKey + AProgramName; if AForm=nil then Result := Result + '\' else if AInstanceName = '' then Result := Result + '\' + AForm.ClassName else Result := Result + '\' + AForm.ClassName + '#' + AInstanceName; end; function GetFormLongRegistryKey(const AForm: TForm; const AInstanceName: string = ''): string; begin Result := GetFormRegistryKey(AForm, L_Data.ProgramName, AInstanceName); end; function GetFormShortRegistryKey(const AForm: TForm; const AInstanceName: string = ''): string; begin Result := GetFormRegistryKey(AForm, L_Data.ProgramShort, AInstanceName); end; function StoreFormPositionShort(AForm: TForm; const AInstanceName: string = ''): boolean; begin Result := DoStoreFormPosition(AForm, GetFormShortRegistryKey(AForm, AInstanceName)); end; function StoreFormPosition(AForm: TForm; const AInstanceName: string = ''): boolean; begin Result := DoStoreFormPosition(AForm, GetFormLongRegistryKey(AForm, AInstanceName)); end; /////////////////////////////////////////////////////////////////////////////// function DoRestoreFormPosition(AForm: TForm; const AKey: string): boolean; var FormData : TFormData; begin Result := False; if not Assigned(AForm) then Exit; FormData.Key := AKey; if not FormData.LoadFromRegistry then begin AForm.Left := (Screen.Width div 2) - (AForm.Width div 2); AForm.Top := (Screen.Height div 2) - (AForm.Height div 2); Exit; end; {if} AForm.Position := poDesigned; //disables automatic OnCreate positioning AForm.DefaultMonitor := dmDesktop; //disables automatic OnCreate positioning AForm.Left := FormData.NormalPosition.Left; AForm.Top := FormData.NormalPosition.Top; AForm.Width := FormData.NormalPosition.Right - FormData.NormalPosition.Left; AForm.Height := FormData.NormalPosition.Bottom - FormData.NormalPosition.Top; TestFormPos(AForm); //make sure its visible if FormData.Maximized then AForm.WindowState := wsMaximized; Result := True; end; function RestoreFormPositionShort(AForm: TForm; const AInstanceName: string = ''): boolean; begin Result := DoRestoreFormPosition(AForm, GetFormShortRegistryKey(AForm, AInstanceName)); end; function RestoreFormPosition(AForm: TForm; const AInstanceName: string = ''): boolean; begin Result := DoRestoreFormPosition(AForm, GetFormLongRegistryKey(AForm, AInstanceName)); end; /////////////////////////////////////////////////////////////////////////////// { TRestorableForm } procedure TRestorableForm.AfterConstruction; begin inherited; RestoreFormPosition(self); end; procedure TRestorableForm.BeforeDestruction; begin StoreFormPosition(self); inherited; end; { TFormData } end. |
Changes to src/prj/d2009/Paleo.dpr.
1 2 3 4 5 6 7 | program Paleo; uses Forms, FCommit in '..\..\FCommit.pas' {frmCommit}, fviewcontents in '..\..\fviewcontents.pas' {frmViewContents}, fviewdiff in '..\..\fviewdiff.pas' {frmViewDiff}, | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | program Paleo; uses Forms, FCommit in '..\..\FCommit.pas' {frmCommit}, fviewcontents in '..\..\fviewcontents.pas' {frmViewContents}, fviewdiff in '..\..\fviewdiff.pas' {frmViewDiff}, UAppSettings in '..\..\UAppSettings.pas'; {$R *.res} begin Application.Initialize; Application.MainFormOnTaskbar := True; Application.Title := 'Fossil UI'; |
︙ | ︙ |
Changes to src/prj/d2009/Paleo.dproj.
︙ | ︙ | |||
67 68 69 70 71 72 73 | <FormType>dfm</FormType> <Form>frmViewContents</Form> </DCCReference> <DCCReference Include="..\..\fviewdiff.pas"> <FormType>dfm</FormType> <Form>frmViewDiff</Form> </DCCReference> | | | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | <FormType>dfm</FormType> <Form>frmViewContents</Form> </DCCReference> <DCCReference Include="..\..\fviewdiff.pas"> <FormType>dfm</FormType> <Form>frmViewDiff</Form> </DCCReference> <DCCReference Include="..\..\UAppSettings.pas"/> <BuildConfiguration Include="Base"> <Key>Base</Key> </BuildConfiguration> <BuildConfiguration Include="Debug"> <Key>Cfg_2</Key> <CfgParent>Base</CfgParent> </BuildConfiguration> |
︙ | ︙ |
Changes to src/u_fossil.pas.
︙ | ︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 20 21 | uses Classes, SysUtils; type TFossilStatus = (fsUnversioned, fsUnchanged, fsAdded, fsEdited, fsDeleted, fsIgnored); const cFossilStatuses: array[0..5] of string = ('extra', 'unchanged', 'added', 'edited', 'deleted', 'ignored'); type { ------------------------------------------------------------------------------------------------ } { TFossil } | > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | uses Classes, SysUtils; type TFossilStatus = (fsUnversioned, fsUnchanged, fsAdded, fsEdited, fsDeleted, fsIgnored); EFossilError = class(Exception); const cFossilStatuses: array[0..5] of string = ('extra', 'unchanged', 'added', 'edited', 'deleted', 'ignored'); type { ------------------------------------------------------------------------------------------------ } { TFossil } |
︙ | ︙ | |||
178 179 180 181 182 183 184 | try S.CopyFrom(EMS, EMS.Size); S.Position := 0; Msg := S.ReadString(S.Size); if SameFileName(Copy(Msg, 2, Length(FExePath)), FExePath) then begin Msg := Copy(Msg, Length(FExePath) + 3, Length(Msg)); end; | | | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | try S.CopyFrom(EMS, EMS.Size); S.Position := 0; Msg := S.ReadString(S.Size); if SameFileName(Copy(Msg, 2, Length(FExePath)), FExePath) then begin Msg := Copy(Msg, Length(FExePath) + 3, Length(Msg)); end; raise EFossilError.Create(Msg); finally S.Free; end; end; finally OMS.Free; EMS.Free; |
︙ | ︙ | |||
276 277 278 279 280 281 282 283 284 285 286 287 288 289 | try Options := ''; if Opened and Closed then Options := '--all' else if Closed then Options := '--closed'; Result.Text := Run('branch list' + Options); except FreeAndNil(Result); raise; end; end; { ------------------------------------------------------------------------------------------------ } | > | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | try Options := ''; if Opened and Closed then Options := '--all' else if Closed then Options := '--closed'; Result.Text := Run('branch list' + Options); // TODO: filter something; remove the asterisk from the active branch except FreeAndNil(Result); raise; end; end; { ------------------------------------------------------------------------------------------------ } |
︙ | ︙ |