unit LangManComp;

//***************************************************************************
//**  LangMan - Localization components for Delphi (Support UNICODE)       **
//***************************************************************************
//**                                                                       **
//**  File:      LangManComp.pas                                           **
//**                                                                       **
//**  Version:   1.2.2                                                     **
//**                                                                       **
//**  Date:      14.8.2012                                                 **
//**                                                                       **
//**  Author:    Ing. Tomas Halabala - REGULACE.ORG                        **
//**                                                                       **
//**  License:   This components set is free for personal use.             **
//**             Comercial use is not allowed without author permission!   **
//**                                                                       **
//**             Tato sada komponent je zdarma pro nekomerční použití.     **
//**             Komerční využití konzultujte s autorem!                   **
//**                                                                       **
//**             Šíření je dovoleno pouze v nezměněné podobě.              **
//**             Autor neodpovídá za žádné případné škody způsobené        **
//**             používáním této komponenty.                               **
//**                                                                       **
//**             Tento zdrojový kód je chráněn autorským zákonem.          **
//**                                                                       **
//**  Disclaimer:THE SOFTWARE AND ANY RELATED DOCUMENTATION IS PROVIDED    **
//**             "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR   **
//**             IMPLIED, INCLUDING, WITHOUT LIMITATION, THE IMPLIED       **
//**             WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR   **
//**             PURPOSE, OR NONINFRINGEMENT. AUTHOR DOES NOT WARRANT,     **
//**             GUARANTEE, OR MAKE ANY REPRESENTATIONS REGARDING THE USE, **
//**             OR THE RESULTS OF THE USE, OF THE SOFTWARE IN TERMS OF    **
//**             CORRECTNESS, ACCURACY, RELIABILITY, OR OTHERWISE.         **
//**             THE ENTIRE RISK ARISING OUT OF USE OR PERFORMANCE         **
//**             OF THE SOFTWARE REMAINS WITH YOU.                         **
//**                                                                       **
//**  Copyright: Copyright © 2009-2012 by Ing.Tomas Halabala.              **
//**                                                                       **
//**  E-mail:    tomas.halabala@regulace.org                               **
//**                                                                       **
//**  Webpages:  http://www.regulace.org                                   **
//**                                                                       **
//***************************************************************************

{$INCLUDE LM_Config.inc}
{$WARNINGS OFF}

interface

uses Windows, Messages, LangManCompatibility, SysUtils, Stdctrls, Classes,
     Controls, Contnrs, Menus, Graphics, ImgList, ComCtrls,
     LangManSys, LangForm, LMAdditions

     {$IFDEF WIN3_1},
     Outline
     {$ENDIF};

//***************************************************************************
//**  LangMan Component classes definitions                                **
//***************************************************************************
type
  TLangManComponent = class;
  TProgrammableLexicon = class;
  TLangFormLexicon = class;
  TSpans = class;
  TFlagsList = class;

  TLangManEngine = class(TComponent)
  private
    LanguageMngForm  : TLanguageManager;
    Languages        : TStringList;
    FileNames        : TStringList;
    LangMenu         : TStringList;
    Flags            : TFlagsList;
    SpanClients      : TSpans;

    DataStruct       : TComponentStructure;
    DataLexicon      : TLexiconData;
    LangFormLexicon  : TLangFormLexicon;

    LangDir               : String;
    IsInternalLanguage    : Boolean;
    IsInitialized         : Boolean;
    IsFullyCreated        : Boolean;
    FirstTranslated       : Boolean;
    ResourcesLoaded       : Boolean;
    ApplicationOnActivate : TNotifyEvent;

    fCurrentLanguage   : TLanguage;
    fDesignLanguage    : TLanguage;
    fDefaultLanguage   : TLanguage;
    fLangSubdir        : String;
    fLangFileExt       : String;
    fLangFileSign      : String;
    fLangFileEncoding  : TLFEncoding;
    fLangEditorVisible : boolean;
    fLangCreatorVisible: boolean;
    fIncludeLangMan    : boolean;
    fLangMenuFlags     : boolean;
    fLanguageMenu      : TMenuItem;
    fDesignLangFlag    : TPicture;
    fLangResources     : TStringList;

    fOnChangeLangQuery : TContinueQuery;
    fOnChangeLanguage  : TNotifyEvent;
    fOnBeforeEdit      : TNotifyEvent;
    fOnAfterEdit       : TNotifyEvent;

    procedure SetDesignLang(Input: TLanguage);
    function GetDefaultLanguage: TLanguage;
    procedure SetDefaultLanguage(Input: TLanguage);
    procedure SetLangSubdir(Input: string);
    procedure SetLangFileExt(Input: string);
    procedure SetLangFileSign(Sign: string);
    procedure SetLangCreatorVisible(Enable: boolean);
    procedure SetLangEditorVisible(Enable: boolean);
    procedure SetIncludeLangMan(Input: boolean);
    procedure SetLangMenuFlags(Input: boolean);
    procedure SetLanguageMenu(MenuItem: TMenuItem);
    procedure DesignLangFlagChanged(Sender: TObject);
    procedure SetDesignLangFlag(FlagImage: TPicture);
    procedure SetLangResources(ResLangs: TStringList);

    function CheckLangDir: Boolean;
    procedure ReCreateLangMenus;
    procedure FindLangFiles;
    procedure ChangeLangMenu(MenuItem: TMenuItem);
    procedure LangMenuClick(Sender: TObject);
    procedure ApplicationRun(AOwner: TObject);
    function LoadLangFromFile(LangName: TLanguage; CreateSource: boolean; MarkOld: Boolean = false; AntiLoop: TLanguage = ''): boolean;
    function LoadLangManLang(StringArray: array of string): boolean;
    function InternalLanguages(Lang: TLanguage): boolean;
    procedure TranslateLangForm;
    function LangManCommands(Command: String): TLanguage;
    procedure LangFormSelectLang(AOwner: TObject);
    procedure CreateLanguage(AOwner: TObject);
    procedure LoadGroups(AOwner: TObject);
    procedure StoreWorks;
    procedure StoreChanges;
    procedure ChangeGroup(AOwner: TObject);
    procedure CompleteSourceData;
    procedure SaveLanguageFile(LangName, SuperiorLang, FileName: string);
    function GetString(Lex: TComponent; Index: Integer): string;
    function ResourceLangToFile(LangIndex: Integer): Boolean;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function Translate(LangName: TLanguage): TLanguage;
    function GetLanguagesList: TStrings;
    function GetLangFilesList: TStrings;
    procedure ShowLangEditor;
    procedure ShowLangCreator;
    property CurrentLanguage: String read fCurrentLanguage;
  published
    property DesignLanguageName: TLanguage read fDesignLanguage write SetDesignLang;
    property DefaultLanguage: TLanguage read GetDefaultLanguage write SetDefaultLanguage;
    property LangSubdirectory: String read fLangSubdir write SetLangSubdir;
    property LangFileExtension: String read fLangFileExt write SetLangFileExt;
    property LangFileSignature: String read fLangFileSign write SetLangFileSign;
{$IF CompilerVersion > 19}
    property LangFileEncoding: TLFEncoding read fLangFileEncoding write fLangFileEncoding default Unicode;
{$IFEND}
    property LangCreatorVisible: boolean read fLangCreatorVisible write SetLangCreatorVisible default True;
    property LangEditorVisible: boolean read fLangEditorVisible write SetLangEditorVisible default True;
    property TranslateLangMan: boolean read fIncludeLangMan write SetIncludeLangMan default False;
    property LangMenuFlags: boolean read fLangMenuFlags write SetLAngMenuFlags default True;
    property LanguageMenu: TMenuItem read fLanguageMenu write SetLanguageMenu;
    property DesignLangFlag: TPicture read fDesignLangFlag write SetDesignLangFlag;
    property LangResources: TStringList read fLangResources write SetLangResources;
    property OnChangeLangQuery: TContinueQuery read fOnChangeLangQuery write fOnChangeLangQuery;
    property OnChangeLanguage: TNotifyEvent read fOnChangeLanguage write fOnChangeLanguage;
    property OnBeforeEdit: TNotifyEvent read fOnBeforeEdit write fOnBeforeEdit;
    property OnAfterEdit: TNotifyEvent read fOnAfterEdit write fOnAfterEdit;
  end;

  TAdditionSet = set of TAdditionProperties;

  TLangManComponent = class (TComponent)
  private
    fLangManEngine : TLangManEngine;
    fOnChangeLanguage: TNotifyEvent;
    procedure SetLangManEngine(LangMan: TLangManEngine);
  protected
    procedure ChangeLanguage(AOwner: TObject); virtual;
  published
    property LangManEngine: TLangManEngine read fLangManEngine write SetLangManEngine;
    property OnChangeLanguage: TNotifyEvent read fOnChangeLanguage write fOnChangeLanguage;
  end;

  TLangManClient = class(TLangManComponent)
  private
    ParentControl : TComponent;
    DesignStruct  : TComponentStructure;
    OwnerOnCreate : TNotifyEvent;

    fAfterCreate            : boolean;    // sestavení jazykového seznamu až po volání metody OnCreate formuláře
    fTransStringProp        : TTranslateStringProperties;
    fTransTStringsProp      : TTranslateTStringsProperties;
    fTransStructuredProp    : TTranslateStructuredProperties;
    fTransOtherProp         : TTranslateOtherProperties;
    fTransAdditions         : TAdditionSet;

    procedure SetTransStringProp(Input: TTranslateStringProperties);
    procedure SetTransTStringsProp(Input: TTranslateTStringsProperties);
    procedure SetTransStructuredProp(Input: TTranslateStructuredProperties);
    procedure SetTransOtherProp(Input: TTranslateOtherProperties);
    procedure SetTransAdditions(Input: TAdditionSet);

    function TransComp(Component: TComponent; ChClass: TClass): Boolean;
    function TransProp(Prop: TStringProperties): Boolean; overload;
    function TransProp(Prop: TTStringsProperties): Boolean; overload;
    function TransProp(Prop: TStructuredProperties): Boolean; overload;
    function TransProp(Prop: TOtherProperties): Boolean; overload;
    function TransCompProp(Component: TComponent; ChClass: TClass; Prop: TStringProperties): Boolean; overload;
    function TransCompProp(Component: TComponent; ChClass: TClass; Prop: TTStringsProperties): Boolean; overload;
    function TransCompProp(Component: TComponent; ChClass: TClass; Prop: TStructuredProperties): Boolean; overload;
    function TransCompProp(Component: TComponent; ChClass: TClass; Prop: TOtherProperties): Boolean; overload;

    function StructItem(Name, Parent: string; PropertyType: Word; Addr: string = ''): string;
    procedure CreateStructItem(Component: PTComponent; PropertyType: Word; Input, Addr: string);
    function ChangeStructItem(Component: PTComponent; PropertyType : Word; InitText: string; fchInit: boolean; ActionString: string = ''): string;
    function ChangeStructItemEx(Component: PTComponent; PropertyType : Word; InitText: string; fchInit: boolean; PresetAddr: string = ''): string;
    procedure ChangeStructStrings(Component: PTComponent; PropertyType : Word; Data: TStrings; fchInit: boolean);
    procedure ChangeStructStringsEx(Component: PTComponent; PropertyType : Word; Data: TStrings; fchInit: boolean; PresetAddr: string);
    procedure ChangeStructPanels(Component: PTComponent; PropertyType : Word; Data: PTStatusPanels; fchInit: boolean);
    procedure ChangeStructBands(Component: PTComponent; PropertyType : Word; Data: PTCoolBands; fchInit: boolean);
  {$IF CompilerVersion > 19}
    procedure ChangeStructCategories(Component: PTComponent; PropertyType : Word; Data: PTButtonCategories; fchInit: boolean);
    procedure ChangeStructButtonsGrp(Component: PTComponent; PropertyType : Word; Data: PTGrpButtonItems; fchInit: boolean);
  {$IFEND}
    procedure ChangeStructTreeNodes(Component: PTComponent; PropertyType : Word; Data: PTTreeNodes; fchInit: boolean);
    procedure ChangeStructListColumns(Component: PTComponent; PropertyType : Word; Data: PTListColumns; fchInit: boolean);
  {$IF CompilerVersion > 19}
    procedure ChangeStructListGroups(Component: PTComponent; PropertyType : Word; Data: PTListGroups; fchInit: boolean);
  {$IFEND}
    procedure ChangeStructListItems(Component: PTComponent; PropertyType : Word; Data: PTListItems; fchInit: boolean);
    procedure ChangeStructHeaderSections(Component: PTComponent; PropertyType : Word; Data: PTHeaderSections; fchInit: boolean);
  {$IFDEF DATABASES}
    procedure ChangeStructDBTitleCaptions(Component: PTComponent; PropertyType : Word; Data: PTDBGridColumns; fchInit: boolean);
    procedure ChangeStructTableProducerColumns(Component: TComponent; PropertyType : Word; fchInit: boolean);
  {$ENDIF}
  {$IFDEF WIN3_1}
    procedure ChangeStructOutlineItems(Component: PTComponent; PropertyType : Word; Outline: TCustomOutline; fchInit: boolean);
  {$ENDIF}
    procedure ChangeStructFileTypes(Component: PTComponent; PropertyType: Word; Data: PTFileTypeItems; fchInit: boolean);
  {$IF CompilerVersion > 17}
    procedure ChangeStructTaskDlgButtons(Component: PTComponent; PropertyType: Word; Data: PTTaskDialogButtons; fchInit: boolean);
  {$IFEND}
    function ChangeStructFilter(Component: PTComponent; PropertyType : Word; InitFilter: string; fchInit: boolean): string;
  {$IFDEF RAVE}
    procedure ChangeStructRaveProject(Component: TComponent; PropertyType : Word; fchInit: boolean);
    procedure ChangeStructRaveSystem(Component: TComponent; PropertyType : Word; fchInit: boolean);
  {$ENDIF}
  {$IFDEF TEECHART}
    procedure ChangeStructCustomAxes(Component: PTComponent; PropertyType : Word; Data: PTCollection; fchInit: boolean; PresetAddr: string);
  {$ENDIF}
    procedure ChangeStrings(Component: TComponent; fchInit: boolean);
    procedure InitForm(AOwner: TObject);
    procedure ControlChanges(fchInit: boolean);
  protected
    procedure ChangeLanguage(AOwner: TObject); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function AddComponent(Component: TComponent; Name: string; Translate: boolean): Boolean;
    procedure RecreateTransStruct;
    procedure TranslateComponent(Component: TComponent; Name: string = '');
    procedure Translate;
  published
    property InitAfterCreateForm: boolean read fAfterCreate write fAfterCreate default false;
    property TransStringProp: TTranslateStringProperties read fTransStringProp write SetTransStringProp default TranslateStringPropertiesDefault;
    property TransTStringsProp: TTranslateTStringsProperties read fTransTStringsProp write SetTransTStringsProp default TranslateTStringsPropertiesDefault;
    property TransStructuredProp: TTranslateStructuredProperties read fTransStructuredProp write SetTransStructuredProp default TranslateStructuredPropertiesDefault;
    property TransOtherProp: TTranslateOtherProperties read fTransOtherProp write SetTransOtherProp default TranslateOtherPropertiesDefault;
    property TransAdditions: TAdditionSet read fTransAdditions write SetTransAdditions default DefaultEnabled;
  end;

  TLexicon = class (TLangManComponent)
  private
    Slaves: TObjectList;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  protected
    procedure ChangeLanguage(AOwner: TObject); override;
    function GetItem(Index: Integer): string; virtual; abstract;
    function MaxIndex: Integer; virtual; abstract;
    function IsDefined(Index: Integer): boolean; virtual; abstract;
    function GetLink(Index: Integer): string; virtual;
    function CompleteString(const Str: string): string; virtual;
    property Link [Index: Integer]: string read GetLink;
  end;

  TDesignedLexicon = class (TLexicon)
  private
    fItems: TStringList;
    procedure SetItems(Value: TStringList);
  protected
    function GetItem(Index: Integer): string; override;
    function MaxIndex: Integer; override;
    function IsDefined(Index: Integer): boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function CreateItem(Text: string): Integer;
    function CompleteString(const Str: string): string; override;
    property Item [Index: Integer]: string read GetItem;
    property Link;
  published
    property Items : TStringList read fItems write SetItems;
  end;

  TProgrammableLexicon = class (TLexicon)
  private
    fIndexedItems: TIndexedItems;
    fOnInitialization: TNotifyEvent;
    procedure SetOnInitialization(Event: TNotifyEvent);
  protected
    function GetItem(Index: Integer): string; override;
    function MaxIndex: Integer; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure DefineItem(ItemNr: Word; Text: string);
    function IsDefined(Index: Integer): boolean; override;
    function CompleteString(const Str: string): string; override;
    property Item [Index: Integer]: string read GetItem;
    property Link;
  published
    property OnInitialization: TNotifyEvent read fOnInitialization write SetOnInitialization;
  end;

{  TSmartLexicon = class (TLexicon)
  private
  protected
    function GetItem(Index: Integer): string; override;
    function MaxIndex: Integer; override;
    function IsDefined(Index: Integer): boolean; override;
  public
  end;}

  TLangFormLexicon = class (TProgrammableLexicon)
  public
    constructor Create(AOwner: TComponent); override;
    function GetItem(Index: Integer): string; override;
  end;

  // New in v.1.2.0 21.1.2012
  TLMStringStyle = record
    Color: TColor;
    Font: TFontName;
    Charset: TFontCharset;
    Style: TFontStyles;
    Size: Integer;
    Pitch: TFontPitch;
  end;
  TLMStringStyles = array of TLMStringStyle;

  // New in v.1.2.0 21.1.2012
  TLangManRichEdit = class(TCustomRichEdit)
  private
    LMLines: TStringList;
    fAssignedLexicon: TLexicon;
    fAutoFont: Boolean;
    AutoFontSetup: Boolean;
    Styles: TLMStringStyles;
    procedure LexiconAssign(Lexicon: TLexicon);
    procedure SetupFont(Style: ShortInt);
    function WriteFormattedText(const Text: String; WrittingPosition: Integer): Integer;
    function GetLineStart(LineIndex: Integer): Integer;
    function SelLine(LineIndex: Integer; IncludeCRLF: Boolean = false): Boolean;
    function GetAutoFont: Boolean;
    function GetLink(Index: Integer): String;
    procedure SetAutoFont(const Value: Boolean);
  public
    constructor Create(AOwner: TComponent); override; //ReadOnly:= true;
    destructor Destroy; override;
    procedure AssignStyles(LMStringStyles: TLMStringStyles);
    procedure ClearStyles;
    function GetStyles: TLMStringStyles;
    function StylesCount: Integer;
    function SetStyle(Style: TFontStyles; Size: Integer = 0; Color: TColor = clDefault; FontName: TFontName = ''; Charset: TFontCharset = DEFAULT_CHARSET; Pitch: TFontPitch = fpDefault; StyleIndex: ShortInt = -1): Integer;
    function Format(const Text: String; StyleIndex: ShortInt): String;
    procedure Write(const Text: String; StyleIndex: ShortInt = -1);
    procedure WriteLn(const Text: String; StyleIndex: ShortInt = -1);
    procedure NextLine;
    procedure Clear;
    function LinesCount: Integer;
    function ReadLineText(LineIndex: Integer): String;
    function ReadLineFText(LineIndex: Integer): String;
    procedure DeleteLine(LineIndex: Integer);
    procedure RewriteLine(LineIndex: Integer; const Text: String; StyleIndex: ShortInt = -1);
    procedure InsertLine(LineIndex: Integer; const Text: String; StyleIndex: ShortInt = -1);
    procedure Translate;
{$IF CompilerVersion > 19}
    procedure LoadFromFile(const SourceFile: TFileName); overload;
    procedure LoadFromFile(const SourceFile: TFileName; Encoding: TEncoding); overload;
    procedure LoadFromStream(SourceStream: TStream); overload;
    procedure LoadFromStream(SourceStream: TStream; Encoding: TEncoding); overload;
    procedure SaveRichTextToFile(const DestinationFile: TFileName); overload;
    procedure SaveRichTextToFile(const DestinationFile: TFileName; Encoding: TEncoding); overload;
    procedure SaveRichTextToStream(DestinationStream: TStream); overload;
    procedure SaveRichTextToStream(DestinationStream: TStream; Encoding: TEncoding); overload;
    procedure SaveEncodedFormToFile(const DestinationFile: TFileName); overload;
    procedure SaveEncodedFormToFile(const DestinationFile: TFileName; Encoding: TEncoding); overload;
    procedure SaveEncodedFormToStream(DestinationStream: TStream); overload;
    procedure SaveEncodedFormToStream(DestinationStream: TStream; Encoding: TEncoding); overload;
{$ELSE}
    procedure LoadFromFile(const SourceFile: TFileName);
    procedure LoadFromStream(SourceStream: TStream);
    procedure SaveRichTextToFile(const DestinationFile: TFileName);
    procedure SaveRichTextToStream(DestinationStream: TStream);
    procedure SaveEncodedFormToFile(const DestinationFile: TFileName);
    procedure SaveEncodedFormToStream(DestinationStream: TStream);
{$IFEND}
    property Link [Index: Integer]: string read GetLink;
  published
    property Align;
    property Alignment;
    property Anchors;
    property AssignedLexicon: TLexicon read fAssignedLexicon write LexiconAssign;
    property AutoFont: Boolean read GetAutoFont write SetAutoFont default True;
    property BevelEdges;
    property BevelInner;
    property BevelOuter;
    property BevelKind default bkNone;
    property BevelWidth;
    property BiDiMode;
    property BorderStyle;
    property BorderWidth;
    property Color;
    property Ctl3D;
    property DragCursor;
    property DragKind;
    property DragMode;
    property Enabled;
    property Font;
    property HideSelection;
    property HideScrollBars;
    property ImeMode;
    property ImeName;
    property Constraints;
    property MaxLength;
    property ParentBiDiMode;
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PlainText;
    property PopupMenu;
    property ScrollBars;
    property ShowHint;
    property TabOrder;
    property TabStop default True;
    property Visible;
    property WantTabs;
    property WantReturns;
    property WordWrap default False;
    property OnChange;
    property OnContextPopup;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDock;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnMouseWheel;
    property OnMouseWheelDown;
    property OnMouseWheelUp;
    property OnProtectChange;
    property OnResizeRequest;
    property OnSaveClipboard;
    property OnSelectionChange;
    property OnStartDock;
    property OnStartDrag;
{$IF CompilerVersion > 19}
    property OnMouseActivate;
    property OnClick;
    property OnDblClick;
    property OnMouseEnter;
    property OnMouseLeave;
{$IFEND}
  end;

  TLangManStrings = class(TStringList)
  private
    Controlled: TStrings;
    AssignedLexicon: TLexicon;
  public
    constructor Create(ControlledStrings: TStrings; Lexicon: TLexicon); virtual;
    destructor Destroy; override;
    function Add(const S: string): Integer; override;
    function AddObject(const S: string; AObject: TObject): Integer; override;
    procedure Clear; override;
    procedure Delete(Index: Integer); override;
    procedure Exchange(Index1, Index2: Integer); override;
    procedure Insert(Index: Integer; const S: string); override;
    procedure InsertObject(Index: Integer; const S: string; AObject: TObject); override;
    procedure CustomSort(Compare: TStringListSortCompare); override;
    procedure Translate;
  end;

  TLangComboStyle = (scDropDownList, scOwnerDrawFixed, scOwnerDrawVariable);

  TLangCombo = class (TShadowComboBox)
  private
    fLangManEngine : TLangManEngine;
    fOnChangeLanguage: TNotifyEvent;
    procedure SetLangManEngine(LangMan: TLangManEngine);
    function GetStyleCombo: TLangComboStyle;
    procedure SetStyleCombo(Input: TLangComboStyle);
    procedure ChangeLanguage(AOwner: TObject);
  public
    constructor Create(AOwner: TComponent); override;
  published
    property LangManEngine: TLangManEngine read fLangManEngine write SetLangManEngine;
    property StyleCombo: TLangComboStyle read GetStyleCombo write SetStyleCombo;
    property Align;
    property Anchors;
    property AutoCloseUp default False;
    property AutoComplete default True;
  {$IF CompilerVersion > 19}
    property AutoCompleteDelay default 500;
    property ParentDoubleBuffered;
  {$IFEND}
    property AutoDropDown default False;
    property BevelEdges;
    property BevelInner;
    property BevelKind default bkNone;
    property BevelOuter;
    property BiDiMode;
    property Color;
    property Constraints;
    property Ctl3D;
    property DoubleBuffered;
    property DragCursor;
    property DragKind;
    property DragMode;
    property DropDownCount;
    property Enabled;
    property Font;
    property ImeMode;
    property ImeName;
    property ItemHeight;
    property ParentBiDiMode;
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Visible;
    property OnChangeLanguage: TNotifyEvent read fOnChangeLanguage write fOnChangeLanguage;
    property OnClick;
    property OnCloseUp;
    property OnContextPopup;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnDrawItem;
    property OnDropDown;
    property OnEndDock;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMeasureItem;
  {$IF CompilerVersion > 19}
    property OnMouseEnter;
    property OnMouseLeave;
  {$IFEND}
    property OnSelect;
    property OnStartDock;
    property OnStartDrag;
  end;

  TLangFlagsCombo = class(TShadowComboBoxEx)
  private
    fLangManEngine : TLangManEngine;
    fOnChangeLanguage: TNotifyEvent;
    procedure SetLangManEngine(LangMan: TLangManEngine);
    procedure ChangeLanguage(AOwner: TObject);
  protected
    function GetItemHt: Integer; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property LangManEngine: TLangManEngine read fLangManEngine write SetLangManEngine;
    property Align;
    property Anchors;
    property BiDiMode;
    property Color;
    property Constraints;
    property Ctl3D;
    property DoubleBuffered;
    property DragCursor;
    property DragKind;
    property DragMode;
    property DropDownCount;
    property Enabled;
    property Font;
    property ImeMode;
    property ImeName;
