Resource

Resource Basics

Resource Name Find Duplicate Label Names
Resource Version 2.2
Category Catalog
Downloads 919
Release Date 4/3/2015 10:53:51 AM
 

Resource Details

Description Find Duplicate Catalog Labels in the catalog hierarchy.

Duplicates can be saved as:
1. every duplicate name to a text file
2. unique names to a text file

There's also an option to automatically merge the changes.
When merging duplicates then there's a special handling for labels in the Miscellaneous category. Those will always be merged to the duplicate label that is outside of the Miscellaneous category
Installation Instructions Save this file to your local hard drive
Usage Instructions 1. From Mian menu, select Tools -> Scripter
2. Load this file
3. Run the script
Changes in this version Added option to save every name and added option to auto merge
Special Requirements
 

Author Information

Author Name IDimager Support
 

Available Attachments

Attachment #1 DuplicateLabels.jpg
 

Script

{
  Version 2.2
  Author: IDimager
  Date: 10 august 2020
  Changes: 
    a. Now uses PublicCatalog instead of Catalog
    b. You can configure to use catalog labels with a minimum name length

  Version 2.1
  Author: IDimager
  Date: 28 november 2017
  Changes: When merging then first determine which label should be in the lead (typically the one not in Miscellaneous)

  Version 2.0
  Author: IDimager
  Date: 3 April 2015
  Changes: Added option to save every name and added option to auto merge

  Version 1.1
  Author: IDimager
  Date: 24 Januari 2014
  Changes: Made compatible with PSU


  Version 1.0
  Author: IDimager
  Initial Date: 3 september 2010
}

const
  cMinLabelNameLength = 0;

  procedure FindDuplicates (AList: TTntStringList; AResult: TTntStringList);
  var
    AIdx: Integer;
    AName: WideString;
    AProp, AProp2: TCatalogItemProp;
    ADupProps: TStringList;
    AIsDup: Boolean;
  begin
    while AList.Count > 0 do
    begin
      AIsDup := False;
      AName := AList.Strings[AList.Count - 1];
      AProp := AList.Objects[AList.Count - 1];

      AList.Delete (AList.Count - 1);

      AIdx := AList.IndexOf (AName)
      if AIdx <> -1 then
      begin
        ADupProps := TStringList.Create;
        ADupProps.AddObject(AProp.GUID, AProp);
        AResult.AddObject (AProp.PropName, ADupProps);
        while AIdx <> -1 do
        begin
          AIsDup := True;
          AProp2 := AList.Objects[AIdx];
          ADupProps.AddObject(AProp2.GUID, AProp2);
          AList.Delete (AIdx);

          AIdx := AList.IndexOf (AName);
        end;
      end;
    end;
  end;

var
  ASl: TTntStringList;
  AProps: TCatalogItemProps;
  ACat: TCatalogPropCategory;
  AProp, AProp2: TCatalogItemProp;
  ADups: TTntStringList;
  APropDups: TStringList;
  ARes, i, j, ALeadIdx: Integer;
  ACheckResult: Boolean;
  AOptions: TTntStringList;
begin
  ASl := TTntStringList.Create;
  ADups := TTntStringList.Create;
  ADups.Sorted := True;

  Screen.Cursor := crHourglass;
  AProps := TCatalogItemProps.Create (TCatalogItemProp, '');
  PublicCatalog.EnumAllProps (AProps);

  // read all leaf-names to the stringlist
  for i := 0 to AProps.Count - 1 do
  begin
    // skip catalog labels with a length of 1
    if Length(AProps.Items[i].PropName) > cMinLabelNameLength then
      ASl.AddObject(AProps.Items[i].PropName, AProps.Items[i]);
  end;

  ASl.Sorted := True;
  ASl.CaseSensitive := False;

  FindDuplicates (ASl, ADups);
  Screen.Cursor := crDefault;

  if ADups.Count > 0 then
  begin
    ASl.Clear;

    // what to do with the duplicates
    AOptions := TTntStringList.Create;
    AOptions.Add('Save all duplicate names to file*');    // the * at the ends indicates the default option
    AOptions.Add('Save unique duplicate names to file');
    AOptions.Add('Automatically merge all found duplicates together');
    ACheckResult := False;
    ARes := AskCustom(
                       'What to do with the results?',
                       'select your option',
                       '',
                       '',
                       ACheckResult,
                       AOptions
                     );
    AOptions.Free;

    Screen.Cursor := crHourglass;
    for i := 0 to ADups.Count - 1 do
    begin
      APropDups := TStringList(ADups.Objects[i]);

      if APropDups.Count >= 2 then   // these are duplicates so it will be odd if this fails
      begin
        if ARes = 0 then   // all names to files
        begin
          for j := 0 to APropDups.Count - 1 do
          begin
            AProp := TCatalogItemProp(APropDups.Objects[j]);
            ASl.Add (PublicCatalog.PathNameForProp (AProp, '::', True));
          end;
        end

        else if ARes = 1 then  // only names to file
        begin
          AProp := TCatalogItemProp(APropDups.Objects[0]);
          ASl.Add (AProp.PropName);
        end

        else if ARes = 2 then   // auto merge all
        begin
          ALeadIdx := 0;
          for j := 0 to APropDups.Count - 1 do
          begin
            AProp := TCatalogItemProp(APropDups.Objects[j]);
            ACat := TCatalogPropCategory.Create(nil);
            PublicCatalog.EnumCategoryForProp(AProp, ACat);
            if ACat.GUID <> KeywordsGUID then
            begin
              ALeadIdx := j;
              break;
            end;
            ACat.Free;
          end;

          AProp := TCatalogItemProp(APropDups.Objects[ALeadIdx]);
          for j := 0 to APropDups.Count - 1 do
          begin
            if j = ALeadIdx then
              Continue;
            AProp2 := TCatalogItemProp(APropDups.Objects[j]);
            PublicCatalog.MergePropWithProp(AProp2, AProp, True);
          end;
        end;
      end;

      APropDups.Free;  // no more need...
    end;
    Screen.Cursor := crDefault;

    if ASl.Count > 0 then
    begin
      SaveDialog.Title := 'Save duplicates report as...';
      SaveDialog.InitialDir := WindowsDesktopDir;
      SaveDialog.DefaultExt := '.txt';
      SaveDialog.FileName := 'duplicate labels';

      if SaveDialog.Execute then
      begin
        ASl.SaveToFile (SaveDialog.FileName);
        Say ('Duplicates report saved as ' + SaveDialog.FileName);
      end;
    end

    else if ARes = 2 then
      Say('Merge complete...');
  end
  else
    Say ('No duplicates found');

  AProps.Free;
  ADups.Free;
  ASl.Free;
end;