From 80aa75a802a2e54bbf63a18e2b102663a17bacf5 Mon Sep 17 00:00:00 2001 From: artem78 Date: Sat, 24 Jun 2023 15:00:52 +0300 Subject: [PATCH 01/38] [Tests] Fix missed package dependency --- Test/AutoScreenshotTest.lpi | 13 ++++++++----- Test/AutoScreenshotTestGUI.lpi | 11 +++++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Test/AutoScreenshotTest.lpi b/Test/AutoScreenshotTest.lpi index f08e7c8..74bdc63 100644 --- a/Test/AutoScreenshotTest.lpi +++ b/Test/AutoScreenshotTest.lpi @@ -28,18 +28,21 @@ - + - + - + - + + + + - + diff --git a/Test/AutoScreenshotTestGUI.lpi b/Test/AutoScreenshotTestGUI.lpi index f9809b9..023bf72 100644 --- a/Test/AutoScreenshotTestGUI.lpi +++ b/Test/AutoScreenshotTestGUI.lpi @@ -28,16 +28,19 @@ - + - + - + - + + + + From 7f92f5abd35326c1b869382f9b34189ba295d244 Mon Sep 17 00:00:00 2001 From: artem78 Date: Sat, 24 Jun 2023 16:11:59 +0300 Subject: [PATCH 02/38] [Tests] Make tests for capturing in BMP format --- Test/.gitignore | 1 + Test/AutoScreenshotTest.lpi | 5 ++ Test/AutoScreenshotTest.lpr | 3 +- Test/AutoScreenshotTestGUI.lpi | 7 ++- Test/AutoScreenshotTestGUI.lpr | 3 +- Test/grabbertests.pas | 107 +++++++++++++++++++++++++++++++++ 6 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 Test/.gitignore create mode 100644 Test/grabbertests.pas diff --git a/Test/.gitignore b/Test/.gitignore new file mode 100644 index 0000000..2734a16 --- /dev/null +++ b/Test/.gitignore @@ -0,0 +1 @@ +./out/ diff --git a/Test/AutoScreenshotTest.lpi b/Test/AutoScreenshotTest.lpi index 74bdc63..2ff623f 100644 --- a/Test/AutoScreenshotTest.lpi +++ b/Test/AutoScreenshotTest.lpi @@ -65,6 +65,11 @@ + + + + + diff --git a/Test/AutoScreenshotTest.lpr b/Test/AutoScreenshotTest.lpr index 5fcdf3c..1d0758f 100644 --- a/Test/AutoScreenshotTest.lpr +++ b/Test/AutoScreenshotTest.lpr @@ -3,7 +3,8 @@ {$mode objfpc}{$H+} uses - Interfaces, Forms, consoletestrunner, fpcunittestrunner, uTestCases; + Interfaces, Forms, consoletestrunner, fpcunittestrunner, uTestCases, + GrabberTests; {$R *.res} diff --git a/Test/AutoScreenshotTestGUI.lpi b/Test/AutoScreenshotTestGUI.lpi index 023bf72..83acf8e 100644 --- a/Test/AutoScreenshotTestGUI.lpi +++ b/Test/AutoScreenshotTestGUI.lpi @@ -42,7 +42,7 @@ - + @@ -65,6 +65,11 @@ + + + + + diff --git a/Test/AutoScreenshotTestGUI.lpr b/Test/AutoScreenshotTestGUI.lpr index f7c6d52..5af2ddf 100644 --- a/Test/AutoScreenshotTestGUI.lpr +++ b/Test/AutoScreenshotTestGUI.lpr @@ -3,7 +3,8 @@ {$mode objfpc}{$H+} uses - Interfaces, Forms, GuiTestRunner, fpcunittestrunner, uTestCases; + Interfaces, Forms, GuiTestRunner, fpcunittestrunner, uTestCases, + GrabberTests; {$R *.res} diff --git a/Test/grabbertests.pas b/Test/grabbertests.pas new file mode 100644 index 0000000..1f124a8 --- /dev/null +++ b/Test/grabbertests.pas @@ -0,0 +1,107 @@ +unit GrabberTests; + +{$mode ObjFPC}{$H+} + +interface + +uses + Classes, SysUtils, fpcunit, testutils, testregistry; + +type + + { TGrabberTestCase } + + TGrabberTestCase = class(TTestCase) + protected + procedure SetUp; override; + private + OutputDir: string; + procedure AssertBetween(AMinExpected, AMaxExpected, AActual: Integer); + procedure AssertBetween(const AMsg: String; AMinExpected, AMaxExpected, AActual: Integer); + published + procedure TestBmp; + public + constructor Create; override; + end; + +implementation + +uses ScreenGrabber, ZStream, Forms, BGRABitmap, FileUtil; + +{ TGrabberTestCase } + +procedure TGrabberTestCase.SetUp; +begin + inherited SetUp; + + if not DirectoryExists(OutputDir) then + CreateDir(OutputDir) + else + DeleteDirectory(OutputDir, True); +end; + +procedure TGrabberTestCase.AssertBetween(AMinExpected, AMaxExpected, + AActual: Integer); +begin + AssertTrue(AActual >= AMinExpected); + AssertTrue(AActual <= AMaxExpected); +end; + +procedure TGrabberTestCase.AssertBetween(const AMsg: String; AMinExpected, + AMaxExpected, AActual: Integer); +begin + AssertTrue(AMsg, AActual >= AMinExpected); + AssertTrue(AMsg, AActual <= AMaxExpected); +end; + +procedure TGrabberTestCase.TestBmp; +var + Grabber: TScreenGrabber; + FileName: String; + BitmapSize: Integer; + ColorDepth: TColorDepth; + Bitmap: TBGRABitmap; +begin + FileName := ConcatPaths([OutputDir, 'image.bmp']); + + for ColorDepth in {TColorDepth} [cd16Bit, cd24Bit, cd32Bit] do + begin + Grabber := TScreenGrabber.Create(fmtBMP, ColorDepth, 100, False, Tcompressionlevel.clNone); + try + //Grabber.CaptureAllMonitors(FileName); + Grabber.CaptureMonitor(FileName, 0); + + AssertTrue(FileExists(FileName)); + + BitmapSize := (Ord(ColorDepth) div 8) * Screen.Monitors[0].Width * Screen.Monitors[0].Height; + AssertBetween('Image size', BitmapSize, BitmapSize + 100 {headers, etc...}, FileSize(FileName)); + + try + Bitmap := TBGRABitmap.Create(FileName); + finally + AssertEquals('Image width', Screen.Monitors[0].Width, Bitmap.Width); + AssertEquals('Image height', Screen.Monitors[0].Height, Bitmap.Height); + //AssertEquals(Ord(ColorDepth), Bitmap.???); // Todo: make this + + Bitmap.Free; + end; + finally + Grabber.Free; + end; + end; +end; + +constructor TGrabberTestCase.Create; +begin + inherited Create; + + OutputDir := ConcatPaths([ExtractFileDir(Application.ExeName), 'out']); + OutputDir := IncludeTrailingPathDelimiter(OutputDir); +end; + +initialization + + RegisterTest(TGrabberTestCase); + +end. + From 26f2b1c8aa6acb9157bdf331d9bbea46dd9562d3 Mon Sep 17 00:00:00 2001 From: artem78 Date: Sat, 24 Jun 2023 16:53:31 +0300 Subject: [PATCH 03/38] [Tests] Rename test case unit and class --- Test/AutoScreenshotTest.lpi | 3 +- Test/AutoScreenshotTest.lpr | 2 +- Test/AutoScreenshotTestGUI.lpi | 3 +- Test/AutoScreenshotTestGUI.lpr | 2 +- Test/{uTestCases.pas => utilstests.pas} | 362 ++++++++++++------------ 5 files changed, 187 insertions(+), 185 deletions(-) rename Test/{uTestCases.pas => utilstests.pas} (91%) diff --git a/Test/AutoScreenshotTest.lpi b/Test/AutoScreenshotTest.lpi index 2ff623f..81b3000 100644 --- a/Test/AutoScreenshotTest.lpi +++ b/Test/AutoScreenshotTest.lpi @@ -48,8 +48,9 @@ - + + diff --git a/Test/AutoScreenshotTest.lpr b/Test/AutoScreenshotTest.lpr index 1d0758f..a3cb839 100644 --- a/Test/AutoScreenshotTest.lpr +++ b/Test/AutoScreenshotTest.lpr @@ -3,7 +3,7 @@ {$mode objfpc}{$H+} uses - Interfaces, Forms, consoletestrunner, fpcunittestrunner, uTestCases, + Interfaces, Forms, consoletestrunner, fpcunittestrunner, UtilsTests, GrabberTests; {$R *.res} diff --git a/Test/AutoScreenshotTestGUI.lpi b/Test/AutoScreenshotTestGUI.lpi index 83acf8e..9667125 100644 --- a/Test/AutoScreenshotTestGUI.lpi +++ b/Test/AutoScreenshotTestGUI.lpi @@ -48,8 +48,9 @@ - + + diff --git a/Test/AutoScreenshotTestGUI.lpr b/Test/AutoScreenshotTestGUI.lpr index 5af2ddf..6508dfd 100644 --- a/Test/AutoScreenshotTestGUI.lpr +++ b/Test/AutoScreenshotTestGUI.lpr @@ -3,7 +3,7 @@ {$mode objfpc}{$H+} uses - Interfaces, Forms, GuiTestRunner, fpcunittestrunner, uTestCases, + Interfaces, Forms, GuiTestRunner, fpcunittestrunner, UtilsTests, GrabberTests; {$R *.res} diff --git a/Test/uTestCases.pas b/Test/utilstests.pas similarity index 91% rename from Test/uTestCases.pas rename to Test/utilstests.pas index abf79e6..a43edaf 100644 --- a/Test/uTestCases.pas +++ b/Test/utilstests.pas @@ -1,181 +1,181 @@ -unit uTestCases; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, fpcunit, testutils, testregistry; - -type - - { TMyTestCase } - - TMyTestCase= class(TTestCase) - private - function GetFormattedPath(Path: String): String; - published - procedure TestFormatPath; - procedure TestDecode; - procedure TestJoinPath; - procedure TestVersions; - procedure TestAutoRun; - end; - -implementation - -uses uUtils, {SysUtils} DateUtils, uUtilsMore, Forms; - -{ TMyTestCase } - -function TMyTestCase.GetFormattedPath(Path: String): String; -var - DateTime: TDateTime; -begin - DateTime := EncodeDateTime(2020, 4, 19, 12, 34, 56, 789); - Result := FormatDateTime2(Path, DateTime); -end; - -procedure TMyTestCase.TestDecode; -begin - AssertEquals('This is' + #13 + #10 + 'multiline' + #13 + #10 + 'text', - DecodeControlCharacters('This is\r\nmultiline\r\ntext')); - AssertEquals('lorem' + #9 + 'ipsum' + #13 + #10 + 'dolor sit\amet' + #13 + #10, - DecodeControlCharacters('lorem\tipsum\r\ndolor sit\\amet\r\n')); - AssertEquals('', DecodeControlCharacters('')); - AssertEquals('blablabla', DecodeControlCharacters('blablabla')); -end; - -procedure TMyTestCase.TestFormatPath; -{var - CompName, UserName: String;} -begin - AssertEquals('19-04-2020', GetFormattedPath('%D-%M-%Y')); - AssertEquals('2020_04_19', GetFormattedPath('%Y_%M_%D')); - AssertEquals('12.34.56', GetFormattedPath('%H.%N.%S')); - if '12.34.56' = GetFormattedPath('%H.%M.%S') then - Fail('Month and minute mixed up'); - AssertEquals('No format variables', - 'screenshot123', GetFormattedPath('screenshot123')); - AssertEquals('Complex test', - '2020\04-19\screenshot_20200419_123456.png', - GetFormattedPath('%Y\%M-%D\screenshot_%Y%M%D_%H%N%S.png')); - AssertEquals('Non ASCII symbols', - 'скриншот 123456.jpeg', - GetFormattedPath('скриншот %H%N%S.jpeg')); - AssertEquals('20200419_123456/123456-19042020', GetFormattedPath('%Y%M%D_%H%N%S/%H%N%S-%D%M%Y')); - - // ToDo: Test incorect strings - - {// Note: On your machine this values will be different - CompName := 'PC'; - UserName := 'Artem'; - AssertEquals('PC and user name', - CompName + '_' + UserName + '_image.tiff', - GetFormattedPath('%COMP_%USER_image.tiff'));} -end; - -procedure TMyTestCase.TestJoinPath; - function JoinPath(const Base: String; const Path: String): String; - begin - Result := ConcatPaths([Base, Path]); - end; - -begin - //CheckEqualsString('', JoinPath('', '')); - {$IFDEF MSWINDOWS} - AssertEquals('c:\root\subdir\', JoinPath('c:\root', 'subdir\')); - AssertEquals('Path starts with backslash', - 'd:\folder1\folder2\folder3\folder4\', - JoinPath('d:\folder1\folder2\', '\folder3\folder4\')); - AssertEquals('Empty path', 'a:\DisketDir\', JoinPath('a:\DisketDir', '')); - AssertEquals('Relative path', - 'mydir\picture.jpeg', JoinPath('mydir', 'picture.jpeg')); - {$ENDIF} -end; - -procedure TMyTestCase.TestVersions; -var - V1, V2: TProgramVersion; -begin - with V1 do - begin - Major := 5; - Minor := 12; - Revision := 101; - Build := 54912; - end; - - with V2 do - begin - Major := 3; - Minor := 0; - Revision := 2; - Build := 0; - end; - - // Test equal / not equal - AssertTrue(V1 = TProgramVersion.Create(5, 12, 101, 54912)); - AssertFalse(V1 = V2); - AssertTrue(V1 <> V2); - AssertTrue(V2 = TProgramVersion.Create(3, 0, 2)); - AssertTrue(V1 = TProgramVersion.Create('5.12.101.54912')); - AssertTrue(V1 <> TProgramVersion.Create('5.12.101')); - AssertTrue(V2 = TProgramVersion.Create('v3.0.2')); - AssertTrue(V2 = TProgramVersion.Create('V3.0.2.0')); - AssertTrue(V2 <> TProgramVersion.Create('v3.02')); - - // Test more / less - AssertTrue(V1 > V2); - AssertTrue(V2 < V1); - AssertTrue(V2 < TProgramVersion.Create(3, 1)); - AssertTrue(V2 > TProgramVersion.Create(3, 0, 1)); - AssertTrue(V2 < TProgramVersion.Create(3, 0, 2, 55)); - AssertTrue(V1 < TProgramVersion.Create(5, 12, 101, 54913)); - AssertTrue(V1 > TProgramVersion.Create(5, 12, 101, 54911)); - AssertFalse(V1 > V1); - - // Test to string conversion - AssertEquals('12.345.67.8', TProgramVersion.Create(12, 345, 67, 8).ToString(False)); - AssertEquals('12.345.67.0', TProgramVersion.Create(12, 345, 67, 0).ToString(False)); - AssertEquals('12.345.0.0', TProgramVersion.Create(12, 345, 0, 0) .ToString(False)); - AssertEquals('12.0.0.0', TProgramVersion.Create(12, 0, 0, 0) .ToString(False)); - AssertEquals('12.0.0.8', TProgramVersion.Create(12, 0, 0, 8) .ToString(False)); - AssertEquals('0.0.0.8', TProgramVersion.Create(0, 0, 0, 8) .ToString(False)); - AssertEquals('0.345.0.0', TProgramVersion.Create(0, 345, 0, 0) .ToString(False)); - AssertEquals('0.0.0.0', TProgramVersion.Create(0, 0, 0, 0) .ToString(False)); - - AssertEquals('12.345.67.8', TProgramVersion.Create(12, 345, 67, 8).ToString(True)); - AssertEquals('12.345.67', TProgramVersion.Create(12, 345, 67, 0).ToString(True)); - AssertEquals('12.345', TProgramVersion.Create(12, 345, 0, 0) .ToString(True)); - AssertEquals('12', TProgramVersion.Create(12, 0, 0, 0) .ToString(True)); - AssertEquals('12.0.0.8', TProgramVersion.Create(12, 0, 0, 8) .ToString(True)); - AssertEquals('0.0.0.8', TProgramVersion.Create(0, 0, 0, 8) .ToString(True)); - AssertEquals('0.345', TProgramVersion.Create(0, 345, 0, 0) .ToString(True)); - //AssertEquals({''} '0', TProgramVersion.Create(0, 0, 0, 0) .ToString(True)); - - // ToDo: Check wrong version strings -end; - -procedure TMyTestCase.TestAutoRun; -var - ExeFileName, AppTitle: String; -begin - ExeFileName := Application.ExeName; - AppTitle := 'AutoRun test'; - - AssertFalse(CheckAutoRun(ExeFileName, AppTitle)); - AutoRun(ExeFileName, AppTitle, True); // Turn on autorun - AssertTrue(CheckAutoRun(ExeFileName, AppTitle)); - AssertFalse(CheckAutoRun('xyz', 'abcdefg')); - AutoRun(ExeFileName, AppTitle, False); // Turn off autorun - AssertFalse(CheckAutoRun(ExeFileName, AppTitle)); - - -end; - -initialization - - RegisterTest(TMyTestCase); -end. - +unit UtilsTests; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, fpcunit, testutils, testregistry; + +type + + { TUtilsTestCase } + + TUtilsTestCase= class(TTestCase) + private + function GetFormattedPath(Path: String): String; + published + procedure TestFormatPath; + procedure TestDecode; + procedure TestJoinPath; + procedure TestVersions; + procedure TestAutoRun; + end; + +implementation + +uses uUtils, {SysUtils} DateUtils, uUtilsMore, Forms; + +{ TUtilsTestCase } + +function TUtilsTestCase.GetFormattedPath(Path: String): String; +var + DateTime: TDateTime; +begin + DateTime := EncodeDateTime(2020, 4, 19, 12, 34, 56, 789); + Result := FormatDateTime2(Path, DateTime); +end; + +procedure TUtilsTestCase.TestDecode; +begin + AssertEquals('This is' + #13 + #10 + 'multiline' + #13 + #10 + 'text', + DecodeControlCharacters('This is\r\nmultiline\r\ntext')); + AssertEquals('lorem' + #9 + 'ipsum' + #13 + #10 + 'dolor sit\amet' + #13 + #10, + DecodeControlCharacters('lorem\tipsum\r\ndolor sit\\amet\r\n')); + AssertEquals('', DecodeControlCharacters('')); + AssertEquals('blablabla', DecodeControlCharacters('blablabla')); +end; + +procedure TUtilsTestCase.TestFormatPath; +{var + CompName, UserName: String;} +begin + AssertEquals('19-04-2020', GetFormattedPath('%D-%M-%Y')); + AssertEquals('2020_04_19', GetFormattedPath('%Y_%M_%D')); + AssertEquals('12.34.56', GetFormattedPath('%H.%N.%S')); + if '12.34.56' = GetFormattedPath('%H.%M.%S') then + Fail('Month and minute mixed up'); + AssertEquals('No format variables', + 'screenshot123', GetFormattedPath('screenshot123')); + AssertEquals('Complex test', + '2020\04-19\screenshot_20200419_123456.png', + GetFormattedPath('%Y\%M-%D\screenshot_%Y%M%D_%H%N%S.png')); + AssertEquals('Non ASCII symbols', + 'скриншот 123456.jpeg', + GetFormattedPath('скриншот %H%N%S.jpeg')); + AssertEquals('20200419_123456/123456-19042020', GetFormattedPath('%Y%M%D_%H%N%S/%H%N%S-%D%M%Y')); + + // ToDo: Test incorect strings + + {// Note: On your machine this values will be different + CompName := 'PC'; + UserName := 'Artem'; + AssertEquals('PC and user name', + CompName + '_' + UserName + '_image.tiff', + GetFormattedPath('%COMP_%USER_image.tiff'));} +end; + +procedure TUtilsTestCase.TestJoinPath; + function JoinPath(const Base: String; const Path: String): String; + begin + Result := ConcatPaths([Base, Path]); + end; + +begin + //CheckEqualsString('', JoinPath('', '')); + {$IFDEF MSWINDOWS} + AssertEquals('c:\root\subdir\', JoinPath('c:\root', 'subdir\')); + AssertEquals('Path starts with backslash', + 'd:\folder1\folder2\folder3\folder4\', + JoinPath('d:\folder1\folder2\', '\folder3\folder4\')); + AssertEquals('Empty path', 'a:\DisketDir\', JoinPath('a:\DisketDir', '')); + AssertEquals('Relative path', + 'mydir\picture.jpeg', JoinPath('mydir', 'picture.jpeg')); + {$ENDIF} +end; + +procedure TUtilsTestCase.TestVersions; +var + V1, V2: TProgramVersion; +begin + with V1 do + begin + Major := 5; + Minor := 12; + Revision := 101; + Build := 54912; + end; + + with V2 do + begin + Major := 3; + Minor := 0; + Revision := 2; + Build := 0; + end; + + // Test equal / not equal + AssertTrue(V1 = TProgramVersion.Create(5, 12, 101, 54912)); + AssertFalse(V1 = V2); + AssertTrue(V1 <> V2); + AssertTrue(V2 = TProgramVersion.Create(3, 0, 2)); + AssertTrue(V1 = TProgramVersion.Create('5.12.101.54912')); + AssertTrue(V1 <> TProgramVersion.Create('5.12.101')); + AssertTrue(V2 = TProgramVersion.Create('v3.0.2')); + AssertTrue(V2 = TProgramVersion.Create('V3.0.2.0')); + AssertTrue(V2 <> TProgramVersion.Create('v3.02')); + + // Test more / less + AssertTrue(V1 > V2); + AssertTrue(V2 < V1); + AssertTrue(V2 < TProgramVersion.Create(3, 1)); + AssertTrue(V2 > TProgramVersion.Create(3, 0, 1)); + AssertTrue(V2 < TProgramVersion.Create(3, 0, 2, 55)); + AssertTrue(V1 < TProgramVersion.Create(5, 12, 101, 54913)); + AssertTrue(V1 > TProgramVersion.Create(5, 12, 101, 54911)); + AssertFalse(V1 > V1); + + // Test to string conversion + AssertEquals('12.345.67.8', TProgramVersion.Create(12, 345, 67, 8).ToString(False)); + AssertEquals('12.345.67.0', TProgramVersion.Create(12, 345, 67, 0).ToString(False)); + AssertEquals('12.345.0.0', TProgramVersion.Create(12, 345, 0, 0) .ToString(False)); + AssertEquals('12.0.0.0', TProgramVersion.Create(12, 0, 0, 0) .ToString(False)); + AssertEquals('12.0.0.8', TProgramVersion.Create(12, 0, 0, 8) .ToString(False)); + AssertEquals('0.0.0.8', TProgramVersion.Create(0, 0, 0, 8) .ToString(False)); + AssertEquals('0.345.0.0', TProgramVersion.Create(0, 345, 0, 0) .ToString(False)); + AssertEquals('0.0.0.0', TProgramVersion.Create(0, 0, 0, 0) .ToString(False)); + + AssertEquals('12.345.67.8', TProgramVersion.Create(12, 345, 67, 8).ToString(True)); + AssertEquals('12.345.67', TProgramVersion.Create(12, 345, 67, 0).ToString(True)); + AssertEquals('12.345', TProgramVersion.Create(12, 345, 0, 0) .ToString(True)); + AssertEquals('12', TProgramVersion.Create(12, 0, 0, 0) .ToString(True)); + AssertEquals('12.0.0.8', TProgramVersion.Create(12, 0, 0, 8) .ToString(True)); + AssertEquals('0.0.0.8', TProgramVersion.Create(0, 0, 0, 8) .ToString(True)); + AssertEquals('0.345', TProgramVersion.Create(0, 345, 0, 0) .ToString(True)); + //AssertEquals({''} '0', TProgramVersion.Create(0, 0, 0, 0) .ToString(True)); + + // ToDo: Check wrong version strings +end; + +procedure TUtilsTestCase.TestAutoRun; +var + ExeFileName, AppTitle: String; +begin + ExeFileName := Application.ExeName; + AppTitle := 'AutoRun test'; + + AssertFalse(CheckAutoRun(ExeFileName, AppTitle)); + AutoRun(ExeFileName, AppTitle, True); // Turn on autorun + AssertTrue(CheckAutoRun(ExeFileName, AppTitle)); + AssertFalse(CheckAutoRun('xyz', 'abcdefg')); + AutoRun(ExeFileName, AppTitle, False); // Turn off autorun + AssertFalse(CheckAutoRun(ExeFileName, AppTitle)); + + +end; + +initialization + + RegisterTest(TUtilsTestCase); +end. + From 82f7b47249cf682f03c47da3aa68c9ba3a22f698 Mon Sep 17 00:00:00 2001 From: artem78 Date: Wed, 28 Jun 2023 13:14:25 +0300 Subject: [PATCH 04/38] [Tests] fix in gitignore --- Test/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Test/.gitignore b/Test/.gitignore index 2734a16..89f9ac0 100644 --- a/Test/.gitignore +++ b/Test/.gitignore @@ -1 +1 @@ -./out/ +out/ From a4f3dbb8a236a0fbe2012b56e4915c94e9a2812a Mon Sep 17 00:00:00 2001 From: artem78 Date: Thu, 6 Jul 2023 22:02:13 +0300 Subject: [PATCH 05/38] [Linux] Make DEB-package using LazPackager --- .gitignore | 4 +++ AutoScreenshot.lpi | 79 ++++++++++++++++++++++++++++++++++++++++++++++ uLocalization.pas | 15 ++++++++- 3 files changed, 97 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e6e9d18..3420a40 100755 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,7 @@ dunit.ini /Test/AutoScreenshotTest /Test/AutoScreenshotTestGUI /*log.txt + +# Linux build files +/DEBUILD/ +/DEBUILD.sh diff --git a/AutoScreenshot.lpi b/AutoScreenshot.lpi index 09a5cdc..a4ce6eb 100644 --- a/AutoScreenshot.lpi +++ b/AutoScreenshot.lpi @@ -47,6 +47,85 @@ + + + + + + + + + + + + + + + diff --git a/uLocalization.pas b/uLocalization.pas index 04eb663..b211af4 100644 --- a/uLocalization.pas +++ b/uLocalization.pas @@ -248,10 +248,23 @@ procedure TLocalizer.LoadFromFile(AFileName: String); end; end; +var + LangDir: String; + initialization begin + {$IfDef Windows} + LangDir := AppendPathDelim(ConcatPaths([ProgramDirectory, 'lang']); + {$EndIf} + {$IfDef Linux} + if IsPortable then + LangDir := AppendPathDelim(ConcatPaths([ProgramDirectory, 'lang'])) + else + LangDir := '/usr/share/autoscreenshot/lang/'; + {$EndIf} + // ToDo: Use alternatives only in Release build - Localizer := TLocalizer.Create(AppendPathDelim(ConcatPaths([ProgramDirectory, 'lang'])), True); + Localizer := TLocalizer.Create(LangDir, True); end; finalization From 9f279252a7de456bc1b5e118246f28ee9bdd6c09 Mon Sep 17 00:00:00 2001 From: artem78 Date: Sun, 9 Jul 2023 22:37:02 +0300 Subject: [PATCH 06/38] [Linux] Add menu entry when installed from DEB package --- AutoScreenshot.lpi | 6 +++++- autoscreenshot.desktop | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 autoscreenshot.desktop diff --git a/AutoScreenshot.lpi b/AutoScreenshot.lpi index a4ce6eb..a1ad4aa 100644 --- a/AutoScreenshot.lpi +++ b/AutoScreenshot.lpi @@ -106,6 +106,9 @@ override_dh_auto_install: install -m 644 -T "lang/tr.ini" "$(ROOT)/usr/share/autoscreenshot/lang/tr.ini" install -m 644 -T "lang/uk.ini" "$(ROOT)/usr/share/autoscreenshot/lang/uk.ini" install -m 644 -T "lang/zh.ini" "$(ROOT)/usr/share/autoscreenshot/lang/zh.ini" + install -d -m 755 "$(ROOT)/usr/share/applications" + sed -e '/^\s*#/d; /^\s*$$/d' "autoscreenshot.desktop" > "autoscreenshot_tmp.desktop" + install -m 644 "autoscreenshot_tmp.desktop" "$(ROOT)/usr/share/applications" %: dh $@ @@ -121,7 +124,8 @@ override_dh_auto_install: ?CP? -r res/ ?TEMPFOLDER?/ ?CP? *.inc ?TEMPFOLDER?/ ?CP? -r libs/ ?TEMPFOLDER?/ -?CP? -r lang/ ?TEMPFOLDER?/"/> +?CP? -r lang/ ?TEMPFOLDER?/ +?CP? *.desktop ?TEMPFOLDER?/"/> diff --git a/autoscreenshot.desktop b/autoscreenshot.desktop new file mode 100644 index 0000000..b5339e3 --- /dev/null +++ b/autoscreenshot.desktop @@ -0,0 +1,18 @@ +[Desktop Entry] +#Version=1.0 +Encoding=UTF-8 +Type=Application +Name=AutoScreenshot +#Name[ru]= +GenericName=Screenshot tool +#GenericName[ru]= +Comment=Automatic screenshot capturing +Comment[ru]=Автоматическое создание снимков экрана +Exec="/usr/bin/autoscreenshot" +#StartupNotify=false +#StartupWMClass=Lmxconverter +Terminal=false +Categories=Graphics;Utility;ImageProcessing +#Icon=autoscreenshot +Keywords=screenshot;capture;capturing;grabbing + From fcc164aad7954ac4f995877a468ee9899064867c Mon Sep 17 00:00:00 2001 From: artem78 Date: Sun, 9 Jul 2023 22:55:30 +0300 Subject: [PATCH 07/38] [Linux] Fix portable checking for Linux --- uUtils.pas | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/uUtils.pas b/uUtils.pas index 39ff1a3..c3acb5f 100644 --- a/uUtils.pas +++ b/uUtils.pas @@ -419,11 +419,18 @@ procedure RunCmdInbackground(ACmd: String); end; function IsPortable: Boolean; +{$IfDef Windows} var UninstallerFileName: String; +{$EndIf} begin + {$IfDef Windows} UninstallerFileName := ExtractFilePath(Application.ExeName) + 'unins000.exe'; Result := not FileExists(UninstallerFileName); + {$EndIf} + {$IfDef Linux} + Result := not Application.ExeName.StartsWith('/usr/bin/'); + {$EndIf} end; function GetUserPicturesDir: WideString; From f1bdaff7f0ece1252aa21491b5ea35cf938c7879 Mon Sep 17 00:00:00 2001 From: artem78 Date: Sun, 9 Jul 2023 23:50:17 +0300 Subject: [PATCH 08/38] [Linux] Fix resolving user pictures directory path in Linux --- uUtils.pas | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/uUtils.pas b/uUtils.pas index c3acb5f..1b53964 100644 --- a/uUtils.pas +++ b/uUtils.pas @@ -434,14 +434,30 @@ function IsPortable: Boolean; end; function GetUserPicturesDir: WideString; +{$IfDef Linux} +var + CmdRes: AnsiString; +{$EndIf} begin + Result := ''; + {$IfDef Windows} //Result := GetUserDir + 'Pictures'; Result := GetWindowsSpecialDirUnicode(CSIDL_MYPICTURES); {$EndIf} {$IfDef Linux} - Result := '~/Pictures'; // Not 100% guarantee, but most likely + try + if RunCommand('xdg-user-dir PICTURES', CmdRes) then + Result := Trim(CmdRes); + except + end; + + if (Result = '') or (not DirectoryExists(Result)) then + // As fallback - not 100% guarantee, but most likely + Result := ConcatPaths([GetEnvironmentVariable('HOME'), 'Pictures']); {$EndIf} + + Result := IncludeTrailingPathDelimiter(Result); end; end. From 2ece4a615941f0ec85fc2ce26ad99f88739536be Mon Sep 17 00:00:00 2001 From: artem78 Date: Mon, 10 Jul 2023 12:04:17 +0300 Subject: [PATCH 09/38] [Linux] Add icon for menu entry in DEB package --- AutoScreenshot.lpi | 10 ++++++++++ autoscreenshot.desktop | 2 +- res/main_icon_16px.png | Bin 0 -> 1047 bytes res/main_icon_24px.png | Bin 0 -> 1546 bytes res/main_icon_32px.png | Bin 0 -> 2125 bytes res/main_icon_48px.png | Bin 0 -> 3254 bytes res/main_icon_64px.png | Bin 0 -> 4914 bytes 7 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 res/main_icon_16px.png create mode 100644 res/main_icon_24px.png create mode 100644 res/main_icon_32px.png create mode 100644 res/main_icon_48px.png create mode 100644 res/main_icon_64px.png diff --git a/AutoScreenshot.lpi b/AutoScreenshot.lpi index a1ad4aa..ae923df 100644 --- a/AutoScreenshot.lpi +++ b/AutoScreenshot.lpi @@ -109,6 +109,16 @@ override_dh_auto_install: install -d -m 755 "$(ROOT)/usr/share/applications" sed -e '/^\s*#/d; /^\s*$$/d' "autoscreenshot.desktop" > "autoscreenshot_tmp.desktop" install -m 644 "autoscreenshot_tmp.desktop" "$(ROOT)/usr/share/applications" + install -d -m 755 "$(ROOT)/usr/share/icons/hicolor/16x16/apps" + install -m 644 -T "res/main_icon_16px.png" "$(ROOT)/usr/share/icons/hicolor/16x16/apps/autoscreenshot.png" + install -d -m 755 "$(ROOT)/usr/share/icons/hicolor/24x24/apps" + install -m 644 -T "res/main_icon_24px.png" "$(ROOT)/usr/share/icons/hicolor/24x24/apps/autoscreenshot.png" + install -d -m 755 "$(ROOT)/usr/share/icons/hicolor/32x32/apps" + install -m 644 -T "res/main_icon_32px.png" "$(ROOT)/usr/share/icons/hicolor/32x32/apps/autoscreenshot.png" + install -d -m 755 "$(ROOT)/usr/share/icons/hicolor/48x48/apps" + install -m 644 -T "res/main_icon_48px.png" "$(ROOT)/usr/share/icons/hicolor/48x48/apps/autoscreenshot.png" + install -d -m 755 "$(ROOT)/usr/share/icons/hicolor/64x64/apps" + install -m 644 -T "res/main_icon_64px.png" "$(ROOT)/usr/share/icons/hicolor/64x64/apps/autoscreenshot.png" %: dh $@ diff --git a/autoscreenshot.desktop b/autoscreenshot.desktop index b5339e3..224f2c7 100644 --- a/autoscreenshot.desktop +++ b/autoscreenshot.desktop @@ -13,6 +13,6 @@ Exec="/usr/bin/autoscreenshot" #StartupWMClass=Lmxconverter Terminal=false Categories=Graphics;Utility;ImageProcessing -#Icon=autoscreenshot +Icon=autoscreenshot Keywords=screenshot;capture;capturing;grabbing diff --git a/res/main_icon_16px.png b/res/main_icon_16px.png new file mode 100644 index 0000000000000000000000000000000000000000..8e93a5953a69ddb4bc3a0bcfe448d9d1719190e8 GIT binary patch literal 1047 zcmV+y1nB#TP)EX>4Tx04R}tkv&MmKpe$iQ>CR;9PA*{AwzYtAS&XhRVYG*P%E_RU~=gfG%+M8 zE{=k0!NHHks)LKOt`4q(Aou~|>f)s6A|?JWDYS_3;J6>}?mh0_0YbCJG^=L}&~)3( zrc+|Rup)+D5kdrE#39PeGG-+y1K;s=j{slql03`*+@GUQEm{l+h{Q9@Fm2*>;;BvB z;Ji;9V-;B?J|`YE>4LMc6{Svtpa#g{| zF^>&skX=9cAN=mtDou=gNzoM0`{Fns!$4>kXf+(?``B?>CqVESxY9fRjV3VtNqVEB zC60jpZQ$a%qbYm9A(Ki)h;#%$LRx*qpmVHz`-Ff zQl{)RpLd75d;9lHyT2bs0dke@_;aBE000JJOGiWi{{a60|De66lK=n!32;bRa{vGf z6951U69E94oEQKA00(qQO+^Ri2MP!w7Hm*Vce& z{=T4Yz7(2_jlh!B4iQ1n!3ko81wzIOb}EuC(xD_;M-P==>YxclpgV-k+|pA;6a^z` zw>r$UmvyP_@c+Gd_;nagdJ#gu@LZm^@AEw0$1=vS9Tc%mxB*7S9+>8aTK4a0rL)a% z0Zc{bt^zmK6D`a7tJoNmuw!JC)RCEqE5IlRTx8R(8vPiwB zhNcD&*=&|BQctE&K%m6iR*@cHXECLd0dTuK4Z(cZ?y?NOQ< z>Njq%_$EnOy8zhR(#ZVV_t@1nxZG}D%uX{D4lx?J2EgO^Q!ZYKaQN5&c2zYW-X%9z zA@%AxL*WoUe}KW^2!q2BeEtAK;Sj0U&o*S#N+BEv;W(^mjZz9F1eujIeLdZb&BPhM zei>hTC*#pLeLdY|KBWNtOLCR#?$Nr;7Hd#9?i{DQf^afSF$Dr zKfa_9xt{=(R#Z{l*g|nhDFEM>KVqFYeeR#1_@78vz)oP-78|Tsz`AV(<`=s#EX>4Tx04R}tkv&MmKpe$iQ>CR;9PA*{AwzYtAS&XhRVYG*P%E_RU~=gfG%+M8 zE{=k0!NHHks)LKOt`4q(Aou~|>f)s6A|?JWDYS_3;J6>}?mh0_0YbCJG^=L}&~)3( zrc+|Rup)+D5kdrE#39PeGG-+y1K;s=j{slql03`*+@GUQEm{l+h{Q9@Fm2*>;;BvB z;Ji;9V-;B?J|`YE>4LMc6{Svtpa#g{| zF^>&skX=9cAN=mtDou=gNzoM0`{Fns!$4>kXf+(?``B?>CqVESxY9fRjV3VtNqVEB zC60jpZQ$a%qbYm9A(Ki)h;#%$LRx*qpmVHz`-Ff zQl{)RpLd75d;9lHyT2bs0dke@_;aBE000JJOGiWi{{a60|De66lK=n!32;bRa{vGf z6951U69E94oEQKA00(qQO+^Ri2MP!w0(Od+nE(I;2uVaiR7l6|m2FIwWf;eQ9L@ob z#}E#07C6xa3QL{%I;3=9FWADDB8T>&wlKFEGgof%twtM_V#C?OWt*qcR2UP5nl;D5 zsX0gBIE17fMGZM}4xrD=d7k@uo<1CX)U_60Tx;vvt`GNh{jdLZ|F3)3ZusB+ZHob@ zYw%SA)qwkUTmfn}RlZtN*Whyktw6~g{5Z`54mxiistcaXbEkT}JT%cmir4G@+;?Cr zPygB-c*i#-N5?QFH*eh zX==BB%1Y9dy!_e*malsQM{F$Np+UkU5{~gq@hG`%~RKXq7^?MZe{Ub2N#3Xe5mn&OA{wfqAWM?%iY%i=G<02{ zC<-Z=+3Y*iNY%zlOjRP#)5&0*1!MA%C?HwoR?CB#h zBNIiIz!6JAViGa$z5kI_@zP4Nr)1i)!=q!I^Y?M(+8~7s3z(Yq2t&ajo40Hw)tf~5 z>Xqc?%mCng|8E>FgTfnE(I)07*qoM6N<$f*|eN0RR91 literal 0 HcmV?d00001 diff --git a/res/main_icon_32px.png b/res/main_icon_32px.png new file mode 100644 index 0000000000000000000000000000000000000000..b3254cfdad88d5e8a19dad199dbf97acea0a63f9 GIT binary patch literal 2125 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 literal 0 HcmV?d00001 diff --git a/res/main_icon_64px.png b/res/main_icon_64px.png new file mode 100644 index 0000000000000000000000000000000000000000..cf98434c042b877300e89cda518f78edd18913c5 GIT binary patch literal 4914 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 literal 0 HcmV?d00001 From 017a4ffaf4bbf1198e254e9675fc74542c0e0e43 Mon Sep 17 00:00:00 2001 From: artem78 Date: Sun, 16 Jul 2023 16:15:31 +0300 Subject: [PATCH 10/38] [Linux] Fix *.desktop file name in DEB-package --- AutoScreenshot.lpi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutoScreenshot.lpi b/AutoScreenshot.lpi index ae923df..985ec4c 100644 --- a/AutoScreenshot.lpi +++ b/AutoScreenshot.lpi @@ -108,7 +108,7 @@ override_dh_auto_install: install -m 644 -T "lang/zh.ini" "$(ROOT)/usr/share/autoscreenshot/lang/zh.ini" install -d -m 755 "$(ROOT)/usr/share/applications" sed -e '/^\s*#/d; /^\s*$$/d' "autoscreenshot.desktop" > "autoscreenshot_tmp.desktop" - install -m 644 "autoscreenshot_tmp.desktop" "$(ROOT)/usr/share/applications" + install -m 644 "autoscreenshot_tmp.desktop" "$(ROOT)/usr/share/applications/autoscreenshot.desktop" install -d -m 755 "$(ROOT)/usr/share/icons/hicolor/16x16/apps" install -m 644 -T "res/main_icon_16px.png" "$(ROOT)/usr/share/icons/hicolor/16x16/apps/autoscreenshot.png" install -d -m 755 "$(ROOT)/usr/share/icons/hicolor/24x24/apps" From 7e5477ecc240bace63d55764975232bed5007705 Mon Sep 17 00:00:00 2001 From: artem78 Date: Sun, 16 Jul 2023 16:30:11 +0300 Subject: [PATCH 11/38] [Linux] Improve rules for DEB package --- AutoScreenshot.lpi | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/AutoScreenshot.lpi b/AutoScreenshot.lpi index 985ec4c..390fea4 100644 --- a/AutoScreenshot.lpi +++ b/AutoScreenshot.lpi @@ -95,30 +95,16 @@ override_dh_auto_build: override_dh_auto_install: install -d -m 755 "$(ROOT)/usr/bin" install -s -m 755 ?EXECUTABLE? "$(ROOT)/usr/bin/autoscreenshot" - install -d -m 755 "$(ROOT)/usr/share/autoscreenshot" install -d -m 755 "$(ROOT)/usr/share/autoscreenshot/lang" - install -m 644 -T "lang/de.ini" "$(ROOT)/usr/share/autoscreenshot/lang/de.ini" - install -m 644 -T "lang/en.ini" "$(ROOT)/usr/share/autoscreenshot/lang/en.ini" - install -m 644 -T "lang/es.ini" "$(ROOT)/usr/share/autoscreenshot/lang/es.ini" - install -m 644 -T "lang/fr.ini" "$(ROOT)/usr/share/autoscreenshot/lang/fr.ini" - install -m 644 -T "lang/pt.ini" "$(ROOT)/usr/share/autoscreenshot/lang/pt.ini" - install -m 644 -T "lang/ru.ini" "$(ROOT)/usr/share/autoscreenshot/lang/ru.ini" - install -m 644 -T "lang/tr.ini" "$(ROOT)/usr/share/autoscreenshot/lang/tr.ini" - install -m 644 -T "lang/uk.ini" "$(ROOT)/usr/share/autoscreenshot/lang/uk.ini" - install -m 644 -T "lang/zh.ini" "$(ROOT)/usr/share/autoscreenshot/lang/zh.ini" + cp lang/*.ini "$(ROOT)/usr/share/autoscreenshot/lang/" + chmod -R 644 "$(ROOT)/usr/share/autoscreenshot/lang/" install -d -m 755 "$(ROOT)/usr/share/applications" sed -e '/^\s*#/d; /^\s*$$/d' "autoscreenshot.desktop" > "autoscreenshot_tmp.desktop" install -m 644 "autoscreenshot_tmp.desktop" "$(ROOT)/usr/share/applications/autoscreenshot.desktop" - install -d -m 755 "$(ROOT)/usr/share/icons/hicolor/16x16/apps" - install -m 644 -T "res/main_icon_16px.png" "$(ROOT)/usr/share/icons/hicolor/16x16/apps/autoscreenshot.png" - install -d -m 755 "$(ROOT)/usr/share/icons/hicolor/24x24/apps" - install -m 644 -T "res/main_icon_24px.png" "$(ROOT)/usr/share/icons/hicolor/24x24/apps/autoscreenshot.png" - install -d -m 755 "$(ROOT)/usr/share/icons/hicolor/32x32/apps" - install -m 644 -T "res/main_icon_32px.png" "$(ROOT)/usr/share/icons/hicolor/32x32/apps/autoscreenshot.png" - install -d -m 755 "$(ROOT)/usr/share/icons/hicolor/48x48/apps" - install -m 644 -T "res/main_icon_48px.png" "$(ROOT)/usr/share/icons/hicolor/48x48/apps/autoscreenshot.png" - install -d -m 755 "$(ROOT)/usr/share/icons/hicolor/64x64/apps" - install -m 644 -T "res/main_icon_64px.png" "$(ROOT)/usr/share/icons/hicolor/64x64/apps/autoscreenshot.png" + for size in $$(ls -1 res | egrep -o main_icon_[0-9]+px.png | egrep -o [0-9]+); do \ + install -d -m 755 "$(ROOT)/usr/share/icons/hicolor/$${size}x$${size}/apps"; \ + install -m 644 -T "res/main_icon_$${size}px.png" "$(ROOT)/usr/share/icons/hicolor/$${size}x$${size}/apps/autoscreenshot.png"; \ + done %: dh $@ From 6dd59555cd65855d12480d6fdb650a378cd60a1c Mon Sep 17 00:00:00 2001 From: artem78 Date: Tue, 18 Jul 2023 15:05:37 +0300 Subject: [PATCH 12/38] [Linux] Add ppa to DEB-package --- AutoScreenshot.lpi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutoScreenshot.lpi b/AutoScreenshot.lpi index 390fea4..6cd673b 100644 --- a/AutoScreenshot.lpi +++ b/AutoScreenshot.lpi @@ -49,7 +49,7 @@ - + +?CP? *.desktop ?TEMPFOLDER?/ + +?CP? -rf debian ?TEMPFOLDER?/"/> diff --git a/debian/postrm b/debian/postrm new file mode 100755 index 0000000..1787377 --- /dev/null +++ b/debian/postrm @@ -0,0 +1,14 @@ +#!/bin/sh -e + +case "$1" in + purge) + for i in $(getent passwd | grep "$SHELL" | cut -d: -f6); do + rm -rf "$i/.config/AutoScreenshot"; + done + ;; + + *) + ;; +esac + +exit 0 From 09faf3ce32ade85a3a459d9168e8d2ff8f914c5d Mon Sep 17 00:00:00 2001 From: artem78 Date: Sat, 22 Jul 2023 14:43:32 +0300 Subject: [PATCH 14/38] Delete unused variable --- uAutoScreen.pas | 1 - 1 file changed, 1 deletion(-) diff --git a/uAutoScreen.pas b/uAutoScreen.pas index ddb32d1..62ec5e7 100755 --- a/uAutoScreen.pas +++ b/uAutoScreen.pas @@ -600,7 +600,6 @@ procedure TMainForm.FormShow(Sender: TObject); procedure TMainForm.HotKetsSettingsMenuItemClick(Sender: TObject); var HotKeysForm: THotKeysForm; - HasErrors: Boolean = False; begin // ToDo: Reduce amount of code duplicates From 5b7d47ef928e3bd5268d4cd23bb67e1cf852f930 Mon Sep 17 00:00:00 2001 From: artem78 Date: Thu, 3 Aug 2023 12:37:21 +0300 Subject: [PATCH 15/38] Fix missed bracket after commit a4f3dbb8 --- uLocalization.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uLocalization.pas b/uLocalization.pas index b211af4..08fc898 100644 --- a/uLocalization.pas +++ b/uLocalization.pas @@ -254,7 +254,7 @@ procedure TLocalizer.LoadFromFile(AFileName: String); initialization begin {$IfDef Windows} - LangDir := AppendPathDelim(ConcatPaths([ProgramDirectory, 'lang']); + LangDir := AppendPathDelim(ConcatPaths([ProgramDirectory, 'lang'])); {$EndIf} {$IfDef Linux} if IsPortable then From f38316a94b4fa7010206238a38e61d7d7f1da315 Mon Sep 17 00:00:00 2001 From: artem78 Date: Wed, 23 Aug 2023 08:24:57 +0300 Subject: [PATCH 16/38] Fix submodule url --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index a90a550..b01eb45 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "libs/Cross.Codebot"] path = libs/Cross.Codebot - url = ../../sysrpl/Cross.Codebot.git + url = git@github.com:artem78/Cross.Codebot.git From 3923f17ce5649b1fdfd1ed5806ab9094786e8a2f Mon Sep 17 00:00:00 2001 From: artem78 Date: Sun, 27 Aug 2023 13:41:57 +0300 Subject: [PATCH 17/38] Make UI for old screenshot removing feature --- uAutoScreen.lfm | 69 +++++++++++++++++++++++---- uAutoScreen.pas | 122 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 181 insertions(+), 10 deletions(-) diff --git a/uAutoScreen.lfm b/uAutoScreen.lfm index b77cd4c..62ef809 100755 --- a/uAutoScreen.lfm +++ b/uAutoScreen.lfm @@ -1,8 +1,8 @@ object MainForm: TMainForm Left = 278 - Height = 524 + Height = 675 Top = 153 - Width = 656 + Width = 723 AutoSize = True BorderIcons = [biSystemMenu, biMinimize] BorderStyle = bsSingle @@ -11,8 +11,8 @@ object MainForm: TMainForm ChildSizing.TopBottomSpacing = 15 ChildSizing.HorizontalSpacing = 6 ChildSizing.VerticalSpacing = 6 - ClientHeight = 502 - ClientWidth = 656 + ClientHeight = 653 + ClientWidth = 723 Menu = MainMenu OnCreate = FormCreate OnDestroy = FormDestroy @@ -104,7 +104,7 @@ object MainForm: TMainForm AnchorSideBottom.Side = asrBottom Left = 40 Height = 28 - Top = 446 + Top = 510 Width = 107 Anchors = [akLeft, akBottom] AutoSize = True @@ -148,11 +148,11 @@ object MainForm: TMainForm object AutoCaptureControlGroup: TGroupBox AnchorSideLeft.Control = Owner AnchorSideLeft.Side = asrCenter - AnchorSideTop.Control = PostCmdEdit + AnchorSideTop.Control = OldScreenshotsRemovingGroupBox AnchorSideTop.Side = asrBottom - Left = 218 + Left = 251 Height = 57 - Top = 425 + Top = 489 Width = 220 AutoSize = True BorderSpacing.Top = 24 @@ -517,6 +517,59 @@ object MainForm: TMainForm TabOrder = 4 end end + object OldScreenshotsRemovingGroupBox: TGroupBox + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = PostCmdEdit + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + Left = 15 + Height = 58 + Top = 407 + Width = 693 + Anchors = [akTop, akLeft, akRight] + AutoSize = True + Caption = 'Delete old screenshots' + ChildSizing.LeftRightSpacing = 6 + ChildSizing.TopBottomSpacing = 6 + ChildSizing.HorizontalSpacing = 6 + ChildSizing.VerticalSpacing = 6 + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 999 + ClientHeight = 41 + ClientWidth = 691 + TabOrder = 15 + object EnableOldScreenshotsRemovingCheckBox: TCheckBox + Left = 6 + Height = 29 + Top = 6 + Width = 74 + Caption = 'Enabled' + OnChange = EnableOldScreenshotsRemovingCheckBoxChange + TabOrder = 0 + end + object OldScreenshotsRemovingPeriodValueSpinEdit: TSpinEdit + Left = 86 + Height = 29 + Top = 6 + Width = 50 + MaxValue = 999 + MinValue = 1 + OnChange = OldScreenshotsRemovingPeriodValueSpinEditChange + TabOrder = 1 + Value = 1 + end + object OldScreenshotsRemovingPeriodUnitComboBox: TComboBox + Left = 142 + Height = 29 + Top = 6 + Width = 100 + ItemHeight = 0 + OnChange = OldScreenshotsRemovingPeriodUnitComboBoxChange + Style = csDropDownList + TabOrder = 2 + end + end object Timer: TTimer Enabled = False OnTimer = TimerTimer diff --git a/uAutoScreen.pas b/uAutoScreen.pas index ddb32d1..7a9de62 100755 --- a/uAutoScreen.pas +++ b/uAutoScreen.pas @@ -20,11 +20,16 @@ interface type TTrayIconState = (tisDefault, tisBlackWhite, tisFlashAnimation); + TOldScreenshotsRemovingPeriodUnit = (osrpuHours, osrpuDays, osrpuWeeks, osrpuMonths); + { TMainForm } TMainForm = class(TForm) AutoCheckForUpdatesMenuItem: TMenuItem; + EnableOldScreenshotsRemovingCheckBox: TCheckBox; + OldScreenshotsRemovingPeriodUnitComboBox: TComboBox; CompressionLevelComboBox: TComboBox; + OldScreenshotsRemovingGroupBox: TGroupBox; HotKetsSettingsMenuItem: TMenuItem; CompressionLevelLabel: TLabel; ImageFormatOptionsPanel: TPanel; @@ -33,6 +38,7 @@ TMainForm = class(TForm) PostCmdEdit: TEdit; CheckForUpdatesMenuItem: TMenuItem; OutputDirEdit: TDirectoryEdit; + OldScreenshotsRemovingPeriodValueSpinEdit: TSpinEdit; Timer: TTimer; OutputDirLabel: TLabel; CaptureIntervalLabel: TLabel; @@ -82,11 +88,14 @@ TMainForm = class(TForm) procedure CheckForUpdatesMenuItemClick(Sender: TObject); procedure AutoCheckForUpdatesMenuItemClick(Sender: TObject); procedure CompressionLevelComboBoxChange(Sender: TObject); + procedure EnableOldScreenshotsRemovingCheckBoxChange(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormShow(Sender: TObject); procedure HotKetsSettingsMenuItemClick(Sender: TObject); procedure DonateMenuItemClick(Sender: TObject); + procedure OldScreenshotsRemovingPeriodUnitComboBoxChange(Sender: TObject); + procedure OldScreenshotsRemovingPeriodValueSpinEditChange(Sender: TObject); procedure OutputDirEditChange(Sender: TObject); procedure CaptureIntervalDateTimePickerChange(Sender: TObject); procedure PostCmdEditChange(Sender: TObject); @@ -199,6 +208,12 @@ TMainForm = class(TForm) procedure SetCompressionLevel(ALevel: Tcompressionlevel); function GetCompressionLevel: Tcompressionlevel; procedure UpdateFormAutoSize; + procedure SetOldScreenshotsRemovingEnabled(AValue: Boolean); + function GetOldScreenshotsRemovingEnabled: Boolean; + procedure SetOldScreenshotsRemovingPeriodValue(AValue: Integer {Cardinal}); + function GetOldScreenshotsRemovingPeriodValue: Integer {Cardinal}; + procedure SetOldScreenshotsRemovingPeriodUnit(AValue: TOldScreenshotsRemovingPeriodUnit); + function GetOldScreenshotsRemovingPeriodUnit: TOldScreenshotsRemovingPeriodUnit; procedure OnHotKeyEvent(const AHotKeyId: String); procedure OnDebugLnEvent(Sender: TObject; S: string; var Handled: Boolean); @@ -228,6 +243,13 @@ TMainForm = class(TForm) property PostCommand: String read GetPostCommand write SetPostCommand; property AutoCheckForUpdates: Boolean read GetAutoCheckForUpdates write SetAutoCheckForUpdates; property CompressionLevel: Tcompressionlevel read GetCompressionLevel write SetCompressionLevel; + property OldScreenshotsRemovingEnabled: Boolean read GetOldScreenshotsRemovingEnabled + write SetOldScreenshotsRemovingEnabled; + property OldScreenshotsRemovingPeriodValue: Integer read GetOldScreenshotsRemovingPeriodValue + write SetOldScreenshotsRemovingPeriodValue; + property OldScreenshotsRemovingPeriodUnit: TOldScreenshotsRemovingPeriodUnit + read GetOldScreenshotsRemovingPeriodUnit + write SetOldScreenshotsRemovingPeriodUnit; // Messages {$IfDef Windows} @@ -248,6 +270,8 @@ TMainForm = class(TForm) MinCounterDigits = 1; MaxCounterDigits = 10; UpdateCheckIntervalInSeconds = 3 * 24 * 60 * 60; // Every 3 days + MinOldScreenshotsRemovingPeriodValue = 1; + MaxOldScreenshotsRemovingPeriodValue = 999; var MainForm: TMainForm; @@ -255,8 +279,9 @@ TMainForm = class(TForm) implementation -uses uAbout, DateUtils, StrUtils, uUtils, Math, uFileNameTemplateHelpForm, - uIniHelper, UpdateChecker, FileUtil, LCLType, Idle, LazLogger; +uses uAbout, DateUtils, StrUtils, uUtils, Math, TypInfo, + uFileNameTemplateHelpForm, uIniHelper, UpdateChecker, FileUtil, LCLType, Idle, + LazLogger; {$R *.lfm} @@ -286,6 +311,16 @@ function MyGetApplicationName: String; Result := 'AutoScreenshot'; end; +function OldScreenshotsRemovingPeriodUnitToString(AValue: TOldScreenshotsRemovingPeriodUnit): String; +begin + Result := GetEnumName(TypeInfo(TOldScreenshotsRemovingPeriodUnit), Ord(AValue)); +end; + +function StringToOldScreenshotsRemovingPeriodUnit(AValue: String): TOldScreenshotsRemovingPeriodUnit; +begin + Result := TOldScreenshotsRemovingPeriodUnit(GetEnumValue(TypeInfo(TOldScreenshotsRemovingPeriodUnit),AValue)); +end; + procedure TMainForm.InitUI; var Fmt: TImageFormat; @@ -331,6 +366,21 @@ procedure TMainForm.InitUI; Append('%COMP' + PathDelim + '%USER' + PathDelim + 'screenshot %Y-%M-%D %H-%N-%S '); Append('screenshot %NUM'); end; + + with OldScreenshotsRemovingPeriodValueSpinEdit do + begin + MinValue := MinOldScreenshotsRemovingPeriodValue; + MaxValue := MaxOldScreenshotsRemovingPeriodValue; + end; + + with OldScreenshotsRemovingPeriodUnitComboBox.Items do + begin + Clear; + Append('Hours'); + Append('Days'); + Append('Weeks'); + Append('Months'); + end; end; procedure TMainForm.ReadSettings; @@ -345,6 +395,8 @@ procedure TMainForm.ReadSettings; DefaultCounterValue = MinCounterValue; DefaultCounterDigits = 6; DefaultCompressionLevel = cldefault; + DefaultOldScreenshotsRemovingPeriodValue = 1; + DefaultOldScreenshotsRemovingPeriodUnit = osrpuMonths; LogFileName = 'log.txt'; var @@ -465,6 +517,19 @@ procedure TMainForm.ReadSettings; // Compression level CompressionLevel := Tcompressionlevel(Ini.ReadInteger(DefaultConfigIniSection, 'Compression', Ord(DefaultCompressionLevel))); + + // Old screenshots removing + OldScreenshotsRemovingEnabled := Ini.ReadBool(DefaultConfigIniSection, + 'OldScreenshotsRemovingEnabled', False); + OldScreenshotsRemovingPeriodValue := Ini.ReadInteger(DefaultConfigIniSection, + 'OldScreenshotsRemovingPeriodValue', + DefaultOldScreenshotsRemovingPeriodValue); + OldScreenshotsRemovingPeriodUnit := StringToOldScreenshotsRemovingPeriodUnit( + Ini.ReadString(DefaultConfigIniSection, + 'OldScreenshotsRemovingPeriodUnit', + OldScreenshotsRemovingPeriodUnitToString(DefaultOldScreenshotsRemovingPeriodUnit) + ) + ); end; procedure TMainForm.FormCreate(Sender: TObject); @@ -576,6 +641,12 @@ procedure TMainForm.CompressionLevelComboBoxChange(Sender: TObject); CompressionLevel := Tcompressionlevel(CompressionLevelComboBox.ItemIndex); end; +procedure TMainForm.EnableOldScreenshotsRemovingCheckBoxChange(Sender: TObject); +begin + //Ini.WriteBool(DefaultConfigIniSection, 'OldScreenshotsRemovingEnabled', TCheckBox(Sender).Checked); + OldScreenshotsRemovingEnabled := TCheckBox(Sender).Checked; +end; + procedure TMainForm.FormDestroy(Sender: TObject); begin {$IfDef Linux} @@ -617,6 +688,18 @@ procedure TMainForm.DonateMenuItemClick(Sender: TObject); ShowMessage('PayPal: megabyte1024@yandex.com'); end; +procedure TMainForm.OldScreenshotsRemovingPeriodUnitComboBoxChange( + Sender: TObject); +begin + OldScreenshotsRemovingPeriodUnit := TOldScreenshotsRemovingPeriodUnit(TComboBox(Sender).ItemIndex); +end; + +procedure TMainForm.OldScreenshotsRemovingPeriodValueSpinEditChange( + Sender: TObject); +begin + OldScreenshotsRemovingPeriodValue := TSpinEdit(Sender).Value; +end; + procedure TMainForm.OutputDirEditChange(Sender: TObject); begin Ini.WriteString(DefaultConfigIniSection, 'OutputDir', OutputDirEdit.Text); @@ -1665,6 +1748,41 @@ procedure TMainForm.UpdateFormAutoSize; {$EndIf} end; +procedure TMainForm.SetOldScreenshotsRemovingEnabled(AValue: Boolean); +begin + EnableOldScreenshotsRemovingCheckBox.Checked := AValue; + Ini.WriteBool(DefaultConfigIniSection, 'OldScreenshotsRemovingEnabled', AValue); +end; + +function TMainForm.GetOldScreenshotsRemovingEnabled: Boolean; +begin + Result := EnableOldScreenshotsRemovingCheckBox.Checked; +end; + +procedure TMainForm.SetOldScreenshotsRemovingPeriodValue(AValue: Integer); +begin + OldScreenshotsRemovingPeriodValueSpinEdit.Value := AValue; + Ini.WriteInteger(DefaultConfigIniSection, 'OldScreenshotsRemovingPeriodValue', AValue); +end; + +function TMainForm.GetOldScreenshotsRemovingPeriodValue: Integer; +begin + Result := OldScreenshotsRemovingPeriodValueSpinEdit.Value; +end; + +procedure TMainForm.SetOldScreenshotsRemovingPeriodUnit( + AValue: TOldScreenshotsRemovingPeriodUnit); +begin + OldScreenshotsRemovingPeriodUnitComboBox.ItemIndex := Ord(AValue); + Ini.WriteString(DefaultConfigIniSection, 'OldScreenshotsRemovingPeriodUnit', + OldScreenshotsRemovingPeriodUnitToString(AValue)); +end; + +function TMainForm.GetOldScreenshotsRemovingPeriodUnit: TOldScreenshotsRemovingPeriodUnit; +begin + Result := TOldScreenshotsRemovingPeriodUnit(OldScreenshotsRemovingPeriodUnitComboBox.ItemIndex); +end; + procedure TMainForm.OnHotKeyEvent(const AHotKeyId: String); begin case AHotKeyId of From 3de6c89e2dac55e171a13aaa4daa77df7b28669a Mon Sep 17 00:00:00 2001 From: artem78 Date: Sun, 27 Aug 2023 20:57:57 +0300 Subject: [PATCH 18/38] Write enum value to ini without prefix --- uAutoScreen.pas | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/uAutoScreen.pas b/uAutoScreen.pas index 7a9de62..c65b479 100755 --- a/uAutoScreen.pas +++ b/uAutoScreen.pas @@ -314,11 +314,13 @@ function MyGetApplicationName: String; function OldScreenshotsRemovingPeriodUnitToString(AValue: TOldScreenshotsRemovingPeriodUnit): String; begin Result := GetEnumName(TypeInfo(TOldScreenshotsRemovingPeriodUnit), Ord(AValue)); + if Result.StartsWith('osrpu') then + Result := Result.Remove(0, 5); end; function StringToOldScreenshotsRemovingPeriodUnit(AValue: String): TOldScreenshotsRemovingPeriodUnit; begin - Result := TOldScreenshotsRemovingPeriodUnit(GetEnumValue(TypeInfo(TOldScreenshotsRemovingPeriodUnit),AValue)); + Result := TOldScreenshotsRemovingPeriodUnit(GetEnumValue(TypeInfo(TOldScreenshotsRemovingPeriodUnit), 'osrpu' + AValue)); end; procedure TMainForm.InitUI; From 00b5c2e82e44b6cdaa39d32a6688df0a0f36fe52 Mon Sep 17 00:00:00 2001 From: artem78 Date: Thu, 3 Aug 2023 11:28:53 +0300 Subject: [PATCH 19/38] [Build] Add files to zip in subfolder --- MakeInstallerAndZip.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/MakeInstallerAndZip.sh b/MakeInstallerAndZip.sh index 3cebcab..fa6e6ae 100755 --- a/MakeInstallerAndZip.sh +++ b/MakeInstallerAndZip.sh @@ -85,6 +85,12 @@ function MakeZip(){ cp -v --preserve=timestamps lang/*.ini "$BuildDir/lang/" echo "Done!" echo "" + + # Move files to subfolder + TmpDir=$(mktemp -d --suffix "-AutoScreenshotBuild") + echo "TmpDir=${TmpDir}" + #mkdir -p "$TmpDir/AutoScreenshot_${ProgramVersion}" + cp -R --preserve=timestamps "$BuildDir" "$TmpDir/AutoScreenshot_${ProgramVersion}" # Pack to ZIP archive ### Note! For MinGW (Git Bash) see https://stackoverflow.com/a/55749636 ### @@ -96,11 +102,13 @@ function MakeZip(){ fi ZipPath="$TargetZipDir/AutoScreenshot_${ProgramVersion}_${OsTypeName}_portable.zip" rm -f "$ZipPath" - cd "$BuildDir" + cd "$TmpDir" zip -r "$ZipPath" * #tar -C "$BuildDir" -cvf "$ZipPath" "$BuildDir/*" echo "Done!" echo "" + + rm -rf "$TmpDir" } function MakeInstaller(){ From 533d5377460b5fa1189acd5786729d7f3e633aa4 Mon Sep 17 00:00:00 2001 From: artem78 Date: Wed, 2 Aug 2023 16:17:37 +0300 Subject: [PATCH 20/38] Create donate window --- AutoScreenshot.lpi | 10 ++++- lang/en.ini | 3 ++ lang/ru.ini | 3 ++ uAutoScreen.pas | 11 ++++- udonateform.lfm | 18 ++++++++ udonateform.pas | 106 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 udonateform.lfm create mode 100644 udonateform.pas diff --git a/AutoScreenshot.lpi b/AutoScreenshot.lpi index ae923df..be6e58e 100644 --- a/AutoScreenshot.lpi +++ b/AutoScreenshot.lpi @@ -319,7 +319,7 @@ override_dh_auto_install: - + @@ -412,6 +412,14 @@ override_dh_auto_install: + + + + + + + + diff --git a/lang/en.ini b/lang/en.ini index 6d34728..c22f896 100644 --- a/lang/en.ini +++ b/lang/en.ini @@ -82,6 +82,9 @@ SingleCapture=Single screenshot NoHotKey=(None) HotKeyOccupied=Hotkey already in use! +; === Donate window === +Copy=Copy + ; === General ==== Yes=Yes No=No diff --git a/lang/ru.ini b/lang/ru.ini index eaf0b45..d67801d 100644 --- a/lang/ru.ini +++ b/lang/ru.ini @@ -83,6 +83,9 @@ SingleCapture=Сделать один скриншот NoHotKey=(Не выбрано) HotKeyOccupied=Горячая клавиша уже используется! +; === Donate window === +Copy=Cкопировать + ; === General ==== Yes=Да No=Нет diff --git a/uAutoScreen.pas b/uAutoScreen.pas index ddb32d1..6881c43 100755 --- a/uAutoScreen.pas +++ b/uAutoScreen.pas @@ -256,7 +256,7 @@ TMainForm = class(TForm) implementation uses uAbout, DateUtils, StrUtils, uUtils, Math, uFileNameTemplateHelpForm, - uIniHelper, UpdateChecker, FileUtil, LCLType, Idle, LazLogger; + uIniHelper, UpdateChecker, FileUtil, LCLType, Idle, uDonateForm, LazLogger; {$R *.lfm} @@ -614,7 +614,14 @@ procedure TMainForm.HotKetsSettingsMenuItemClick(Sender: TObject); procedure TMainForm.DonateMenuItemClick(Sender: TObject); begin - ShowMessage('PayPal: megabyte1024@yandex.com'); + with TDonateForm.Create(Self) do + begin + try + ShowModal; + finally + Free; + end; + end; end; procedure TMainForm.OutputDirEditChange(Sender: TObject); diff --git a/udonateform.lfm b/udonateform.lfm new file mode 100644 index 0000000..2878538 --- /dev/null +++ b/udonateform.lfm @@ -0,0 +1,18 @@ +object DonateForm: TDonateForm + Left = 260 + Height = 240 + Top = 250 + Width = 320 + AutoSize = True + BorderStyle = bsDialog + Caption = 'DonateForm' + ChildSizing.LeftRightSpacing = 15 + ChildSizing.TopBottomSpacing = 15 + ChildSizing.HorizontalSpacing = 6 + ChildSizing.VerticalSpacing = 6 + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 3 + OnCreate = FormCreate + Position = poOwnerFormCenter + LCLVersion = '2.2.4.0' +end diff --git a/udonateform.pas b/udonateform.pas new file mode 100644 index 0000000..ddda720 --- /dev/null +++ b/udonateform.pas @@ -0,0 +1,106 @@ +unit uDonateForm; + +{$mode ObjFPC}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs; + +type + + { TDonateForm } + + TDonateForm = class(TForm) + procedure FormCreate(Sender: TObject); + private + procedure CopyWalletToClipboard(ASender: TObject); + public + + end; + +var + DonateForm: TDonateForm; + +implementation + +uses StdCtrls, Clipbrd, uLocalization; + +{$R *.lfm} + +{ TDonateForm } + +procedure TDonateForm.FormCreate(Sender: TObject); +var + Wallets: TStringList; + I: Integer; +begin + Caption := Localizer.I18N('Donate'); + + Wallets := TStringList.Create; + try + with Wallets do + begin; + AddPair('PayPal', 'megabyte1024@yandex.com'); + AddPair('ETH Ethereum / Tether USDT', '0xB14C877b2eAF7E3b4b49df25039122C0545edA74'); + AddPair('Webmoney WMZ', 'Z598881055273'); + end; + + for I := 0 to Wallets.Count - 1 do + begin + with TLabel.Create(Self) do + begin + Caption := Wallets.Names[I] + ':'; + BorderSpacing.CellAlignVertical := ccaCenter; + BorderSpacing.CellAlignHorizontal := ccaRightBottom; + Parent := Self; + end; + + with TEdit.Create(Self) do + begin + Width := 300; + Constraints.MinWidth := Width; + Text := Wallets.ValueFromIndex[I]; + ReadOnly := True; + BorderSpacing.CellAlignVertical := ccaCenter; + Parent := Self; + end; + + with TButton.Create(Self) do + begin + Caption := Localizer.I18N('Copy'); + OnClick := @CopyWalletToClipboard; + BorderSpacing.CellAlignVertical := ccaCenter; + Parent := Self; + end; + end; + finally + Wallets.Free; + end; +end; + +procedure TDonateForm.CopyWalletToClipboard(ASender: TObject); + function FindPrevComponent(AComponent: TComponent): TComponent; + begin + if not AComponent.HasParent then + Result := Nil + else + begin + if AComponent.ComponentIndex > 0 then + Result := AComponent.GetParentComponent.Components[AComponent.ComponentIndex - 1] + else + Result := Nil; + end; + end; + +var + Component: TEdit; +begin + Component := TEdit(FindPrevComponent(TComponent(ASender))); + //Component.SelectAll; + //Component.CopyToClipboard; + Clipboard.AsText := Component.Text; +end; + +end. + From 81894068a5cdd3e7a07bd0f64681e7be1bb8f5b4 Mon Sep 17 00:00:00 2001 From: artem78 Date: Wed, 2 Aug 2023 17:42:35 +0300 Subject: [PATCH 21/38] Load wallets for donation from URL --- udonateform.pas | 61 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/udonateform.pas b/udonateform.pas index ddda720..ee4aff8 100644 --- a/udonateform.pas +++ b/udonateform.pas @@ -15,6 +15,7 @@ TDonateForm = class(TForm) procedure FormCreate(Sender: TObject); private procedure CopyWalletToClipboard(ASender: TObject); + class procedure LoadWalletsData(ASL: TStringList); static; public end; @@ -24,7 +25,7 @@ TDonateForm = class(TForm) implementation -uses StdCtrls, Clipbrd, uLocalization; +uses StdCtrls, Clipbrd, uLocalization, fpjson, opensslsockets, fphttpclient; {$R *.lfm} @@ -39,12 +40,7 @@ procedure TDonateForm.FormCreate(Sender: TObject); Wallets := TStringList.Create; try - with Wallets do - begin; - AddPair('PayPal', 'megabyte1024@yandex.com'); - AddPair('ETH Ethereum / Tether USDT', '0xB14C877b2eAF7E3b4b49df25039122C0545edA74'); - AddPair('Webmoney WMZ', 'Z598881055273'); - end; + LoadWalletsData(Wallets); for I := 0 to Wallets.Count - 1 do begin @@ -97,10 +93,57 @@ procedure TDonateForm.CopyWalletToClipboard(ASender: TObject); Component: TEdit; begin Component := TEdit(FindPrevComponent(TComponent(ASender))); - //Component.SelectAll; - //Component.CopyToClipboard; Clipboard.AsText := Component.Text; end; +class procedure TDonateForm.LoadWalletsData(ASL: TStringList); +const + ApiUrl = 'https://api.github.com/gists/6c79ab382865da9b598927194c52eb09'; +var + Http: TFPHTTPClient; + Json: TJSONData; + Str: String; + Enumerator: TBaseJSONEnumerator; + PaymentMethod, WalletID: String; +begin + ASL.Clear; + + Http := TFPHttpClient.Create(Nil); + try + Http.AllowRedirect := True; + Http.AddHeader('Accept', 'application/vnd.github+json'); + Http.AddHeader('User-Agent', 'Auto Screenshot'); + Json := GetJSON(Http.Get(ApiUrl)); + try + Str := TJSONObject(Json).Objects['files'].Objects['donate_wallets.json'].Strings['content']; + finally + Json.Free; + end; + + Json := GetJSON(Str); + try + Enumerator := TJSONObject(Json).GetEnumerator; + try + while Enumerator.MoveNext do + begin + with TJSONArray(Enumerator.Current.Value) do + begin + PaymentMethod := Items[0].AsString; + WalletID := Items[1].AsString; + end; + ASL.AddPair(PaymentMethod, WalletID); + end; + finally + Enumerator.Free; + end; + finally + Json.Free; + end; + + finally + Http.Free; + end; +end; + end. From 6a6a80a7315e12ecf73b0e2a4c35b042fd15b75c Mon Sep 17 00:00:00 2001 From: artem78 Date: Thu, 31 Aug 2023 09:57:30 +0300 Subject: [PATCH 22/38] Open donate web page as fallback if loading wallets data was failed --- udonateform.lfm | 1 + udonateform.pas | 87 ++++++++++++++++++++++++++++++++++--------------- 2 files changed, 61 insertions(+), 27 deletions(-) diff --git a/udonateform.lfm b/udonateform.lfm index 2878538..7ce4afa 100644 --- a/udonateform.lfm +++ b/udonateform.lfm @@ -13,6 +13,7 @@ object DonateForm: TDonateForm ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.ControlsPerLine = 3 OnCreate = FormCreate + OnShow = FormShow Position = poOwnerFormCenter LCLVersion = '2.2.4.0' end diff --git a/udonateform.pas b/udonateform.pas index ee4aff8..d18028f 100644 --- a/udonateform.pas +++ b/udonateform.pas @@ -13,9 +13,11 @@ interface TDonateForm = class(TForm) procedure FormCreate(Sender: TObject); + procedure FormShow(Sender: TObject); private procedure CopyWalletToClipboard(ASender: TObject); class procedure LoadWalletsData(ASL: TStringList); static; + class procedure OpenWebPage; static; public end; @@ -25,7 +27,8 @@ TDonateForm = class(TForm) implementation -uses StdCtrls, Clipbrd, uLocalization, fpjson, opensslsockets, fphttpclient; +uses StdCtrls, Clipbrd, LCLIntf, uLocalization, fpjson, opensslsockets, + fphttpclient; {$R *.lfm} @@ -40,41 +43,55 @@ procedure TDonateForm.FormCreate(Sender: TObject); Wallets := TStringList.Create; try - LoadWalletsData(Wallets); + try + LoadWalletsData(Wallets); - for I := 0 to Wallets.Count - 1 do - begin - with TLabel.Create(Self) do + for I := 0 to Wallets.Count - 1 do begin - Caption := Wallets.Names[I] + ':'; - BorderSpacing.CellAlignVertical := ccaCenter; - BorderSpacing.CellAlignHorizontal := ccaRightBottom; - Parent := Self; - end; + with TLabel.Create(Self) do + begin + Caption := Wallets.Names[I] + ':'; + BorderSpacing.CellAlignVertical := ccaCenter; + BorderSpacing.CellAlignHorizontal := ccaRightBottom; + Parent := Self; + end; - with TEdit.Create(Self) do - begin - Width := 300; - Constraints.MinWidth := Width; - Text := Wallets.ValueFromIndex[I]; - ReadOnly := True; - BorderSpacing.CellAlignVertical := ccaCenter; - Parent := Self; - end; + with TEdit.Create(Self) do + begin + Width := 300; + Constraints.MinWidth := Width; + Text := Wallets.ValueFromIndex[I]; + ReadOnly := True; + BorderSpacing.CellAlignVertical := ccaCenter; + Parent := Self; + end; - with TButton.Create(Self) do - begin - Caption := Localizer.I18N('Copy'); - OnClick := @CopyWalletToClipboard; - BorderSpacing.CellAlignVertical := ccaCenter; - Parent := Self; + with TButton.Create(Self) do + begin + Caption := Localizer.I18N('Copy'); + OnClick := @CopyWalletToClipboard; + BorderSpacing.CellAlignVertical := ccaCenter; + Parent := Self; + end; end; + finally + Wallets.Free; end; - finally - Wallets.Free; + except + // No action needed there end; end; +procedure TDonateForm.FormShow(Sender: TObject); +begin + if ComponentCount = 0 then + begin + // Open Donate url in web browser as fallback if something goes wrong + OpenWebPage; + Close; + end +end; + procedure TDonateForm.CopyWalletToClipboard(ASender: TObject); function FindPrevComponent(AComponent: TComponent): TComponent; begin @@ -145,5 +162,21 @@ class procedure TDonateForm.LoadWalletsData(ASL: TStringList); end; end; +class procedure TDonateForm.OpenWebPage; +var + Url: String; +begin + case Localizer.LanguageInfo.Code of + 'fr': + Url := 'https://github.com/artem78/AutoScreenshot/blob/master/docs/README-fr.md#faire-un-don'; + 'ru', 'uk': + Url := 'https://github.com/artem78/AutoScreenshot/blob/master/docs/README-ru.md#%D0%B2%D0%BE%D0%B7%D0%BD%D0%B0%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D1%82%D1%8C-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B0-%D0%BC%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE'; + else + Url := 'https://github.com/artem78/AutoScreenshot/tree/master#donate'; + end; + + OpenURL(Url); +end; + end. From 4f534a267d40e5b768cf7f0457472979227333fe Mon Sep 17 00:00:00 2001 From: artem78 Date: Thu, 31 Aug 2023 14:06:58 +0300 Subject: [PATCH 23/38] Refactoring --- AutoScreenshot.lpi | 7 ++- oldscreenshotcleaner.pas | 82 ++++++++++++++++++++++++++ uAutoScreen.pas | 123 +++++++++++++++------------------------ 3 files changed, 134 insertions(+), 78 deletions(-) create mode 100644 oldscreenshotcleaner.pas diff --git a/AutoScreenshot.lpi b/AutoScreenshot.lpi index 09a5cdc..e17dcda 100644 --- a/AutoScreenshot.lpi +++ b/AutoScreenshot.lpi @@ -226,7 +226,7 @@ - + @@ -319,6 +319,11 @@ + + + + + diff --git a/oldscreenshotcleaner.pas b/oldscreenshotcleaner.pas new file mode 100644 index 0000000..6eb0911 --- /dev/null +++ b/oldscreenshotcleaner.pas @@ -0,0 +1,82 @@ +unit OldScreenshotCleaner; + +{$mode ObjFPC}{$H+} + +interface + +uses + Classes, SysUtils; + +type + TIntervalUnit = (iuHours, iuDays, iuWeeks, iuMonths); + + TInterval = record + Val: Cardinal; + Unit_: TIntervalUnit; + end; + + TOldScreenshotCleanerChangeCallback = procedure of object; + + { TOldScreenshotCleaner } + + TOldScreenshotCleaner = class + private + FInterval: TInterval; + FActive: Boolean; + FOnChangeCallback: TOldScreenshotCleanerChangeCallback; + + procedure SetInterval(AInterval: TInterval); + procedure SetActive(AActive: Boolean); + public + + property Interval: TInterval read FInterval write SetInterval; + property Active: Boolean read FActive write SetActive; + property OnChangeCallback: TOldScreenshotCleanerChangeCallback + read FOnChangeCallback write FOnChangeCallback; + end; + + function IntervalUnitToString(AValue: TIntervalUnit): String; + function StringToIntervalUnit(AValue: String): TIntervalUnit; + +implementation + +uses TypInfo; + +function IntervalUnitToString(AValue: TIntervalUnit): String; +begin + Result := GetEnumName(TypeInfo(TIntervalUnit), Ord(AValue)); + if Result.StartsWith('iu') then + Result := Result.Remove(0, 2); +end; + +function StringToIntervalUnit(AValue: String): TIntervalUnit; +begin + Result := TIntervalUnit(GetEnumValue(TypeInfo(TIntervalUnit), 'iu' + AValue)); +end; + +{ TOldScreenshotCleaner } + +procedure TOldScreenshotCleaner.SetInterval(AInterval: TInterval); +begin + //if (FInterval.Unit_ = AInterval.Unit_) and (FInterval.Val = AInterval.Val) then + // Exit; + + FInterval := AInterval; + + if Assigned(FOnChangeCallback) then + FOnChangeCallback; +end; + +procedure TOldScreenshotCleaner.SetActive(AActive: Boolean); +begin + //if FActive = AActive then + // Exit; + + FActive := AActive; + + if Assigned(FOnChangeCallback) then + FOnChangeCallback; +end; + +end. + diff --git a/uAutoScreen.pas b/uAutoScreen.pas index c65b479..74f0b7f 100755 --- a/uAutoScreen.pas +++ b/uAutoScreen.pas @@ -14,14 +14,12 @@ interface {Messages,} SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, {ComCtrls,} ExtCtrls, StdCtrls, inifiles, Spin, {FileCtrl,} Menus, Buttons, EditBtn, uLocalization, DateTimePicker, LCLIntf, - ScreenGrabber, uHotKeysForm, uUtilsMore, GlobalKeyHook, UniqueInstance, - ZStream { for Tcompressionlevel }; + ScreenGrabber, uHotKeysForm, uUtilsMore, GlobalKeyHook, OldScreenshotCleaner, + UniqueInstance, ZStream { for Tcompressionlevel }; type TTrayIconState = (tisDefault, tisBlackWhite, tisFlashAnimation); - TOldScreenshotsRemovingPeriodUnit = (osrpuHours, osrpuDays, osrpuWeeks, osrpuMonths); - { TMainForm } TMainForm = class(TForm) @@ -155,6 +153,7 @@ TMainForm = class(TForm) FGrayscale: Boolean; KeyHook: TGlobalKeyHook; + OldScreenshotCleaner: TOldScreenshotCleaner; { Methods } procedure SetTimerEnabled(AEnabled: Boolean); @@ -208,16 +207,11 @@ TMainForm = class(TForm) procedure SetCompressionLevel(ALevel: Tcompressionlevel); function GetCompressionLevel: Tcompressionlevel; procedure UpdateFormAutoSize; - procedure SetOldScreenshotsRemovingEnabled(AValue: Boolean); - function GetOldScreenshotsRemovingEnabled: Boolean; - procedure SetOldScreenshotsRemovingPeriodValue(AValue: Integer {Cardinal}); - function GetOldScreenshotsRemovingPeriodValue: Integer {Cardinal}; - procedure SetOldScreenshotsRemovingPeriodUnit(AValue: TOldScreenshotsRemovingPeriodUnit); - function GetOldScreenshotsRemovingPeriodUnit: TOldScreenshotsRemovingPeriodUnit; procedure OnHotKeyEvent(const AHotKeyId: String); procedure OnDebugLnEvent(Sender: TObject; S: string; var Handled: Boolean); function OnHotKeysSaving(ASender: TObject; out AErrorMsg: string): Boolean; + procedure OnScreenshotCleanerChanged; {$IfDef Linux} procedure OnScreenConfigurationChanged(const AEvent: TXEvent); @@ -243,13 +237,6 @@ TMainForm = class(TForm) property PostCommand: String read GetPostCommand write SetPostCommand; property AutoCheckForUpdates: Boolean read GetAutoCheckForUpdates write SetAutoCheckForUpdates; property CompressionLevel: Tcompressionlevel read GetCompressionLevel write SetCompressionLevel; - property OldScreenshotsRemovingEnabled: Boolean read GetOldScreenshotsRemovingEnabled - write SetOldScreenshotsRemovingEnabled; - property OldScreenshotsRemovingPeriodValue: Integer read GetOldScreenshotsRemovingPeriodValue - write SetOldScreenshotsRemovingPeriodValue; - property OldScreenshotsRemovingPeriodUnit: TOldScreenshotsRemovingPeriodUnit - read GetOldScreenshotsRemovingPeriodUnit - write SetOldScreenshotsRemovingPeriodUnit; // Messages {$IfDef Windows} @@ -279,7 +266,7 @@ TMainForm = class(TForm) implementation -uses uAbout, DateUtils, StrUtils, uUtils, Math, TypInfo, +uses uAbout, DateUtils, StrUtils, uUtils, Math, uFileNameTemplateHelpForm, uIniHelper, UpdateChecker, FileUtil, LCLType, Idle, LazLogger; @@ -311,18 +298,6 @@ function MyGetApplicationName: String; Result := 'AutoScreenshot'; end; -function OldScreenshotsRemovingPeriodUnitToString(AValue: TOldScreenshotsRemovingPeriodUnit): String; -begin - Result := GetEnumName(TypeInfo(TOldScreenshotsRemovingPeriodUnit), Ord(AValue)); - if Result.StartsWith('osrpu') then - Result := Result.Remove(0, 5); -end; - -function StringToOldScreenshotsRemovingPeriodUnit(AValue: String): TOldScreenshotsRemovingPeriodUnit; -begin - Result := TOldScreenshotsRemovingPeriodUnit(GetEnumValue(TypeInfo(TOldScreenshotsRemovingPeriodUnit), 'osrpu' + AValue)); -end; - procedure TMainForm.InitUI; var Fmt: TImageFormat; @@ -397,8 +372,10 @@ procedure TMainForm.ReadSettings; DefaultCounterValue = MinCounterValue; DefaultCounterDigits = 6; DefaultCompressionLevel = cldefault; - DefaultOldScreenshotsRemovingPeriodValue = 1; - DefaultOldScreenshotsRemovingPeriodUnit = osrpuMonths; + DefaultScreenshotCleanerInterval: TInterval = ( + Val: 1; + Unit_: iuMonths + ); LogFileName = 'log.txt'; var @@ -407,6 +384,8 @@ procedure TMainForm.ReadSettings; FmtStr: String; Seconds: Integer; LogFilePath: String; + Interval: TInterval; + CleanerActive: Boolean; begin // Logging if Ini.ReadBool(DefaultConfigIniSection, 'Logging', False) then @@ -521,17 +500,19 @@ procedure TMainForm.ReadSettings; CompressionLevel := Tcompressionlevel(Ini.ReadInteger(DefaultConfigIniSection, 'Compression', Ord(DefaultCompressionLevel))); // Old screenshots removing - OldScreenshotsRemovingEnabled := Ini.ReadBool(DefaultConfigIniSection, + CleanerActive := Ini.ReadBool(DefaultConfigIniSection, 'OldScreenshotsRemovingEnabled', False); - OldScreenshotsRemovingPeriodValue := Ini.ReadInteger(DefaultConfigIniSection, + Interval.Val := Ini.ReadInteger(DefaultConfigIniSection, 'OldScreenshotsRemovingPeriodValue', - DefaultOldScreenshotsRemovingPeriodValue); - OldScreenshotsRemovingPeriodUnit := StringToOldScreenshotsRemovingPeriodUnit( + DefaultScreenshotCleanerInterval.Val); + Interval.Unit_ := StringToIntervalUnit( Ini.ReadString(DefaultConfigIniSection, 'OldScreenshotsRemovingPeriodUnit', - OldScreenshotsRemovingPeriodUnitToString(DefaultOldScreenshotsRemovingPeriodUnit) + IntervalUnitToString(DefaultScreenshotCleanerInterval.Unit_) ) ); + OldScreenshotCleaner.Interval := Interval; + OldScreenshotCleaner.Active := CleanerActive; end; procedure TMainForm.FormCreate(Sender: TObject); @@ -570,6 +551,10 @@ procedure TMainForm.FormCreate(Sender: TObject); IniFileName := ConcatPaths([GetAppConfigDir(False), 'config.ini']); Ini := TIniFile.Create(IniFileName); Ini.WriteString(DefaultConfigIniSection, 'ProgramVersion', GetProgramVersionStr); + + OldScreenshotCleaner := TOldScreenshotCleaner.Create; + OldScreenshotCleaner.OnChangeCallback := @OnScreenshotCleanerChanged; + ReadSettings; DebugLn('Program started at ', DateTimeToStr(Now)); @@ -645,8 +630,7 @@ procedure TMainForm.CompressionLevelComboBoxChange(Sender: TObject); procedure TMainForm.EnableOldScreenshotsRemovingCheckBoxChange(Sender: TObject); begin - //Ini.WriteBool(DefaultConfigIniSection, 'OldScreenshotsRemovingEnabled', TCheckBox(Sender).Checked); - OldScreenshotsRemovingEnabled := TCheckBox(Sender).Checked; + OldScreenshotCleaner.Active := TCheckBox(Sender).Checked; end; procedure TMainForm.FormDestroy(Sender: TObject); @@ -659,7 +643,7 @@ procedure TMainForm.FormDestroy(Sender: TObject); Grabber.Free; KeyHook.Free; - + OldScreenshotCleaner.Free; Ini.Free; DebugLn('Program ended'); @@ -692,14 +676,22 @@ procedure TMainForm.DonateMenuItemClick(Sender: TObject); procedure TMainForm.OldScreenshotsRemovingPeriodUnitComboBoxChange( Sender: TObject); +var + Interval: TInterval; begin - OldScreenshotsRemovingPeriodUnit := TOldScreenshotsRemovingPeriodUnit(TComboBox(Sender).ItemIndex); + Interval := OldScreenshotCleaner.Interval; + Interval.Unit_:= TIntervalUnit(TComboBox(Sender).ItemIndex); + OldScreenshotCleaner.Interval := Interval; end; procedure TMainForm.OldScreenshotsRemovingPeriodValueSpinEditChange( Sender: TObject); +var + Interval: TInterval; begin - OldScreenshotsRemovingPeriodValue := TSpinEdit(Sender).Value; + Interval := OldScreenshotCleaner.Interval; + Interval.Val := TSpinEdit(Sender).Value; + OldScreenshotCleaner.Interval := Interval; end; procedure TMainForm.OutputDirEditChange(Sender: TObject); @@ -1750,41 +1742,6 @@ procedure TMainForm.UpdateFormAutoSize; {$EndIf} end; -procedure TMainForm.SetOldScreenshotsRemovingEnabled(AValue: Boolean); -begin - EnableOldScreenshotsRemovingCheckBox.Checked := AValue; - Ini.WriteBool(DefaultConfigIniSection, 'OldScreenshotsRemovingEnabled', AValue); -end; - -function TMainForm.GetOldScreenshotsRemovingEnabled: Boolean; -begin - Result := EnableOldScreenshotsRemovingCheckBox.Checked; -end; - -procedure TMainForm.SetOldScreenshotsRemovingPeriodValue(AValue: Integer); -begin - OldScreenshotsRemovingPeriodValueSpinEdit.Value := AValue; - Ini.WriteInteger(DefaultConfigIniSection, 'OldScreenshotsRemovingPeriodValue', AValue); -end; - -function TMainForm.GetOldScreenshotsRemovingPeriodValue: Integer; -begin - Result := OldScreenshotsRemovingPeriodValueSpinEdit.Value; -end; - -procedure TMainForm.SetOldScreenshotsRemovingPeriodUnit( - AValue: TOldScreenshotsRemovingPeriodUnit); -begin - OldScreenshotsRemovingPeriodUnitComboBox.ItemIndex := Ord(AValue); - Ini.WriteString(DefaultConfigIniSection, 'OldScreenshotsRemovingPeriodUnit', - OldScreenshotsRemovingPeriodUnitToString(AValue)); -end; - -function TMainForm.GetOldScreenshotsRemovingPeriodUnit: TOldScreenshotsRemovingPeriodUnit; -begin - Result := TOldScreenshotsRemovingPeriodUnit(OldScreenshotsRemovingPeriodUnitComboBox.ItemIndex); -end; - procedure TMainForm.OnHotKeyEvent(const AHotKeyId: String); begin case AHotKeyId of @@ -1852,6 +1809,18 @@ function TMainForm.OnHotKeysSaving(ASender: TObject; out AErrorMsg: string): Boo Result := not HasErrors; end; +procedure TMainForm.OnScreenshotCleanerChanged; +begin + EnableOldScreenshotsRemovingCheckBox.Checked := OldScreenshotCleaner.Active; + Ini.WriteBool(DefaultConfigIniSection, 'OldScreenshotsRemovingEnabled', OldScreenshotCleaner.Active); + + OldScreenshotsRemovingPeriodValueSpinEdit.Value := OldScreenshotCleaner.Interval.Val; + Ini.WriteInteger(DefaultConfigIniSection, 'OldScreenshotsRemovingPeriodValue', OldScreenshotCleaner.Interval.Val); + + OldScreenshotsRemovingPeriodUnitComboBox.ItemIndex := Ord(OldScreenshotCleaner.Interval.Unit_); + Ini.WriteString(DefaultConfigIniSection, 'OldScreenshotsRemovingPeriodUnit', IntervalUnitToString(OldScreenshotCleaner.Interval.Unit_)); +end; + {$IfDef Linux} procedure TMainForm.OnScreenConfigurationChanged(const AEvent: TXEvent); begin From 58d69e3741464f6b6f964a26bd7354bf342c6df0 Mon Sep 17 00:00:00 2001 From: artem78 Date: Fri, 1 Sep 2023 20:55:46 +0300 Subject: [PATCH 24/38] Combine two settings in one --- oldscreenshotcleaner.pas | 36 ++++++++++++++++++++++++++---------- uAutoScreen.pas | 20 +++++--------------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/oldscreenshotcleaner.pas b/oldscreenshotcleaner.pas index 6eb0911..d12cbe7 100644 --- a/oldscreenshotcleaner.pas +++ b/oldscreenshotcleaner.pas @@ -35,25 +35,41 @@ TOldScreenshotCleaner = class read FOnChangeCallback write FOnChangeCallback; end; - function IntervalUnitToString(AValue: TIntervalUnit): String; - function StringToIntervalUnit(AValue: String): TIntervalUnit; + operator explicit (const AInterval: TInterval): String; + operator explicit (const AStr: String): TInterval; implementation -uses TypInfo; - -function IntervalUnitToString(AValue: TIntervalUnit): String; +operator explicit (const AInterval: TInterval): String; +var + UnitShortName: Char; begin - Result := GetEnumName(TypeInfo(TIntervalUnit), Ord(AValue)); - if Result.StartsWith('iu') then - Result := Result.Remove(0, 2); + case AInterval.Unit_ of + iuHours: UnitShortName := 'h'; + iudays: UnitShortName := 'd'; + iuWeeks: UnitShortName := 'w'; + iuMonths: UnitShortName := 'm'; + end; + + Result := IntToStr(AInterval.Val) + UnitShortName; end; -function StringToIntervalUnit(AValue: String): TIntervalUnit; +operator explicit (const AStr: String): TInterval; +var + UnitShortName: Char; begin - Result := TIntervalUnit(GetEnumValue(TypeInfo(TIntervalUnit), 'iu' + AValue)); + UnitShortName := AStr[Length(AStr)]; + case UnitShortName of + 'h': Result.Unit_ := iuHours; + 'd': Result.Unit_ := iudays; + 'w': Result.Unit_ := iuWeeks; + 'm': Result.Unit_ := iuMonths; + else raise Exception.CreateFmt('Unknown unit character ''%s''', [UnitShortName]); + end; + Result.Val := StrToInt(Copy(AStr, 1, Length(AStr) - 1)); end; + { TOldScreenshotCleaner } procedure TOldScreenshotCleaner.SetInterval(AInterval: TInterval); diff --git a/uAutoScreen.pas b/uAutoScreen.pas index 74f0b7f..be6cbed 100755 --- a/uAutoScreen.pas +++ b/uAutoScreen.pas @@ -384,7 +384,6 @@ procedure TMainForm.ReadSettings; FmtStr: String; Seconds: Integer; LogFilePath: String; - Interval: TInterval; CleanerActive: Boolean; begin // Logging @@ -501,17 +500,10 @@ procedure TMainForm.ReadSettings; // Old screenshots removing CleanerActive := Ini.ReadBool(DefaultConfigIniSection, - 'OldScreenshotsRemovingEnabled', False); - Interval.Val := Ini.ReadInteger(DefaultConfigIniSection, - 'OldScreenshotsRemovingPeriodValue', - DefaultScreenshotCleanerInterval.Val); - Interval.Unit_ := StringToIntervalUnit( - Ini.ReadString(DefaultConfigIniSection, - 'OldScreenshotsRemovingPeriodUnit', - IntervalUnitToString(DefaultScreenshotCleanerInterval.Unit_) - ) - ); - OldScreenshotCleaner.Interval := Interval; + 'OldScreenshotsRemovingEnabled', False); + OldScreenshotCleaner.Interval := TInterval(Ini.ReadString(DefaultConfigIniSection, + 'OldScreenshotsRemovingPeriod', + String(DefaultScreenshotCleanerInterval))); OldScreenshotCleaner.Active := CleanerActive; end; @@ -1815,10 +1807,8 @@ procedure TMainForm.OnScreenshotCleanerChanged; Ini.WriteBool(DefaultConfigIniSection, 'OldScreenshotsRemovingEnabled', OldScreenshotCleaner.Active); OldScreenshotsRemovingPeriodValueSpinEdit.Value := OldScreenshotCleaner.Interval.Val; - Ini.WriteInteger(DefaultConfigIniSection, 'OldScreenshotsRemovingPeriodValue', OldScreenshotCleaner.Interval.Val); - OldScreenshotsRemovingPeriodUnitComboBox.ItemIndex := Ord(OldScreenshotCleaner.Interval.Unit_); - Ini.WriteString(DefaultConfigIniSection, 'OldScreenshotsRemovingPeriodUnit', IntervalUnitToString(OldScreenshotCleaner.Interval.Unit_)); + Ini.WriteString(DefaultConfigIniSection, 'OldScreenshotsRemovingPeriod', String(OldScreenshotCleaner.Interval)); end; {$IfDef Linux} From 63bf31d399e46246a76b2c772f082501d42f34a5 Mon Sep 17 00:00:00 2001 From: artem78 Date: Fri, 1 Sep 2023 21:08:31 +0300 Subject: [PATCH 25/38] Rename variables and ettings --- oldscreenshotcleaner.pas | 12 ++++++------ uAutoScreen.pas | 26 +++++++++++++------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/oldscreenshotcleaner.pas b/oldscreenshotcleaner.pas index d12cbe7..002e175 100644 --- a/oldscreenshotcleaner.pas +++ b/oldscreenshotcleaner.pas @@ -21,15 +21,15 @@ TInterval = record TOldScreenshotCleaner = class private - FInterval: TInterval; + FMaxAge: TInterval; FActive: Boolean; FOnChangeCallback: TOldScreenshotCleanerChangeCallback; - procedure SetInterval(AInterval: TInterval); + procedure SetMaxAge(AMaxAge: TInterval); procedure SetActive(AActive: Boolean); public - property Interval: TInterval read FInterval write SetInterval; + property MaxAge: TInterval read FMaxAge write SetMaxAge; property Active: Boolean read FActive write SetActive; property OnChangeCallback: TOldScreenshotCleanerChangeCallback read FOnChangeCallback write FOnChangeCallback; @@ -72,12 +72,12 @@ implementation { TOldScreenshotCleaner } -procedure TOldScreenshotCleaner.SetInterval(AInterval: TInterval); +procedure TOldScreenshotCleaner.SetMaxAge(AMaxAge: TInterval); begin - //if (FInterval.Unit_ = AInterval.Unit_) and (FInterval.Val = AInterval.Val) then + //if (FMaxAge.Unit_ = AMaxAge.Unit_) and (FMaxAge.Val = AMaxAge.Val) then // Exit; - FInterval := AInterval; + FMaxAge := AMaxAge; if Assigned(FOnChangeCallback) then FOnChangeCallback; diff --git a/uAutoScreen.pas b/uAutoScreen.pas index be6cbed..6573eba 100755 --- a/uAutoScreen.pas +++ b/uAutoScreen.pas @@ -372,7 +372,7 @@ procedure TMainForm.ReadSettings; DefaultCounterValue = MinCounterValue; DefaultCounterDigits = 6; DefaultCompressionLevel = cldefault; - DefaultScreenshotCleanerInterval: TInterval = ( + DefaultScreenshotCleanerMaxAge: TInterval = ( Val: 1; Unit_: iuMonths ); @@ -500,10 +500,10 @@ procedure TMainForm.ReadSettings; // Old screenshots removing CleanerActive := Ini.ReadBool(DefaultConfigIniSection, - 'OldScreenshotsRemovingEnabled', False); - OldScreenshotCleaner.Interval := TInterval(Ini.ReadString(DefaultConfigIniSection, - 'OldScreenshotsRemovingPeriod', - String(DefaultScreenshotCleanerInterval))); + 'OldScreenshotCleanerEnabled', False); + OldScreenshotCleaner.MaxAge := TInterval(Ini.ReadString(DefaultConfigIniSection, + 'OldScreenshotCleanerMaxAge', + String(DefaultScreenshotCleanerMaxAge))); OldScreenshotCleaner.Active := CleanerActive; end; @@ -671,9 +671,9 @@ procedure TMainForm.OldScreenshotsRemovingPeriodUnitComboBoxChange( var Interval: TInterval; begin - Interval := OldScreenshotCleaner.Interval; + Interval := OldScreenshotCleaner.MaxAge; Interval.Unit_:= TIntervalUnit(TComboBox(Sender).ItemIndex); - OldScreenshotCleaner.Interval := Interval; + OldScreenshotCleaner.MaxAge := Interval; end; procedure TMainForm.OldScreenshotsRemovingPeriodValueSpinEditChange( @@ -681,9 +681,9 @@ procedure TMainForm.OldScreenshotsRemovingPeriodValueSpinEditChange( var Interval: TInterval; begin - Interval := OldScreenshotCleaner.Interval; + Interval := OldScreenshotCleaner.MaxAge; Interval.Val := TSpinEdit(Sender).Value; - OldScreenshotCleaner.Interval := Interval; + OldScreenshotCleaner.MaxAge := Interval; end; procedure TMainForm.OutputDirEditChange(Sender: TObject); @@ -1804,11 +1804,11 @@ function TMainForm.OnHotKeysSaving(ASender: TObject; out AErrorMsg: string): Boo procedure TMainForm.OnScreenshotCleanerChanged; begin EnableOldScreenshotsRemovingCheckBox.Checked := OldScreenshotCleaner.Active; - Ini.WriteBool(DefaultConfigIniSection, 'OldScreenshotsRemovingEnabled', OldScreenshotCleaner.Active); + Ini.WriteBool(DefaultConfigIniSection, 'OldScreenshotCleanerEnabled', OldScreenshotCleaner.Active); - OldScreenshotsRemovingPeriodValueSpinEdit.Value := OldScreenshotCleaner.Interval.Val; - OldScreenshotsRemovingPeriodUnitComboBox.ItemIndex := Ord(OldScreenshotCleaner.Interval.Unit_); - Ini.WriteString(DefaultConfigIniSection, 'OldScreenshotsRemovingPeriod', String(OldScreenshotCleaner.Interval)); + OldScreenshotsRemovingPeriodValueSpinEdit.Value := OldScreenshotCleaner.MaxAge.Val; + OldScreenshotsRemovingPeriodUnitComboBox.ItemIndex := Ord(OldScreenshotCleaner.MaxAge.Unit_); + Ini.WriteString(DefaultConfigIniSection, 'OldScreenshotCleanerMaxAge', String(OldScreenshotCleaner.MaxAge)); end; {$IfDef Linux} From 216b6d5510e674ca9a22b1d53f9dab119ab416ab Mon Sep 17 00:00:00 2001 From: artem78 Date: Sat, 2 Sep 2023 21:33:11 +0300 Subject: [PATCH 26/38] Disable old screenshot cleaner parameters when disabled --- uAutoScreen.pas | 3 +++ 1 file changed, 3 insertions(+) diff --git a/uAutoScreen.pas b/uAutoScreen.pas index 6573eba..5e96b15 100755 --- a/uAutoScreen.pas +++ b/uAutoScreen.pas @@ -1809,6 +1809,9 @@ procedure TMainForm.OnScreenshotCleanerChanged; OldScreenshotsRemovingPeriodValueSpinEdit.Value := OldScreenshotCleaner.MaxAge.Val; OldScreenshotsRemovingPeriodUnitComboBox.ItemIndex := Ord(OldScreenshotCleaner.MaxAge.Unit_); Ini.WriteString(DefaultConfigIniSection, 'OldScreenshotCleanerMaxAge', String(OldScreenshotCleaner.MaxAge)); + + OldScreenshotsRemovingPeriodValueSpinEdit.Enabled := OldScreenshotCleaner.Active; + OldScreenshotsRemovingPeriodUnitComboBox.Enabled := OldScreenshotCleaner.Active; end; {$IfDef Linux} From 9f5ca0afce272ce9f4ce443a51280843dc65f384 Mon Sep 17 00:00:00 2001 From: artem78 Date: Sun, 3 Sep 2023 12:53:44 +0300 Subject: [PATCH 27/38] Edit UI and rename components --- uAutoScreen.lfm | 77 ++++++++++++++++++++++++------------------------- uAutoScreen.pas | 34 +++++++++++----------- 2 files changed, 54 insertions(+), 57 deletions(-) diff --git a/uAutoScreen.lfm b/uAutoScreen.lfm index 62ef809..49a3bf5 100755 --- a/uAutoScreen.lfm +++ b/uAutoScreen.lfm @@ -104,7 +104,7 @@ object MainForm: TMainForm AnchorSideBottom.Side = asrBottom Left = 40 Height = 28 - Top = 510 + Top = 481 Width = 107 Anchors = [akLeft, akBottom] AutoSize = True @@ -112,7 +112,7 @@ object MainForm: TMainForm Caption = 'Take screenshot' Constraints.MinWidth = 100 OnClick = TakeScreenshotButtonClick - TabOrder = 12 + TabOrder = 14 end object OpenOutputDirButton: TButton AnchorSideLeft.Control = OutputDirEdit @@ -143,16 +143,16 @@ object MainForm: TMainForm OnClick = StopWhenInactiveCheckBoxClick ParentShowHint = False ShowHint = True - TabOrder = 6 + TabOrder = 7 end object AutoCaptureControlGroup: TGroupBox AnchorSideLeft.Control = Owner AnchorSideLeft.Side = asrCenter - AnchorSideTop.Control = OldScreenshotsRemovingGroupBox + AnchorSideTop.Control = OldScreenshotCleanerPanel AnchorSideTop.Side = asrBottom Left = 251 Height = 57 - Top = 489 + Top = 460 Width = 220 AutoSize = True BorderSpacing.Top = 24 @@ -165,7 +165,7 @@ object MainForm: TMainForm ChildSizing.ControlsPerLine = 2 ClientHeight = 40 ClientWidth = 218 - TabOrder = 13 + TabOrder = 15 object StartAutoCaptureButton: TBitBtn Left = 6 Height = 28 @@ -203,7 +203,7 @@ object MainForm: TMainForm Width = 261 Caption = 'Start auto capture when program starts' OnClick = StartCaptureOnStartUpCheckBoxClick - TabOrder = 7 + TabOrder = 8 end object StartMinimizedCheckBox: TCheckBox AnchorSideLeft.Control = OutputDirEdit @@ -215,7 +215,7 @@ object MainForm: TMainForm Width = 159 Caption = 'Start minimized to tray' OnClick = StartMinimizedCheckBoxClick - TabOrder = 8 + TabOrder = 9 end object FileNameTemplateComboBox: TComboBox AnchorSideLeft.Control = OutputDirEdit @@ -283,7 +283,7 @@ object MainForm: TMainForm Width = 225 Caption = 'Run application at system startup' OnClick = AutoRunCheckBoxClick - TabOrder = 9 + TabOrder = 10 end object MonitorComboBox: TComboBox AnchorSideLeft.Control = OutputDirEdit @@ -303,7 +303,7 @@ object MainForm: TMainForm ) OnChange = MonitorComboBoxChange Style = csDropDownList - TabOrder = 10 + TabOrder = 11 end object SeqNumberGroup: TGroupBox AnchorSideLeft.Control = OutputDirEdit @@ -385,7 +385,7 @@ object MainForm: TMainForm OnChange = PostCmdEditChange ParentShowHint = False ShowHint = True - TabOrder = 11 + TabOrder = 12 end object PostCmdLabel: TLabel AnchorSideTop.Control = PostCmdEdit @@ -415,7 +415,7 @@ object MainForm: TMainForm ChildSizing.ControlsPerLine = 99 ClientHeight = 29 ClientWidth = 856 - TabOrder = 14 + TabOrder = 6 object ImageFormatComboBox: TComboBox Left = 0 Height = 29 @@ -426,7 +426,7 @@ object MainForm: TMainForm ItemHeight = 0 OnChange = ImageFormatComboBoxChange Style = csDropDownList - TabOrder = 1 + TabOrder = 0 end object CompressionLevelLabel: TLabel Left = 130 @@ -453,7 +453,7 @@ object MainForm: TMainForm ) OnChange = CompressionLevelComboBoxChange Style = csDropDownList - TabOrder = 0 + TabOrder = 1 end object JPEGQualityLabel: TLabel Left = 379 @@ -517,55 +517,52 @@ object MainForm: TMainForm TabOrder = 4 end end - object OldScreenshotsRemovingGroupBox: TGroupBox - AnchorSideLeft.Control = Owner + object OldScreenshotCleanerPanel: TPanel + AnchorSideLeft.Control = OutputDirEdit AnchorSideTop.Control = PostCmdEdit AnchorSideTop.Side = asrBottom AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom - Left = 15 - Height = 58 + Left = 192 + Height = 29 Top = 407 - Width = 693 - Anchors = [akTop, akLeft, akRight] + Width = 367 AutoSize = True - Caption = 'Delete old screenshots' - ChildSizing.LeftRightSpacing = 6 - ChildSizing.TopBottomSpacing = 6 + BevelOuter = bvNone ChildSizing.HorizontalSpacing = 6 ChildSizing.VerticalSpacing = 6 ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.ControlsPerLine = 999 - ClientHeight = 41 - ClientWidth = 691 - TabOrder = 15 - object EnableOldScreenshotsRemovingCheckBox: TCheckBox - Left = 6 + ClientHeight = 29 + ClientWidth = 367 + TabOrder = 13 + object OldScreenshotCleanerEnabledCheckBox: TCheckBox + Left = 0 Height = 29 - Top = 6 - Width = 74 - Caption = 'Enabled' - OnChange = EnableOldScreenshotsRemovingCheckBoxChange + Top = 0 + Width = 205 + Caption = 'Delete screenshots older than' + OnChange = OldScreenshotCleanerEnabledCheckBoxChange TabOrder = 0 end - object OldScreenshotsRemovingPeriodValueSpinEdit: TSpinEdit - Left = 86 + object OldScreenshotCleanerMaxAgeValueSpinEdit: TSpinEdit + Left = 211 Height = 29 - Top = 6 + Top = 0 Width = 50 MaxValue = 999 MinValue = 1 - OnChange = OldScreenshotsRemovingPeriodValueSpinEditChange + OnChange = OldScreenshotCleanerMaxAgeValueSpinEditChange TabOrder = 1 Value = 1 end - object OldScreenshotsRemovingPeriodUnitComboBox: TComboBox - Left = 142 + object OldScreenshotCleanerMaxAgeUnitComboBox: TComboBox + Left = 267 Height = 29 - Top = 6 + Top = 0 Width = 100 ItemHeight = 0 - OnChange = OldScreenshotsRemovingPeriodUnitComboBoxChange + OnChange = OldScreenshotCleanerMaxAgeUnitComboBoxChange Style = csDropDownList TabOrder = 2 end diff --git a/uAutoScreen.pas b/uAutoScreen.pas index 5e96b15..fbd02fa 100755 --- a/uAutoScreen.pas +++ b/uAutoScreen.pas @@ -24,19 +24,19 @@ interface TMainForm = class(TForm) AutoCheckForUpdatesMenuItem: TMenuItem; - EnableOldScreenshotsRemovingCheckBox: TCheckBox; - OldScreenshotsRemovingPeriodUnitComboBox: TComboBox; CompressionLevelComboBox: TComboBox; - OldScreenshotsRemovingGroupBox: TGroupBox; + OldScreenshotCleanerEnabledCheckBox: TCheckBox; HotKetsSettingsMenuItem: TMenuItem; CompressionLevelLabel: TLabel; ImageFormatOptionsPanel: TPanel; DonateMenuItem: TMenuItem; + OldScreenshotCleanerPanel: TPanel; + OldScreenshotCleanerMaxAgeUnitComboBox: TComboBox; + OldScreenshotCleanerMaxAgeValueSpinEdit: TSpinEdit; PostCmdLabel: TLabel; PostCmdEdit: TEdit; CheckForUpdatesMenuItem: TMenuItem; OutputDirEdit: TDirectoryEdit; - OldScreenshotsRemovingPeriodValueSpinEdit: TSpinEdit; Timer: TTimer; OutputDirLabel: TLabel; CaptureIntervalLabel: TLabel; @@ -86,14 +86,14 @@ TMainForm = class(TForm) procedure CheckForUpdatesMenuItemClick(Sender: TObject); procedure AutoCheckForUpdatesMenuItemClick(Sender: TObject); procedure CompressionLevelComboBoxChange(Sender: TObject); - procedure EnableOldScreenshotsRemovingCheckBoxChange(Sender: TObject); + procedure OldScreenshotCleanerEnabledCheckBoxChange(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormShow(Sender: TObject); procedure HotKetsSettingsMenuItemClick(Sender: TObject); procedure DonateMenuItemClick(Sender: TObject); - procedure OldScreenshotsRemovingPeriodUnitComboBoxChange(Sender: TObject); - procedure OldScreenshotsRemovingPeriodValueSpinEditChange(Sender: TObject); + procedure OldScreenshotCleanerMaxAgeUnitComboBoxChange(Sender: TObject); + procedure OldScreenshotCleanerMaxAgeValueSpinEditChange(Sender: TObject); procedure OutputDirEditChange(Sender: TObject); procedure CaptureIntervalDateTimePickerChange(Sender: TObject); procedure PostCmdEditChange(Sender: TObject); @@ -344,13 +344,13 @@ procedure TMainForm.InitUI; Append('screenshot %NUM'); end; - with OldScreenshotsRemovingPeriodValueSpinEdit do + with OldScreenshotCleanerMaxAgeValueSpinEdit do begin MinValue := MinOldScreenshotsRemovingPeriodValue; MaxValue := MaxOldScreenshotsRemovingPeriodValue; end; - with OldScreenshotsRemovingPeriodUnitComboBox.Items do + with OldScreenshotCleanerMaxAgeUnitComboBox.Items do begin Clear; Append('Hours'); @@ -620,7 +620,7 @@ procedure TMainForm.CompressionLevelComboBoxChange(Sender: TObject); CompressionLevel := Tcompressionlevel(CompressionLevelComboBox.ItemIndex); end; -procedure TMainForm.EnableOldScreenshotsRemovingCheckBoxChange(Sender: TObject); +procedure TMainForm.OldScreenshotCleanerEnabledCheckBoxChange(Sender: TObject); begin OldScreenshotCleaner.Active := TCheckBox(Sender).Checked; end; @@ -666,7 +666,7 @@ procedure TMainForm.DonateMenuItemClick(Sender: TObject); ShowMessage('PayPal: megabyte1024@yandex.com'); end; -procedure TMainForm.OldScreenshotsRemovingPeriodUnitComboBoxChange( +procedure TMainForm.OldScreenshotCleanerMaxAgeUnitComboBoxChange( Sender: TObject); var Interval: TInterval; @@ -676,7 +676,7 @@ procedure TMainForm.OldScreenshotsRemovingPeriodUnitComboBoxChange( OldScreenshotCleaner.MaxAge := Interval; end; -procedure TMainForm.OldScreenshotsRemovingPeriodValueSpinEditChange( +procedure TMainForm.OldScreenshotCleanerMaxAgeValueSpinEditChange( Sender: TObject); var Interval: TInterval; @@ -1803,15 +1803,15 @@ function TMainForm.OnHotKeysSaving(ASender: TObject; out AErrorMsg: string): Boo procedure TMainForm.OnScreenshotCleanerChanged; begin - EnableOldScreenshotsRemovingCheckBox.Checked := OldScreenshotCleaner.Active; + OldScreenshotCleanerEnabledCheckBox.Checked := OldScreenshotCleaner.Active; Ini.WriteBool(DefaultConfigIniSection, 'OldScreenshotCleanerEnabled', OldScreenshotCleaner.Active); - OldScreenshotsRemovingPeriodValueSpinEdit.Value := OldScreenshotCleaner.MaxAge.Val; - OldScreenshotsRemovingPeriodUnitComboBox.ItemIndex := Ord(OldScreenshotCleaner.MaxAge.Unit_); + OldScreenshotCleanerMaxAgeValueSpinEdit.Value := OldScreenshotCleaner.MaxAge.Val; + OldScreenshotCleanerMaxAgeUnitComboBox.ItemIndex := Ord(OldScreenshotCleaner.MaxAge.Unit_); Ini.WriteString(DefaultConfigIniSection, 'OldScreenshotCleanerMaxAge', String(OldScreenshotCleaner.MaxAge)); - OldScreenshotsRemovingPeriodValueSpinEdit.Enabled := OldScreenshotCleaner.Active; - OldScreenshotsRemovingPeriodUnitComboBox.Enabled := OldScreenshotCleaner.Active; + OldScreenshotCleanerMaxAgeValueSpinEdit.Enabled := OldScreenshotCleaner.Active; + OldScreenshotCleanerMaxAgeUnitComboBox.Enabled := OldScreenshotCleaner.Active; end; {$IfDef Linux} From 74c6575640076413b753673c8ecb7f4a73832390 Mon Sep 17 00:00:00 2001 From: artem78 Date: Sun, 3 Sep 2023 13:22:54 +0300 Subject: [PATCH 28/38] Add localization for new strings --- lang/en.ini | 5 +++++ lang/ru.ini | 5 +++++ uAutoScreen.pas | 17 +++++++++++++---- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/lang/en.ini b/lang/en.ini index 6d34728..8e89983 100644 --- a/lang/en.ini +++ b/lang/en.ini @@ -49,6 +49,11 @@ CompressionLevelFastest=Fastest CompressionLevelDefault=Default CompressionLevelMax=Maximum Donate=Donate +DeleteScreenshotsOlderThan=Delete old screenshots after +Hours=hours +Days=days +Weeks=weeks +Months=months ; === Tray icon menu === Restore=Restore diff --git a/lang/ru.ini b/lang/ru.ini index eaf0b45..20efc61 100644 --- a/lang/ru.ini +++ b/lang/ru.ini @@ -50,6 +50,11 @@ CompressionLevelFastest=Быстрое CompressionLevelDefault=Обычное CompressionLevelMax=Максимальное Donate=Сделать пожертвование +DeleteScreenshotsOlderThan=Удалять снимки старше +Hours=часов +Days=дней +Weeks=недель +Months=месяцев ; === Tray icon menu === Restore=Восстановить diff --git a/uAutoScreen.pas b/uAutoScreen.pas index fbd02fa..1f711ad 100755 --- a/uAutoScreen.pas +++ b/uAutoScreen.pas @@ -301,6 +301,7 @@ function MyGetApplicationName: String; procedure TMainForm.InitUI; var Fmt: TImageFormat; + I: Integer; begin {$IFOPT D+} MainForm.Caption := MainForm.Caption + ' [DEBUG BUILD]'; @@ -353,11 +354,10 @@ procedure TMainForm.InitUI; with OldScreenshotCleanerMaxAgeUnitComboBox.Items do begin Clear; - Append('Hours'); - Append('Days'); - Append('Weeks'); - Append('Months'); + for I := Ord(Low(TIntervalUnit)) to Ord(High(TIntervalUnit)) do + Append(''); end; + end; procedure TMainForm.ReadSettings; @@ -1056,6 +1056,15 @@ procedure TMainForm.TranslateForm; Items[3] := Localizer.I18N('CompressionLevelMax'); end; + OldScreenshotCleanerEnabledCheckBox.Caption := Localizer.I18N('DeleteScreenshotsOlderThan'); + with OldScreenshotCleanerMaxAgeUnitComboBox do + begin + Items[Ord(iuHours)] := Localizer.I18N('Hours'); + Items[Ord(iuDays)] := Localizer.I18N('Days'); + Items[Ord(iuWeeks)] := Localizer.I18N('Weeks'); + Items[Ord(iuMonths)] := Localizer.I18N('Months'); + end; + // Tray icon RestoreWindowTrayMenuItem.Caption := Localizer.I18N('Restore'); ToggleAutoCaptureTrayMenuItem.Caption := Localizer.I18N('EnableAutoCapture'); From 5bb777ba2ce28d4b336448d375242e7be9c09e7a Mon Sep 17 00:00:00 2001 From: artem78 Date: Mon, 4 Sep 2023 10:59:12 +0300 Subject: [PATCH 29/38] Fix constant case --- oldscreenshotcleaner.pas | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/oldscreenshotcleaner.pas b/oldscreenshotcleaner.pas index 002e175..d368a76 100644 --- a/oldscreenshotcleaner.pas +++ b/oldscreenshotcleaner.pas @@ -46,7 +46,7 @@ implementation begin case AInterval.Unit_ of iuHours: UnitShortName := 'h'; - iudays: UnitShortName := 'd'; + iuDays: UnitShortName := 'd'; iuWeeks: UnitShortName := 'w'; iuMonths: UnitShortName := 'm'; end; @@ -61,7 +61,7 @@ implementation UnitShortName := AStr[Length(AStr)]; case UnitShortName of 'h': Result.Unit_ := iuHours; - 'd': Result.Unit_ := iudays; + 'd': Result.Unit_ := iuDays; 'w': Result.Unit_ := iuWeeks; 'm': Result.Unit_ := iuMonths; else raise Exception.CreateFmt('Unknown unit character ''%s''', [UnitShortName]); From 4b45210fdfd2474305cabec49b4a49f8a9c9c052 Mon Sep 17 00:00:00 2001 From: Artem Date: Mon, 4 Sep 2023 14:56:40 +0300 Subject: [PATCH 30/38] Delete trailing whitespace from predefined filename templates --- uAutoScreen.pas | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uAutoScreen.pas b/uAutoScreen.pas index 62ec5e7..13f6bd9 100755 --- a/uAutoScreen.pas +++ b/uAutoScreen.pas @@ -327,8 +327,8 @@ procedure TMainForm.InitUI; Clear; Append('screenshot %Y-%M-%D %H-%N-%S'); Append('%Y' + PathDelim + '%M' + PathDelim + '%D' + PathDelim + 'screenshot %H-%N-%S'); - Append('%Y-%M' + PathDelim + '%D' + PathDelim + 'screenshot %H-%N-%S '); - Append('%COMP' + PathDelim + '%USER' + PathDelim + 'screenshot %Y-%M-%D %H-%N-%S '); + Append('%Y-%M' + PathDelim + '%D' + PathDelim + 'screenshot %H-%N-%S'); + Append('%COMP' + PathDelim + '%USER' + PathDelim + 'screenshot %Y-%M-%D %H-%N-%S'); Append('screenshot %NUM'); end; end; From dbbef876d939ab02fe6b5c7e4e095d682ae3f035 Mon Sep 17 00:00:00 2001 From: artem78 Date: Mon, 4 Sep 2023 17:11:31 +0300 Subject: [PATCH 31/38] Implement old screenshots removing --- AutoScreenshot.lpi | 15 ++++- oldscreenshotcleaner.pas | 123 ++++++++++++++++++++++++++++++++++++-- uUtils.pas | 124 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 256 insertions(+), 6 deletions(-) diff --git a/AutoScreenshot.lpi b/AutoScreenshot.lpi index e17dcda..bfaaa8e 100644 --- a/AutoScreenshot.lpi +++ b/AutoScreenshot.lpi @@ -88,7 +88,20 @@ - + + + + + + + + + diff --git a/oldscreenshotcleaner.pas b/oldscreenshotcleaner.pas index d368a76..8309164 100644 --- a/oldscreenshotcleaner.pas +++ b/oldscreenshotcleaner.pas @@ -5,7 +5,7 @@ interface uses - Classes, SysUtils; + Classes, SysUtils, ExtCtrls; type TIntervalUnit = (iuHours, iuDays, iuWeeks, iuMonths); @@ -22,24 +22,48 @@ TInterval = record TOldScreenshotCleaner = class private FMaxAge: TInterval; - FActive: Boolean; FOnChangeCallback: TOldScreenshotCleanerChangeCallback; + Timer: TTimer; + procedure SetMaxAge(AMaxAge: TInterval); procedure SetActive(AActive: Boolean); + function GetActive: Boolean; + procedure DoOnTimer(ASender: TObject); + procedure UpdateUI; + public + constructor Create; + destructor Destroy; override; property MaxAge: TInterval read FMaxAge write SetMaxAge; - property Active: Boolean read FActive write SetActive; + property Active: Boolean read GetActive write SetActive; property OnChangeCallback: TOldScreenshotCleanerChangeCallback read FOnChangeCallback write FOnChangeCallback; + procedure Start; + procedure Stop; end; operator explicit (const AInterval: TInterval): String; operator explicit (const AStr: String): TInterval; + operator - (ADateTime: TDateTime; AInterval: TInterval): TDateTime; implementation +uses LazLoggerBase, uUtils, ScreenGrabber, DateUtils, + /////////// + uAutoScreen, Forms + /////////// + ; + +const + RunInterval: Integer = + {$IFOPT D+} + 5 * MSecsPerSec; + {$Else} + 0.5 * MSecsPerSec * SecsPerHour; // 30 minutes + {$ENDIF} + operator explicit (const AInterval: TInterval): String; var UnitShortName: Char; @@ -69,6 +93,16 @@ implementation Result.Val := StrToInt(Copy(AStr, 1, Length(AStr) - 1)); end; +operator - (ADateTime: TDateTime; AInterval: TInterval): TDateTime; +begin + case AInterval.Unit_ of + iuHours: Result := IncHour(ADateTime, -AInterval.Val); + iuDays: Result := IncDay(ADateTime, -AInterval.Val); + iuWeeks: Result := IncDay(ADateTime, -AInterval.Val * 7); + iuMonths: Result := IncMonth(ADateTime, -AInterval.Val); + end; +end; + { TOldScreenshotCleaner } @@ -88,11 +122,92 @@ procedure TOldScreenshotCleaner.SetActive(AActive: Boolean); //if FActive = AActive then // Exit; - FActive := AActive; + if AActive then + Start + else + Stop; if Assigned(FOnChangeCallback) then FOnChangeCallback; end; +function TOldScreenshotCleaner.GetActive: Boolean; +begin + Result := Timer.Enabled; +end; + +procedure TOldScreenshotCleaner.DoOnTimer(ASender: TObject); +var + MaxDateTime: TDateTime; + ImgExts: TStringList; + ImgFmt: TImageFormat; + Dir: String; +begin + // Set normal timer interval at first run + if Timer.Interval <> RunInterval then + Timer.Interval := RunInterval; + + MaxDateTime := Now - MaxAge; + //DebugLn('MaxDateTime=', DateTimeToStr(MaxDateTime)); + + ImgExts := TStringList.Create; + try + for ImgFmt in TImageFormat do + ImgExts.Append(ImageFormatInfoArray[ImgFmt].Extension); + //DebugLn('ImgExts=', ImgExts.CommaText); + + Dir := MainForm.OutputDirEdit.Directory {TODO: remake this!}; + Assert(not Dir.IsEmpty, 'Wrong path!'); + Assert(Dir <> '/', 'Wrong path!'); + + DebugLn('Start clearing old screenshots until ', DateTimeToStr(MaxDateTime)); + DebugLnEnter; + DeleteOldFiles(Dir, MaxDateTime, True, ImgExts.ToStringArray, True, @UpdateUI); + finally + ImgExts.Free; + DebugLnExit; + DebugLn('Old files cleaning finished'); + end; +end; + +procedure TOldScreenshotCleaner.UpdateUI; +begin + Application.ProcessMessages; +end; + +constructor TOldScreenshotCleaner.Create; +begin + Timer := TTimer.Create(Nil); + Timer.Enabled := False; + Timer.OnTimer := @DoOnTimer; +end; + +destructor TOldScreenshotCleaner.Destroy; +begin + Stop; + Timer.Free; + + inherited Destroy; +end; + +procedure TOldScreenshotCleaner.Start; +begin + if not Timer.Enabled then + begin + Timer.Interval := 1 * MSecsPerSec; // For the first run only, will be increased later + Timer.Enabled := True; + DebugLn('Old screenshot cleaner started'); + end; +end; + +procedure TOldScreenshotCleaner.Stop; +begin + if Timer.Enabled then + begin + Timer.Enabled := False; + DebugLn('Old screenshot cleaner stopped'); + end; +end; + end. diff --git a/uUtils.pas b/uUtils.pas index 39ff1a3..734eb1c 100644 --- a/uUtils.pas +++ b/uUtils.pas @@ -75,6 +75,13 @@ procedure RunCmdInbackground(ACmd: String); function IsPortable: Boolean; function GetUserPicturesDir: WideString; +type + TDeleteOldFilesCallback = procedure of Object; + +procedure DeleteOldFiles(const ADir: string; AMaxDateTime: TDateTime; + AIncludeSubdirs: Boolean; const AAllowedExtensions: array of {String} AnsiString; + ADeleteEmptyDirs: Boolean; ACallback: TDeleteOldFilesCallback = Nil); + implementation uses @@ -84,7 +91,8 @@ implementation {$IfDef Linux} Unix, LazUTF8, LazFileUtils, {$EndIf} - SysUtils, Classes, DateUtils, StrUtils, uLanguages, Forms {???}, FileInfo, process; + SysUtils, Classes, DateUtils, StrUtils, uLanguages, Forms {???}, FileInfo, process, + FileUtil, LazLogger; {$IfDef Windows} const @@ -437,4 +445,118 @@ function GetUserPicturesDir: WideString; {$EndIf} end; +procedure DeleteOldFiles(const ADir: string; AMaxDateTime: TDateTime; + AIncludeSubdirs: Boolean; const AAllowedExtensions: array of {String} AnsiString; + ADeleteEmptyDirs: Boolean; ACallback: TDeleteOldFilesCallback); + + function IsEmptyDirectory(ADir: String): Boolean; + var + SearchRecResult: TSearchRec; + begin + Result := True; + + if FindFirst(ConcatPaths([ADir, '*']), faAnyFile, SearchRecResult) = 0 then + begin + repeat + if (SearchRecResult.Name = '.') or (SearchRecResult.Name = '..') then + Continue; + + Result := False; + Break; + until FindNext(SearchRecResult) <> 0; + FindClose(SearchRecResult); + end; + end; +var + SearchRec: TSearchRec; + ExtList: TStringList; + Ext: String; + FullName: String; + Res: Boolean; +begin + ExtList := TStringList.Create; + try + ExtList.CaseSensitive := False; + ExtList.Duplicates := dupIgnore; + ExtList.Sorted := True; + + for Ext in AAllowedExtensions do + ExtList.Add(Ext); + + {DebugLn}DebugLnEnter('Prepare for clean "%s" directory from old files', [ADir]); + //DebugLn('Allowed extensions: ', ExtList.CommaText); + + if FindFirst(ConcatPaths([ADir, '*']), faAnyFile, SearchRec) = 0 then + begin + try + repeat + if Assigned(ACallback) then + ACallback; + + FullName := ConcatPaths([ADir, SearchRec.Name]); + + if (SearchRec.Attr and faDirectory) = faDirectory then + begin + if (SearchRec.Name = '.') or (SearchRec.Name = '..') then + Continue; + + if AIncludeSubdirs then + DeleteOldFiles(ConcatPaths([ADir, SearchRec.Name]), AMaxDateTime, + AIncludeSubdirs, AAllowedExtensions, ADeleteEmptyDirs); + + Continue; + end; + + if ExtList.Count > 0 then + begin + Ext := ExtractFileExt(SearchRec.Name); + if (Length(Ext) > 0) and (Ext[1] = '.') then + Delete(Ext, 1, 1); // Delete dot before extension + if ExtList.IndexOf(Ext) = -1 then + begin + DebugLn('Skip "%s" with excluded extension', [FullName]); + Continue; + end; + end; + + if SearchRec.TimeStamp >= AMaxDateTime then + begin + DebugLn('Skip new file "%s" with date %s', [FullName, DateTimeToStr(SearchRec.TimeStamp)]); + Continue; + end; + + DebugLn('Try to delete "%s" with date %s ...', [FullName, DateTimeToStr(SearchRec.TimeStamp)]); +{$IfDef SIMULATE_OLD_FILES_DELETION} + DebugLn('[ Simulation! ]'); + Res := True; +{$Else} + Res := DeleteFile(FullName); +{$EndIf} + DebugLn(IfThen(Res, 'Ok', 'Failed!')); + until FindNext(SearchRec) <> 0; + finally + FindClose(SearchRec); + end; + end; + + if ADeleteEmptyDirs and IsEmptyDirectory(ADir) then + begin + DebugLn('Try to delete empty directory "%s" ...', [ADir]); +{$IfDef SIMULATE_OLD_FILES_DELETION} + DebugLn('[ Simulation! ]'); + Res := True; +{$Else} + Res := DeleteDirectory(ADir, False); +{$EndIf} + DebugLn(IfThen(Res, 'Ok', 'Failed!')); + end; + + finally + ExtList.Free; + end; + + DebugLn('Old files cleaning in directory "%s" finished', [ADir]); + DebugLnExit; +end; + end. From a34856c4d2faecab82f94d5509e5f243859f2b58 Mon Sep 17 00:00:00 2001 From: artem78 Date: Thu, 7 Sep 2023 16:04:38 +0300 Subject: [PATCH 32/38] Use file creation time instead of modification in Windows In Linux creation time not available everywhere --- uUtils.pas | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/uUtils.pas b/uUtils.pas index 734eb1c..14741df 100644 --- a/uUtils.pas +++ b/uUtils.pas @@ -445,6 +445,24 @@ function GetUserPicturesDir: WideString; {$EndIf} end; +{$IfDef Windows} +function FileCreatedTime(const ASearchRec: TSearchRec): TDateTime; +// Source: https://www.cyberforum.ru/post10364301.html+} +var + t1:TFILETIME; + t2:TSYSTEMTIME; +begin + FileTimeToLocalFileTime(ASearchRec.FindData.ftCreationTime,t1); + FileTimeToSystemTime(t1,t2); + Result := SystemTimeToDateTime(t2); +end; +{$EndIf} + +function FileModifiedTime(const ASearchRec: TSearchRec): TDateTime; inline; +begin + Result := ASearchRec.TimeStamp; +end; + procedure DeleteOldFiles(const ADir: string; AMaxDateTime: TDateTime; AIncludeSubdirs: Boolean; const AAllowedExtensions: array of {String} AnsiString; ADeleteEmptyDirs: Boolean; ACallback: TDeleteOldFilesCallback); @@ -473,6 +491,7 @@ procedure DeleteOldFiles(const ADir: string; AMaxDateTime: TDateTime; Ext: String; FullName: String; Res: Boolean; + FileTime: TDateTime; begin ExtList := TStringList.Create; try @@ -519,13 +538,22 @@ procedure DeleteOldFiles(const ADir: string; AMaxDateTime: TDateTime; end; end; - if SearchRec.TimeStamp >= AMaxDateTime then + {$IfDef Windows} + FileTime := FileCreatedTime(SearchRec); + {$EndIf} + {$IfDef Linux} + // On Linux getting creation time is not always possible and not easy, + // therefore modification time used instead. + FileTime := FileModifiedTime(SearchRec); + {$EndIf} + + if FileTime >= AMaxDateTime then begin - DebugLn('Skip new file "%s" with date %s', [FullName, DateTimeToStr(SearchRec.TimeStamp)]); + DebugLn('Skip new file "%s" with date %s', [FullName, DateTimeToStr(FileTime)]); Continue; end; - DebugLn('Try to delete "%s" with date %s ...', [FullName, DateTimeToStr(SearchRec.TimeStamp)]); + DebugLn('Try to delete "%s" with date %s ...', [FullName, DateTimeToStr(FileTime)]); {$IfDef SIMULATE_OLD_FILES_DELETION} DebugLn('[ Simulation! ]'); Res := True; From dc147d13da0fc80a7d9cd4849576d4359ef5ab9c Mon Sep 17 00:00:00 2001 From: artem78 Date: Thu, 7 Sep 2023 16:08:50 +0300 Subject: [PATCH 33/38] Fix --- oldscreenshotcleaner.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oldscreenshotcleaner.pas b/oldscreenshotcleaner.pas index 8309164..9bf848d 100644 --- a/oldscreenshotcleaner.pas +++ b/oldscreenshotcleaner.pas @@ -61,7 +61,7 @@ implementation {$IFOPT D+} 5 * MSecsPerSec; {$Else} - 0.5 * MSecsPerSec * SecsPerHour; // 30 minutes + 30 * MSecsPerSec * SecsPerMin; // 30 minutes {$ENDIF} operator explicit (const AInterval: TInterval): String; From c9fbd3435246b9da0004d53e63c27d7895d3c29c Mon Sep 17 00:00:00 2001 From: artem78 Date: Thu, 7 Sep 2023 21:25:33 +0300 Subject: [PATCH 34/38] Small changes --- oldscreenshotcleaner.pas | 3 ++- uUtils.pas | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/oldscreenshotcleaner.pas b/oldscreenshotcleaner.pas index 9bf848d..2fd0448 100644 --- a/oldscreenshotcleaner.pas +++ b/oldscreenshotcleaner.pas @@ -194,7 +194,8 @@ procedure TOldScreenshotCleaner.Start; begin if not Timer.Enabled then begin - Timer.Interval := 1 * MSecsPerSec; // For the first run only, will be increased later + Timer.Interval := 1 * MSecsPerSec; // To start immediately, will be + // increased later after first run Timer.Enabled := True; DebugLn('Old screenshot cleaner started'); end; diff --git a/uUtils.pas b/uUtils.pas index 14741df..7660c3e 100644 --- a/uUtils.pas +++ b/uUtils.pas @@ -549,7 +549,7 @@ procedure DeleteOldFiles(const ADir: string; AMaxDateTime: TDateTime; if FileTime >= AMaxDateTime then begin - DebugLn('Skip new file "%s" with date %s', [FullName, DateTimeToStr(FileTime)]); + DebugLn('Skip file "%s" with date %s', [FullName, DateTimeToStr(FileTime)]); Continue; end; From 02801fae08143dd91ad949029a72ab8577595a5d Mon Sep 17 00:00:00 2001 From: artem78 Date: Fri, 8 Sep 2023 09:09:46 +0300 Subject: [PATCH 35/38] [Logging] Fix indent in log file --- uAutoScreen.pas | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/uAutoScreen.pas b/uAutoScreen.pas index 010f6af..ad912da 100755 --- a/uAutoScreen.pas +++ b/uAutoScreen.pas @@ -1765,13 +1765,17 @@ procedure TMainForm.OnDebugLnEvent(Sender: TObject; S: string; var Handled: Boolean); var Callback: {TLazLoggerWriteEvent} procedure(Sender: TObject; S: string; var Handled: Boolean) of object; + IndentLevel: Integer; begin S := Format('[%s] %s', [FormatDateTime('hh:nn:ss.zzz', Now()), S]); Callback := DebugLogger.OnDebugLn; + IndentLevel := DebugLogger.NestLvlIndent; DebugLogger.OnDebugLn := Nil; + DebugLogger.NestLvlIndent := 0; try DebugLn(S); finally + DebugLogger.NestLvlIndent := IndentLevel; DebugLogger.OnDebugLn := Callback; end; Handled := True; From 62f2c11aa14538012e08698f279d77b2ae7ad55f Mon Sep 17 00:00:00 2001 From: artem78 Date: Fri, 8 Sep 2023 09:15:14 +0300 Subject: [PATCH 36/38] Fix units count in lpi file --- AutoScreenshot.lpi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutoScreenshot.lpi b/AutoScreenshot.lpi index 7ad8fd8..75eb90a 100644 --- a/AutoScreenshot.lpi +++ b/AutoScreenshot.lpi @@ -320,7 +320,7 @@ override_dh_auto_install: - + From 5306b0e4967688dba07474554ef5c3ac2a2e1097 Mon Sep 17 00:00:00 2001 From: artem78 Date: Mon, 10 Jul 2023 19:02:28 +0300 Subject: [PATCH 37/38] [Linux] Remove unnecessary dependency from DEB (libssl-dev) --- AutoScreenshot.lpi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutoScreenshot.lpi b/AutoScreenshot.lpi index 75eb90a..4ca5007 100644 --- a/AutoScreenshot.lpi +++ b/AutoScreenshot.lpi @@ -69,7 +69,7 @@ Vcs-Browser: https://github.com/artem78/AutoScreenshot Package: ?PACKAGE_NAME? Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, openssl, libssl-dev +Depends: ${shlibs:Depends}, ${misc:Depends}, openssl Description: ?DESCRIPTION? ?DESCRIPTION_LONG? "/> From 775812698157f0edb774b90af46abfaf361fa317 Mon Sep 17 00:00:00 2001 From: artem78 Date: Fri, 8 Sep 2023 10:59:40 +0300 Subject: [PATCH 38/38] [Docs] Update readme --- docs/README-fr.md | 2 +- docs/README-ru.md | 5 ++++- docs/README.md | 5 ++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/README-fr.md b/docs/README-fr.md index 02d091b..24fca49 100644 --- a/docs/README-fr.md +++ b/docs/README-fr.md @@ -59,7 +59,7 @@ Auto Screenshot La dernière version pour Windows est disponible [ici](https://github.com/artem78/AutoScreenshot/releases/latest). Vous pouvez choisir entre la version portable zip ou l'installeur. -### Version Linux +### Version Linux [Télécharger](https://github.com/artem78/AutoScreenshot/releases/tag/v1.10.4-linux.alpha.1) Noter que c'est une **Alpha** et certaines fonctionnalités de la version Windows ne sont pas encore implémentées diff --git a/docs/README-ru.md b/docs/README-ru.md index cce0a69..118f124 100644 --- a/docs/README-ru.md +++ b/docs/README-ru.md @@ -27,6 +27,7 @@ Auto Screenshot * Захват с нескольких экранов * Поддержка режима High DPI * Выполнение произвольных команд после снимка +* Автоматическая очистка от старых снимков * Полностью бесплатное ПО с окрытым исходным кодом ## Снимки экрана @@ -62,13 +63,15 @@ Auto Screenshot Доступен zip-архив с portable-версией или установщик. ### Linux -На текущий момент только portable-версия. Планирую в будущем добавить также в виде deb пакета. +Доступна портативная версия, а также в виде deb пакета. Работоспособность проверена в дистрибутивах Linux Mint и Ubuntu + ## Чем я могу помочь проекту? * [Сообщить об ошибке](https://github.com/artem78/AutoScreenshot/issues/new?assignees=&labels=bug&template=bug_report.md&title=) diff --git a/docs/README.md b/docs/README.md index c20bed9..3a4a54d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -25,6 +25,7 @@ Auto Screenshot * Multiple screens support * High DPI support * Can execute custom command after screenshot was taken +* Clearing old screenshots * Absolutely free and open source ## Screenshots @@ -58,12 +59,14 @@ Download program [here](https://github.com/artem78/AutoScreenshot/releases/). You can choose between portable zip or installer. ### Linux -At the moment only portable version is available. I will make deb-package in the future. +For Linux portable version and deb package available. Tested with Linux Mint and Ubuntu. + ## How can I help? * [Report about found bug](https://github.com/artem78/AutoScreenshot/issues/new?assignees=&labels=bug&template=bug_report.md&title=)