//    property ItemHeight;
    property ParentBiDiMode;
    property ParentColor;
    property ParentCtl3D;
  {$IF CompilerVersion > 19}
    property ParentDoubleBuffered;
  {$IFEND}
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Visible;
    property OnChangeLanguage: TNotifyEvent read fOnChangeLanguage write fOnChangeLanguage;
    property OnClick;
    property OnContextPopup;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnDropDown;
    property OnEndDock;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseMove;
    property OnSelect;
    property OnStartDock;
    property OnStartDrag;
  end;

  TSpans = class (TObject)
  private
    Components : TComponentList;
  public
    constructor Create;
    destructor Destroy; override;
    procedure RegisterClient(Client: TComponent);
    procedure UnregisterClient(Client: TComponent);
    procedure CallClientProcs;
    procedure ChangeLangLists(Languages: TStrings; CurrentLang: TLanguage; FlagsList: TFlagsList);
    function IsRegistered(OwnerName, ComponentName: string): Boolean;
  end;

  TFlagsList = class (TImageList)
  private
    MaxAddress : SmallInt;
    FlagPointer : array of SmallInt;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure ClearFlags;
    function GetImageIndex(LangIndex: Word): Integer;
    function AddFlag(Image: TGraphic):Integer;
    function RewriteFlag(Index: Integer; Image: TGraphic): Integer;
    function ImportFlag(ImageList: TCustomImageList; Index: Integer): Integer;
  end;

  procedure RegisterProperty(Component: TComponent; PropertyValue: String; PropertyID: TAdditionProperties; ItemAddr: String = ''); overload;
  procedure RegisterProperty(Component: TComponent; PropertyValue: String; PropertyID: TStringProperties; ItemAddr: String = ''); overload;
  procedure RegisterProperty(Component: TComponent; PropertyValue: String; PropertyID: TTStringsProperties; ItemAddr: String = ''); overload;
  procedure RegisterProperty(Component: TComponent; PropertyValue: String; PropertyID: TStructuredProperties; ItemAddr: String = ''); overload;
  procedure RegisterProperty(Component: TComponent; PropertyValue: String; PropertyID: TOtherProperties; ItemAddr: String = ''); overload;

  function TranslateProperty(Component: TComponent; PropertyValue: String; PropertyID: TAdditionProperties; ItemAddr: String = ''): String; overload;
  function TranslateProperty(Component: TComponent; PropertyValue: String; PropertyID: TStringProperties; ItemAddr: String = ''): String; overload;
  function TranslateProperty(Component: TComponent; PropertyValue: String; PropertyID: TTStringsProperties; ItemAddr: String = ''): String; overload;
  function TranslateProperty(Component: TComponent; PropertyValue: String; PropertyID: TStructuredProperties; ItemAddr: String = ''): String; overload;
  function TranslateProperty(Component: TComponent; PropertyValue: String; PropertyID: TOtherProperties; ItemAddr: String = ''): String; overload;

implementation

uses LangManCtrls, Forms, Dialogs, Extctrls, Buttons, ValEdit,
     ActnList, Tabs, FileCtrl, Types, StdActns, ExtActns, RichEdit,

     {$IF CompilerVersion > 19}
     CategoryButtons, ButtonGroup,
     {$IFEND}

     ActnMan

     {$IFDEF DATABASES},
     DBGrids, DBCtrls, DBWeb
     {$ENDIF}
     {$IFDEF WIN3_1},
     TabNotBk
     {$ENDIF}
     {$IFDEF RAVE},
     RpRave, RpSystem, RpFiler, RpRender, RpRenderPDF, RvClass, RvProj, RvCsStd
     {$ENDIF}
     {$IFDEF TEECHART},
       {$IF CompilerVersion > 22}
         VCLTee.Chart, VCLTee.TeEngine
       {$ELSE}
         Chart, TeEngine
       {$IFEND}
     {$ENDIF};

var ActiveClient: TLangManClient;

//***************************************************************************
//**  LangManEngine Component methods                                      **
//***************************************************************************

procedure TLangManEngine.SetDesignLang(Input: TLanguage);
var NewName, OldName: TLanguage;
begin
  if Input <> '' then NewName := Input
                 else NewName := 'Design language';
  OldName := fDesignLanguage;
  fDesignLanguage := NewName;
  if Languages.Count = 0 then begin
    Languages.Add(NewName);
    FileNames.Add(NewName);
  end else begin
    Languages.Strings[0] := NewName;
    FileNames.Strings[0] := NewName;
  end;
  if fCurrentLanguage = OldName then fCurrentLanguage := NewName;
  if fDefaultLanguage = OldName then fDefaultLanguage := NewName;
  if OldName <> NewName then begin
    TranslateLangForm;
    FindLangFiles;
  end;
end;

function TLangManEngine.GetDefaultLanguage;
begin
  if DesignTime then begin
    DT_EngineOptions.Subdir := fLangSubdir;
    DT_EngineOptions.DesignLang := fDesignLanguage;
    DT_EngineOptions.LangFileExt := fLangFileExt;
    DT_EngineOptions.LangFileSign := fLangFileSign;
  end;
  Result := fDefaultLanguage;
end;

procedure TLangManEngine.SetDefaultLanguage(Input: TLanguage);
begin
  if fDefaultLanguage <> Input then begin
    fDefaultLanguage := Input;
    TranslateLangForm;
 //   FindLangFiles;
  end;
end;

procedure TLangManEngine.SetLangSubdir(Input: string);
begin
  LangDir := GetLangDir(ExtractFilePath(Application.ExeName), Trim(Input));
  if fLangSubdir <> Input then begin
    fLangSubdir := Trim(Input);
    FindLangFiles;
  end;
end;

procedure TLangManEngine.SetLangFileExt(Input: string);
begin
  if fLangFileExt <> Input then begin
    if Input <> '' then begin
      if Input[1] <> '.' then fLangFileExt := '.' + Input
                         else fLangFileExt := Input;
    end else fLangFileExt := '';
    FindLangFiles;
  end;
end;

procedure TLangManEngine.SetLangFileSign(Sign: string);
begin
  if fLangFileSign <> Sign then begin
    fLangFileSign := Sign;
    FindLangFiles;
  end;
end;

procedure TLangManEngine.SetLangCreatorVisible(Enable: Boolean);
begin
  if fLangCreatorVisible <> Enable then begin
    fLangCreatorVisible := Enable;
    ReCreateLangMenus;
  end;
end;

procedure TLangManEngine.SetLangEditorVisible(Enable: Boolean);
begin
  if fLangEditorVisible <> Enable then begin
    fLangEditorVisible := Enable;
    ReCreateLangMenus;
  end;
end;

procedure TLangManEngine.SetIncludeLangMan(Input: Boolean);
begin
  fIncludeLangMan := Input;
end;

procedure TLangManEngine.SetLangMenuFlags(Input: Boolean);
begin
  if Input <> fLangMenuFlags then begin
    fLangMenuFlags := Input;
    if (NOT DesignTime) and Assigned(fLanguageMenu) then ChangeLangMenu(fLanguageMenu);
  end;
end;

procedure TLangManEngine.SetLanguageMenu(MenuItem: TMenuItem);
begin
  fLanguageMenu := MenuItem;
  if Assigned(fLanguageMenu) then ReCreateLangMenus;
end;

procedure TLangManEngine.DesignLangFlagChanged(Sender: TObject);
begin
  fDesignLangFlag.OnChange := nil;
  AdaptFlagImage(fDesignLangFlag);
  FindLangFiles;
  fDesignLangFlag.OnChange := DesignLangFlagChanged;
end;

procedure TLangManEngine.SetDesignLangFlag(FlagImage: TPicture);
begin
  fDesignLangFlag.Assign(FlagImage);
end;

procedure TLangManEngine.SetLangResources(ResLangs: TStringList);
begin
  fLangResources.Assign(ResLangs);
  FindLangFiles;
end;

function TLangManEngine.CheckLangDir: Boolean;
begin
  Result := true;
  if NOT DirectoryExists(LangDir) then begin
    if (LangDir <> '') then Result := ForceDirectories(LangDir)  //CreateDir(LangDir);
                       else Result := false;
    if NOT Result then MessageDlg(LangFormLexicon.Item[29], mtError, [mbOK], 0);
  end;
end;

procedure TLangManEngine.ReCreateLangMenus;
begin
  if IsFullyCreated then begin
    LangMenu.Clear;
    LangMenu.Assign(Languages);
    if fLangCreatorVisible then begin
      LangMenu.Add(LangFormLexicon.Item[CREATOR_LANGITEM]);
      Flags.ImportFlag(LanguageMngForm.MenuIcons,0);
    end;
    if fLangEditorVisible and (Languages.Count > 1) then begin
      LangMenu.Add(LangFormLexicon.Item[EDITOR_LANGITEM]);
      Flags.ImportFlag(LanguageMngForm.MenuIcons,1);
    end;
    SpanClients.ChangeLangLists(LangMenu, fCurrentLanguage, Flags);
    if Assigned(fLanguageMenu) then ChangeLangMenu(fLanguageMenu);
  end;
end;

procedure TLangManEngine.FindLangFiles;
var SearchRec: TSearchRec;
    FindResult: Integer;
    LResStream: TResourceStream;

  procedure RegisterLang(LangFile, LangName: string);
  var LangExist: Integer;
  begin
    if (LangName <> '') then begin
      LangExist := Languages.IndexOf(LangName);
      if LangExist > 0 then begin
        if (NOT FileExists(FileNames.Strings[LangExist])) and
           fLangEditorVisible and
           (fLangResources.IndexOf(FileNames.Strings[LangExist]) >= 0) then begin
          FileNames.Strings[LangExist] := LangFile;
          if LoadedFlag then with LanguageMngForm.FlagImage.Picture do begin
            try
              Bitmap.LoadFromStream(GetFlag);
              Flags.RewriteFlag(LangExist,Graphic);
            except
              Flags.RewriteFlag(LangExist,nil);
            end;
          end else Flags.RewriteFlag(LangExist,nil);
        end;
      end else begin
        FileNames.Add(LangFile);
        Languages.Add(LangName);
        if LoadedFlag then with LanguageMngForm.FlagImage.Picture do begin
          try
            Bitmap.LoadFromStream(GetFlag);
            Flags.AddFlag(Graphic);
          except
            Flags.RewriteFlag(LangExist,nil);
          end;
        end else Flags.AddFlag(nil);
      end;
    end;
  end;

begin
  if IsFullyCreated then begin
    //DataStruct.Clear;  //REM od v1.1.7 -> jazykovy soubor zustava nacteny v pameti
                         // kvuli dynamickym formularum a runtime volani Translate
                         // aby nebylo zapotrebi znovu nacitat jazyk ze souboru
    Languages.Clear;
    FileNames.Clear;
    Flags.ClearFlags;
    Languages.Add(fDesignLanguage);
    FileNames.Add(fDesignLanguage);
    Flags.AddFlag(fDesignLangFlag.Graphic);
    if fLangResources.Count > 0 then begin
     ResourcesLoaded := true;
     for FindResult := 0 to fLangResources.Count - 1 do begin
      // load langs from resources
      try
        LResStream := TResourceStream.Create(HInstance, fLangResources.Strings[FindResult], RT_RCDATA);
        try
          RegisterLang(fLangResources.Strings[FindResult], GetLangName(LResStream, '[' + fLangFileSign + ']', true));
        finally
          LResStream.Free;
        end;
      except
        if NOT DesignTime then fLangResources.Delete(FindResult);
      end;
     end;
    end;
    if (LangDir <> '') then begin
      FindResult := FindFirst(LangDir + '*.*',faAnyFile,SearchRec);
      while FindResult = 0 do begin
        if ExtractFileExt(LowerCase(SearchRec.Name)) = LowerCase(fLangFileExt) then begin
          RegisterLang(LangDir + SearchRec.Name, GetLangName(LangDir + SearchRec.Name, '[' + fLangFileSign + ']', true));
        end;
        FindResult := FindNext(SearchRec);
      end;
      FindClose(SearchRec);
    end;
    ReCreateLangMenus;
  end;
end;

procedure TLangManEngine.ChangeLangMenu(MenuItem: TMenuItem);
var LangIndex: Integer;

  function CreateMenuItem(LangName: string; FlagIndex: Integer): TMenuItem;
  begin
    Result := TMenuItem.Create(MenuItem);
    with Result do begin
      Caption := LangName;
      AutoCheck := true;
      RadioItem := true;
      Checked := LangName = CurrentLanguage;
      if fLangMenuFlags then ImageIndex := Flags.GetImageIndex(FlagIndex);
      OnClick := LangMenuClick;
    end;
  end;

begin
  if MenuItem <> nil then begin
    for LangIndex := 0 to LangMenu.Count - 1 do begin
      if LangIndex < MenuItem.Count then begin
        with MenuItem.Items[LangIndex] do begin
          Caption := LangMenu.Strings[LangIndex];
          AutoCheck := true;
          RadioItem := true;
          Checked := LangMenu.Strings[LangIndex] = CurrentLanguage;
          if fLangMenuFlags then ImageIndex := Flags.GetImageIndex(LangIndex);
          OnClick := LangMenuClick;
        end;
      end else MenuItem.Add(CreateMenuItem(LangMenu.Strings[LangIndex],LangIndex));
    end;
    while LangIndex < (MenuItem.Count - 1) do MenuItem.Delete(LangIndex);
    MenuItem.SubMenuImages := Flags;
  end;
end;

procedure TLangManEngine.LangMenuClick(Sender: TObject);
var SelLang: String;
begin
  if Sender is TMenuItem then begin
    SelLang := RemoveAmpersand((Sender as TMenuItem).Caption);
    if SelLang <> fCurrentLanguage then Translate(SelLang);
  end;
end;

procedure TLangManEngine.ApplicationRun(AOwner: TObject);
begin
  if (NOT FirstTranslated) and (fDefaultLanguage <> fDesignLanguage) then begin
    if (fLangResources.Count > 0) AND (NOT ResourcesLoaded) then FindLangFiles;
    Translate(fDefaultLanguage);
  end else FindLangFiles;
  Application.OnActivate := ApplicationOnActivate;
  if Assigned(ApplicationOnActivate) then ApplicationOnActivate(AOwner);
  IsInitialized := true;
end;

{$HINTS OFF}

function TLangManEngine.LoadLangFromFile(LangName: TLanguage; CreateSource: boolean; MarkOld: Boolean = false; AntiLoop: TLanguage = ''): boolean;
var LangIndex, SI, FPos: Integer;
    LangSource: TStringList;
    LangResource: TResourceStream;
    Bufstr, LexiconName: String;
    Bufint: Integer;
    Data  : TStructLine;

  function CheckSuperiorLanguage(LangDef: string): boolean;
  var SuperiorIndex: Integer;
      SuperiorLanguage: string;
  begin
    Result := false;
    SuperiorIndex := -1;
    SuperiorLanguage := GetDescriptor(LangDef,SUPERIOR_LANGUAGE_DESCRIPTOR);
    if SuperiorLanguage <> '' then SuperiorIndex := Languages.IndexOf(SuperiorLanguage);
    if SuperiorIndex < 0 then begin
      SuperiorLanguage := fDefaultLanguage;
      if SuperiorLanguage <> '' then SuperiorIndex := Languages.IndexOf(SuperiorLanguage);
      if (SuperiorIndex < 0) OR (SuperiorLanguage = AntiLoop) then SuperiorLanguage := fDesignLanguage;
    end;
    if AntiLoop = '' then begin  // první načítaný jazyk
      LoadLangFromFile(SuperiorLanguage,false,MarkOld,LangName);
      if CreateSource then begin
        LanguageMngForm.SuperiorLanguage := SuperiorLanguage;
        Result := true;
      end;
    end else begin               // rekurzivní načítání
      LoadLangFromFile(SuperiorLanguage,false,MarkOld,AntiLoop);
    end;
  end;

  function CheckLineStructure(Bufint: Integer; Bufstr: string): boolean;
  begin
    Result := false;
    Data.Text := ExtrahovatZUvozovek(Bufstr);
    if (BufInt >= 0) then begin
      Data.Properties := BufInt;
      Data.Name := GetDescriptor(Bufstr,COMPONENT_DESCRIPTOR);
      if Data.Name = '' then Exit;
      Data.Parent := GetDescriptor(Bufstr,PARENT_DESCRIPTOR);
      if Pos(NOTRANS_DESCRIPTOR,Bufstr) > 0 then Data.Changeable := ca_NO
                                            else Data.Changeable := ca_YES;
      if Pos(OLD_ITEM_DESCRIPTOR,Bufstr) > 0
        then Data.Changeable := Data.Changeable OR ca_OLD
        else if MarkOld and (NOT SpanClients.IsRegistered(Data.Parent, Data.Name))
               then Data.Changeable := Data.Changeable + ca_OLD;
      Data.ItemAddr := GetDescriptor(Bufstr,ITEM_DESCRIPTOR);
      Result := true;
    end;
  end;

