classes.pas 83 KB

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