classes.pas 83 KB

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