begin
  Result := false;
  DataStruct.Clear;
  DataLexicon.Clear;
  if CreateSource then begin
    LanguageMngForm.SourceStruct.Clear;
    LanguageMngForm.SourceLexicon.Clear;
  end;
  LangIndex := Languages.IndexOf(LangName);
  if (LangIndex > 0) then begin
    try
      LangSource := TStringList.Create;
      LangSource.NameValueSeparator := cTAB;
      try
        if FileExists(FileNames.Strings[LangIndex]) then begin
          LangSource.LoadFromFile(FileNames.Strings[LangIndex]);
        end else begin
          if LangResources.IndexOf(FileNames.Strings[LangIndex]) >= 0 then begin
            LangResource := TResourceStream.Create(HInstance,FileNames.Strings[LangIndex],RT_RCDATA);
            try
              LangSource.LoadFromStream(LangResource);
            finally
              LangResource.Free;
            end;
          end else begin
            Result := false;
            Exit;
          end;
        end;
        if LangSource.Count > 0 then begin
          if LangSource.Strings[0] <> '[' + fLangFileSign + ']' then Abort;
          FPos := 1;
          while NOT EoFile(LangSource, FPos) do begin
            Bufstr := LangSource.Strings[FPos];
            Inc(FPos);
            if Pos(LANGUAGE_DESCRIPTOR,Bufstr) > 0 then begin
              if CheckSuperiorLanguage(Bufstr) then CompleteSourceData;
              // misto pro kontrolu verze souboru (po pripadnych budoucich zmenach ve formatu)
              Bufstr := ExtrahovatZUvozovek(Bufstr);
              if Bufstr = LangName then Break;
            end;
          end;
          while NOT EoFile(LangSource, FPos) DO begin
            if NOT FileReadInt(LangSource,Bufint,FPos) then Continue;
            Bufstr := LangSource.ValueFromIndex[FPos];
            Inc(FPos);
            if Pos(LEXICON_SEPARATOR,Bufstr) > 0 then Break;
            if CheckLineStructure(Bufint,Bufstr) then begin
              if (NOT CreateSource) then begin
                SI := GetStructIndex(DataStruct,Data.Name,Data.Parent,Bufint,Data.ItemAddr);
                if SI >= 0 then begin
                  if (Data.Changeable and ca_YES) = ca_NO then Data.Text := DataStruct.Text.Strings[SI];
                  DataStruct.Line[SI] := Data
                end else DataStruct.AddLine(Data);
              end else DataStruct.AddLine(Data);
            end;
          end;
          LexiconName := '';
          while NOT EoFile(LangSource, FPos) DO begin
            if NOT FileReadInt(LangSource,Bufint,FPos) then Continue;
            Bufstr := LangSource.ValueFromIndex[FPos];
            Inc(FPos);
            if Pos(SMART_SEPARATOR,Bufstr) > 0 then Break;
            if Pos(LEXICON_DESCRIPTOR,Bufstr) > 0 then begin
              LexiconName := GetDescriptor(Bufstr,LEXICON_DESCRIPTOR);
              if LexiconName <> '' then DataLexicon.NewLexicon(LexiconName)
                                   else Abort;
            end else begin
              Bufstr := ExtrahovatZUvozovek(Bufstr);
              if (BufInt >= 0) and (Bufstr <> '') then begin
                if LexiconName <> '' then DataLexicon.WriteItem(LexiconName,BufInt,Bufstr);
              end;
            end;
          end;
          while NOT EoFile(LangSource, FPos) DO begin
            if NOT FileReadInt(LangSource,Bufint,FPos) then Continue;
            Bufstr := LangSource.ValueFromIndex[FPos];
            Inc(FPos);
            if Pos(FLAG_ICON_DESCRIPTOR,Bufstr) > 0 then Break;
            GetDescriptor(Bufstr,KEY_DESCRIPTOR); // vrati klic
            Bufstr := ExtrahovatZUvozovek(Bufstr); // preklad do Bufstr
            // zalozeni prekladu pod klicem (nutno doprogramovat)
          end;
          // Ikona se cte pouze pri nacitani pro editaci
          if CreateSource then LoadFlag(LangSource, FPos)
                          else EraseFlag;
          Result := true;
        end;
      finally
        LangSource.Free;
      end;
    except
  //    MessageDlg(,mtError,[mbOK],0);   none
    end;
  end else Result := LangIndex = 0;
end;

{$HINTS ON}

function TLangManEngine.LoadLangManLang(StringArray: array of string): boolean;
var LI: Word;
begin
  for LI := 0 to LANGMANLANG_ITEMS do LangFormLexicon.DefineItem(LI,StringArray[LI]);
  Result := true;
end;

function TLangManEngine.InternalLanguages(Lang: TLanguage): boolean;
begin
  Result := false;
  if Slovak(Lang) then Result := LoadLangManLang(SLOVAK_LANGMAN);
  // other internal langs
  if Czech(Lang) then Result := LoadLangManLang(CZECH_LANGMAN);
  if English(Lang) then Result := LoadLangManLang(ENGLISH_LANGMAN);
end;

procedure TLangManEngine.TranslateLangForm;
begin
  if IsFullyCreated then begin
    if fCurrentLanguage <> '' then IsInternalLanguage := InternalLanguages(fCurrentLanguage)
                              else IsInternalLanguage := false;
    if NOT IsInternalLanguage then begin
      if (fDefaultLanguage <> fCurrentLanguage) and
         (fDefaultLAnguage <> '') and
         InternalLanguages(fDefaultLanguage) then Exit;
      if (fDesignLanguage <> fCurrentLanguage) and
         (fDesignLanguage <> '') and
         InternalLanguages(fDesignLanguage) then Exit;
      LoadLangManLang(ENGLISH_LANGMAN);
    end;
  end;
end;

function TLangManEngine.LangManCommands(Command: String): TLanguage;

  procedure FormInitialize(EL: byte);
  begin
    with LanguageMngForm do begin
      EditMode := EL = 1;
      CurrentGroup := -1;
      CurrentObject := -1;
      LangManLangVisible := false;
      LangCombo.Items.Clear;
      LangCombo.Items.Assign(Languages);
      LangCombo.Style := csDropDownList;
      LangCombo.ItemIndex := -1;
      LangCombo.Enabled := true;
      Caption := LangFormLexicon.Item[0];
      LLanguage.Caption := LangFormLexicon.Item[3+EL] + ':';
      AddLangButton.Visible := false;
      FinishBtn.Visible := false;
      LRefLangLabel.Caption := LangFormLexicon.Item[5] + ' :';
      LRefLang.Left := LRefLangLabel.Width + LRefLangLabel.Left + 6;
      LRefTextLabel.Caption := LangFormLexicon.Item[6] + ' :';
      LRefText.Left := LRefTextLabel.Width + LRefTextLabel.Left + 6;
      LRefLang.Caption := '';
      LRefText.Caption := '';
      LangFilesPanel.Enabled := false;
      LangListEditor.Enabled := false;
      LangListEditor.Strings.Clear;
      LangListEditor.TitleCaptions.Strings[0] := LangFormLexicon.Item[7];
      LangListEditor.TitleCaptions.Strings[1] := LangFormLexicon.Item[8];
      DontTransBtn.Caption := LangFormLexicon.Item[9];
      DontTransBtn.Enabled := false;
      LGroup.Caption := LangFormLexicon.Item[10] + ':';
      LObject.Caption := LangFormLexicon.Item[11] + ':';
      AddLangButton.Hint := LangFormLexicon.Item[12];
      DontTransBtn.Hint := LangFormLexicon.Item[13];
      GroupCombo.Hint := LangFormLexicon.Item[14];
      ILeft.Hint := LangFormLexicon.Item[15];
      IRight.Hint := LangFormLexicon.Item[16];
      SaveDialog.Filter := '[' + LangFormLexicon.Item[20] +  ' *' + LowerCase(fLangFileExt) + ']|*' + LowerCase(fLangFileExt);
      SaveDialog.Title := LangFormLexicon.Item[21];
      NotFoundMessage := LangFormLexicon.Item[23];
      CloseQueryMessage := LangFormLexicon.Item[24];
      FlagImage.Hint := LangFormLexicon.Item[25];
      OpenPictureDialog.Title := LangFormLexicon.Item[26];
      EraseFlagMessage := LangFormLexicon.Item[27];
      FinishBtn.Caption := LangFormLexicon.Item[28];
      LItem.Caption := '-/-';
      ObjectCombo.Items.Clear;
      GroupCombo.Items.Clear;
      FlagImage.Visible := false;
      LangCombo.OnChange := LangFormSelectLang;
    end;
  end;

begin
  Result := Command;
  if Command = LangFormLexicon.Item[CREATOR_LANGITEM] then begin
    if Assigned(fOnBeforeEdit) then fOnBeforeEdit(Self);
    FormInitialize(0);
    with LanguageMngForm do begin
      if ShowModal = mrOK then begin
        StoreChanges;
        SaveLanguagefile(LangCombo.Text,
                         SuperiorLAnguage,
                         LangDir + ExtractFileName(SaveDialog.FileName));
      end;
      Result := LangCombo.Text;
    end;
    FindLangFiles;
    if Assigned(fOnAfterEdit) then fOnAfterEdit(Self);
  end;
  if (Command = LangFormLexicon.Item[EDITOR_LANGITEM]) and (Languages.Count > 1) then begin
    if Assigned(fOnBeforeEdit) then fOnBeforeEdit(Self);
    FormInitialize(1);
    with LanguageMngForm do begin
      LangCombo.Items.Delete(0);  // remove Design language from Edit List
      if ShowModal = mrOK then begin
        StoreChanges;
        SaveLanguageFile(LangCombo.Text,
                         SuperiorLanguage,
                         FileNames.Strings[LangCombo.ItemIndex + 1]);
      end;
      Result := LangCombo.Text;
    end;
    SpanClients.ChangeLangLists(LangMenu, fCurrentLanguage, Flags);
    if Assigned(fOnAfterEdit) then fOnAfterEdit(Self);
  end;
end;

procedure TLangManEngine.LangFormSelectLang(AOwner: TObject);
var LangIndex: Integer;
begin
  with LanguageMngForm do begin
    if EditMode then begin
      LangIndex := Languages.IndexOf(LangCombo.Text);
      if LangIndex >= 0 then begin
        if NOT FileExists(FileNames.Strings[LangIndex]) then begin
          // edit language from resources
          if NOT ResourceLangToFile(LangIndex) then begin
            Close;
            Exit;
          end;
        end;
      end;
      if LoadLangFromFile(LangCombo.Text,true,true) then begin
        LangCombo.OnChange := nil;
        LangCombo.Enabled := false;
        LoadGroups(Self);
        EditStart;
      end else begin
        MessageDlg(LangFormLexicon.Item[17],mtError,[mbOK],0);
        LangCombo.ItemIndex := -1;
      end;
    end else begin
      if LoadLangFromFile(LangCombo.Text,false) then begin
        LLanguage.Caption := LangFormLexicon.Item[18] + ':';
        LangLabelBuf := LangFormLexicon.Item[4] + ':';
        LangMessageBuf := LangFormLexicon.Item[19];
        CompleteSourceData;
        SuperiorLanguage := LangCombo.Text;
        LangCombo.OnChange := nil;
        LangCombo.ItemIndex := -1;
        LangCombo.Style := csSimple;
        LangCombo.Text := '';
        AddLangButton.OnClick := CreateLanguage;
        AddLangButton.Visible := true;
      end else begin
        MessageDlg(LangFormLexicon.Item[17],mtError,[mbOK],0);
        LangCombo.ItemIndex := -1;
      end;
    end;
  end;
end;

procedure TLangManEngine.CreateLanguage(AOwner: TObject);
begin
  with LanguageMngForm do begin
    if LangCombo.Text <> '' then begin
      if Languages.IndexOf(LangCombo.Text) < 0 then begin
        if CheckLangDir then begin
          SaveDialog.InitialDir := LangDir;
          SaveDialog.DefaultExt := LowerCase(fLangFileExt);
          if SaveDialog.Execute and (ExtractFileName(SaveDialog.FileName) <> '') then begin
            LLanguage.Caption := LangLabelBuf;
            LangCombo.Enabled := false;
            LoadGroups(Self);
            EditStart;
          end;
        end else Close;
      end else MessageDlg(LangCombo.Text + ' ' + LangMessageBuf,mtWarning,[mbOK],0);
    end;
  end;
end;

procedure TLangManEngine.LoadGroups(AOwner: TObject);
var SpanIndex: Integer;
    LangManLex: TComponent;
begin
  with LanguageMngForm do begin
    GroupCombo.Items.Clear;
    LangManLex := nil;
    if fIncludeLangMan and (NOT InternalLanguages(LangCombo.Text)) then begin
      TranslateLangForm;
      LangManLangVisible := true;
    end;
    if SpanClients.Components.Count > 0 then begin
      while ClientGroups.Count > 0 do ClientGroups.Extract(ClientGroups.Items[0]);
      for SpanIndex := 0 to SpanClients.Components.Count - 1 do begin
        if SpanClients.Components.Items[SpanIndex] is TLangManClient then begin
          GroupCombo.Items.Add((SpanClients.Components.Items[SpanIndex] as TLangManClient).ParentControl.Name);
          ClientGroups.Add(SpanClients.Components.Items[SpanIndex]);
        end;
        if SpanClients.Components.Items[SpanIndex] is TLexicon then begin
          if (SpanClients.Components.Items[SpanIndex] is TLangFormLexicon) then begin
            if (LangManLangVisible) then LangManLex := SpanClients.Components.Items[SpanIndex];
          end else begin
            GroupCombo.Items.Add(GetLexiconName(SpanClients.Components.Items[SpanIndex]));
            ClientGroups.Add(SpanClients.Components.Items[SpanIndex]);
          end;
        end;
      end;
    end;
    if LangManLex <> nil then begin  // LangMan na konec seznamu skupin
      GroupCombo.Items.Add(GetLexiconName(LangManLex));
      ClientGroups.Add(LangManLex);
    end;
    GroupCombo.OnChange := ChangeGroup;
  end;
end;

procedure TLangManEngine.StoreWorks;
var II, SI: Integer;
    LexName: string;
begin
  with LanguageMngForm do begin
    if CurrentGroup >= 0 then begin
      if LexiconMode then begin
        if WorkLexicon.Count > 0 then begin
          LexName := GroupCombo.Items.Strings[CurrentGroup];
          if NOT DataLexicon.LexiconExists(LexName) then DataLexicon.NewLexicon(LexName);
          for II := 0 to WorkLexicon.MaxIndex do begin
            if WorkLexicon.IsIncluded(II) then begin
              if (WorkLexicon.Get(II) <> '') then DataLexicon.WriteItem(LexName,II,WorkLexicon.Get(II))
                                             else DataLexicon.RemoveItem(LexName,II);
            end;
          end;
        end;
      end else begin
        if WorkStruct.Names.Count > 0 then begin
          for II := 0 to WorkStruct.Names.Count - 1 do begin
            SI := GetStructIndex(DataStruct,
                                 WorkStruct.Names.Strings[II],
                                 WorkStruct.Parents.Strings[II],
                                 WorkStruct.Properties.GetWord(II),
                                 WorkStruct.ItemAddr.Strings[II]);
            if ca_CHANGED = (WorkStruct.Changeable.GetWord(II) and ca_CHANGED) then begin
              if SI >= 0 then begin
                           DataStruct.Text.Strings[SI] := WorkStruct.Text.Strings[II];
                           DataStruct.Changeable.RewriteWord(SI,WorkStruct.Changeable.GetWord(II));
                         end else DataStruct.AddLine(WorkStruct.Line[II]);
            end;
          end;
        end;
      end;
      CurrentGroup := -1; // ulozeny zmeny ve WorkStruct ci WorkLexicon
    end;
  end;
end;

procedure TLangManEngine.StoreChanges;
begin
  with LanguageMngForm do begin
    StoreCurrentTranslate(false);
    StoreWorks;
  end;
end;

procedure TLangManEngine.ChangeGroup(AOwner: TObject);
var LI, SI: Integer;
    Lexicon: TLexicon;
    Speedy: boolean;
begin
  with LanguageMngForm do begin
    StoreChanges;
    WorkLexicon.Clear;
    WorkStruct.Clear;
    if GroupCombo.ItemIndex >= 0 then begin
      LexiconMode := NOT (ClientGroups.Items[GroupCombo.ItemIndex] is TLangManClient);
      if LexiconMode then begin
        Lexicon := TLexicon(ClientGroups.Items[GroupCombo.ItemIndex]);
        if Lexicon.MaxIndex >= 0 then begin
          for LI := 0 to Lexicon.MaxIndex do
            if Lexicon.IsDefined(LI) and (Lexicon.GetItem(LI) <> '') then begin
              if DataLexicon.IsIncluded(GetLexiconName(Lexicon),LI)
                then WorkLexicon.Add(LI,DataLexicon.ReadItem(GetLexiconName(Lexicon),LI))
                else if SourceLexicon.IsIncluded(GetLexiconName(Lexicon),LI)
                       then WorkLexicon.Add(LI,SourceLexicon.ReadItem(GetLexiconName(Lexicon),LI))
                       else WorkLexicon.Add(LI,Lexicon.GetItem(LI));
            end;
        end;
        ObjectCombo.ItemIndex := -1;
        LItem.Caption := '-/-';
        DontTransBtn.Enabled := false;
      end else begin
        CopyStructure((ClientGroups.Items[GroupCombo.ItemIndex] as TLangManClient).DesignStruct, WorkStruct);
        with WorkStruct do begin
          if Names.Count > 0 then begin
            for LI := 0 to Names.Count - 1 do begin
              Speedy := false;
              if DataStruct.Names.Count > 0 then begin
                SI := GetStructIndex(DataStruct,
                                     Names.Strings[LI],
                                     Parents.Strings[LI],
                                     Properties.GetWord(LI),
                                     ItemAddr.Strings[LI]);
                if SI >= 0 then begin
                  Changeable.RewriteWord(LI,ca_CHANGED OR DataStruct.Changeable.GetWord(SI));
                  Text.Strings[LI] := DataStruct.Text.Strings[SI];
                  Speedy := true;
                end;
              end;
              if NOT Speedy then begin
                SI := GetStructIndex(SourceStruct,
                                     Names.Strings[LI],
                                     Parents.Strings[LI],
                                     Properties.GetWord(LI),
                                     ItemAddr.Strings[LI]);
                if SI >= 0 then begin
                  Text.Strings[LI] := SourceStruct.Text.Strings[SI];
                  Changeable.RewriteWord(LI,SourceStruct.Changeable.GetWord(SI));
                end;
              end;
            end;
          end;
        end;
        DontTransBtn.Enabled := true;
        ParseStruct;
        if ObjectCombo.Items.Count > 0 then ObjectCombo.ItemIndex := 0;
        LItemAktualize;
      end;
    end;
    LObject.Enabled := NOT LexiconMode;
    LItem.Enabled := NOT LexiconMode;
    ObjectCombo.Enabled := NOT LexiconMode;
    TranslateObject;
  end;
end;

procedure TLangManEngine.CompleteSourceData;
var SI,OI,Index: Integer;
    Client: TLangManClient;
    DataLine: TStructLine;
    Lexicon: TLexicon;
begin
  LanguageMngForm.SourceStruct.Clear;
  LanguageMngForm.SourceLexicon.Clear;
  if SpanClients.Components.Count > 0 then begin
    for SI := 0 to SpanClients.Components.Count - 1 do begin
      if SpanClients.Components.Items[SI] is TLangManClient then begin
        Client := TLangManClient(SpanClients.Components.Items[SI]);
        if Client.DesignStruct.Names.Count > 0 then begin
          for OI := 0 to Client.DesignStruct.Names.Count - 1 do begin
            DataLine := Client.DesignStruct.Line[OI];
            Index := GetStructIndex(DataStruct,DataLine.Name,DataLine.Parent,DataLine.Properties,DataLine.ItemAddr);
            if (Index >= 0) then begin
              DataLine.Changeable := DataStruct.Changeable.GetWord(Index) and (NOT ca_OLD);
              if DataStruct.Text.Strings[Index] <> '' then DataLine.Text := DataStruct.Text.Strings[Index];
            end;
            LanguageMngForm.SourceStruct.AddLine(DataLine);
          end;
        end;
      end;
      if SpanClients.Components.Items[SI] is TLexicon then begin
        Lexicon := TLexicon(SpanClients.Components.Items[SI]);
        LanguageMngForm.SourceLexicon.NewLexicon(GetLexiconName(Lexicon));
        if Lexicon.MaxIndex >= 0 then begin
          for OI := 0 to Lexicon.MaxIndex do begin
            if Lexicon.IsDefined(OI) then begin
              if DataLexicon.IsIncluded(GetLexiconName(Lexicon),OI)
                then LanguageMngForm.SourceLexicon.WriteItem(GetLexiconName(Lexicon),OI,DataLexicon.ReadItem(GetLexiconName(Lexicon),OI))
                else LanguageMngForm.SourceLexicon.WriteItem(GetLexiconName(Lexicon),OI,Lexicon.GetItem(OI));
            end;
          end;
        end;
      end;
    end;
  end;
  DataStruct.Clear;
  DataLexicon.Clear;
end;

procedure TLangManEngine.SaveLanguageFile(LangName, SuperiorLang, FileName: string);
var LFile: TStringList;
    I, LI: Integer;
    LexName, LineBuf: string;

  function LineFormatter(PropertyType: Word; Text, Name, Parent: string; ItemAddr: string; ChangeAble: Word): string;
  begin
    if (Changeable and ca_YES) = ca_YES
      then Result := IntToStr(PropertyType) + cTAB + UVOZOVKA + Text + UVOZOVKA + cTAB +
                     COMPONENT_DESCRIPTOR + Name + STREDNIK + cTAB +
                     PARENT_DESCRIPTOR + Parent + STREDNIK
      else Result := IntToStr(PropertyType) + cTAB + NOTRANS_DESCRIPTOR + cTAB +
                     COMPONENT_DESCRIPTOR + Name + STREDNIK + cTAB +
                     PARENT_DESCRIPTOR + Parent + STREDNIK;
    if ItemAddr <> '' then Result := Result + cTAB + ITEM_DESCRIPTOR + ItemAddr + STREDNIK;
    if (Changeable and ca_OLD) = ca_OLD then Result := Result + cTAB + OLD_ITEM_DESCRIPTOR;
  end;

