classes.pas 82 KB

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