From ed16bfdb501e294343f82bb6a2a0dd8d8c3881b9 Mon Sep 17 00:00:00 2001 From: juha Date: Sun, 8 Jan 2012 22:28:51 +0000 Subject: [PATCH] PoChecker: Improvements for duplicate string feature. Issue #21049, patch from Bart Broersma git-svn-id: trunk@34671 - --- components/pochecker/Proj/pocheckermain.lfm | 42 ++++---- components/pochecker/Proj/pocheckermain.pp | 20 ++-- components/pochecker/pocheckermain.pp | 18 ++-- components/pochecker/pofamilies.pp | 107 ++++++++++++-------- components/pochecker/resultdlg.lfm | 99 +++++++++++++++--- components/pochecker/resultdlg.pp | 20 +++- components/pochecker/simplepofiles.pp | 18 +++- 7 files changed, 229 insertions(+), 95 deletions(-) diff --git a/components/pochecker/Proj/pocheckermain.lfm b/components/pochecker/Proj/pocheckermain.lfm index 925f4971f6..ad603fe0c9 100644 --- a/components/pochecker/Proj/pocheckermain.lfm +++ b/components/pochecker/Proj/pocheckermain.lfm @@ -15,8 +15,8 @@ object PoCheckerForm: TPoCheckerForm AnchorSideTop.Control = SelectTestLabel AnchorSideTop.Side = asrBottom Left = 201 - Height = 169 - Top = 33 + Height = 174 + Top = 28 Width = 373 Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Top = 6 @@ -28,9 +28,9 @@ object PoCheckerForm: TPoCheckerForm AnchorSideLeft.Control = OpenBtn AnchorSideLeft.Side = asrBottom Left = 201 - Height = 19 + Height = 14 Top = 8 - Width = 144 + Width = 97 BorderSpacing.Left = 9 Caption = 'Select test types' Font.Style = [fsBold] @@ -112,9 +112,9 @@ object PoCheckerForm: TPoCheckerForm TabOrder = 3 object CurTestHeaderLabel: TLabel Left = 8 - Height = 19 + Height = 14 Top = 8 - Width = 96 + Width = 62 Caption = 'Current Test:' ParentColor = False end @@ -123,9 +123,9 @@ object PoCheckerForm: TPoCheckerForm AnchorSideTop.Control = CurTestHeaderLabel AnchorSideTop.Side = asrBottom Left = 8 - Height = 19 - Top = 27 - Width = 111 + Height = 14 + Top = 22 + Width = 69 Caption = 'Current po-file:' ParentColor = False end @@ -134,10 +134,10 @@ object PoCheckerForm: TPoCheckerForm AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = CurTestHeaderLabel AnchorSideTop.Side = asrCenter - Left = 110 - Height = 19 + Left = 76 + Height = 14 Top = 8 - Width = 95 + Width = 64 BorderSpacing.Around = 6 Caption = 'CurTestLabel' ParentColor = False @@ -147,10 +147,10 @@ object PoCheckerForm: TPoCheckerForm AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = CurPoHeaderLabel AnchorSideTop.Side = asrCenter - Left = 125 - Height = 19 - Top = 27 - Width = 82 + Left = 83 + Height = 14 + Top = 22 + Width = 56 BorderSpacing.Around = 6 Caption = 'CurPoLabel' ParentColor = False @@ -158,9 +158,9 @@ object PoCheckerForm: TPoCheckerForm end object NoErrLabel: TLabel Left = 8 - Height = 24 - Top = 232 - Width = 171 + Height = 25 + Top = 231 + Width = 149 Anchors = [akLeft, akBottom] Caption = 'No errors found' Font.Color = clGreen @@ -174,9 +174,9 @@ object PoCheckerForm: TPoCheckerForm AnchorSideTop.Control = TestListBox AnchorSideTop.Side = asrBottom Left = 201 - Height = 23 + Height = 17 Top = 208 - Width = 97 + Width = 64 BorderSpacing.Top = 6 Caption = 'Select All' Enabled = False diff --git a/components/pochecker/Proj/pocheckermain.pp b/components/pochecker/Proj/pocheckermain.pp index 27a041e1f9..07a79a3c1e 100644 --- a/components/pochecker/Proj/pocheckermain.pp +++ b/components/pochecker/Proj/pocheckermain.pp @@ -76,7 +76,8 @@ resourcestring sErrorOnCreate = 'Error creating an instance of TPoFamily:' + LineEnding + '%s'; sErrorOnCleanup = 'An unrecoverable error occurred' + LineEnding + '%s' + LineEnding + 'Please close the program'; - sTotalErrors = 'Total errors found: %d'; + sTotalErrors = 'Total errors found : %d'; + sTotalWarnings = 'Total warnings found: %d'; //sNoErrorsFound = 'No errors found.'; sNoTestSelected = 'There are no tests selected.'; @@ -181,7 +182,7 @@ end; procedure TPoCheckerForm.ShowError(const Msg: String); begin - MessageDlg('GPoCheck', Msg, mtError, [mbOk], 0); + MessageDlg('Po-checker', Msg, mtError, [mbOk], 0); end; function TPoCheckerForm.TrySelectFile: Boolean; @@ -253,7 +254,7 @@ end; procedure TPoCheckerForm.RunSelectedTests; var Options: TPoTestOptions; - ErrorCount: Integer; + ErrorCount, WarningCount: Integer; SL: TStrings; ResultDlg: TResultDlgForm; begin @@ -271,11 +272,13 @@ begin if (not (ptoFindAllChilds in Options)) and Assigned(PoFamily.Child) and (PoFamily.ChildName <> FChoosenChildName) then PoFamily.ChildName := FChoosenChildName; - PoFamily.RunTests(Options, ErrorCount, SL); - if (ErrorCount > 0) then + PoFamily.RunTests(Options, ErrorCount, WarningCount, SL); + if (ErrorCount > 0) or (WarningCount > 0) then + debugln('RunSelectedTests: ',Format(sTotalErrors,[ErrorCount])); + debugln(' ',Format(sTotalWarnings,[WarningCount])); begin - debugln('RunSelectedTests: ',Format(sTotalErrors,[ErrorCount])); SL.Add(Format(sTotalErrors,[ErrorCount])); + SL.Add(Format(sTotalWarnings,[WarningCount])); ResultDlg := TResultDlgForm.Create(Nil); try ResultDlg.Log.Assign(SL); @@ -284,9 +287,8 @@ begin finally ResultDlg.Free; end; - end - else //no errors - NoErrLabel.Visible := True; + end; + NoErrLabel.Visible := (ErrorCount = 0); finally if Assigned(SL) then SL.Free; diff --git a/components/pochecker/pocheckermain.pp b/components/pochecker/pocheckermain.pp index d276d8dc1a..8b993cdc77 100644 --- a/components/pochecker/pocheckermain.pp +++ b/components/pochecker/pocheckermain.pp @@ -77,6 +77,7 @@ resourcestring sErrorOnCleanup = 'An unrecoverable error occurred' + LineEnding + '%s' + LineEnding + 'Please close the program'; sTotalErrors = 'Total errors / warnings found: %d'; + sTotalWarnings = 'Total warnings found: %d'; //sNoErrorsFound = 'No errors found.'; sNoTestSelected = 'There are no tests selected.'; @@ -191,7 +192,7 @@ end; procedure TPoCheckerForm.ShowError(const Msg: String); begin - MessageDlg('GPoCheck', Msg, mtError, [mbOk], 0); + MessageDlg('Po-checker', Msg, mtError, [mbOk], 0); end; function TPoCheckerForm.TrySelectFile: Boolean; @@ -263,7 +264,7 @@ end; procedure TPoCheckerForm.RunSelectedTests; var Options: TPoTestOptions; - ErrorCount: Integer; + ErrorCount, WarningCount: Integer; SL: TStrings; ResultDlg: TResultDlgForm; begin @@ -281,11 +282,13 @@ begin if (not (ptoFindAllChilds in Options)) and Assigned(PoFamily.Child) and (PoFamily.ChildName <> FChoosenChildName) then PoFamily.ChildName := FChoosenChildName; - PoFamily.RunTests(Options, ErrorCount, SL); - if (ErrorCount > 0) then + PoFamily.RunTests(Options, ErrorCount, WarningCount, SL); + if (ErrorCount > 0) or (WarningCount > 0) then + debugln('RunSelectedTests: ',Format(sTotalErrors,[ErrorCount])); + debugln(' ',Format(sTotalWarnings,[WarningCount])); begin - debugln('RunSelectedTests: ',Format(sTotalErrors,[ErrorCount])); SL.Add(Format(sTotalErrors,[ErrorCount])); + SL.Add(Format(sTotalWarnings,[WarningCount])); ResultDlg := TResultDlgForm.Create(Nil); try ResultDlg.Log.Assign(SL); @@ -294,9 +297,8 @@ begin finally ResultDlg.Free; end; - end - else //no errors - NoErrLabel.Visible := True; + end; + NoErrLabel.Visible := (ErrorCount = 0); finally if Assigned(SL) then SL.Free; diff --git a/components/pochecker/pofamilies.pp b/components/pochecker/pofamilies.pp index 0842e7e36c..885a09ef0c 100644 --- a/components/pochecker/pofamilies.pp +++ b/components/pochecker/pofamilies.pp @@ -63,10 +63,10 @@ Type procedure CheckFormatArgs(out ErrorCount: Integer; ErrorLog: TStrings); procedure CheckMissingIdentifiers(out ErrorCount: Integer; ErrorLog: TStrings); procedure CheckMismatchedOriginals(out ErrorCount: Integer; ErrorLog: TStrings); - procedure CheckDuplicateOriginals(out ErrorCount: Integer; ErrorLog: TStrings); + procedure CheckDuplicateOriginals(out WarningCount: Integer; ErrorLog: TStrings); public - procedure RunTests(const Options: TPoTestOptions; out ErrorCount: Integer; ErrorLog: TStrings); + procedure RunTests(const Options: TPoTestOptions; out ErrorCount, WarningCount: Integer; ErrorLog: TStrings); property Master: TSimplePoFile read FMaster; property Child: TSimplePoFile read FChild; @@ -107,10 +107,11 @@ resourcestring sCheckMissingIdentifiers = 'CheckMissingIdentifiers'; sCheckNrOfItems = 'CheckNrOfItems'; sCheckMismatchedOriginals = 'CheckMismatchedOriginals'; - sCheckDuplicateOriginals = 'CheckDiplicateOriginals'; + sCheckDuplicateOriginals = 'CheckDuplicateOriginals'; sIncompatibleFormatArgs = '[Line: %d] Incompatible format() arguments for:' ; - sNrErrorsFound = 'Found %d errors / warnings.'; + sNrErrorsFound = 'Found %d errors.'; + sNrWarningsFound = 'Found %d warnings.'; sLineInFileName = '[Line %d] in %s:'; sIdentifierNotFoundIn = 'Identifier [%s] not found in %s'; sMissingMasterIdentifier = 'Identifier [%s] found in %s, but it does not exist in %s'; @@ -127,12 +128,8 @@ resourcestring sMismatchOriginalsM = '%s: %s'; sMismatchOriginalsC = '%s: %s'; - sDuplicateOriginals = 'This resourcestring:'; - sDuplicateIdentifier = '#: %s'; - sDuplicateOriginal = 'msgid "%s"'; - sDuplicateContext = 'msgctxt "%s"'; - sDuplicateOriginals2 = 'has the same value as idenftifier %s at line %d'; - //sDuplicateOriginals3 = 'For this entry it is recommended to set: msgctxt="%s"'; + sDuplicateOriginals = 'The (untranslated) value "%s" is used for more than 1 entry:'; + sDuplicateLineNrWithValue = '[Line %d] %s'; //Helper functions @@ -515,49 +512,61 @@ begin //debugln('TPoFamily.CheckMismatchedOriginals: ',Dbgs(ErrorCount),' Errors'); end; -procedure TPoFamily.CheckDuplicateOriginals(out ErrorCount: Integer; +procedure TPoFamily.CheckDuplicateOriginals(out WarningCount: Integer; ErrorLog: TStrings); var i: Integer; - PoItem, Dup: TPOFileItem; + PoItem: TPOFileItem; + LastHash, CurHash: Cardinal; begin //debugln('TPoFamily.CheckMismatchedOriginals'); DoTestStart(PoTestOptionNames[ptoCheckDuplicateOriginals], ShortMasterName); - ErrorCount := NoError; - for i := FMaster.Count - 1 downto 0 do + WarningCount := 0; + + //debugln('TPoFamily.CehckDuplicateOriginals'); + //debugln('FMaster.OriginalList.Count = ',DbgS(FMaster.OriginalList.Count)); + LastHash := 0; + for i := 0 to FMaster.OriginalList.Count - 1 do begin - PoItem := FMaster.PoItems[i]; - Dup := FMaster.OriginalToItem(PoItem.Original); - if Assigned(Dup) and (Dup.Identifier <> PoItem.Identifier) {and (Dup.Context = '')} then + PoItem := TPoFileItem(FMaster.OriginalList.List[i]^.Data); + if Assigned(PoItem) then begin - if (ErrorCount = 0) then + CurHash := FMaster.OriginalList.List[i]^.HashValue ; + if ((PoItem.Tag and tgHasDup) = tgHasDup) then begin - ErrorLog.Add(Divider); - ErrorLog.Add(Format(sErrorsByTest,[sCheckDuplicateOriginals])); - ErrorLog.Add(ShortMasterName); - ErrorLog.Add(Divider); - ErrorLog.Add(''); + if (WarningCount = 0) then + begin + ErrorLog.Add(Divider); + ErrorLog.Add(Format(sErrorsByTest,[sCheckDuplicateOriginals])); + ErrorLog.Add(ShortMasterName); + ErrorLog.Add(Divider); + ErrorLog.Add(''); + end; + if (CurHash <> LastHash) then + begin//new value for PoItem.Original + LastHash := CurHash; + Inc(WarningCount); + if (WarningCount > 1) then ErrorLog.Add(''); + ErrorLog.Add(Format(sDuplicateOriginals,[PoItem.Original])); + //debugln(format('The (untranslated) value "%s" is used for more than 1 entry:',[PoItem.Original])); + end; + ErrorLog.Add(format(sDuplicateLineNrWithValue,[PoItem.LineNr,PoItem.Identifier])); + //debugln(format(sDuplicateLineNrWithValue,[PoItem.LineNr,PoItem.Identifier])); end; - Inc(ErrorCount); - ErrorLog.Add(Format(sLineNr,[PoItem.LineNr])); - ErrorLog.Add(sDuplicateOriginals); - ErrorLog.Add(Format(sDuplicateIdentifier,[PoItem.Identifier])); - ErrorLog.Add(Format(sDuplicateOriginal,[PoItem.Original])); - ErrorLog.Add(Format(sDuplicateContext,[PoItem.Context])); - ErrorLog.Add(Format(sDuplicateOriginals2,[Dup.Identifier,Dup.LineNr])); - //ErrorLog.Add(Format(sDuplicateOriginals3,[PoItem.Identifier])); - ErrorLog.Add(''); end; end; - if (ErrorCount > 0) then + + if (WarningCount > 0) then begin - ErrorLog.Add(Format(sNrErrorsFound,[ErrorCount])); + ErrorLog.Add(''); + ErrorLog.Add(Format(sNrWarningsFound,[WarningCount])); ErrorLog.Add(Divider); ErrorLog.Add(''); ErrorLog.Add(''); end; - DoTestEnd(PoTestOptionNames[ptoCheckDuplicateOriginals], ErrorCount); - //debugln('TPoFamily.CheckDuplicateOriginals: ',Dbgs(ErrorCount),' Errors'); + + DoTestEnd(PoTestOptionNames[ptoCheckDuplicateOriginals], WarningCount); + //debugln('TPoFamily.CheckDuplicateOriginals: ',Dbgs(WarningCount),' Errors'); end; { @@ -567,16 +576,17 @@ Pre conditions: * If a Child is assigned it must be child of Master } procedure TPoFamily.RunTests(const Options: TPoTestOptions; out - ErrorCount: Integer; ErrorLog: TStrings); + ErrorCount, WarningCount: Integer; ErrorLog: TStrings); var SL: TStringList; - CurrErrCnt: Integer; + CurrErrCnt, CurrWarnCnt: Integer; i: Integer; CurrChildName: String; S: String; begin SL := nil; ErrorCount := NoError; + WarningCount := NoError; if (not Assigned(FMaster)) and (not Assigned(FChild)) then begin {$ifdef DebugSimplePoFiles} @@ -626,7 +636,7 @@ begin else begin SL := TStringList.Create; - Sl.Add(FChildName); + if Assigned(FChild) then Sl.Add(FChildName); end; // for i := 0 to sl.count - 1 do debugln(extractfilename(sl.strings[i])); @@ -636,8 +646,23 @@ begin //First run checks that are Master-only if (ptoCheckDuplicateOriginals in Options) then begin - CheckDuplicateOriginals(CurrErrCnt, ErrorLog); - ErrorCount := CurrErrCnt + ErrorCount; + CheckDuplicateOriginals(CurrWarnCnt, ErrorLog); + WarningCount := CurrWarnCnt + WarningCount; + end; + + {$ifdef DebugSimplePoFiles} + Debugln('TPoFamily.RunTests: number of childs for testing = ',DbgS(Sl.Count)); + {$endif} + + if (Options - [ptoCheckDuplicateOriginals] <> []) and (Sl.Count = 0) then + begin + {$ifdef DebugSimplePoFiles} + Debugln('TPoFamily.RunTests: Warning: No child selected or found for selected tests'); + {$endif} + Inc(WarningCount); + ErrorLog.Add(Divider); + ErrorLog.Add('Warning: No child selected (or found) for selected tests.'); + ErrorLog.Add(Divider); end; //then iterate all Children diff --git a/components/pochecker/resultdlg.lfm b/components/pochecker/resultdlg.lfm index b318983b6c..86f34628f5 100644 --- a/components/pochecker/resultdlg.lfm +++ b/components/pochecker/resultdlg.lfm @@ -27,10 +27,10 @@ object ResultDlgForm: TResultDlgForm object CloseBtn: TBitBtn AnchorSideRight.Control = Panel1 AnchorSideRight.Side = asrBottom - Left = 652 - Height = 30 - Top = 10 - Width = 80 + Left = 661 + Height = 26 + Top = 12 + Width = 71 Anchors = [akRight] AutoSize = True BorderSpacing.Right = 10 @@ -41,26 +41,99 @@ object ResultDlgForm: TResultDlgForm end object SaveBtn: TBitBtn AnchorSideRight.Control = CloseBtn - Left = 536 - Height = 30 - Top = 10 - Width = 106 + Left = 553 + Height = 26 + Top = 12 + Width = 98 Anchors = [akRight] AutoSize = True BorderSpacing.Around = 10 Caption = '&Save to file' + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000BA6A368FB969 + 35B5B86935EEB76835FFB56835FFB46734FFB26634FFB06533FFAE6433FFAC63 + 32FFAA6232FFA96132FFA86031FFA76031FEA66031F1A86131C4BA6A35DEEBC6 + ADFFEAC5ADFFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFB + F8FFFEFBF8FFFEFBF8FFFEFBF8FFC89A7CFFC79879FFA76031EDBA6B37FEEDCA + B3FFE0A27AFFFEFAF7FF62C088FF62C088FF62C088FF62C088FF62C088FF62C0 + 88FF62C088FF62C088FFFDF9F6FFCA8D65FFC99B7CFFA76031FEBB6C38FFEECC + B6FFE1A27AFFFEFAF7FFBFDCC2FFBFDCC2FFBFDCC2FFBFDCC2FFBFDCC2FFBFDC + C2FFBFDCC2FFBFDCC2FFFDF9F6FFCD9068FFCC9E81FFA86132FFBB6B38FFEFCE + B8FFE1A279FFFEFAF7FF62C088FF62C088FF62C088FF62C088FF62C088FF62C0 + 88FF62C088FF62C088FFFDF9F6FFCF936AFFCEA384FFAA6132FFBA6A36FFEFD0 + BBFFE2A27AFFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFB + F8FFFEFBF8FFFEFBF8FFFEFBF8FFD3966DFFD2A78AFFAB6232FFBB6A36FFF0D2 + BEFFE2A37AFFE2A37AFFE1A37AFFE2A37BFFE1A37BFFE0A178FFDE9F77FFDD9F + 76FFDC9D74FFD99B72FFD89971FFD69970FFD5AB8EFFAD6333FFBB6A36FFF2D5 + C2FFE3A37AFFE3A37AFFE2A37BFFE2A37BFFE2A47BFFE1A279FFE0A178FFDEA0 + 77FFDE9E75FFDC9D74FFDA9B73FFD99B73FFDAB095FFAF6433FFBB6A36FFF2D8 + C5FFE3A47BFFE3A37AFFE3A47AFFE2A47BFFE2A37BFFE1A37BFFE1A279FFDFA0 + 77FFDE9F76FFDD9E74FFDB9C72FFDC9D74FFDDB59AFFB16534FFBB6B36FFF4D9 + C7FFE6A67DFFC88C64FFC98D65FFC98E67FFCB926CFFCB926DFFCA9069FFC88C + 65FFC88C64FFC88C64FFC88C64FFDA9C74FFE1BA9FFFB36634FFBB6B36FEF4DC + C9FFE7A77DFFF9ECE1FFF9ECE1FFF9EDE3FFFCF4EEFFFDFAF7FFFDF7F3FFFAED + E5FFF7E7DBFFF7E5D9FFF6E5D8FFDEA077FFE4BEA4FFB46734FFBC6B36FAF5DD + CCFFE7A87EFFFAF0E8FFFAF0E8FFC98D66FFFAF0E9FFFDF8F3FFFEFAF8FFFCF4 + EFFFF9E9DFFFF7E7DBFFF7E5D9FFE0A278FFE7C2A9FFB66835FFBC6B36F0F6DF + D0FFE8A87EFFFCF6F1FFFCF6F1FFC88C64FFFAF1E9FFFBF4EEFFFDFAF7FFFDF9 + F6FFFAF0E8FFF8E8DDFFF7E6DBFFE1A37AFFEFD5C3FFB76935FEBC6B36D8F6DF + D1FFE9AA80FFFEFAF6FFFDFAF6FFC88C64FFFBF3EEFFFBF1EAFFFCF6F2FFFEFB + F8FFFCF6F1FFF9ECE2FFF8E7DBFFEED0BAFFECD0BDFFBB703EF8BC6B369BF6E0 + D1FFF7E0D1FFFEFBF8FFFEFBF7FFFDF9F6FFFCF5F0FFFAF0EAFFFBF2EDFFFDF9 + F6FFFDFAF7FFFBF1EBFFF8E9DFFEECD0BDFBC9895EECB5693563BC6B3671BC6B + 3690BC6B36CCBC6B36EEBC6B36FABB6B36FEBB6B36FFBB6A36FFBB6A36FFBC6C + 39FFBD6E3BFFBB6D3AFFBB6B38EFBB703ECBB6693554FFFFFF00 + } + OnClick = SaveBtnClick TabOrder = 1 end object CopyBtn: TBitBtn AnchorSideRight.Control = SaveBtn - Left = 452 - Height = 30 - Top = 10 - Width = 74 + Left = 416 + Height = 26 + Top = 12 + Width = 127 Anchors = [akRight] AutoSize = True BorderSpacing.Around = 10 - Caption = 'CopyBtn' + Caption = 'Copy to clipboard' + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00C57342C1C67545E6C87545FEC775 + 45F3C87545F3C77545F3C77545F3C87546F4C57444E8CA7F53F1FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00C77949EDFCF3ECFFFAF1E8FFFAF0 + E7FFFBF1E9FFFBF2EAFFFBF2EAFFFBF2EBFFFDF4EEFFCA8054F9FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00CF8253FFEFF1E7FFFFE9D9FFFFEA + DBFFFFE9D9FFFFE7D7FFFFE5D2FFFFE2CBFFEFF2E8FFCE8156FFFFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00CC8352FBFBF5EEFFFFE9D9FFFFEA + DBFFFFE9D9FFFFE7D7FFFFE5D2FFFFE2CBFFFBF6EFFFCC8355FEC7794AB9C879 + 4BCEC87545DDC77545D4C87545D4C77545D4CA8452FFFFF7F1FFFFE9D9FFFFEA + DBFFFFE9D9FFFFE7D7FFFFE5D2FFFFE2CBFFFFF7F1FFCB8555FEC87C4ED3FCF3 + ECDEFAF1E8DEFAF0E7DEFBF1E9DEFBF2EADEE4BA91FFFFF7F0FFFFE7D5FFFDE7 + D6FFFDE6D4FFFCE4D0FFFBE3CBFFFADCC2FFFEF3E8FFCC8656FECF8253DEEFF1 + E7DEFFE9D9DEFFEADBDEFFE9D9DEFFE7D7DEE4BB91FFFFF7F2FFFEE7D5FFFEE7 + D5FFFDE5D1FFFAE0CAFFF9DEC4FFF7D9BCFFFDF2E7FFCC8757FECC8352DBFBF5 + EEDEFFE9D9DEFFEADBDEFFE9D9DEFFE7D7DEE4BB92FFFEF7F1FFFCE5D2FFFCE4 + D1FFFBE2CCFFF9DDC4FFF6D7BBFFF3D1AFFFFAEFE4FFCC8758FECA8452DBFFF7 + F1DEFFE9D9DEFFEADBDEFFE9D9DEFFE7D7DEE4BB92FFFEF6F0FFFCE2CDFFFCE3 + CDFFFADFC8FFF7D9BCFFF5E9DDFFFAF3EBFFFBF8F3FFCA8353FECB8553DBFFF7 + F0DEFFE7D5DEFDE7D6DEFDE6D4DEFCE4D0DEE4BB93FFFEF5EDFFFCDEC5FFFBE0 + C7FFF9DCC2FFF5D3B4FFFEF9F3FFFAE2C4FFECC193FFC37D4893CB8654DBFFF7 + F2DEFEE7D5DEFEE7D5DEFDE5D1DEFAE0CADEE5BE96FFFFFFFEFFFDF3E9FFFDF3 + EAFFFCF2E8FFFAEFE3FFFAF2E7FFEABB88FFCF8555B3B4693D0CCB8655DBFEF7 + F1DEFCE5D2DEFCE4D1DEFBE2CCDEF9DDC4DEEAC39DFFE6BF96FFE4BB92FFE4BB + 92FFD1A06CF5D09E6DF6CC965FDAC479427EB2673C09FFFFFF00CB8655DBFEF6 + F0DEFCE2CDDEFCE3CDDEFADFC8DEF7D9BCDEF5E9DDDEFAF3EBDEFBF8F3DECD95 + 65DCFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00CB8656DAFEF5 + EDDEFCDEC5DEFBE0C7DEF9DCC2DEF5D3B4DEFEF9F3DEFAE2C4DEECC193DEC37D + 4880FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00CA8554D0FFFF + FFDBFDF3E9DEFDF3EADEFCF2E8DEFAEFE3DEFAF2E7DEEABB88DECF85559CB469 + 3D0AFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00C77947AACC86 + 55CECC8857DECB8856DBCC8856DBCB8757DBCA8350D0C479426EB2673C08FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } OnClick = CopyBtnClick TabOrder = 0 end diff --git a/components/pochecker/resultdlg.pp b/components/pochecker/resultdlg.pp index eb379b41a7..89d9b36ee4 100644 --- a/components/pochecker/resultdlg.pp +++ b/components/pochecker/resultdlg.pp @@ -26,6 +26,7 @@ type procedure FormDestroy(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormShow(Sender: TObject); + procedure SaveBtnClick(Sender: TObject); private PoHL: TSynPoSyn; procedure SaveToFile; @@ -37,8 +38,11 @@ implementation {$R *.lfm} -const +ResourceString sSaveError = 'Error saving file:' + LineEnding + '%s'; + sSaveCaption = 'Save to file'; + sCopyCaption = 'Copy to clipboard'; + { TResultDlgForm } @@ -49,6 +53,8 @@ begin FLog := TStringList.Create; PoHL := TSynPoSyn.Create(Self); LogMemo.Highlighter := PoHL; + SaveBtn.Caption := sSaveCaption; + CopyBtn.Caption := sCopyCaption; end; procedure TResultDlgForm.FormClose(Sender: TObject; @@ -84,6 +90,18 @@ begin LogMemo.Lines.Assign(FLog); end; +procedure TResultDlgForm.SaveBtnClick(Sender: TObject); +begin + if SaveDialog.Execute then + begin + try + LogMemo.Lines.SaveToFile(SaveDialog.FileName); + except + on E: EStreamError do MessageDlg('Po-checker',Format(sSaveError,[SaveDialog.FileName]),mtError, [mbOk],0); + end; + end; +end; + procedure TResultDlgForm.SaveToFile; begin if SaveDialog.Execute then diff --git a/components/pochecker/simplepofiles.pp b/components/pochecker/simplepofiles.pp index 57855ebe27..170f83c047 100644 --- a/components/pochecker/simplepofiles.pp +++ b/components/pochecker/simplepofiles.pp @@ -101,6 +101,8 @@ type function GetPoItem(Index: Integer): TPoFileItem; protected property Items: TFPList read FItems; + public + property OriginalList: TStringHashList read FOriginalToItem; public constructor Create(const AFilename: String; const Full: Boolean = True); constructor Create(AStream: TStream; const Full: Boolean = True); @@ -148,6 +150,9 @@ function UTF8ToSystemCharSet(const s: string): string; inline; //function UpdatePoFile(Files: TStrings; const POFilename: string): boolean; +const + tgHasDup = $01; + implementation {$ifdef DebugSimplePoFiles} @@ -914,7 +919,8 @@ end; procedure TSimplePOFile.Add(const Identifier, OriginalValue, TranslatedValue, Comments, Context, Flags, PreviousID: string; LineNr: Integer); var - Item: TPOFileItem; + Item, OItem: TPOFileItem; + OIndex: Integer; //p: Integer; begin if (not FAllEntries) and (TranslatedValue='') then exit; @@ -924,7 +930,7 @@ begin Item.Context:=Context; Item.Flags:=Flags; Item.PreviousID:=PreviousID; - Item.Tag:=FTag; + Item.Tag:=0; Item.LineNr := LineNr; FItems.Add(Item); @@ -942,6 +948,14 @@ begin } //if FIdentifierToItem.Data[UpperCase(Identifier)]=nil then raise Exception.Create(''); + OIndex := FOriginalToItem.Find(OriginalValue); + if (OIndex > -1) then + begin + //TPoFileItem(FOriginalToItem.List[OIndex]^.Data).Tag := TPoFileItem(FOriginalToItem.List[OIndex]^.Data).Tag or tgHasDup; + OItem := TPoFileItem(FOriginalToItem.List[OIndex]^.Data); + OItem.Tag := OItem.Tag or tgHasDup; + Item.Tag := Item.Tag or tgHasDup; + end; FOriginalToItem.Add(OriginalValue,Item); //if FOriginalToItem.Data[OriginalValue]=nil then raise Exception.Create(''); end;