begin
  if CheckLangDir and (LangName <> '') and (FileName <> '') then begin
    try
      LFile := TStringList.Create;
      try
        LFile.Add('[' + fLangFileSign + ']');
        LineBuf := '0' + cTAB + LANGUAGE_DESCRIPTOR + UVOZOVKA + LangName + UVOZOVKA;
        if (SuperiorLang <> '') then LineBuf := LineBuf + cTAB + SUPERIOR_LANGUAGE_DESCRIPTOR + SuperiorLang + STREDNIK;
        LFile.Add(LineBuf + cTAB + LANGUAGE_FILEVERSION_DESCRIPTOR + LANGUAGE_FILE_VERSION + STREDNIK);
        if DataStruct.Names.Count > 0 then begin
          for I := 0 to DataStruct.Names.Count - 1 do begin
            with DataStruct do LFile.Add(LineFormatter(Properties.GetWord(I),
                                                       Text.Strings[I],
                                                       Names.Strings[I],
                                                       Parents.Strings[I],
                                                       ItemAddr.Strings[I],
                                                       Changeable.GetWord(I)));
          end;
        end;
        LFile.Add('0' + cTAB + LEXICON_SEPARATOR);
        if (DataLexicon.LexiconCount > 0) then begin
          for LI := 0 to DataLexicon.LexiconCount - 1 do begin
            LexName := DataLexicon.LexiconName(LI);
            if DataLexicon.ItemsCount(LexName) > 0 then begin
              LFile.Add('0' + cTAB + LEXICON_DESCRIPTOR + LexName + STREDNIK);
              for I := 0 to DataLexicon.MaxItemNr(LexName) do begin
                if DataLexicon.IsIncluded(LexName,I) and
                   (DataLexicon.ReadItem(LexName,I) <> '') then
                  LFile.Add(IntToStr(I) + cTAB + UVOZOVKA + DataLexicon.ReadItem(LexName,I) + UVOZOVKA);
              end;
            end;
          end;
        end;
        LFile.Add('0' + cTAB + SMART_SEPARATOR);
        // ulozeni smart lexiconu neni implementovano

        if LoadedFlag then SaveFlag(LFile);
      {$IF CompilerVersion > 19}
        case fLangFileEncoding of
          Unicode: LFile.SaveToFile(FileName, TEncoding.Unicode);
          BigEndianUnicode: LFile.SaveToFile(FileName, TEncoding.BigEndianUnicode);
          UTF8: LFile.SaveToFile(FileName, TEncoding.UTF8);
          else LFile.SaveToFile(FileName);
        end;
      {$ELSE}
        LFile.SaveToFile(FileName);
      {$IFEND}
      finally
        LFile.Free;
      end;
    except
      MessageDlg(LangFormLexicon.Item[22],mtError,[mbOK],0);
    end;
  end;
end;

function TLangManEngine.GetString(Lex: TComponent; Index: Integer): string;
begin
  Result := DataLexicon.ReadItem(GetLexiconName(Lex),Index);
end;

function TLangManEngine.ResourceLangToFile(LangIndex: Integer): Boolean;
var LResStream: TResourceStream;
    ResID: Integer;
    StrBuf: String;
begin
  Result := false;
  if fLangResources.Count > 0 then begin
    ResID := fLangResources.IndexOf(FileNames.Strings[LangIndex]);
    if ResID >= 0 then begin
      // load language from resources
      try
        if CheckLangDir then begin
          LResStream := TResourceStream.Create(HInstance, fLangResources.Strings[ResID], RT_RCDATA);
          try
            if ExtractFileExt(LowerCase(fLangResources.Strings[ResID])) = LowerCase(fLangFileExt)
              then FileNames.Strings[LangIndex] := LangDir + fLangResources.Strings[ResID]
              else FileNames.Strings[LangIndex] := LangDir + fLangResources.Strings[ResID] + fLangFileExt;
            while FileExists(FileNames.Strings[LangIndex]) do begin
              StrBuf := FileNames.Strings[LangIndex];
              if Length(fLangFileExt) > 0 then Insert('2',StrBuf,Length(StrBuf) + 1 - Length(fLangFileExt))
                                          else StrBuf := StrBuf + '2';
              FileNames.Strings[LangIndex] := StrBuf;
            end;
            LResStream.SaveToFile(FileNames.Strings[LangIndex]);
          finally
            LResStream.Free;
          end;
          Result := true;
        end;
      except
        // Ignore
      end;
    end;
  end;
end;

constructor TLangManEngine.Create(AOwner: TComponent);
begin
  IsInitialized := false;
  IsFullyCreated := false;
  FirstTranslated := false;
  ResourcesLoaded := false;
  inherited Create(AOwner);
  fLangMenuFlags := true;
  SpanClients     := TSpans.Create;
  Languages       := TStringList.Create;
  FileNames       := TStringList.Create;
  LangMenu        := TStringList.Create;
  fLangResources  := TStringList.Create;
  Flags           := TFlagsList.Create(Self);
  fDesignLangFlag := TPicture.Create;
  DataStruct      := TComponentStructure.Create;
  DataLexicon     := TLexiconData.Create;
  LangFormLexicon := TLangFormLexicon.Create(Self);
  LanguageMngForm := TLanguageManager.Create(Self);
  if Languages.Count = 0 then SetDesignLang('');
  if LangDir = '' then SetLangSubdir('');
  fDesignLangFlag.OnChange := DesignLangFlagChanged;
  SetLangFileExt('lng');
  fLangFileSign := 'LANGUAGE_FILE';
  SetLangCreatorVisible(True);
  SetLangEditorVisible(True);
  fIncludeLangMan := False;
  fLangFileEncoding := Unicode;
  IsFullyCreated := true;
  TranslateLangForm;
  FindLangFiles;
  if NOT DesignTime then begin
    ApplicationOnActivate := Application.OnActivate;
    Application.OnActivate := ApplicationRun;
  end;
end;

destructor TLangManEngine.Destroy;
begin
  LangFormLexicon.Free;
  LanguageMngForm.Free;
  Languages.Free;
  FileNames.Free;
  fLangResources.Free;
  LangMenu.Free;
  Flags.Free;
  fDesignLangFlag.Free;
  DataStruct.Free;
  DataLexicon.Free;
  SpanClients.Free;
  if Assigned(fLanguageMenu) then fLanguageMenu.Clear;
  inherited Destroy;
end;

function TLangManEngine.Translate(LangName: TLanguage): TLanguage;
var Lang: TLanguage;
    Continue: Boolean;
begin
  Continue := true;
  if Assigned(fOnChangeLangQuery) then fOnChangeLangQuery(Self,Continue);
  if Continue then begin
    Lang := LangManCommands(LangName);
    if (Languages.IndexOf(Lang) >= 0) then begin
      FirstTranslated := true;
      if LoadLangFromFile(Lang,false) then begin
        fCurrentLanguage := Lang;   // od v1.1.7
        SpanClients.CallClientProcs;
     // fCurrentLanguage := Lang;   // do v1.1.6
      end else begin
        fCurrentLanguage := fDesignLanguage;
        SpanClients.CallClientProcs;
      end;
      if Assigned(fOnChangeLanguage) then fOnChangeLanguage(Self);
      TranslateLangForm;
      ReCreateLangMenus;
    end;
    Result := fCurrentLanguage;
  end else ReCreateLangMenus;
end;

function TLangManEngine.GetLanguagesList: TStrings;
begin
  Result := Languages;
end;

function TLangManEngine.GetLangFilesList: TStrings;
begin
  Result := FileNames;
end;

procedure TLangManEngine.ShowLangEditor;
begin
  Translate(LangFormLexicon.Item[EDITOR_LANGITEM]);
end;

procedure TLangManEngine.ShowLangCreator;
begin
  Translate(LangFormLexicon.Item[CREATOR_LANGITEM]);
end;

//***************************************************************************
//**  LangManComponent methods                                             **
//***************************************************************************

procedure TLangManComponent.SetLangManEngine(LangMan: TLangManEngine);
begin
  if fLangManEngine <> LangMan then begin
    if (fLangManEngine <> nil) then fLangManEngine.SpanClients.UnregisterClient(Self);
    fLangManEngine := LangMan;
    if LangMan <> nil then fLangManEngine.SpanClients.RegisterClient(Self);
  end;
end;

procedure TLangManComponent.ChangeLanguage(AOwner: TObject);
begin
  if Assigned(fOnChangeLanguage) then fOnChangeLanguage(Self);
end;

//***************************************************************************
//**  LangManClient Component methods                                      **
//***************************************************************************

procedure TLangManClient.SetTransStringProp(Input: TTranslateStringProperties);
begin
  fTransStringProp := Input;
end;

procedure TLangManClient.SetTransTStringsProp(Input: TTranslateTStringsProperties);
begin
  fTransTStringsProp := Input;
end;

procedure TLangManClient.SetTransStructuredProp(Input: TTranslateStructuredProperties);
begin
  fTransStructuredProp := Input;
end;

procedure TLangManClient.SetTransOtherProp(Input: TTranslateOtherProperties);
begin
  fTransOtherProp := Input;
end;

procedure TLangManClient.SetTransAdditions(Input: TAdditionSet);
begin
  fTransAdditions := Input;
end;

function TLangManClient.TransComp(Component: TComponent; ChClass: TClass): Boolean;
begin
  Result := (Component is ChClass) and
            (NOT PriorityAbsorption(Component, ChClass));
end;

function TLangManClient.TransProp(Prop: TStringProperties): Boolean;
begin
  Result := (Prop in fTransStringProp);
end;

function TLangManClient.TransProp(Prop: TTStringsProperties): Boolean;
begin
  Result := (Prop in fTransTStringsProp);
end;

function TLangManClient.TransProp(Prop: TStructuredProperties): Boolean;
begin
  Result := (Prop in fTransStructuredProp);
end;

function TLangManClient.TransProp(Prop: TOtherProperties): Boolean;
begin
  Result := (Prop in fTransOtherProp);
end;

function TLangManClient.TransCompProp(Component: TComponent; ChClass: TClass; Prop: TStringProperties): Boolean;
begin
  Result := (Component is ChClass) and
            (Prop in fTransStringProp) and
            (NOT PriorityAbsorption(Component, ChClass));
end;

function TLangManClient.TransCompProp(Component: TComponent; ChClass: TClass; Prop: TTStringsProperties): Boolean;
begin
  Result := (Component is ChClass) and
            (Prop in fTransTStringsProp) and
            (NOT PriorityAbsorption(Component, ChClass));
end;

function TLangManClient.TransCompProp(Component: TComponent; ChClass: TClass; Prop: TStructuredProperties): Boolean;
begin
  Result := (Component is ChClass) and
            (Prop in fTransStructuredProp) and
            (NOT PriorityAbsorption(Component, ChClass));
end;

function TLangManClient.TransCompProp(Component: TComponent; ChClass: TClass; Prop: TOtherProperties): Boolean;
begin
  Result := (Component is ChClass) and
            (Prop in fTransOtherProp) and
            (NOT PriorityAbsorption(Component, ChClass));
end;

function TLangManClient.StructItem(Name, Parent: string; PropertyType: Word; Addr: string = ''): string;
var Bufstr: string;
begin
  Bufstr := GetStructItem(fLangManEngine.DataStruct,Name,Parent,PropertyType,Addr);
  if (Bufstr = '') then Bufstr := GetStructItem(DesignStruct,Name,Parent,PropertyType,Addr);
  Result := Bufstr;
end;

procedure TLangManClient.CreateStructItem(Component: PTComponent; PropertyType: Word; Input: string; Addr: string);
begin
  if ContainChars(Input) then with DesignStruct do begin
    Names.Add(Component^.Name);
    Parents.Add(Component^.Owner.Name);
    Properties.AddWord(PropertyType);
    Text.Add(Input);
    ItemAddr.Add(Addr);
    ChangeAble.AddWord(ca_YES);
  end;
end;

function TLangManClient.ChangeStructItem(Component: PTComponent; PropertyType : Word; InitText: string; fchInit: boolean; ActionString: string = ''): string;
var Bufstr: string;
begin
  if fchInit then begin
    if ContainChars(InitText) and (InitText <> Component^.Name) and (InitText <> ActionString) then begin
      with DesignStruct do begin
        Names.Add(Component^.Name);
        Parents.Add(Component^.Owner.Name);
        Properties.AddWord(PropertyType);
        Text.Add(InitText);
        ItemAddr.Add('');
        ChangeAble.AddWord(ca_YES);
      end;
    end;
    Result := InitText;
  end else begin
    Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType);
    if Bufstr <> '' then Result := Bufstr
                    else Result := InitText;
  end;
end;

function TLangManClient.ChangeStructItemEx(Component: PTComponent; PropertyType: Word; InitText: string; fchInit: Boolean; PresetAddr: string = ''): string;
var Bufstr: string;
begin
  if fchInit then begin
    CreateStructItem(Component,PropertyType,InitText,PresetAddr);
    Result := InitText;
  end else begin
    Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,PresetAddr);
    if Bufstr <> '' then Result := Bufstr
                    else Result := InitText;
  end;
end;

procedure TLangManClient.ChangeStructStrings(Component: PTComponent; PropertyType : Word; Data: TStrings; fchInit: boolean);
var Bufstr: string;
    II: Integer;
begin
  if Data.Count > 0 then for II := 0 to Data.Count - 1 do
    if fchInit then CreateStructItem(Component,PropertyType,Data.Strings[II],CreateAddr(II))
               else begin
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,CreateAddr(II));
      if Bufstr <> '' then Data.Strings[II] := Bufstr;
    end;
end;

procedure TLangManClient.ChangeStructStringsEx(Component: PTComponent; PropertyType: Word; Data: TStrings; fchInit: Boolean; PresetAddr: string);
var Bufstr: string;
    II: Integer;
begin
  if Data.Count > 0 then for II := 0 to Data.Count - 1 do
    if fchInit then CreateStructItem(Component,PropertyType,Data.Strings[II],NestedAddr(PresetAddr,II))
               else begin
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,NestedAddr(PresetAddr,II));
      if Bufstr <> '' then Data.Strings[II] := Bufstr;
    end;
end;

procedure TLangManClient.ChangeStructPanels(Component: PTComponent; PropertyType: Word; Data: PTStatusPanels; fchInit: Boolean);
var Bufstr, Addr: string;
    PI: Integer;
begin
  if Data^.Count > 0 then for PI := 0 to Data^.Count - 1 do begin
    Addr := CreateAddr(PI);
    if fchInit then CreateStructItem(Component,PropertyType,Data^.Items[PI].Text,NestedProperty(Addr,pnText))
               else begin
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,NestedProperty(Addr,pnText));
      if Bufstr <> '' then Data^.Items[PI].Text := Bufstr;
    end;
  end;
end;

procedure TLangManClient.ChangeStructBands(Component: PTComponent; PropertyType: Word; Data: PTCoolBands; fchInit: Boolean);
var Bufstr, Addr: string;
    CB: Integer;
begin
  if Data^.Count > 0 then for CB := 0 to Data^.Count - 1 do begin
    Addr := CreateAddr(CB);
    if fchInit then CreateStructItem(Component,PropertyType,Data^.Items[CB].Text,NestedProperty(Addr,pnText))
               else begin
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,NestedProperty(Addr,pnText));
      if Bufstr <> '' then Data^.Items[CB].Text := Bufstr;
    end;
  end;
end;


{$IF CompilerVersion > 19}
procedure TLangManClient.ChangeStructCategories(Component: PTComponent; PropertyType: Word; Data: PTButtonCategories; fchInit: Boolean);
var Bufstr, Addr, AddrS: string;
    CI,II: Integer;
begin
  if Data^.Count > 0 then for CI := 0 to Data^.Count - 1 do begin
    Addr := CreateAddr(CI);
//    if (pnCaption in fPropertiesOptions) then begin
      if fchInit then CreateStructItem(Component,PropertyType,Data^.Items[CI].Caption,NestedProperty(Addr,pnCaption))
                 else begin
        Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,NestedProperty(Addr,pnCaption));
        if Bufstr <> '' then Data^.Items[CI].Caption := Bufstr;
      end;
//    end;
    if Data^.Items[CI].Items.Count > 0 then for II := 0 to Data^.Items[CI].Items.Count - 1 do begin
      AddrS := NestedAddr(Addr,II);
      if fchInit then begin
        if NOT ((Data^.Items[CI].Items.Items[II].Action is TCustomAction) and
                ((Data^.Items[CI].Items.Items[II].Action as TCustomAction).Caption =
                 Data^.Items[CI].Items.Items[II].Caption))
          then CreateStructItem(Component,PropertyType,
                                Data^.Items[CI].Items.Items[II].Caption,
                                NestedProperty(AddrS,pnCaption))
      end else begin
        Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,
                             NestedProperty(AddrS,pnCaption));
        if Bufstr <> '' then Data^.Items[CI].Items.Items[II].Caption := Bufstr;
      end;
      if (pnHint in fTransStringProp) then begin
        if fchInit then begin
          if NOT ((Data^.Items[CI].Items.Items[II].Action is TCustomAction) and
                  ((Data^.Items[CI].Items.Items[II].Action as TCustomAction).Hint =
                   Data^.Items[CI].Items.Items[II].Hint))
            then CreateStructItem(Component,PropertyType,
                                  Data^.Items[CI].Items.Items[II].Hint,
                                  NestedProperty(AddrS,pnHint))
        end else begin
          Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,
                               NestedProperty(AddrS,pnHint));
          if Bufstr <> '' then Data^.Items[CI].Items.Items[II].Hint := Bufstr;
        end;
      end;
    end;
  end;
end;

procedure TLangManClient.ChangeStructButtonsGrp(Component: PTComponent; PropertyType: Word; Data: PTGrpButtonItems; fchInit: Boolean);
var Bufstr, Addr: string;
    BI: Integer;
begin
  if Data^.Count > 0 then for BI := 0 to Data^.Count - 1 do begin
    Addr := CreateAddr(BI);
    if fchInit then begin
      if NOT ((Data^.Items[BI].Action is TCustomAction) and
              ((Data^.Items[BI].Action as TCustomAction).Caption = Data^.Items[BI].Caption))
        then CreateStructItem(Component,PropertyType,
                              Data^.Items[BI].Caption,
                              NestedProperty(Addr,pnCaption))
    end else begin
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,
                           NestedProperty(Addr,pnCaption));
      if Bufstr <> '' then Data^.Items[BI].Caption := Bufstr;
    end;
    if (pnHint in fTransStringProp) then begin
      if fchInit then begin
        if NOT ((Data^.Items[BI].Action is TCustomAction) and
                ((Data^.Items[BI].Action as TCustomAction).Hint = Data^.Items[BI].Hint))
          then CreateStructItem(Component,PropertyType,
                                Data^.Items[BI].Hint,
                                NestedProperty(Addr,pnHint))
      end else begin
        Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,
                             NestedProperty(Addr,pnHint));
        if Bufstr <> '' then Data^.Items[BI].Hint := Bufstr;
      end;
    end;
  end;
end;
{$IFEND}

procedure TLangManClient.ChangeStructTreeNodes(Component: PTComponent; PropertyType: Word; Data: PTTreeNodes; fchInit: Boolean);
var TN, TNI: Integer;

  procedure TreeNode(NestedData: TTreeNode; Addr: string);
  var Bufstr: string;
      TNN: Integer;
  begin
    if fchInit then CreateStructItem(Component,PropertyType,NestedData.Text,Addr)
               else begin
      BufStr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,Addr);
      if BufStr <> '' then NestedData.Text := Bufstr;
    end;
    if NestedData.Count > 0
      then for TNN := 0 to NestedData.Count - 1 do TreeNode(NestedData.Item[TNN],NestedAddr(Addr,TNN));
  end;

begin
  TNI := 0;
  if Data^.Count > 0 then for TN := 0 to Data^.Count - 1 do begin
    if Data^.Item[TN].Level = 0 then begin
      TreeNode(Data^.Item[TN],CreateAddr(TNI));
      Inc(TNI);
    end;
  end;
end;

procedure TLangManClient.ChangeStructListColumns(Component: PTComponent; PropertyType: Word; Data: PTListColumns; fchInit: Boolean);
var Bufstr, Addr: string;
    CI: Integer;
begin
  if Data^.Count > 0 then for CI := 0 to Data^.Count - 1 do begin
    Addr := CreateAddr(CI);
    if fchInit then CreateStructItem(Component,PropertyType,
                                     Data^.Items[CI].Caption,
                                     NestedProperty(Addr,pnCaption))
               else begin
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,
                           NestedProperty(Addr,pnCaption));
      if Bufstr <> '' then Data^.Items[CI].Caption := Bufstr;
    end;
  end;
end;

{$IF CompilerVersion > 19}
procedure TLangManClient.ChangeStructListGroups(Component: PTComponent; PropertyType: Word; Data: PTListGroups; fchInit: Boolean);
var Bufstr, Addr: string;
    GI: Integer;
