2
0

classes.pas 84 KB

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