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