begin
  if Data^.Count > 0 then for GI := 0 to Data^.Count - 1 do begin
    Addr := CreateAddr(GI);
    if fchInit then begin
      CreateStructItem(Component,PropertyType,Data^.Items[GI].Header,NestedProperty(Addr,epnHeader));
      CreateStructItem(Component,PropertyType,Data^.Items[GI].Footer,NestedProperty(Addr,epnFooter));
      CreateStructItem(Component,PropertyType,Data^.Items[GI].Subtitle,NestedProperty(Addr,epnSubtitle));
  {$IF CompilerVersion < 22}
      CreateStructItem(Component,PropertyType,Data^.Items[GI].BottomDescription,NestedProperty(Addr,epnBottomDescription));
      CreateStructItem(Component,PropertyType,Data^.Items[GI].SubsetTitle,NestedProperty(Addr,epnSubsetTitle));
      CreateStructItem(Component,PropertyType,Data^.Items[GI].TopDescription,NestedProperty(Addr,epnTopDescription));
  {$IFEND}
    end else begin
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,NestedProperty(Addr,epnHeader));
      if Bufstr <> '' then Data^.Items[GI].Header := Bufstr;
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,NestedProperty(Addr,epnFooter));
      if Bufstr <> '' then Data^.Items[GI].Footer := Bufstr;
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,NestedProperty(Addr,epnSubtitle));
      if Bufstr <> '' then Data^.Items[GI].Subtitle := Bufstr;
  {$IF CompilerVersion < 22}
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,NestedProperty(Addr,epnBottomDescription));
      if Bufstr <> '' then Data^.Items[GI].BottomDescription := Bufstr;
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,NestedProperty(Addr,epnSubsetTitle));
      if Bufstr <> '' then Data^.Items[GI].SubsetTitle := Bufstr;
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,NestedProperty(Addr,epnTopDescription));
      if Bufstr <> '' then Data^.Items[GI].TopDescription := Bufstr;
  {$IFEND}
    end;
  end;
end;
{$IFEND}

procedure TLangManClient.ChangeStructListItems(Component: PTComponent; PropertyType: Word; Data: PTListItems; fchInit: Boolean);
var LI, SLI : Integer;
    BufStr, Addr: string;
begin
  if Data^.Count > 0 then for LI := 0 to Data^.Count - 1 do begin
    Addr := CreateAddr(LI);
    if fchInit then CreateStructItem(Component,PropertyType,Data^.Item[LI].Caption,NestedProperty(Addr,pnCaption))
               else begin
      BufStr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,NestedProperty(Addr,pnCaption));
      if BufStr <> '' then Data^.Item[LI].Caption := Bufstr;
    end;
    if Data^.Item[LI].SubItems.Count > 0
     then for SLI := 0 to Data^.Item[LI].SubItems.Count - 1 do begin
      if fchInit then CreateStructItem(Component,PropertyType,Data^.Item[LI].SubItems.Strings[SLI],NestedAddr(Addr,SLI))
                 else begin
        BufStr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,NestedAddr(Addr,SLI));
        if BufStr <> '' then Data^.Item[LI].SubItems.Strings[SLI] := Bufstr;
      end;
    end;
  end;
end;

procedure TLangManClient.ChangeStructHeaderSections(Component: PTComponent; PropertyType: Word; Data: PTHeaderSections; fchInit: Boolean);
var Bufstr, Addr: string;
    SI: Integer;
begin
  if Data^.Count > 0 then for SI := 0 to Data^.Count - 1 do begin
    Addr := CreateAddr(SI);
    if fchInit then CreateStructItem(Component,PropertyType,
                                     Data^.Items[SI].Text,
                                     NestedProperty(Addr,pnText))
               else begin
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,
                           NestedProperty(Addr,pnText));
      if Bufstr <> '' then Data^.Items[SI].Text := Bufstr;
    end;
  end;
end;

{$IFDEF DATABASES}
procedure TLangManClient.ChangeStructDBTitleCaptions(Component: PTComponent; PropertyType: Word; Data: PTDBGridColumns; fchInit: Boolean);
var Bufstr: string;
    TI: Integer;
begin
  if Data^.Count > 0 then for TI := 0 to Data^.Count - 1 do begin
    if fchInit then CreateStructItem(Component,PropertyType,Data^.Items[TI].Title.Caption,CreateAddr(TI))
               else begin
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,CreateAddr(TI));
      if Bufstr <> '' then Data^.Items[TI].Title.Caption := Bufstr;
    end;
  end;
end;

procedure TLangManClient.ChangeStructTableProducerColumns(Component: TComponent; PropertyType: Word; fchInit: Boolean);
var Cols: THTMLTableColumns;
    Bufstr: string;
    CI: Integer;
begin
  Cols := (Component as TDSTableProducer).Columns;
  if Cols.Count > 0 then for CI := 0 to Cols.Count - 1 do begin
    if fchInit then CreateStructItem(@Component,PropertyType,Cols.Items[CI].Title.Caption,NestedProperty(CreateAddr(CI),pnCaption))
               else begin
      Bufstr := StructItem(Component.Name,Component.Owner.Name,PropertyType,NestedProperty(CreateAddr(CI),pnCaption));
      if Bufstr <> '' then Cols.Items[CI].Title.Caption := Bufstr;
    end;
  end;
end;
{$ENDIF}
{$IFDEF WIN3_1}
procedure TLangManClient.ChangeStructOutlineItems(Component: PTComponent; PropertyType: Word; Outline: TCustomOutline; fchInit: Boolean);
var Bufstr: string;
    OI: Integer;
begin
  if Outline.ItemCount > 0 then for OI := 1 to Outline.ItemCount do begin
    if fchInit then CreateStructItem(Component,PropertyType,Outline.Items[OI].Text,CreateAddr(OI))
               else begin
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,CreateAddr(OI));
      if Bufstr <> '' then Outline.Items[OI].Text := Bufstr;
    end;
  end;
end;
{$ENDIF}

procedure TLangManClient.ChangeStructFileTypes(Component: PTComponent; PropertyType: Word; Data: PTFileTypeItems; fchInit: Boolean);
var Bufstr, Addr: String;
    FTI: Integer;
begin
  if Data^.Count > 0 then for FTI := 0 to Data^.Count - 1 do begin
    Addr := AsPropertyName('[' + Data^.Items[FTI].FileMask + ']');
    if Addr <> '' then begin
      if fchInit then CreateStructItem(Component, PropertyType, Data^.Items[FTI].DisplayName, Addr)
                 else begin
        Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,Addr);
        if Bufstr <> '' then Data^.Items[FTI].DisplayName := Bufstr;
      end;
    end;
  end;
end;

{$IF CompilerVersion > 17}
procedure TLangManClient.ChangeStructTaskDlgButtons(Component: PTComponent; PropertyType: Word; Data: PTTaskDialogButtons; fchInit: Boolean);
var Bufstr, Addr: String;
    BI: Integer;
begin
  if Data^.Count > 0 then for BI := 0 to Data^.Count - 1 do begin
    Addr := CreateAddr(BI);
    if fchInit then begin
      CreateStructItem(Component, PropertyType, Data^.Items[BI].Caption, NestedProperty(Addr, pnCaption));
      if Data^.Items[BI] is TTaskDialogButtonItem then CreateStructItem(Component, PropertyType, (Data^.Items[BI] as TTaskDialogButtonItem).CommandLinkHint, NestedProperty(Addr, epnCommandLinkHint));
    end else begin
      Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,NestedProperty(Addr, pnCaption));
      if Bufstr <> '' then Data^.Items[BI].Caption := Bufstr;
      if Data^.Items[BI] is TTaskDialogButtonItem then begin
        Bufstr := StructItem(Component^.Name,Component^.Owner.Name,PropertyType,NestedProperty(Addr, epnCommandLinkHint));
        if Bufstr <> '' then (Data^.Items[BI] as TTaskDialogButtonItem).CommandLinkHint := Bufstr;
      end;
    end;
  end;
end;
{$IFEND}

function TLangManClient.ChangeStructFilter(Component: PTComponent; PropertyType: Word; InitFilter: string; fchInit: Boolean): string;
var FilterBuf, FilterName, FilterMask, Addr: string;
    BarPos: Integer;
begin
  Result := '';
  FilterBuf := InitFilter;
  BarPos := AnsiPos('|', FilterBuf);
  while BarPos > 0 do begin
    FilterName := Copy(FilterBuf, 1, BarPos - 1);
    Delete(FilterBuf, 1, BarPos);
    BarPos := AnsiPos('|', FilterBuf);
    if BarPos > 0 then begin
      FilterMask := Copy(FilterBuf, 1, BarPos - 1);
      Delete(FilterBuf, 1, BarPos);
    end else begin
      FilterMask := FilterBuf;
      FilterBuf := '';
    end;
    BarPos := AnsiPos('|', FilterBuf);
    Addr := AsPropertyName('[' + FilterMask + ']');
    if Addr <> '' then begin
      if fchInit then CreateStructItem(Component, PropertyType, FilterName, Addr)
                 else begin
        Addr := StructItem(Component^.Name, Component^.Owner.Name, PropertyType, Addr);
        if Addr <> '' then begin
          if Result = '' then Result := Addr + '|' + FilterMask
                         else Result := Result + '|' + Addr + '|' + FilterMask;

        end else begin
          if Result = '' then Result := FilterName + '|' + FilterMask
                         else Result := Result + '|' + FilterName + '|' + FilterMask;
        end;
      end;
    end;
  end;
  if fchInit then Result := InitFilter;
end;

{$IFDEF RAVE}
procedure TLangManClient.ChangeStructRaveProject(Component: TComponent; PropertyType: Word; fchInit: Boolean);
var ProjMan: TRaveProjectManager;
    RegPages: TList;
    Report: TRaveReport;
    RI, PI: Integer;

  procedure TranslateRavePage(Page: TRavePage; RegName: string);
  var RaveText: TRaveText;
      RaveMemo: TRaveMemo;
      Addr, Bufstr, LinesIn, LinesOut, LineBuf: string;
      CI, LineIndex, EnterPos: Integer;
  begin
    if RegPages.IndexOf(Page) >= 0 then Exit
                                   else RegPages.Add(Page);
    for CI := 0 to Page.ComponentCount - 1 do begin
      if Page.Components[CI].ClassType = TRaveText then begin
        RaveText := Page.Components[CI] as TRaveText;
        Addr := RaveText.Name + ALTDOT + GetNameFromArrays(PropIndex(pnText));
        if fchInit then begin
          if ContainChars(RaveText.Text) and (RaveText.Text <> RaveText.Name) then begin
            with DesignStruct do begin
              Names.Add(RegName + TECKA + Page.Name);
              Parents.Add(Component.Owner.Name);
              Properties.AddWord(PropertyType);
              Text.Add(RaveText.Text);
              ItemAddr.Add(Addr);
              ChangeAble.AddWord(ca_YES);
            end;
          end;
        end else begin
          Bufstr := StructItem(RegName + TECKA + Page.Name,Component.Owner.Name,PropertyType,Addr);
          if Bufstr <> '' then RaveText.Text := Bufstr;
        end;
      end else if (Page.Components[CI].ClassType = TRaveMemo) and TransProp(pnLines) then begin
        RaveMemo := Page.Components[CI] as TRaveMemo;
        Addr := RaveMemo.Name + ALTDOT + GetNameFromArrays(PropIndex(pnLines));
        LinesIn := RaveMemo.Text;
        LineIndex := 0;
        LinesOut := '';
        repeat
          EnterPos := Pos(#13,LinesIn);
          if EnterPos > 0 then begin
            LineBuf := Copy(LinesIn,1,EnterPos-1);
            LinesIn := Copy(LinesIn, EnterPos + 2, Length(LinesIn) - (EnterPos + 1));
          end else LineBuf := LinesIn;
          if fchInit then begin
            if ContainChars(LineBuf) then with DesignStruct do begin
              Names.Add(RegName + TECKA + Page.Name);
              Parents.Add(Component.Owner.Name);
              Properties.AddWord(PropertyType);
              Text.Add(LineBuf);
              ItemAddr.Add(NestedAddr(Addr,LineIndex));
              Changeable.AddWord(ca_YES);
            end;
          end else begin
            Bufstr := StructItem(RegName + TECKA + Page.Name,Component.Owner.Name,PropertyType,NestedAddr(Addr,LineIndex));
            if Bufstr <> '' then LineBuf := Bufstr;
          end;
          if EnterPos > 0 then LinesOut := LinesOut + LineBuf + #13#10
                          else LinesOut := LinesOut + LineBuf;
          Inc(LineIndex);
        until EnterPos <= 0;
        RaveMemo.Text := LinesOut;
      end;
    end;
  end;

begin
  if (Component as TRVProject).StoreRAV or FileExists((Component as TRVProject).ProjectFile) then begin
    try
      (Component as TRVProject).Open;
    except
      Exit;
    end;
    if (Component as TRVProject).Active then begin
      RegPages := TList.Create;
      ProjMan := (Component as TRVProject).ProjMan;
      if ProjMan.GlobalPageList.Count > 0 then begin
        for PI := 0 to ProjMan.GlobalPageList.Count - 1 do begin
          TranslateRavePage(ProjMan.GlobalPageList.Items[PI],Component.Name);
        end;
      end;
      if ProjMan.ReportList.Count > 0 then for RI := 0 to ProjMan.ReportList.Count - 1 do begin
        Report := ProjMan.ReportList.Items[RI];
        if Report.LoadedPageCount > 0 then
          for PI := 0 to Report.LoadedPageCount - 1 do
            TranslateRavePage(Report.LoadedPage[PI],Component.Name + TECKA + Report.Name);
      end;
      RegPages.Free;
    end;
  end;
end;

procedure TLangManClient.ChangeStructRaveSystem(Component: TComponent; PropertyType: Word; fchInit: Boolean);
var RvSystem: TRvSystem;
begin
  RvSystem := Component as TRvSystem;
  RvSystem.SystemFiler.StatusFormat := ChangeStructItemEx(@Component,PropertyType,RvSystem.SystemFiler.StatusFormat,fchInit,'Filer' + ALTDOT + 'StatusFormat');
  ChangeStructStringsEx(@Component,PropertyType,RvSystem.SystemFiler.StatusText,fchInit,'Filer' + ALTDOT + 'StatusText');
  RvSystem.SystemPrinter.StatusFormat := ChangeStructItemEx(@Component,PropertyType,RvSystem.SystemPrinter.StatusFormat,fchInit,'Printer' + ALTDOT + 'StatusFormat');
  ChangeStructStringsEx(@Component,PropertyType,RvSystem.SystemPrinter.StatusText,fchInit,'Printer' + ALTDOT + 'StatusText');
  RvSystem.SystemPrinter.Title := ChangeStructItemEx(@Component,PropertyType,RvSystem.SystemPrinter.Title,fchInit,'Printer' + ALTDOT + 'Title');
  RvSystem.TitlePreview := ChangeStructItemEx(@Component,PropertyType,RvSystem.TitlePreview,fchInit,'TitlePreview');
  RvSystem.TitleSetup := ChangeStructItemEx(@Component,PropertyType,RvSystem.TitleSetup,fchInit,'TitleSetup');
  RvSystem.TitleStatus := ChangeStructItemEx(@Component,PropertyType,RvSystem.TitleStatus,fchInit,'TitleStatus');
end;
{$ENDIF}

{$IFDEF TEECHART}
procedure TLangManClient.ChangeStructCustomAxes(Component: PTComponent; PropertyType: Word; Data: PTCollection; fchInit: Boolean; PresetAddr: string);
var CAI: Integer;
    Bufstr: string;
begin
  if Data^.Count > 0 then for CAI := 0 to Data^.Count - 1 do begin
    if fchInit then CreateStructItem(Component, PropertyType, (Data^.Items[CAI] as TChartAxis).Title.Caption, NestedAddr(PresetAddr,CAI))
               else begin
      Bufstr := StructItem(Component^.Name, Component^.Owner.Name, PropertyType, NestedAddr(PresetAddr,CAI));
      if Bufstr <> '' then (Data^.Items[CAI] as TChartAxis).Title.Caption := Bufstr;
    end;
  end;
end;
{$ENDIF}

//*****************************************************************************
//******** Component autotranslation procedure begin **************************

procedure TLangManClient.ChangeStrings(Component: TComponent; fchInit: boolean);
var ActionString: string;
begin
  //trans
  if Component.Name <> '' then try
    //********************************************************************
    //*** String Properties **********************************************
    //********************************************************************

    ActionString := '';
    if (Component is TControl) and ((Component as TControl).Action is TCustomAction) then ActionString := ((Component as TControl).Action as TCustomAction).Caption;

    // Caption group
    if TransProp(pnCaption) then begin

      if TransComp(Component, TMenuItem) then begin
        if ((Component as TMenuItem).Action is TCustomAction) then ActionString := ((Component as TMenuItem).Action as TCustomAction).Caption;
       (Component as TMenuItem).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TMenuItem).Caption,fchInit,ActionString);
      end else

       if TransComp(Component, TCustomLabel) then begin
         (Component as TCustomLabel).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TCustomLabel).Caption,fchInit,ActionString);
       end else

        if TransComp(Component, TButton) then begin
         (Component as TButton).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TButton).Caption,fchInit,ActionString);
        end else

         if TransComp(Component, TBitBtn) then begin
           (Component as TBitBtn).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TBitBtn).Caption,fchInit,ActionString);
         end else

          if TransComp(Component, TSpeedButton) then begin
            (Component as TSpeedButton).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TSpeedButton).Caption,fchInit,ActionString);
          end else

           if TransComp(Component, TStaticText) then begin
             (Component as TStaticText).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TStaticText).Caption,fchInit,ActionString);
           end else

            if TransComp(Component, TCheckBox) then begin
              (Component as TCheckBox).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TCheckBox).Caption,fchInit,ActionString);
            end else

             if TransComp(Component, TRadioButton) then begin
               (Component as TRadioButton).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TRadioButton).Caption,fchInit,ActionString);
             end else

              if TransComp(Component, TGroupBox) then begin
                (Component as TGroupBox).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TGroupBox).Caption,fchInit,ActionString);
              end else

               if TransComp(Component, TRadioGroup) then begin
                 (Component as TRadioGroup).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TRadioGroup).Caption,fchInit,ActionString);
               end else

                if TransComp(Component, TPanel) then begin
                  (Component as TPanel).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TPanel).Caption,fchInit,ActionString);
                end else

                 if TransComp(Component, TCustomAction) then begin
                   (Component as TCustomAction).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TCustomAction).Caption,fchInit);
                 end else

{$IF CompilerVersion > 19}
                  if TransComp(Component, TFlowPanel) then begin
                    (Component as TFlowPanel).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TFlowPanel).Caption,fchInit,ActionString);
                  end else

                   if TransComp(Component, TGridPanel) then begin
                     (Component as TGridPanel).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TGridPanel).Caption,fchInit,ActionString);
                   end else

                    if TransComp(Component, TCategoryPanel) then begin
                      (Component as TCategoryPanel).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TCategoryPanel).Caption,fchInit,ActionString);
                    end else
{$IFEND}

                     if TransComp(Component, TTabSheet) then begin
                       (Component as TTabSheet).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TTabSheet).Caption,fchInit,ActionString);
                     end else

                      if TransComp(Component, TToolButton) then begin
                        (Component as TToolButton).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TToolButton).Caption,fchInit,ActionString);
                      end else

                     {$IFDEF DATABASES}
                       if TransComp(Component, TDBCheckBox) then begin
                         (Component as TDBCheckBox).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TDBCheckBox).Caption,fchInit,ActionString);
                       end else
                     {$ENDIF}

                         if TransComp(Component, TCustomForm) then begin
                           (Component as TCustomForm).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TCustomForm).Caption,fchInit,ActionString);
                         end;

    end;

    // EditLabel .Caption, .Hint
{$IF CompilerVersion > 19}
    if TransComp(Component, TCustomLabeledEdit) then begin
      if TransProp(pnEditLabelCaption) then
        (Component as TCustomLabeledEdit).EditLabel.Caption := ChangeStructItem(@Component,PropIndex(pnEditLabelCaption),(Component as TCustomLabeledEdit).EditLabel.Caption,fchInit,ActionString);
      if TransProp(pnEditLabelHint) then
        (Component as TCustomLabeledEdit).EditLabel.Hint := ChangeStructItem(@Component,PropIndex(pnEditLabelHint),(Component as TCustomLabeledEdit).EditLabel.Hint,fchInit);
    end;
{$IFEND}

    // Hint group
    if TransProp(pnHint) then begin

      if TransComp(Component, TControl) then begin
        if ((Component as TControl).Action is TCustomAction) then ActionString := ((Component as TControl).Action as TCustomAction).Hint;
        (Component as TControl).Hint := ChangeStructItem(@Component,PropIndex(pnHint),(Component as TControl).Hint,fchInit,ActionString);
      end else

       if TransComp(Component, TMenuItem) then begin
         if ((Component as TMenuItem).Action is TCustomAction) then ActionString := ((Component as TMenuItem).Action as TCustomAction).Hint;
         (Component as TMenuItem).Hint := ChangeStructItem(@Component,PropIndex(pnHint),(Component as TMenuItem).Hint,fchInit,ActionString);
       end else

        if TransComp(Component, TCustomAction) then begin
          (Component as TCustomAction).Hint := ChangeStructItem(@Component,PropIndex(pnHint),(Component as TCustomAction).Hint,fchInit);
        end;

    end;

