Changeset 151


Ignore:
Timestamp:
Jun 6, 2023, 11:15:57 AM (19 months ago)
Author:
chronos
Message:
  • Added: New file compare dialog with additional normalize options.
  • Modified: Compare action uses external compare tool.
Location:
trunk
Files:
3 added
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/Core.pas

    r149 r151  
    77  LastOpenedList, ApplicationInfo, PersistentForm, ScaleDPI, Common,
    88  Translator, DataFile, VCard, Menus, RegistryEx, Theme, AboutDialog,
    9   Registry;
     9  Registry, VCardFile;
    1010
    1111type
     
    8787    procedure AddItemToLastOpenedList(FileName: string);
    8888    procedure DoDataFileChange;
     89    function GetDefaultCompareTool: string;
    8990  public
    9091    DefaultDataFileClass: TDataFileClass;
     
    9495    LastContactTabIndex: Integer;
    9596    LastContactFileName: string;
    96     LastCompareFileName: string;
    9797    LastPhotoFileName: string;
    9898    LastQrCodeFileName: string;
     
    102102    ToolbarVisible: Boolean;
    103103    DefaultVcardVersion: string;
     104    DefaultPhoneCountryPrefix: string;
     105    CompareTool: string;
    104106    function GetProfileImage: TImage;
     107    function GetTempDir: string;
    105108    procedure FileNew;
    106109    procedure FileOpen(FileName: string);
     
    123126
    124127uses
    125   FormMain, FormSettings, FormFindDuplicity, TestCase,
    126   FormGenerate, FormError, FormFind, FormTest, FormSource, FormCompare,
    127   TestCases, VCardFile;
     128  FormMain, FormSettings, FormFindDuplicity, FormCompare, TestCase,
     129  FormGenerate, FormError, FormFind, FormTest, FormSource, FormCompareSideBySide,
     130  TestCases;
    128131
    129132resourcestring
     
    184187procedure TCore.AFileCompareExecute(Sender: TObject);
    185188var
    186   TempFile: TDataFile;
    187   TempFileName: string;
    188 begin
    189   TempFile := DefaultDataFileClass.Create(nil);
    190   try
    191     OpenDialog1.Filter := TempFile.GetFileFilter;
    192   finally
    193     TempFile.Free;
    194   end;
    195   OpenDialog1.DefaultExt := '';
    196   OpenDialog1.InitialDir := ExtractFileDir(Core.LastCompareFileName);
    197   OpenDialog1.FileName := ExtractFileName(Core.LastCompareFileName);
    198   OpenDialog1.Options := OpenDialog1.Options - [ofAllowMultiSelect];
    199   if OpenDialog1.Execute then begin
    200     with TFormCompare.Create(nil) do
    201     try
    202       TempFileName := GetTempDir + DirectorySeparator + Application.Title +
    203         DirectorySeparator + 'Compare' + VCardFileExt;
    204       ForceDirectories(ExtractFileDir(TempFileName));
    205       TVCardFile(DataFile).SaveToFile(TempFileName);
    206       LoadFileLeft(TempFileName);
    207       LoadFileRight(OpenDialog1.FileName);
    208       ShowModal;
    209     finally
    210       Free;
    211     end;
    212     Core.LastCompareFileName := OpenDialog1.FileName;
     189  FormCompare: TFormCompare;
     190begin
     191  FormCompare := TFormCompare.Create(nil);
     192  try
     193    FormCompare.ShowModal;
     194  finally
     195    FreeAndNil(FormCompare);
    213196  end;
    214197end;
     
    556539    LastPhotoFileName := ReadStringWithDefault('LastPhotoFileName', '');
    557540    LastQrCodeFileName := ReadStringWithDefault('LastQrCodeFileName', '');
    558     LastCompareFileName := ReadStringWithDefault('LastCompareFileName', '');
     541    CompareTool := ReadStringWithDefault('CompareTool', GetDefaultCompareTool);
     542    DefaultPhoneCountryPrefix := ReadStringWithDefault('DefaultPhoneCountryPrefix', DefaultPhoneCountryPrefix);
    559543  finally
    560544    Free;
     
    583567    WriteString('LastPhotoFileName', LastPhotoFileName);
    584568    WriteString('LastQrCodeFileName', LastQrCodeFileName);
    585     WriteString('LastCompareFileName', LastCompareFileName);
     569    WriteString('CompareTool', CompareTool);
     570    WriteString('DefaultPhoneCountryPrefix', DefaultPhoneCountryPrefix);
    586571  finally
    587572    Free;
     
    609594end;
    610595
     596function TCore.GetDefaultCompareTool: string;
     597const
     598  KDiff3 = '/usr/bin/kdiff3';
     599  Kompare = '/usr/bin/kompare';
     600  Meld = '/usr/bin/meld';
     601  Diffuse = '/usr/bin/diffuse';
     602  BeyondCompare = '/usr/bin/bcompare';
     603begin
     604  if FileExists(KDiff3) then Result := KDiff3
     605  else if FileExists(Meld) then Result := Meld
     606  else if FileExists(Kompare) then Result := Kompare
     607  else if FileExists(Diffuse) then Result := Diffuse
     608  else if FileExists(BeyondCompare) then Result := BeyondCompare
     609  else Result := '';
     610end;
     611
    611612function TCore.GetProfileImage: TImage;
    612613begin
     
    617618  end;
    618619  Result := ProfileImage;
     620end;
     621
     622function TCore.GetTempDir: string;
     623begin
     624  Result := SysUtils.GetTempDir + Application.Title;
    619625end;
    620626
  • trunk/Forms/FormCompare.lfm

    r149 r151  
    11object FormCompare: TFormCompare
    2   Left = 574
    3   Height = 888
    4   Top = 322
    5   Width = 1191
     2  Left = 602
     3  Height = 456
     4  Top = 639
     5  Width = 867
    66  Caption = 'Compare'
    7   ClientHeight = 854
    8   ClientWidth = 1191
     7  ClientHeight = 456
     8  ClientWidth = 867
    99  DesignTimePPI = 144
    10   Menu = MainMenu1
    11   OnActivate = FormActivate
    1210  OnClose = FormClose
    1311  OnCreate = FormCreate
    1412  OnDestroy = FormDestroy
    15   OnResize = FormResize
    1613  OnShow = FormShow
    17   LCLVersion = '2.2.0.4'
    18   object PanelLeft: TPanel
    19     Left = 0
    20     Height = 854
    21     Top = 0
    22     Width = 584
    23     Align = alLeft
    24     BevelOuter = bvNone
    25     ClientHeight = 854
    26     ClientWidth = 584
     14  LCLVersion = '2.2.6.0'
     15  object EditAnotherFile: TEdit
     16    Left = 144
     17    Height = 43
     18    Top = 19
     19    Width = 570
     20    Anchors = [akTop, akLeft, akRight]
    2721    TabOrder = 0
    28     object EditLeftFileName: TEdit
    29       Left = 15
    30       Height = 42
    31       Top = 11
    32       Width = 523
    33       Anchors = [akTop, akLeft, akRight]
    34       ReadOnly = True
    35       TabOrder = 0
    36     end
    37     inline SynEditLeft: TSynEditEx
    38       Left = 15
    39       Height = 781
    40       Top = 61
    41       Width = 562
    42       Anchors = [akTop, akLeft, akRight, akBottom]
    43       Font.Height = 12
    44       Font.Name = 'DejaVu Sans Mono'
    45       Font.Pitch = fpFixed
    46       Font.Quality = fqNonAntialiased
    47       ParentColor = False
    48       ParentFont = False
    49       TabOrder = 1
    50       Gutter.Width = 75
    51       Gutter.MouseActions = <>
    52       RightGutter.Width = 0
    53       RightGutter.MouseActions = <>
    54       Keystrokes = <     
    55         item
    56           Command = ecUp
    57           ShortCut = 38
    58         end     
    59         item
    60           Command = ecSelUp
    61           ShortCut = 8230
    62         end     
    63         item
    64           Command = ecScrollUp
    65           ShortCut = 16422
    66         end     
    67         item
    68           Command = ecDown
    69           ShortCut = 40
    70         end     
    71         item
    72           Command = ecSelDown
    73           ShortCut = 8232
    74         end     
    75         item
    76           Command = ecScrollDown
    77           ShortCut = 16424
    78         end     
    79         item
    80           Command = ecLeft
    81           ShortCut = 37
    82         end     
    83         item
    84           Command = ecSelLeft
    85           ShortCut = 8229
    86         end     
    87         item
    88           Command = ecWordLeft
    89           ShortCut = 16421
    90         end     
    91         item
    92           Command = ecSelWordLeft
    93           ShortCut = 24613
    94         end     
    95         item
    96           Command = ecRight
    97           ShortCut = 39
    98         end     
    99         item
    100           Command = ecSelRight
    101           ShortCut = 8231
    102         end     
    103         item
    104           Command = ecWordRight
    105           ShortCut = 16423
    106         end     
    107         item
    108           Command = ecSelWordRight
    109           ShortCut = 24615
    110         end     
    111         item
    112           Command = ecPageDown
    113           ShortCut = 34
    114         end     
    115         item
    116           Command = ecSelPageDown
    117           ShortCut = 8226
    118         end     
    119         item
    120           Command = ecPageBottom
    121           ShortCut = 16418
    122         end     
    123         item
    124           Command = ecSelPageBottom
    125           ShortCut = 24610
    126         end     
    127         item
    128           Command = ecPageUp
    129           ShortCut = 33
    130         end     
    131         item
    132           Command = ecSelPageUp
    133           ShortCut = 8225
    134         end     
    135         item
    136           Command = ecPageTop
    137           ShortCut = 16417
    138         end     
    139         item
    140           Command = ecSelPageTop
    141           ShortCut = 24609
    142         end     
    143         item
    144           Command = ecLineStart
    145           ShortCut = 36
    146         end     
    147         item
    148           Command = ecSelLineStart
    149           ShortCut = 8228
    150         end     
    151         item
    152           Command = ecEditorTop
    153           ShortCut = 16420
    154         end     
    155         item
    156           Command = ecSelEditorTop
    157           ShortCut = 24612
    158         end     
    159         item
    160           Command = ecLineEnd
    161           ShortCut = 35
    162         end     
    163         item
    164           Command = ecSelLineEnd
    165           ShortCut = 8227
    166         end     
    167         item
    168           Command = ecEditorBottom
    169           ShortCut = 16419
    170         end     
    171         item
    172           Command = ecSelEditorBottom
    173           ShortCut = 24611
    174         end     
    175         item
    176           Command = ecToggleMode
    177           ShortCut = 45
    178         end     
    179         item
    180           Command = ecCopy
    181           ShortCut = 16429
    182         end     
    183         item
    184           Command = ecPaste
    185           ShortCut = 8237
    186         end     
    187         item
    188           Command = ecDeleteChar
    189           ShortCut = 46
    190         end     
    191         item
    192           Command = ecCut
    193           ShortCut = 8238
    194         end     
    195         item
    196           Command = ecDeleteLastChar
    197           ShortCut = 8
    198         end     
    199         item
    200           Command = ecDeleteLastChar
    201           ShortCut = 8200
    202         end     
    203         item
    204           Command = ecDeleteLastWord
    205           ShortCut = 16392
    206         end     
    207         item
    208           Command = ecUndo
    209           ShortCut = 32776
    210         end     
    211         item
    212           Command = ecRedo
    213           ShortCut = 40968
    214         end     
    215         item
    216           Command = ecLineBreak
    217           ShortCut = 13
    218         end     
    219         item
    220           Command = ecSelectAll
    221           ShortCut = 16449
    222         end     
    223         item
    224           Command = ecCopy
    225           ShortCut = 16451
    226         end     
    227         item
    228           Command = ecBlockIndent
    229           ShortCut = 24649
    230         end     
    231         item
    232           Command = ecLineBreak
    233           ShortCut = 16461
    234         end     
    235         item
    236           Command = ecInsertLine
    237           ShortCut = 16462
    238         end     
    239         item
    240           Command = ecDeleteWord
    241           ShortCut = 16468
    242         end     
    243         item
    244           Command = ecBlockUnindent
    245           ShortCut = 24661
    246         end     
    247         item
    248           Command = ecPaste
    249           ShortCut = 16470
    250         end     
    251         item
    252           Command = ecCut
    253           ShortCut = 16472
    254         end     
    255         item
    256           Command = ecDeleteLine
    257           ShortCut = 16473
    258         end     
    259         item
    260           Command = ecDeleteEOL
    261           ShortCut = 24665
    262         end     
    263         item
    264           Command = ecUndo
    265           ShortCut = 16474
    266         end     
    267         item
    268           Command = ecRedo
    269           ShortCut = 24666
    270         end     
    271         item
    272           Command = ecGotoMarker0
    273           ShortCut = 16432
    274         end     
    275         item
    276           Command = ecGotoMarker1
    277           ShortCut = 16433
    278         end     
    279         item
    280           Command = ecGotoMarker2
    281           ShortCut = 16434
    282         end     
    283         item
    284           Command = ecGotoMarker3
    285           ShortCut = 16435
    286         end     
    287         item
    288           Command = ecGotoMarker4
    289           ShortCut = 16436
    290         end     
    291         item
    292           Command = ecGotoMarker5
    293           ShortCut = 16437
    294         end     
    295         item
    296           Command = ecGotoMarker6
    297           ShortCut = 16438
    298         end     
    299         item
    300           Command = ecGotoMarker7
    301           ShortCut = 16439
    302         end     
    303         item
    304           Command = ecGotoMarker8
    305           ShortCut = 16440
    306         end     
    307         item
    308           Command = ecGotoMarker9
    309           ShortCut = 16441
    310         end     
    311         item
    312           Command = ecSetMarker0
    313           ShortCut = 24624
    314         end     
    315         item
    316           Command = ecSetMarker1
    317           ShortCut = 24625
    318         end     
    319         item
    320           Command = ecSetMarker2
    321           ShortCut = 24626
    322         end     
    323         item
    324           Command = ecSetMarker3
    325           ShortCut = 24627
    326         end     
    327         item
    328           Command = ecSetMarker4
    329           ShortCut = 24628
    330         end     
    331         item
    332           Command = ecSetMarker5
    333           ShortCut = 24629
    334         end     
    335         item
    336           Command = ecSetMarker6
    337           ShortCut = 24630
    338         end     
    339         item
    340           Command = ecSetMarker7
    341           ShortCut = 24631
    342         end     
    343         item
    344           Command = ecSetMarker8
    345           ShortCut = 24632
    346         end     
    347         item
    348           Command = ecSetMarker9
    349           ShortCut = 24633
    350         end     
    351         item
    352           Command = EcFoldLevel1
    353           ShortCut = 41009
    354         end     
    355         item
    356           Command = EcFoldLevel2
    357           ShortCut = 41010
    358         end     
    359         item
    360           Command = EcFoldLevel3
    361           ShortCut = 41011
    362         end     
    363         item
    364           Command = EcFoldLevel4
    365           ShortCut = 41012
    366         end     
    367         item
    368           Command = EcFoldLevel5
    369           ShortCut = 41013
    370         end     
    371         item
    372           Command = EcFoldLevel6
    373           ShortCut = 41014
    374         end     
    375         item
    376           Command = EcFoldLevel7
    377           ShortCut = 41015
    378         end     
    379         item
    380           Command = EcFoldLevel8
    381           ShortCut = 41016
    382         end     
    383         item
    384           Command = EcFoldLevel9
    385           ShortCut = 41017
    386         end     
    387         item
    388           Command = EcFoldLevel0
    389           ShortCut = 41008
    390         end     
    391         item
    392           Command = EcFoldCurrent
    393           ShortCut = 41005
    394         end     
    395         item
    396           Command = EcUnFoldCurrent
    397           ShortCut = 41003
    398         end     
    399         item
    400           Command = EcToggleMarkupWord
    401           ShortCut = 32845
    402         end     
    403         item
    404           Command = ecNormalSelect
    405           ShortCut = 24654
    406         end     
    407         item
    408           Command = ecColumnSelect
    409           ShortCut = 24643
    410         end     
    411         item
    412           Command = ecLineSelect
    413           ShortCut = 24652
    414         end     
    415         item
    416           Command = ecTab
    417           ShortCut = 9
    418         end     
    419         item
    420           Command = ecShiftTab
    421           ShortCut = 8201
    422         end     
    423         item
    424           Command = ecMatchBracket
    425           ShortCut = 24642
    426         end     
    427         item
    428           Command = ecColSelUp
    429           ShortCut = 40998
    430         end     
    431         item
    432           Command = ecColSelDown
    433           ShortCut = 41000
    434         end     
    435         item
    436           Command = ecColSelLeft
    437           ShortCut = 40997
    438         end     
    439         item
    440           Command = ecColSelRight
    441           ShortCut = 40999
    442         end     
    443         item
    444           Command = ecColSelPageDown
    445           ShortCut = 40994
    446         end     
    447         item
    448           Command = ecColSelPageBottom
    449           ShortCut = 57378
    450         end     
    451         item
    452           Command = ecColSelPageUp
    453           ShortCut = 40993
    454         end     
    455         item
    456           Command = ecColSelPageTop
    457           ShortCut = 57377
    458         end     
    459         item
    460           Command = ecColSelLineStart
    461           ShortCut = 40996
    462         end     
    463         item
    464           Command = ecColSelLineEnd
    465           ShortCut = 40995
    466         end     
    467         item
    468           Command = ecColSelEditorTop
    469           ShortCut = 57380
    470         end     
    471         item
    472           Command = ecColSelEditorBottom
    473           ShortCut = 57379
    474         end>
    475       MouseActions = <>
    476       MouseTextActions = <>
    477       MouseSelActions = <>
    478       VisibleSpecialChars = [vscSpace, vscTabAtLast]
    479       SelectedColor.BackPriority = 50
    480       SelectedColor.ForePriority = 50
    481       SelectedColor.FramePriority = 50
    482       SelectedColor.BoldPriority = 50
    483       SelectedColor.ItalicPriority = 50
    484       SelectedColor.UnderlinePriority = 50
    485       SelectedColor.StrikeOutPriority = 50
    486       BracketHighlightStyle = sbhsBoth
    487       BracketMatchColor.Background = clNone
    488       BracketMatchColor.Foreground = clNone
    489       BracketMatchColor.Style = [fsBold]
    490       FoldedCodeColor.Background = clNone
    491       FoldedCodeColor.Foreground = clGray
    492       FoldedCodeColor.FrameColor = clGray
    493       MouseLinkColor.Background = clNone
    494       MouseLinkColor.Foreground = clBlue
    495       LineHighlightColor.Background = clNone
    496       LineHighlightColor.Foreground = clNone
    497       OnChange = SynEditLeftChange
    498       OnScroll = SynEditLeftScroll
    499       inline SynLeftGutterPartList1: TSynGutterPartList
    500         object SynGutterMarks1: TSynGutterMarks
    501           Width = 36
    502           MouseActions = <>
    503         end
    504         object SynGutterLineNumber1: TSynGutterLineNumber
    505           Width = 15
    506           MouseActions = <>
    507           MarkupInfo.Background = clBtnFace
    508           MarkupInfo.Foreground = clNone
    509           DigitCount = 2
    510           ShowOnlyLineNumbersMultiplesOf = 1
    511           ZeroStart = False
    512           LeadingZeros = False
    513         end
    514         object SynGutterChanges1: TSynGutterChanges
    515           Width = 6
    516           MouseActions = <>
    517           ModifiedColor = 59900
    518           SavedColor = clGreen
    519         end
    520         object SynGutterSeparator1: TSynGutterSeparator
    521           Width = 3
    522           MouseActions = <>
    523           MarkupInfo.Background = clWhite
    524           MarkupInfo.Foreground = clGray
    525         end
    526         object SynGutterCodeFolding1: TSynGutterCodeFolding
    527           Width = 15
    528           MouseActions = <>
    529           MarkupInfo.Background = clNone
    530           MarkupInfo.Foreground = clGray
    531           MouseActionsExpanded = <>
    532           MouseActionsCollapsed = <>
    533         end
    534       end
    535     end
    536     object SpeedButtonOpenLeft: TSpeedButton
    537       Left = 542
    538       Height = 33
    539       Top = 14
    540       Width = 35
    541       Action = AFileOpenLeft
    542       Anchors = [akTop, akRight]
    543       Images = Core.ImageList1
    544       ImageIndex = 5
    545       ShowCaption = False
    546     end
    54722  end
    548   object Splitter1: TSplitter
    549     Left = 584
    550     Height = 854
    551     Top = 0
    552     Width = 8
     23  object ButtonBrowse: TButton
     24    Left = 730
     25    Height = 38
     26    Top = 19
     27    Width = 113
     28    Anchors = [akTop, akRight]
     29    Caption = 'Browse'
     30    OnClick = ButtonBrowseClick
     31    TabOrder = 1
    55332  end
    554   object PanelRight: TPanel
    555     Left = 592
    556     Height = 854
    557     Top = 0
    558     Width = 599
    559     Align = alClient
    560     BevelOuter = bvNone
    561     ClientHeight = 854
    562     ClientWidth = 599
     33  object Label1: TLabel
     34    Left = 21
     35    Height = 26
     36    Top = 26
     37    Width = 104
     38    Caption = 'Another file:'
     39    ParentColor = False
     40  end
     41  object ButtonCancel: TButton
     42    Left = 730
     43    Height = 38
     44    Top = 389
     45    Width = 113
     46    Anchors = [akRight, akBottom]
     47    Caption = 'Cancel'
     48    ModalResult = 2
    56349    TabOrder = 2
    564     object EditRightFileName: TEdit
    565       Left = 12
    566       Height = 42
    567       Top = 11
    568       Width = 527
    569       Anchors = [akTop, akLeft, akRight]
    570       ReadOnly = True
    571       TabOrder = 0
    572     end
    573     inline SynEditRight: TSynEditEx
    574       Left = 15
    575       Height = 781
    576       Top = 61
    577       Width = 571
    578       Anchors = [akTop, akLeft, akRight, akBottom]
    579       Font.Height = 12
    580       Font.Name = 'DejaVu Sans Mono'
    581       Font.Pitch = fpFixed
    582       Font.Quality = fqNonAntialiased
    583       ParentColor = False
    584       ParentFont = False
    585       TabOrder = 1
    586       Gutter.Width = 75
    587       Gutter.MouseActions = <>
    588       RightGutter.Width = 0
    589       RightGutter.MouseActions = <>
    590       Keystrokes = <     
    591         item
    592           Command = ecUp
    593           ShortCut = 38
    594         end     
    595         item
    596           Command = ecSelUp
    597           ShortCut = 8230
    598         end     
    599         item
    600           Command = ecScrollUp
    601           ShortCut = 16422
    602         end     
    603         item
    604           Command = ecDown
    605           ShortCut = 40
    606         end     
    607         item
    608           Command = ecSelDown
    609           ShortCut = 8232
    610         end     
    611         item
    612           Command = ecScrollDown
    613           ShortCut = 16424
    614         end     
    615         item
    616           Command = ecLeft
    617           ShortCut = 37
    618         end     
    619         item
    620           Command = ecSelLeft
    621           ShortCut = 8229
    622         end     
    623         item
    624           Command = ecWordLeft
    625           ShortCut = 16421
    626         end     
    627         item
    628           Command = ecSelWordLeft
    629           ShortCut = 24613
    630         end     
    631         item
    632           Command = ecRight
    633           ShortCut = 39
    634         end     
    635         item
    636           Command = ecSelRight
    637           ShortCut = 8231
    638         end     
    639         item
    640           Command = ecWordRight
    641           ShortCut = 16423
    642         end     
    643         item
    644           Command = ecSelWordRight
    645           ShortCut = 24615
    646         end     
    647         item
    648           Command = ecPageDown
    649           ShortCut = 34
    650         end     
    651         item
    652           Command = ecSelPageDown
    653           ShortCut = 8226
    654         end     
    655         item
    656           Command = ecPageBottom
    657           ShortCut = 16418
    658         end     
    659         item
    660           Command = ecSelPageBottom
    661           ShortCut = 24610
    662         end     
    663         item
    664           Command = ecPageUp
    665           ShortCut = 33
    666         end     
    667         item
    668           Command = ecSelPageUp
    669           ShortCut = 8225
    670         end     
    671         item
    672           Command = ecPageTop
    673           ShortCut = 16417
    674         end     
    675         item
    676           Command = ecSelPageTop
    677           ShortCut = 24609
    678         end     
    679         item
    680           Command = ecLineStart
    681           ShortCut = 36
    682         end     
    683         item
    684           Command = ecSelLineStart
    685           ShortCut = 8228
    686         end     
    687         item
    688           Command = ecEditorTop
    689           ShortCut = 16420
    690         end     
    691         item
    692           Command = ecSelEditorTop
    693           ShortCut = 24612
    694         end     
    695         item
    696           Command = ecLineEnd
    697           ShortCut = 35
    698         end     
    699         item
    700           Command = ecSelLineEnd
    701           ShortCut = 8227
    702         end     
    703         item
    704           Command = ecEditorBottom
    705           ShortCut = 16419
    706         end     
    707         item
    708           Command = ecSelEditorBottom
    709           ShortCut = 24611
    710         end     
    711         item
    712           Command = ecToggleMode
    713           ShortCut = 45
    714         end     
    715         item
    716           Command = ecCopy
    717           ShortCut = 16429
    718         end     
    719         item
    720           Command = ecPaste
    721           ShortCut = 8237
    722         end     
    723         item
    724           Command = ecDeleteChar
    725           ShortCut = 46
    726         end     
    727         item
    728           Command = ecCut
    729           ShortCut = 8238
    730         end     
    731         item
    732           Command = ecDeleteLastChar
    733           ShortCut = 8
    734         end     
    735         item
    736           Command = ecDeleteLastChar
    737           ShortCut = 8200
    738         end     
    739         item
    740           Command = ecDeleteLastWord
    741           ShortCut = 16392
    742         end     
    743         item
    744           Command = ecUndo
    745           ShortCut = 32776
    746         end     
    747         item
    748           Command = ecRedo
    749           ShortCut = 40968
    750         end     
    751         item
    752           Command = ecLineBreak
    753           ShortCut = 13
    754         end     
    755         item
    756           Command = ecSelectAll
    757           ShortCut = 16449
    758         end     
    759         item
    760           Command = ecCopy
    761           ShortCut = 16451
    762         end     
    763         item
    764           Command = ecBlockIndent
    765           ShortCut = 24649
    766         end     
    767         item
    768           Command = ecLineBreak
    769           ShortCut = 16461
    770         end     
    771         item
    772           Command = ecInsertLine
    773           ShortCut = 16462
    774         end     
    775         item
    776           Command = ecDeleteWord
    777           ShortCut = 16468
    778         end     
    779         item
    780           Command = ecBlockUnindent
    781           ShortCut = 24661
    782         end     
    783         item
    784           Command = ecPaste
    785           ShortCut = 16470
    786         end     
    787         item
    788           Command = ecCut
    789           ShortCut = 16472
    790         end     
    791         item
    792           Command = ecDeleteLine
    793           ShortCut = 16473
    794         end     
    795         item
    796           Command = ecDeleteEOL
    797           ShortCut = 24665
    798         end     
    799         item
    800           Command = ecUndo
    801           ShortCut = 16474
    802         end     
    803         item
    804           Command = ecRedo
    805           ShortCut = 24666
    806         end     
    807         item
    808           Command = ecGotoMarker0
    809           ShortCut = 16432
    810         end     
    811         item
    812           Command = ecGotoMarker1
    813           ShortCut = 16433
    814         end     
    815         item
    816           Command = ecGotoMarker2
    817           ShortCut = 16434
    818         end     
    819         item
    820           Command = ecGotoMarker3
    821           ShortCut = 16435
    822         end     
    823         item
    824           Command = ecGotoMarker4
    825           ShortCut = 16436
    826         end     
    827         item
    828           Command = ecGotoMarker5
    829           ShortCut = 16437
    830         end     
    831         item
    832           Command = ecGotoMarker6
    833           ShortCut = 16438
    834         end     
    835         item
    836           Command = ecGotoMarker7
    837           ShortCut = 16439
    838         end     
    839         item
    840           Command = ecGotoMarker8
    841           ShortCut = 16440
    842         end     
    843         item
    844           Command = ecGotoMarker9
    845           ShortCut = 16441
    846         end     
    847         item
    848           Command = ecSetMarker0
    849           ShortCut = 24624
    850         end     
    851         item
    852           Command = ecSetMarker1
    853           ShortCut = 24625
    854         end     
    855         item
    856           Command = ecSetMarker2
    857           ShortCut = 24626
    858         end     
    859         item
    860           Command = ecSetMarker3
    861           ShortCut = 24627
    862         end     
    863         item
    864           Command = ecSetMarker4
    865           ShortCut = 24628
    866         end     
    867         item
    868           Command = ecSetMarker5
    869           ShortCut = 24629
    870         end     
    871         item
    872           Command = ecSetMarker6
    873           ShortCut = 24630
    874         end     
    875         item
    876           Command = ecSetMarker7
    877           ShortCut = 24631
    878         end     
    879         item
    880           Command = ecSetMarker8
    881           ShortCut = 24632
    882         end     
    883         item
    884           Command = ecSetMarker9
    885           ShortCut = 24633
    886         end     
    887         item
    888           Command = EcFoldLevel1
    889           ShortCut = 41009
    890         end     
    891         item
    892           Command = EcFoldLevel2
    893           ShortCut = 41010
    894         end     
    895         item
    896           Command = EcFoldLevel3
    897           ShortCut = 41011
    898         end     
    899         item
    900           Command = EcFoldLevel4
    901           ShortCut = 41012
    902         end     
    903         item
    904           Command = EcFoldLevel5
    905           ShortCut = 41013
    906         end     
    907         item
    908           Command = EcFoldLevel6
    909           ShortCut = 41014
    910         end     
    911         item
    912           Command = EcFoldLevel7
    913           ShortCut = 41015
    914         end     
    915         item
    916           Command = EcFoldLevel8
    917           ShortCut = 41016
    918         end     
    919         item
    920           Command = EcFoldLevel9
    921           ShortCut = 41017
    922         end     
    923         item
    924           Command = EcFoldLevel0
    925           ShortCut = 41008
    926         end     
    927         item
    928           Command = EcFoldCurrent
    929           ShortCut = 41005
    930         end     
    931         item
    932           Command = EcUnFoldCurrent
    933           ShortCut = 41003
    934         end     
    935         item
    936           Command = EcToggleMarkupWord
    937           ShortCut = 32845
    938         end     
    939         item
    940           Command = ecNormalSelect
    941           ShortCut = 24654
    942         end     
    943         item
    944           Command = ecColumnSelect
    945           ShortCut = 24643
    946         end     
    947         item
    948           Command = ecLineSelect
    949           ShortCut = 24652
    950         end     
    951         item
    952           Command = ecTab
    953           ShortCut = 9
    954         end     
    955         item
    956           Command = ecShiftTab
    957           ShortCut = 8201
    958         end     
    959         item
    960           Command = ecMatchBracket
    961           ShortCut = 24642
    962         end     
    963         item
    964           Command = ecColSelUp
    965           ShortCut = 40998
    966         end     
    967         item
    968           Command = ecColSelDown
    969           ShortCut = 41000
    970         end     
    971         item
    972           Command = ecColSelLeft
    973           ShortCut = 40997
    974         end     
    975         item
    976           Command = ecColSelRight
    977           ShortCut = 40999
    978         end     
    979         item
    980           Command = ecColSelPageDown
    981           ShortCut = 40994
    982         end     
    983         item
    984           Command = ecColSelPageBottom
    985           ShortCut = 57378
    986         end     
    987         item
    988           Command = ecColSelPageUp
    989           ShortCut = 40993
    990         end     
    991         item
    992           Command = ecColSelPageTop
    993           ShortCut = 57377
    994         end     
    995         item
    996           Command = ecColSelLineStart
    997           ShortCut = 40996
    998         end     
    999         item
    1000           Command = ecColSelLineEnd
    1001           ShortCut = 40995
    1002         end     
    1003         item
    1004           Command = ecColSelEditorTop
    1005           ShortCut = 57380
    1006         end     
    1007         item
    1008           Command = ecColSelEditorBottom
    1009           ShortCut = 57379
    1010         end>
    1011       MouseActions = <>
    1012       MouseTextActions = <>
    1013       MouseSelActions = <>
    1014       VisibleSpecialChars = [vscSpace, vscTabAtLast]
    1015       SelectedColor.BackPriority = 50
    1016       SelectedColor.ForePriority = 50
    1017       SelectedColor.FramePriority = 50
    1018       SelectedColor.BoldPriority = 50
    1019       SelectedColor.ItalicPriority = 50
    1020       SelectedColor.UnderlinePriority = 50
    1021       SelectedColor.StrikeOutPriority = 50
    1022       BracketHighlightStyle = sbhsBoth
    1023       BracketMatchColor.Background = clNone
    1024       BracketMatchColor.Foreground = clNone
    1025       BracketMatchColor.Style = [fsBold]
    1026       FoldedCodeColor.Background = clNone
    1027       FoldedCodeColor.Foreground = clGray
    1028       FoldedCodeColor.FrameColor = clGray
    1029       MouseLinkColor.Background = clNone
    1030       MouseLinkColor.Foreground = clBlue
    1031       LineHighlightColor.Background = clNone
    1032       LineHighlightColor.Foreground = clNone
    1033       OnChange = SynEditRightChange
    1034       OnScroll = SynEditRightScroll
    1035       inline SynLeftGutterPartList1: TSynGutterPartList
    1036         object SynGutterMarks1: TSynGutterMarks
    1037           Width = 36
    1038           MouseActions = <>
    1039         end
    1040         object SynGutterLineNumber1: TSynGutterLineNumber
    1041           Width = 15
    1042           MouseActions = <>
    1043           MarkupInfo.Background = clBtnFace
    1044           MarkupInfo.Foreground = clNone
    1045           DigitCount = 2
    1046           ShowOnlyLineNumbersMultiplesOf = 1
    1047           ZeroStart = False
    1048           LeadingZeros = False
    1049         end
    1050         object SynGutterChanges1: TSynGutterChanges
    1051           Width = 6
    1052           MouseActions = <>
    1053           ModifiedColor = 59900
    1054           SavedColor = clGreen
    1055         end
    1056         object SynGutterSeparator1: TSynGutterSeparator
    1057           Width = 3
    1058           MouseActions = <>
    1059           MarkupInfo.Background = clWhite
    1060           MarkupInfo.Foreground = clGray
    1061         end
    1062         object SynGutterCodeFolding1: TSynGutterCodeFolding
    1063           Width = 15
    1064           MouseActions = <>
    1065           MarkupInfo.Background = clNone
    1066           MarkupInfo.Foreground = clGray
    1067           MouseActionsExpanded = <>
    1068           MouseActionsCollapsed = <>
    1069         end
    1070       end
    1071     end
    1072     object SpeedButtonOpenRight: TSpeedButton
    1073       Left = 551
    1074       Height = 33
    1075       Top = 15
    1076       Width = 35
    1077       Action = AFileOpenRight
    1078       Anchors = [akTop, akRight]
    1079       Images = Core.ImageList1
    1080       ImageIndex = 2
    1081       ShowCaption = False
    1082     end
    108350  end
    1084   object OpenDialogSide: TOpenDialog
    1085     Left = 323
    1086     Top = 346
     51  object ButtonCompare: TButton
     52    Left = 586
     53    Height = 38
     54    Top = 389
     55    Width = 113
     56    Anchors = [akRight, akBottom]
     57    Caption = 'Compare'
     58    ModalResult = 1
     59    OnClick = ButtonCompareClick
     60    TabOrder = 3
    108761  end
    1088   object MainMenu1: TMainMenu
    1089     Images = Core.ImageList1
    1090     Left = 330
    1091     Top = 476
    1092     object MenuItem1: TMenuItem
    1093       Caption = 'File'
    1094       object MenuItem2: TMenuItem
    1095         Action = AFileOpenLeft
    1096       end
    1097       object MenuItem3: TMenuItem
    1098         Action = AFileOpenRight
    1099       end
    1100       object MenuItem4: TMenuItem
    1101         Action = AReloadFiles
    1102       end
    1103       object MenuItem5: TMenuItem
    1104         Action = ASwitchSides
    1105       end
    1106       object MenuItemClose: TMenuItem
    1107         Caption = 'Close'
    1108         OnClick = MenuItemCloseClick
    1109       end
    1110     end
     62  object CheckBoxSortContacts: TCheckBox
     63    Left = 23
     64    Height = 30
     65    Top = 81
     66    Width = 136
     67    Caption = 'Sort contacts'
     68    Checked = True
     69    State = cbChecked
     70    TabOrder = 4
    111171  end
    1112   object ActionList1: TActionList
    1113     Images = Core.ImageList1
    1114     Left = 733
    1115     Top = 346
    1116     object AFileOpenLeft: TAction
    1117       Caption = 'Open left file'
    1118       ImageIndex = 5
    1119       OnExecute = AFileOpenLeftExecute
    1120     end
    1121     object AFileOpenRight: TAction
    1122       Caption = 'Open right file'
    1123       ImageIndex = 2
    1124       OnExecute = AFileOpenRightExecute
    1125     end
    1126     object AReloadFiles: TAction
    1127       Caption = 'Reload files'
    1128       OnExecute = AReloadFilesExecute
    1129     end
    1130     object ASwitchSides: TAction
    1131       Caption = 'Switch sides'
    1132       OnExecute = ASwitchSidesExecute
    1133     end
     72  object CheckBoxNormalizePhoneNumbers: TCheckBox
     73    Left = 23
     74    Height = 30
     75    Top = 120
     76    Width = 253
     77    Caption = 'Normalize phone numbers'
     78    Checked = True
     79    State = cbChecked
     80    TabOrder = 5
     81  end
     82  object CheckBoxWithoutPhotos: TCheckBox
     83    Left = 24
     84    Height = 30
     85    Top = 160
     86    Width = 157
     87    Caption = 'Without photos'
     88    Checked = True
     89    State = cbChecked
     90    TabOrder = 6
     91  end
     92  object CheckBoxRemoveExactDuplicates: TCheckBox
     93    Left = 24
     94    Height = 30
     95    Top = 200
     96    Width = 236
     97    Caption = 'Remove exact duplicates'
     98    Checked = True
     99    State = cbChecked
     100    TabOrder = 7
     101  end
     102  object OpenDialog1: TOpenDialog
     103    Left = 713
     104    Top = 113
    1134105  end
    1135106end
  • trunk/Forms/FormCompare.lrj

    r149 r151  
    11{"version":1,"strings":[
    22{"hash":174352581,"name":"tformcompare.caption","sourcebytes":[67,111,109,112,97,114,101],"value":"Compare"},
    3 {"hash":315429,"name":"tformcompare.menuitem1.caption","sourcebytes":[70,105,108,101],"value":"File"},
    4 {"hash":4863637,"name":"tformcompare.menuitemclose.caption","sourcebytes":[67,108,111,115,101],"value":"Close"},
    5 {"hash":195475957,"name":"tformcompare.afileopenleft.caption","sourcebytes":[79,112,101,110,32,108,101,102,116,32,102,105,108,101],"value":"Open left file"},
    6 {"hash":56694677,"name":"tformcompare.afileopenright.caption","sourcebytes":[79,112,101,110,32,114,105,103,104,116,32,102,105,108,101],"value":"Open right file"},
    7 {"hash":65066931,"name":"tformcompare.areloadfiles.caption","sourcebytes":[82,101,108,111,97,100,32,102,105,108,101,115],"value":"Reload files"},
    8 {"hash":265810003,"name":"tformcompare.aswitchsides.caption","sourcebytes":[83,119,105,116,99,104,32,115,105,100,101,115],"value":"Switch sides"}
     3{"hash":77164181,"name":"tformcompare.buttonbrowse.caption","sourcebytes":[66,114,111,119,115,101],"value":"Browse"},
     4{"hash":205155338,"name":"tformcompare.label1.caption","sourcebytes":[65,110,111,116,104,101,114,32,102,105,108,101,58],"value":"Another file:"},
     5{"hash":77089212,"name":"tformcompare.buttoncancel.caption","sourcebytes":[67,97,110,99,101,108],"value":"Cancel"},
     6{"hash":174352581,"name":"tformcompare.buttoncompare.caption","sourcebytes":[67,111,109,112,97,114,101],"value":"Compare"},
     7{"hash":3349587,"name":"tformcompare.checkboxsortcontacts.caption","sourcebytes":[83,111,114,116,32,99,111,110,116,97,99,116,115],"value":"Sort contacts"},
     8{"hash":198682019,"name":"tformcompare.checkboxnormalizephonenumbers.caption","sourcebytes":[78,111,114,109,97,108,105,122,101,32,112,104,111,110,101,32,110,117,109,98,101,114,115],"value":"Normalize phone numbers"},
     9{"hash":130155747,"name":"tformcompare.checkboxwithoutphotos.caption","sourcebytes":[87,105,116,104,111,117,116,32,112,104,111,116,111,115],"value":"Without photos"},
     10{"hash":78724163,"name":"tformcompare.checkboxremoveexactduplicates.caption","sourcebytes":[82,101,109,111,118,101,32,101,120,97,99,116,32,100,117,112,108,105,99,97,116,101,115],"value":"Remove exact duplicates"}
    911]}
  • trunk/Forms/FormCompare.pas

    r149 r151  
    44
    55uses
    6   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
    7   VCard, Diff, LCLType, LCLIntf, ComCtrls, Buttons, Menus, ActnList, SynEdit,
    8   SynEditMiscClasses, SynHighlighterPosition, SynEditHighlighter, Common,
    9   USynEditEx;
     6  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, DataFile,
     7  VCardFile, VCard, Common, RegistryEx;
    108
    119type
     
    1412
    1513  TFormCompare = class(TForm)
    16     ASwitchSides: TAction;
    17     AReloadFiles: TAction;
    18     AFileOpenLeft: TAction;
    19     AFileOpenRight: TAction;
    20     ActionList1: TActionList;
    21     EditLeftFileName: TEdit;
    22     EditRightFileName: TEdit;
    23     MainMenu1: TMainMenu;
    24     MenuItem1: TMenuItem;
    25     MenuItem2: TMenuItem;
    26     MenuItem3: TMenuItem;
    27     MenuItem4: TMenuItem;
    28     MenuItem5: TMenuItem;
    29     MenuItemClose: TMenuItem;
    30     OpenDialogSide: TOpenDialog;
    31     PanelLeft: TPanel;
    32     PanelRight: TPanel;
    33     SpeedButtonOpenLeft: TSpeedButton;
    34     SpeedButtonOpenRight: TSpeedButton;
    35     Splitter1: TSplitter;
    36     SynEditLeft: TSynEditEx;
    37     SynEditRight: TSynEditEx;
    38     procedure AFileOpenLeftExecute(Sender: TObject);
    39     procedure AFileOpenRightExecute(Sender: TObject);
    40     procedure AReloadFilesExecute(Sender: TObject);
    41     procedure ASwitchSidesExecute(Sender: TObject);
    42     procedure FormActivate(Sender: TObject);
     14    ButtonCancel: TButton;
     15    ButtonCompare: TButton;
     16    ButtonBrowse: TButton;
     17    CheckBoxWithoutPhotos: TCheckBox;
     18    CheckBoxSortContacts: TCheckBox;
     19    CheckBoxNormalizePhoneNumbers: TCheckBox;
     20    CheckBoxRemoveExactDuplicates: TCheckBox;
     21    EditAnotherFile: TEdit;
     22    Label1: TLabel;
     23    OpenDialog1: TOpenDialog;
     24    procedure ButtonBrowseClick(Sender: TObject);
     25    procedure ButtonCompareClick(Sender: TObject);
    4326    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    4427    procedure FormCreate(Sender: TObject);
    4528    procedure FormDestroy(Sender: TObject);
    46     procedure FormResize(Sender: TObject);
    4729    procedure FormShow(Sender: TObject);
    48     procedure MenuItemCloseClick(Sender: TObject);
    49     procedure SynEditLeftChange(Sender: TObject);
    50     procedure SynEditLeftScroll(Sender: TObject);
    51     procedure SynEditRightChange(Sender: TObject);
    52     procedure SynEditRightScroll(Sender: TObject);
    5330  private
    54     FLeftSide: string;
    55     FRightSide: string;
    56     Diff: TDiff;
    57     HighlighterLeft: TSynPositionHighlighter;
    58     HighlighterRight: TSynPositionHighlighter;
    59     AttrAdded: TtkTokenKind;
    60     AttrDeleted: TtkTokenKind;
    61     AttrModified: TtkTokenKind;
    62     LastWidth: Integer;
    63     procedure SetLeftSide(AValue: string);
    64     procedure SetRightSide(AValue: string);
    65     procedure ReloadContent;
    66     procedure UpdateInterface;
    67     procedure UpdateHighlight;
    68     function LoadFile(AFileName: string): string;
    69   public
    70     procedure LoadFileLeft(FileName: string);
    71     procedure LoadFileRight(FileName: string);
    72     property LeftSide: string read FLeftSide write SetLeftSide;
    73     property RightSide: string read FRightSide write SetRightSide;
     31    LeftVCard: TVCardFile;
     32    RightVCard: TVCardFile;
     33    procedure CompareInternal;
     34    procedure CompareExternal;
     35    procedure LoadConfig;
     36    procedure RemoveExactDuplicates(Contacts: TContacts);
     37    procedure NormalizePhoneNumbers(Contacts: TContacts);
     38    procedure RemovePhotos(Contacts: TContacts);
     39    procedure SaveConfig;
    7440  end;
    7541
     
    8046
    8147uses
    82   Core, VCardFile;
     48  Core, FormCompareSideBySide;
    8349
    8450{ TFormCompare }
     51
     52procedure TFormCompare.FormCreate(Sender: TObject);
     53begin
     54  Core.Core.Translator.TranslateComponentRecursive(Self);
     55  Core.Core.ThemeManager1.UseTheme(Self);
     56  LeftVCard := TVCardFile.Create(nil);
     57  RightVCard := TVCardFile.Create(nil);
     58end;
     59
     60procedure TFormCompare.FormDestroy(Sender: TObject);
     61begin
     62  FreeAndNil(LeftVCard);
     63  FreeAndNil(RightVCard);
     64end;
    8565
    8666procedure TFormCompare.FormClose(Sender: TObject; var CloseAction: TCloseAction
    8767  );
    8868begin
     69  SaveConfig;
    8970  Core.Core.PersistentForm1.Save(Self);
    9071end;
    9172
    92 procedure TFormCompare.ASwitchSidesExecute(Sender: TObject);
     73procedure TFormCompare.ButtonCompareClick(Sender: TObject);
     74begin
     75  LeftVCard.Assign(TVCardFile(Core.Core.DataFile));
     76  RightVCard.LoadFromFile(EditAnotherFile.Text);
     77
     78  if CheckBoxSortContacts.Checked then begin
     79    LeftVCard.VCard.Contacts.Sort;
     80    RightVCard.VCard.Contacts.Sort;
     81  end;
     82
     83  if CheckBoxWithoutPhotos.Checked then begin
     84    RemovePhotos(LeftVCard.VCard.Contacts);
     85    RemovePhotos(RightVCard.VCard.Contacts);
     86  end;
     87
     88  if CheckBoxNormalizePhoneNumbers.Checked then begin
     89    NormalizePhoneNumbers(LeftVCard.VCard.Contacts);
     90    NormalizePhoneNumbers(RightVCard.VCard.Contacts);
     91  end;
     92
     93  if CheckBoxRemoveExactDuplicates.Checked then begin
     94    RemoveExactDuplicates(LeftVCard.VCard.Contacts);
     95    RemoveExactDuplicates(RightVCard.VCard.Contacts);
     96  end;
     97
     98  CompareExternal;
     99end;
     100
     101procedure TFormCompare.RemovePhotos(Contacts: TContacts);
     102var
     103  I: Integer;
     104  J: Integer;
     105  ContactProperties: TContactProperties;
     106begin
     107  for I := 0 to Contacts.Count - 1 do
     108  with Contacts[I].Properties do begin
     109    ContactProperties := GetMultipleByName('PHOTO');
     110    for J := ContactProperties.Count - 1 downto 0 do
     111      Remove(ContactProperties[J]);
     112    ContactProperties.Free;
     113  end;
     114end;
     115
     116procedure TFormCompare.NormalizePhoneNumbers(Contacts: TContacts);
     117var
     118  I: Integer;
     119  J: Integer;
     120  ContactProperties: TContactProperties;
     121begin
     122  for I := 0 to Contacts.Count - 1 do
     123  with Contacts[I].Properties do begin
     124    ContactProperties := GetMultipleByName('TEL');
     125    for J := 0 to ContactProperties.Count - 1 do begin
     126      ContactProperties[J].Value := StringReplace(ContactProperties[J].Value, ' ', '', [rfReplaceAll]);
     127      if not ContactProperties[J].Value.StartsWith('+') then
     128        ContactProperties[J].Value := Core.Core.DefaultPhoneCountryPrefix + ContactProperties[J].Value;
     129    end;
     130    ContactProperties.Free;
     131  end;
     132end;
     133
     134procedure TFormCompare.ButtonBrowseClick(Sender: TObject);
     135var
     136  TempFile: TDataFile;
     137begin
     138  TempFile := Core.Core.DefaultDataFileClass.Create(nil);
     139  try
     140    OpenDialog1.Filter := TempFile.GetFileFilter;
     141  finally
     142    TempFile.Free;
     143  end;
     144
     145  OpenDialog1.DefaultExt := '';
     146  OpenDialog1.InitialDir := ExtractFileDir(EditAnotherFile.Text);
     147  OpenDialog1.FileName := ExtractFileName(EditAnotherFile.Text);
     148  OpenDialog1.Options := OpenDialog1.Options - [ofAllowMultiSelect];
     149  if OpenDialog1.Execute then begin
     150    EditAnotherFile.Text := OpenDialog1.FileName;
     151  end;
     152end;
     153
     154procedure TFormCompare.FormShow(Sender: TObject);
     155begin
     156  Core.Core.PersistentForm1.Load(Self);
     157  LoadConfig;
     158end;
     159
     160procedure TFormCompare.CompareInternal;
    93161var
    94162  TempFileName: string;
    95   TempContent: string;
    96 begin
    97   TempContent := SynEditLeft.Text;
    98   SynEditLeft.Text := SynEditRight.Text;
    99   SynEditRight.Text := TempContent;
    100 
    101   TempFileName := EditLeftFileName.Text;
    102   EditLeftFileName.Text := EditRightFileName.Text;
    103   EditRightFileName.Text := TempFileName;
    104 
    105   UpdateInterface;
    106   UpdateHighlight;
    107 end;
    108 
    109 procedure TFormCompare.FormActivate(Sender: TObject);
    110 begin
    111   if LastWidth = -1 then LastWidth := Width;
    112 end;
    113 
    114 procedure TFormCompare.AReloadFilesExecute(Sender: TObject);
    115 begin
    116   LoadFileLeft(EditLeftFileName.Text);
    117   LoadFileRight(EditRightFileName.Text);
    118   UpdateHighlight;
    119   UpdateInterface;
    120 end;
    121 
    122 procedure TFormCompare.AFileOpenLeftExecute(Sender: TObject);
    123 begin
    124   OpenDialogSide.InitialDir := ExtractFileDir(EditLeftFileName.Text);
    125   OpenDialogSide.FileName := ExtractFileName(EditLeftFileName.Text);
    126   if OpenDialogSide.Execute then begin
    127     EditLeftFileName.Text := OpenDialogSide.FileName;
    128     SynEditLeft.Text := LoadFileToStr(OpenDialogSide.FileName);
    129   end;
    130 end;
    131 
    132 procedure TFormCompare.AFileOpenRightExecute(Sender: TObject);
    133 begin
    134   OpenDialogSide.InitialDir := ExtractFileDir(EditRightFileName.Text);
    135   OpenDialogSide.FileName := ExtractFileName(EditRightFileName.Text);
    136   if OpenDialogSide.Execute then begin
    137     EditRightFileName.Text := OpenDialogSide.FileName;
    138     SynEditRight.Text := LoadFileToStr(OpenDialogSide.FileName);
    139   end;
    140   UpdateHighlight;
    141 end;
    142 
    143 procedure TFormCompare.FormCreate(Sender: TObject);
    144 begin
    145   Core.Core.Translator.TranslateComponentRecursive(Self);
    146   Core.Core.ThemeManager1.UseTheme(Self);
    147   Diff := TDiff.Create(Self);
    148 
    149   HighlighterLeft := TSynPositionHighlighter.Create(Self);
    150   with HighlighterLeft do begin
    151     AttrAdded := CreateTokenID('Added', clNone, clLightGreen, []);
    152     AttrDeleted := CreateTokenID('Deleted', clNone, clLightBlue, []);
    153     AttrModified := CreateTokenID('Modified', clNone, clLightRed, []);
    154   end;
    155   SynEditLeft.Highlighter := HighlighterLeft;
    156 
    157   HighlighterRight := TSynPositionHighlighter.Create(Self);
    158   with HighlighterRight do begin
    159     AttrAdded := CreateTokenID('Added', clNone, clLightGreen, []);
    160     AttrDeleted := CreateTokenID('Deleted', clNone, clLightBlue, []);
    161     AttrModified := CreateTokenID('Modified', clNone, clLightRed, []);
    162   end;
    163   SynEditRight.Highlighter := HighlighterRight;
    164 
    165   LastWidth := -1;
    166 end;
    167 
    168 procedure TFormCompare.FormDestroy(Sender: TObject);
    169 begin
    170   FreeAndNil(HighlighterLeft);
    171   FreeAndNil(HighlighterRight);
    172   FreeAndNil(Diff);
    173 end;
    174 
    175 procedure TFormCompare.FormResize(Sender: TObject);
    176 var
    177   LastHandler: TNotifyEvent;
    178   NewPanelWidth: Integer;
    179 const
    180   MaxRatio = 0.8;
    181 begin
    182   if LastWidth <> -1 then begin
    183     LastHandler := PanelLeft.OnResize;
    184     try
    185       PanelLeft.OnResize := nil;
    186       NewPanelWidth := Round((PanelLeft.Width / LastWidth) * Width);
    187       if NewPanelWidth > Round(Width * MaxRatio) then NewPanelWidth := Round(Width * MaxRatio);
    188       PanelLeft.Width := NewPanelWidth;
    189     finally
    190       PanelLeft.OnResize := LastHandler;
    191     end;
    192     LastWidth := Width;
    193   end;
    194 end;
    195 
    196 procedure TFormCompare.FormShow(Sender: TObject);
    197 begin
    198   Core.Core.PersistentForm1.Load(Self);
    199   UpdateInterface;
    200   ReloadContent;
    201 end;
    202 
    203 procedure TFormCompare.MenuItemCloseClick(Sender: TObject);
    204 begin
    205   Close;
    206 end;
    207 
    208 procedure TFormCompare.SynEditLeftChange(Sender: TObject);
    209 begin
    210   UpdateHighlight;
    211 end;
    212 
    213 procedure TFormCompare.SynEditLeftScroll(Sender: TObject);
    214 begin
    215   SynEditRight.TopLine := SynEditLeft.TopLine;
    216 end;
    217 
    218 procedure TFormCompare.SynEditRightChange(Sender: TObject);
    219 begin
    220   UpdateHighlight;
    221 end;
    222 
    223 procedure TFormCompare.SynEditRightScroll(Sender: TObject);
    224 begin
    225   SynEditLeft.TopLine := SynEditRight.TopLine;
    226 end;
    227 
    228 procedure TFormCompare.SetLeftSide(AValue: string);
    229 begin
    230   if FLeftSide = AValue then Exit;
    231   FLeftSide := AValue;
    232 end;
    233 
    234 procedure TFormCompare.SetRightSide(AValue: string);
    235 begin
    236   if FRightSide = AValue then Exit;
    237   FRightSide := AValue;
    238 end;
    239 
    240 procedure TFormCompare.ReloadContent;
    241 begin
    242   UpdateHighlight;
    243 end;
    244 
    245 procedure TFormCompare.UpdateInterface;
    246 begin
    247 end;
    248 
    249 procedure TFormCompare.UpdateHighlight;
    250 var
    251   LeftText: string;
    252   RightText: string;
     163begin
     164  with TFormCompareSideBySide.Create(nil) do
     165  try
     166    TempFileName := Core.Core.GetTempDir +
     167      DirectorySeparator + 'Compare' + VCardFileExt;
     168    ForceDirectories(ExtractFileDir(TempFileName));
     169    TVCardFile(Core.Core.DataFile).SaveToFile(TempFileName);
     170    LoadFileLeft(TempFileName);
     171    LoadFileRight(EditAnotherFile.Text);
     172    ShowModal;
     173  finally
     174    Free;
     175  end;
     176end;
     177
     178procedure CompareText(TextLeft, TextRight: string; FileNameLeft: string = 'FileLeft.txt';
     179  FileNameRight: string = 'FileRight.txt');
     180var
     181  TempFileRight: string;
     182  TempFileLeft: string;
     183begin
     184  if not DirectoryExists(Core.Core.GetTempDir) then
     185    CreateDir(Core.Core.GetTempDir);
     186  TempFileLeft := Core.Core.GetTempDir + DirectorySeparator + FileNameLeft;
     187  TempFileRight := Core.Core.GetTempDir + DirectorySeparator + FileNameRight;
     188  SaveStringToFile(TextLeft, TempFileLeft);
     189  SaveStringToFile(TextRight, TempFileRight);
     190  ExecuteProgram(Core.Core.CompareTool, [TempFileLeft, TempFileRight]);
     191end;
     192
     193procedure TFormCompare.CompareExternal;
     194begin
     195  CompareText(LeftVCard.VCard.AsString, RightVCard.Vcard.AsString,
     196    ExtractFileName(LeftVCard.FileName), ExtractFileName(EditAnotherFile.Text));
     197end;
     198
     199procedure TFormCompare.LoadConfig;
     200begin
     201  with TRegistryEx.Create do
     202  try
     203    CurrentContext := Core.Core.ApplicationInfo1.GetRegistryContext;
     204    EditAnotherFile.Text := ReadStringWithDefault('LastCompareFileName', '');
     205    CheckBoxWithoutPhotos.Checked := ReadBoolWithDefault('WithoutPhotos', True);
     206    CheckBoxSortContacts.Checked := ReadBoolWithDefault('SortContacts', True);
     207    CheckBoxNormalizePhoneNumbers.Checked := ReadBoolWithDefault('NormalizePhoneNumbers', True);
     208    CheckBoxRemoveExactDuplicates.Checked := ReadBoolWithDefault('RemoveExactDuplicates', True);
     209  finally
     210    Free;
     211  end;
     212end;
     213
     214procedure TFormCompare.RemoveExactDuplicates(Contacts: TContacts);
     215var
    253216  I: Integer;
    254   LastKind: TChangeKind;
    255   P1: TPoint;
    256   P2: TPoint;
    257   Rec: TCompareRec;
    258   NextToken1: TtkTokenKind;
    259   NextToken2: TtkTokenKind;
    260 begin
    261   LeftText := SynEditLeft.Lines.Text;
    262   RightText := SynEditRight.Lines.Text;
    263 
    264   Diff.Execute(PChar(LeftText), PChar(RightText), Length(LeftText), Length(RightText));
    265 
    266   HighlighterLeft.ClearAllTokens;
    267   HighlighterRight.ClearAllTokens;
    268   LeftText := '';
    269   RightText := '';
    270   LastKind := ckNone;
    271   P1 := Point(1, 0);
    272   P2 := Point(1, 0);
    273   NextToken1 := tkText;
    274   NextToken2 := tkText;
    275   for I := 0 to Diff.Count - 1 do
    276     with Diff.Compares[I] do begin
    277       Rec := Diff.Compares[I];
    278       if Rec.Chr1 = LineEnding then begin
    279         if NextToken1 <> tkText then begin
    280           HighlighterLeft.AddToken(P1.Y, 0, NextToken1);
    281           NextToken1 := tkText;
    282         end;
    283         Inc(P1.Y);
    284         P1.X := 0;
    285         LeftText := LeftText + Rec.Chr1;
    286       end else begin
    287         if Kind = ckAdd then LeftText := LeftText + ' '
    288           else LeftText := LeftText + Rec.chr1;
    289         if Kind <> LastKind then begin
    290           HighlighterLeft.AddToken(P1.Y, P1.X, NextToken1);
    291           if Kind = ckNone then NextToken1 := tkText
    292           //else if Kind = ckAdd then NextToken1 := AttrAdded
    293           else if Kind = ckDelete then NextToken1 := AttrDeleted
    294           else if Kind = ckModify then NextToken1 := AttrModified;
    295         end;
    296         Inc(P1.X);
    297       end;
    298 
    299       if Rec.Chr2 = LineEnding then begin
    300         if NextToken2 <> tkText then begin
    301           HighlighterRight.AddToken(P2.Y, 0, NextToken2);
    302           NextToken2 := tkText;
    303         end;
    304         Inc(P2.Y);
    305         P2.X := 0;
    306         RightText := RightText + Rec.Chr2;
    307       end else begin
    308         if Kind = ckDelete then RightText := RightText + ' '
    309           else RightText := RightText + Rec.Chr2;
    310         if Kind <> LastKind then begin
    311           HighlighterRight.AddToken(P2.Y, P2.X, NextToken2);
    312           if Kind = ckNone then NextToken2 := tkText
    313           else if Kind = ckAdd then NextToken2 := AttrAdded
    314           //else if Kind = ckDelete then NextToken2 := AttrDeleted
    315           else if Kind = ckModify then NextToken2 := AttrModified;
    316         end;
    317         Inc(P2.X);
    318       end;
    319 
    320       LastKind := Kind;
    321     end;
    322 
    323   //SynEditLeft.Lines.Text := LeftText;
    324   //SynEditRight.Lines.Text := RightText;
    325 end;
    326 
    327 function TFormCompare.LoadFile(AFileName: string): string;
    328 var
    329   Ext: string;
    330 begin
    331   Ext := ExtractFileExt(AFileName);
    332   if Ext = VCardFileExt then begin
    333     with TVCardFile.Create(nil) do
    334     try
    335       LoadFromFile(AFileName);
    336       Result := VCard.AsString;
    337     finally
    338       Free;
    339     end;
    340   end else Result := LoadFileToStr(AFileName);
    341 end;
    342 
    343 procedure TFormCompare.LoadFileLeft(FileName: string);
    344 begin
    345   EditLeftFileName.Text := FileName;
    346   LeftSide := LoadFile(FileName);
    347   SynEditLeft.Text := LeftSide;
    348 end;
    349 
    350 procedure TFormCompare.LoadFileRight(FileName: string);
    351 begin
    352   EditRightFileName.Text := FileName;
    353   RightSide := LoadFile(FileName);
    354   SynEditRight.Text := RightSide;
     217begin
     218  Contacts.RemoveExactDuplicates;
     219  for I := 0 to Contacts.Count - 1 do
     220    Contacts[I].Properties.RemoveExactDuplicates;
     221end;
     222
     223procedure TFormCompare.SaveConfig;
     224begin
     225  with TRegistryEx.Create do
     226  try
     227    CurrentContext := Core.Core.ApplicationInfo1.GetRegistryContext;
     228    WriteString('LastCompareFileName', EditAnotherFile.Text);
     229    WriteBool('WithoutPhotos', CheckBoxWithoutPhotos.Checked);
     230    WriteBool('SortContacts', CheckBoxSortContacts.Checked);
     231    WriteBool('NormalizePhoneNumbers', CheckBoxNormalizePhoneNumbers.Checked);
     232    WriteBool('RemoveExactDuplicates', CheckBoxRemoveExactDuplicates.Checked);
     233  finally
     234    Free;
     235  end;
    355236end;
    356237
  • trunk/Forms/FormSettings.lfm

    r149 r151  
    11object FormSettings: TFormSettings
    22  Left = 798
    3   Height = 404
    4   Top = 321
    5   Width = 526
     3  Height = 521
     4  Top = 204
     5  Width = 857
    66  Caption = 'Settings'
    7   ClientHeight = 404
    8   ClientWidth = 526
     7  ClientHeight = 521
     8  ClientWidth = 857
    99  Constraints.MinHeight = 404
    1010  Constraints.MinWidth = 526
     
    1515  Position = poScreenCenter
    1616  LCLVersion = '2.2.6.0'
    17   object ComboBoxLanguage: TComboBox
    18     Left = 240
    19     Height = 42
    20     Top = 16
    21     Width = 264
    22     ItemHeight = 0
    23     ParentFont = False
    24     Style = csDropDownList
    25     TabOrder = 0
    26   end
    27   object Label1: TLabel
    28     Left = 24
    29     Height = 26
    30     Top = 24
    31     Width = 88
    32     Caption = 'Language:'
    33     ParentColor = False
    34     ParentFont = False
    35   end
    3617  object ButtonOk: TButton
    37     Left = 400
     18    Left = 731
    3819    Height = 37
    39     Top = 351
     20    Top = 468
    4021    Width = 113
    4122    Anchors = [akRight, akBottom]
     
    4425    OnClick = ButtonOkClick
    4526    ParentFont = False
    46     TabOrder = 7
     27    TabOrder = 1
    4728  end
    4829  object ButtonCancel: TButton
    49     Left = 256
     30    Left = 587
    5031    Height = 37
    51     Top = 351
     32    Top = 468
    5233    Width = 113
    5334    Anchors = [akRight, akBottom]
     
    5536    ModalResult = 2
    5637    ParentFont = False
    57     TabOrder = 6
    58   end
    59   object CheckBoxAutomaticDPI: TCheckBox
    60     Left = 23
    61     Height = 30
    62     Top = 247
    63     Width = 148
    64     Caption = 'Automatic DPI'
    65     OnChange = CheckBoxAutomaticDPIChange
    66     ParentFont = False
    67     TabOrder = 4
    68     Visible = False
    69   end
    70   object SpinEditDPI: TSpinEdit
    71     Left = 239
    72     Height = 43
    73     Top = 279
    74     Width = 145
    75     MaxValue = 300
    76     MinValue = 96
    77     ParentFont = False
    78     TabOrder = 5
    79     Value = 96
    80     Visible = False
    81   end
    82   object LabelDPI: TLabel
    83     Left = 55
    84     Height = 26
    85     Top = 287
    86     Width = 35
    87     Caption = 'DPI:'
    88     ParentColor = False
    89     ParentFont = False
    90     Visible = False
    91   end
    92   object CheckBoxReopenLastFileOnStart: TCheckBox
    93     Left = 23
    94     Height = 30
    95     Top = 207
    96     Width = 226
    97     Caption = 'Reopen last file on start'
    98     ParentFont = False
    99     TabOrder = 3
    100   end
    101   object Bevel1: TBevel
    102     Left = 12
    103     Height = 2
    104     Top = 332
    105     Width = 496
    106     Anchors = [akLeft, akRight, akBottom]
    107   end
    108   object Label2: TLabel
    109     Left = 24
    110     Height = 26
    111     Top = 72
    112     Width = 63
    113     Caption = 'Theme:'
    114     ParentColor = False
    115     ParentFont = False
    116   end
    117   object ComboBoxTheme: TComboBox
    118     Left = 240
    119     Height = 42
    120     Top = 64
    121     Width = 264
    122     ItemHeight = 0
    123     ParentFont = False
    124     Style = csDropDownList
    125     TabOrder = 1
    126   end
    127   object Label3: TLabel
    128     Left = 24
    129     Height = 26
    130     Top = 120
    131     Width = 186
    132     Caption = 'Default vCard version:'
    133     ParentColor = False
    134   end
    135   object EditDefaultVcardVersion: TEdit
    136     Left = 240
    137     Height = 43
    138     Top = 112
    139     Width = 144
     38    TabOrder = 0
     39  end
     40  object ScrollBox1: TScrollBox
     41    Left = 8
     42    Height = 448
     43    Top = 8
     44    Width = 845
     45    HorzScrollBar.Page = 504
     46    VertScrollBar.Page = 427
     47    Anchors = [akTop, akLeft, akRight, akBottom]
     48    ClientHeight = 446
     49    ClientWidth = 843
    14050    TabOrder = 2
    141   end
    142   object Label4: TLabel
    143     Left = 24
    144     Height = 26
    145     Top = 165
    146     Width = 133
    147     Caption = 'Map query URL:'
    148     ParentColor = False
    149   end
    150   object EditMapUrl: TEdit
    151     Left = 240
    152     Height = 43
    153     Top = 161
    154     Width = 267
    155     Anchors = [akTop, akLeft, akRight]
    156     TabOrder = 8
     51    object Label1: TLabel
     52      Left = 24
     53      Height = 26
     54      Top = 24
     55      Width = 88
     56      Caption = 'Language:'
     57      ParentColor = False
     58      ParentFont = False
     59    end
     60    object ComboBoxLanguage: TComboBox
     61      Left = 240
     62      Height = 42
     63      Top = 16
     64      Width = 264
     65      ItemHeight = 0
     66      ParentFont = False
     67      Style = csDropDownList
     68      TabOrder = 0
     69    end
     70    object CheckBoxAutomaticDPI: TCheckBox
     71      Left = 23
     72      Height = 30
     73      Top = 247
     74      Width = 148
     75      Caption = 'Automatic DPI'
     76      OnChange = CheckBoxAutomaticDPIChange
     77      ParentFont = False
     78      TabOrder = 1
     79      Visible = False
     80    end
     81    object SpinEditDPI: TSpinEdit
     82      Left = 240
     83      Height = 43
     84      Top = 279
     85      Width = 145
     86      MaxValue = 300
     87      MinValue = 96
     88      ParentFont = False
     89      TabOrder = 2
     90      Value = 96
     91      Visible = False
     92    end
     93    object LabelDPI: TLabel
     94      Left = 55
     95      Height = 26
     96      Top = 287
     97      Width = 35
     98      Caption = 'DPI:'
     99      ParentColor = False
     100      ParentFont = False
     101      Visible = False
     102    end
     103    object CheckBoxReopenLastFileOnStart: TCheckBox
     104      Left = 23
     105      Height = 30
     106      Top = 207
     107      Width = 226
     108      Caption = 'Reopen last file on start'
     109      ParentFont = False
     110      TabOrder = 3
     111    end
     112    object Label2: TLabel
     113      Left = 24
     114      Height = 26
     115      Top = 72
     116      Width = 63
     117      Caption = 'Theme:'
     118      ParentColor = False
     119      ParentFont = False
     120    end
     121    object ComboBoxTheme: TComboBox
     122      Left = 240
     123      Height = 42
     124      Top = 64
     125      Width = 264
     126      ItemHeight = 0
     127      ParentFont = False
     128      Style = csDropDownList
     129      TabOrder = 4
     130    end
     131    object Label3: TLabel
     132      Left = 24
     133      Height = 26
     134      Top = 120
     135      Width = 186
     136      Caption = 'Default vCard version:'
     137      ParentColor = False
     138    end
     139    object EditDefaultVcardVersion: TEdit
     140      Left = 240
     141      Height = 43
     142      Top = 112
     143      Width = 144
     144      TabOrder = 5
     145    end
     146    object Label4: TLabel
     147      Left = 24
     148      Height = 26
     149      Top = 165
     150      Width = 133
     151      Caption = 'Map query URL:'
     152      ParentColor = False
     153    end
     154    object EditMapUrl: TEdit
     155      Left = 240
     156      Height = 43
     157      Top = 160
     158      Width = 588
     159      Anchors = [akTop, akLeft, akRight]
     160      TabOrder = 6
     161    end
     162    object Label5: TLabel
     163      Left = 23
     164      Height = 26
     165      Top = 340
     166      Width = 120
     167      Caption = 'Compare tool:'
     168      ParentColor = False
     169    end
     170    object EditCompareTool: TEdit
     171      Left = 240
     172      Height = 43
     173      Top = 336
     174      Width = 472
     175      Anchors = [akTop, akLeft, akRight]
     176      TabOrder = 7
     177    end
     178    object ButtonBrowse: TButton
     179      Left = 720
     180      Height = 38
     181      Top = 340
     182      Width = 113
     183      Anchors = [akTop, akRight]
     184      Caption = 'Browse'
     185      OnClick = ButtonBrowseClick
     186      TabOrder = 8
     187    end
     188    object Label6: TLabel
     189      Left = 23
     190      Height = 26
     191      Top = 392
     192      Width = 248
     193      Caption = 'Default phone country prefix:'
     194      ParentColor = False
     195    end
     196    object EditDefaultPhoneCountryPrefix: TEdit
     197      Left = 296
     198      Height = 43
     199      Top = 384
     200      Width = 144
     201      TabOrder = 9
     202    end
     203  end
     204  object OpenDialog1: TOpenDialog
     205    Left = 506
     206    Top = 258
    157207  end
    158208end
  • trunk/Forms/FormSettings.lrj

    r149 r151  
    11{"version":1,"strings":[
    22{"hash":213582195,"name":"tformsettings.caption","sourcebytes":[83,101,116,116,105,110,103,115],"value":"Settings"},
    3 {"hash":82521866,"name":"tformsettings.label1.caption","sourcebytes":[76,97,110,103,117,97,103,101,58],"value":"Language:"},
    43{"hash":1371,"name":"tformsettings.buttonok.caption","sourcebytes":[79,107],"value":"Ok"},
    54{"hash":77089212,"name":"tformsettings.buttoncancel.caption","sourcebytes":[67,97,110,99,101,108],"value":"Cancel"},
     5{"hash":82521866,"name":"tformsettings.label1.caption","sourcebytes":[76,97,110,103,117,97,103,101,58],"value":"Language:"},
    66{"hash":37628553,"name":"tformsettings.checkboxautomaticdpi.caption","sourcebytes":[65,117,116,111,109,97,116,105,99,32,68,80,73],"value":"Automatic DPI"},
    77{"hash":300234,"name":"tformsettings.labeldpi.caption","sourcebytes":[68,80,73,58],"value":"DPI:"},
     
    99{"hash":95339402,"name":"tformsettings.label2.caption","sourcebytes":[84,104,101,109,101,58],"value":"Theme:"},
    1010{"hash":232157114,"name":"tformsettings.label3.caption","sourcebytes":[68,101,102,97,117,108,116,32,118,67,97,114,100,32,118,101,114,115,105,111,110,58],"value":"Default vCard version:"},
    11 {"hash":26355722,"name":"tformsettings.label4.caption","sourcebytes":[77,97,112,32,113,117,101,114,121,32,85,82,76,58],"value":"Map query URL:"}
     11{"hash":26355722,"name":"tformsettings.label4.caption","sourcebytes":[77,97,112,32,113,117,101,114,121,32,85,82,76,58],"value":"Map query URL:"},
     12{"hash":220155194,"name":"tformsettings.label5.caption","sourcebytes":[67,111,109,112,97,114,101,32,116,111,111,108,58],"value":"Compare tool:"},
     13{"hash":77164181,"name":"tformsettings.buttonbrowse.caption","sourcebytes":[66,114,111,119,115,101],"value":"Browse"},
     14{"hash":99356634,"name":"tformsettings.label6.caption","sourcebytes":[68,101,102,97,117,108,116,32,112,104,111,110,101,32,99,111,117,110,116,114,121,32,112,114,101,102,105,120,58],"value":"Default phone country prefix:"}
    1215]}
  • trunk/Forms/FormSettings.pas

    r149 r151  
    1212
    1313  TFormSettings = class(TForm)
    14     Bevel1: TBevel;
     14    ButtonBrowse: TButton;
    1515    ButtonOk: TButton;
    1616    ButtonCancel: TButton;
     17    CheckBoxAutomaticDPI: TCheckBox;
    1718    CheckBoxReopenLastFileOnStart: TCheckBox;
    18     CheckBoxAutomaticDPI: TCheckBox;
    1919    ComboBoxLanguage: TComboBox;
    2020    ComboBoxTheme: TComboBox;
     21    EditCompareTool: TEdit;
    2122    EditDefaultVcardVersion: TEdit;
     23    EditDefaultPhoneCountryPrefix: TEdit;
    2224    EditMapUrl: TEdit;
    2325    Label1: TLabel;
    2426    Label2: TLabel;
    2527    Label3: TLabel;
     28    Label4: TLabel;
     29    Label5: TLabel;
     30    Label6: TLabel;
    2631    LabelDPI: TLabel;
     32    OpenDialog1: TOpenDialog;
     33    ScrollBox1: TScrollBox;
    2734    SpinEditDPI: TSpinEdit;
     35    procedure ButtonBrowseClick(Sender: TObject);
    2836    procedure ButtonOkClick(Sender: TObject);
    2937    procedure CheckBoxAutomaticDPIChange(Sender: TObject);
     
    7179end;
    7280
     81procedure TFormSettings.ButtonBrowseClick(Sender: TObject);
     82begin
     83  OpenDialog1.InitialDir := ExtractFileDir(EditCompareTool.Text);
     84  OpenDialog1.FileName := ExtractFileName(EditCompareTool.Text);
     85  if OpenDialog1.Execute then begin
     86    EditCompareTool.Text := OpenDialog1.FileName;
     87  end;
     88end;
     89
    7390procedure TFormSettings.CheckBoxAutomaticDPIChange(Sender: TObject);
    7491begin
     
    101118    EditDefaultVcardVersion.Text := DefaultVcardVersion;
    102119    EditMapUrl.Text := MapUrl;
     120    EditCompareTool.Text := CompareTool;
     121    EditDefaultPhoneCountryPrefix.Text := DefaultPhoneCountryPrefix;
    103122  end;
    104123  UpdateInterface;
     
    113132    DefaultVcardVersion := EditDefaultVcardVersion.Text;
    114133    MapUrl := EditMapUrl.Text;
     134    CompareTool := EditCompareTool.Text;
     135    DefaultPhoneCountryPrefix := EditDefaultPhoneCountryPrefix.Text;
    115136  end;
    116137end;
  • trunk/Languages/vCardStudio.cs.po

    r150 r151  
    227227
    228228#: tcore.aremoveexactduplicates.caption
     229msgctxt "tcore.aremoveexactduplicates.caption"
    229230msgid "Remove exact duplicates"
    230231msgstr "Odstranit přesné duplikáty"
     
    306307msgstr "Dostupné:"
    307308
    308 #: tformcompare.afileopenleft.caption
     309#: tformcompare.buttonbrowse.caption
     310msgctxt "tformcompare.buttonbrowse.caption"
     311msgid "Browse"
     312msgstr "Procházet"
     313
     314#: tformcompare.buttoncancel.caption
     315msgctxt "tformcompare.buttoncancel.caption"
     316msgid "Cancel"
     317msgstr "Zrušit"
     318
     319#: tformcompare.buttoncompare.caption
     320msgctxt "tformcompare.buttoncompare.caption"
     321msgid "Compare"
     322msgstr "Porovnat"
     323
     324#: tformcompare.caption
     325msgctxt "tformcompare.caption"
     326msgid "Compare"
     327msgstr "Porovnat"
     328
     329#: tformcompare.checkboxnormalizephonenumbers.caption
     330msgid "Normalize phone numbers"
     331msgstr "Normalizovat telefonní čísla:"
     332
     333#: tformcompare.checkboxremoveexactduplicates.caption
     334msgctxt "tformcompare.checkboxremoveexactduplicates.caption"
     335msgid "Remove exact duplicates"
     336msgstr "Odstranit přesné duplikáty"
     337
     338#: tformcompare.checkboxsortcontacts.caption
     339msgid "Sort contacts"
     340msgstr "Seřadit kontakty"
     341
     342#: tformcompare.checkboxwithoutphotos.caption
     343msgid "Without photos"
     344msgstr "Bez fotek"
     345
     346#: tformcompare.label1.caption
     347msgid "Another file:"
     348msgstr "Druhý soubor:"
     349
     350#: tformcomparesidebyside.afileopenleft.caption
     351msgctxt "tformcomparesidebyside.afileopenleft.caption"
    309352msgid "Open left file"
    310353msgstr "Otevřít levý soubor"
    311354
    312 #: tformcompare.afileopenright.caption
     355#: tformcomparesidebyside.afileopenright.caption
     356msgctxt "tformcomparesidebyside.afileopenright.caption"
    313357msgid "Open right file"
    314358msgstr "Otevřít pravý soubor"
    315359
    316 #: tformcompare.areloadfiles.caption
     360#: tformcomparesidebyside.areloadfiles.caption
     361msgctxt "tformcomparesidebyside.areloadfiles.caption"
    317362msgid "Reload files"
    318363msgstr "Znovu načíst soubory"
    319364
    320 #: tformcompare.aswitchsides.caption
     365#: tformcomparesidebyside.aswitchsides.caption
     366msgctxt "tformcomparesidebyside.aswitchsides.caption"
    321367msgid "Switch sides"
    322368msgstr "Prohodit strany"
    323369
    324 #: tformcompare.caption
    325 msgid "Compare"
    326 msgstr "Porovnat"
    327 
    328 #: tformcompare.menuitem1.caption
    329 msgctxt "tformcompare.menuitem1.caption"
     370#: tformcomparesidebyside.caption
     371msgctxt "tformcomparesidebyside.caption"
     372msgid "Compare side by side"
     373msgstr "Porovnat vedle sebe"
     374
     375#: tformcomparesidebyside.menuitem1.caption
     376msgctxt "tformcomparesidebyside.menuitem1.caption"
    330377msgid "File"
    331378msgstr "Soubor"
    332379
    333 #: tformcompare.menuitemclose.caption
    334 msgctxt "tformcompare.menuitemclose.caption"
     380#: tformcomparesidebyside.menuitemclose.caption
     381msgctxt "tformcomparesidebyside.menuitemclose.caption"
    335382msgid "Close"
    336383msgstr "Zavřít"
     
    11531200msgstr "Pole:"
    11541201
     1202#: tformsettings.buttonbrowse.caption
     1203msgctxt "tformsettings.buttonbrowse.caption"
     1204msgid "Browse"
     1205msgstr "Procházet"
     1206
    11551207#: tformsettings.buttoncancel.caption
    11561208msgctxt "tformsettings.buttoncancel.caption"
     
    11911243msgstr "URL dotazu mapy:"
    11921244
     1245#: tformsettings.label5.caption
     1246msgid "Compare tool:"
     1247msgstr "Nástroj porovnání:"
     1248
     1249#: tformsettings.label6.caption
     1250msgid "Default phone country prefix:"
     1251msgstr "Výchozí telefonní prefix země:"
     1252
    11931253#: tformsettings.labeldpi.caption
    11941254msgid "DPI:"
  • trunk/Languages/vCardStudio.pot

    r150 r151  
    217217
    218218#: tcore.aremoveexactduplicates.caption
     219msgctxt "tcore.aremoveexactduplicates.caption"
    219220msgid "Remove exact duplicates"
    220221msgstr ""
     
    296297msgstr ""
    297298
    298 #: tformcompare.afileopenleft.caption
     299#: tformcompare.buttonbrowse.caption
     300msgctxt "tformcompare.buttonbrowse.caption"
     301msgid "Browse"
     302msgstr ""
     303
     304#: tformcompare.buttoncancel.caption
     305msgctxt "tformcompare.buttoncancel.caption"
     306msgid "Cancel"
     307msgstr ""
     308
     309#: tformcompare.buttoncompare.caption
     310msgctxt "tformcompare.buttoncompare.caption"
     311msgid "Compare"
     312msgstr ""
     313
     314#: tformcompare.caption
     315msgctxt "tformcompare.caption"
     316msgid "Compare"
     317msgstr ""
     318
     319#: tformcompare.checkboxnormalizephonenumbers.caption
     320msgid "Normalize phone numbers"
     321msgstr ""
     322
     323#: tformcompare.checkboxremoveexactduplicates.caption
     324msgctxt "tformcompare.checkboxremoveexactduplicates.caption"
     325msgid "Remove exact duplicates"
     326msgstr ""
     327
     328#: tformcompare.checkboxsortcontacts.caption
     329msgid "Sort contacts"
     330msgstr ""
     331
     332#: tformcompare.checkboxwithoutphotos.caption
     333msgid "Without photos"
     334msgstr ""
     335
     336#: tformcompare.label1.caption
     337msgid "Another file:"
     338msgstr ""
     339
     340#: tformcomparesidebyside.afileopenleft.caption
     341msgctxt "tformcomparesidebyside.afileopenleft.caption"
    299342msgid "Open left file"
    300343msgstr ""
    301344
    302 #: tformcompare.afileopenright.caption
     345#: tformcomparesidebyside.afileopenright.caption
     346msgctxt "tformcomparesidebyside.afileopenright.caption"
    303347msgid "Open right file"
    304348msgstr ""
    305349
    306 #: tformcompare.areloadfiles.caption
     350#: tformcomparesidebyside.areloadfiles.caption
     351msgctxt "tformcomparesidebyside.areloadfiles.caption"
    307352msgid "Reload files"
    308353msgstr ""
    309354
    310 #: tformcompare.aswitchsides.caption
     355#: tformcomparesidebyside.aswitchsides.caption
     356msgctxt "tformcomparesidebyside.aswitchsides.caption"
    311357msgid "Switch sides"
    312358msgstr ""
    313359
    314 #: tformcompare.caption
    315 msgid "Compare"
    316 msgstr ""
    317 
    318 #: tformcompare.menuitem1.caption
    319 msgctxt "tformcompare.menuitem1.caption"
     360#: tformcomparesidebyside.caption
     361msgctxt "tformcomparesidebyside.caption"
     362msgid "Compare side by side"
     363msgstr ""
     364
     365#: tformcomparesidebyside.menuitem1.caption
     366msgctxt "tformcomparesidebyside.menuitem1.caption"
    320367msgid "File"
    321368msgstr ""
    322369
    323 #: tformcompare.menuitemclose.caption
    324 msgctxt "tformcompare.menuitemclose.caption"
     370#: tformcomparesidebyside.menuitemclose.caption
     371msgctxt "tformcomparesidebyside.menuitemclose.caption"
    325372msgid "Close"
    326373msgstr ""
     
    11431190msgstr ""
    11441191
     1192#: tformsettings.buttonbrowse.caption
     1193msgctxt "tformsettings.buttonbrowse.caption"
     1194msgid "Browse"
     1195msgstr ""
     1196
    11451197#: tformsettings.buttoncancel.caption
    11461198msgctxt "tformsettings.buttoncancel.caption"
     
    11811233msgstr ""
    11821234
     1235#: tformsettings.label5.caption
     1236msgid "Compare tool:"
     1237msgstr ""
     1238
     1239#: tformsettings.label6.caption
     1240msgid "Default phone country prefix:"
     1241msgstr ""
     1242
    11831243#: tformsettings.labeldpi.caption
    11841244msgid "DPI:"
  • trunk/Languages/vCardStudio.sv.po

    r150 r151  
    228228
    229229#: tcore.aremoveexactduplicates.caption
     230msgctxt "tcore.aremoveexactduplicates.caption"
    230231msgid "Remove exact duplicates"
    231232msgstr ""
     
    307308msgstr ""
    308309
    309 #: tformcompare.afileopenleft.caption
     310#: tformcompare.buttonbrowse.caption
     311msgctxt "tformcompare.buttonbrowse.caption"
     312msgid "Browse"
     313msgstr ""
     314
     315#: tformcompare.buttoncancel.caption
     316#, fuzzy
     317msgctxt "tformcompare.buttoncancel.caption"
     318msgid "Cancel"
     319msgstr "Avbryt"
     320
     321#: tformcompare.buttoncompare.caption
     322msgctxt "tformcompare.buttoncompare.caption"
     323msgid "Compare"
     324msgstr ""
     325
     326#: tformcompare.caption
     327msgctxt "tformcompare.caption"
     328msgid "Compare"
     329msgstr ""
     330
     331#: tformcompare.checkboxnormalizephonenumbers.caption
     332msgid "Normalize phone numbers"
     333msgstr ""
     334
     335#: tformcompare.checkboxremoveexactduplicates.caption
     336msgctxt "tformcompare.checkboxremoveexactduplicates.caption"
     337msgid "Remove exact duplicates"
     338msgstr ""
     339
     340#: tformcompare.checkboxsortcontacts.caption
     341msgid "Sort contacts"
     342msgstr ""
     343
     344#: tformcompare.checkboxwithoutphotos.caption
     345msgid "Without photos"
     346msgstr ""
     347
     348#: tformcompare.label1.caption
     349msgid "Another file:"
     350msgstr ""
     351
     352#: tformcomparesidebyside.afileopenleft.caption
     353msgctxt "tformcomparesidebyside.afileopenleft.caption"
    310354msgid "Open left file"
    311355msgstr ""
    312356
    313 #: tformcompare.afileopenright.caption
     357#: tformcomparesidebyside.afileopenright.caption
     358msgctxt "tformcomparesidebyside.afileopenright.caption"
    314359msgid "Open right file"
    315360msgstr ""
    316361
    317 #: tformcompare.areloadfiles.caption
     362#: tformcomparesidebyside.areloadfiles.caption
     363msgctxt "tformcomparesidebyside.areloadfiles.caption"
    318364msgid "Reload files"
    319365msgstr ""
    320366
    321 #: tformcompare.aswitchsides.caption
     367#: tformcomparesidebyside.aswitchsides.caption
     368msgctxt "tformcomparesidebyside.aswitchsides.caption"
    322369msgid "Switch sides"
    323370msgstr ""
    324371
    325 #: tformcompare.caption
    326 msgid "Compare"
    327 msgstr ""
    328 
    329 #: tformcompare.menuitem1.caption
    330 #, fuzzy
    331 msgctxt "tformcompare.menuitem1.caption"
     372#: tformcomparesidebyside.caption
     373msgctxt "tformcomparesidebyside.caption"
     374msgid "Compare side by side"
     375msgstr ""
     376
     377#: tformcomparesidebyside.menuitem1.caption
     378#, fuzzy
     379msgctxt "tformcomparesidebyside.menuitem1.caption"
    332380msgid "File"
    333381msgstr "Fil"
    334382
    335 #: tformcompare.menuitemclose.caption
    336 #, fuzzy
    337 msgctxt "tformcompare.menuitemclose.caption"
     383#: tformcomparesidebyside.menuitemclose.caption
     384#, fuzzy
     385msgctxt "tformcomparesidebyside.menuitemclose.caption"
    338386msgid "Close"
    339387msgstr "Stäng"
     
    11891237msgstr ""
    11901238
     1239#: tformsettings.buttonbrowse.caption
     1240msgctxt "tformsettings.buttonbrowse.caption"
     1241msgid "Browse"
     1242msgstr ""
     1243
    11911244#: tformsettings.buttoncancel.caption
    11921245msgctxt "tformsettings.buttoncancel.caption"
     
    12271280msgstr "Kart söknings URL:"
    12281281
     1282#: tformsettings.label5.caption
     1283msgid "Compare tool:"
     1284msgstr ""
     1285
     1286#: tformsettings.label6.caption
     1287msgid "Default phone country prefix:"
     1288msgstr ""
     1289
    12291290#: tformsettings.labeldpi.caption
    12301291msgid "DPI:"
  • trunk/Packages/Common/DataFile.pas

    r148 r151  
    7777procedure TDataFile.Assign(Source: TPersistent);
    7878begin
    79   inherited;
    8079  if Source is TDataFile then begin
    8180    FFileName := TDataFile(Source).FFileName;
    8281    FModified := TDataFile(Source).FModified;
    83   end;
     82  end else inherited;
    8483end;
    8584
  • trunk/Packages/VCard/VCard.pas

    r148 r151  
    147147    procedure AssignToList(List: TObjects);
    148148    function GetByName(Name: string): TContactProperty;
     149    function GetMultipleByName(Name: string): TContactProperties;
    149150    function GetByNameGroups(Name: string; Groups: TStringArray;
    150151      NoGroups: TStringArray): TContactProperty;
    151152    function GetByNameGroupsMultiple(Name: string; Groups: TStringArray;
    152153      NoGroups: TStringArray): TContactProperties;
     154    function RemoveExactDuplicates: Integer;
    153155  end;
    154156
     
    572574procedure TVCard.Assign(Source: TPersistent);
    573575begin
    574   inherited;
    575   if Source is TVCard then Contacts.Assign((Source as TVCard).Contacts);
     576  if Source is TVCard then
     577    Contacts.Assign((Source as TVCard).Contacts)
     578  else inherited;
    576579end;
    577580
     
    10051008end;
    10061009
     1010function TContactProperties.GetMultipleByName(Name: string): TContactProperties;
     1011var
     1012  I: Integer;
     1013begin
     1014  Result := TContactProperties.Create(False);
     1015  for I  := 0 to Count - 1 do
     1016  if (Items[I].Name = Name) or EndsWith(Items[I].Name, '.' + Name) then
     1017    Result.Add(Items[I]);
     1018end;
     1019
    10071020function TContactProperties.GetByNameGroups(Name: string; Groups: TStringArray;
    10081021  NoGroups: TStringArray): TContactProperty;
     
    10251038  if Items[I].MatchNameGroups(Name, Groups, NoGroups) then
    10261039    Result.Add(Items[I]);
     1040end;
     1041
     1042function TContactProperties.RemoveExactDuplicates: Integer;
     1043var
     1044  I: Integer;
     1045  J: Integer;
     1046begin
     1047  Result := 0;
     1048  for I := 0 to Count - 1 do
     1049    for J := Count - 1 downto I + 1 do
     1050      if Items[I].CompareTo(Items[J]) then begin
     1051        Remove(Items[J]);
     1052        Inc(Result);
     1053      end;
    10271054end;
    10281055
  • trunk/TestCases.pas

    r149 r151  
    181181        VCardEnd + VCardLineEnding;
    182182    end;
     183
     184    with TTestCaseLoadSave(AddNew('Merge same cell phone', TTestCaseLoadSave)) do begin
     185      Input := VCardBegin + MacLineEnding +
     186        VCardVersion + MacLineEnding +
     187        'N:Surname;Name' + MacLineEnding +
     188        'FN:Name Surname' + MacLineEnding +
     189        'TEL;CELL:123456789' + MacLineEnding +
     190        VCardEnd + MacLineEnding +
     191
     192        VCardBegin + MacLineEnding +
     193        VCardVersion + MacLineEnding +
     194        'N:Surname2;Name' + MacLineEnding +
     195        'FN:Name Surname2' + MacLineEnding +
     196        'TEL;CELL:123456789' + MacLineEnding +
     197        VCardEnd + MacLineEnding;
     198      Output := VCardBegin + VCardLineEnding +
     199        VCardVersion + VCardLineEnding +
     200        'N:Surname;Name' + VCardLineEnding +
     201        'FN:Name Surname' + VCardLineEnding +
     202        'TEL;CELL:123456789' + MacLineEnding +
     203        VCardEnd + VCardLineEnding;
     204    end;
    183205  end;
    184206end;
  • trunk/VCardFile.pas

    r149 r151  
    6767begin
    6868  inherited;
    69   if Source is TVCardFile then
    70     VCard.Assign(TVCardFile(Source).VCard);
     69  VCard.Assign(TVCardFile(Source).VCard)
    7170end;
    7271
  • trunk/vCardStudio.lpi

    r149 r151  
    123123      </Item7>
    124124    </RequiredPackages>
    125     <Units Count="24">
     125    <Units Count="25">
    126126      <Unit0>
    127127        <Filename Value="vCardStudio.lpr"/>
     
    249249      </Unit18>
    250250      <Unit19>
    251         <Filename Value="Forms\FormCompare.pas"/>
    252         <IsPartOfProject Value="True"/>
    253         <ComponentName Value="FormCompare"/>
     251        <Filename Value="Forms\FormCompareSideBySide.pas"/>
     252        <IsPartOfProject Value="True"/>
     253        <ComponentName Value="FormCompareSideBySide"/>
    254254        <HasResources Value="True"/>
    255255        <ResourceBaseClass Value="Form"/>
     
    274274        <ResourceBaseClass Value="Form"/>
    275275      </Unit23>
     276      <Unit24>
     277        <Filename Value="Forms\FormCompare.pas"/>
     278        <IsPartOfProject Value="True"/>
     279        <ComponentName Value="FormCompare"/>
     280        <HasResources Value="True"/>
     281        <ResourceBaseClass Value="Form"/>
     282      </Unit24>
    276283    </Units>
    277284  </ProjectOptions>
  • trunk/vCardStudio.lpr

    r149 r151  
    66  {$ENDIF}
    77  Interfaces, // this includes the LCL widgetset
    8   Forms, FormMain, Core, Diff, SysUtils, FormCompare, TestCases,
    9   VCardFile, FormColumns;
     8  Forms, FormMain, Core, Diff, SysUtils, FormCompareSideBySide, TestCases,
     9  VCardFile, FormColumns, FormCompare;
    1010
    1111{$R *.res}
     
    1717
    1818begin
    19   Application.Scaled:=True;
    20   Application.Title:='vCard Studio';
     19  Application.Scaled := True;
     20  Application.Title := 'vCard Studio';
    2121  {$if declared(UseHeapTrace)}
    2222  DeleteFile(ExtractFilePath(ParamStr(0)) + HeapTraceLog);
    2323  SetHeapTraceOutput(ExtractFilePath(ParamStr(0)) + HeapTraceLog);
    2424  {$ENDIF}
    25   RequireDerivedFormResource:=True;
     25  RequireDerivedFormResource := True;
    2626  Application.Initialize;
    2727  Application.CreateForm(TCore, Core.Core);
Note: See TracChangeset for help on using the changeset viewer.