classes.pas 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654
  1. {
  2. This file is part of the Pas2JS run time library.
  3. Copyright (c) 2017 by Mattias Gaertner
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. unit Classes;
  11. {$mode objfpc}
  12. interface
  13. uses
  14. RTLConsts, Types, SysUtils;
  15. type
  16. TNotifyEvent = procedure(Sender: TObject) of object;
  17. // Notification operations :
  18. // Observer has changed, is freed, item added to/deleted from list, custom event.
  19. TFPObservedOperation = (ooChange,ooFree,ooAddItem,ooDeleteItem,ooCustom);
  20. EListError = class(Exception);
  21. EStringListError = class(EListError);
  22. EComponentError = class(Exception);
  23. TListAssignOp = (laCopy, laAnd, laOr, laXor, laSrcUnique, laDestUnique);
  24. TListSortCompare = function(Item1, Item2: JSValue): Integer;
  25. TListCallback = Types.TListCallback;
  26. TListStaticCallback = Types.TListStaticCallback;
  27. TAlignment = (taLeftJustify, taRightJustify, taCenter);
  28. { TFPListEnumerator }
  29. TFPList = Class;
  30. TFPListEnumerator = class
  31. private
  32. FList: TFPList;
  33. FPosition: Integer;
  34. public
  35. constructor Create(AList: TFPList);
  36. function GetCurrent: JSValue;
  37. function MoveNext: Boolean;
  38. property Current: JSValue read GetCurrent;
  39. end;
  40. { TFPList }
  41. TFPList = class(TObject)
  42. private
  43. FList: TJSValueDynArray;
  44. FCount: Integer;
  45. FCapacity: Integer;
  46. procedure CopyMove(aList: TFPList);
  47. procedure MergeMove(aList: TFPList);
  48. procedure DoCopy(ListA, ListB: TFPList);
  49. procedure DoSrcUnique(ListA, ListB: TFPList);
  50. procedure DoAnd(ListA, ListB: TFPList);
  51. procedure DoDestUnique(ListA, ListB: TFPList);
  52. procedure DoOr(ListA, ListB: TFPList);
  53. procedure DoXOr(ListA, ListB: TFPList);
  54. protected
  55. function Get(Index: Integer): JSValue; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE}
  56. procedure Put(Index: Integer; Item: JSValue); {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE}
  57. procedure SetCapacity(NewCapacity: Integer);
  58. procedure SetCount(NewCount: Integer);
  59. Procedure RaiseIndexError(Index: Integer);
  60. public
  61. //Type
  62. // TDirection = (FromBeginning, FromEnd);
  63. destructor Destroy; override;
  64. procedure AddList(AList: TFPList);
  65. function Add(Item: JSValue): Integer; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE}
  66. procedure Clear;
  67. procedure Delete(Index: Integer); {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE}
  68. class procedure Error(const Msg: string; const Data: String);
  69. procedure Exchange(Index1, Index2: Integer);
  70. function Expand: TFPList; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE}
  71. function Extract(Item: JSValue): JSValue;
  72. function First: JSValue;
  73. function GetEnumerator: TFPListEnumerator;
  74. function IndexOf(Item: JSValue): Integer;
  75. function IndexOfItem(Item: JSValue; Direction: TDirection): Integer;
  76. procedure Insert(Index: Integer; Item: JSValue); {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE}
  77. function Last: JSValue;
  78. procedure Move(CurIndex, NewIndex: Integer);
  79. procedure Assign (ListA: TFPList; AOperator: TListAssignOp=laCopy; ListB: TFPList=nil);
  80. function Remove(Item: JSValue): Integer;
  81. procedure Pack;
  82. procedure Sort(const Compare: TListSortCompare);
  83. procedure ForEachCall(const proc2call: TListCallback; const arg: JSValue);
  84. procedure ForEachCall(const proc2call: TListStaticCallback; const arg: JSValue);
  85. property Capacity: Integer read FCapacity write SetCapacity;
  86. property Count: Integer read FCount write SetCount;
  87. property Items[Index: Integer]: JSValue read Get write Put; default;
  88. property List: TJSValueDynArray read FList;
  89. end;
  90. TListNotification = (lnAdded, lnExtracted, lnDeleted);
  91. TList = class;
  92. { TListEnumerator }
  93. TListEnumerator = class
  94. private
  95. FList: TList;
  96. FPosition: Integer;
  97. public
  98. constructor Create(AList: TList);
  99. function GetCurrent: JSValue;
  100. function MoveNext: Boolean;
  101. property Current: JSValue read GetCurrent;
  102. end;
  103. { TList }
  104. TList = class(TObject)
  105. private
  106. FList: TFPList;
  107. procedure CopyMove (aList : TList);
  108. procedure MergeMove (aList : TList);
  109. procedure DoCopy(ListA, ListB : TList);
  110. procedure DoSrcUnique(ListA, ListB : TList);
  111. procedure DoAnd(ListA, ListB : TList);
  112. procedure DoDestUnique(ListA, ListB : TList);
  113. procedure DoOr(ListA, ListB : TList);
  114. procedure DoXOr(ListA, ListB : TList);
  115. protected
  116. function Get(Index: Integer): JSValue;
  117. procedure Put(Index: Integer; Item: JSValue);
  118. procedure Notify(aValue: JSValue; Action: TListNotification); virtual;
  119. procedure SetCapacity(NewCapacity: Integer);
  120. function GetCapacity: integer;
  121. procedure SetCount(NewCount: Integer);
  122. function GetCount: integer;
  123. function GetList: TJSValueDynArray;
  124. property FPList : TFPList Read FList;
  125. public
  126. constructor Create; reintroduce;
  127. destructor Destroy; override;
  128. Procedure AddList(AList : TList);
  129. function Add(Item: JSValue): Integer;
  130. procedure Clear; virtual;
  131. procedure Delete(Index: Integer);
  132. class procedure Error(const Msg: string; Data: String); virtual;
  133. procedure Exchange(Index1, Index2: Integer);
  134. function Expand: TList;
  135. function Extract(Item: JSValue): JSValue;
  136. function First: JSValue;
  137. function GetEnumerator: TListEnumerator;
  138. function IndexOf(Item: JSValue): Integer;
  139. procedure Insert(Index: Integer; Item: JSValue);
  140. function Last: JSValue;
  141. procedure Move(CurIndex, NewIndex: Integer);
  142. procedure Assign (ListA: TList; AOperator: TListAssignOp=laCopy; ListB: TList=nil);
  143. function Remove(Item: JSValue): Integer;
  144. procedure Pack;
  145. procedure Sort(const Compare: TListSortCompare);
  146. property Capacity: Integer read GetCapacity write SetCapacity;
  147. property Count: Integer read GetCount write SetCount;
  148. property Items[Index: Integer]: JSValue read Get write Put; default;
  149. property List: TJSValueDynArray read GetList;
  150. end;
  151. { TPersistent }
  152. TPersistent = class(TObject)
  153. private
  154. //FObservers : TFPList;
  155. procedure AssignError(Source: TPersistent);
  156. protected
  157. procedure AssignTo(Dest: TPersistent); virtual;
  158. function GetOwner: TPersistent; virtual;
  159. public
  160. procedure Assign(Source: TPersistent); virtual;
  161. //procedure FPOAttachObserver(AObserver : TObject);
  162. //procedure FPODetachObserver(AObserver : TObject);
  163. //procedure FPONotifyObservers(ASender : TObject; AOperation: TFPObservedOperation; Data: TObject);
  164. function GetNamePath: string; virtual;
  165. end;
  166. TPersistentClass = Class of TPersistent;
  167. TStrings = Class;
  168. { TStringsEnumerator class }
  169. TStringsEnumerator = class
  170. private
  171. FStrings: TStrings;
  172. FPosition: Integer;
  173. public
  174. constructor Create(AStrings: TStrings); reintroduce;
  175. function GetCurrent: String;
  176. function MoveNext: Boolean;
  177. property Current: String read GetCurrent;
  178. end;
  179. { TStrings class }
  180. TStrings = class(TPersistent)
  181. private
  182. FSpecialCharsInited : boolean;
  183. FAlwaysQuote: Boolean;
  184. FQuoteChar : Char;
  185. FDelimiter : Char;
  186. FNameValueSeparator : Char;
  187. FUpdateCount: Integer;
  188. FLBS : TTextLineBreakStyle;
  189. FSkipLastLineBreak : Boolean;
  190. FStrictDelimiter : Boolean;
  191. FLineBreak : String;
  192. function GetCommaText: string;
  193. function GetName(Index: Integer): string;
  194. function GetValue(const Name: string): string;
  195. Function GetLBS : TTextLineBreakStyle;
  196. Procedure SetLBS (AValue : TTextLineBreakStyle);
  197. procedure SetCommaText(const Value: string);
  198. procedure SetValue(const Name, Value: string);
  199. procedure SetDelimiter(c:Char);
  200. procedure SetQuoteChar(c:Char);
  201. procedure SetNameValueSeparator(c:Char);
  202. procedure DoSetTextStr(const Value: string; DoClear : Boolean);
  203. Function GetDelimiter : Char;
  204. Function GetNameValueSeparator : Char;
  205. Function GetQuoteChar: Char;
  206. Function GetLineBreak : String;
  207. procedure SetLineBreak(const S : String);
  208. Function GetSkipLastLineBreak : Boolean;
  209. procedure SetSkipLastLineBreak(const AValue : Boolean);
  210. protected
  211. procedure Error(const Msg: string; Data: Integer);
  212. function Get(Index: Integer): string; virtual; abstract;
  213. function GetCapacity: Integer; virtual;
  214. function GetCount: Integer; virtual; abstract;
  215. function GetObject(Index: Integer): TObject; virtual;
  216. function GetTextStr: string; virtual;
  217. procedure Put(Index: Integer; const S: string); virtual;
  218. procedure PutObject(Index: Integer; AObject: TObject); virtual;
  219. procedure SetCapacity(NewCapacity: Integer); virtual;
  220. procedure SetTextStr(const Value: string); virtual;
  221. procedure SetUpdateState(Updating: Boolean); virtual;
  222. property UpdateCount: Integer read FUpdateCount;
  223. Function DoCompareText(const s1,s2 : string) : PtrInt; virtual;
  224. Function GetDelimitedText: string;
  225. Procedure SetDelimitedText(Const AValue: string);
  226. Function GetValueFromIndex(Index: Integer): string;
  227. Procedure SetValueFromIndex(Index: Integer; const Value: string);
  228. Procedure CheckSpecialChars;
  229. // Class Function GetNextLine (Const Value : String; Var S : String; Var P : Integer) : Boolean;
  230. Function GetNextLinebreak (Const Value : String; Out S : String; Var P : Integer) : Boolean;
  231. public
  232. constructor Create; reintroduce;
  233. destructor Destroy; override;
  234. function Add(const S: string): Integer; virtual; overload;
  235. // function AddFmt(const Fmt : string; const Args : Array of const): Integer; overload;
  236. function AddObject(const S: string; AObject: TObject): Integer; virtual; overload;
  237. // function AddObject(const Fmt: string; Args : Array of const; AObject: TObject): Integer; overload;
  238. procedure Append(const S: string);
  239. procedure AddStrings(TheStrings: TStrings); overload; virtual;
  240. procedure AddStrings(TheStrings: TStrings; ClearFirst : Boolean); overload;
  241. procedure AddStrings(const TheStrings: array of string); overload; virtual;
  242. procedure AddStrings(const TheStrings: array of string; ClearFirst : Boolean); overload;
  243. Procedure AddText(Const S : String); virtual;
  244. procedure Assign(Source: TPersistent); override;
  245. procedure BeginUpdate;
  246. procedure Clear; virtual; abstract;
  247. procedure Delete(Index: Integer); virtual; abstract;
  248. procedure EndUpdate;
  249. function Equals(Obj: TObject): Boolean; override; overload;
  250. function Equals(TheStrings: TStrings): Boolean; overload;
  251. procedure Exchange(Index1, Index2: Integer); virtual;
  252. function GetEnumerator: TStringsEnumerator;
  253. function IndexOf(const S: string): Integer; virtual;
  254. function IndexOfName(const Name: string): Integer; virtual;
  255. function IndexOfObject(AObject: TObject): Integer; virtual;
  256. procedure Insert(Index: Integer; const S: string); virtual; abstract;
  257. procedure InsertObject(Index: Integer; const S: string; AObject: TObject);
  258. procedure Move(CurIndex, NewIndex: Integer); virtual;
  259. procedure GetNameValue(Index : Integer; Out AName,AValue : String);
  260. function ExtractName(Const S:String):String;
  261. Property TextLineBreakStyle : TTextLineBreakStyle Read GetLBS Write SetLBS;
  262. property Delimiter: Char read GetDelimiter write SetDelimiter;
  263. property DelimitedText: string read GetDelimitedText write SetDelimitedText;
  264. property LineBreak : string Read GetLineBreak write SetLineBreak;
  265. Property StrictDelimiter : Boolean Read FStrictDelimiter Write FStrictDelimiter;
  266. property AlwaysQuote: Boolean read FAlwaysQuote write FAlwaysQuote;
  267. property QuoteChar: Char read GetQuoteChar write SetQuoteChar;
  268. Property NameValueSeparator : Char Read GetNameValueSeparator Write SetNameValueSeparator;
  269. property ValueFromIndex[Index: Integer]: string read GetValueFromIndex write SetValueFromIndex;
  270. property Capacity: Integer read GetCapacity write SetCapacity;
  271. property CommaText: string read GetCommaText write SetCommaText;
  272. property Count: Integer read GetCount;
  273. property Names[Index: Integer]: string read GetName;
  274. property Objects[Index: Integer]: TObject read GetObject write PutObject;
  275. property Values[const Name: string]: string read GetValue write SetValue;
  276. property Strings[Index: Integer]: string read Get write Put; default;
  277. property Text: string read GetTextStr write SetTextStr;
  278. Property SkipLastLineBreak : Boolean Read GetSkipLastLineBreak Write SetSkipLastLineBreak;
  279. end;
  280. { TStringList}
  281. TStringItem = record
  282. FString: string;
  283. FObject: TObject;
  284. end;
  285. TStringItemArray = Array of TStringItem;
  286. TStringList = class;
  287. TStringListSortCompare = function(List: TStringList; Index1, Index2: Integer): Integer;
  288. TStringsSortStyle = (sslNone,sslUser,sslAuto);
  289. TStringsSortStyles = Set of TStringsSortStyle;
  290. TStringList = class(TStrings)
  291. private
  292. FList: TStringItemArray;
  293. FCount: Integer;
  294. FOnChange: TNotifyEvent;
  295. FOnChanging: TNotifyEvent;
  296. FDuplicates: TDuplicates;
  297. FCaseSensitive : Boolean;
  298. FForceSort : Boolean;
  299. FOwnsObjects : Boolean;
  300. FSortStyle: TStringsSortStyle;
  301. procedure ExchangeItemsInt(Index1, Index2: Integer);
  302. function GetSorted: Boolean;
  303. procedure Grow;
  304. procedure InternalClear(FromIndex : Integer = 0; ClearOnly : Boolean = False);
  305. procedure QuickSort(L, R: Integer; CompareFn: TStringListSortCompare);
  306. procedure SetSorted(Value: Boolean);
  307. procedure SetCaseSensitive(b : boolean);
  308. procedure SetSortStyle(AValue: TStringsSortStyle);
  309. protected
  310. Procedure CheckIndex(AIndex : Integer);
  311. procedure ExchangeItems(Index1, Index2: Integer); virtual;
  312. procedure Changed; virtual;
  313. procedure Changing; virtual;
  314. function Get(Index: Integer): string; override;
  315. function GetCapacity: Integer; override;
  316. function GetCount: Integer; override;
  317. function GetObject(Index: Integer): TObject; override;
  318. procedure Put(Index: Integer; const S: string); override;
  319. procedure PutObject(Index: Integer; AObject: TObject); override;
  320. procedure SetCapacity(NewCapacity: Integer); override;
  321. procedure SetUpdateState(Updating: Boolean); override;
  322. procedure InsertItem(Index: Integer; const S: string); virtual;
  323. procedure InsertItem(Index: Integer; const S: string; O: TObject); virtual;
  324. Function DoCompareText(const s1,s2 : string) : PtrInt; override;
  325. function CompareStrings(const s1,s2 : string) : Integer; virtual;
  326. public
  327. destructor Destroy; override;
  328. function Add(const S: string): Integer; override;
  329. procedure Clear; override;
  330. procedure Delete(Index: Integer); override;
  331. procedure Exchange(Index1, Index2: Integer); override;
  332. function Find(const S: string; Out Index: Integer): Boolean; virtual;
  333. function IndexOf(const S: string): Integer; override;
  334. procedure Insert(Index: Integer; const S: string); override;
  335. procedure Sort; virtual;
  336. procedure CustomSort(CompareFn: TStringListSortCompare); virtual;
  337. property Duplicates: TDuplicates read FDuplicates write FDuplicates;
  338. property Sorted: Boolean read GetSorted write SetSorted;
  339. property CaseSensitive: Boolean read FCaseSensitive write SetCaseSensitive;
  340. property OnChange: TNotifyEvent read FOnChange write FOnChange;
  341. property OnChanging: TNotifyEvent read FOnChanging write FOnChanging;
  342. property OwnsObjects : boolean read FOwnsObjects write FOwnsObjects;
  343. Property SortStyle : TStringsSortStyle Read FSortStyle Write SetSortStyle;
  344. end;
  345. TCollection = class;
  346. { TCollectionItem }
  347. TCollectionItem = class(TPersistent)
  348. private
  349. FCollection: TCollection;
  350. FID: Integer;
  351. FUpdateCount: Integer;
  352. function GetIndex: Integer;
  353. protected
  354. procedure SetCollection(Value: TCollection);virtual;
  355. procedure Changed(AllItems: Boolean);
  356. function GetOwner: TPersistent; override;
  357. function GetDisplayName: string; virtual;
  358. procedure SetIndex(Value: Integer); virtual;
  359. procedure SetDisplayName(const Value: string); virtual;
  360. property UpdateCount: Integer read FUpdateCount;
  361. public
  362. constructor Create(ACollection: TCollection); virtual; reintroduce;
  363. destructor Destroy; override;
  364. function GetNamePath: string; override;
  365. property Collection: TCollection read FCollection write SetCollection;
  366. property ID: Integer read FID;
  367. property Index: Integer read GetIndex write SetIndex;
  368. property DisplayName: string read GetDisplayName write SetDisplayName;
  369. end;
  370. TCollectionEnumerator = class
  371. private
  372. FCollection: TCollection;
  373. FPosition: Integer;
  374. public
  375. constructor Create(ACollection: TCollection); reintroduce;
  376. function GetCurrent: TCollectionItem;
  377. function MoveNext: Boolean;
  378. property Current: TCollectionItem read GetCurrent;
  379. end;
  380. TCollectionItemClass = class of TCollectionItem;
  381. TCollectionNotification = (cnAdded, cnExtracting, cnDeleting);
  382. TCollectionSortCompare = function (Item1, Item2: TCollectionItem): Integer;
  383. TCollection = class(TPersistent)
  384. private
  385. FItemClass: TCollectionItemClass;
  386. FItems: TFpList;
  387. FUpdateCount: Integer;
  388. FNextID: Integer;
  389. FPropName: string;
  390. function GetCount: Integer;
  391. function GetPropName: string;
  392. procedure InsertItem(Item: TCollectionItem);
  393. procedure RemoveItem(Item: TCollectionItem);
  394. procedure DoClear;
  395. protected
  396. { Design-time editor support }
  397. function GetAttrCount: Integer; virtual;
  398. function GetAttr(Index: Integer): string; virtual;
  399. function GetItemAttr(Index, ItemIndex: Integer): string; virtual;
  400. procedure Changed;
  401. function GetItem(Index: Integer): TCollectionItem;
  402. procedure SetItem(Index: Integer; Value: TCollectionItem);
  403. procedure SetItemName(Item: TCollectionItem); virtual;
  404. procedure SetPropName; virtual;
  405. procedure Update(Item: TCollectionItem); virtual;
  406. procedure Notify(Item: TCollectionItem;Action: TCollectionNotification); virtual;
  407. property PropName: string read GetPropName write FPropName;
  408. property UpdateCount: Integer read FUpdateCount;
  409. public
  410. constructor Create(AItemClass: TCollectionItemClass); reintroduce;
  411. destructor Destroy; override;
  412. function Owner: TPersistent;
  413. function Add: TCollectionItem;
  414. procedure Assign(Source: TPersistent); override;
  415. procedure BeginUpdate; virtual;
  416. procedure Clear;
  417. procedure EndUpdate; virtual;
  418. procedure Delete(Index: Integer);
  419. function GetEnumerator: TCollectionEnumerator;
  420. function GetNamePath: string; override;
  421. function Insert(Index: Integer): TCollectionItem;
  422. function FindItemID(ID: Integer): TCollectionItem;
  423. procedure Exchange(Const Index1, index2: integer);
  424. procedure Sort(Const Compare : TCollectionSortCompare);
  425. property Count: Integer read GetCount;
  426. property ItemClass: TCollectionItemClass read FItemClass;
  427. property Items[Index: Integer]: TCollectionItem read GetItem write SetItem;
  428. end;
  429. TOwnedCollection = class(TCollection)
  430. private
  431. FOwner: TPersistent;
  432. protected
  433. Function GetOwner: TPersistent; override;
  434. public
  435. Constructor Create(AOwner: TPersistent; AItemClass: TCollectionItemClass); reintroduce;
  436. end;
  437. TComponent = Class;
  438. TOperation = (opInsert, opRemove);
  439. TComponentStateItem = ( csLoading, csReading, csWriting, csDestroying,
  440. csDesigning, csAncestor, csUpdating, csFixups, csFreeNotification,
  441. csInline, csDesignInstance);
  442. TComponentState = set of TComponentStateItem;
  443. TComponentStyleItem = (csInheritable, csCheckPropAvail, csSubComponent, csTransient);
  444. TComponentStyle = set of TComponentStyleItem;
  445. TGetChildProc = procedure (Child: TComponent) of object;
  446. TComponentName = string;
  447. { TComponentEnumerator }
  448. TComponentEnumerator = class
  449. private
  450. FComponent: TComponent;
  451. FPosition: Integer;
  452. public
  453. constructor Create(AComponent: TComponent);
  454. function GetCurrent: TComponent;
  455. function MoveNext: Boolean;
  456. property Current: TComponent read GetCurrent;
  457. end;
  458. TComponent = class(TPersistent)
  459. private
  460. FOwner: TComponent;
  461. FName: TComponentName;
  462. FTag: Ptrint;
  463. FComponents: TFpList;
  464. FFreeNotifies: TFpList;
  465. FDesignInfo: Longint;
  466. FComponentState: TComponentState;
  467. function GetComponent(AIndex: Integer): TComponent;
  468. function GetComponentCount: Integer;
  469. function GetComponentIndex: Integer;
  470. procedure Insert(AComponent: TComponent);
  471. procedure Remove(AComponent: TComponent);
  472. procedure RemoveNotification(AComponent: TComponent);
  473. procedure SetComponentIndex(Value: Integer);
  474. protected
  475. FComponentStyle: TComponentStyle;
  476. procedure ChangeName(const NewName: TComponentName);
  477. procedure GetChildren(Proc: TGetChildProc; Root: TComponent); virtual;
  478. function GetChildOwner: TComponent; virtual;
  479. function GetChildParent: TComponent; virtual;
  480. function GetOwner: TPersistent; override;
  481. procedure Loaded; virtual;
  482. procedure Loading; virtual;
  483. procedure Notification(AComponent: TComponent; Operation: TOperation); virtual;
  484. procedure PaletteCreated; virtual;
  485. procedure SetAncestor(Value: Boolean);
  486. procedure SetDesigning(Value: Boolean; SetChildren : Boolean = True);
  487. procedure SetDesignInstance(Value: Boolean);
  488. procedure SetInline(Value: Boolean);
  489. procedure SetName(const NewName: TComponentName); virtual;
  490. procedure SetChildOrder(Child: TComponent; Order: Integer); virtual;
  491. procedure SetParentComponent(Value: TComponent); virtual;
  492. procedure Updating; virtual;
  493. procedure Updated; virtual;
  494. procedure ValidateRename(AComponent: TComponent; const CurName, NewName: string); virtual;
  495. procedure ValidateContainer(AComponent: TComponent); virtual;
  496. procedure ValidateInsert(AComponent: TComponent); virtual;
  497. public
  498. constructor Create(AOwner: TComponent); virtual; reintroduce;
  499. destructor Destroy; override;
  500. procedure BeforeDestruction; override;
  501. procedure DestroyComponents;
  502. procedure Destroying;
  503. // function ExecuteAction(Action: TBasicAction): Boolean; virtual;
  504. function FindComponent(const AName: string): TComponent;
  505. procedure FreeNotification(AComponent: TComponent);
  506. procedure RemoveFreeNotification(AComponent: TComponent);
  507. function GetNamePath: string; override;
  508. function GetParentComponent: TComponent; virtual;
  509. function HasParent: Boolean; virtual;
  510. procedure InsertComponent(AComponent: TComponent);
  511. procedure RemoveComponent(AComponent: TComponent);
  512. procedure SetSubComponent(ASubComponent: Boolean);
  513. function GetEnumerator: TComponentEnumerator;
  514. // function UpdateAction(Action: TBasicAction): Boolean; dynamic;
  515. property Components[Index: Integer]: TComponent read GetComponent;
  516. property ComponentCount: Integer read GetComponentCount;
  517. property ComponentIndex: Integer read GetComponentIndex write SetComponentIndex;
  518. property ComponentState: TComponentState read FComponentState;
  519. property ComponentStyle: TComponentStyle read FComponentStyle;
  520. property DesignInfo: Longint read FDesignInfo write FDesignInfo;
  521. property Owner: TComponent read FOwner;
  522. published
  523. property Name: TComponentName read FName write SetName stored False;
  524. property Tag: PtrInt read FTag write FTag {default 0};
  525. end;
  526. Procedure RegisterClass(AClass : TPersistentClass);
  527. Function GetClass(AClassName : string) : TPersistentClass;
  528. implementation
  529. uses JS;
  530. { TComponentEnumerator }
  531. constructor TComponentEnumerator.Create(AComponent: TComponent);
  532. begin
  533. inherited Create;
  534. FComponent := AComponent;
  535. FPosition := -1;
  536. end;
  537. function TComponentEnumerator.GetCurrent: TComponent;
  538. begin
  539. Result := FComponent.Components[FPosition];
  540. end;
  541. function TComponentEnumerator.MoveNext: Boolean;
  542. begin
  543. Inc(FPosition);
  544. Result := FPosition < FComponent.ComponentCount;
  545. end;
  546. { TListEnumerator }
  547. constructor TListEnumerator.Create(AList: TList);
  548. begin
  549. inherited Create;
  550. FList := AList;
  551. FPosition := -1;
  552. end;
  553. function TListEnumerator.GetCurrent: JSValue;
  554. begin
  555. Result := FList[FPosition];
  556. end;
  557. function TListEnumerator.MoveNext: Boolean;
  558. begin
  559. Inc(FPosition);
  560. Result := FPosition < FList.Count;
  561. end;
  562. { TFPListEnumerator }
  563. constructor TFPListEnumerator.Create(AList: TFPList);
  564. begin
  565. inherited Create;
  566. FList := AList;
  567. FPosition := -1;
  568. end;
  569. function TFPListEnumerator.GetCurrent: JSValue;
  570. begin
  571. Result := FList[FPosition];
  572. end;
  573. function TFPListEnumerator.MoveNext: Boolean;
  574. begin
  575. Inc(FPosition);
  576. Result := FPosition < FList.Count;
  577. end;
  578. { TFPList }
  579. procedure TFPList.CopyMove(aList: TFPList);
  580. var r : integer;
  581. begin
  582. Clear;
  583. for r := 0 to aList.count-1 do
  584. Add(aList[r]);
  585. end;
  586. procedure TFPList.MergeMove(aList: TFPList);
  587. var r : integer;
  588. begin
  589. For r := 0 to aList.count-1 do
  590. if IndexOf(aList[r]) < 0 then
  591. Add(aList[r]);
  592. end;
  593. procedure TFPList.DoCopy(ListA, ListB: TFPList);
  594. begin
  595. if Assigned(ListB) then
  596. CopyMove(ListB)
  597. else
  598. CopyMove(ListA);
  599. end;
  600. procedure TFPList.DoSrcUnique(ListA, ListB: TFPList);
  601. var r : integer;
  602. begin
  603. if Assigned(ListB) then
  604. begin
  605. Clear;
  606. for r := 0 to ListA.Count-1 do
  607. if ListB.IndexOf(ListA[r]) < 0 then
  608. Add(ListA[r]);
  609. end
  610. else
  611. begin
  612. for r := Count-1 downto 0 do
  613. if ListA.IndexOf(Self[r]) >= 0 then
  614. Delete(r);
  615. end;
  616. end;
  617. procedure TFPList.DoAnd(ListA, ListB: TFPList);
  618. var r : integer;
  619. begin
  620. if Assigned(ListB) then
  621. begin
  622. Clear;
  623. for r := 0 to ListA.count-1 do
  624. if ListB.IndexOf(ListA[r]) >= 0 then
  625. Add(ListA[r]);
  626. end
  627. else
  628. begin
  629. for r := Count-1 downto 0 do
  630. if ListA.IndexOf(Self[r]) < 0 then
  631. Delete(r);
  632. end;
  633. end;
  634. procedure TFPList.DoDestUnique(ListA, ListB: TFPList);
  635. procedure MoveElements(Src, Dest: TFPList);
  636. var r : integer;
  637. begin
  638. Clear;
  639. for r := 0 to Src.count-1 do
  640. if Dest.IndexOf(Src[r]) < 0 then
  641. self.Add(Src[r]);
  642. end;
  643. var Dest : TFPList;
  644. begin
  645. if Assigned(ListB) then
  646. MoveElements(ListB, ListA)
  647. else
  648. Dest := TFPList.Create;
  649. try
  650. Dest.CopyMove(Self);
  651. MoveElements(ListA, Dest)
  652. finally
  653. Dest.Destroy;
  654. end;
  655. end;
  656. procedure TFPList.DoOr(ListA, ListB: TFPList);
  657. begin
  658. if Assigned(ListB) then
  659. begin
  660. CopyMove(ListA);
  661. MergeMove(ListB);
  662. end
  663. else
  664. MergeMove(ListA);
  665. end;
  666. procedure TFPList.DoXOr(ListA, ListB: TFPList);
  667. var
  668. r : integer;
  669. l : TFPList;
  670. begin
  671. if Assigned(ListB) then
  672. begin
  673. Clear;
  674. for r := 0 to ListA.Count-1 do
  675. if ListB.IndexOf(ListA[r]) < 0 then
  676. Add(ListA[r]);
  677. for r := 0 to ListB.Count-1 do
  678. if ListA.IndexOf(ListB[r]) < 0 then
  679. Add(ListB[r]);
  680. end
  681. else
  682. begin
  683. l := TFPList.Create;
  684. try
  685. l.CopyMove(Self);
  686. for r := Count-1 downto 0 do
  687. if listA.IndexOf(Self[r]) >= 0 then
  688. Delete(r);
  689. for r := 0 to ListA.Count-1 do
  690. if l.IndexOf(ListA[r]) < 0 then
  691. Add(ListA[r]);
  692. finally
  693. l.Destroy;
  694. end;
  695. end;
  696. end;
  697. function TFPList.Get(Index: Integer): JSValue;
  698. begin
  699. If (Index < 0) or (Index >= FCount) then
  700. RaiseIndexError(Index);
  701. Result:=FList[Index];
  702. end;
  703. procedure TFPList.Put(Index: Integer; Item: JSValue);
  704. begin
  705. if (Index < 0) or (Index >= FCount) then
  706. RaiseIndexError(Index);
  707. FList[Index] := Item;
  708. end;
  709. procedure TFPList.SetCapacity(NewCapacity: Integer);
  710. begin
  711. If (NewCapacity < FCount) then
  712. Error (SListCapacityError, str(NewCapacity));
  713. if NewCapacity = FCapacity then
  714. exit;
  715. SetLength(FList,NewCapacity);
  716. FCapacity := NewCapacity;
  717. end;
  718. procedure TFPList.SetCount(NewCount: Integer);
  719. begin
  720. if (NewCount < 0) then
  721. Error(SListCountError, str(NewCount));
  722. If NewCount > FCount then
  723. begin
  724. If NewCount > FCapacity then
  725. SetCapacity(NewCount);
  726. end;
  727. FCount := NewCount;
  728. end;
  729. procedure TFPList.RaiseIndexError(Index: Integer);
  730. begin
  731. Error(SListIndexError, str(Index));
  732. end;
  733. destructor TFPList.Destroy;
  734. begin
  735. Clear;
  736. inherited Destroy;
  737. end;
  738. procedure TFPList.AddList(AList: TFPList);
  739. Var
  740. I : Integer;
  741. begin
  742. If (Capacity<Count+AList.Count) then
  743. Capacity:=Count+AList.Count;
  744. For I:=0 to AList.Count-1 do
  745. Add(AList[i]);
  746. end;
  747. function TFPList.Add(Item: JSValue): Integer;
  748. begin
  749. if FCount = FCapacity then
  750. Expand;
  751. FList[FCount] := Item;
  752. Result := FCount;
  753. Inc(FCount);
  754. end;
  755. procedure TFPList.Clear;
  756. begin
  757. if Assigned(FList) then
  758. begin
  759. SetCount(0);
  760. SetCapacity(0);
  761. end;
  762. end;
  763. procedure TFPList.Delete(Index: Integer);
  764. begin
  765. If (Index<0) or (Index>=FCount) then
  766. Error (SListIndexError, str(Index));
  767. FCount := FCount-1;
  768. System.Delete(FList,Index,1);
  769. Dec(FCapacity);
  770. end;
  771. class procedure TFPList.Error(const Msg: string; const Data: String);
  772. begin
  773. Raise EListError.CreateFmt(Msg,[Data]);
  774. end;
  775. procedure TFPList.Exchange(Index1, Index2: Integer);
  776. var
  777. Temp : JSValue;
  778. begin
  779. If (Index1 >= FCount) or (Index1 < 0) then
  780. Error(SListIndexError, str(Index1));
  781. If (Index2 >= FCount) or (Index2 < 0) then
  782. Error(SListIndexError, str(Index2));
  783. Temp := FList[Index1];
  784. FList[Index1] := FList[Index2];
  785. FList[Index2] := Temp;
  786. end;
  787. function TFPList.Expand: TFPList;
  788. var
  789. IncSize : Integer;
  790. begin
  791. if FCount < FCapacity then exit(self);
  792. IncSize := 4;
  793. if FCapacity > 3 then IncSize := IncSize + 4;
  794. if FCapacity > 8 then IncSize := IncSize+8;
  795. if FCapacity > 127 then Inc(IncSize, FCapacity shr 2);
  796. SetCapacity(FCapacity + IncSize);
  797. Result := Self;
  798. end;
  799. function TFPList.Extract(Item: JSValue): JSValue;
  800. var
  801. i : Integer;
  802. begin
  803. i := IndexOf(Item);
  804. if i >= 0 then
  805. begin
  806. Result := Item;
  807. Delete(i);
  808. end
  809. else
  810. Result := nil;
  811. end;
  812. function TFPList.First: JSValue;
  813. begin
  814. If FCount = 0 then
  815. Result := Nil
  816. else
  817. Result := Items[0];
  818. end;
  819. function TFPList.GetEnumerator: TFPListEnumerator;
  820. begin
  821. Result:=TFPListEnumerator.Create(Self);
  822. end;
  823. function TFPList.IndexOf(Item: JSValue): Integer;
  824. Var
  825. C : Integer;
  826. begin
  827. Result:=0;
  828. C:=Count;
  829. while (Result<C) and (FList[Result]<>Item) do
  830. Inc(Result);
  831. If Result>=C then
  832. Result:=-1;
  833. end;
  834. function TFPList.IndexOfItem(Item: JSValue; Direction: TDirection): Integer;
  835. begin
  836. if Direction=fromBeginning then
  837. Result:=IndexOf(Item)
  838. else
  839. begin
  840. Result:=Count-1;
  841. while (Result >=0) and (Flist[Result]<>Item) do
  842. Result:=Result - 1;
  843. end;
  844. end;
  845. procedure TFPList.Insert(Index: Integer; Item: JSValue);
  846. begin
  847. if (Index < 0) or (Index > FCount )then
  848. Error(SlistIndexError, str(Index));
  849. TJSArray(FList).splice(Index, 0, Item);
  850. inc(FCapacity);
  851. inc(FCount);
  852. end;
  853. function TFPList.Last: JSValue;
  854. begin
  855. If FCount = 0 then
  856. Result := nil
  857. else
  858. Result := Items[FCount - 1];
  859. end;
  860. procedure TFPList.Move(CurIndex, NewIndex: Integer);
  861. var
  862. Temp: JSValue;
  863. begin
  864. if (CurIndex < 0) or (CurIndex > Count - 1) then
  865. Error(SListIndexError, str(CurIndex));
  866. if (NewIndex < 0) or (NewIndex > Count -1) then
  867. Error(SlistIndexError, str(NewIndex));
  868. if CurIndex=NewIndex then exit;
  869. Temp:=FList[CurIndex];
  870. // ToDo: use TJSArray.copyWithin if available
  871. TJSArray(FList).splice(CurIndex,1);
  872. TJSArray(FList).splice(NewIndex,0,Temp);
  873. end;
  874. procedure TFPList.Assign(ListA: TFPList; AOperator: TListAssignOp;
  875. ListB: TFPList);
  876. begin
  877. case AOperator of
  878. laCopy : DoCopy (ListA, ListB); // replace dest with src
  879. laSrcUnique : DoSrcUnique (ListA, ListB); // replace dest with src that are not in dest
  880. laAnd : DoAnd (ListA, ListB); // remove from dest that are not in src
  881. laDestUnique: DoDestUnique (ListA, ListB);// remove from dest that are in src
  882. laOr : DoOr (ListA, ListB); // add to dest from src and not in dest
  883. laXOr : DoXOr (ListA, ListB); // add to dest from src and not in dest, remove from dest that are in src
  884. end;
  885. end;
  886. function TFPList.Remove(Item: JSValue): Integer;
  887. begin
  888. Result := IndexOf(Item);
  889. If Result <> -1 then
  890. Delete(Result);
  891. end;
  892. procedure TFPList.Pack;
  893. var
  894. Dst, i: Integer;
  895. V: JSValue;
  896. begin
  897. Dst:=0;
  898. for i:=0 to Count-1 do
  899. begin
  900. V:=FList[i];
  901. if not Assigned(V) then continue;
  902. FList[Dst]:=V;
  903. inc(Dst);
  904. end;
  905. end;
  906. // Needed by Sort method.
  907. Procedure QuickSort(aList: TJSValueDynArray; L, R : Longint;
  908. const Compare: TListSortCompare);
  909. var
  910. I, J : Longint;
  911. P, Q : JSValue;
  912. begin
  913. repeat
  914. I := L;
  915. J := R;
  916. P := aList[ (L + R) div 2 ];
  917. repeat
  918. while Compare(P, aList[i]) > 0 do
  919. I := I + 1;
  920. while Compare(P, aList[J]) < 0 do
  921. J := J - 1;
  922. If I <= J then
  923. begin
  924. Q := aList[I];
  925. aList[I] := aList[J];
  926. aList[J] := Q;
  927. I := I + 1;
  928. J := J - 1;
  929. end;
  930. until I > J;
  931. // sort the smaller range recursively
  932. // sort the bigger range via the loop
  933. // Reasons: memory usage is O(log(n)) instead of O(n) and loop is faster than recursion
  934. if J - L < R - I then
  935. begin
  936. if L < J then
  937. QuickSort(aList, L, J, Compare);
  938. L := I;
  939. end
  940. else
  941. begin
  942. if I < R then
  943. QuickSort(aList, I, R, Compare);
  944. R := J;
  945. end;
  946. until L >= R;
  947. end;
  948. procedure TFPList.Sort(const Compare: TListSortCompare);
  949. begin
  950. if Not Assigned(FList) or (FCount < 2) then exit;
  951. QuickSort(Flist, 0, FCount-1, Compare);
  952. end;
  953. procedure TFPList.ForEachCall(const proc2call: TListCallback; const arg: JSValue
  954. );
  955. var
  956. i : integer;
  957. v : JSValue;
  958. begin
  959. For I:=0 To Count-1 Do
  960. begin
  961. v:=FList[i];
  962. if Assigned(v) then
  963. proc2call(v,arg);
  964. end;
  965. end;
  966. procedure TFPList.ForEachCall(const proc2call: TListStaticCallback;
  967. const arg: JSValue);
  968. var
  969. i : integer;
  970. v : JSValue;
  971. begin
  972. For I:=0 To Count-1 Do
  973. begin
  974. v:=FList[i];
  975. if Assigned(v) then
  976. proc2call(v,arg);
  977. end;
  978. end;
  979. { TList }
  980. procedure TList.CopyMove(aList: TList);
  981. var
  982. r : integer;
  983. begin
  984. Clear;
  985. for r := 0 to aList.count-1 do
  986. Add(aList[r]);
  987. end;
  988. procedure TList.MergeMove(aList: TList);
  989. var r : integer;
  990. begin
  991. For r := 0 to aList.count-1 do
  992. if IndexOf(aList[r]) < 0 then
  993. Add(aList[r]);
  994. end;
  995. procedure TList.DoCopy(ListA, ListB: TList);
  996. begin
  997. if Assigned(ListB) then
  998. CopyMove(ListB)
  999. else
  1000. CopyMove(ListA);
  1001. end;
  1002. procedure TList.DoSrcUnique(ListA, ListB: TList);
  1003. var r : integer;
  1004. begin
  1005. if Assigned(ListB) then
  1006. begin
  1007. Clear;
  1008. for r := 0 to ListA.Count-1 do
  1009. if ListB.IndexOf(ListA[r]) < 0 then
  1010. Add(ListA[r]);
  1011. end
  1012. else
  1013. begin
  1014. for r := Count-1 downto 0 do
  1015. if ListA.IndexOf(Self[r]) >= 0 then
  1016. Delete(r);
  1017. end;
  1018. end;
  1019. procedure TList.DoAnd(ListA, ListB: TList);
  1020. var r : integer;
  1021. begin
  1022. if Assigned(ListB) then
  1023. begin
  1024. Clear;
  1025. for r := 0 to ListA.Count-1 do
  1026. if ListB.IndexOf(ListA[r]) >= 0 then
  1027. Add(ListA[r]);
  1028. end
  1029. else
  1030. begin
  1031. for r := Count-1 downto 0 do
  1032. if ListA.IndexOf(Self[r]) < 0 then
  1033. Delete(r);
  1034. end;
  1035. end;
  1036. procedure TList.DoDestUnique(ListA, ListB: TList);
  1037. procedure MoveElements(Src, Dest : TList);
  1038. var r : integer;
  1039. begin
  1040. Clear;
  1041. for r := 0 to Src.Count-1 do
  1042. if Dest.IndexOf(Src[r]) < 0 then
  1043. Add(Src[r]);
  1044. end;
  1045. var Dest : TList;
  1046. begin
  1047. if Assigned(ListB) then
  1048. MoveElements(ListB, ListA)
  1049. else
  1050. try
  1051. Dest := TList.Create;
  1052. Dest.CopyMove(Self);
  1053. MoveElements(ListA, Dest)
  1054. finally
  1055. Dest.Destroy;
  1056. end;
  1057. end;
  1058. procedure TList.DoOr(ListA, ListB: TList);
  1059. begin
  1060. if Assigned(ListB) then
  1061. begin
  1062. CopyMove(ListA);
  1063. MergeMove(ListB);
  1064. end
  1065. else
  1066. MergeMove(ListA);
  1067. end;
  1068. procedure TList.DoXOr(ListA, ListB: TList);
  1069. var
  1070. r : integer;
  1071. l : TList;
  1072. begin
  1073. if Assigned(ListB) then
  1074. begin
  1075. Clear;
  1076. for r := 0 to ListA.Count-1 do
  1077. if ListB.IndexOf(ListA[r]) < 0 then
  1078. Add(ListA[r]);
  1079. for r := 0 to ListB.Count-1 do
  1080. if ListA.IndexOf(ListB[r]) < 0 then
  1081. Add(ListB[r]);
  1082. end
  1083. else
  1084. try
  1085. l := TList.Create;
  1086. l.CopyMove (Self);
  1087. for r := Count-1 downto 0 do
  1088. if listA.IndexOf(Self[r]) >= 0 then
  1089. Delete(r);
  1090. for r := 0 to ListA.Count-1 do
  1091. if l.IndexOf(ListA[r]) < 0 then
  1092. Add(ListA[r]);
  1093. finally
  1094. l.Destroy;
  1095. end;
  1096. end;
  1097. function TList.Get(Index: Integer): JSValue;
  1098. begin
  1099. Result := FList.Get(Index);
  1100. end;
  1101. procedure TList.Put(Index: Integer; Item: JSValue);
  1102. var V : JSValue;
  1103. begin
  1104. V := Get(Index);
  1105. FList.Put(Index, Item);
  1106. if Assigned(V) then
  1107. Notify(V, lnDeleted);
  1108. if Assigned(Item) then
  1109. Notify(Item, lnAdded);
  1110. end;
  1111. procedure TList.Notify(aValue: JSValue; Action: TListNotification);
  1112. begin
  1113. if Assigned(aValue) then ;
  1114. if Action=lnExtracted then ;
  1115. end;
  1116. procedure TList.SetCapacity(NewCapacity: Integer);
  1117. begin
  1118. FList.SetCapacity(NewCapacity);
  1119. end;
  1120. function TList.GetCapacity: integer;
  1121. begin
  1122. Result := FList.Capacity;
  1123. end;
  1124. procedure TList.SetCount(NewCount: Integer);
  1125. begin
  1126. if NewCount < FList.Count then
  1127. while FList.Count > NewCount do
  1128. Delete(FList.Count - 1)
  1129. else
  1130. FList.SetCount(NewCount);
  1131. end;
  1132. function TList.GetCount: integer;
  1133. begin
  1134. Result := FList.Count;
  1135. end;
  1136. function TList.GetList: TJSValueDynArray;
  1137. begin
  1138. Result := FList.List;
  1139. end;
  1140. constructor TList.Create;
  1141. begin
  1142. inherited Create;
  1143. FList := TFPList.Create;
  1144. end;
  1145. destructor TList.Destroy;
  1146. begin
  1147. if Assigned(FList) then
  1148. Clear;
  1149. FreeAndNil(FList);
  1150. end;
  1151. procedure TList.AddList(AList: TList);
  1152. var
  1153. I: Integer;
  1154. begin
  1155. { this only does FList.AddList(AList.FList), avoiding notifications }
  1156. FList.AddList(AList.FList);
  1157. { make lnAdded notifications }
  1158. for I := 0 to AList.Count - 1 do
  1159. if Assigned(AList[I]) then
  1160. Notify(AList[I], lnAdded);
  1161. end;
  1162. function TList.Add(Item: JSValue): Integer;
  1163. begin
  1164. Result := FList.Add(Item);
  1165. if Assigned(Item) then
  1166. Notify(Item, lnAdded);
  1167. end;
  1168. procedure TList.Clear;
  1169. begin
  1170. While (FList.Count>0) do
  1171. Delete(Count-1);
  1172. end;
  1173. procedure TList.Delete(Index: Integer);
  1174. var V : JSValue;
  1175. begin
  1176. V:=FList.Get(Index);
  1177. FList.Delete(Index);
  1178. if assigned(V) then
  1179. Notify(V, lnDeleted);
  1180. end;
  1181. class procedure TList.Error(const Msg: string; Data: String);
  1182. begin
  1183. Raise EListError.CreateFmt(Msg,[Data]);
  1184. end;
  1185. procedure TList.Exchange(Index1, Index2: Integer);
  1186. begin
  1187. FList.Exchange(Index1, Index2);
  1188. end;
  1189. function TList.Expand: TList;
  1190. begin
  1191. FList.Expand;
  1192. Result:=Self;
  1193. end;
  1194. function TList.Extract(Item: JSValue): JSValue;
  1195. var c : integer;
  1196. begin
  1197. c := FList.Count;
  1198. Result := FList.Extract(Item);
  1199. if c <> FList.Count then
  1200. Notify (Result, lnExtracted);
  1201. end;
  1202. function TList.First: JSValue;
  1203. begin
  1204. Result := FList.First;
  1205. end;
  1206. function TList.GetEnumerator: TListEnumerator;
  1207. begin
  1208. Result:=TListEnumerator.Create(Self);
  1209. end;
  1210. function TList.IndexOf(Item: JSValue): Integer;
  1211. begin
  1212. Result := FList.IndexOf(Item);
  1213. end;
  1214. procedure TList.Insert(Index: Integer; Item: JSValue);
  1215. begin
  1216. FList.Insert(Index, Item);
  1217. if Assigned(Item) then
  1218. Notify(Item,lnAdded);
  1219. end;
  1220. function TList.Last: JSValue;
  1221. begin
  1222. Result := FList.Last;
  1223. end;
  1224. procedure TList.Move(CurIndex, NewIndex: Integer);
  1225. begin
  1226. FList.Move(CurIndex, NewIndex);
  1227. end;
  1228. procedure TList.Assign(ListA: TList; AOperator: TListAssignOp; ListB: TList);
  1229. begin
  1230. case AOperator of
  1231. laCopy : DoCopy (ListA, ListB); // replace dest with src
  1232. laSrcUnique : DoSrcUnique (ListA, ListB); // replace dest with src that are not in dest
  1233. laAnd : DoAnd (ListA, ListB); // remove from dest that are not in src
  1234. laDestUnique: DoDestUnique (ListA, ListB);// remove from dest that are in src
  1235. laOr : DoOr (ListA, ListB); // add to dest from src and not in dest
  1236. laXOr : DoXOr (ListA, ListB); // add to dest from src and not in dest, remove from dest that are in src
  1237. end;
  1238. end;
  1239. function TList.Remove(Item: JSValue): Integer;
  1240. begin
  1241. Result := IndexOf(Item);
  1242. if Result <> -1 then
  1243. Self.Delete(Result);
  1244. end;
  1245. procedure TList.Pack;
  1246. begin
  1247. FList.Pack;
  1248. end;
  1249. procedure TList.Sort(const Compare: TListSortCompare);
  1250. begin
  1251. FList.Sort(Compare);
  1252. end;
  1253. { TPersistent }
  1254. procedure TPersistent.AssignError(Source: TPersistent);
  1255. var
  1256. SourceName: String;
  1257. begin
  1258. if Source<>Nil then
  1259. SourceName:=Source.ClassName
  1260. else
  1261. SourceName:='Nil';
  1262. raise EConvertError.Create('Cannot assign a '+SourceName+' to a '+ClassName+'.');
  1263. end;
  1264. procedure TPersistent.AssignTo(Dest: TPersistent);
  1265. begin
  1266. Dest.AssignError(Self);
  1267. end;
  1268. function TPersistent.GetOwner: TPersistent;
  1269. begin
  1270. Result:=nil;
  1271. end;
  1272. procedure TPersistent.Assign(Source: TPersistent);
  1273. begin
  1274. If Source<>Nil then
  1275. Source.AssignTo(Self)
  1276. else
  1277. AssignError(Nil);
  1278. end;
  1279. function TPersistent.GetNamePath: string;
  1280. var
  1281. OwnerName: String;
  1282. TheOwner: TPersistent;
  1283. begin
  1284. Result:=ClassName;
  1285. TheOwner:=GetOwner;
  1286. if TheOwner<>Nil then
  1287. begin
  1288. OwnerName:=TheOwner.GetNamePath;
  1289. if OwnerName<>'' then Result:=OwnerName+'.'+Result;
  1290. end;
  1291. end;
  1292. {
  1293. This file is part of the Free Component Library (FCL)
  1294. Copyright (c) 1999-2000 by the Free Pascal development team
  1295. See the file COPYING.FPC, included in this distribution,
  1296. for details about the copyright.
  1297. This program is distributed in the hope that it will be useful,
  1298. but WITHOUT ANY WARRANTY; without even the implied warranty of
  1299. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  1300. **********************************************************************}
  1301. {****************************************************************************}
  1302. {* TStringsEnumerator *}
  1303. {****************************************************************************}
  1304. constructor TStringsEnumerator.Create(AStrings: TStrings);
  1305. begin
  1306. inherited Create;
  1307. FStrings := AStrings;
  1308. FPosition := -1;
  1309. end;
  1310. function TStringsEnumerator.GetCurrent: String;
  1311. begin
  1312. Result := FStrings[FPosition];
  1313. end;
  1314. function TStringsEnumerator.MoveNext: Boolean;
  1315. begin
  1316. Inc(FPosition);
  1317. Result := FPosition < FStrings.Count;
  1318. end;
  1319. {****************************************************************************}
  1320. {* TStrings *}
  1321. {****************************************************************************}
  1322. // Function to quote text. Should move maybe to sysutils !!
  1323. // Also, it is not clear at this point what exactly should be done.
  1324. { //!! is used to mark unsupported things. }
  1325. (*
  1326. Function QuoteString (Const S : String; Const Quote : String) : String;
  1327. Var
  1328. I,J : Integer;
  1329. begin
  1330. J:=0;
  1331. Result:=S;
  1332. for i:=1 to length(s) do
  1333. begin
  1334. inc(j);
  1335. if S[i]=Quote then
  1336. begin
  1337. Insert(Quote,Result,J);
  1338. inc(j);
  1339. end;
  1340. end;
  1341. Result:=Quote+Result+Quote;
  1342. end;
  1343. *)
  1344. {
  1345. For compatibility we can't add a Constructor to TSTrings to initialize
  1346. the special characters. Therefore we add a routine which is called whenever
  1347. the special chars are needed.
  1348. }
  1349. Procedure Tstrings.CheckSpecialChars;
  1350. begin
  1351. If Not FSpecialCharsInited then
  1352. begin
  1353. FQuoteChar:='"';
  1354. FDelimiter:=',';
  1355. FNameValueSeparator:='=';
  1356. FLBS:=DefaultTextLineBreakStyle;
  1357. FSpecialCharsInited:=true;
  1358. FLineBreak:=sLineBreak;
  1359. end;
  1360. end;
  1361. Function TStrings.GetSkipLastLineBreak : Boolean;
  1362. begin
  1363. CheckSpecialChars;
  1364. Result:=FSkipLastLineBreak;
  1365. end;
  1366. procedure TStrings.SetSkipLastLineBreak(const AValue : Boolean);
  1367. begin
  1368. CheckSpecialChars;
  1369. FSkipLastLineBreak:=AValue;
  1370. end;
  1371. Function TStrings.GetLBS : TTextLineBreakStyle;
  1372. begin
  1373. CheckSpecialChars;
  1374. Result:=FLBS;
  1375. end;
  1376. Procedure TStrings.SetLBS (AValue : TTextLineBreakStyle);
  1377. begin
  1378. CheckSpecialChars;
  1379. FLBS:=AValue;
  1380. end;
  1381. procedure TStrings.SetDelimiter(c:Char);
  1382. begin
  1383. CheckSpecialChars;
  1384. FDelimiter:=c;
  1385. end;
  1386. Function TStrings.GetDelimiter : Char;
  1387. begin
  1388. CheckSpecialChars;
  1389. Result:=FDelimiter;
  1390. end;
  1391. procedure TStrings.SetLineBreak(Const S : String);
  1392. begin
  1393. CheckSpecialChars;
  1394. FLineBreak:=S;
  1395. end;
  1396. Function TStrings.GetLineBreak : String;
  1397. begin
  1398. CheckSpecialChars;
  1399. Result:=FLineBreak;
  1400. end;
  1401. procedure TStrings.SetQuoteChar(c:Char);
  1402. begin
  1403. CheckSpecialChars;
  1404. FQuoteChar:=c;
  1405. end;
  1406. Function TStrings.GetQuoteChar :Char;
  1407. begin
  1408. CheckSpecialChars;
  1409. Result:=FQuoteChar;
  1410. end;
  1411. procedure TStrings.SetNameValueSeparator(c:Char);
  1412. begin
  1413. CheckSpecialChars;
  1414. FNameValueSeparator:=c;
  1415. end;
  1416. Function TStrings.GetNameValueSeparator :Char;
  1417. begin
  1418. CheckSpecialChars;
  1419. Result:=FNameValueSeparator;
  1420. end;
  1421. function TStrings.GetCommaText: string;
  1422. Var
  1423. C1,C2 : Char;
  1424. FSD : Boolean;
  1425. begin
  1426. CheckSpecialChars;
  1427. FSD:=StrictDelimiter;
  1428. C1:=Delimiter;
  1429. C2:=QuoteChar;
  1430. Delimiter:=',';
  1431. QuoteChar:='"';
  1432. StrictDelimiter:=False;
  1433. Try
  1434. Result:=GetDelimitedText;
  1435. Finally
  1436. Delimiter:=C1;
  1437. QuoteChar:=C2;
  1438. StrictDelimiter:=FSD;
  1439. end;
  1440. end;
  1441. Function TStrings.GetDelimitedText: string;
  1442. Var
  1443. I: integer;
  1444. RE : string;
  1445. S : String;
  1446. doQuote : Boolean;
  1447. begin
  1448. CheckSpecialChars;
  1449. result:='';
  1450. RE:=QuoteChar+'|'+Delimiter;
  1451. if not StrictDelimiter then
  1452. RE:=' |'+RE;
  1453. RE:='/'+RE+'/';
  1454. // Check for break characters and quote if required.
  1455. For i:=0 to count-1 do
  1456. begin
  1457. S:=Strings[i];
  1458. doQuote:=FAlwaysQuote or (TJSString(s).search(RE)=-1);
  1459. if DoQuote then
  1460. Result:=Result+QuoteString(S,QuoteChar)
  1461. else
  1462. Result:=Result+S;
  1463. if I<Count-1 then
  1464. Result:=Result+Delimiter;
  1465. end;
  1466. // Quote empty string:
  1467. If (Length(Result)=0) and (Count=1) then
  1468. Result:=QuoteChar+QuoteChar;
  1469. end;
  1470. procedure TStrings.GetNameValue(Index : Integer; Out AName,AValue : String);
  1471. Var L : longint;
  1472. begin
  1473. CheckSpecialChars;
  1474. AValue:=Strings[Index];
  1475. L:=Pos(FNameValueSeparator,AValue);
  1476. If L<>0 then
  1477. begin
  1478. AName:=Copy(AValue,1,L-1);
  1479. // System.Delete(AValue,1,L);
  1480. AValue:=Copy(AValue,L+1,length(AValue)-L);
  1481. end
  1482. else
  1483. AName:='';
  1484. end;
  1485. function TStrings.ExtractName(const s:String):String;
  1486. var
  1487. L: Longint;
  1488. begin
  1489. CheckSpecialChars;
  1490. L:=Pos(FNameValueSeparator,S);
  1491. If L<>0 then
  1492. Result:=Copy(S,1,L-1)
  1493. else
  1494. Result:='';
  1495. end;
  1496. function TStrings.GetName(Index: Integer): string;
  1497. Var
  1498. V : String;
  1499. begin
  1500. GetNameValue(Index,Result,V);
  1501. end;
  1502. Function TStrings.GetValue(const Name: string): string;
  1503. Var
  1504. L : longint;
  1505. N : String;
  1506. begin
  1507. Result:='';
  1508. L:=IndexOfName(Name);
  1509. If L<>-1 then
  1510. GetNameValue(L,N,Result);
  1511. end;
  1512. Function TStrings.GetValueFromIndex(Index: Integer): string;
  1513. Var
  1514. N : String;
  1515. begin
  1516. GetNameValue(Index,N,Result);
  1517. end;
  1518. Procedure TStrings.SetValueFromIndex(Index: Integer; const Value: string);
  1519. begin
  1520. If (Value='') then
  1521. Delete(Index)
  1522. else
  1523. begin
  1524. If (Index<0) then
  1525. Index:=Add('');
  1526. CheckSpecialChars;
  1527. Strings[Index]:=GetName(Index)+FNameValueSeparator+Value;
  1528. end;
  1529. end;
  1530. Procedure TStrings.SetDelimitedText(const AValue: string);
  1531. var i,j:integer;
  1532. aNotFirst:boolean;
  1533. begin
  1534. CheckSpecialChars;
  1535. BeginUpdate;
  1536. i:=1;
  1537. j:=1;
  1538. aNotFirst:=false;
  1539. { Paraphrased from Delphi XE2 help:
  1540. Strings must be separated by Delimiter characters or spaces.
  1541. They may be enclosed in QuoteChars.
  1542. QuoteChars in the string must be repeated to distinguish them from the QuoteChars enclosing the string.
  1543. }
  1544. try
  1545. Clear;
  1546. If StrictDelimiter then
  1547. begin
  1548. while i<=length(AValue) do begin
  1549. // skip delimiter
  1550. if aNotFirst and (i<=length(AValue)) and (AValue[i]=FDelimiter) then inc(i);
  1551. // read next string
  1552. if i<=length(AValue) then begin
  1553. if AValue[i]=FQuoteChar then begin
  1554. // next string is quoted
  1555. j:=i+1;
  1556. while (j<=length(AValue)) and
  1557. ( (AValue[j]<>FQuoteChar) or
  1558. ( (j+1<=length(AValue)) and (AValue[j+1]=FQuoteChar) ) ) do begin
  1559. if (j<=length(AValue)) and (AValue[j]=FQuoteChar) then inc(j,2)
  1560. else inc(j);
  1561. end;
  1562. // j is position of closing quote
  1563. Add( StringReplace (Copy(AValue,i+1,j-i-1),
  1564. FQuoteChar+FQuoteChar,FQuoteChar, [rfReplaceAll]));
  1565. i:=j+1;
  1566. end else begin
  1567. // next string is not quoted; read until delimiter
  1568. j:=i;
  1569. while (j<=length(AValue)) and
  1570. (AValue[j]<>FDelimiter) do inc(j);
  1571. Add( Copy(AValue,i,j-i));
  1572. i:=j;
  1573. end;
  1574. end else begin
  1575. if aNotFirst then Add('');
  1576. end;
  1577. aNotFirst:=true;
  1578. end;
  1579. end
  1580. else
  1581. begin
  1582. while i<=length(AValue) do begin
  1583. // skip delimiter
  1584. if aNotFirst and (i<=length(AValue)) and (AValue[i]=FDelimiter) then inc(i);
  1585. // skip spaces
  1586. while (i<=length(AValue)) and (Ord(AValue[i])<=Ord(' ')) do inc(i);
  1587. // read next string
  1588. if i<=length(AValue) then begin
  1589. if AValue[i]=FQuoteChar then begin
  1590. // next string is quoted
  1591. j:=i+1;
  1592. while (j<=length(AValue)) and
  1593. ( (AValue[j]<>FQuoteChar) or
  1594. ( (j+1<=length(AValue)) and (AValue[j+1]=FQuoteChar) ) ) do begin
  1595. if (j<=length(AValue)) and (AValue[j]=FQuoteChar) then inc(j,2)
  1596. else inc(j);
  1597. end;
  1598. // j is position of closing quote
  1599. Add( StringReplace (Copy(AValue,i+1,j-i-1),
  1600. FQuoteChar+FQuoteChar,FQuoteChar, [rfReplaceAll]));
  1601. i:=j+1;
  1602. end else begin
  1603. // next string is not quoted; read until control character/space/delimiter
  1604. j:=i;
  1605. while (j<=length(AValue)) and
  1606. (Ord(AValue[j])>Ord(' ')) and
  1607. (AValue[j]<>FDelimiter) do inc(j);
  1608. Add( Copy(AValue,i,j-i));
  1609. i:=j;
  1610. end;
  1611. end else begin
  1612. if aNotFirst then Add('');
  1613. end;
  1614. // skip spaces
  1615. while (i<=length(AValue)) and (Ord(AValue[i])<=Ord(' ')) do inc(i);
  1616. aNotFirst:=true;
  1617. end;
  1618. end;
  1619. finally
  1620. EndUpdate;
  1621. end;
  1622. end;
  1623. Procedure TStrings.SetCommaText(const Value: string);
  1624. Var
  1625. C1,C2 : Char;
  1626. begin
  1627. CheckSpecialChars;
  1628. C1:=Delimiter;
  1629. C2:=QuoteChar;
  1630. Delimiter:=',';
  1631. QuoteChar:='"';
  1632. Try
  1633. SetDelimitedText(Value);
  1634. Finally
  1635. Delimiter:=C1;
  1636. QuoteChar:=C2;
  1637. end;
  1638. end;
  1639. Procedure TStrings.SetValue(const Name, Value: string);
  1640. Var L : longint;
  1641. begin
  1642. CheckSpecialChars;
  1643. L:=IndexOfName(Name);
  1644. if L=-1 then
  1645. Add (Name+FNameValueSeparator+Value)
  1646. else
  1647. Strings[L]:=Name+FNameValueSeparator+value;
  1648. end;
  1649. Procedure TStrings.Error(const Msg: string; Data: Integer);
  1650. begin
  1651. Raise EStringListError.CreateFmt(Msg,[IntToStr(Data)]);
  1652. end;
  1653. Function TStrings.GetCapacity: Integer;
  1654. begin
  1655. Result:=Count;
  1656. end;
  1657. Function TStrings.GetObject(Index: Integer): TObject;
  1658. begin
  1659. if Index=0 then ;
  1660. Result:=Nil;
  1661. end;
  1662. Function TStrings.GetTextStr: string;
  1663. Var
  1664. I : Longint;
  1665. S,NL : String;
  1666. begin
  1667. CheckSpecialChars;
  1668. // Determine needed place
  1669. if FLineBreak<>sLineBreak then
  1670. NL:=FLineBreak
  1671. else
  1672. Case FLBS of
  1673. tlbsLF : NL:=#10;
  1674. tlbsCRLF : NL:=#13#10;
  1675. tlbsCR : NL:=#13;
  1676. end;
  1677. Result:='';
  1678. For i:=0 To count-1 do
  1679. begin
  1680. S:=Strings[I];
  1681. Result:=Result+S;
  1682. if (I<Count-1) or Not SkipLastLineBreak then
  1683. Result:=Result+NL;
  1684. end;
  1685. end;
  1686. Procedure TStrings.Put(Index: Integer; const S: string);
  1687. Var Obj : TObject;
  1688. begin
  1689. Obj:=Objects[Index];
  1690. Delete(Index);
  1691. InsertObject(Index,S,Obj);
  1692. end;
  1693. Procedure TStrings.PutObject(Index: Integer; AObject: TObject);
  1694. begin
  1695. // Empty.
  1696. if Index=0 then exit;
  1697. if AObject=nil then exit;
  1698. end;
  1699. Procedure TStrings.SetCapacity(NewCapacity: Integer);
  1700. begin
  1701. // Empty.
  1702. if NewCapacity=0 then ;
  1703. end;
  1704. Function TStrings.GetNextLineBreak (Const Value : String; Out S : String; Var P : Integer) : Boolean;
  1705. Var
  1706. PP : Integer;
  1707. begin
  1708. S:='';
  1709. Result:=False;
  1710. If ((Length(Value)-P)<0) then
  1711. exit;
  1712. PP:=TJSString(Value).IndexOf(LineBreak,P-1)+1;
  1713. if (PP<1) then
  1714. PP:=Length(Value)+1;
  1715. S:=Copy(Value,P,PP-P);
  1716. P:=PP+length(LineBreak);
  1717. Result:=True;
  1718. end;
  1719. Procedure TStrings.DoSetTextStr(const Value: string; DoClear : Boolean);
  1720. Var
  1721. S : String;
  1722. P : Integer;
  1723. begin
  1724. Try
  1725. BeginUpdate;
  1726. if DoClear then
  1727. Clear;
  1728. P:=1;
  1729. While GetNextLineBreak (Value,S,P) do
  1730. Add(S);
  1731. finally
  1732. EndUpdate;
  1733. end;
  1734. end;
  1735. Procedure TStrings.SetTextStr(const Value: string);
  1736. begin
  1737. CheckSpecialChars;
  1738. DoSetTextStr(Value,True);
  1739. end;
  1740. Procedure TStrings.AddText(const S: string);
  1741. begin
  1742. CheckSpecialChars;
  1743. DoSetTextStr(S,False);
  1744. end;
  1745. Procedure TStrings.SetUpdateState(Updating: Boolean);
  1746. begin
  1747. // FPONotifyObservers(Self,ooChange,Nil);
  1748. if Updating then ;
  1749. end;
  1750. destructor TSTrings.Destroy;
  1751. begin
  1752. inherited destroy;
  1753. end;
  1754. constructor TStrings.Create;
  1755. begin
  1756. inherited Create;
  1757. FAlwaysQuote:=False;
  1758. end;
  1759. Function TStrings.Add(const S: string): Integer;
  1760. begin
  1761. Result:=Count;
  1762. Insert (Count,S);
  1763. end;
  1764. (*
  1765. function TStrings.AddFmt(const Fmt : string; const Args : Array of const): Integer;
  1766. begin
  1767. Result:=Add(Format(Fmt,Args));
  1768. end;
  1769. *)
  1770. Function TStrings.AddObject(const S: string; AObject: TObject): Integer;
  1771. begin
  1772. Result:=Add(S);
  1773. Objects[result]:=AObject;
  1774. end;
  1775. (*
  1776. function TStrings.AddObject(const Fmt: string; Args : Array of const; AObject: TObject): Integer;
  1777. begin
  1778. Result:=AddObject(Format(Fmt,Args),AObject);
  1779. end;
  1780. *)
  1781. Procedure TStrings.Append(const S: string);
  1782. begin
  1783. Add (S);
  1784. end;
  1785. Procedure TStrings.AddStrings(TheStrings: TStrings; ClearFirst : Boolean);
  1786. begin
  1787. beginupdate;
  1788. try
  1789. if ClearFirst then
  1790. Clear;
  1791. AddStrings(TheStrings);
  1792. finally
  1793. EndUpdate;
  1794. end;
  1795. end;
  1796. Procedure TStrings.AddStrings(TheStrings: TStrings);
  1797. Var Runner : longint;
  1798. begin
  1799. For Runner:=0 to TheStrings.Count-1 do
  1800. self.AddObject (Thestrings[Runner],TheStrings.Objects[Runner]);
  1801. end;
  1802. Procedure TStrings.AddStrings(const TheStrings: array of string);
  1803. Var Runner : longint;
  1804. begin
  1805. if Count + High(TheStrings)+1 > Capacity then
  1806. Capacity := Count + High(TheStrings)+1;
  1807. For Runner:=Low(TheStrings) to High(TheStrings) do
  1808. self.Add(Thestrings[Runner]);
  1809. end;
  1810. Procedure TStrings.AddStrings(const TheStrings: array of string; ClearFirst : Boolean);
  1811. begin
  1812. beginupdate;
  1813. try
  1814. if ClearFirst then
  1815. Clear;
  1816. AddStrings(TheStrings);
  1817. finally
  1818. EndUpdate;
  1819. end;
  1820. end;
  1821. Procedure TStrings.Assign(Source: TPersistent);
  1822. Var
  1823. S : TStrings;
  1824. begin
  1825. If Source is TStrings then
  1826. begin
  1827. S:=TStrings(Source);
  1828. BeginUpdate;
  1829. Try
  1830. clear;
  1831. FSpecialCharsInited:=S.FSpecialCharsInited;
  1832. FQuoteChar:=S.FQuoteChar;
  1833. FDelimiter:=S.FDelimiter;
  1834. FNameValueSeparator:=S.FNameValueSeparator;
  1835. FLBS:=S.FLBS;
  1836. FLineBreak:=S.FLineBreak;
  1837. AddStrings(S);
  1838. finally
  1839. EndUpdate;
  1840. end;
  1841. end
  1842. else
  1843. Inherited Assign(Source);
  1844. end;
  1845. Procedure TStrings.BeginUpdate;
  1846. begin
  1847. if FUpdateCount = 0 then SetUpdateState(true);
  1848. inc(FUpdateCount);
  1849. end;
  1850. Procedure TStrings.EndUpdate;
  1851. begin
  1852. If FUpdateCount>0 then
  1853. Dec(FUpdateCount);
  1854. if FUpdateCount=0 then
  1855. SetUpdateState(False);
  1856. end;
  1857. Function TStrings.Equals(Obj: TObject): Boolean;
  1858. begin
  1859. if Obj is TStrings then
  1860. Result := Equals(TStrings(Obj))
  1861. else
  1862. Result := inherited Equals(Obj);
  1863. end;
  1864. Function TStrings.Equals(TheStrings: TStrings): Boolean;
  1865. Var Runner,Nr : Longint;
  1866. begin
  1867. Result:=False;
  1868. Nr:=Self.Count;
  1869. if Nr<>TheStrings.Count then exit;
  1870. For Runner:=0 to Nr-1 do
  1871. If Strings[Runner]<>TheStrings[Runner] then exit;
  1872. Result:=True;
  1873. end;
  1874. Procedure TStrings.Exchange(Index1, Index2: Integer);
  1875. Var
  1876. Obj : TObject;
  1877. Str : String;
  1878. begin
  1879. beginUpdate;
  1880. Try
  1881. Obj:=Objects[Index1];
  1882. Str:=Strings[Index1];
  1883. Objects[Index1]:=Objects[Index2];
  1884. Strings[Index1]:=Strings[Index2];
  1885. Objects[Index2]:=Obj;
  1886. Strings[Index2]:=Str;
  1887. finally
  1888. EndUpdate;
  1889. end;
  1890. end;
  1891. function TStrings.GetEnumerator: TStringsEnumerator;
  1892. begin
  1893. Result:=TStringsEnumerator.Create(Self);
  1894. end;
  1895. Function TStrings.DoCompareText(const s1,s2 : string) : PtrInt;
  1896. begin
  1897. result:=CompareText(s1,s2);
  1898. end;
  1899. Function TStrings.IndexOf(const S: string): Integer;
  1900. begin
  1901. Result:=0;
  1902. While (Result<Count) and (DoCompareText(Strings[Result],S)<>0) do Result:=Result+1;
  1903. if Result=Count then Result:=-1;
  1904. end;
  1905. Function TStrings.IndexOfName(const Name: string): Integer;
  1906. Var
  1907. len : longint;
  1908. S : String;
  1909. begin
  1910. CheckSpecialChars;
  1911. Result:=0;
  1912. while (Result<Count) do
  1913. begin
  1914. S:=Strings[Result];
  1915. len:=pos(FNameValueSeparator,S)-1;
  1916. if (len>=0) and (DoCompareText(Name,Copy(S,1,Len))=0) then
  1917. exit;
  1918. inc(result);
  1919. end;
  1920. result:=-1;
  1921. end;
  1922. Function TStrings.IndexOfObject(AObject: TObject): Integer;
  1923. begin
  1924. Result:=0;
  1925. While (Result<count) and (Objects[Result]<>AObject) do Result:=Result+1;
  1926. If Result=Count then Result:=-1;
  1927. end;
  1928. Procedure TStrings.InsertObject(Index: Integer; const S: string;
  1929. AObject: TObject);
  1930. begin
  1931. Insert (Index,S);
  1932. Objects[Index]:=AObject;
  1933. end;
  1934. Procedure TStrings.Move(CurIndex, NewIndex: Integer);
  1935. Var
  1936. Obj : TObject;
  1937. Str : String;
  1938. begin
  1939. BeginUpdate;
  1940. Try
  1941. Obj:=Objects[CurIndex];
  1942. Str:=Strings[CurIndex];
  1943. Objects[CurIndex]:=Nil; // Prevent Delete from freeing.
  1944. Delete(Curindex);
  1945. InsertObject(NewIndex,Str,Obj);
  1946. finally
  1947. EndUpdate;
  1948. end;
  1949. end;
  1950. {****************************************************************************}
  1951. {* TStringList *}
  1952. {****************************************************************************}
  1953. procedure TStringList.ExchangeItemsInt(Index1, Index2: Integer);
  1954. Var
  1955. S : String;
  1956. O : TObject;
  1957. begin
  1958. S:=Flist[Index1].FString;
  1959. O:=Flist[Index1].FObject;
  1960. Flist[Index1].Fstring:=Flist[Index2].Fstring;
  1961. Flist[Index1].FObject:=Flist[Index2].FObject;
  1962. Flist[Index2].Fstring:=S;
  1963. Flist[Index2].FObject:=O;
  1964. end;
  1965. function TStringList.GetSorted: Boolean;
  1966. begin
  1967. Result:=FSortStyle in [sslUser,sslAuto];
  1968. end;
  1969. procedure TStringList.ExchangeItems(Index1, Index2: Integer);
  1970. begin
  1971. ExchangeItemsInt(Index1, Index2);
  1972. end;
  1973. procedure TStringList.Grow;
  1974. Var
  1975. NC : Integer;
  1976. begin
  1977. NC:=Capacity;
  1978. If NC>=256 then
  1979. NC:=NC+(NC Div 4)
  1980. else if NC=0 then
  1981. NC:=4
  1982. else
  1983. NC:=NC*4;
  1984. SetCapacity(NC);
  1985. end;
  1986. procedure TStringList.InternalClear(FromIndex: Integer; ClearOnly: Boolean);
  1987. Var
  1988. I: Integer;
  1989. begin
  1990. if FromIndex < FCount then
  1991. begin
  1992. if FOwnsObjects then
  1993. begin
  1994. For I:=FromIndex to FCount-1 do
  1995. begin
  1996. Flist[I].FString:='';
  1997. freeandnil(Flist[i].FObject);
  1998. end;
  1999. end
  2000. else
  2001. begin
  2002. For I:=FromIndex to FCount-1 do
  2003. Flist[I].FString:='';
  2004. end;
  2005. FCount:=FromIndex;
  2006. end;
  2007. if Not ClearOnly then
  2008. SetCapacity(0);
  2009. end;
  2010. procedure TStringList.QuickSort(L, R: Integer; CompareFn: TStringListSortCompare
  2011. );
  2012. var
  2013. Pivot, vL, vR: Integer;
  2014. begin
  2015. //if ExchangeItems is override call that, else call (faster) ExchangeItemsInt
  2016. if R - L <= 1 then begin // a little bit of time saver
  2017. if L < R then
  2018. if CompareFn(Self, L, R) > 0 then
  2019. ExchangeItems(L, R);
  2020. Exit;
  2021. end;
  2022. vL := L;
  2023. vR := R;
  2024. Pivot := L + Random(R - L); // they say random is best
  2025. while vL < vR do begin
  2026. while (vL < Pivot) and (CompareFn(Self, vL, Pivot) <= 0) do
  2027. Inc(vL);
  2028. while (vR > Pivot) and (CompareFn(Self, vR, Pivot) > 0) do
  2029. Dec(vR);
  2030. ExchangeItems(vL, vR);
  2031. if Pivot = vL then // swap pivot if we just hit it from one side
  2032. Pivot := vR
  2033. else if Pivot = vR then
  2034. Pivot := vL;
  2035. end;
  2036. if Pivot - 1 >= L then
  2037. QuickSort(L, Pivot - 1, CompareFn);
  2038. if Pivot + 1 <= R then
  2039. QuickSort(Pivot + 1, R, CompareFn);
  2040. end;
  2041. procedure TStringList.InsertItem(Index: Integer; const S: string);
  2042. begin
  2043. InsertItem(Index, S, nil);
  2044. end;
  2045. procedure TStringList.InsertItem(Index: Integer; const S: string; O: TObject);
  2046. Var
  2047. It : TStringItem;
  2048. begin
  2049. Changing;
  2050. If FCount=Capacity then Grow;
  2051. it.FString:=S;
  2052. it.FObject:=O;
  2053. TJSArray(FList).Splice(Index,0,It);
  2054. Inc(FCount);
  2055. Changed;
  2056. end;
  2057. procedure TStringList.SetSorted(Value: Boolean);
  2058. begin
  2059. If Value then
  2060. SortStyle:=sslAuto
  2061. else
  2062. SortStyle:=sslNone
  2063. end;
  2064. procedure TStringList.Changed;
  2065. begin
  2066. If (FUpdateCount=0) Then
  2067. begin
  2068. If Assigned(FOnChange) then
  2069. FOnchange(Self);
  2070. end;
  2071. end;
  2072. procedure TStringList.Changing;
  2073. begin
  2074. If FUpdateCount=0 then
  2075. if Assigned(FOnChanging) then
  2076. FOnchanging(Self);
  2077. end;
  2078. function TStringList.Get(Index: Integer): string;
  2079. begin
  2080. CheckIndex(Index);
  2081. Result:=Flist[Index].FString;
  2082. end;
  2083. function TStringList.GetCapacity: Integer;
  2084. begin
  2085. Result:=Length(FList);
  2086. end;
  2087. function TStringList.GetCount: Integer;
  2088. begin
  2089. Result:=FCount;
  2090. end;
  2091. function TStringList.GetObject(Index: Integer): TObject;
  2092. begin
  2093. CheckIndex(Index);
  2094. Result:=Flist[Index].FObject;
  2095. end;
  2096. procedure TStringList.Put(Index: Integer; const S: string);
  2097. begin
  2098. If Sorted then
  2099. Error(SSortedListError,0);
  2100. CheckIndex(Index);
  2101. Changing;
  2102. Flist[Index].FString:=S;
  2103. Changed;
  2104. end;
  2105. procedure TStringList.PutObject(Index: Integer; AObject: TObject);
  2106. begin
  2107. CheckIndex(Index);
  2108. Changing;
  2109. Flist[Index].FObject:=AObject;
  2110. Changed;
  2111. end;
  2112. procedure TStringList.SetCapacity(NewCapacity: Integer);
  2113. begin
  2114. If (NewCapacity<0) then
  2115. Error (SListCapacityError,NewCapacity);
  2116. If NewCapacity<>Capacity then
  2117. SetLength(FList,NewCapacity)
  2118. end;
  2119. procedure TStringList.SetUpdateState(Updating: Boolean);
  2120. begin
  2121. If Updating then
  2122. Changing
  2123. else
  2124. Changed
  2125. end;
  2126. destructor TStringList.Destroy;
  2127. begin
  2128. InternalClear;
  2129. Inherited destroy;
  2130. end;
  2131. function TStringList.Add(const S: string): Integer;
  2132. begin
  2133. If Not (SortStyle=sslAuto) then
  2134. Result:=FCount
  2135. else
  2136. If Find (S,Result) then
  2137. Case DUplicates of
  2138. DupIgnore : Exit;
  2139. DupError : Error(SDuplicateString,0)
  2140. end;
  2141. InsertItem (Result,S);
  2142. end;
  2143. procedure TStringList.Clear;
  2144. begin
  2145. if FCount = 0 then Exit;
  2146. Changing;
  2147. InternalClear;
  2148. Changed;
  2149. end;
  2150. procedure TStringList.Delete(Index: Integer);
  2151. begin
  2152. CheckIndex(Index);
  2153. Changing;
  2154. if FOwnsObjects then
  2155. FreeAndNil(Flist[Index].FObject);
  2156. TJSArray(FList).splice(Index,1);
  2157. FList[Count-1].FString:='';
  2158. Flist[Count-1].FObject:=Nil;
  2159. Dec(FCount);
  2160. Changed;
  2161. end;
  2162. procedure TStringList.Exchange(Index1, Index2: Integer);
  2163. begin
  2164. CheckIndex(Index1);
  2165. CheckIndex(Index2);
  2166. Changing;
  2167. ExchangeItemsInt(Index1,Index2);
  2168. changed;
  2169. end;
  2170. procedure TStringList.SetCaseSensitive(b : boolean);
  2171. begin
  2172. if b=FCaseSensitive then
  2173. Exit;
  2174. FCaseSensitive:=b;
  2175. if FSortStyle=sslAuto then
  2176. begin
  2177. FForceSort:=True;
  2178. try
  2179. Sort;
  2180. finally
  2181. FForceSort:=False;
  2182. end;
  2183. end;
  2184. end;
  2185. procedure TStringList.SetSortStyle(AValue: TStringsSortStyle);
  2186. begin
  2187. if FSortStyle=AValue then Exit;
  2188. if (AValue=sslAuto) then
  2189. Sort;
  2190. FSortStyle:=AValue;
  2191. end;
  2192. procedure TStringList.CheckIndex(AIndex: Integer);
  2193. begin
  2194. If (AIndex<0) or (AIndex>=FCount) then
  2195. Error(SListIndexError,AIndex);
  2196. end;
  2197. function TStringList.DoCompareText(const s1, s2: string): PtrInt;
  2198. begin
  2199. if FCaseSensitive then
  2200. result:=CompareStr(s1,s2)
  2201. else
  2202. result:=CompareText(s1,s2);
  2203. end;
  2204. function TStringList.CompareStrings(const s1,s2 : string) : Integer;
  2205. begin
  2206. Result := DoCompareText(s1, s2);
  2207. end;
  2208. function TStringList.Find(const S: string; out Index: Integer): Boolean;
  2209. var
  2210. L, R, I: Integer;
  2211. CompareRes: PtrInt;
  2212. begin
  2213. Result := false;
  2214. Index:=-1;
  2215. if Not Sorted then
  2216. Raise EListError.Create(SErrFindNeedsSortedList);
  2217. // Use binary search.
  2218. L := 0;
  2219. R := Count - 1;
  2220. while (L<=R) do
  2221. begin
  2222. I := L + (R - L) div 2;
  2223. CompareRes := DoCompareText(S, Flist[I].FString);
  2224. if (CompareRes>0) then
  2225. L := I+1
  2226. else begin
  2227. R := I-1;
  2228. if (CompareRes=0) then begin
  2229. Result := true;
  2230. if (Duplicates<>dupAccept) then
  2231. L := I; // forces end of while loop
  2232. end;
  2233. end;
  2234. end;
  2235. Index := L;
  2236. end;
  2237. function TStringList.IndexOf(const S: string): Integer;
  2238. begin
  2239. If Not Sorted then
  2240. Result:=Inherited indexOf(S)
  2241. else
  2242. // faster using binary search...
  2243. If Not Find (S,Result) then
  2244. Result:=-1;
  2245. end;
  2246. procedure TStringList.Insert(Index: Integer; const S: string);
  2247. begin
  2248. If SortStyle=sslAuto then
  2249. Error (SSortedListError,0)
  2250. else
  2251. begin
  2252. If (Index<0) or (Index>FCount) then
  2253. Error(SListIndexError,Index); // Cannot use CheckIndex, because there >= FCount...
  2254. InsertItem (Index,S);
  2255. end;
  2256. end;
  2257. procedure TStringList.CustomSort(CompareFn: TStringListSortCompare);
  2258. begin
  2259. If (FForceSort or (Not (FSortStyle=sslAuto))) and (FCount>1) then
  2260. begin
  2261. Changing;
  2262. QuickSort(0,FCount-1, CompareFn);
  2263. Changed;
  2264. end;
  2265. end;
  2266. function StringListAnsiCompare(List: TStringList; Index1, Index: Integer): Integer;
  2267. begin
  2268. Result := List.DoCompareText(List.FList[Index1].FString,
  2269. List.FList[Index].FString);
  2270. end;
  2271. procedure TStringList.Sort;
  2272. begin
  2273. CustomSort(@StringListAnsiCompare);
  2274. end;
  2275. {****************************************************************************}
  2276. {* TCollectionItem *}
  2277. {****************************************************************************}
  2278. function TCollectionItem.GetIndex: Integer;
  2279. begin
  2280. if FCollection<>nil then
  2281. Result:=FCollection.FItems.IndexOf(Self)
  2282. else
  2283. Result:=-1;
  2284. end;
  2285. procedure TCollectionItem.SetCollection(Value: TCollection);
  2286. begin
  2287. IF Value<>FCollection then
  2288. begin
  2289. If FCollection<>Nil then FCollection.RemoveItem(Self);
  2290. if Value<>Nil then Value.InsertItem(Self);
  2291. end;
  2292. end;
  2293. procedure TCollectionItem.Changed(AllItems: Boolean);
  2294. begin
  2295. If (FCollection<>Nil) and (FCollection.UpdateCount=0) then
  2296. begin
  2297. If AllItems then
  2298. FCollection.Update(Nil)
  2299. else
  2300. FCollection.Update(Self);
  2301. end;
  2302. end;
  2303. function TCollectionItem.GetNamePath: string;
  2304. begin
  2305. If FCollection<>Nil then
  2306. Result:=FCollection.GetNamePath+'['+IntToStr(Index)+']'
  2307. else
  2308. Result:=ClassName;
  2309. end;
  2310. function TCollectionItem.GetOwner: TPersistent;
  2311. begin
  2312. Result:=FCollection;
  2313. end;
  2314. function TCollectionItem.GetDisplayName: string;
  2315. begin
  2316. Result:=ClassName;
  2317. end;
  2318. procedure TCollectionItem.SetIndex(Value: Integer);
  2319. Var Temp : Longint;
  2320. begin
  2321. Temp:=GetIndex;
  2322. If (Temp>-1) and (Temp<>Value) then
  2323. begin
  2324. FCollection.FItems.Move(Temp,Value);
  2325. Changed(True);
  2326. end;
  2327. end;
  2328. procedure TCollectionItem.SetDisplayName(const Value: string);
  2329. begin
  2330. Changed(False);
  2331. if Value='' then ;
  2332. end;
  2333. constructor TCollectionItem.Create(ACollection: TCollection);
  2334. begin
  2335. Inherited Create;
  2336. SetCollection(ACollection);
  2337. end;
  2338. destructor TCollectionItem.Destroy;
  2339. begin
  2340. SetCollection(Nil);
  2341. Inherited Destroy;
  2342. end;
  2343. {****************************************************************************}
  2344. {* TCollectionEnumerator *}
  2345. {****************************************************************************}
  2346. constructor TCollectionEnumerator.Create(ACollection: TCollection);
  2347. begin
  2348. inherited Create;
  2349. FCollection := ACollection;
  2350. FPosition := -1;
  2351. end;
  2352. function TCollectionEnumerator.GetCurrent: TCollectionItem;
  2353. begin
  2354. Result := FCollection.Items[FPosition];
  2355. end;
  2356. function TCollectionEnumerator.MoveNext: Boolean;
  2357. begin
  2358. Inc(FPosition);
  2359. Result := FPosition < FCollection.Count;
  2360. end;
  2361. {****************************************************************************}
  2362. {* TCollection *}
  2363. {****************************************************************************}
  2364. function TCollection.Owner: TPersistent;
  2365. begin
  2366. result:=getowner;
  2367. end;
  2368. function TCollection.GetCount: Integer;
  2369. begin
  2370. Result:=FItems.Count;
  2371. end;
  2372. Procedure TCollection.SetPropName;
  2373. {
  2374. Var
  2375. TheOwner : TPersistent;
  2376. PropList : PPropList;
  2377. I, PropCount : Integer;
  2378. }
  2379. begin
  2380. FPropName:='';
  2381. {
  2382. TheOwner:=GetOwner;
  2383. // TODO: This needs to wait till Mattias finishes typeinfo.
  2384. // It's normally only used in the designer so should not be a problem currently.
  2385. if (TheOwner=Nil) Or (TheOwner.Classinfo=Nil) Then Exit;
  2386. // get information from the owner RTTI
  2387. PropCount:=GetPropList(TheOwner, PropList);
  2388. Try
  2389. For I:=0 To PropCount-1 Do
  2390. If (PropList^[i]^.PropType^.Kind=tkClass) And
  2391. (GetObjectProp(TheOwner, PropList^[i], ClassType)=Self) Then
  2392. Begin
  2393. FPropName:=PropList^[i]^.Name;
  2394. Exit;
  2395. End;
  2396. Finally
  2397. FreeMem(PropList);
  2398. End;
  2399. }
  2400. end;
  2401. function TCollection.GetPropName: string;
  2402. {Var
  2403. TheOwner : TPersistent;}
  2404. begin
  2405. Result:=FPropNAme;
  2406. // TheOwner:=GetOwner;
  2407. // If (Result<>'') or (TheOwner=Nil) Or (TheOwner.Classinfo=Nil) then exit;
  2408. SetPropName;
  2409. Result:=FPropName;
  2410. end;
  2411. procedure TCollection.InsertItem(Item: TCollectionItem);
  2412. begin
  2413. If Not(Item Is FitemClass) then
  2414. exit;
  2415. FItems.add(Item);
  2416. Item.FCollection:=Self;
  2417. Item.FID:=FNextID;
  2418. inc(FNextID);
  2419. SetItemName(Item);
  2420. Notify(Item,cnAdded);
  2421. Changed;
  2422. end;
  2423. procedure TCollection.RemoveItem(Item: TCollectionItem);
  2424. Var
  2425. I : Integer;
  2426. begin
  2427. Notify(Item,cnExtracting);
  2428. I:=FItems.IndexOfItem(Item,fromEnd);
  2429. If (I<>-1) then
  2430. FItems.Delete(I);
  2431. Item.FCollection:=Nil;
  2432. Changed;
  2433. end;
  2434. function TCollection.GetAttrCount: Integer;
  2435. begin
  2436. Result:=0;
  2437. end;
  2438. function TCollection.GetAttr(Index: Integer): string;
  2439. begin
  2440. Result:='';
  2441. if Index=0 then ;
  2442. end;
  2443. function TCollection.GetItemAttr(Index, ItemIndex: Integer): string;
  2444. begin
  2445. Result:=TCollectionItem(FItems.Items[ItemIndex]).DisplayName;
  2446. if Index=0 then ;
  2447. end;
  2448. function TCollection.GetEnumerator: TCollectionEnumerator;
  2449. begin
  2450. Result := TCollectionEnumerator.Create(Self);
  2451. end;
  2452. function TCollection.GetNamePath: string;
  2453. var o : TPersistent;
  2454. begin
  2455. o:=getowner;
  2456. if assigned(o) and (propname<>'') then
  2457. result:=o.getnamepath+'.'+propname
  2458. else
  2459. result:=classname;
  2460. end;
  2461. procedure TCollection.Changed;
  2462. begin
  2463. if FUpdateCount=0 then
  2464. Update(Nil);
  2465. end;
  2466. function TCollection.GetItem(Index: Integer): TCollectionItem;
  2467. begin
  2468. Result:=TCollectionItem(FItems.Items[Index]);
  2469. end;
  2470. procedure TCollection.SetItem(Index: Integer; Value: TCollectionItem);
  2471. begin
  2472. TCollectionItem(FItems.items[Index]).Assign(Value);
  2473. end;
  2474. procedure TCollection.SetItemName(Item: TCollectionItem);
  2475. begin
  2476. if Item=nil then ;
  2477. end;
  2478. procedure TCollection.Update(Item: TCollectionItem);
  2479. begin
  2480. if Item=nil then ;
  2481. end;
  2482. constructor TCollection.Create(AItemClass: TCollectionItemClass);
  2483. begin
  2484. inherited create;
  2485. FItemClass:=AItemClass;
  2486. FItems:=TFpList.Create;
  2487. end;
  2488. destructor TCollection.Destroy;
  2489. begin
  2490. FUpdateCount:=1; // Prevent OnChange
  2491. try
  2492. DoClear;
  2493. Finally
  2494. FUpdateCount:=0;
  2495. end;
  2496. if assigned(FItems) then
  2497. FItems.Destroy;
  2498. Inherited Destroy;
  2499. end;
  2500. function TCollection.Add: TCollectionItem;
  2501. begin
  2502. Result:=FItemClass.Create(Self);
  2503. end;
  2504. procedure TCollection.Assign(Source: TPersistent);
  2505. Var I : Longint;
  2506. begin
  2507. If Source is TCollection then
  2508. begin
  2509. Clear;
  2510. For I:=0 To TCollection(Source).Count-1 do
  2511. Add.Assign(TCollection(Source).Items[I]);
  2512. exit;
  2513. end
  2514. else
  2515. Inherited Assign(Source);
  2516. end;
  2517. procedure TCollection.BeginUpdate;
  2518. begin
  2519. inc(FUpdateCount);
  2520. end;
  2521. procedure TCollection.Clear;
  2522. begin
  2523. if FItems.Count=0 then
  2524. exit; // Prevent Changed
  2525. BeginUpdate;
  2526. try
  2527. DoClear;
  2528. finally
  2529. EndUpdate;
  2530. end;
  2531. end;
  2532. procedure TCollection.DoClear;
  2533. var
  2534. Item: TCollectionItem;
  2535. begin
  2536. While FItems.Count>0 do
  2537. begin
  2538. Item:=TCollectionItem(FItems.Last);
  2539. if Assigned(Item) then
  2540. Item.Destroy;
  2541. end;
  2542. end;
  2543. procedure TCollection.EndUpdate;
  2544. begin
  2545. if FUpdateCount>0 then
  2546. dec(FUpdateCount);
  2547. if FUpdateCount=0 then
  2548. Changed;
  2549. end;
  2550. function TCollection.FindItemID(ID: Integer): TCollectionItem;
  2551. Var
  2552. I : Longint;
  2553. begin
  2554. For I:=0 to Fitems.Count-1 do
  2555. begin
  2556. Result:=TCollectionItem(FItems.items[I]);
  2557. If Result.Id=Id then
  2558. exit;
  2559. end;
  2560. Result:=Nil;
  2561. end;
  2562. procedure TCollection.Delete(Index: Integer);
  2563. Var
  2564. Item : TCollectionItem;
  2565. begin
  2566. Item:=TCollectionItem(FItems[Index]);
  2567. Notify(Item,cnDeleting);
  2568. If assigned(Item) then
  2569. Item.Destroy;
  2570. end;
  2571. function TCollection.Insert(Index: Integer): TCollectionItem;
  2572. begin
  2573. Result:=Add;
  2574. Result.Index:=Index;
  2575. end;
  2576. procedure TCollection.Notify(Item: TCollectionItem;Action: TCollectionNotification);
  2577. begin
  2578. if Item=nil then ;
  2579. if Action=cnAdded then ;
  2580. end;
  2581. procedure TCollection.Sort(Const Compare : TCollectionSortCompare);
  2582. begin
  2583. BeginUpdate;
  2584. try
  2585. FItems.Sort(TListSortCompare(Compare));
  2586. Finally
  2587. EndUpdate;
  2588. end;
  2589. end;
  2590. procedure TCollection.Exchange(Const Index1, index2: integer);
  2591. begin
  2592. FItems.Exchange(Index1,Index2);
  2593. end;
  2594. {****************************************************************************}
  2595. {* TOwnedCollection *}
  2596. {****************************************************************************}
  2597. Constructor TOwnedCollection.Create(AOwner: TPersistent; AItemClass: TCollectionItemClass);
  2598. Begin
  2599. FOwner := AOwner;
  2600. inherited Create(AItemClass);
  2601. end;
  2602. Function TOwnedCollection.GetOwner: TPersistent;
  2603. begin
  2604. Result:=FOwner;
  2605. end;
  2606. {****************************************************************************}
  2607. {* TComponent *}
  2608. {****************************************************************************}
  2609. Function TComponent.GetComponent(AIndex: Integer): TComponent;
  2610. begin
  2611. If not assigned(FComponents) then
  2612. Result:=Nil
  2613. else
  2614. Result:=TComponent(FComponents.Items[Aindex]);
  2615. end;
  2616. Function TComponent.GetComponentCount: Integer;
  2617. begin
  2618. If not assigned(FComponents) then
  2619. result:=0
  2620. else
  2621. Result:=FComponents.Count;
  2622. end;
  2623. Function TComponent.GetComponentIndex: Integer;
  2624. begin
  2625. If Assigned(FOwner) and Assigned(FOwner.FComponents) then
  2626. Result:=FOWner.FComponents.IndexOf(Self)
  2627. else
  2628. Result:=-1;
  2629. end;
  2630. Procedure TComponent.Insert(AComponent: TComponent);
  2631. begin
  2632. If not assigned(FComponents) then
  2633. FComponents:=TFpList.Create;
  2634. FComponents.Add(AComponent);
  2635. AComponent.FOwner:=Self;
  2636. end;
  2637. Procedure TComponent.Remove(AComponent: TComponent);
  2638. begin
  2639. AComponent.FOwner:=Nil;
  2640. If assigned(FCOmponents) then
  2641. begin
  2642. FComponents.Remove(AComponent);
  2643. IF FComponents.Count=0 then
  2644. begin
  2645. FComponents.Destroy;
  2646. FComponents:=Nil;
  2647. end;
  2648. end;
  2649. end;
  2650. Procedure TComponent.RemoveNotification(AComponent: TComponent);
  2651. begin
  2652. if FFreeNotifies<>nil then
  2653. begin
  2654. FFreeNotifies.Remove(AComponent);
  2655. if FFreeNotifies.Count=0 then
  2656. begin
  2657. FFreeNotifies.Destroy;
  2658. FFreeNotifies:=nil;
  2659. Exclude(FComponentState,csFreeNotification);
  2660. end;
  2661. end;
  2662. end;
  2663. Procedure TComponent.SetComponentIndex(Value: Integer);
  2664. Var Temp,Count : longint;
  2665. begin
  2666. If Not assigned(Fowner) then exit;
  2667. Temp:=getcomponentindex;
  2668. If temp<0 then exit;
  2669. If value<0 then value:=0;
  2670. Count:=Fowner.FComponents.Count;
  2671. If Value>=Count then value:=count-1;
  2672. If Value<>Temp then
  2673. begin
  2674. FOWner.FComponents.Delete(Temp);
  2675. FOwner.FComponents.Insert(Value,Self);
  2676. end;
  2677. end;
  2678. Procedure TComponent.ChangeName(const NewName: TComponentName);
  2679. begin
  2680. FName:=NewName;
  2681. end;
  2682. Procedure TComponent.GetChildren(Proc: TGetChildProc; Root: TComponent);
  2683. begin
  2684. // Does nothing.
  2685. if Proc=nil then ;
  2686. if Root=nil then ;
  2687. end;
  2688. Function TComponent.GetChildOwner: TComponent;
  2689. begin
  2690. Result:=Nil;
  2691. end;
  2692. Function TComponent.GetChildParent: TComponent;
  2693. begin
  2694. Result:=Self;
  2695. end;
  2696. Function TComponent.GetNamePath: string;
  2697. begin
  2698. Result:=FName;
  2699. end;
  2700. Function TComponent.GetOwner: TPersistent;
  2701. begin
  2702. Result:=FOwner;
  2703. end;
  2704. Procedure TComponent.Loaded;
  2705. begin
  2706. Exclude(FComponentState,csLoading);
  2707. end;
  2708. Procedure TComponent.Loading;
  2709. begin
  2710. Include(FComponentState,csLoading);
  2711. end;
  2712. Procedure TComponent.Notification(AComponent: TComponent;
  2713. Operation: TOperation);
  2714. Var
  2715. C : Longint;
  2716. begin
  2717. If (Operation=opRemove) then
  2718. RemoveFreeNotification(AComponent);
  2719. If Not assigned(FComponents) then
  2720. exit;
  2721. C:=FComponents.Count-1;
  2722. While (C>=0) do
  2723. begin
  2724. TComponent(FComponents.Items[C]).Notification(AComponent,Operation);
  2725. Dec(C);
  2726. if C>=FComponents.Count then
  2727. C:=FComponents.Count-1;
  2728. end;
  2729. end;
  2730. procedure TComponent.PaletteCreated;
  2731. begin
  2732. end;
  2733. Procedure TComponent.SetAncestor(Value: Boolean);
  2734. Var Runner : Longint;
  2735. begin
  2736. If Value then
  2737. Include(FComponentState,csAncestor)
  2738. else
  2739. Exclude(FCOmponentState,csAncestor);
  2740. if Assigned(FComponents) then
  2741. For Runner:=0 To FComponents.Count-1 do
  2742. TComponent(FComponents.Items[Runner]).SetAncestor(Value);
  2743. end;
  2744. Procedure TComponent.SetDesigning(Value: Boolean; SetChildren : Boolean = True);
  2745. Var Runner : Longint;
  2746. begin
  2747. If Value then
  2748. Include(FComponentState,csDesigning)
  2749. else
  2750. Exclude(FComponentState,csDesigning);
  2751. if Assigned(FComponents) and SetChildren then
  2752. For Runner:=0 To FComponents.Count - 1 do
  2753. TComponent(FComponents.items[Runner]).SetDesigning(Value);
  2754. end;
  2755. Procedure TComponent.SetDesignInstance(Value: Boolean);
  2756. begin
  2757. If Value then
  2758. Include(FComponentState,csDesignInstance)
  2759. else
  2760. Exclude(FComponentState,csDesignInstance);
  2761. end;
  2762. Procedure TComponent.SetInline(Value: Boolean);
  2763. begin
  2764. If Value then
  2765. Include(FComponentState,csInline)
  2766. else
  2767. Exclude(FComponentState,csInline);
  2768. end;
  2769. Procedure TComponent.SetName(const NewName: TComponentName);
  2770. begin
  2771. If FName=NewName then exit;
  2772. If (NewName<>'') and not IsValidIdent(NewName) then
  2773. Raise EComponentError.CreateFmt(SInvalidName,[NewName]);
  2774. If Assigned(FOwner) Then
  2775. FOwner.ValidateRename(Self,FName,NewName)
  2776. else
  2777. ValidateRename(Nil,FName,NewName);
  2778. ChangeName(NewName);
  2779. end;
  2780. Procedure TComponent.SetChildOrder(Child: TComponent; Order: Integer);
  2781. begin
  2782. // does nothing
  2783. if Child=nil then ;
  2784. if Order=0 then ;
  2785. end;
  2786. Procedure TComponent.SetParentComponent(Value: TComponent);
  2787. begin
  2788. // Does nothing
  2789. if Value=nil then ;
  2790. end;
  2791. Procedure TComponent.Updating;
  2792. begin
  2793. Include (FComponentState,csUpdating);
  2794. end;
  2795. Procedure TComponent.Updated;
  2796. begin
  2797. Exclude(FComponentState,csUpdating);
  2798. end;
  2799. Procedure TComponent.ValidateRename(AComponent: TComponent;
  2800. const CurName, NewName: string);
  2801. begin
  2802. //!! This contradicts the Delphi manual.
  2803. If (AComponent<>Nil) and (CompareText(CurName,NewName)<>0) and (AComponent.Owner = Self) and
  2804. (FindComponent(NewName)<>Nil) then
  2805. raise EComponentError.Createfmt(SDuplicateName,[newname]);
  2806. If (csDesigning in FComponentState) and (FOwner<>Nil) then
  2807. FOwner.ValidateRename(AComponent,Curname,Newname);
  2808. end;
  2809. Procedure TComponent.ValidateContainer(AComponent: TComponent);
  2810. begin
  2811. AComponent.ValidateInsert(Self);
  2812. end;
  2813. Procedure TComponent.ValidateInsert(AComponent: TComponent);
  2814. begin
  2815. // Does nothing.
  2816. if AComponent=nil then ;
  2817. end;
  2818. Constructor TComponent.Create(AOwner: TComponent);
  2819. begin
  2820. FComponentStyle:=[csInheritable];
  2821. If Assigned(AOwner) then AOwner.InsertComponent(Self);
  2822. end;
  2823. Destructor TComponent.Destroy;
  2824. Var
  2825. I : Integer;
  2826. C : TComponent;
  2827. begin
  2828. Destroying;
  2829. If Assigned(FFreeNotifies) then
  2830. begin
  2831. I:=FFreeNotifies.Count-1;
  2832. While (I>=0) do
  2833. begin
  2834. C:=TComponent(FFreeNotifies.Items[I]);
  2835. // Delete, so one component is not notified twice, if it is owned.
  2836. FFreeNotifies.Delete(I);
  2837. C.Notification (self,opRemove);
  2838. If (FFreeNotifies=Nil) then
  2839. I:=0
  2840. else if (I>FFreeNotifies.Count) then
  2841. I:=FFreeNotifies.Count;
  2842. dec(i);
  2843. end;
  2844. FreeAndNil(FFreeNotifies);
  2845. end;
  2846. DestroyComponents;
  2847. If FOwner<>Nil Then FOwner.RemoveComponent(Self);
  2848. inherited destroy;
  2849. end;
  2850. Procedure TComponent.BeforeDestruction;
  2851. begin
  2852. if not(csDestroying in FComponentstate) then
  2853. Destroying;
  2854. end;
  2855. Procedure TComponent.DestroyComponents;
  2856. Var acomponent: TComponent;
  2857. begin
  2858. While assigned(FComponents) do
  2859. begin
  2860. aComponent:=TComponent(FComponents.Last);
  2861. Remove(aComponent);
  2862. Acomponent.Destroy;
  2863. end;
  2864. end;
  2865. Procedure TComponent.Destroying;
  2866. Var Runner : longint;
  2867. begin
  2868. If csDestroying in FComponentstate Then Exit;
  2869. include (FComponentState,csDestroying);
  2870. If Assigned(FComponents) then
  2871. for Runner:=0 to FComponents.Count-1 do
  2872. TComponent(FComponents.Items[Runner]).Destroying;
  2873. end;
  2874. Function TComponent.FindComponent(const AName: string): TComponent;
  2875. Var I : longint;
  2876. begin
  2877. Result:=Nil;
  2878. If (AName='') or Not assigned(FComponents) then exit;
  2879. For i:=0 to FComponents.Count-1 do
  2880. if (CompareText(TComponent(FComponents[I]).Name,AName)=0) then
  2881. begin
  2882. Result:=TComponent(FComponents.Items[I]);
  2883. exit;
  2884. end;
  2885. end;
  2886. Procedure TComponent.FreeNotification(AComponent: TComponent);
  2887. begin
  2888. If (Owner<>Nil) and (AComponent=Owner) then exit;
  2889. If not (Assigned(FFreeNotifies)) then
  2890. FFreeNotifies:=TFpList.Create;
  2891. If FFreeNotifies.IndexOf(AComponent)=-1 then
  2892. begin
  2893. FFreeNotifies.Add(AComponent);
  2894. AComponent.FreeNotification (self);
  2895. end;
  2896. end;
  2897. procedure TComponent.RemoveFreeNotification(AComponent: TComponent);
  2898. begin
  2899. RemoveNotification(AComponent);
  2900. AComponent.RemoveNotification (self);
  2901. end;
  2902. Function TComponent.GetParentComponent: TComponent;
  2903. begin
  2904. Result:=Nil;
  2905. end;
  2906. Function TComponent.HasParent: Boolean;
  2907. begin
  2908. Result:=False;
  2909. end;
  2910. Procedure TComponent.InsertComponent(AComponent: TComponent);
  2911. begin
  2912. AComponent.ValidateContainer(Self);
  2913. ValidateRename(AComponent,'',AComponent.FName);
  2914. Insert(AComponent);
  2915. If csDesigning in FComponentState then
  2916. AComponent.SetDesigning(true);
  2917. Notification(AComponent,opInsert);
  2918. end;
  2919. Procedure TComponent.RemoveComponent(AComponent: TComponent);
  2920. begin
  2921. Notification(AComponent,opRemove);
  2922. Remove(AComponent);
  2923. Acomponent.Setdesigning(False);
  2924. ValidateRename(AComponent,AComponent.FName,'');
  2925. end;
  2926. procedure TComponent.SetSubComponent(ASubComponent: Boolean);
  2927. begin
  2928. if ASubComponent then
  2929. Include(FComponentStyle, csSubComponent)
  2930. else
  2931. Exclude(FComponentStyle, csSubComponent);
  2932. end;
  2933. function TComponent.GetEnumerator: TComponentEnumerator;
  2934. begin
  2935. Result:=TComponentEnumerator.Create(Self);
  2936. end;
  2937. { ---------------------------------------------------------------------
  2938. Global routines
  2939. ---------------------------------------------------------------------}
  2940. var
  2941. ClassList : TJSObject;
  2942. Procedure RegisterClass(AClass : TPersistentClass);
  2943. begin
  2944. ClassList[AClass.ClassName]:=AClass;
  2945. end;
  2946. Function GetClass(AClassName : string) : TPersistentClass;
  2947. begin
  2948. Result:=nil;
  2949. if AClassName='' then exit;
  2950. if not ClassList.hasOwnProperty(AClassName) then exit;
  2951. Result:=TPersistentClass(ClassList[AClassName]);
  2952. end;
  2953. initialization
  2954. ClassList:=TJSObject.create(nil);
  2955. end.