{$IF CompilerVersion > 19}
    // TCustomEdit.TextHint
    if TransCompProp(Component, TCustomEdit, pnTextHint) then begin
      (Component as TCustomEdit).TextHint := ChangeStructItem(@Component,PropIndex(pnTextHint),(Component as TCustomEdit).TextHint,fchInit);
    end;
{$IFEND}

    // HelpKeyword
    if TransCompProp(Component, TControl, pnHelpKeyword) then begin
      if ((Component as TControl).Action is TCustomAction) then ActionString := ((Component as TControl).Action as TCustomAction).HelpKeyword;
      (Component as TControl).HelpKeyword := ChangeStructItem(@Component,PropIndex(pnHelpKeyword),(Component as TControl).HelpKeyword,fchInit,ActionString);
    end else

      if TransCompProp(Component, TCustomAction, pnHelpKeyword) then begin
        (Component as TCustomAction).HelpKeyword := ChangeStructItem(@Component,PropIndex(pnHelpKeyword),(Component as TCustomAction).HelpKeyword,fchInit);
      end;

    // Text group
    if TransProp(pnText) then begin

      if TransComp(Component, TCustomEdit) then begin
        (Component as TCustomEdit).Text := ChangeStructItem(@Component,PropIndex(pnText),(Component as TCustomEdit).Text,fchInit,ActionString);
      end else

       if TransComp(Component, TComboBox) then begin
         (Component as TComboBox).Text := ChangeStructItem(@Component,PropIndex(pnText),(Component as TComboBox).Text,fchInit,ActionString);
       end else

        if TransComp(Component, TComboBoxEx) then begin
          (Component as TComboBoxEx).Text := ChangeStructItem(@Component,PropIndex(pnText),(Component as TComboBoxEx).Text,fchInit,ActionString);
        end;

    end;

    // TOpenDialog.Title and Title of dilog actions: TFileOpen.Dialog, TFileSaveAs.Dialog, TFileRun.Dialog, TOpenPicture.Dilog, TSavePicture.Dialog
    if TransProp(pnTitle) then begin
      if TransComp(Component, TOpenDialog) then begin
        (Component as TOpenDialog).Title := ChangeStructItem(@Component,PropIndex(pnTitle),(Component as TOpenDialog).Title,fchInit);
      end else

       if TransComp(Component, TFileOpen) then begin
         (Component as TFileOpen).Dialog.Title := ChangeStructItem(@Component,PropIndex(pnTitle),(Component as TFileOpen).Dialog.Title,fchInit);
       end else

        if TransComp(Component, TFileSaveAs) then begin
          (Component as TFileSaveAs).Dialog.Title := ChangeStructItem(@Component,PropIndex(pnTitle),(Component as TFileSaveAs).Dialog.Title,fchInit);
        end else

         if TransComp(Component, TFileRun) then begin
           (Component as TFileRun).BrowseDlg.Title := ChangeStructItem(@Component,PropIndex(pnTitle),(Component as TFileRun).BrowseDlg.Title,fchInit);
         end else

          if TransComp(Component, TOpenPicture) then begin
            (Component as TOpenPicture).Dialog.Title := ChangeStructItem(@Component,PropIndex(pnTitle),(Component as TOpenPicture).Dialog.Title,fchInit);
          end else

           if TransComp(Component, TSavePicture) then begin
             (Component as TSavePicture).Dialog.Title := ChangeStructItem(@Component,PropIndex(pnTitle),(Component as TSavePicture).Dialog.Title,fchInit);
           end;
    end;

    // TBrowseForFolder.DialogCaption
    if TransCompProp(Component, TBrowseForFolder, pnDialogCaption) then begin
      (Component as TBrowseForFolder).DialogCaption := ChangeStructItem(@Component,PropIndex(pnDialogCaption),(Component as TBrowseForFolder).DialogCaption,fchInit);
    end;

    // TValuedLabel.ValueName
    if TransCompProp(Component, TValuedLabel, pnValueName) then begin
      (Component as TValuedLabel).ValueName := ChangeStructItem(@Component,PropIndex(pnValueName),(Component as TValuedLabel).ValueName,fchInit,ActionString);
    end;

    // TCustomStatusBar.SimpleText
    if TransCompProp(Component, TCustomStatusBar, pnSimpleText) then begin
      (Component as TCustomStatusBar).SimpleText := ChangeStructItem(@Component,PropIndex(pnSimpleText),(Component as TCustomStatusBar).SimpleText,fchInit,ActionString);
    end;

    //********************************************************************
    //*** TStrings properties ********************************************
    //********************************************************************

    // TCustomMemo.Lines
    if TransCompProp(Component, TCustomMemo, pnLines) then begin
      ChangeStructStrings(@Component,PropIndex(pnLines),(Component as TCustomMemo).Lines,fchInit);
    end;

    // Items group
    if TransProp(pnItems) then begin

      if TransComp(Component, TCustomListBox) then begin
        ChangeStructStrings(@Component,PropIndex(pnItems),(Component as TCustomListBox).Items,fchInit);
      end else

       if TransComp(Component, TCustomCombo) then begin
         ChangeStructStrings(@Component,PropIndex(pnItems),(Component as TCustomCombo).Items,fchInit);
       end else

        if TransComp(Component, TRadioGroup) then begin
          ChangeStructStrings(@Component,PropIndex(pnItems),(Component as TRadioGroup).Items,fchInit);
        end
         {$IFDEF DATABASES}
         else if TransComp(Component, TDBRadioGroup) then begin
           ChangeStructStrings(@Component,PropIndex(pnItems),(Component as TDBRadioGroup).Items,fchInit);
         end
         {$ENDIF}
         ;

    end;

    // TitleCaptions (TValueListEditor)
    if TransCompProp(Component, TValueListEditor, pnTitleCaptions) then begin
      ChangeStructStrings(@Component,PropIndex(pnTitleCaptions),(Component as TValueListEditor).TitleCaptions,fchInit);
      (Component as TValueListEditor).Invalidate;
    end;

    // Tabs group
    if TransProp(pnTabs) then begin

      if TransComp(Component, TTabSet) then begin
        ChangeStructStrings(@Component,PropIndex(pnTabs),(Component as TTabSet).Tabs,fchInit);
      end else

       if TransComp(Component, TTabControl) then begin
         ChangeStructStrings(@Component,PropIndex(pnTabs),(Component as TTabControl).Tabs,fchInit);
       end;

    end;

    // Pages group
    if TransProp(pnPages) then begin
     {$IFDEF WIN3_1}
      if TransComp(Component, TTabbedNotebook) then begin
        ChangeStructStrings(@Component,PropIndex(pnPages),(Component as TTabbedNotebook).Pages,fchInit);
      end else
     {$ENDIF}

       if TransComp(Component, TNotebook) then begin
         ChangeStructStrings(@Component,PropIndex(pnPages),(Component as TNotebook).Pages,fchInit);
       end;

    end;

    // THeader.Sections
    if TransCompProp(Component, THeader, pnSections) then begin
      ChangeStructStrings(@Component,PropIndex(pnSections),(Component as THeader).Sections,fchInit);
    end;

    //********************************************************************
    //*** Structured properties ******************************************
    //********************************************************************

    // Panels (TStatusPanels)
    if TransCompProp(Component, TCustomStatusBar, pnPanels) then begin
      ChangeStructPanels(@Component,PropIndex(pnPanels),@(Component as TCustomStatusBar).Panels,fchInit);
    end;

    // Bands (TCoolBar)
    if TransCompProp(Component, TCoolBar, pnBands) then begin
      ChangeStructBands(@Component,PropIndex(pnBands),@(Component as TCoolBar).Bands,fchInit);
    end;

{$IF CompilerVersion > 19}
    // Categories (TButtonCategories)
    if TransCompProp(Component, TCategoryButtons, pnButtonCategories) then begin
      ChangeStructCategories(@Component,PropIndex(pnButtonCategories),@(Component as TCategoryButtons).Categories,fchInit);
    end;

    // Items (TGrpButtonItems)
    if TransCompProp(Component, TButtonGroup, pnGrpButtonItems) then begin
      ChangeStructButtonsGrp(@Component,PropIndex(pnGrpButtonItems),@(Component as TButtonGroup).Items,fchInit);
    end;
{$IFEND}

    // Items (TTreeView)
    if TransCompProp(Component, TTreeView, pnTreeItems) then begin
      ChangeStructTreeNodes(@Component,PropIndex(pnTreeItems),@(Component as TTreeView).Items,fchInit);
    end;

    // TListView .Columns, .Groups
    if TransComp(Component, TListView) then begin
      if TransProp(pnListColumns) then
        ChangeStructListColumns(@Component,PropIndex(pnListColumns),@(Component as TListView).Columns,fchInit);
  {$IF CompilerVersion > 19}
      if TransProp(pnListGroups) then
        ChangeStructListGroups(@Component,PropIndex(pnListGroups),@(Component as TListView).Groups,fchInit);
  {$IFEND}
    end;

  {$IF CompilerVersion > 19}
    // Items (TCustomListView)
    if TransCompProp(Component, TCustomListView, pnListItems) then begin
      ChangeStructListItems(@Component,PropIndex(pnListItems),@(Component as TCustomListView).Items,fchInit);
    end;
  {$ELSE}
    // Items (TListView)
    if TransCompProp(Component, TListView, pnListItems) then begin
      ChangeStructListItems(@Component,PropIndex(pnListItems),@(Component as TListView).Items,fchInit);
    end;
  {$IFEND}

    // Sections (THeaderSections)
    if TransCompProp(Component, TCustomHeaderControl, pnHeaderSections) then begin
      ChangeStructHeaderSections(@Component,PropIndex(pnHeaderSections),@(Component as TCustomHeaderControl).Sections,fchInit);
    end;

  {$IFDEF DATABASES}
    // Columns (TDBGridColumns)
    if TransCompProp(Component, TDBGrid, pnDBGridTitleCaptions) then begin
      ChangeStructDBTitleCaptions(@Component,PropIndex(pnDBGridTitleCaptions),@(Component as TDBGrid).Columns,fchInit);
    end;
  {$ENDIF}
  {$IFDEF WIN3_1}
    // Lines (TOutline)
    if TransCompProp(Component, TCustomOutline, pnOutlineItems) then begin
      ChangeStructOutlineItems(@Component,PropIndex(pnOutlineItems),Component as TCustomOutline,fchInit);
    end;
  {$ENDIF}

    //********************************************************************
    //*** Other properties ***********************************************
    //********************************************************************

    // Filter group
    if TransProp(pnFilter) then begin

      if TransComp(Component, TFilterComboBox) then begin
        (Component as TFilterComboBox).Filter := ChangeStructFilter(@Component,PropIndex(pnFilter),(Component as TFilterComboBox).Filter,fchInit);
      end else

       if TransComp(Component, TOpenDialog) then begin
         (Component as TOpenDialog).Filter := ChangeStructFilter(@Component,PropIndex(pnFilter),(Component as TOpenDialog).Filter,fchInit);
       end else

        if TransComp(Component, TFileOpen) then begin
          (Component as TFileOpen).Dialog.Filter := ChangeStructFilter(@Component, PropIndex(pnFilter), (Component as TFileOpen).Dialog.Filter,fchInit);
        end else

         if TransComp(Component, TFileSaveAs) then begin
           (Component as TFileSaveAs).Dialog.Filter := ChangeStructFilter(@Component, PropIndex(pnFilter), (Component as TFileSaveAs).Dialog.Filter,fchInit);
         end else

          if TransComp(Component, TFileRun) then begin
            (Component as TFileRun).BrowseDlg.Filter := ChangeStructFilter(@Component, PropIndex(pnFilter), (Component as TFileRun).BrowseDlg.Filter,fchInit);
          end else

           if TransComp(Component, TOpenPicture) then begin
             (Component as TOpenPicture).Dialog.Filter := ChangeStructFilter(@Component, PropIndex(pnFilter), (Component as TOpenPicture).Dialog.Filter,fchInit);
           end else

            if TransComp(Component, TSavePicture) then begin
              (Component as TSavePicture).Dialog.Filter := ChangeStructFilter(@Component, PropIndex(pnFilter), (Component as TSavePicture).Dialog.Filter,fchInit);
            end;
    end;

  {$IFDEF RAVE}  // All from Rave >ALL
    // TRVProject
    if TransCompProp(Component, TRvProject, cnRvProject) then begin
      ChangeStructRaveProject(Component,PropIndex(cnRvProject),fchInit);
    end;
    // TRvSystem
    if TransCompProp(Component, TRvSystem, cnRvSystem) then begin
      ChangeStructRaveSystem(Component,PropIndex(cnRvSystem),fchInit);
    end;
    // TRvNDRWriter
    if TransCompProp(Component, TRvNDRWriter, cnRvSystem) then begin
      (Component as TRvNDRWriter).StatusFormat := ChangeStructItemEx(@Component,PropIndex(cnRvSystem),(Component as TRvNDRWriter).StatusFormat,fchInit,'StatusFormat');
      ChangeStructStringsEx(@Component,PropIndex(cnRvSystem),(Component as TRvNDRWriter).StatusText,fchInit,'StatusText');
      (Component as TRvNDRWriter).Title := ChangeStructItemEx(@Component,PropIndex(cnRvSystem),(Component as TRvNDRWriter).Title,fchInit,'Title');
    end;
    // TRpRender
    if TransCompProp(Component, TRpRender, cnRvRender) then begin
      (Component as TRpRender).DisplayName := ChangeStructItem(@Component,PropIndex(cnRvRender),(Component as TRpRender).DisplayName,fchInit);
    end;
    // TRvRenderPDF
    if TransCompProp(Component, TRvRenderPDF, pnPDF_DocInfo) then begin
      (Component as TRvRenderPDF).DocInfo.Author := ChangeStructItemEx(@Component,PropIndex(pnPDF_DocInfo),(Component as TRvRenderPDF).DocInfo.Author,fchInit,NestedProperty('',epnAuthor));
      (Component as TRvRenderPDF).DocInfo.Creator := ChangeStructItemEx(@Component,PropIndex(pnPDF_DocInfo),(Component as TRvRenderPDF).DocInfo.Creator,fchInit,NestedProperty('',epnCreator));
      (Component as TRvRenderPDF).DocInfo.KeyWords := ChangeStructItemEx(@Component,PropIndex(pnPDF_DocInfo),(Component as TRvRenderPDF).DocInfo.KeyWords,fchInit,NestedProperty('',epnKeyWords));
      (Component as TRvRenderPDF).DocInfo.Producer := ChangeStructItemEx(@Component,PropIndex(pnPDF_DocInfo),(Component as TRvRenderPDF).DocInfo.Producer,fchInit,NestedProperty('',epnProducer));
      (Component as TRvRenderPDF).DocInfo.Subject := ChangeStructItemEx(@Component,PropIndex(pnPDF_DocInfo),(Component as TRvRenderPDF).DocInfo.Subject,fchInit,NestedProperty('',epnSubject));
      (Component as TRvRenderPDF).DocInfo.Title := ChangeStructItemEx(@Component,PropIndex(pnPDF_DocInfo),(Component as TRvRenderPDF).DocInfo.Title,fchInit,NestedProperty('',pnTitle));
    end;
  {$ENDIF}

  {$IFDEF TEECHART}
    // TCustomChart >ALL
    if TransCompProp(Component, TCustomChart, cnTChart) then begin
      ChangeStructStringsEx(@Component,PropIndex(cnTChart),(Component as TCustomChart).Title.Text,fchInit,'Title' + ALTDOT + 'Text');
      ChangeStructStringsEx(@Component,PropIndex(cnTChart),(Component as TCustomChart).SubTitle.Text,fchInit,'SubTitle' + ALTDOT + 'Text');
      ChangeStructStringsEx(@Component,PropIndex(cnTChart),(Component as TCustomChart).Foot.Text,fchInit,'Foot' + ALTDOT + 'Text');
      ChangeStructStringsEx(@Component,PropIndex(cnTChart),(Component as TCustomChart).SubFoot.Text,fchInit,'SubFoot' + ALTDOT + 'Text');
      (Component as TCustomChart).BottomAxis.Title.Caption := ChangeStructItemEx(@Component,PropIndex(cnTChart),(Component as TCustomChart).BottomAxis.Title.Caption,fchInit,'BottomAxis');
      (Component as TCustomChart).LeftAxis.Title.Caption := ChangeStructItemEx(@Component,PropIndex(cnTChart),(Component as TCustomChart).LeftAxis.Title.Caption,fchInit,'LeftAxis');
      (Component as TCustomChart).TopAxis.Title.Caption := ChangeStructItemEx(@Component,PropIndex(cnTChart),(Component as TCustomChart).TopAxis.Title.Caption,fchInit,'TopAxis');
      (Component as TCustomChart).RightAxis.Title.Caption := ChangeStructItemEx(@Component,PropIndex(cnTChart),(Component as TCustomChart).RightAxis.Title.Caption,fchInit,'RightAxis');
      (Component as TCustomChart).DepthAxis.Title.Caption := ChangeStructItemEx(@Component,PropIndex(cnTChart),(Component as TCustomChart).DepthAxis.Title.Caption,fchInit,'DepthAxis');
      (Component as TCustomChart).DepthTopAxis.Title.Caption := ChangeStructItemEx(@Component,PropIndex(cnTChart),(Component as TCustomChart).DepthTopAxis.Title.Caption,fchInit,'DepthTopAxis');
      ChangeStructCustomAxes(@Component, PropIndex(cnTChart), @(Component as TCustomChart).CustomAxes, fchInit, 'CustomAxes');
      ChangeStructStringsEx(@Component,PropIndex(cnTChart),(Component as TCustomChart).Legend.Title.Text,fchInit,'Legend' + ALTDOT + 'Title');
    end;
  {$ENDIF}

    //********************************************************************
    //*** Mix property types - Complete components ***********************
    //********************************************************************

{$IF CompilerVersion > 19}
    // TCustomTrayIcon .Hint, .BalloonHint, .BalloonTitle >ALL
    if TransComp(Component, TCustomTrayIcon) then begin
      if TransProp(pnHint) then
        (Component as TCustomTrayIcon).Hint := ChangeStructItem(@Component,PropIndex(pnHint),(Component as TCustomTrayIcon).Hint,fchInit);
      if TransProp(pnBalloonHint) then
        (Component as TCustomTrayIcon).BalloonHint := ChangeStructItem(@Component,PropIndex(pnBalloonHint),(Component as TCustomTrayIcon).BalloonHint,fchInit);
      if TransProp(pnBalloonTitle) then
        (Component as TCustomTrayIcon).BalloonTitle := ChangeStructItem(@Component,PropIndex(pnBalloonTitle),(Component as TCustomTrayIcon).BalloonTitle,fchInit);
    end;
{$IFEND}

  {$IFDEF DATABASES}
    // TDSTableProducer .Caption, .Header, .Footer, .Columns >ALL
    if TransComp(Component, TDSTableProducer) then begin
      if TransProp(pnCaption) then
        (Component as TDSTableProducer).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TDSTableProducer).Caption,fchInit);
      if TransProp(pnHeader) then
        ChangeStructStrings(@Component,PropIndex(pnHeader),(Component as TDSTableProducer).Header,fchInit);
      if TransProp(pnFooter) then
        ChangeStructStrings(@Component,PropIndex(pnFooter),(Component as TDSTableProducer).Footer,fchInit);
      if TransProp(pnTabProducerColumns) then
        ChangeStructTableProducerColumns(Component,PropIndex(pnTabProducerColumns),fchInit);
    end;
  {$ENDIF}

    // TCustomFileDialog .FileNameLabel, .OKButtonLabel, .FileTypes >ALL
    if TransComp(Component, TCustomFileDialog) then begin
      if TransProp(pnFileNameLabel) then
        (Component as TCustomFileDialog).FileNameLabel := ChangeStructItem(@Component,PropIndex(pnFileNameLabel),(Component as TCustomFileDialog).FileNameLabel,fchInit);
      if TransProp(pnOkButtonLabel) then
        (Component as TCustomFileDialog).OkButtonLabel := ChangeStructItem(@Component,PropIndex(pnOkButtonLabel),(Component as TCustomFileDialog).OkButtonLabel,fchInit);
      if TransProp(pnTitle) then
        (Component as TCustomFileDialog).Title := ChangeStructItem(@Component,PropIndex(pnTitle),(Component as TCustomFileDialog).Title,fchInit);
      if TransProp(pnFileTypes) then
        ChangeStructFileTypes(@Component,PropIndex(pnFileTypes),@(Component as TCustomFileDialog).FileTypes,fchInit);
    end;

{$IF CompilerVersion > 17}
    // TCustomTaskDialog .Buttons, .Caption, .ExpandButtonCaption, .ExpandedText,
    //                   .FooterText, .RadioButtons, .Text, .Title, .VerificationText >ALL
    if TransComp(Component, TCustomTaskDialog) then begin
      if TransProp(pnButtons) then
        ChangeStructTaskDlgButtons(@Component,PropIndex(pnButtons),@(Component as TCustomTaskDialog).Buttons,fchInit);
      if TransProp(pnCaption) then
        (Component as TCustomTaskDialog).Caption := ChangeStructItem(@Component,PropIndex(pnCaption),(Component as TCustomTaskDialog).Caption,fchInit);
      if TransProp(pnExpandButtonCaption) then
        (Component as TCustomTaskDialog).ExpandButtonCaption := ChangeStructItem(@Component,PropIndex(pnExpandButtonCaption),(Component as TCustomTaskDialog).ExpandButtonCaption,fchInit);
      if TransProp(pnExpandedText) then
        (Component as TCustomTaskDialog).ExpandedText := ChangeStructItem(@Component,PropIndex(pnExpandedText),(Component as TCustomTaskDialog).ExpandedText,fchInit);
      if TransProp(pnFooterText) then
        (Component as TCustomTaskDialog).FooterText := ChangeStructItem(@Component,PropIndex(pnFooterText),(Component as TCustomTaskDialog).FooterText,fchInit);
      if TransProp(pnRadioButtons) then
        ChangeStructTaskDlgButtons(@Component,PropIndex(pnRadioButtons),@(Component as TCustomTaskDialog).RadioButtons,fchInit);
      if TransProp(pnText) then
        (Component as TCustomTaskDialog).Text := ChangeStructItem(@Component,PropIndex(pnText),(Component as TCustomTaskDialog).Text,fchInit);
      if TransProp(pnTitle) then
        (Component as TCustomTaskDialog).Title := ChangeStructItem(@Component,PropIndex(pnTitle),(Component as TCustomTaskDialog).Title,fchInit);
      if TransProp(pnVerificationText) then
        (Component as TCustomTaskDialog).VerificationText := ChangeStructItem(@Component,PropIndex(pnVerificationText),(Component as TCustomTaskDialog).VerificationText,fchInit);
    end;
{$IFEND}

  except
    //exception ignored
  end;
end;

//******** Component autotranslation procedure end ****************************
//*****************************************************************************

procedure TLangManClient.InitForm(AOwner: TObject);
begin
  if fAfterCreate and Assigned(OwnerOnCreate) then OwnerOnCreate(Self);
  ControlChanges(true);
  if (NOT fAfterCreate) and Assigned(OwnerOnCreate) then OwnerOnCreate(Self);
  if (fLangManEngine <> nil) then begin
    if (fLangManEngine.IsInitialized) and // if form is created dynamically
       (fLangManEngine.CurrentLanguage <> fLangManEngine.DesignLanguageName)
      then ChangeLanguage(Self);
  end;
end;

procedure TLangManClient.ControlChanges(fchInit: boolean);
var IComponent: integer;
begin
  if ParentControl is TForm then ChangeStrings(ParentControl, fchInit);
  if ParentControl.ComponentCount > 0 then begin
    ActiveClient := Self;
    for IComponent := 0 to ParentControl.ComponentCount - 1 do begin
      ChangeStrings(ParentControl.Components[IComponent],fchInit);
      if fchinit then RegisterAdditions(ParentControl.Components[IComponent])
                 else TranslateAdditions(ParentControl.Components[IComponent]);
    end;
  end;
end;

procedure TLangManClient.ChangeLanguage(AOwner: TObject);
begin
  ControlChanges(false);
  inherited ChangeLanguage(AOwner);
end;

constructor TLangManClient.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  DesignStruct := TComponentStructure.Create;
  if (NOT DesignTime) and (AOwner is TComponent) then begin
    ParentControl := TComponent(AOwner);
    if ParentControl is TForm then begin
      OwnerOnCreate := (ParentControl as TForm).OnCreate;
      (ParentControl as TForm).OnCreate := InitForm;
    end else begin
      if ParentControl is TDataModule then begin
        OwnerOnCreate := (ParentControl as TDataModule).OnCreate;
        (ParentControl as TDataModule).OnCreate := InitForm;
      end else ControlChanges(true);
    end;
  end;
  SetTransStringProp(TranslateStringPropertiesDefault);
  SetTransTStringsProp(TranslateTStringsPropertiesDefault);
  SetTransStructuredProp(TranslateStructuredPropertiesDefault);
  SetTransOtherProp(TranslateOtherPropertiesDefault);
  SetTransAdditions(DefaultEnabled);
end;

destructor TLangManClient.Destroy;
begin
  DesignStruct.Free;
  inherited Destroy;
end;

function TLangManClient.AddComponent(Component: TComponent; Name: string; Translate: boolean): Boolean;
begin
  if Component.Owner = ParentControl then begin
    if Name <> '' then Component.Name := Name;
    ActiveClient := Self;
    ChangeStrings(Component, true);
    RegisterAdditions(Component);
    if Translate then begin
      ChangeStrings(Component, false);
      TranslateAdditions(Component);
    end;
    Result := true;
  end else Result := false;
end;

procedure TLangManClient.RecreateTransStruct;
begin
  DesignStruct.Clear;
  ControlChanges(true);
end;

procedure TLangManClient.TranslateComponent(Component: TComponent; Name: string = '');
begin
  if (Name <> '') then Component.Name := Name;
  if Component.Owner <> nil then begin
    ChangeStrings(Component, false);
    TranslateAdditions(Component);
  end;
end;

procedure TLangManClient.Translate;
begin
  ChangeLanguage(Self);
end;

//***************************************************************************
//**  LangMan Lexicon methods                                              **
//***************************************************************************

constructor TLexicon.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Slaves := TObjectList.Create;
  Slaves.OwnsObjects := false;
end;

destructor TLexicon.Destroy;
begin
  Slaves.Free;
  inherited Destroy;
end;

procedure TLexicon.ChangeLanguage(AOwner: TObject);
var SlaveIndex: Integer;
begin
  if Slaves.Count > 0 then for SlaveIndex := 0 to Slaves.Count - 1 do begin
    if Slaves.Items[SlaveIndex] is TLangManStrings then
      (Slaves.Items[SlaveIndex] as TLangManStrings).Translate
                                                   else begin
      if Slaves.Items[SlaveIndex] is TLangManRichEdit then
        (Slaves.Items[SlaveIndex] as TLangManRichEdit).Translate;
    end;
  end;
  inherited ChangeLanguage(AOwner);
end;

function TLexicon.GetLink(Index: Integer): string;
begin
  Result := LINK_IDENT + NR_IDENT + IntToStr(Index) + STREDNIK;
end;

function TLexicon.CompleteString(const Str: string): string;
var Index, SLength, ItemNr, LinkLength: Integer;
begin
  Result := '';
  SLength := Length(Str);
  if SLength > 0 then begin
    Index := 0;
    repeat
      Inc(Index);
      if (Str[Index] = LINK_IDENT) and  ((Index+2) < SLength) and
         (Str[Index+1] = NR_IDENT) then begin
        Inc(Index,2);
        ItemNr := 0;
        LinkLength := 3;
        repeat
          if ((Ord(Str[Index]) >= Ord('0')) and (Ord(Str[Index]) <= Ord('9'))) then begin
            ItemNr := (ItemNr * 10) + (Ord(Str[Index]) - Ord('0'));
            Inc(LinkLength);
          end else begin
            Index := Index + 2 - LinkLength;
            Result := Result + LINK_IDENT;
            LinkLength := -1;
            Break;
          end;
          Inc(Index);
        until Str[Index] = STREDNIK;
        if LinkLength > 0 then begin
          if (ItemNr > MaxIndex) or (NOT IsDefined(ItemNr))
            then Result := Result + BAD_LINK
            else Result := Result + GetItem(ItemNr);
          Continue;
        end;
      end;
      Result := Result + Str[Index];
    until Index >= SLength;
  end;
end;

function TDesignedLexicon.GetItem(Index: Integer): string;
var Bufstr: string;
begin
  Bufstr := '';
  if fLangManEngine <> nil then Bufstr := fLangManEngine.GetString(Self,Index);
  if Bufstr = '' then Result := fItems.Strings[Index]
                 else Result := Bufstr;
end;

function TDesignedLexicon.MaxIndex: Integer;
begin
  Result := fItems.Count - 1;
end;

function TDesignedLexicon.IsDefined(Index: Integer): Boolean;
begin
  Result := Index < fItems.Count;
end;

procedure TDesignedLexicon.SetItems(Value: TStringList);
begin
  if Assigned(fItems) then fItems.Assign(Value)
                      else fItems := Value;
end;

constructor TDesignedLexicon.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  fItems := TStringList.Create;
end;

destructor TDesignedLexicon.Destroy;
begin
  fItems.Free;
  inherited Destroy;
end;

function TDesignedLexicon.CreateItem(Text: string): Integer;
begin
  Result := fItems.Add(Text);
end;

function TDesignedLexicon.CompleteString(const Str: string): string;
begin
  Result := inherited CompleteString(Str);
end;

procedure TProgrammableLexicon.SetOnInitialization(Event: TNotifyEvent);
begin
  fOnInitialization := Event;
  if Assigned(fOnInitialization) then fOnInitialization(Self);
end;

function TProgrammableLexicon.GetItem(Index: Integer): string;
var Bufstr: string;
begin
  Bufstr := '';
  if fLangManEngine <> nil then Bufstr := fLangManEngine.GetString(Self,Index);
  if Bufstr = '' then Result := fIndexedItems.Get(Index)
                 else Result := Bufstr;
end;

function TProgrammableLexicon.MaxIndex: Integer;
begin
  Result := fIndexedItems.MaxIndex;
end;

constructor TProgrammableLexicon.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  fIndexedItems := TIndexedItems.Create(Self.Name);
end;

destructor TProgrammableLexicon.Destroy;
begin
  fIndexedItems.Free;
  inherited Destroy;
end;

procedure TProgrammableLexicon.DefineItem(ItemNr: Word; Text: string);
begin
  fIndexedItems.Write(ItemNr,Text);
end;

function TProgrammableLexicon.IsDefined(Index: Integer): Boolean;
begin
  Result := fIndexedItems.IsIncluded(Index);
end;

function TProgrammableLexicon.CompleteString(const Str: string): string;
begin
  Result := inherited CompleteString(Str);
end;

constructor TLangFormLexicon.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  LangManEngine := TLangManEngine(AOwner);
end;

function TLangFormLexicon.GetItem(Index: Integer): string;
var Bufstr: string;
begin
  Bufstr := '';
  if (fLangManEngine <> nil) and (fLangManEngine.fIncludeLangMan) then Bufstr := fLangManEngine.GetString(Self,Index);
  if Bufstr = '' then Result := fIndexedItems.Get(Index)
                 else Result := Bufstr;
end;

//***************************************************************************
//**  TLangManRichEdit                                                     **
//***************************************************************************

constructor TLangManRichEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ReadOnly := true;
  WordWrap := false;
  Styles := nil;
  LMLines := TStringList.Create;
  LMLines.Add('');
  fAutoFont := True;
  AutoFontSetup := false;
end;

destructor TLangManRichEdit.Destroy;
begin
  if Assigned(fAssignedLexicon) AND Assigned(fAssignedLexicon.Slaves) then fAssignedLexicon.Slaves.Remove(Self);
  LMLines.Free;
  Styles := nil;
  inherited Destroy;
end;

procedure TLangManRichEdit.LexiconAssign(Lexicon: TLexicon);
begin
  if fAssignedLexicon <> Lexicon then begin
    if Assigned(fAssignedLexicon) AND Assigned(fAssignedLexicon.Slaves) then fAssignedLexicon.Slaves.Remove(Self);
    fAssignedLexicon := Lexicon;
    Lexicon.Slaves.Add(Self);
    Translate;
  end;
end;

procedure TLangManRichEdit.SetupFont(Style: ShortInt);
begin
  if (Style < 0) OR (Style > High(Styles)) then begin
    SelAttributes := DefAttributes;
  end else begin
    SelAttributes.Style := Styles[Style].Style;
    if Styles[Style].Color = clDefault then SelAttributes.Color := DefAttributes.Color
                                          else SelAttributes.Color := Styles[Style].Color;
    if Styles[Style].Font = '' then SelAttributes.Name := DefAttributes.Name
                               else SelAttributes.Name := Styles[Style].Font;
    if Styles[Style].Charset = DEFAULT_CHARSET then SelAttributes.Charset := DefAttributes.Charset
                                               else SelAttributes.Charset := Styles[Style].Charset;
    if Styles[Style].Size = 0 then SelAttributes.Size := DefAttributes.Size
                              else SelAttributes.Size := Styles[Style].Size;
    if Styles[Style].Pitch = fpDefault then SelAttributes.Pitch := DefAttributes.Pitch
                                       else SelAttributes.Pitch := Styles[Style].Pitch;
  end;
end;

function TLangManRichEdit.WriteFormattedText(const Text: string; WrittingPosition: Integer): Integer;
var TxtLen, I, Nr, StackSize: Integer;
    Strbuf: String;
    CurrentStyle: ShortInt;
    StyleStack: array[1..32] of ShortInt;

    function ReadNr: Boolean;
    var LinkLength: Integer;
    begin
      if (Text[I+1] = NR_IDENT) then begin
        Inc(I,2);
        Nr := 0;
        LinkLength := 3;
        repeat
          if (I < TxtLen) AND ((Ord(Text[I]) >= Ord('0')) AND (Ord(Text[I]) <= Ord('9'))) then begin
            Nr := (Nr * 10) + (Ord(Text[I]) - Ord('0'));
            Inc(LinkLength);
          end else begin
            I := I + 2 - LinkLength;
            Strbuf := Strbuf + LINK_IDENT;
            Result := false;
            Exit;
          end;
          Inc(I);
        until Text[I] = STREDNIK;
        Result := true;
      end else Result := false;
    end;

    procedure WriteBuf(Style: ShortInt);
    var SetStyle: ShortInt;
    begin
      SelText := Strbuf;
      Inc(Result, Length(Strbuf));
      Strbuf := '';
      SelStart := Result;
      // nastaveni stylu
      if Style = -1 then begin
        if StackSize > 0 then begin
          // styl z vrchu haldy
          if StackSize <= 32 then SetStyle := StyleStack[StackSize];
          Dec(StackSize);
        end else SetStyle := -1;
      end else begin
        // styl dle Style
        Inc(StackSize);
        if StackSize <= 32 then StyleStack[StackSize] := CurrentStyle;
        SetStyle := Style;
      end;
      CurrentStyle := SetStyle;
      SetupFont(SetStyle);
    end;

begin
  if NOT AutoFontSetup then begin
    AutoFontSetup := true;
    SetAutoFont(fAutoFont);
  end;
  TxtLen := Length(Text);
  Result := WrittingPosition;
  if TxtLen > 0 then begin
    SelStart := WrittingPosition;
    I := 0;
    SelAttributes := DefAttributes;
    CurrentStyle := -1;
    StackSize := 0;
    Strbuf := '';
    repeat
      Inc(I);
      if (Text[I] = LINK_IDENT) AND (I < TxtLen) AND ReadNr then begin
        if Assigned(AssignedLexicon) then begin
          if (Nr > AssignedLexicon.MaxIndex) or (NOT AssignedLexicon.IsDefined(Nr))
            then Strbuf := Strbuf + BAD_LINK
            else Strbuf := Strbuf + AssignedLexicon.GetItem(Nr);
        end else Strbuf := Strbuf + BAD_LINK;
        Continue;
      end else begin
        if (Text[I] = STYLE_IDENT) AND (I < TxtLen) then begin
          if (Text[I+1] = STREDNIK) then begin
            WriteBuf(-1);
            Inc(I);
            Continue;
          end else begin
            if ReadNr then begin
              WriteBuf(Nr);
              Continue;
            end;
          end;
        end;
      end;
      Strbuf := Strbuf + Text[I];
    until I >= TxtLen;
    if Strbuf <> '' then begin
      SelText := Strbuf;
      Inc(Result, Length(Strbuf));
    end;
  end;
end;

function TLangManRichEdit.GetLineStart(LineIndex: Integer): Integer;
var TextLength, LineNr: Integer;
    Content: String;
begin
  Result := 0;
  LineNr := 0;
  if LineNr < LineIndex then begin
    Content := Text;
    TextLength := Length(Content);
    if TextLength = 0 then Exit;
    repeat
      Inc(Result);
      while (Content[Result] <> #10) do begin
        if Result >= TextLength then begin
          Dec(Result, LineNr);
          Exit;
        end;
        Inc(Result);
      end;
      Inc(LineNr);
    until LineNr >= LineIndex;
    Dec(Result, LineNr);
  end;
end;

function TLangManRichEdit.SelLine(LineIndex: Integer; IncludeCRLF: Boolean = false): Boolean;
var TextLength, LineNr, LineStart, LineEnd: Integer;
    Content: String;
begin
  Result := false;
  if LineIndex < 0 then Exit;
  TextLength := GetTextLen;
  if TextLength = 0 then begin
    if LineIndex = 0 then begin
      SelStart := 0;
      Result := true;
    end;
    Exit;
  end;
  LineStart := 0;
  LineNr := 0;
  Content := Text;
  while LineNr < LineIndex do begin
    Inc(LineStart);
    while (Content[LineStart] <> #10) do begin
      if LineStart >= TextLength then Exit;
      Inc(LineStart);
    end;
    Inc(LineNr);
  end;
  SelStart := LineStart - LineNr;
  if LineStart >= TextLength then begin
    Result := true;
  end else begin
    LineEnd := LineStart + 1;
    while Content[LineEnd] <> #13 do begin
      if LineEnd >= TextLength then begin
        SelLength := LineEnd - LineStart;
        Result := true;
        Exit;
      end;
      Inc(LineEnd);
    end;
    if IncludeCRLF then SelLength := LineEnd - LineStart
                   else SelLength := (LineEnd - LineStart) - 1;
    Result := true;
  end;
end;

function TLangManRichEdit.GetAutoFont;
begin
  if DesignTime then Result := fAutoFont
                else Result := (SendMessage(Handle, EM_GETLANGOPTIONS, 0, 0) AND IMF_AUTOFONT) = IMF_AUTOFONT;
end;

function TLangManRichEdit.GetLink(Index: Integer): String;
begin
  if Assigned(AssignedLexicon) then Result := AssignedLexicon.GetLink(Index)
                               else Result := LINK_IDENT + NR_IDENT + IntToStr(Index) + STREDNIK;
end;

procedure TLangManRichEdit.SetAutoFont(const Value: Boolean);
begin
  fAutoFont := Value;
  if Value then SendMessage(Handle, EM_SETLANGOPTIONS, 0, SendMessage(Handle, EM_GETLANGOPTIONS, 0, 0) OR IMF_AUTOFONT)
           else SendMessage(Handle, EM_SETLANGOPTIONS, 0, SendMessage(Handle, EM_GETLANGOPTIONS, 0, 0) AND (NOT IMF_AUTOFONT));
  if AutoFontSetup then Translate;
end;

procedure TLangManRichEdit.AssignStyles(LMStringStyles: TLMStringStyles);
begin
  Styles := nil;
  Styles := LMStringStyles;
  Translate;
end;

procedure TLangManRichEdit.ClearStyles;
begin
  Styles := nil;
  Translate;
end;

function TLangManRichEdit.GetStyles: TLMStringStyles;
begin
  Result := Styles;
end;

function TLangManRichEdit.StylesCount: Integer;
begin
  Result := Length(Styles);
end;

function TLangManRichEdit.SetStyle(Style: TFontStyles; Size: Integer = 0; Color: TColor = clDefault; FontName: TFontName = ''; Charset: TFontCharset = DEFAULT_CHARSET; Pitch: TFontPitch = fpDefault; StyleIndex: ShortInt = -1): Integer;
var StylesCount: Integer;
    StyleEdit: Boolean;
begin
  StyleEdit := false;
  StylesCount := Length(Styles);
  if StyleIndex < 0 then begin
    SetLength(Styles, StylesCount + 1);
    Result := StylesCount;
  end else begin
    if StyleIndex > High(Styles) then begin
      SetLength(Styles, StyleIndex + 1);
      while StylesCount < StyleIndex do begin
        Styles[StylesCount].Color := clDefault;
        Styles[StylesCount].Font := '';
        Styles[StylesCount].Charset := DEFAULT_CHARSET;
        Styles[StylesCount].Style := [];
        Styles[StylesCount].Size := 0;
        Styles[StylesCount].Pitch := fpDefault;
        Inc(StylesCount);
      end;
    end else StyleEdit := true;
    Result := StyleIndex;
  end;
  Styles[Result].Color := Color;
  Styles[Result].Font := FontName;
  Styles[Result].Charset := Charset;
  Styles[Result].Style := Style;
  Styles[Result].Size := Size;
  Styles[Result].Pitch := Pitch;
  if StyleEdit then Translate;
end;

function TLangManRichEdit.Format(const Text: String; StyleIndex: ShortInt): String;
begin
  if StyleIndex >= 0 then Result := STYLE_IDENT + NR_IDENT + IntToStr(StyleIndex) + STREDNIK + Text + STYLE_IDENT + STREDNIK
                     else Result := Text;
end;

procedure TLangManRichEdit.Write(const Text: String; StyleIndex: ShortInt = -1);
var FText: String;
begin
  if StyleIndex >= 0 then begin
    FText := Format(Text, StyleIndex);
    LMLines.Strings[LMLines.Count-1] := LMLines.Strings[LMLines.Count-1] + FText;
    WriteFormattedText(FText, GetTextLen);
  end else begin
    LMLines.Strings[LMLines.Count-1] := LMLines.Strings[LMLines.Count-1] + Text;
    WriteFormattedText(Text, GetTextLen);
  end;
end;

procedure TLangManRichEdit.WriteLn(const Text: String; StyleIndex: ShortInt = -1);
begin
  Write(Text, StyleIndex);
  NextLine;
end;

procedure TLangManRichEdit.NextLine;
begin
  SelStart := GetTextLen;
  SelText := #13#10;
  LMLines.Add('');
end;

procedure TLangManRichEdit.Clear;
begin
  LMLines.Clear;
  LMLines.Add('');
  Lines.Clear;
end;

function TLangManRichEdit.LinesCount: Integer;
begin
  Result := LMLines.Count;
end;

function TLangManRichEdit.ReadLineText(LineIndex: Integer): String;
begin
  if WordWrap then begin
    if SelLine(LineIndex) then Result := GetSelText
                          else Result := '';
  end else begin
    if LineIndex < 0 then Result := ''
                     else Result := Lines.Strings[LineIndex];
  end;
end;

function TLangManRichEdit.ReadLineFText(LineIndex: Integer): String;
begin
  if (LineIndex >= 0) AND (LineIndex < LMLines.Count) then Result := LMLines.Strings[LineIndex]
                                                      else Result := '';
end;

procedure TLangManRichEdit.DeleteLine(LineIndex: Integer);
begin
  if LineIndex < 0 then Exit;
  if WordWrap then begin
    if SelLine(LineIndex, true) then begin
      SelText := '';
      LMLines.Delete(LineIndex);
    end;
  end else begin
    Lines.Delete(LineIndex);
    LMLines.Delete(LineIndex);
  end;
end;

procedure TLangManRichEdit.RewriteLine(LineIndex: Integer; const Text: String; StyleIndex: ShortInt = -1);
var FLine: String;
    LineStart: Integer;
begin
  if LineIndex < 0 then Exit;
  FLine := Format(Text, StyleIndex);

{$IF CompilerVersion > 19}
  if WordWrap then begin
    if SelLine(LineIndex) then begin
      SelText := '';
      WriteFormattedText(FLine, SelStart);
    end else Exit;
  end else begin
    LineStart := SendMessage(Handle, EM_LINEINDEX, LineIndex, 0);
    if LineStart >= 0 then begin
      SendMessage(Handle, EM_SETSEL, LineStart, LineStart + SendMessage(Handle, EM_LINELENGTH, LineStart, 0));
      SendTextMessage(Handle, EM_REPLACESEL, 0, '');
      WriteFormattedText(FLine + #13#10, LineStart);
    end;
  end;
{$ELSE}
  if SelLine(LineIndex) then begin
    SelText := '';
    WriteFormattedText(FLine, SelStart);
  end else Exit;
{$IFEND}

  LMLines.Strings[LineIndex] := FLine;
end;

procedure TLangManRichEdit.InsertLine(LineIndex: Integer; const Text: String; StyleIndex: ShortInt = -1);
var FLine: String;
    LineStart, LineLength: Integer;
begin
  if LineIndex < 0 then Exit;
  FLine := Format(Text, StyleIndex);
  if WordWrap then begin
    if LineIndex > LMLines.Count then Exit;
    if LineIndex = LMLines.Count then WriteFormattedText(#13#10 + FLine, GetTextLen)
                                 else WriteFormattedText(FLine + #13#10, GetLineStart(LineIndex));
  end else begin
    LineStart := SendMessage(Handle, EM_LINEINDEX, LineIndex, 0);
    if LineStart >= 0 then begin
      WriteFormattedText(FLine + #13#10, LineStart);
    end else begin
      LineStart := SendMessage(Handle, EM_LINEINDEX, LineIndex - 1, 0);
      if LineStart < 0 then Exit;
      LineLength := SendMessage(Handle, EM_LINELENGTH, LineStart, 0);
      if LineLength = 0 then Exit;
      WriteFormattedText(#13#10 + FLine, LineStart + LineLength);
    end;
  end;
  LMLines.Insert(LineIndex, FLine);
end;

procedure TLangManRichEdit.Translate;
var LineIndex, TotalLength, LinesCount: Integer;
begin
  inherited Clear;
  SetupFont(-1);
  LinesCount := LMLines.Count;
  if LinesCount > 0 then begin
    TotalLength := WriteFormattedText(LMLines.Strings[0], 0);
    LineIndex := 1;
    while LineIndex < LinesCount do begin
      SelStart := TotalLength;
      SelText := #13#10;
      TotalLength := WriteFormattedText(LMLines.Strings[LineIndex], TotalLength + 2);
      Inc(LineIndex);
    end;
  end;
end;

procedure TLangManRichEdit.LoadFromFile(const SourceFile: TFileName);
begin
  LMLines.LoadFromFile(SourceFile);
  Translate;
end;

procedure TLangManRichEdit.LoadFromStream(SourceStream: TStream);
begin
  LMLines.LoadFromStream(SourceStream);
  Translate;
end;

procedure TLangManRichEdit.SaveRichTextToFile(const DestinationFile: TFileName);
begin
  Lines.SaveToFile(DestinationFile);
end;

procedure TLangManRichEdit.SaveRichTextToStream(DestinationStream: TStream);
begin
  Lines.SaveToStream(DestinationStream);
end;

procedure TLangManRichEdit.SaveEncodedFormToFile(const DestinationFile: TFileName);
begin
  LMLines.SaveToFile(DestinationFile);
end;

procedure TLangManRichEdit.SaveEncodedFormToStream(DestinationStream: TStream);
begin
  LMLines.SaveToStream(DestinationStream);
end;

{$IF CompilerVersion > 19}

procedure TLangManRichEdit.LoadFromFile(const SourceFile: TFileName; Encoding: TEncoding);
begin
  LMLines.LoadFromFile(SourceFile, Encoding);
  Translate;
end;

procedure TLangManRichEdit.LoadFromStream(SourceStream: TStream; Encoding: TEncoding);
begin
  LMLines.LoadFromStream(SourceStream, Encoding);
  Translate;
end;

procedure TLangManRichEdit.SaveRichTextToFile(const DestinationFile: TFileName; Encoding: TEncoding);
begin
  Lines.SaveToFile(DestinationFile, Encoding);
end;

procedure TLangManRichEdit.SaveRichTextToStream(DestinationStream: TStream; Encoding: TEncoding);
begin
  Lines.SaveToStream(DestinationStream, Encoding);
end;

procedure TLangManRichEdit.SaveEncodedFormToFile(const DestinationFile: TFileName; Encoding: TEncoding);
begin
  LMLines.SaveToFile(DestinationFile, Encoding);
end;

procedure TLangManRichEdit.SaveEncodedFormToStream(DestinationStream: TStream; Encoding: TEncoding);
begin
  LMLines.SaveToStream(DestinationStream, Encoding);
end;

{$IFEND}

//***************************************************************************
//**  LangManStrings Tool                                                  **
//***************************************************************************

constructor TLangManStrings.Create(ControlledStrings: TStrings; Lexicon: TLexicon);
begin
  if ControlledStrings = nil then raise Exception.Create('ControlledStrings must be assigned!');
  if Lexicon = nil then raise Exception.Create('Lexicon must be assigned!');
  inherited Create;
  AssignedLexicon := Lexicon;
  Assign(ControlledStrings);
  Controlled := ControlledStrings;
  AssignedLexicon.Slaves.Add(Self);
end;

destructor TLangManStrings.Destroy;
begin
  if Assigned(AssignedLexicon) AND Assigned(AssignedLexicon.Slaves) then AssignedLexicon.Slaves.Remove(Self);
  inherited Destroy;
end;

function TLangManStrings.Add(const S: string): Integer;
begin
  Result := inherited Add(S);
end;

function TLangManStrings.AddObject(const S: string; AObject: TObject): Integer;
begin
  Result := inherited AddObject(S, AObject);
  if Assigned(Controlled) then Result := Controlled.AddObject(AssignedLexicon.CompleteString(S),AObject);
end;

procedure TLangManStrings.Clear;
begin
  inherited Clear;
  if Assigned(Controlled) then Controlled.Clear;
end;

procedure TLangManStrings.Delete(Index: Integer);
begin
  inherited Delete(Index);
  Translate;
end;

procedure TLangManStrings.Exchange(Index1, Index2: Integer);
begin
  inherited Exchange(Index1, Index2);
  Translate;
end;

procedure TLangManStrings.Insert(Index: Integer; const S: string);
begin
  inherited Insert(Index, S);
end;

procedure TLangManStrings.InsertObject(Index: Integer; const S: string; AObject: TObject);
begin
  inherited InsertObject(Index, S, AObject);
  Translate;
end;

procedure TLangManStrings.CustomSort(Compare: TStringListSortCompare);
begin
  inherited CustomSort(Compare);
  Translate;
end;

procedure TLangManStrings.Translate;
var Line: Integer;
begin
  if Assigned(Controlled) then begin
    Controlled.Clear;
    if Count > 0 then for Line := 0 to Count - 1 do begin
      Controlled.Add(AssignedLexicon.CompleteString(Strings[Line]));
    end;
  end;
end;

//***************************************************************************
//**  LangMan LangCombo methods                                            **
//***************************************************************************

procedure TLangCombo.SetLangManEngine(LangMan: TLangManEngine);
begin
  if fLangManEngine <> LangMan then begin
    if (fLangManEngine <> nil) then fLangManEngine.SpanClients.UnregisterClient(Self);
    fLangManEngine := LangMan;
    if LangMan <> nil then begin
      fLangManEngine.SpanClients.RegisterClient(Self);
      fLangManEngine.SpanClients.ChangeLangLists(fLangManEngine.LangMenu,
                                                 fLangManEngine.fCurrentLanguage,
                                                 fLangManEngine.Flags);
    end;
  end;
end;

function TLangCombo.GetStyleCombo: TLangComboStyle;
begin
  case Style of
    csDropDownList: Result := scDropDownList;
    csOwnerDrawFixed: Result := scOwnerDrawFixed;
    csOwnerDrawVariable: Result := scOwnerDrawVariable;
    else begin
      Style := csDropDownList;
      Result := scDropDownList;
    end;
  end;
end;

procedure TLangCombo.SetStyleCombo(Input: TLangComboStyle);
begin
  case Input of
    scDropDownList: Style := csDropDownList;
    scOwnerDrawFixed: Style := csOwnerDrawFixed;
    scOwnerDrawVariable: Style := csOwnerDrawVariable;
    else Style := csDropDownList;
  end;
end;

procedure TLangCombo.ChangeLanguage(AOwner: TObject);
begin
  if fLangManEngine <> nil then begin
    if (ItemIndex >= 0) and
       (Text <> fLangManEngine.CurrentLanguage) then begin
      fLangManEngine.Translate(Text);
      if Assigned(fOnChangeLanguage) then fOnChangeLanguage(Self);
    end;
  end;
end;

constructor TLangCombo.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Style := csDropDownList;
  OnChange := ChangeLanguage;
end;

function TLangFlagsCombo.GetItemHt: Integer;
begin
  Result := Height - 6;
end;

procedure TLangFlagsCombo.SetLangManEngine(LangMan: TLangManEngine);
begin
  if fLangManEngine <> LangMan then begin
    if (fLangManEngine <> nil) then fLangManEngine.SpanClients.UnregisterClient(Self);
    fLangManEngine := LangMan;
    if LangMan <> nil then begin
      Images := LangMan.Flags;
      fLangManEngine.SpanClients.RegisterClient(Self);
      fLangManEngine.SpanClients.ChangeLangLists(fLangManEngine.LangMenu,
                                                 fLangManEngine.fCurrentLanguage,
                                                 fLangManEngine.Flags);
    end else Images := nil;
  end;
end;

procedure TLangFlagsCombo.ChangeLanguage(AOwner: TObject);
begin
  if fLangManEngine <> nil then begin
    if (ItemIndex >= 0) and
       (ItemsEx.Items[ItemIndex].Caption <> fLangManEngine.CurrentLanguage) then begin
      fLangManEngine.Translate(ItemsEx.Items[ItemIndex].Caption);
      if Assigned(fOnChangeLanguage) then fOnChangeLanguage(Self);
    end;
  end;
end;

constructor TLangFlagsCombo.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Style := csExDropDownList;
  OnChange := ChangeLanguage;
end;

//***************************************************************************
//**  LangMan TSpans                                                       **
//***************************************************************************

constructor TSpans.Create;
begin
  Components := TComponentList.Create;
end;
destructor  TSpans.Destroy;
begin
  Components.Free;
  Inherited;
end;
procedure TSpans.RegisterClient(Client: TComponent);
begin
  if Client <> nil then Components.Add(Client);
end;
procedure TSpans.UnregisterClient(Client: TComponent);
var ClientIndex: Integer;
begin
  ClientIndex := Components.IndexOf(Client);
  if ClientIndex >= 0 then Components.Extract(Client);
end;
procedure TSpans.CallClientProcs;
var ClientIndex: Integer;
begin
  if Components.Count > 0 then begin
    for ClientIndex := 0 to Components.Count - 1 do
      if Components.Items[ClientIndex] is TLangManComponent then
        (Components.Items[ClientIndex] as TLangManComponent).ChangeLanguage(Self);
  end;
end;
procedure TSpans.ChangeLangLists(Languages: TStrings; CurrentLang: TLanguage; FlagsList: TFlagsList);
var ClientIndex, LI: Integer;
begin
  if Components.Count > 0 then begin
    for ClientIndex := 0 to Components.Count - 1 do begin
      if Components.Items[ClientIndex] is TLangCombo then begin
        (Components.Items[ClientIndex] as TLangCombo).Items.Assign(Languages);
        (Components.Items[ClientIndex] as TLangCombo).ItemIndex := (Components.Items[ClientIndex] as TLangCombo).Items.IndexOf(CurrentLang);
        (Components.Items[ClientIndex] as TLangCombo).Invalidate;
      end;
      if Components.Items[ClientIndex] is TLangFlagsCombo then begin
        with (Components.Items[ClientIndex] as TLangFlagsCombo) do begin
          for LI := 0 to Languages.Count - 1 do begin
            if (LI + 1) > ItemsEx.Count then begin
              ItemsEx.AddItem( Languages.Strings[LI], FlagsList.GetImageIndex(LI),
                               FlagsList.GetImageIndex(LI), -1, -1, nil);
            end else with ItemsEx.ComboItems[LI] do begin
              Caption := Languages.Strings[LI];
              ImageIndex := FlagsList.GetImageIndex(LI);
              SelectedImageIndex := FlagsList.GetImageIndex(LI);
              OverlayImageIndex := -1;
              Indent := -1;
              Data := nil;
            end;
          end;
          while LI < (ItemsEx.Count - 1) do ItemsEx.Delete(LI);
          ItemIndex := Items.IndexOf(CurrentLang);
          Invalidate;
        end;
      end;
      // dalsi LangMan komponenty prepinajici jazyk
    end;
  end;
end;
function TSpans.IsRegistered(OwnerName: string; ComponentName: string): Boolean;
var ClientIndex, DotPos: Integer;
begin
  Result := false;
  if Components.Count > 0 then begin
    for ClientIndex := 0 to Components.Count - 1 do begin
      if Components.Items[ClientIndex] is TLangManClient then begin
        if (OwnerName = '') then begin
          if (Components.Items[ClientIndex] as TLangManClient).ParentControl.Name = ComponentName then begin
            Result := true;
            Exit;
          end;
        end else if (Components.Items[ClientIndex] as TLangManClient).ParentControl.Name = OwnerName then begin
          if (Components.Items[ClientIndex] as TLangManClient).ParentControl.FindComponent(ComponentName) <> nil then begin
            Result := true;
            Exit;
          end else begin
            DotPos := Pos(TECKA,ComponentName);
            if DotPos > 1 then begin
              if (Components.Items[ClientIndex] as TLangManClient).ParentControl.FindComponent(Copy(ComponentName,1,DotPos-1)) <> nil then begin
                Result := true;
                Exit;
              end;
            end;
          end;
        end;
      end;
    end;
  end;
end;

//***************************************************************************
//**  LangMan Flag List                                                    **
//***************************************************************************

constructor TFlagsList.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
{  BkColor := clWhite;
  DrawingStyle := dsTransparent; }
  FlagPointer := nil;
  MaxAddress := -1;
end;
destructor TFlagsList.Destroy;
begin
  FlagPointer := nil;
  inherited Destroy;
end;
procedure TFlagsList.ClearFlags;
begin
  Clear;
  FlagPointer := nil;
  MaxAddress := -1;
end;
function TFlagsList.GetImageIndex(LangIndex: Word):Integer;
begin
  if LangIndex <= Integer(MaxAddress) then Result := FlagPointer[LangIndex]
                                      else Result := -1;
end;
function TFlagsList.AddFlag(Image: TGraphic): Integer;
begin
  Result := -1;
  try
   try
    if (Image <> nil) and
       (Image.Height = Height) and
       (Image.Width = Width) then begin
      if Image is TIcon then Result := AddIcon(Image as TIcon);
      if Image is TBitmap then Result := AddMasked(Image as TBitmap, clWhite);
    end;
   finally
    Inc(MaxAddress);
    SetLength(FlagPointer,MaxAddress + 1);
    FlagPointer[MaxAddress] := Result;
   end;
  except
    // ignore
  end;
end;
function TFlagsList.RewriteFlag(Index: Integer; Image: TGraphic): Integer;
begin
  Result := -1;
  if Index <= Integer(MaxAddress) then begin
    try
      try
        if (Image <> nil) and
           (Image.Height = Height) and
           (Image.Width = Width) then begin
          if Image is TIcon then FlagPointer[Index] := AddIcon(Image as TIcon);
          if Image is TBitmap then FlagPointer[Index] := AddMasked(Image as TBitmap, clWhite);
        end else FlagPointer[Index] := -1;
      finally
        Result := FlagPointer[Index];
      end;
    except
      FlagPointer[Index] := -1;
    end;
  end else Result := AddFlag(Image);
end;
function TFlagsList.ImportFlag(ImageList: TCustomImageList; Index: Integer): Integer;
begin
  Result := -1;
  try
   try
    Result := AddImage(ImageList, Index);
   finally
    Inc(MaxAddress);
    SetLength(FlagPointer,MaxAddress + 1);
    FlagPointer[MaxAddress] := Result;
   end;
  except
    //ignore
  end;
end;

//***************************************************************************
//**  LangMan Component additions engine                                   **
//***************************************************************************

procedure RegisterProperty(Component: TComponent; PropertyValue: String;
                           PropertyID: TAdditionProperties; ItemAddr: String = '');
begin
  if (PropertyID in ActiveClient.TransAdditions) and ContainChars(PropertyValue) and
     ((ItemAddr <> '') or (Component.Name <> PropertyValue))
    then ActiveClient.CreateStructItem(
                                       @Component,
                                       Ord(PropertyID) + ADDIT_NAMES_START,
                                       PropertyValue,
                                       ItemAddr
                                       );
end;

procedure RegisterProperty(Component: TComponent; PropertyValue: String;
                           PropertyID: TStringProperties; ItemAddr: String = '');
begin
  if (PropertyID in ActiveClient.TransStringProp) and ContainChars(PropertyValue) and
     ((ItemAddr <> '') or (Component.Name <> PropertyValue))
    then ActiveClient.CreateStructItem(
                                       @Component,
                                       PropIndex(PropertyID),
                                       PropertyValue,
                                       ItemAddr
                                       );
end;

procedure RegisterProperty(Component: TComponent; PropertyValue: String;
                           PropertyID: TTStringsProperties; ItemAddr: String = '');
begin
  if (PropertyID in ActiveClient.TransTStringsProp) and ContainChars(PropertyValue) and
     ((ItemAddr <> '') or (Component.Name <> PropertyValue))
    then ActiveClient.CreateStructItem(
                                       @Component,
                                       PropIndex(PropertyID),
                                       PropertyValue,
                                       ItemAddr
                                       );
end;

procedure RegisterProperty(Component: TComponent; PropertyValue: String;
                           PropertyID: TStructuredProperties; ItemAddr: String = '');
begin
  if (PropertyID in ActiveClient.TransStructuredProp) and ContainChars(PropertyValue) and
     ((ItemAddr <> '') or (Component.Name <> PropertyValue))
    then ActiveClient.CreateStructItem(
                                       @Component,
                                       PropIndex(PropertyID),
                                       PropertyValue,
                                       ItemAddr
                                       );
end;

procedure RegisterProperty(Component: TComponent; PropertyValue: String;
                           PropertyID: TOtherProperties; ItemAddr: String = '');
begin
  if (PropertyID in ActiveClient.TransOtherProp) and ContainChars(PropertyValue) and
     ((ItemAddr <> '') or (Component.Name <> PropertyValue))
    then ActiveClient.CreateStructItem(
                                       @Component,
                                       PropIndex(PropertyID),
                                       PropertyValue,
                                       ItemAddr
                                       );
end;

function TranslateProperty(Component: TComponent; PropertyValue: String;
                           PropertyID: TAdditionProperties; ItemAddr: String = ''): String;
var Bufstr: String;
begin
  if (PropertyID in ActiveClient.TransAdditions) then begin
    Bufstr := ActiveClient.StructItem(
                                      Component.Name,
                                      Component.Owner.Name,
                                      Ord(PropertyID) + ADDIT_NAMES_START,
                                      ItemAddr
                                      );
    if Bufstr <> '' then Result := Bufstr
                    else Result := PropertyValue;
  end else Result := PropertyValue;
end;

function TranslateProperty(Component: TComponent; PropertyValue: String;
                           PropertyID: TStringProperties; ItemAddr: String = ''): String;
var Bufstr: String;
begin
  if (PropertyID in ActiveClient.TransStringProp) then begin
    Bufstr := ActiveClient.StructItem(
                                      Component.Name,
                                      Component.Owner.Name,
                                      PropIndex(PropertyID),
                                      ItemAddr
                                      );
    if Bufstr <> '' then Result := Bufstr
                    else Result := PropertyValue;
  end else Result := PropertyValue;
end;

function TranslateProperty(Component: TComponent; PropertyValue: String;
                           PropertyID: TTStringsProperties; ItemAddr: String = ''): String;
var Bufstr: String;
begin
  if (PropertyID in ActiveClient.TransTStringsProp) then begin
    Bufstr := ActiveClient.StructItem(
                                      Component.Name,
                                      Component.Owner.Name,
                                      PropIndex(PropertyID),
                                      ItemAddr
                                      );
    if Bufstr <> '' then Result := Bufstr
                    else Result := PropertyValue;
  end else Result := PropertyValue;
end;

function TranslateProperty(Component: TComponent; PropertyValue: String;
                           PropertyID: TStructuredProperties; ItemAddr: String = ''): String;
var Bufstr: String;
begin
  if (PropertyID in ActiveClient.TransStructuredProp) then begin
    Bufstr := ActiveClient.StructItem(
                                      Component.Name,
                                      Component.Owner.Name,
                                      PropIndex(PropertyID),
                                      ItemAddr
                                      );
    if Bufstr <> '' then Result := Bufstr
                    else Result := PropertyValue;
  end else Result := PropertyValue;
end;

function TranslateProperty(Component: TComponent; PropertyValue: String;
                           PropertyID: TOtherProperties; ItemAddr: String = ''): String;
var Bufstr: String;
begin
  if (PropertyID in ActiveClient.TransOtherProp) then begin
    Bufstr := ActiveClient.StructItem(
                                      Component.Name,
                                      Component.Owner.Name,
                                      PropIndex(PropertyID),
                                      ItemAddr
                                      );
    if Bufstr <> '' then Result := Bufstr
                    else Result := PropertyValue;
  end else Result := PropertyValue;
end;

//***************************************************************************
//**  LangMan Component initialization for Design time                     **
//***************************************************************************
begin
  DesignTime := Application.MainForm <> nil;
end.
