home *** CD-ROM | disk | FTP | other *** search
Wrap
unit WABD_Objects; {$include kbmWABD.inc} interface uses Classes, SysUtils, Windows, Forms, Graphics, Controls, StdCtrls, ExtCtrls, DB, Grids, WABD_About, Chart, teEngine, dialogs, jpeg, WABD_Cookies, WABD_Request, WABD_Response, ComCtrls, Inifiles, registry, WABD_Utils, WABD_ISAPI, WABD_Graphics; // ========================================================================= // kbmWABD // ------- // Web Application Builder for Delphi - Kim Bo Madsens interpretation. // // Based on the open source and freeware version 1.25 of Ben Zieglers library // WABD. Heavily modified and extended by Kim Bo Madsen/Optical Services - Scandinavia. // // The library contains all the functionality needed for building large scale // web ISAPI applications using D3/4/5 or BCB3/4 very rapidly. // // Copyright 1997,1998 for v. 1.25 and all previous versions Ben Ziegler (Zieglersoft) // Copyright 1999-2001 for v. 2.xx and newer Kim Bo Madsen/Optical Services - Scandinavia // All rights reserved. // // The copyright includes all files in this library, not only this file. // // LICENSE AGREEMENT // // You are allowed to use this component in any project for free. // You are NOT allowed to claim that you have created this component or to // copy its code into your own component and claim that it was your idea. // // Since this library is open source and freeware, all later incarnations _must_ also // be open source and freeware. // // All the added functionality to the original 1.25 library is offered for free // for your convinience, and the only thing I REQUIRE is to get an e-mail about what // project this library (or derived versions) are used for. // // You dont need to state the name of the creators (Ben Ziegler and Kim Bo Madsen) in // your software, although it would be appreciated if you do. // // If you find bugs or alter the component (f.ex. see suggested enhancements // further down), please DONT just send the corrected/new code out on the internet, // but instead send it to me, so I can put it into the official version. You will // be acredited if you do so. // // Ben Ziegler has to my knowledge not claimed any restrictions which // should violate this license agreement. // // DISCLAIMER // By using this component or parts theirof you are accepting the full // responsibility of the use. You are understanding that the authors (Ben Ziegler or // Kim Bo Madsen) cant be made responsible in any way for any problems occuring // using this component. // You also recognize the authors (Ben Ziegler and Kim Bo Madsen) as the creators // of this component and agrees not to claim otherwize! // // Please forward corrected versions (source code ONLY!), comments, // and emails saying you are using it for this or that project to: // kbm@optical.dk // // New versions can be found at the kbmwabd community at // http://www.egroups.com/group/kbmwabd // // Please direct all support questions through the kbmwabd community. // Support questions send directly to me will in general _not_ be answered. // // Suggestions for future enhancements: // // - Help file, // - Example projects // // History: // 1.25 Original version programmed and released as open source and freeware by Ben Ziegler. // // 2.00 Many, many, many things added, like remote administation, frames support, charting, // Javascript support, statistics collection, logon security, file upload, javascript // based menutree component and alot more. Most part of internal routines largely rewritten to // support new functionality, avoid use of 3rd party libs unless extremely needed (Bens Lib) // enhance stability. Kim Bo Madsen (kbm@optical.dk) // // 2.10 First stable version 2. The system is in its 2.10 release really very stable and is used // for a large web based ISAPI EIS (Executive Information System) application. // Kim Bo Madsen (kbm@optical.dk) // // 2.11 Fixed bug so a wannabe admin doesnt get aut. routed to another machine even if not authenticated. // Prepared network timing utilities which when enabled in a future version will show up in the stats display. // // 2.12 Implemented network timing utilities. // Fixed bug in TWABD_MenuTree where OnEvent JS function was reallocated even if it was allocated in the parent TWABD_Body. // // 2.13 Fixed bug not calling mousedown on TWABD_Chart. KBM 28-08-2000 // // 2.20 Added TWABD_HTML and TWABD_HTMLFile (with support for file caching). // Supporting Cookies in TWABD_Session. Improved variable access routines. // Added Stateless sessions which will be destroyed right after use. // Kim Bo Madsen (kbm@optical.dk) 27-11-2000 // // 2.21 Added missing HTML_Input file. Added Anders Melanders GifImage KBM 05-Jan-2001 // sources in a zipfile (not newest version). // Fixed renamed MainForm (MainBody now) attribute reference in WABD_Admin. // Fixed menutree.js javascript. Please reload it into the javascript component pointed // at by the TWABD_MenuTree to activate the new changes. // Fixed Acess Violation on Preview Browser on TWABD_Form. // // 2.22 Fixed TWABD_Label CanClick=true assertion error. Reason was missing _ in WABD_LABEL_STR. // // 2.23 Added TWABD_HTMLEmbed and TWABD_HTMLFileEmbed. Removed TWABD_RawSection. // Fixed TWABD_Table_Strings.SetSafeSize which resulted in corrupt string array. // bug reported by reidr@buzybee.com. // Fixed several bugs todo with using Session without checking for nil. (Will be nil in // design mode). // TWABD_Raw changed name to TWABD_HTMLSection. If you have used TWABD_Raw anywhere, // you have to change it to use TWABD_HTMLSection. You can preserve existing work by // using the Borland utility 'Convert' to convert your datamodules (*.DFM) to // text and then manually rename Lines to HTML for all TWABD_Raw entries. Then // rename all references to TWABD_Raw to TWABD_HTMLSection. Further open your *.pas/*.cpp // files in notepad and change all references too. Sorry if this causes troubles, but // it is required to keep a consistent naming scheme. // // 2.23a Fixed missing Result:=HTML.Text in TWABD_HTMLSection.Object_To_HTML. // 2.23b Fixed EVENTID bug in Javascript due to renaming of constants in 2.20. // // 2.24 Added Show procedure to TWABD_Base_HTML. Thus one can force to show html instead // of form dynamically during runtime. // Made GetFilePath,GetLocalFilePath,GetImagePath,GetLocalImagePath public in TWABD_Setup. // Changed reading ImagePath etc. to return only user setup, not interpreted stuff. Use // GetImagePath etc. instead. // Added NoWrap property to section objects. // Added OnSetupClickableCell event for TWABD_Table and TWABD_Datatable for setting up // if each cell is clickable and what is the target. // Added OnUserClickCell event to TWABD_Table and TWABD_DataTable for reacting to // users clicking a clickable cell. // Enhanced TWABD_Table and TWABD_DataTable to allow Javascript for table, row and cell. // Enhanced TWABD_Base_Image not to specify width and height if imageheight and imagewidth<=0. // Fixed radio button behaviour and generated A/V on new session. // Fixed showing TWABD_HTML or TWABD_HTMLFile in a frame. // Fixed TWABD_MenuTree to generate correct node layout. // Added support for embedding TWABD_MenuTree in subframe. Note only 1 TWABD_Menutree is // allowed in the same webbrowser. // // 2.25 Added support for reloading menutree frame with new data on frame reload. // Prepared for multiple concurrent menutrees in same browser. // Fixed TWABD_Menutree loaddata generation on last top level node. // // 2.26 Changed to use Height/Width instead of ImageHeight/ImageWidth in IMG // html. Added AutoSize property (boolean) to determine if to autosize // image when ImageFile is set. // Added Align property to TWABD_Formsection. // Added TWABD_ExternalFrame for external framereferences for Target/SubmitTo. // TWABD_FormSection_Base.Object_To_HTML now makes one cell less in headerline. // // 2.27 Added Height property for TWABD_FormSection and TWABD_Table. // Fixed setting properties for non submitted forms (when a frame is loading the form f.ex.) // Added VertAlign property to TWABD_Formsection. // Renamed Align to HorzAlign in TWABD_FormSection. // Changed the type of Cell oriented alignments to TWABD_HorzAlignment/TWBAD_VertAlignment. // Changed name of TWABD_FormSection_Base to TWABD_FormSection_Grid and let it // inherit from new TWABD_FormSection_Base. // Added new TWABD_FormSection_Base which contains size and alignment settings. // BEWARE that installing this version WILL require a few changes in your designtime // properties. Remember to open all datamodules and ignore the warnings. Then reset the // appropriate alignment values and if needed correct the eventhandler for cell setup. // Added support for Height/Width on TWABD_Form level. // Added support for showing another form on exception in OnExcetpion in TWABD_Session. // // 2.28 Added out of order detection for TWABD_Form. Check IsOutOfOrder and OnOutOfOrder event. // // 2.29 Added support for multiple selections in listboxes. // Fixed bug on clickable TWABD_Image. Bug reported by Henk Fikkert (henk.fikkert@simulation.nl) // // 2.30 Fixed script 'Collection' bug in Menutree. // Fixed menutree layout problem with two seperate subnodes. Bug reported // by Szakßly Balßzs (szakalyb@freemail.hu). // Fixed so OnShow is called before menutree is shown. // Fixed AddNode on TWABD_MenuTree. // Fixed Cell/Row Javascript of TWABD_Table variants. Bug reported by Henk Fikkert (henk.fikkert@simulation.nl) // Made CreateSessionCookie public and improved it a bit. // Added new method SaveHTMLToFile(AFile:string) which can be called for every kbmWABD element // to generate static HTML. You can then f.ex. reference the static HTML using // a TWABD_HTMLFile or TWABD_HTMLEmbed. // Added Version property to TWABD_Session and TWABD_SessionMgr which simply reports // the version of kbmWABD. // // 2.30a Added D3 installation package file. // // 2.31 Added support for file upload from browser (TWABD_UploadFile). // Added UseSessionCookie property to all TWABD_Body based components. // Default true for TWABD_HTML/HTMLFile body, and false for others. // Added EncType to TWABD_Body. Published it in TWABD_HTML/HTMLFile and TWABD_Form. // Default empty. // Added support for Title on several form objects. Notice that this is not widely supported // by browsers. // Prepared support for other interfaces than ISAPI with Kylix and Apache in mind :) // Thus removed HTML_Input.pas, and introduced several new units like: // WABD_Cookies.pas, WABD_Request.pas, WABD_Response.pas, WABD_HTMLRequest.pas // Added support for TWABD_Body EncodeType. // // 2.32 Changed TWABD_Frame.LinkForm to TWABD_Frame.LinkBody. You can change the name of // your existing properties in your current DFM's // by using the Borland tool Convert.exe to convert the DFM to text and back. // Cleaned up Javascript event support. Now many more objects has support // for more Javascript events. // Removed unlogical JS_OnUserEvent on TWABD_Frameset. Ignore errors when opening form. // HTMLRequest parsing routines now checking for no data. // Changed so JS event code generation only surrounds eventhandler with " if eventhandler // contains space and is not already surrounded by ' or ". // Added installation packages for D4 and BCB4. // Added nice About screen :) // Removed orphaned FileData from TWABD_UploadFile. Shouldnt have been there in the first place. // Please ignore property errors from this. // // 2.33 Automatic support for WML (Wap phones) now added. // Following components are compatible with WAP and can generate and understand WML: // TWABD_HTML, TWABD_HTMLFile, TWABD_Form, TWABD_FormSection, // TWABD_HTMLSection, TWABD_HTMLFileSection, TWABD_AutoRefresh, // TWABD_Expires, TWABD_BlankLines, TWABD_HTMLEmbed, HTML_HTMLFileEmbed, // TWABD_AutoLoad, TWABD_Image, TWABD_LiveImage, TWABD_Chart, // TWABD_Label, TWABD_Memo, TWABD_Button, TWABD_Edit, TWABD_ComboBox, // TWABD_ListBox, TWABD_Anchor and TWABD_CheckBox. // Some properties are only used by HTML for some // of the components since they have no natural place in WML. // All other components are simply ignored during WML generation. // Added NoWrap to formsection_grid objects which if true will override // settings on section object level. // Added Format and EmptyOK to TWABD_Edit. These are only used by WAP. // Added Produce property to TWABD_Session to specify what output should be produced. // It can be set to prodAuto, prodHTML and prodWML. If set to auto, the request from the // client will determine what format will be returned. // Added liAuto to TWABD_LiveImage ImageType. If set to liAuto, then the imagetype send // will be determined according to the Session.Produce and in case of HTML, // the number of colors in the image. // Added MaxAge to TWABD_Expires. // Enhanced so adding an allready existing cookie will auto overwrite it. // Added Literal property to TWABD_Table/TWABD_Datatable as suggested by Henk Fikkert. // Added self parameter to TWABD_Session.OnException event handler. // Added OnException handler to TWABD_SessionMgr (last line of defence). // Fixed A/V bugs when TWABD_AutoLoad and TWABD_AutoRefresh was used. // Added NewSession boolean to TWABD_AutoRefresh. If no URL specified and false will // attempt to reload in current session, otherwise starts a new session. // If URL is specified, reloads external page pointed to by URL. // Improved TWABD_Anchor. If no destination or Target given the // anchor will be percieved as a bookmark (a destination for a anchor). // To jump to a bookmark, set the destination of another anchor to #nameofbookmark // where nameofbookmark is the name of the TWABD_Anchor bookmark component. // This is only valid for HTML, not WML. // Remember to keep the generated WML relatively small for WAP devices not to choke. // Images typically should be max 170x100 pixels large, although kbmWABD supports them // much bigger. // Modified the body searching mechanism to automatically look in multiple datamodules. // The purpose is if a session has several datamodules opened at the same time // to evenly distribute the kbmWABD components on them. // Suggested by Szakßly Balßzs (szakalyb@freemail.hu). // // 2.34 16. July. 2001 // Added support for D6. Now all code is seperated in runtime and designtime. // Fixed bug in TWABD_Menu.ProcessRequest where nodes added programmatically // didnt fire the click event as expected. Problem was different owners // of the programatically added nodes. Bug reported // by Henk Fikkert (henk.fikkert@simulation.nl) // Removed forgotten ShowMessage in TWABD_UploadFile. Problem spotted by // Fred Schetterer (fredsegroups@home.com). // Added designtime changing of size of components by click and drag on right or lower // edge of component in formsection designer. // Added Lock and Unlock thread locking on TWABD_Setup. Made all Getxxxx calls // threadsafe. This will allow setting a TWABD_Setup on the sessionmanager module // and let it be used by session modules. Remember to Lock...Unlock when setting // properties at runtime if a TWABD_Setup is shared between sessions. // Added LocalRootPath which if AutoSetGlobalRootPath is true // alters the WABD_DefaultRequestLocalFilePath global variable. // Added ExpandFromGlobalRootPath property which if true will use // WABD_DefaultRequestLocalFilePath for expanding paths. // Added ExpandFromRootPath property which if true will build local // path names from GlobalRootPath or LocalRootPath and a relative // LocalFile/LocalImage path. Only one TWABD_Setup on the TWABD_SessionMgr should // have AutoSetGlobalRootPath:=true. // Fixed multipart parsing when final line not ending with #10#13. // Added RandomSessionID boolean on TWABD_SessionMgr (default false). // If true will generate random session id number instead of sequential. // Remember setting SiteID to -1 will generate a random site id 0-255. // The siteid and the sessionid is combined for a 32 bit session id for the clients. // Added TotalSessionCount readonly property which returns the total number // of spawned sessions since the ISAPI was started. const WABD_VERSION_STR = 'kbmWABD v. 2.34'; WABD_VERSION = 2.34; CR = #13#10; PIXELS_PER_CHAR_X = 8; // I just picked this number PIXELS_PER_CHAR_Y = 18; // I just picked this number MSECS=60*60*24*1000; // Millisecs per 24 hours. WABD_SES_ID_STR = '_WABD_SESSIONID'; // Hidden Text field to hold session information WABD_SES_ID_STR_FORMAT = '%d:%s'; WABD_EVENT_ID_STR = '_WABD_EVENTID'; // Hidden Text field. X:CtrlName // X=0 : None // X=1 : OnClick WABD_CLIENTPROCESSTIME_STR = '_WABD_CLIENTPROCESSTIME'; // Hidden Text field send by client of how long time from request to answer. WABD_SERVERPROCESSTIME_STR = '_WABD_SERVERPROCESSTIME'; // Hidden Text field send by server of how long server processing took on last request. WABD_CLIENTSUBMITTIMESTAMP_STR = '_WABD_CLIENTSUBMITTIMESTAMP'; // Hidden Text field set by client to timestamp just before submitting. WABD_CLIENTLOADTIMESTAMP_STR = '_WABD_CLIENTLOADTIMESTAMP'; // Hidden Text field set by client to timestamp just after page is loaded. WABD_SERVERTIMESTAMP_STR = '_WABD_SERVERTIMESTAMP'; // Hidden Text field set by server to timestamp just before posting response. WABD_FORMSUBMITCOUNT_STR = '_WABD_FORMSUBMITCOUNT'; // Hidden Text field set by server to identify out of order submissions of forms. WABD_STAMP_STR = '_WABD_STAMP'; // Time stamp (ignored by wabd on input). WABD_RELOAD_STR = '_WABD_RELOAD'; // Reload page without any inputs submitted. WABD_LABEL_STR = '_WABD_LABEL'; WABD_TABLE_STR = '_WABD_TABLE'; WABD_DATA_STR = '_WABD_DATA'; WABD_BUTTON_STR = '_WABD_BUTTON_NAME'; // "Name" used for buttons WABD_RADIO_STR = '_WABD_RADIO_NAME'; // "Name" used for radiobuttons WABD_FRAME_STR = '_WABD_FRAME'; // To indicate that a frame is making the query. WABD_MENUTREE_STR = '_WABD_MENUTREE'; // To indicate that a menutree is making the query. LabPointSizes : array[1..7] of integer = (6,8,9,12,18,24,36); // XLabPointSizes : array[1..7] of integer = (4,6,6,8,12,16,24); XLabPointSizes : array[1..7] of integer = (6,8,9,12,18,24,36); YLabPointSizes : array[1..7] of integer = (14,20,22,28,40,54,96); JS_BEGIN = '<script LANGUAGE="JavaScript">'+CR+'<!--'+CR; JS_END = '//-->'+CR+'</script>'+CR; JS_MenuTree='menutree.js'; WABD_SEMAPHORE_TIMEOUT=20*60*60*1000; // 20 minutes should be more than enough. // Internal sequence names. WABD_IMAGE_SEQUENCE = 'WABD_IMAGE_SEQUENCE'; // Default group names for stats. WABD_STATGRP_RESPONSE = 'Response'; WABD_STATGRP_NETRESPONSE = 'Net response'; WABD_STATGRP_SENDSIZE = 'Sendsize'; WABD_STATGRP_RECVSIZE = 'Recvsize'; // Variable name constants for menutree. WABD_MT_IMG_BLANK='MT_BLANK'; WABD_MT_IMG_BRANCH_CONT='MT_BRANCH_CONT'; WABD_MT_IMG_BRANCH_END='MT_BRANCH_END'; WABD_MT_IMG_FOLDER_CLOSED='MT_FOLDER_CLOSED'; WABD_MT_IMG_FOLDER_OPEN='MT_FOLDER_OPEN'; WABD_MT_IMG_ROOT='MT_ROOT'; WABD_MT_IMG_MINUS_CONT='MT_MINUS_CONT'; WABD_MT_IMG_MINUS_END='MT_MINUS_END'; WABD_MT_IMG_PLUS_CONT='MT_PLUS_CONT'; WABD_MT_IMG_PLUS_END='MT_PLUS_END'; WABD_MT_IMG_VERT_LINE='MT_VERT_LINE'; WABD_MT_FRAME='MT_FRAME'; WABD_MT_FRAME_TARGET='MT_TARGET_FRAME'; WABD_MT_SIZE_FONT='MT_FONTSIZE'; WABD_MT_COLOR_FONT='MT_FONTCOLOR'; WABD_MT_COLOR_LINK='MT_LINKCOLOR'; WABD_MT_COLOR_ALINK='MT_ALINKCOLOR'; WABD_MT_COLOR_VLINK='MT_VLINKCOLOR'; WABD_MT_IMG_BG='MT_BACKGROUND'; WABD_MT_COLOR_BG='MT_BACKGROUNDCOLOR'; type // ************************************************************************ // "Base" Level objects TWABD_Session = class; TWABD_Setup = class; TWABD_Body = class; TWABD_Form = class; TWABD_HTML = class; TWABD_Base_Frame = class; TWABD_Frame = class; TWABD_Frameset = class; TWABD_ExternalFrame = class; TWABD_Parent = class; TWABD_Admin = class; TWABD_SessionMgr = class; TWABD_Base_Image = class; TWABD_Image = class; TWABD_SectionObject = class; TWABD_Button = class; TWABD_SectionObjectClass = class of TWABD_SectionObject; TWABD_Chart = class; TWABD_Tree = class; TWABD_MenuTree = class; TWABD_MenuTreeClass = class of TWABD_MenuTree; TWABD_Table = class; TWABD_Javascript = class; TWABD_JS_Function = class; TGarbageThread = class(TThread) protected procedure DoGarbageCollection; procedure Execute; override; public SesMgr : TWABD_SessionMgr; end; TWABD_SequenceRec = record Persistent:boolean; Name:PChar; Value:longint; end; PWABD_SequenceRec = ^TWABD_SequenceRec; TWABD_SesStatRec = record Stamp:TDateTime; Value:double; User:PChar; //string[20]; Info:PChar; //string[100]; end; PWABD_SesStatRec = ^TWABD_SesStatRec; TWABD_SesSubStatRec = record Count:longint; Value:double; Min:double; Max:double; end; PWABD_SesSubStatRec = ^TWABD_SesSubStatRec; TWABD_SesSubStat = class(TStringList) public destructor Destroy; override; procedure AddPoint(ID:string; Value:double); procedure ClearPoints; end; TWABD_SesStatGroups = (wabdStatGroupTurnAround,wabdStatGroupCount,wabdStatGroupValue); TWABD_SesStatGroup = class(TThreadList) protected FName:string; FSum:double; FCount:integer; FMin:double; FMax:double; FBufferSize:integer; FGroupType:TWABD_SesStatGroups; public HourlyValues:array [0..23] of double; HourlyCount:array [0..23] of integer; DailyValues:array [1..31] of double; DailyCount:array [1..31] of integer; MonthlyValues:array [1..12] of double; MonthlyCount:array [1..12] of integer; DayValues:array [1..7] of double; DayCount:array [1..7] of integer; SubStat:TWABD_SesSubStat; constructor Create; destructor Destroy; override; procedure Clean; procedure Zero; property Name:string read FName; property Sum:double read FSum; property TotalCount:integer read FCount; property Min:double read FMin; property Max:double read FMax; property BufferSize:integer read FBufferSize; property GroupType:TWABD_SesStatGroups read FGroupType; end; TWABD_SesStat = class(TThreadList) protected public destructor Destroy; override; procedure AddGroup(GrpName:string; GrpType:TWABD_SesStatGroups; BufSize:integer); procedure AddPoint(GrpName:string; User,Info:string; Value:double); procedure Clean; procedure Save(dllname:string); procedure Load(dllname:string); procedure Zero; function IndexOf(GrpName:string):integer; end; TWABD_OnCreateGuestSession = procedure(var NewSession: TWABD_Session; TriedToBeAdmin:boolean; Request:TWABD_CustomRequest) of object; TWABD_OnCreateSession = procedure(var NewSession: TWABD_Session; Request:TWABD_CustomRequest) of object; TWABD_OnDestroySession = procedure(Session: TWABD_Session) of object; TWABD_OnFirstSession = procedure(Session: TWABD_Session) of object; TWABD_OnChartPointClick = procedure(Sender: TObject; Index:integer; SerieLabel,SerieValue:double; SerieLabelString:string) of object; TWABD_Storage = (storeNone,storeIniFile,storeRegistry); TWABD_OnStorage = procedure(Sender:TComponent; Section:String; Reg:TRegistry; Ini:TIniFile) of object; TWABD_Setup = class(TComponent) protected FLock : TRTLCriticalSection; FLocalRootPath : string; FAutoSetGlobalRootPath : boolean; FLocalImagePath : string; FImagePath : string; FLocalFilePath : string; FFilePath : string; FStorage : TWABD_Storage; FStoragePath: string; FSectionName: string; FAutoLoad : boolean; FAutoSave : boolean; FExpandFromRootPath : boolean; FExpandFromGlobalRootPath: boolean; FOnLoad : TWABD_OnStorage; FOnSave : TWABD_OnStorage; procedure Loaded; override; procedure SetLocalRootPath(APath:string); function GetLocalRootPath:string; public constructor Create(AOwner:TComponent); override; destructor Destroy; override; procedure Load; procedure Save; function GetImagePath:string; function GetLocalImagePath:string; function GetFilePath:string; function GetLocalFilePath:string; procedure Lock; procedure Unlock; published property LocalImagePath : string read FLocalImagePath write FLocalImagePath; property ImagePath : string read FImagePath write FImagePath; property LocalFilePath : string read FLocalFilePath write FLocalFilePath; property FilePath : string read FFilePath write FFilePath; property Storage : TWABD_Storage read FStorage write FStorage; property StoragePath:string read FStoragePath write FStoragePath; property SectionName:string read FSectionName write FSectionName; property AutoLoad:boolean read FAutoLoad write FAutoLoad; property AutoSave:boolean read FAutoSave write FAutoSave; property OnLoad:TWABD_OnStorage read FOnLoad write FOnLoad; property OnSave:TWABD_OnStorage read FOnSave write FOnSave; property ExpandFromRootPath:boolean read FExpandFromRootPath write FExpandFromRootPath; property ExpandFromGlobalRootPath:boolean read FExpandFromGlobalRootPath write FExpandFromGlobalRootPath; property LocalRootPath:string read GetLocalRootPath write SetLocalRootPath; property AutoSetGlobalRootPath:boolean read FAutoSetGlobalRootPath write FAutoSetGlobalRootPath; end; TWABD_RouteWhen = (rwNever, rwWhenFull, rwAllways); TWABD_RouteHow = (rhRandom, rhRoundRobin); TWABD_OnAuthenticate = procedure(RemoteHost:string; UserName:string; Password:string; var Authenticated:boolean) of object; TWABD_OnTerminate = function(Flags:integer):boolean of object; TWABD_OnValidateRequest = procedure(Request:TWABD_CustomRequest; Response:TWABD_CustomResponse; var Accept:boolean) of object; TWABD_OnGarbageCollection = procedure(SesMgr:TWABD_SessionMgr) of object; TWABD_OnException = procedure(Sender:TObject; E: Exception; var Handled: boolean) of object; TWABD_SessionMgr = class(TComponent) protected FAbout : TWABDAbout; FCreate : TWABD_OnCreateSession; FDestroy : TWABD_OnDestroySession; FCreateAdmin: TWABD_OnCreateSession; FCreateGuest: TWABD_OnCreateGuestSession; FOnFirstSes : TWABD_OnFirstSession; FOnValidateRequest : TWABD_OnValidateRequest; FOnException: TWABD_OnException; FCheck : integer; // Interval to perform Garbage Collection (seconds) FGarbage : boolean; // True = perform Garbage collection FWebAdmin : string; // Specify string (email, phonenumber or name) for application administrator. FSiteName : string; FRouteSites : TStringList; // Alternative sites to route call to. FRouteWhen : TWABD_RouteWhen; FRouteHow : TWABD_RouteHow; FRouteLast : integer; // Points into FRouteSites for last one routed to. FSiteID : integer; // Unique ID of this site. (-1= allocates randomly) FGatherStats: boolean; FNetWorkStats: boolean; FStats : TWABD_SesStat; FOnAuthenticate : TWABD_OnAuthenticate; FAdmin : TWABD_Admin; FDefSesTimeout: integer; FMaxSessions: integer; FRandomSessionID : boolean; FMaxIdenticalUser: integer; FOnTerminate: TWABD_OnTerminate; FStorage : TWABD_Storage; FStoragePath: string; FSectionName: string; FAutoLoad : boolean; FAutoSave : boolean; FHTMLTimeOut: TStringList; FOnLoad : TWABD_OnStorage; FOnSave : TWABD_OnStorage; FOnGarbageCollection:TWABD_OnGarbageCollection; FInfo : string; FVerDummy : string; FMaxRequestSize:integer; FTotalSessionCount: longint; // Number of sessions created totally until now. FUniqueList: TThreadList; // List containing unique counters. GarbageThrd : TGarbageThread; StopEvent : THandle; SesMgrCSCreate : TRTLCriticalSection; SesMgrCSDestroy : TRTLCriticalSection; SesMgrCSAuth : TRTLCriticalSection; CreateTime : TDateTime; FVariables : TStrings; FRequest : TWABD_CustomRequest; FResponse : TWABD_CustomResponse; function CreateNewSession(Request:TWABD_CustomRequest; Response:TWABD_CustomResponse):TWABD_Session; function RunExistingSession(const IdStr,BodyName:string; Request:TWABD_CustomRequest; Response:TWABD_CustomResponse):TWABD_Session; procedure DoDestroySession(Ses: TWABD_Session); function Authenticate(Request:TWABD_CustomRequest; Response:TWABD_CustomResponse; LikeToBeAdmin:boolean; var IsAdmin:boolean):boolean; procedure SetGatherStats(b:boolean); function GetSessionCount:integer; procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure Loaded; override; procedure SetSiteID(id:integer); function GetRoute:string; function CountIdenticalUser(UserName:string):integer; procedure SetVariables(NewVariables: TStrings); procedure SetVariableByName(AName:string; AValue:string); function GetVariableByName(AName:string):string; function GetVersion:string; public SessionList : TThreadList; function LocateSessionByID(ASiteID:integer; ASessionID:longint):TWABD_Session; procedure CheckLogOff(Ses: TWABD_Session); constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure ClientRequest(Request:TWABD_CustomRequest; Response:TWABD_CustomResponse); function OnTerminateCallback(Flags:longint):boolean; function ProcessVariables(HTML:string):string; property Stats:TWABD_SesStat read FStats; property SessionCount:integer read GetSessionCount; property TotalSessionCount:longint read FTotalSessionCount; procedure Load; procedure Save; procedure CreateSequence(ID:string; StartValue:longint; Persistent:boolean); function DrawSequenceValue(ID:string):longint; procedure DeleteSequence(ID:string); procedure DeleteAllSequences; property VariableByName[s:string]:string read GetVariableByName write SetVariableByName; property Request:TWABD_CustomRequest read FRequest; property Response:TWABD_CustomResponse read FResponse; published property GatherStatistics:boolean read FGatherStats write SetGatherStats; property NetworkStatistics:boolean read FNetworkStats write FNetworkStats; property MaxRequestSize:integer read FMaxRequestSize write FMaxRequestSize; property CheckTimeoutInterval: integer read FCheck write FCheck; property GarbageCollection: boolean read FGarbage write FGarbage; property OnTerminate: TWABD_OnTerminate read FOnTerminate write FOnTerminate; property OnFirstSession: TWABD_OnFirstSession read FOnFirstSes write FOnFirstSes; property OnCreateSession: TWABD_OnCreateSession read FCreate write FCreate; property OnCreateAdminSession: TWABD_OnCreateSession read FCreateAdmin write FCreateAdmin; property OnCreateGuestSession: TWABD_OnCreateGuestSession read FCreateGuest write FCreateGuest; property OnDestroySession: TWABD_OnDestroySession read FDestroy write FDestroy; property OnAuthenticate: TWABD_OnAuthenticate read FOnAuthenticate write FOnAuthenticate; property OnValidateRequest: TWABD_OnValidateRequest read FOnValidateRequest write FOnValidateRequest; property OnException: TWABD_OnException read FOnException write FOnException; property About: TWABDAbout read FAbout write FAbout; property Variables: TStrings read FVariables write SetVariables; property WebAdministrator: string read FWebAdmin write FWebAdmin; property SiteName: string read FSiteName write FSiteName; property SiteID:integer read FSiteID write SetSiteID; property Admin:TWABD_Admin read FAdmin write FAdmin; property DefaultSessionTimeout:integer read FDefSesTimeout write FDefSesTimeout; property MaxConcurrentSessions:integer read FMaxSessions write FMaxSessions; property MaxIdenticalUser:integer read FMaxIdenticalUser write FMaxIdenticalUser; property RandomSessionID:boolean read FRandomSessionID write FRandomSessionID; property RouteSites:TStringList read FRouteSites write FRouteSites; property RouteHow:TWABD_RouteHow read FRouteHow write FRouteHow; property RouteWhen:TWABD_RouteWhen read FRouteWhen write FRouteWhen; property Storage : TWABD_Storage read FStorage write FStorage; property StoragePath:string read FStoragePath write FStoragePath; property SectionName:string read FSectionName write FSectionName; property AutoLoad:boolean read FAutoLoad write FAutoLoad; property AutoSave:boolean read FAutoSave write FAutoSave; property OnLoad:TWABD_OnStorage read FOnLoad write FOnLoad; property OnSave:TWABD_OnStorage read FOnSave write FOnSave; property OnGarbageCollection:TWABD_OnGarbageCollection read FOnGarbageCollection write FOnGarbageCollection; property HTMLTimeOut: TStringList read FHTMLTimeOut write FHTMLTimeOut; property Info:string read FInfo write FInfo; property Version:string read GetVersion write FVerDummy; end; TWABD_OnTimeOut = procedure(SesMgr:TWABD_SessionMgr; ElapsedTime:longint; var AcceptTimeout:boolean) of object; TWABD_OnLogon = procedure(RemoteHost:string) of object; TWABD_OnLogoff = procedure of object; TWABD_BeforeProcessRequest = procedure(Session:TWABD_Session) of object; TWABD_AfterProcessRequest = procedure(Session:TWABD_Session) of object; TWABD_OnRequest = procedure(Session:TWABD_Session; First:boolean) of object; TWABD_Produce = (prodAuto,prodHTML,prodWML); TWABD_Session = class(TComponent) protected FAbout : TWABDAbout; FMainBody : TWABD_Body; FAuthBody : TWABD_Body; FCurBody : TWABD_Body; FNewBody : TWABD_Body; // To "Show" new body FLogon : TWABD_OnLogon; FLogoff : TWABD_OnLogoff; FTimeOut : TWABD_OnTimeOut; FGarbageCollection : TWABD_OnGarbageCollection; DidLogOff : boolean; FTimeLen : integer; FSessionID : longint; FCreateTime : TDateTime; FLastAccess : TDateTime; FUserName:string; FPassword:string; FQueryFields:TStrings; FHitCount:integer; // Number of hits on this session. FExcept : TWABD_OnException; FVariables : TStrings; FSessionMgr : TWABD_SessionMgr; FDetermineBrowser : boolean; FBeforeProcessRequest : TWABD_BeforeProcessRequest; FAfterProcessRequest : TWABD_AfterProcessRequest; FOnRequest : TWABD_OnRequest; FInfo : string; FSemaphore : THandle; // Used to serialize requests for this session. (Frames could async. do requests) FLockCount : integer; FStateless : boolean; FEnableCookies:boolean; FVerDummy : string; FProduce : TWABD_Produce; FRequest : TWABD_CustomRequest; FResponse : TWABD_CustomResponse; procedure SetVariables(NewVariables: TStrings); procedure SetQueryFields(NewQueryFields:TStrings); procedure SetCookies(NewCookies:TWABD_Cookies); procedure SetVariableByName(AName:string; AValue:string); procedure SetCookieByName(AName:string; AValue:string); procedure SetQueryFieldByName(AName:string; AValue:string); function GetVariableByName(AName:string):string; function GetCookieByName(AName:string):string; function GetQueryFieldByName(AName:string):string; function GetCookies:TWABD_Cookies; function ProcessRequest(BodyName:string; Request:TWABD_CustomRequest): string; // procedure Lock; // procedure Unlock; procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure Loaded; override; function Authenticate:boolean; function GetSesUserName:string; function GetSesPassword:string; function GetVersion:string; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure LogOff; function ProcessVariables(HTML:string):string; procedure SendFile(ContentType,FileName,AsFileName:string); procedure LockSession; procedure UnlockSession; property SessionID:longint read FSessionID; property CurBody: TWABD_Body read FCurBody; property NewBody: TWABD_Body read FNewBody write FNewBody; property SessionMgr: TWABD_SessionMgr read FSessionMgr; property UserName:string read GetSesUserName; property Password:string read GetSesPassword; property LastAccess:TDateTime read FLastAccess; property CreateTime:TDateTime read FCreateTime; property HitCount:integer read FHitCount; property VariableByName[s:string]:string read GetVariableByName write SetVariableByName; property CookieByName[s:string]:string read GetCookieByName write SetCookieByName; property QueryFieldByName[s:string]:string read GetQueryFieldByName write SetQueryFieldByName; property Cookies:TWABD_Cookies read GetCookies write SetCookies; property QueryFields:TStrings read FQueryFields write SetQueryFields; property Response:TWABD_CustomResponse read FResponse; property Request:TWABD_CustomRequest read FRequest; published property MainBody: TWABD_Body read FMainBody write FMainBody; property AuthBody: TWABD_Body read FAuthBody write FAuthBody; property Variables: TStrings read FVariables write SetVariables; property TimeOutLength: integer read FTimeLen write FTimeLen; property OnFirstLogon: TWABD_OnLogon read FLogon write FLogon; property OnLogoff: TWABD_OnLogoff read FLogoff write FLogoff; property OnTimeOut: TWABD_OnTimeOut read FTimeOut write FTimeOut; property OnGarbageCollection: TWABD_OnGarbageCollection read FGarbageCollection write FGarbageCollection; property OnException: TWABD_OnException read FExcept write FExcept; property About: TWABDAbout read FAbout write FAbout; property DoDetermineBrowser: boolean read FDetermineBrowser write FDetermineBrowser; property BeforeProcessRequest : TWABD_BeforeProcessRequest read FBeforeProcessRequest write FBeforeProcessRequest; property AfterProcessRequest : TWABD_AfterProcessRequest read FAfterProcessRequest write FAfterProcessRequest; property OnRequest : TWABD_OnRequest read FOnRequest write FOnRequest; property Info:string read FInfo write FInfo; property Stateless:boolean read FStateless write FStateless; property EnableCookies:boolean read FEnableCookies write FEnableCookies; property Version:string read GetVersion write FVerDummy; property Produce:TWABD_Produce read FProduce write FProduce; end; TWABD_Logging = (logNothing,logLevel1,logLevel2,logAll); TWABD_Admin = class(TComponent) protected FAdminUser:string; FAdminPassword:string; FLogoutHTML:string; LogCS : TRTLCriticalSection; FLogging:boolean; FLogFile:string; FStorage : TWABD_Storage; FStoragePath: string; FSectionName: string; FAutoLoad : boolean; FAutoSave : boolean; FLogWhat : TWABD_Logging; FOnLoad : TWABD_OnStorage; FOnSave : TWABD_OnStorage; procedure Loaded; override; function GetLogging:boolean; public constructor Create(AOwner:TComponent); override; destructor Destroy; override; procedure LogFmt(fmt:string; args:array of const); procedure Log(Text:string); procedure Load; procedure Save; published property AdminUser:string read FAdminUser write FAdminUser; property AdminPassword:string read FAdminPassword write FAdminPassword; property LogoutHTML:string read FLogoutHTML write FLogoutHTML; property Logging:boolean read GetLogging write FLogging; property LogFile:string read FLogFile write FLogFile; property AutoLog:TWABD_Logging read FLogWhat write FLogWhat; property Storage : TWABD_Storage read FStorage write FStorage; property StoragePath:string read FStoragePath write FStoragePath; property SectionName:string read FSectionName write FSectionName; property AutoLoad:boolean read FAutoLoad write FAutoLoad; property AutoSave:boolean read FAutoSave write FAutoSave; property OnLoad:TWABD_OnStorage read FOnLoad write FOnLoad; property OnSave:TWABD_OnStorage read FOnSave write FOnSave; end; TWABD_ObjectClass = class of TWABD_Object; TWABD_Object = class(TComponent) protected FAbout : TWABDAbout; FParent : TWABD_Parent; FParentName : string; // tmp to hold name before all components are loaded FOnChange : TNotifyEvent; FVisible : boolean; FPathInfo : string; FOrder : integer; // Only used on loading InLoaded : boolean; FDependingOn: TWABD_Object; procedure SetParent(NewParent: TWABD_Parent); procedure SetVisible(b: boolean); function GetVisible:boolean; procedure Changed; procedure DefineProperties(Filer: TFiler); override; procedure Loaded; override; procedure ReadParentName(Reader: TReader); procedure WriteParentName(Writer: TWriter); function GetOrder: integer; procedure SetOrder(NewOrder: integer); procedure SetName(const Value: TComponentName); override; procedure Notification(AComponent: TComponent; Operation: TOperation); override; function GetSession: TWABD_Session; function GetSessionID: longint; function GetDLLName: string; property PathInfo:string read FPathInfo write FPathInfo; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function GetHRef(Body:TWABD_Body; Component:TWABD_Object; WabdType,Data:string):string; function Object_To_HTML: string; virtual; abstract; function Object_To_WML: string; virtual; function Object_To_WML_Postfield: string; virtual; function Object_To_Control(AOwner: TWinControl): TControl; virtual; abstract; procedure HTML_To_Object(FormVal: string); virtual; abstract; function GetParentForm: TWABD_Form; procedure SaveHTMLToFile(AFile:string); procedure SaveWMLToFile(AFile:string); property OnChange: TNotifyEvent read FOnChange write FOnChange; property Parent: TWABD_Parent read FParent write SetParent; property Order: integer read GetOrder write SetOrder; property Session:TWABD_Session read GetSession; property SessionID:longint read GetSessionID; property DLLName:string read GetDLLName; published property Visible: boolean read GetVisible write SetVisible; property About: TWABDAbout read FAbout write FAbout; property DependingOn: TWABD_Object read FDependingOn write FDependingOn; end; TWABD_ForEach = procedure(Child: TWABD_Object; var Stop: boolean; UserData: pointer) of object; TWABD_Parent = class(TWABD_Object) protected FWABD_Objs : TList; tmp : string; TheChild : TWABD_Object; function GetWABDObjects(i: integer): TWABD_Object; function GetWABDObjCount: integer; function ButtonByCaption(Caption: string): TWABD_Button; function GetDefaultButton: TWABD_Button; procedure DefButProc(Child: TWABD_Object; var Stop: boolean; UserData: pointer); procedure ChildNameProc(Child: TWABD_Object; var Stop: boolean; UserData: pointer); procedure ButCapProc(Child: TWABD_Object; var Stop: boolean; UserData: pointer); procedure ChildChanged(Sender: TObject); virtual; procedure Loaded; override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_Control(AOwner: TWinControl): TControl; override; function ForEachChild(ForEachProc: TWABD_ForEach; UserData: pointer): boolean; property Children[i: integer] : TWABD_Object read GetWABDObjects; property ChildCount: integer read GetWABDObjCount; function ChildByName(ChildName: string): TWABD_Object; end; // ************************************************************************ // "Top" Level objects TWABD_ReflectNotify = procedure(Sender: TObject; AComponent: TComponent; Operation: TOperation) of object; TChildNameChangedProc = procedure(Sender: TObject; const OldName, NewName: string) of object; TWABDEditForm = class(TPersistent) public ParForm : TWABD_Form; end; TWABDEditFrameset = class(TPersistent) public ParFrameset : TWABD_Frameset; end; TFrameDivision = (fdHorizontal, fdVertical); TFrameScroll = (fsAuto,fsYes,fsNo); TWABD_Base_Frame=class(TWABD_Object) protected FFrameName:string; end; TWABD_ExternalFrameType = (eftOther,eftBlank,eftTop,eftParent,eftSearch,eftSelf); TWABD_ExternalFrame = class(TWABD_Base_Frame) protected FType:TWABD_ExternalFrameType; procedure SetFrameType(AType:TWABD_ExternalFrameType); procedure SetFrameName(AName:string); public constructor Create(AOwner:TComponent); override; function Object_To_HTML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property FrameType:TWABD_ExternalFrameType read FType write SetFrameType; property FrameName:string read FFrameName write SetFrameName; end; TWABD_Frame = class(TWABD_Base_Frame) protected FSize:integer; FVisible:boolean; FLinkBody:TWABD_Body; FFrameBorder:boolean; FBorderColor:TColor; FResize:boolean; FScrolling:TFrameScroll; FMarginHeight:integer; FMarginWidth:integer; procedure SetFrameset(frameset:TWABD_Frameset); function GetFrameset:TWABD_Frameset; procedure SetLinkBody(body:TWABD_Body); procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure SetName(const Value: TComponentName); override; public constructor Create(AOwner: TComponent); override; property FrameName:string read FFrameName; published property Size:integer read FSize write FSize; property Visible:boolean read FVisible write FVisible; property LinkBody:TWABD_Body read FLinkBody write SetLinkBody; property Frameset:TWABD_Frameset read GetFrameset write SetFrameset; property FrameBorder:boolean read FFrameBorder write FFrameBorder; property BorderColor:TColor read FBorderColor write FBorderColor; property Resize:boolean read FResize write FResize; property Scrolling:TFrameScroll read FScrolling write FScrolling; property MarginHeight:integer read FMarginHeight write FMarginHeight; property MarginWidth:integer read FMarginWidth write FMarginWidth; end; TWABD_OnSubmit = procedure(Sender: TObject; Request:TWABD_CustomRequest) of object; TWABD_Body = class(TWABD_Parent) protected FFrame : TWABD_Frame; FOnCreate : TNotifyEvent; FOnShow : TNotifyEvent; FOnSubmit : TWABD_OnSubmit; FJavascript : TWABD_Javascript; FJS_OnUserLoad: TWABD_JS_Function; FJS_OnUserUnload: TWABD_JS_Function; FJS_OnUserEvent: TWABD_JS_Function; FJS_OnUserSubmit: TWABD_JS_Function; FWSession : TWABD_Session; FNameChge : TChildNameChangedProc; FCloseOpener: boolean; FClientSubmitTimeStamp: double; FClientLoadTimeStamp: double; FClientProcessTime: double; FFieldValues: TStrings; FIsReload : boolean; FUseSessionCookie:boolean; FEncType : string; procedure ProcessRequest(Request:TWABD_CustomRequest); virtual; procedure DoShow; virtual; property JS_OnUserEvent:TWABD_JS_Function read FJS_OnUserEvent write FJS_OnUserEvent; property JS_OnUserLoad:TWABD_JS_Function read FJS_OnUserLoad write FJS_OnUserLoad; property JS_OnUserUnload:TWABD_JS_Function read FJS_OnUserUnload write FJS_OnUserUnload; property JS_OnUserSubmit:TWABD_JS_Function read FJS_OnUserSubmit write FJS_OnUserSubmit; property EncType:string read FEncType write FEncType; function GetFieldValueCount:integer; function GetFieldValue(i:integer):string; function GetFieldValueByName(s:string):string; procedure SetFieldValue(i:integer; Value:string); procedure SetFieldValueByName(s:string; Value:string); public RefNotify : TWABD_ReflectNotify; // No one should use this but it's Component Editor procedure CreateSessionCookie; property Session: TWABD_Session read FWSession write FWSession; property OnChildNameChanged: TChildNameChangedProc read FNameChge write FNameChge; property CloseOpener:boolean read FCloseOpener write FCloseOpener; property Frame:TWABD_Frame read FFrame; property ClientSubmitTimeStamp:double read FClientSubmitTimeStamp; property ClientLoadTimeStamp:double read FClientLoadTimeStamp; property ClientProcessTime:double read FClientProcessTime; property IsReload:boolean read FIsReload; property ValueCount:integer read GetFieldValueCount; property Values[i:integer]:string read GetFieldValue write SetFieldValue; property ValueByName[s:string]:string read GetFieldValueByName write SetFieldValueByName; constructor Create(AOwner:TComponent); override; destructor Destroy; override; published property OnCreate: TNotifyEvent read FOnCreate write FOnCreate; property OnShow: TNotifyEvent read FOnShow write FOnShow; property OnSubmit:TWABD_OnSubmit read FOnSubmit write FOnSubmit; property Javascript:TWABD_Javascript read FJavascript write FJavascript; property UseSessionCookie:boolean read FUseSessionCookie write FUseSessionCookie; end; TWABD_Base_HTML = class(TWABD_Body) protected FOnSubmit:TWABD_OnSubmit; FHTML : TStrings; property HTML:TStrings read FHTML write FHTML; public constructor Create(AOwner:TComponent); override; destructor Destroy; override; procedure Show; end; TWABD_HTML = class(TWABD_Base_HTML) protected public function Object_To_HTML: string; override; function Object_To_WML:string; override; procedure HTML_To_Object(FormVal: string); override; published property HTML; property JS_OnUserLoad; property JS_OnUserUnload; property EncType; end; TWABD_HTMLFile = class(TWABD_Base_HTML) protected FFileName : TFileName; FSetup : TWABD_Setup; FLoadedWhen : TDateTime; FSecsBeforeReload : integer; FCached : boolean; procedure Notification(AComponent: TComponent; Operation: TOperation); override; public constructor Create(AOwner:TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_WML:string; override; procedure HTML_To_Object(FormVal: string); override; procedure Reload; property LoadedWhen:TDateTime read FLoadedWhen; property HTML; published property FileName:TFileName read FFileName write FFileName; property SecsBeforeReload:integer read FSecsBeforeReload write FSecsBeforeReload; property Cached:boolean read FCached write FCached; property Setup:TWABD_Setup read FSetup write FSetup; property JS_OnUserLoad; property JS_OnUserUnload; property EncType; end; TWABD_Frameset = class(TWABD_Body) protected FFramesetTitle: string; FDivision : TFrameDivision; FBorderWidth: integer; FBorderColor: TColor; FFrameBorder: boolean; FParentFrame: TWABD_Frame; FEdFrameset : TWABDEditFrameset; procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure SetEdFrameset(NewEdFrameset: TWABDEditFrameset); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; procedure Loaded; override; procedure Show; function DoPostScript: string; function DoPreScript: string; published property Division:TFrameDivision read FDivision write FDivision; property BorderWidth:integer read FBorderWidth write FBorderWidth; property BorderColor:TColor read FBorderColor write FBorderColor; property FrameBorder:boolean read FFrameBorder write FFrameBorder; property Title:string read FFramesetTitle write FFramesetTitle; property EditFrameset: TWABDEditFrameset read FEdFrameset write SetEdFrameset; property JS_OnUserLoad; property JS_OnUserUnload; end; TWABD_HorzAlignment = (alhNone,alhLeft,alhCenter,alhRight); TWABD_VertAlignment = (alvNone,alvTop,alvMiddle,alvBottom,alvBaseline); TWABD_OnUserCallback = procedure(Sender: TObject; Data:string) of object; TWABD_OnSubmitForm = procedure(Sender: TObject; Request:TWABD_CustomRequest; var ProcessEvents:boolean) of object; TWABD_OnOutOfOrder = procedure(Sender: TObject; Request:TWABD_CustomRequest; var DoSetProperties,DoProcessEvents:boolean) of object; TWABD_Form = class(TWABD_Body) private function GetEventID(var str:string):string; procedure SplitEventID(str:string;var EventID:integer; var CtrlName:string; var Data:string); protected FCheckOutOfOrder:boolean; FOutOfOrder : boolean; FOnOutOfOrder:TWABD_OnOutOfOrder; FSubmitCount : longint; FOnSubmitForm : TWABD_OnSubmitForm; FOnUserCallback: TWABD_OnUserCallback; FJS_OnUserEventSubmit: TWABD_JS_Function; FEdForm : TWABDEditForm; FSubmitTo : TWABD_Base_Frame; FSesID : longint; FTextColor : TColor; FLinkColor : TColor; FVLinkColor : TColor; FALinkColor : TColor; FBgndColor : TColor; FBgrdImage : TWABD_Image; FTitle : string; FMarginTop :integer; FMarginBottom:integer; FMarginLeft :integer; FMarginRight :integer; FHeight : integer; FWidth : integer; FEventHandlersOnForm : boolean; FUploadFileOnForm : boolean; function GetFormBody: string; function FormSections_To_HTML: string; virtual; function FormSections_To_WML: string; virtual; function FormSections_To_WML_Postfield: string; virtual; function DoPreScript: string; function DoPostScript: string; procedure ClearControl(Child: TWABD_Object; var Stop: boolean; UserData: pointer); procedure ParseImageParams(Request: TWABD_CustomRequest; var ImageName: string; var x,y: integer); procedure SetProperties(Request:TWABD_CustomRequest); procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure SetName(const Value: TComponentName); override; procedure SetEdForm(NewEdForm: TWABDEditForm); procedure Call_Handler(Request:TWABD_CustomRequest); procedure ProcessRequest(Request:TWABD_CustomRequest); override; function OutOfOrder(Request:TWABD_CustomRequest):boolean; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure ChildChanged(Sender: TObject); override; function Object_To_HTML: string; override; function Object_To_WML:string; override; procedure HTML_To_Object(FormVal: string); override; procedure Show; procedure Loaded; override; property IsOutOfOrder:boolean read FOutOfOrder; published property EncType; property TextColor: TColor read FTextColor write FTextColor; property LinkColor: TColor read FLinkColor write FLinkColor; property VLinkColor: TColor read FVLinkColor write FVLinkColor; property ALinkColor: TColor read FALinkColor write FALinkColor; property BgndColor: TColor read FBgndColor write FBgndColor; property CheckOutOfOrder:boolean read FCheckOutOfOrder write FCheckOutOfOrder; property OnOutOfOrder: TWABD_OnOutOfOrder read FOnOutOfOrder write FOnOutOfOrder; property OnSubmitForm: TWABD_OnSubmitForm read FOnSubmitForm write FOnSubmitForm; property OnUserCallback: TWABD_OnUserCallBack read FOnUserCallback write FOnUserCallback; property BgrdImage: TWABD_Image read FBgrdImage write FBgrdImage; property FormTitle: string read FTitle write FTitle; property EditForm: TWABDEditForm read FEdForm write SetEdForm; property SubmitToFrame: TWABD_Base_Frame read FSubmitTo write FSubmitTo; property MarginTop:integer read FMarginTop write FMarginTop; property MarginBottom:integer read FMarginBottom write FMarginBottom; property MarginLeft:integer read FMarginLeft write FMarginLeft; property MarginRight:integer read FMarginRight write FMarginRight; property Width:integer read FWidth write FWidth; property Height:integer read FHeight write FHeight; property JS_OnUserEventSubmit:TWABD_JS_Function read FJS_OnUserEventSubmit write FJS_OnUserEventSubmit; property JS_OnUserSubmit; property JS_OnUserEvent; property JS_OnUserLoad; property JS_OnUserUnload; end; TWABD_FormSection_Base = class(TWABD_Parent) private FWidth : integer; FHeight : integer; FHorzAlign : TWABD_HorzAlignment; FVertAlign : TWABD_VertAlignment; FEventHandlersOnFormSection : boolean; FTitle : string; published property Width: integer read FWidth write FWidth default 0; property Height: integer read FHeight write FHeight default 0; property HorzAlign:TWABD_HorzAlignment read FHorzAlign write FHorzAlign; property VertAlign:TWABD_VertAlignment read FVertAlign write FVertAlign; property Title:string read FTitle write FTitle; end; TWABD_FormSection_Grid = class(TWABD_FormSection_Base) private NumRow : integer; NumCol : integer; ColSizes : array[0..255] of integer; // eg 5,5,6,6 RowSizes : array[0..255] of integer; ColTot : array[0..255] of integer; // eg 5,10,16,22 RowTot : array[0..255] of integer; FindCol : integer; // Used by ControlAtFunc FindRow : integer; FindCon : TWABD_SectionObject; protected FGridX : integer; FGridY : integer; FCellBorder : integer; FCellSpace : integer; FCellPad : integer; FNoWrap : boolean; function FormSection_To_HTML: string; virtual; function FormSection_To_WML: string; virtual; function FormSection_To_WML_Postfield: string; virtual; procedure SetGridX(NewX: integer); procedure SetGridY(NewY: integer); procedure AutoSizeRowCol; procedure ControlAtFunc(Child: TWABD_Object; var Stop: boolean; UserData: pointer); public constructor Create(AOwner: TComponent); override; function Object_To_HTML: string; override; function Object_To_WML:string; override; function Object_To_WML_Postfield:string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; function AddControl(ControlClass: TWABD_SectionObjectClass; Col, Row: integer): TWABD_SectionObject; function ControlAtPos(Col, Row: integer): TWABD_SectionObject; published property GridX: integer read FGridX write SetGridX default 16; property GridY: integer read FGridY write SetGridY default 16; property CellBorder: integer read FCellBorder write FCellBorder; property CellSpacing: integer read FCellSpace write FCellSpace; property CellPadding: integer read FCellPad write FCellPad; property NoWrap:boolean read FNoWrap write FNoWrap; end; TWABD_FormSection = class(TWABD_FormSection_Grid) published end; TWABD_Header = class(TWABD_FormSection_Base) protected FNum : integer; FCaption : string; procedure SetNum(NewNum: integer); procedure SetName(const Value: TComponentName); override; public constructor Create(AOwner: TComponent); override; function Object_To_HTML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property HeaderNum: integer read FNum write SetNum; property Caption: string read FCaption write FCaption; end; TWABDEditTree = class(TPersistent) public ParTree : TWABD_Tree; end; TWABD_TreeNode = class(TWABD_Object) private FCaption : string; FLevel : integer; FHint : string; FImgIconLink : TWABD_Image; FSubmitTo : TWABD_Base_Frame; FDefaultOpen: boolean; FOnUserClick: TNotifyEvent; FJS_OnUserClick: TWABD_JS_Function; procedure SetCaption(s:string); protected procedure DefineProperties(Filer: TFiler); override; procedure WriteLevel(Writer: TWriter); procedure ReadLevel(Reader: TReader); procedure Notification(AComponent: TComponent; Operation: TOperation); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; property Level:integer read FLevel write FLevel stored true; published property SubmitToFrame:TWABD_Base_Frame read FSubmitTo write FSubmitTo; property Caption:string read FCaption write SetCaption; property Hint:string read FHint write FHint; property Icon:TWABD_Image read FImgIconLink write FImgIconLink; property DefaultOpen:boolean read FDefaultOpen write FDefaultOpen; property OnUserClick:TNotifyEvent read FOnUserClick write FOnUserClick; property JS_OnUserClick:TWABD_JS_Function read FJS_OnUserClick write FJS_OnUserClick; end; TWABD_AddTreeNodeFlag = (atnFirst,atnLast,atnAfter,atnBefore,atnChild); TWABD_AddTreeNodeFlags = set of TWABD_AddTreeNodeFlag; TWABD_TreeClick = procedure(Sender: TObject; Node:TWABD_TreeNode) of object; TWABD_Tree = class(TWABD_Body) protected FEdTree : TWABDEditTree; // Dummy for getting property editor up and running. FOnUserClick: TNotifyEvent; FJS_OnUserClick: TWABD_JS_Function; procedure SetEdTree(NewEdTree: TWABDEditTree); procedure ProcessRequest(Request:TWABD_CustomRequest); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; function NodeByName(NodeName:string):TWABD_TreeNode; function AddNode(Name:string; RefNode:TWABD_TreeNode; Flags:TWABD_AddTreeNodeFlags):TWABD_TreeNode; procedure DeleteNode(ANode:TWABD_TreeNode; FreeNode:boolean); procedure Clear(FreeNodes:boolean); published property Tree: TWABDEditTree read FEdTree write SetEdTree; property OnUserClick:TNotifyEvent read FOnUserClick write FOnUserClick; property JS_OnUserClick:TWABD_JS_Function read FJS_OnUserClick write FJS_OnUserClick; property JS_OnUserEvent; end; TWABD_MenuTree = class(TWABD_Tree) protected FCaption : string; FJavascript : TWABD_Javascript; FImages : TStrings; FVariables : TStrings; FFontColor : TColor; FFontSize : integer; FLinkColor : TColor; FVLinkColor : TColor; FALinkColor : TColor; FBGColor : TColor; FSubmitTo : TWABD_Base_Frame; FImgIconBlank : TWABD_Image; FImgIconBranchCont : TWABD_Image; FImgIconBranchEnd : TWABD_Image; FImgIconFolderClosed : TWABD_Image; FImgIconFolderOpen : TWABD_Image; FImgIconRoot : TWABD_Image; FImgIconMinusCont : TWABD_Image; FImgIconMinusEnd : TWABD_Image; FImgIconPlusCont : TWABD_Image; FImgIconPlusEnd : TWABD_Image; FImgIconVertLine : TWABD_Image; FImgIconLink : TWABD_Image; FBgrdImage : TWABD_Image; procedure Notification(AComponent: TComponent; Operation: TOperation); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_Top_HTML: string; procedure HTML_To_Object(FormVal: string); override; procedure SetupVariables; function GenMenuTreeJSSetup:string; published property Caption:string read FCaption write FCaption; property Images:TStrings read FImages write FImages; property Javascript:TWABD_Javascript read FJavascript write FJavascript; property TextColor:TColor read FFontColor write FFontColor; property TextSize:integer read FFontSize write FFontSize; property BgndColor:TColor read FBGColor write FBGColor; property SubmitToFrame: TWABD_Base_Frame read FSubmitTo write FSubmitTo; property LinkColor: TColor read FLinkColor write FLinkColor; property VLinkColor: TColor read FVLinkColor write FVLinkColor; property ALinkColor: TColor read FALinkColor write FALinkColor; property IconBlank : TWABD_Image read FImgIconBlank write FImgIconBlank; property IconBranchCont : TWABD_Image read FImgIconBranchCont write FImgIconBranchCont; property IconBranchEnd : TWABD_Image read FImgIconBranchEnd write FImgIconBranchEnd; property IconFolderClosed : TWABD_Image read FImgIconFolderClosed write FImgIconFolderClosed; property IconFolderOpen : TWABD_Image read FImgIconFolderOpen write FImgIconFolderOpen; property IconRoot : TWABD_Image read FImgIconRoot write FImgIconRoot; property IconMinusCont : TWABD_Image read FImgIconMinusCont write FImgIconMinusCont; property IconMinusEnd : TWABD_Image read FImgIconMinusEnd write FImgIconMinusEnd; property IconPlusCont : TWABD_Image read FImgIconPlusCont write FImgIconPlusCont; property IconPlusEnd : TWABD_Image read FImgIconPlusEnd write FImgIconPlusEnd; property IconVertLine : TWABD_Image read FImgIconVertLine write FImgIconVertLine; property IconLink : TWABD_Image read FImgIconLink write FImgIconLink; property BgrdImage : TWABD_Image read FBgrdImage write FBgrdImage; end; TWABD_HTMLSection = class(TWABD_FormSection_Base) protected FHTML : TStrings; procedure SetHTML(NewHTML: TStrings); procedure SetName(const Value: TComponentName); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property HTML: TStrings read FHTML write SetHTML; end; TWABD_HTMLFileSection = class(TWABD_HTMLSection) protected FFileName : TFileName; FSetup : TWABD_Setup; FLoadedWhen : TDateTime; FSecsBeforeReload : integer; FCached : boolean; procedure Notification(AComponent: TComponent; Operation: TOperation); override; public procedure Reload; property LoadedWhen:TDateTime read FLoadedWhen; constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_WML: string; override; published property FileName:TFileName read FFileName write FFileName; property SecsBeforeReload:integer read FSecsBeforeReload write FSecsBeforeReload; property Cached:boolean read FCached write FCached; property Setup:TWABD_Setup read FSetup write FSetup; end; TWABD_JS_Function_Placement = (jsfFirst,jsfLast); TWABD_JS_Function_Type = (jsOnEvent, jsOnClick,jsOnDblClick, jsOnChange, jsOnFocus,jsOnBlur, jsOnLoad,jsOnUnload, jsOnSubmit, jsOnMouseDown,jsOnMouseUp,jsOnMouseOver,jsOnMouseOut,jsOnMouseMove, jsOnKeyPress,jsOnKeyDown,jsOnKeyUp); TWABD_JS_Function = class(TPersistent) protected FParams:TStringList; FScript:string; FPlacement:TWABD_JS_Function_Placement; FType:TWABD_JS_Function_Type; procedure SetScript(scr:string); public constructor Create(jsType:TWABD_JS_Function_Type); destructor Destroy; override; published property Params:TStringList read FParams write FParams; property Script:string read FScript write SetScript; property Placement:TWABD_JS_Function_Placement read FPlacement write FPlacement; property FunctionType:TWABD_JS_Function_Type read FType; end; TWABD_JS_Placement = (jsFirst,jsLast); TWABD_Javascript = class(TWABD_Object) protected FPlacement : TWABD_JS_Placement; FLines : TStrings; FSetup : TWABD_Setup; FWSession : TWABD_Session; procedure SetLines(NewLines: TStrings); procedure Notification(AComponent: TComponent; Operation: TOperation); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function ProcessMacros(JS:string):string; property Session: TWABD_Session read FWSession write FWSession; published property Setup: TWABD_Setup read FSetup write FSetup; property Placement:TWABD_JS_Placement read FPlacement write FPlacement; property Lines:TStrings read FLines write FLines; end; TWABD_Autorefresh = class(TWABD_Object) private FInterval : integer; FNewSession : boolean; FURL : string; public function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property NewSession:boolean read FNewSession write FNewSession; property Interval: integer read FInterval write FInterval; property URL:string read FURL write FURL; end; TWABD_Expires = class(TWABD_Object) private FExpires : TDatetime; FMaxAge : integer; FAlwaysReload : boolean; public constructor Create(AOwner:TComponent); override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property Expires: TDatetime read FExpires write FExpires; property MaxAge:integer read FMaxAge write FMaxAge; property AlwaysReload: boolean read FAlwaysReload write FAlwaysReload; end; TWABDTableClick = procedure(Sender: TObject; RowIndex: integer) of object; TWABD_BaseTable = class(TWABD_FormSection_Base) protected FCellBorder : integer; FCellSpace : integer; FCanClick : boolean; FClickText : string; FOnUserClick: TWABDTableClick; published constructor Create(AOwner: TComponent); override; property CellBorder: integer read FCellBorder write FCellBorder; property CellSpacing: integer read FCellSpace write FCellSpace; property CanClick: boolean read FCanClick write FCanClick; property ClickText: string read FClickText write FClickText; property OnUserClick: TWABDTableClick read FOnUserClick write FOnUserClick; end; TStringArray = array[0..0] of PChar; PStringArray = ^TStringArray; TWABD_Table_Strings = class(TPersistent) protected XSize : integer; YSize : integer; FData : PStringArray; function GetString(x,y: integer): string; procedure SetString(x,y: integer; NewString: string); procedure DefineProperties(Filer: TFiler); override; procedure WriteProps(Writer: TWriter); procedure ReadProps(Reader: TReader); procedure SetSize(x,y: integer); procedure FreeData; public constructor Create; destructor Destroy; override; procedure Assign(Source: TPersistent); override; procedure SafeSetSize(x,y: integer); property Strings[x,y: integer]: string read GetString write SetString; default; property Cols: integer read XSize; property Rows: integer read YSize; end; TStringGridEx = class(TStringGrid) public ClickText : string; CanClick : boolean; end; TWABD_OnSetupJavascriptEvent = procedure(Sender:TWABD_Table; Row,Col:integer; var ID,OnMouseDown,OnMouseUp,OnMouseOver,OnMouseOut,OnClick,OnDblClick,OnKeyPress,OnKeyDown,OnKeyUp:string; var Target:TWABD_Base_Frame) of object; TWABD_OnRenderCellEvent = procedure(Sender: TWABD_Table; Row,Col:integer; var Text:string; var HAlign:TWABD_HorzAlignment; var VAlign:TWABD_VertAlignment; var Color,BGColor:TColor; var Size:integer; var Bold,Italic,Underline,Fixed,Strike:boolean; var Width,Height:integer; var AllowWordWrap:boolean) of object; TWABD_OnSetupClickableCellEvent = procedure(Sender:TWABD_Table; Row,Col:integer; var Clickable:boolean; var Target:TWABD_Base_Frame) of object; TWABD_OnUserClickCellEvent = procedure(Sender:TWABD_Object; Row,Col:integer) of object; TWABD_Table = class(TWABD_BaseTable) protected // CellData FFixCol : integer; FFixRow : integer; FStrings : TWABD_Table_Strings; FColWid : array[0..255] of integer; FColAlign : array[0..255] of TWABD_HorzAlignment; FColWrap : array[0..255] of boolean; FColClickable: array[0..255] of boolean; FRenderCell : TWABD_OnRenderCellEvent; FSetupClickableCell : TWABD_OnSetupClickableCellEvent; FSetupCellJavascript : TWABD_OnSetupJavascriptEvent; FSetupRowJavascript : TWABD_OnSetupJavascriptEvent; FUserClickCell : TWABD_OnUserClickCellEvent; FBGColor : TColor; FFontSize : integer; FFontColor : TColor; FWidth : integer; FHeight : integer; FShowEmptyRows : boolean; FOptimize : boolean; FLiteral : boolean; FSubmitTo : TWABD_Base_Frame; FJS_OnUserKeyPress:TWABD_JS_Function; FJS_OnUserKeyDown:TWABD_JS_Function; FJS_OnUserKeyUp:TWABD_JS_Function; FJS_OnUserClick:TWABD_JS_Function; FJS_OnUserDblClick:TWABD_JS_Function; FJS_OnUserMouseMove:TWABD_JS_Function; FJS_OnUserMouseOver:TWABD_JS_Function; FJS_OnUserMouseOut:TWABD_JS_Function; FJS_OnUserMouseDown:TWABD_JS_Function; FJS_OnUserMouseUp:TWABD_JS_Function; procedure SetStrings(NewStrings: TWABD_Table_Strings); function GetBut(Row: integer): string; function GetColWidth(i: integer): integer; procedure SetColWidth(i: integer; v: integer); function GetColAlign(i: integer): TWABD_HorzAlignment; procedure SetColAlign(i: integer; v: TWABD_HorzAlignment); function GetColWrap(i: integer): boolean; procedure SetColWrap(i: integer; v: boolean); function GetColClickable(i: integer): boolean; procedure SetColClickable(i: integer; v: boolean); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; property ColWidth[i: integer]: integer read GetColWidth write SetColWidth; property ColAlign[i: integer]: TWABD_HorzAlignment read GetColAlign write SetColAlign; property ColWrap[i: integer]: boolean read GetColWrap write SetColWrap; property ColClickable[i: integer]: boolean read GetColClickable write SetColClickable; published property FixedCols: integer read FFixCol write FFixCol; property FixedRows: integer read FFixRow write FFixRow; property FontSize: integer read FFontSize write FFontSize; property FontColor: TColor read FFontColor write FFontColor; property Cells: TWABD_Table_Strings read FStrings write SetStrings; property OnRenderCell:TWABD_OnRenderCellEvent read FRenderCell write FRenderCell; property OnSetupClickableCell:TWABD_OnSetupClickableCellEvent read FSetupClickableCell write FSetupClickableCell; property OnSetupCellJavascript:TWABD_OnSetupJavascriptEvent read FSetupCellJavascript write FSetupCellJavascript; property OnSetupRowJavascript:TWABD_OnSetupJavascriptEvent read FSetupRowJavascript write FSetupRowJavascript; property OnUserClickCell:TWABD_OnUserClickCellEvent read FUserClickCell write FUserClickCell; property Width: integer read FWidth write FWidth; property Height: integer read FHeight write FHeight; property ShowEmptyRows:boolean read FShowEmptyRows write FShowEmptyRows; property BGColor:TColor read FBGColor write FBGColor; property Optimize:boolean read FOptimize write FOptimize; property Literal:boolean read FLiteral write FLiteral; property SubmitToFrame: TWABD_Base_Frame read FSubmitTo write FSubmitTo; property JS_OnUserKeyPress:TWABD_JS_Function read FJS_OnUserKeyPress write FJS_OnUserKeyPress; property JS_OnUserKeyUp:TWABD_JS_Function read FJS_OnUserKeyUp write FJS_OnUserKeyUp; property JS_OnUserKeyDown:TWABD_JS_Function read FJS_OnUserKeyDown write FJS_OnUserKeyDown; property JS_OnUserClick:TWABD_JS_Function read FJS_OnUserClick write FJS_OnUserClick; property JS_OnUserDblClick:TWABD_JS_Function read FJS_OnUserDblClick write FJS_OnUserDblClick; property JS_OnUserMouseMove:TWABD_JS_Function read FJS_OnUserMouseMove write FJS_OnUserMouseMove; property JS_OnUserMouseOver:TWABD_JS_Function read FJS_OnUserMouseOver write FJS_OnUserMouseOver; property JS_OnUserMouseOut:TWABD_JS_Function read FJS_OnUserMouseOut write FJS_OnUserMouseOut; property JS_OnUserMouseDown:TWABD_JS_Function read FJS_OnUserMouseDown write FJS_OnUserMouseDown; property JS_OnUserMouseUp:TWABD_JS_Function read FJS_OnUserMouseUp write FJS_OnUserMouseUp; end; TWABD_DataTable = class; TRecClickEvent = procedure(Sender: TWABD_DataTable; RowIndex: integer; var MoveToRecord: boolean) of object; TWABD_DataLink = class(TDataLink) private FOnActiveChanged:TNotifyEvent; FOnDatasetChanged:TNotifyEvent; protected procedure DatasetChanged; override; procedure ActiveChanged; override; published property OnActiveChanged:TNotifyEvent read FOnActiveChanged write FOnActiveChanged; property OnDatasetChanged:TNotifyEvent read FOnDatasetChanged write FOnDatasetChanged; end; TWABD_DataTable = class(TWABD_FormSection_Base) protected FDataLink : TWABD_DataLink; FFormSec : TWABD_FormSection; FNavForm : TWABD_FormSection; FTable : TWABD_Table; FShowForm : boolean; FShowTable : boolean; FNavButs : boolean; FMaxRows : integer; FColWidth : integer; FNumCol : integer; FAutoWid : boolean; FRecClick : TRecClickEvent; FReadOnly : boolean; FCanSelectRecord:boolean; FCalcPages : boolean; FRecordCount: longint; FActiveRec : longint; FBGColor : TColor; FFontSize : integer; FFontColor : TColor; Stat : string; DidAppend : boolean; procedure InitForm; procedure InitTable; procedure InitNavButs; procedure CreateNavBut(x, y : integer; ButCap: string; OnUserClick: TNotifyEvent); procedure FirstClick(Sender: TObject); procedure LastClick(Sender: TObject); procedure NextClick(Sender: TObject); procedure PrevClick(Sender: TObject); procedure NextPgClick(Sender: TObject); procedure PrevPgClick(Sender: TObject); procedure AddClick(Sender: TObject); procedure EditClick(Sender: TObject); procedure DeleteClick(Sender: TObject); function GetDataSource: TDataSource; procedure SetDataSource(NewDataSource: TDataSource); procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure SetName(const NewName: TComponentName); override; procedure TableClick(Sender: TObject; RowIndex: integer); function GetRenderCell:TWABD_OnRenderCellEvent; procedure SetRenderCell(Event:TWABD_OnRenderCellEvent); function GetUserClickCell:TWABD_OnUserClickCellEvent; procedure SetUserClickCell(Event:TWABD_OnUserClickCellEvent); function GetSetupClickableCell:TWABD_OnSetupClickableCellEvent; procedure SetSetupClickableCell(Event:TWABD_OnSetupClickableCellEvent); function GetSetupCellJavascript:TWABD_OnSetupJavascriptEvent; procedure SetSetupCellJavascript(Event:TWABD_OnSetupJavascriptEvent); function GetSetupRowJavascript:TWABD_OnSetupJavascriptEvent; procedure SetSetupRowJavascript(Event:TWABD_OnSetupJavascriptEvent); function GetLiteral:boolean; procedure SetLiteral(Value:boolean); function GetPage:integer; function GetNumPages:integer; procedure RecountRecords(Sender:TObject); function GetCellBorder:integer; function GetCellSpacing:integer; procedure SetCellBorder(i:integer); procedure SetCellSpacing(i:integer); function GetWidth:integer; procedure SetWidth(w:integer); function GetShowEmptyRows:boolean; procedure SetShowEmptyRows(s:boolean); function GetBGColor:TColor; procedure SetBGColor(c:TColor); function GetOptimize:boolean; procedure SetOptimize(o:boolean); function GetFontColor:TColor; procedure SetFontColor(c:TColor); function GetFontSize:integer; procedure SetFontSize(sz:integer); function GetSubmitTo:TWABD_Base_Frame; procedure SetSubmitTo(fr:TWABD_Base_Frame); function GetJSOnUserKeyPress:TWABD_JS_Function; procedure SetJSOnUserKeyPress(Value:TWABD_JS_Function); function GetJSOnUserKeyDown:TWABD_JS_Function; procedure SetJSOnUserKeyDown(Value:TWABD_JS_Function); function GetJSOnUserKeyUp:TWABD_JS_Function; procedure SetJSOnUserKeyUp(Value:TWABD_JS_Function); function GetJSOnUserClick:TWABD_JS_Function; procedure SetJSOnUserClick(Value:TWABD_JS_Function); function GetJSOnUserDblClick:TWABD_JS_Function; procedure SetJSOnUserDblClick(Value:TWABD_JS_Function); function GetJSOnUserMouseOver:TWABD_JS_Function; procedure SetJSOnUserMouseOver(Value:TWABD_JS_Function); function GetJSOnUserMouseDown:TWABD_JS_Function; procedure SetJSOnUserMouseDown(Value:TWABD_JS_Function); function GetJSOnUserMouseMove:TWABD_JS_Function; procedure SetJSOnUserMouseMove(Value:TWABD_JS_Function); function GetJSOnUserMouseUp:TWABD_JS_Function; procedure SetJSOnUserMouseUp(Value:TWABD_JS_Function); function GetJSOnUserMouseOut:TWABD_JS_Function; procedure SetJSOnUserMouseOut(Value:TWABD_JS_Function); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure JumpToTableRecord(RowIndex: integer); function Object_To_HTML: string; override; procedure HTML_To_Object(FormVal: string); override; property FormSection: TWABD_FormSection read FFormSec; property NavSection: TWABD_FormSection read FNavForm; property Table: TWABD_Table read FTable; procedure NextPage; procedure PrevPage; procedure LastPage; procedure FirstPage; published property FontSize: integer read GetFontSize write SetFontSize; property FontColor: TColor read GetFontColor write SetFontColor; property DataSource: TDataSource read GetDataSource write SetDataSource; property ShowEditForm: boolean read FShowForm write FShowForm; property ShowTable: boolean read FShowTable write FShowTable; property ShowNavButs: boolean read FNavButs write FNavButs; property MaxRows: integer read FMaxRows write FMaxRows; property FormColWidth: integer read FColWidth write FColWidth; property NumCols: integer read FNumCol write FNumCol; property AutoWidth: boolean read FAutoWid write FAutoWid default True; property ReadOnly: boolean read FReadOnly write FReadOnly; property ShowRecordButton: boolean read FCanSelectRecord write FCanSelectRecord; property OnRecordClick: TRecClickEvent read FRecClick write FRecClick; property OnRenderCell: TWABD_OnRenderCellEvent read GetRenderCell write SetRenderCell; property OnUserClickCell: TWABD_OnUserClickCellEvent read GetUserClickCell write SetUserClickCell; property OnSetupClickableCell: TWABD_OnSetupClickableCellEvent read GetSetupClickableCell write SetSetupClickableCell; property OnSetupCellJavascript: TWABD_OnSetupJavascriptEvent read GetSetupCellJavascript write SetSetupCellJavascript; property OnSetupRowJavascript: TWABD_OnSetupJavascriptEvent read GetSetupRowJavascript write SetSetupRowJavascript; property Page:integer read GetPage; property NumPages:integer read GetNumPages; property CalcPages:boolean read FCalcPages write FCalcPages; property Literal:boolean read GetLiteral write SetLiteral; property CellBorder:integer read GetCellBorder write SetCellBorder; property CellSpacing:integer read GetCellSpacing write SetCellSpacing; property Width: integer read GetWidth write SetWidth; property ShowEmptyRows: boolean read GetShowEmptyRows write SetShowEmptyRows; property BGColor:TColor read GetBGColor write SetBGColor; property Optimize:boolean read GetOptimize write SetOptimize; property SubmitToFrame: TWABD_Base_Frame read GetSubmitTo write SetSubmitTo; property JS_OnUserKeyPress:TWABD_JS_Function read GetJSOnUserKeyPress write SetJSOnUserKeyPress; property JS_OnUserKeyUp:TWABD_JS_Function read GetJSOnUserKeyUp write SetJSOnUserKeyUp; property JS_OnUserKeyDown:TWABD_JS_Function read GetJSOnUserKeyDown write SetJSOnUserKeyDown; property JS_OnUserClick:TWABD_JS_Function read GetJSOnUserClick write SetJSOnUserClick; property JS_OnUserDblClick:TWABD_JS_Function read GetJSOnUserDblClick write SetJSOnUserDblClick; property JS_OnUserMouseMove:TWABD_JS_Function read GetJSOnUserMouseMove write SetJSOnUserMouseMove; property JS_OnUserMouseOver:TWABD_JS_Function read GetJSOnUserMouseOver write SetJSOnUserMouseOver; property JS_OnUserMouseOut:TWABD_JS_Function read GetJSOnUserMouseOut write SetJSOnUserMouseOut; property JS_OnUserMouseDown:TWABD_JS_Function read GetJSOnUserMouseDown write SetJSOnUserMouseDown; property JS_OnUserMouseUp:TWABD_JS_Function read GetJSOnUserMouseUp write SetJSOnUserMouseUp; end; TWABD_Hidden = class(TWABD_Object) protected FValue : string; public function Object_To_HTML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property Value: string read FValue write FValue; end; TWABD_BlankLines = class(TWABD_FormSection_Base) protected FNumLines : integer; public constructor Create(AOwner: TComponent); override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property NumLines: integer read FNumLines write FNumLines; end; // ************************************************************************ // "Form" Level objects (Buttons, Labels, Edit boxes, etc) TWABD_SectionObject = class(TWABD_Object) private Row, Col : integer; // Used by FormSection_Grid's AutoSizeRowCol function OrigLeft : integer; OrigTop : integer; protected FVertAlign : TWABD_VertAlignment; FHorzAlign : TWABD_HorzAlignment; FLeftPos : integer; // Table start Pos (Left, Top) FTopPos : integer; FWidth : integer; // Table Span Col & Row (Width, Height) FHeight : integer; FColSpan : integer; // if -1, uses Width/GridX for ColSpan, else this number FRowSpan : integer; FTabIndex : integer; FDisabled : boolean; FNoWrap : boolean; FAccessKey : string; FTitle : string; procedure SetLeft(NewLeft: integer); procedure SetTop(NewTop: integer); function GenerateOptionHTML:string; property TabIndex: integer read FTabIndex write FTabIndex; property Disabled: boolean read FDisabled write FDisabled default false; property AccessKey: string read FAccessKey write FAccessKey; property Title: string read FTitle write FTitle; published constructor Create(AOwner: TComponent); override; destructor Destroy; override; property VertAlign:TWABD_VertAlignment read FVertAlign write FVertAlign; property HorzAlign:TWABD_HorzAlignment read FHorzAlign write FHorzAlign; property LeftPos: integer read FLeftPos write SetLeft; property TopPos: integer read FTopPos write SetTop; property ColSpan: integer read FColSpan write FColSpan default -1; property RowSpan: integer read FRowSpan write FRowSpan default -1; property Width: integer read FWidth write FWidth; property Height: integer read FHeight write FHeight; property NoWrap:boolean read FNoWrap write FNoWrap; end; TWABD_BaseEventSectionObject = class(TWABD_SectionObject) protected FOnUserChange: TNotifyEvent; FOnUserClick: TNotifyEvent; FOnUserGotFocus: TNotifyEvent; FOnUserLostFocus: TNotifyEvent; FJS_OnUserClick:TWABD_JS_Function; FJS_OnUserGotFocus:TWABD_JS_Function; FJS_OnUserLostFocus:TWABD_JS_Function; FJS_OnUserDblClick:TWABD_JS_Function; FJS_OnUserMouseMove:TWABD_JS_Function; FJS_OnUserMouseOver:TWABD_JS_Function; FJS_OnUserMouseOut:TWABD_JS_Function; FJS_OnUserMouseDown:TWABD_JS_Function; FJS_OnUserMouseUp:TWABD_JS_Function; FJS_OnUserKeyPress:TWABD_JS_Function; FJS_OnUserKeyDown:TWABD_JS_Function; FJS_OnUserKeyUp:TWABD_JS_Function; FJS_OnUserChange:TWABD_JS_Function; property JS_OnUserChange:TWABD_JS_Function read FJS_OnUserChange write FJS_OnUserChange; property OnUserChange: TNotifyEvent read FOnUserChange write FOnUserChange; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function GenerateEventScript:string; published property JS_OnUserGotFocus:TWABD_JS_Function read FJS_OnUserGotFocus write FJS_OnUserGotFocus; property JS_OnUserLostFocus:TWABD_JS_Function read FJS_OnUserLostFocus write FJS_OnUserLostFocus; property JS_OnUserClick:TWABD_JS_Function read FJS_OnUserClick write FJS_OnUserClick; property JS_OnUserDblClick:TWABD_JS_Function read FJS_OnUserDblClick write FJS_OnUserDblClick; property JS_OnUserMouseMove:TWABD_JS_Function read FJS_OnUserMouseMove write FJS_OnUserMouseMove; property JS_OnUserMouseOver:TWABD_JS_Function read FJS_OnUserMouseOver write FJS_OnUserMouseOver; property JS_OnUserMouseOut:TWABD_JS_Function read FJS_OnUserMouseOut write FJS_OnUserMouseOut; property JS_OnUserMouseDown:TWABD_JS_Function read FJS_OnUserMouseDown write FJS_OnUserMouseDown; property JS_OnUserMouseUp:TWABD_JS_Function read FJS_OnUserMouseUp write FJS_OnUserMouseUp; property JS_OnUserKeyPress:TWABD_JS_Function read FJS_OnUserKeyPress write FJS_OnUserKeyPress; property JS_OnUserKeyDown:TWABD_JS_Function read FJS_OnUserKeyDown write FJS_OnUserKeyDown; property JS_OnUserKeyUp:TWABD_JS_Function read FJS_OnUserKeyUp write FJS_OnUserKeyUp; property OnUserClick: TNotifyEvent read FOnUserClick write FOnUserClick; property OnUserGotFocus: TNotifyEvent read FOnUserGotFocus write FOnUserGotFocus; property OnUserLostFocus: TNotifyEvent read FOnUserLostFocus write FOnUserLostFocus; end; TWABD_HTMLEmbed = class(TWABD_SectionObject) protected FHTML : TStrings; procedure SetHTML(NewHTML:TStrings); procedure SetName(const Value: TComponentName); override; procedure SetWidth(w:integer); procedure SetHeight(h:integer); function GetWidth:integer; function GetHeight:integer; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property HTML: TStrings read FHTML write SetHTML; property Width: integer read GetWidth write SetWidth; property Height: integer read GetHeight write SetHeight; end; TWABD_HTMLFileEmbed = class(TWABD_HTMLEmbed) protected FFileName : TFileName; FSetup : TWABD_Setup; FLoadedWhen : TDateTime; FSecsBeforeReload : integer; FCached : boolean; procedure Notification(AComponent: TComponent; Operation: TOperation); override; public procedure Reload; property LoadedWhen:TDateTime read FLoadedWhen; constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_WML: string; override; published property FileName:TFileName read FFileName write FFileName; property SecsBeforeReload:integer read FSecsBeforeReload write FSecsBeforeReload; property Cached:boolean read FCached write FCached; property Setup:TWABD_Setup read FSetup write FSetup; end; TWABD_LinesObject = class(TWABD_BaseEventSectionObject) protected FLines : TStringList; procedure SetLines(NewLines: TStringList); procedure SetName(const Value: TComponentName); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; published property Lines: TStringList read FLines write SetLines; property JS_OnUserChange; property OnUserChange; end; TWABD_SelLinesObject = class(TWABD_LinesObject) protected FSelList : TList; FOldSelList : TList; FAutoButton : boolean; FButton : TWABD_Object; FOnChange : TNotifyEvent; procedure SetListSelected(AList:TList; Index:integer; Value:boolean); function GetListSelected(AList:TList; Index:integer):boolean; procedure SetSelected(Index:integer; Value:boolean); function GetSelected(Index:integer):boolean; procedure SetOldSelected(Index:integer; Value:boolean); function GetOldSelected(Index:integer):boolean; procedure ClearListSelected(AList:TList); procedure CopyListSelected(Src,Dst:TList); function EqualListSelected(AList1,AList2:TList):boolean; function GetText(Index:integer):string; function GetDesc(Index:integer):string; function GetSelText:string; procedure SetSelText(s:string); function GetSelDesc:string; function GetOldSelText:string; function GetOldSelDesc:string; procedure SetSelIndex(i:integer); function GetSelIndex:integer; procedure SetOldSelIndex(i:integer); function GetOldSelIndex:integer; procedure OnChangeHandler(Sender:TObject); function GetChanged:boolean; property OldText : string read GetOldSelText; property OldDesc : string read GetOldSelDesc; property Text : string read GetSelText write SetSelText; property Desc : string read GetSelDesc; property Texts[Index:integer]:string read GetText; property Descs[Index:integer]:string read GetDesc; property Selected[Index:integer] : boolean read GetSelected write SetSelected; property OldSelected[Index:integer] : boolean read GetOldSelected write SetOldSelected; property SelIndex:integer read GetSelIndex write SetSelIndex; property OldSelIndex:integer read GetOldSelIndex write SetOldSelIndex; property Button:TWABD_Object read FButton write FButton; property SelectionChanged:boolean read GetChanged; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure Clear; published property AutoButton:boolean read FAutoButton write FAutoButton default true; property OnChange:TNotifyEvent read FOnChange write FOnChange; end; TWABD_Anchor = class(TWABD_BaseEventSectionObject) protected FDest : string; FCaption : string; FBold : boolean; FItalic : boolean; FUnderline : boolean; FSubmitTo : TWABD_Base_Frame; procedure SetName(const Value: TComponentName); override; procedure SetCaption(NewCaption: string); procedure Notification(AComponent: TComponent; Operation: TOperation); override; public constructor Create(AOwner: TComponent); override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property Caption: string read FCaption write SetCaption; property Destination: string read FDest write FDest; property Bold: boolean read FBold write FBold; property Italic: boolean read FItalic write FItalic; property Underline: boolean read FUnderline write FUnderline; property SubmitToFrame: TWABD_Base_Frame read FSubmitTo write FSubmitTo; end; TWABD_Autoload = class(TWABD_Object) protected FForm : TWABD_Form; FFrameset : TWABD_Frameset; FDelay : integer; FMenubar : boolean; FToolbar : boolean; FReplace : boolean; FScrollbars : boolean; FStatusbar : boolean; FTitlebar : boolean; FResizable : boolean; FLocationbar: boolean; procedure Notification(AComponent: TComponent; Operation: TOperation); override; public constructor Create(AOwner: TComponent); override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property Form:TWABD_Form read FForm write FForm; property Frameset:TWABD_Frameset read FFrameset write FFrameset; property Delay:integer read FDelay write FDelay; property Menubar:boolean read FMenubar write FMenubar default true; property Toolbar:boolean read FToolbar write FToolbar default true; property Replace:boolean read FReplace write FReplace default false; property Scrollbars:boolean read FScrollbars write FScrollbars default true; property Statusbar:boolean read FStatusbar write FStatusbar default true; property Titlebar:boolean read FTitlebar write FTitlebar default true; property Resizable:boolean read FResizable write FResizable default true; property Locationbar:boolean read FLocationbar write FLocationbar default true; end; TWABD_MouseDown = procedure(Sender: TObject; X, Y: integer) of object; TWABD_HotSpot = class(TWABD_Object) protected FAbout : TWABDAbout; FX1 : integer; FY1 : integer; FX2 : integer; FY2 : integer; FImParent : TWABD_Base_Image; FChange : TNotifyEvent; FOnUserClick: TNotifyEvent; procedure SetX1(i: integer); procedure SetY1(i: integer); procedure SetX2(i: integer); procedure SetY2(i: integer); procedure SetName(const Value: TComponentName); override; procedure Changed; virtual; public destructor Destroy; override; property OnChange: TNotifyEvent read FChange write FChange; published property X1: integer read FX1 write SetX1; property Y1: integer read FY1 write SetY1; property X2: integer read FX2 write SetX2; property Y2: integer read FY2 write SetY2; property ImageParent: TWABD_Base_Image read FImParent write FImParent; property About: TWABDAbout read FAbout write FAbout; property OnUserClick:TNotifyEvent read FOnUserClick write FOnUserClick; end; TWABD_HotSpots = class(TPersistent) public ParImage : TWABD_Base_Image; end; TWABD_Base_Image = class(TWABD_BaseEventSectionObject) protected FAltText : string; FAutoSize : boolean; FMouseDown : TWABD_MouseDown; FHotSpots : TWABD_HotSpots; FImgWidth : integer; FImgHeight : integer; FImageFile : TFileName; FClickable : boolean; FSubmitTo : TWABD_Base_Frame; FDest : string; FSetup : TWABD_Setup; procedure SetName(const Value: TComponentName); override; procedure UpdateImageSize; procedure SetImgWidth(w: integer); virtual; procedure SetImgHeight(h: integer); virtual; procedure MouseDown(x, y: integer); virtual; procedure SetHotSpots(HS: TWABD_HotSpots); procedure SetImageFile(filename:TFileName); procedure Notification(AComponent: TComponent; Operation: TOperation); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; property ImageFile:TFileName read FImageFile write SetImageFile; procedure UpdateImage; virtual; function LocalImagePath:string; function ImagePath:string; published property AutoSize:boolean read FAutoSize write FAutoSize; property Clickable: boolean read FClickable write FClickable; property AltText: string read FAltText write FAltText; property OnMouseDown: TWABD_MouseDown read FMouseDown write FMouseDown; property ImageWidth: integer read FImgWidth write SetImgWidth; property ImageHeight: integer read FImgHeight write SetImgHeight; property HotSpots: TWABD_HotSpots read FHotSpots write SetHotSpots; property SubmitToFrame: TWABD_Base_Frame read FSubmitTo write FSubmitTo; property Setup: TWABD_Setup read FSetup write FSetup; property Destination:string read FDest write FDest; property OnUserClick; property Title; end; TWABD_Image = class(TWABD_Base_Image) published property ImageFile; end; TLiveImageType = (liAuto, liBMP, liJPEG, liGIF, liWBMP); TWABD_LiveImage = class(TWABD_Base_Image) protected FSafeBmp : TBitmap; FDirty : boolean; FFileName : string; WroteFile : boolean; FImgType : TLiveImageType; FInterlaced : boolean; procedure SetImgWidth(w: integer); override; procedure SetImgHeight(h: integer); override; function GetSafeBitmap: TBitmap; function GetCanvas: TCanvas; procedure Loaded; override; function GetFileName: string; function DetermineImageType:TLiveImageType; function GetNewName: string; function GetTransColor:TColor; function GetTransMode:TTransparentMode; function GetPixelFormat:TPixelFormat; procedure SetTransColor(color:TColor); procedure SetTransMode(mode:TTransparentMode); procedure SetPixelFormat(pf:TPixelFormat); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; property SafeBitmap: TBitmap read GetSafeBitmap; property Dirty: boolean read FDirty; property Canvas: TCanvas read GetCanvas; property FileName: string read GetFileName; procedure UpdateImage; override; published property ImageType: TLiveImageType read FImgType write FImgType default liGIF; property TransparentColor:TColor read GetTransColor write SetTransColor; property TransparentMode:TTransparentMode read GetTransMode write SetTransMode; property Interlaced:boolean read FInterlaced write FInterlaced; property PixelFormat:TPixelFormat read GetPixelFormat write SetPixelFormat; end; TWABD_Chart = class(TWABD_LiveImage) protected FChart : TCustomChart; FOnChartPointClick : TWABD_OnChartPointClick; procedure Loaded; override; procedure SetChart(Chart: TCustomChart); procedure MouseDown(x, y: integer); override; procedure Notification(AComponent: TComponent; Operation: TOperation); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property Chart : TCustomChart read FChart write SetChart; property OnChartPointClick: TWABD_OnChartPointClick read FOnChartPointClick write FOnChartPointClick; end; TWABD_Label = class(TWABD_BaseEventSectionObject) protected FCaption : string; FBold : boolean; FItalic : boolean; FUnderline : boolean; FFontColor : TColor; FFontSize : integer; FCanClick : boolean; FSubmitTo : TWABD_Base_Frame; procedure SetName(const Value: TComponentName); override; procedure SetCaption(NewCaption: string); procedure SetFontSize(NewSize: integer); procedure UpdateWidHgt; procedure SetBold(NewBold: boolean); procedure Notification(AComponent: TComponent; Operation: TOperation); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property Caption: string read FCaption write SetCaption; property FontColor: TColor read FFontColor write FFontColor default clNone; property Bold: boolean read FBold write SetBold default False; property Italic: boolean read FItalic write FItalic default False; property Underline: boolean read FUnderline write FUnderline default False; property FontSize: integer read FFontSize write SetFontSize default 3; property CanClick: boolean read FCanClick write FCanClick; property SubmitToFrame: TWABD_Base_Frame read FSubmitTo write FSubmitTo; property OnUserClick; end; TWABD_TextAreaWrap = (taOff,taOut,taInOut); TWABD_Memo = class(TWABD_LinesObject) protected FCols : integer; FRows : integer; FWrap : TWABD_TextAreaWrap; procedure SetCols(NewCols: integer); procedure SetRows(NewRows: integer); public constructor Create(AOwner: TComponent); override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_WML_Postfield: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property Cols: integer read FCols write SetCols; property Rows: integer read FRows write SetRows; property TabIndex: integer read FTabIndex write FTabIndex; property Disabled; property AccessKey; property Title; property WordWrap:TwABD_TextAreaWrap read FWrap write FWrap default taOff; end; TWABD_Button = class(TWABD_BaseEventSectionObject) protected FCaption : string; FDefault : boolean; procedure SetName(const Value: TComponentName); override; procedure SetCaption(NewCaption: string); public constructor Create(AOwner:TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property Caption: string read FCaption write SetCaption; property Default: boolean read FDefault write FDefault default False; property TabIndex; property Disabled; property AccessKey; property OnUserClick; property PathInfo; property Title; end; TWABD_Edit = class(TWABD_BaseEventSectionObject) protected FOldText : string; FText : string; FPass : boolean; FSize : integer; FMax : integer; FReadOnly : boolean; FFormat : string; FEmptyOK : boolean; procedure SetName(const Value: TComponentName); override; procedure SetSize(NewSize: integer); procedure SetText(s:string); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_WML_Postfield: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property OldText: string read FOldText; property Text: string read FText write SetText; property IsPassword: boolean read FPass write FPass; property Size: integer read FSize write SetSize; property MaxLength: integer read FMax write FMax; property ReadOnly:boolean read FReadOnly write FReadOnly; property Format:string read FFormat write FFormat; property EmptyOK:boolean read FEmptyOK write FEmptyOK; property TabIndex; property Disabled; property AccessKey; property OnUserChange; property JS_OnUserChange; property Title; end; TWABD_UploadFile = class(TWABD_BaseEventSectionObject) protected FClientFileName : string; FLocalFileName : string; FMimeType : string; FAcceptMimeTypes : TStringList; FReadOnly : boolean; FSize : integer; procedure SetSize(NewSize: integer); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; property LocalFileName:string read FLocalFileName; property MimeType:string read FMimeType; published property ClientFileName:string read FClientFileName write FClientFileName; property ReadOnly:boolean read FReadOnly write FReadOnly; property Size:integer read FSize write SetSize; property AcceptMimeTypes:TStringList read FAcceptMimeTypes write FAcceptMimeTypes; property Title; property TabIndex; property Disabled; property AccessKey; property OnUserChange; property JS_OnUserChange; end; TWABD_ComboBox = class(TWABD_SelLinesObject) public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_WML_Postfield: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; property OldText; property Desc; property SelectionChanged; property Selected; property Texts; property Descs; published property TabIndex; property Disabled; property AccessKey; property SelIndex; property OldSelIndex; property Button; property AutoButton; property Text; property Title; end; TWABD_RadioButton = class(TWABD_BaseEventSectionObject) protected FCaption : string; FCheck : boolean; FGroup : integer; procedure SetName(const Value: TComponentName); override; procedure SetCaption(NewCaption: string); procedure SetChecked(value:boolean); procedure ResetCheckedProc(Child: TWABD_Object; var Stop: boolean; UserData: pointer); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property Caption: string read FCaption write SetCaption; property Checked: boolean read FCheck write SetChecked; property Group:integer read FGroup write FGroup; property TabIndex; property Disabled; property AccessKey; property OnUserChange; property JS_OnUserChange; property Title; end; TWABD_ListBox = class(TWABD_SelLinesObject) protected FSize : integer; FMultiple : boolean; procedure SetSize(NewSize: integer); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_WML_Postfield: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; property OldText; property Desc; property SelectionChanged; property Selected; property Texts; property Descs; published property Size: integer read FSize write SetSize; property Multiple:boolean read FMultiple write FMultiple; property TabIndex; property Disabled; property AccessKey; property SelIndex; property OldSelIndex; property Button; property AutoButton; property Text; property Title; end; TWABD_CheckBox = class(TWABD_BaseEventSectionObject) protected FCaption : string; FCheck : boolean; procedure SetName(const Value: TComponentName); override; procedure SetCaption(NewCaption: string); procedure SetChecked(Check: boolean); public constructor Create(AOwner:TComponent); override; destructor Destroy; override; function Object_To_HTML: string; override; function Object_To_WML: string; override; function Object_To_WML_Postfield: string; override; function Object_To_Control(AOwner: TWinControl): TControl; override; procedure HTML_To_Object(FormVal: string); override; published property Caption: string read FCaption write SetCaption; property Checked: boolean read FCheck write SetChecked; property Title; property TabIndex; property Disabled; property AccessKey; property OnUserChange; property JS_OnUserChange; end; // ************************************************************************ // Misc. Helper objects TPaintPanel = class(TPanel) protected FFormSec : TWABD_FormSection_Grid; FDrawPic : boolean; FCellBord : integer; FDMode : boolean; procedure Paint; override; procedure SetDrawPic(b: boolean); procedure SetCellBorder(nb: integer); procedure SetDesignMode(nm: boolean); public Pic : TImage; GridX : integer; GridY : integer; property DrawPic: boolean read FDrawPic write SetDrawPic; property CellBorder: integer read FCellBord write SetCellBorder; property DesignMode: boolean read FDMode write SetDesignMode; end; TJumpLabel = class(TLabel) protected FCanClick : boolean; procedure SetCanClick(b: boolean); public JumpDest : string; JumpOut : boolean; constructor Create(AOwner: TComponent); override; property CanClick: boolean read FCanClick write SetCanClick; end; const WABD_JS_Function_TypeText : array [TWABD_JS_Function_Type] of string = ('OnEvent', 'OnClick','OnDblClick', 'OnChange', 'OnFocus','OnBlur', 'OnLoad','OnUnload', 'OnSubmit', 'OnMouseDown','OnMouseUp','OnMouseOver','OnMouseOut','OnMouseMove', 'OnKeyPress','OnKeyDown','OnKeyUp'); WABD_EVENT_USERCHANGE=1; WABD_EVENT_USERCLICK=2; WABD_EVENT_USERGOTFOCUS=3; WABD_EVENT_USERLOSTFOCUS=4; WABD_EVENT_CALLBACK=90; WABD_EVENT_AUTOLOAD=99; implementation uses GifImage, WABD_Crypt; // ************************************************************************ // I N T E R F A C E C U T - O F F // ************************************************************************ // ************************************************************************ // Helper Objects // ************************************************************************ type TTableCell = record SObj : TWABD_SectionObject; Skip : boolean; Width : integer; SpanX : integer; SpanY : integer; end; PTableCell = ^TTableCell; TTableCellArray = array[0..0] of TTableCell; PTableCellArray = ^TTableCellArray; TTableGrid = class protected mx, my : integer; FData : PTableCellArray; public constructor Create; destructor Destroy; override; procedure SetSize(x,y: integer); function GetCell(x,y: integer): PTableCell; end; // ************************************************************************ // Utility functions // ************************************************************************ // Generate functioncall code without ending ;. function GenJSFunctionCall(jsf:TWABD_JS_Function):string; var a:string; s:string; i:integer; begin if (jsf.FScript='') then begin Result:=''; exit; end; // Check that the script doesnt contain parameter list by itself. a:=copy(jsf.FScript,length(jsf.FScript),1); if (a=')') or (a=';') then begin s:=jsf.FScript; if a=';' then s:=copy(s,1,length(s)-1); end else begin // Build Script + parameterlist. a:=''; s:=jsf.FScript+'('; for i:=0 to jsf.FParams.count-1 do begin s:=s+a+jsf.FParams.Strings[i]; a:=','; end; s:=s+')'; end; Result:=s; end; // Generate eventcode. function GenEventCode(jsf:TWABD_JS_Function; NotifyEvent:TNotifyEvent; EventType:integer; Data:string):string; var usercode:string; returnstring:string; handleevent:string; a:string; begin // Generate string for userdefined event java script. usercode:=GenJSFunctionCall(jsf); if usercode<>'' then usercode:=usercode+';'; // Generate string for emulating serverside javascript eventhandling. if Assigned(NotifyEvent) then handleevent:='HandleEvent('+inttostr(EventType)+',this.form,this,'''');' else handleevent:=''; // If its the onsubmit event, there should be a 'return ' before last in event list. if jsf.FType=jsOnSubmit then returnstring:='return ' else returnstring:=''; // Determine order of code segments in event handler. if (usercode<>'') then begin if jsf.Placement=jsfLast then Result:=Data+HandleEvent+UserCode else if Data<>'' then Result:=UserCode+HandleEvent+ReturnString+Data else Result:=UserCode+HandleEvent; end else if Data<>'' then Result:=HandleEvent+ReturnString+Data else Result:=HandleEvent; if Result<>'' then begin if (length(Result)>0) and (not (Result[1] in ['''','"'])) and (Pos(' ',Result)>0) then a:='"' else a:=''; Result:=' '+WABD_JS_Function_TypeText[jsf.FType]+'='+a+Result+a; end; end; // Generate network timing Javascript. function GenNetworkTimingJS:string; // TODO: Need to finish GenNetworkTimingJS. var tsSubmitClient,tsLoadClient,tsServer:string; ptClient,ptServer:string; begin tsSubmitClient:='form.'+WABD_CLIENTSUBMITTIMESTAMP_STR+'.value'; tsLoadClient:='form.'+WABD_CLIENTLOADTIMESTAMP_STR+'.value'; tsServer:='form.'+WABD_SERVERTIMESTAMP_STR+'.value'; ptClient:='form.'+WABD_CLIENTPROCESSTIME_STR+'.value'; ptServer:='form.'+WABD_SERVERPROCESSTIME_STR+'.value'; Result:='function TimeNetworkSubmit(form) {'+CR+ ' var Old='+tsSubmitClient+';'+CR+ ' var Now=new Date();'+CR+ ' '+tsSubmitClient+'=Now.getTime();'+CR+ ' if (Old != -1) '+ptClient+'='+tsLoadClient+'-Old'+';'+CR+ ' return true'+CR+ '};'+CR+CR+ 'function TimeNetworkLoad(form) {'+CR+ ' var Now=new Date();'+CR+ ' '+tsLoadClient+'=Now.getTime();'+CR+ '};'+CR; end; // Generate Javascript for handling on.... events on sectionobjects. function GenEventHandler(DoTiming:boolean;jsf_OnSubmit,jsf_OnUserEvent:TWABD_JS_Function):string; var f1,f2,f3,f4,f5,f6:string; begin f1:='function HandleEvent(ev,form,control,data) {'+CR; f2:='if (form.'+WABD_EVENT_ID_STR+'.value!="") form.'+WABD_EVENT_ID_STR+'.value=form.'+WABD_EVENT_ID_STR+'.value+";";'+CR+ 'form.'+WABD_EVENT_ID_STR+'.value=form.'+WABD_EVENT_ID_STR+'.value+ev+":"+control.name+":"+data;'+CR; f3:='form.submit();'+CR; // Emulate submit event if Javascript given for that purpose. if (Assigned(jsf_OnSubmit)) and (jsf_OnSubmit.FScript<>'') then f4:='if (!'+GenJSFunctionCall(jsf_OnSubmit)+') return;'+CR else f4:=''; // Check if user event handler given, build script for that. if (Assigned(jsf_OnUserEvent)) and (jsf_OnUserEvent.FScript<>'') then f5:=jsf_OnUserEvent.FScript+CR else f5:=''; // Check if network timing enabled, alter submit request. if DoTiming then f6:='TimeNetworkSubmit(form);'+CR else f6:=''; Result:=f1+f5+f4+f2+f6+f3+'};'+CR; end; procedure SplitSessionID(str:string;var Session,FormName:string); var i:integer; begin i:=pos(':',str); Session:=copy(str,1,i-1); FormName:=copy(str,i+1,length(str)); end; // Substitute all variables. function Process_Variables(HTML:string;FVariables:TStrings):string; var s,ss,v:string; j,k:integer; begin s:=''; ss:=HTML; // Loop while there are variables to setup. while true do begin j:=pos('[!--',ss); // Look for startermarker for variable. if j>0 then begin s:=s+copy(ss,1,j-1); // Add the raw data before the startermarker as a result. ss:=copy(ss,j,length(ss)); k:=pos('--!]',ss); // Look for the endmarker for variable. if k>0 then begin v:=copy(ss,5,k-5); // Extract variablename. ss:=copy(ss,k+4,length(ss)); k:=FVariables.IndexOfName(v); if k>=0 then begin v:=FVariables.Strings[k]; k:=pos('=',v); v:=copy(v,k+1,length(v)); end else v:='[!--'+v+'--!]'; s:=s+v; end else raise Exception.CreateFmt('Variable endmarker not found %s', [copy(ss,1,30)]); end else // No startermarker found, just add the rest of the text to result and break. begin s:=s+ss; break; end; end; Result := s; end; function FormatFilename(NewImagePath: string):string; var s:string; begin s:= NewImagePath; if Copy(s, 1, 1)<>'\' then s := '\' + s; Result:=s; end; function FormatPath(Path:string):string; begin Result:=Path; if Copy(Result, Length(Result), 1)<>'/' then Result:=Result+'/'; end; function FormatLocalPath(Path:string):string; var s:string; begin Result:=Path; if (Result<>'') and (Copy(Result, Length(Result), 1)<>'\') then Result:=Result+'\'; if ExtractFileDrive(Result)='' then begin getdir(0,s); if Copy(s,length(s),1)<>'\' then s:=s+'\'; if Result<>'' then Result:=s+Result else Result:=s; end; end; // ************************************************************************ // TWABD_Setup // ************************************************************************ destructor TWABD_SesSubStat.Destroy; begin ClearPoints; inherited; end; // Add sub stat point. procedure TWABD_SesSubStat.AddPoint(ID:string; Value:double); var i:integer; p:PWABD_SesSubStatRec; begin i:=IndexOf(ID); if i<0 then begin GetMem(p,SizeOf(TWABD_SesSubStatRec)); p^.Count:=0; p^.Value:=0.0; p^.Min:=9999999; p^.Max:=0; AddObject(ID,TObject(p)); end else p:=PWABD_SesSubStatRec(Objects[i]); inc(p^.Count); p^.Value:=p^.Value+Value; if Value<p^.Min then p^.Min:=Value; if Value>p^.Max then p^.Max:=Value; end; // Clear all substat points. procedure TWABD_SesSubStat.ClearPoints; var i:integer; begin for i:=0 to Count-1 do FreeMem(Pointer(Objects[i])); end; constructor TWABD_SesStatGroup.Create; begin inherited; SubStat:=TWABD_SesSubStat.create; end; destructor TWABD_SesStatGroup.Destroy; var i:integer; prec:PWABD_SesStatRec; lst:TList; begin lst:=LockList; try with lst do begin for i:=0 to lst.count-1 do begin prec:=PWABD_SesStatRec(Items[i]); StrDispose(prec^.User); StrDispose(prec^.Info); FreeMem(Items[i]); end; Clear; end; finally UnlockList; end; SubStat.free; inherited; end; // Make sure only FBuffersize records is in the list. procedure TWABD_SesStatGroup.Clean; var i,n:integer; prec:PWABD_SesStatRec; lst:TList; begin lst:=LockList; try with lst do begin n:=count - FBufferSize; for i:=0 to n-1 do begin prec:=PWABD_SesStatRec(Items[0]); StrDispose(prec^.User); StrDispose(prec^.Info); FreeMem(Items[0]); Delete(0); end; end; finally UnlockList; end; end; // Clear stat. values for group. procedure TWABD_SesStatGroup.Zero; var i:integer; begin FSum:=0; FCount:=0; FMin:=999E39; FMax:=0; for i:=0 to 23 do begin HourlyValues[i]:=0; HourlyCount[i]:=0; end; for i:=1 to 31 do begin DailyValues[i]:=0; DailyCount[i]:=0; end; for i:=1 to 12 do begin MonthlyValues[i]:=0; MonthlyCount[i]:=0; end; for i:=1 to 7 do begin DayValues[i]:=0; DayCount[i]:=0; end; SubStat.ClearPoints; end; // Add stat. group. procedure TWABD_SesStat.AddGroup(GrpName:string; GrpType:TWABD_SesStatGroups; BufSize:integer); var grp:TWABD_SesStatGroup; begin grp:=TWABD_SesStatGroup.Create; grp.FName:=GrpName; grp.FBufferSize:=BufSize; grp.FGroupType:=GrpType; grp.Zero; Add(grp); end; // Find group by name. function TWABD_SesStat.IndexOf(GrpName:string):integer; var i:integer; lst:TList; begin Result:=-1; lst:=LockList; try with lst do begin for i:=0 to count-1 do with TWABD_SesStatGroup(Items[i]) do if Name=GrpName then begin Result:=i; break; end; end; finally UnlockList; end; end; // Add meassure to a stat. group. procedure TWABD_SesStat.AddPoint(GrpName:string; User,Info:string; Value:double); var i:integer; grp:TWABD_SesStatGroup; prec:PWABD_SesStatRec; h,mm,s,ms,d,m,y,dw:word; stamp:TDateTime; lst:TList; begin i:=IndexOf(GrpName); if (i<0) then exit; lst:=LockList; try with lst do begin grp:=TWABD_SesStatGroup(Items[i]); // Convert value to correct format. if grp.FGroupType=wabdStatGroupTurnAround then Value:=trunc(MSECS*Value); // Get datetime for record. stamp:=Now; DecodeDate(stamp,y,m,d); DecodeTime(stamp,h,mm,s,ms); dw:=DayOfWeek(stamp); // Allocate room for new stat. record. GetMem(prec,sizeof(TWABD_SesStatRec)); prec^.Stamp:=Now; prec^.Value:=Value; prec^.User:=StrNew(PChar(User)); prec^.Info:=StrNew(PChar(Info)); grp.Add(prec); // Calculate group sums. inc(grp.FCount); grp.FSum:=grp.FSum+Value; if Value<grp.FMin then grp.FMin:=Value; if Value>grp.FMax then grp.FMax:=Value; // Calculate hourly sums. grp.HourlyValues[h]:=grp.HourlyValues[h]+Value; inc(grp.HourlyCount[h]); // Calculate daily sums. grp.DailyValues[d]:=grp.DailyValues[d]+Value; inc(grp.DailyCount[d]); // Calculate monthly sums. grp.MonthlyValues[m]:=grp.MonthlyValues[m]+Value; inc(grp.MonthlyCount[m]); // Calculate day sums. grp.DayValues[dw]:=grp.DayValues[dw]+Value; inc(grp.DayCount[dw]); end; finally UnlockList; end; end; procedure TWABD_SesStat.Clean; var i:integer; lst:TList; begin lst:=LockList; try with lst do begin for i:=0 to count-1 do with TWABD_SesStatGroup(Items[i]) do Clean; end; finally UnlockList; end; end; // Save stat info. procedure TWABD_SesStat.Save(dllname:string); var g:integer; grp:TWABD_SesStatGroup; i:integer; s:string; INI:TIniFile; os:char; lst:TList; begin // Replace s:=ChangeFileExt(dllname,'.STA'); if s=dllname then s:=s+'.STA'; // Dont want to overwrite the dll by accident. if ExtractFilePath(s)='' then s:='.\'+s; os:=Decimalseparator; Decimalseparator:='.'; INI:=TInifile.Create(s); lst:=LockList; try with lst do begin // For all groups. for g:=0 to count-1 do begin grp:=TWABD_SesStatGroup(Items[g]); // Write group global info. s:=grp.Name; INI.writestring(s,'Sum',floattostr(grp.FSum)); INI.writeinteger(s,'Count',grp.FCount); INI.writestring(s,'Min',floattostr(grp.FMin)); INI.writestring(s,'Min',floattostr(grp.FMax)); // Write hourly info. s:=grp.Name+' Hourly'; for i:=0 to 23 do begin INI.WriteString(s,'Val'+inttostr(i),floattostr(grp.HourlyValues[i])); INI.Writeinteger(s,'Cnt'+inttostr(i),grp.HourlyCount[i]); end; // Write daily info. s:=grp.Name+' Daily'; for i:=1 to 31 do begin INI.WriteString(s,'Val'+inttostr(i),floattostr(grp.DailyValues[i])); INI.Writeinteger(s,'Cnt'+inttostr(i),grp.DailyCount[i]); end; // Write monthly info. s:=grp.Name+' Monthly'; for i:=1 to 12 do begin INI.WriteString(s,'Val'+inttostr(i),floattostr(grp.MonthlyValues[i])); INI.Writeinteger(s,'Cnt'+inttostr(i),grp.MonthlyCount[i]); end; // Write day info. s:=grp.Name+' Weekday'; for i:=1 to 7 do begin INI.WriteString(s,'Val'+inttostr(i),floattostr(grp.DayValues[i])); INI.Writeinteger(s,'Cnt'+inttostr(i),grp.DayCount[i]); end; end; end; finally UnlockList; end; INI.free; Decimalseparator:=os; end; // Load stat info. procedure TWABD_SesStat.Load(dllname:string); var g:integer; grp:TWABD_SesStatGroup; i,n:integer; s:string; INI:TIniFile; os:char; lst:TList; begin // Replace s:=ChangeFileExt(dllname,'.STA'); if s=dllname then s:=s+'.STA'; // Dont want to overwrite the dll by accident. if ExtractFilePath(s)='' then s:='.\'+s; os:=Decimalseparator; Decimalseparator:='.'; INI:=TInifile.Create(s); lst:=LockList; try with lst do begin // For all groups. for g:=0 to count-1 do begin grp:=TWABD_SesStatGroup(Items[g]); // Write group global info. s:=grp.Name; n:=INI.readinteger(s,'Count',-1); if n<0 then continue; grp.FCount:=n; grp.FSum:=strtofloat(INI.readstring(s,'Sum','0.0')); grp.FMin:=strtofloat(INI.readstring(s,'Min','0.0')); grp.FMax:=strtofloat(INI.readstring(s,'Min','0.0')); // read hourly info. s:=grp.Name+' Hourly'; for i:=0 to 23 do begin grp.HourlyValues[i]:=strtofloat(INI.readString(s,'Val'+inttostr(i),'0.0')); grp.HourlyCount[i]:=INI.readinteger(s,'Cnt'+inttostr(i),0); end; // read daily info. s:=grp.Name+' Daily'; for i:=1 to 31 do begin grp.DailyValues[i]:=strtofloat(INI.readString(s,'Val'+inttostr(i),'0.0')); grp.DailyCount[i]:=INI.readinteger(s,'Cnt'+inttostr(i),0); end; // read monthly info. s:=grp.Name+' Monthly'; for i:=1 to 12 do begin grp.MonthlyValues[i]:=strtofloat(INI.readString(s,'Val'+inttostr(i),'0.0')); grp.MonthlyCount[i]:=INI.readinteger(s,'Cnt'+inttostr(i),0); end; // read day info. s:=grp.Name+' Weekday'; for i:=1 to 7 do begin grp.DayValues[i]:=strtofloat(INI.readString(s,'Val'+inttostr(i),'0.0')); grp.DayCount[i]:=INI.readinteger(s,'Cnt'+inttostr(i),0); end; end; end; finally UnlockList; end; INI.free; Decimalseparator:=os; end; procedure TWABD_SesStat.Zero; var g:integer; grp:TWABD_SesStatGroup; lst:TList; begin lst:=LockList; try with lst do begin // For all groups. for g:=0 to count-1 do begin grp:=TWABD_SesStatGroup(Items[g]); grp.Zero; end; end; finally UnlockList; end; end; // Clear all stat.groups and deallocate memory. destructor TWABD_SesStat.Destroy; var i:integer; lst:TList; begin lst:=LockList; try with lst do begin for i:=0 to count-1 do TWABD_SesStatGroup(Items[i]).free; Clear; end; finally UnlockList; end; inherited; end; // ************************************************************************ // TWABD_Setup // ************************************************************************ constructor TWABD_Setup.Create(AOwner:TComponent); begin inherited; InitializeCriticalSection(FLock); FAutoSetGlobalRootPath:=false; FExpandFromRootPath:=false; FExpandFromGlobalRootPath:=false; end; destructor TWABD_Setup.Destroy; begin // Before destruction, save info. if FAutoSave then Save; DeleteCriticalSection(FLock); inherited; end; procedure TWABD_Setup.Save; var reg:TRegistry; ini:TIniFile; begin Lock; try // Before destruction, save info. case Storage of storeNone: ; storeRegistry: begin reg:=TRegistry.Create; if reg.OpenKey('\Software\'+FStoragePath+'\'+FSectionName,true) then begin reg.WriteString('ImagePath',ImagePath); reg.WriteString('LocalImagePath',LocalImagePath); reg.WriteString('FilePath',FilePath); reg.WriteString('LocalFilePath',LocalFilePath); reg.WriteString('LocalRootPath',LocalRootPath); if assigned(FOnSave) then FOnSave(self,FSectionName,reg,nil); end; reg.free; end; storeIniFile: begin ini:=TIniFile.Create(FStoragePath); if ini<>nil then begin ini.WriteString(FSectionName,'ImagePath',ImagePath); ini.WriteString(FSectionName,'LocalImagePath',LocalFilePath); ini.WriteString(FSectionName,'FilePath',ImagePath); ini.WriteString(FSectionName,'LocalFilePath',LocalFilePath); ini.WriteString(FSectionName,'LocalRootPath',LocalRootPath); if assigned(FOnSave) then FOnSave(self,FSectionName,nil,ini); end; ini.free; end; end; finally Unlock; end; end; procedure TWABD_Setup.Load; var reg:TRegistry; ini:TIniFile; begin Lock; try case Storage of storeNone: ; storeRegistry: begin reg:=TRegistry.Create; if reg.OpenKey('\Software\'+FStoragePath+'\'+FSectionName,false) then begin ImagePath:=reg.ReadString('ImagePath'); LocalImagePath:=reg.ReadString('LocalImagePath'); FilePath:=reg.ReadString('FilePath'); LocalFilePath:=reg.ReadString('LocalFilePath'); LocalRootPath:=reg.ReadString('LocalRootPath'); if assigned(FOnLoad) then FOnLoad(self,FSectionName,reg,nil); end; reg.free; end; storeIniFile: begin ini:=TIniFile.Create(FStoragePath); if ini<>nil then begin ImagePath:=ini.ReadString(FSectionName,'ImagePath',''); LocalImagePath:=ini.ReadString(FSectionName,'LocalImagePath',''); FilePath:=ini.ReadString(FSectionName,'FilePath',''); LocalFilePath:=ini.ReadString(FSectionName,'LocalFilePath',''); LocalRootPath:=ini.ReadString(FSectionName,'LocalRootPath',''); if assigned(FOnLoad) then FOnLoad(self,FSectionName,nil,ini); end; ini.free; end; end; finally Unlock; end; end; procedure TWABD_Setup.Loaded; begin inherited; if FAutoLoad then Load; end; function TWABD_Setup.GetImagePath:string; begin Lock; try Result:=FormatPath(FImagePath); finally Unlock; end; end; function TWABD_Setup.GetLocalImagePath:string; var s:string; begin Lock; try if FExpandFromRootPath then begin if FExpandFromGlobalRootPath then s:=WABD_DefaultRequestLocalFilePath else s:=LocalRootPath; Result:=FormatLocalPath(ExpandFileName(s+'\'+FLocalImagePath)) end else Result:=FormatLocalPath(FLocalImagePath); finally Unlock; end; end; function TWABD_Setup.GetFilePath:string; begin Lock; try Result:=FormatPath(FFilePath); finally Unlock; end; end; function TWABD_Setup.GetLocalFilePath:string; var s:string; begin Lock; try if FExpandFromRootPath then begin if FExpandFromGlobalRootPath then s:=WABD_DefaultRequestLocalFilePath else s:=LocalRootPath; Result:=FormatLocalPath(ExpandFileName(s+'\'+FLocalFilePath)) end else Result:=FormatLocalPath(FLocalFilePath); finally Unlock; end; end; procedure TWABD_Setup.Lock; begin EnterCriticalSection(FLock); end; procedure TWABD_Setup.Unlock; begin LeaveCriticalSection(FLock); end; procedure TWABD_Setup.SetLocalRootPath(APath:string); begin Lock; try if FAutoSetGlobalRootPath then WABD_DefaultRequestLocalFilePath:=APath; FLocalRootPath:=APath; finally Unlock; end; end; function TWABD_Setup.GetLocalRootPath:string; begin Lock; try if FAutoSetGlobalRootPath then Result:=WABD_DefaultRequestLocalFilePath else Result:=FLocalRootPath; finally Unlock; end; end; // ************************************************************************ // TJumpLabel // ************************************************************************ constructor TJumpLabel.Create(AOwner: TComponent); begin inherited; end; procedure TJumpLabel.SetCanClick(b: boolean); begin FCanClick := b; if b then begin {$IFDEF VER100} Cursor := crHandPoint; {$ENDIF} Font.Style := Font.Style + [fsUnderline]; end else begin Cursor := crDefault; end; end; // ************************************************************************ // TTableGrid // ************************************************************************ constructor TTableGrid.Create; begin FData := nil; mx := 0; my := 0; end; destructor TTableGrid.Destroy; begin if FData<>nil then FreeMem(FData); end; procedure TTableGrid.SetSize(x,y: integer); begin if FData<>nil then begin FreeMem(FData); FData:=nil; end; mx := x; my := y; if (x*y) = 0 then exit; GetMem(FData, x*y*sizeof(TTableCell)); FillChar(FData^, x*y*sizeof(TTableCell), 0); end; function TTableGrid.GetCell(x,y: integer): PTableCell; begin {$R-} if x>=mx then raise Exception.CreateFmt('GetCell: X out of bounds (x=%d, MaxX=%d)',[x,mx]); if y>=my then raise Exception.CreateFmt('GetCell: Y out of bounds (y=%d, MaxY=%d)',[y,my]); Result := @FData^[x * my + y]; end; // ************************************************************************ // TWABD_Table_Strings // ************************************************************************ constructor TWABD_Table_Strings.Create; begin inherited; FData := nil; XSize := 0; YSize := 0; end; destructor TWABD_Table_Strings.Destroy; begin FreeData; inherited; end; procedure TWABD_Table_Strings.FreeData; var i:integer; begin if FData<>nil then begin for i:=0 to (XSize*YSize)-1 do if FData[i]<>nil then StrDispose(FData[i]); FreeMem(FData); end; FData:=nil; end; procedure TWABD_Table_Strings.SetSize(x,y: integer); begin if (x=XSize) and (y=YSize) then exit; FreeData; XSize := x; YSize := y; if (XSize = 0) or (YSize = 0) then exit; GetMem(FData, XSize * YSize * sizeof(PChar)); FillChar(FData^, XSize * YSize * sizeof(PChar),chr(0)); end; procedure TWABD_Table_Strings.SafeSetSize(x, y: integer); var MinX, MinY : integer; NewData : PStringArray; xp, yp : integer; begin if XSize < x then MinX := XSize else MinX := x; if YSize < y then MinY := YSize else MinY := y; if (x>0) and (y>0) then begin GetMem(NewData, x * y * sizeof(PChar)); FillChar(NewData^, x * y * sizeof(PChar),chr(0)); for xp := 0 to MinX-1 do for yp := 0 to MinY-1 do if FData^[xp * YSize + yp]<>nil then NewData^[xp * y + yp] := StrNew(FData^[xp * YSize + yp]); end else NewData:=nil; FreeData; XSize := x; YSize := y; FData := NewData; end; function TWABD_Table_Strings.GetString(x,y: integer): string; begin Assert((x < XSize) and (x >= 0), 'GetString: X out of Bounds'); Assert((y < YSize) and (y >= 0), 'GetString: Y out of Bounds'); Result := StrPas(FData^[x * YSize + y]); end; procedure TWABD_Table_Strings.SetString(x,y: integer; NewString: string); begin Assert((x < XSize) and (x >= 0), 'SetString: X out of Bounds'); Assert((y < YSize) and (y >= 0), 'SetString: Y out of Bounds'); FData^[x * YSize + y] := StrNew(PChar(NewString)); end; procedure TWABD_Table_Strings.DefineProperties(Filer: TFiler); begin Filer.DefineProperty('TableStrings', ReadProps, WriteProps, True); end; procedure TWABD_Table_Strings.WriteProps(Writer: TWriter); var x, y : integer; begin Writer.WriteListBegin; Writer.WriteInteger(XSize); Writer.WriteInteger(YSize); for x := 0 to XSize-1 do for y := 0 to YSize-1 do Writer.WriteString(Strings[x,y]); Writer.WriteListEnd; end; procedure TWABD_Table_Strings.ReadProps(Reader: TReader); var x, y : integer; begin Reader.ReadListBegin; x := Reader.ReadInteger; y := Reader.ReadInteger; SetSize(x,y); for x := 0 to XSize-1 do for y := 0 to YSize-1 do Strings[x,y] := Reader.ReadString; Reader.ReadListEnd; end; procedure TWABD_Table_Strings.Assign(Source: TPersistent); var t : TWABD_Table_Strings; x, y : integer; begin if Source=Self then exit; t := Source as TWABD_Table_Strings; SetSize(t.XSize, t.YSize); for x := 0 to XSize-1 do for y := 0 to YSize-1 do Strings[x,y] := t.Strings[x,y]; end; // ************************************************************************ // TPaintPanel // ************************************************************************ procedure TPaintPanel.Paint; var x, y : integer; mx, my : integer; ox, oy : integer; begin inherited; if FDMode then begin for x := 0 to Width div GridX do for y := 0 to Height div GridY do Canvas.Pixels[x * GridX, y * GridY] := clBlack; end; if FDrawPic and not FDMode then begin mx := Width div Pic.Width + 1; my := Height div Pic.Height + 1; ox := Left mod Pic.Width; // To line up with everyone else oy := Top mod Pic.Height; for x := 0 to mx do begin for y := 0 to my do begin Canvas.Draw(x * Pic.Width - ox, y * Pic.Height - oy, Pic.Picture.Graphic); end; end; end; if FCellBord > 0 then begin if FFormSec<>nil then begin for x := 0 to FFormSec.NumCol do begin Canvas.MoveTo(FFormSec.ColTot[x], 0); Canvas.LineTo(FFormSec.ColTot[x], Height); end; for y := 0 to FFormSec.NumRow do begin Canvas.MoveTo(0, FFormSec.RowTot[y]); Canvas.LineTo(Width, FFormSec.RowTot[y]); end; end else begin for x := 0 to Width div GridX do begin Canvas.MoveTo(x * GridX, 0); Canvas.LineTo(x * GridX, Height); end; for y := 0 to Height div GridY do begin Canvas.MoveTo(0, y * GridY); Canvas.LineTo(Width, y * GridY); end; end; end; end; procedure TPaintPanel.SetDrawPic(b: boolean); begin FDrawPic := b; Invalidate; end; procedure TPaintPanel.SetCellBorder(nb: integer); begin FCellBord := nb; Invalidate; end; procedure TPaintPanel.SetDesignMode(nm: boolean); begin FDMode := nm; Invalidate; end; // ************************************************************************ // TWABD_SessionMgr // ************************************************************************ constructor TWABD_SessionMgr.Create(AOwner: TComponent); begin inherited; CreateTime := Now; SessionList := TThreadList.Create; FUniqueList := TThreadList.create; FRouteSites := TStringList.create; FRouteWhen := rwNever; FGarbage := True; FCheck := 60; // Run the check every 60 seconds FVariables := TStringList.create; FHTMLTimeOut := TStringList.create; FWebAdmin := 'the WEB administrator'; FSiteName := 'kbmWABD'; FDefSesTimeout:=600; // 10 minutes. FMaxSessions:=-1; FRouteLast :=-1; FMaxIdenticalUser:=-1; FMaxRequestSize:=-1; // Request size not limited. FRandomSessionID:=false; FTotalSessionCount:=0; Register_WABD_Callback(ClientRequest); // The interface between ISAPI and WABD on requests. Register_WABD_Term_Callback(OnTerminateCallback); // The interface between ISAPI and WABD on termination. InitializeCriticalSection(SesMgrCSCreate); InitializeCriticalSection(SesMgrCSDestroy); InitializeCriticalSection(SesMgrCSAuth); GatherStatistics:=false; // Add an image number sequence. CreateSequence(WABD_IMAGE_SEQUENCE,0,false); StopEvent := CreateEvent(nil, False, False, nil); GarbageThrd := TGarbageThread.Create(True); GarbageThrd.SesMgr := self; GarbageThrd.FreeOnTerminate := False; GarbageThrd.Resume; end; destructor TWABD_SessionMgr.Destroy; var i:integer; lst:TList; begin // Before destruction, save info. if FAutoSave then Save; SetEvent(StopEvent); // TRACE0('Waiting for Garbage Thread'); GarbageThrd.WaitFor; // TRACE0('Garbage Thread terminated'); CloseHandle(StopEvent); // Free stats. if FStats<>nil then FStats.Free; // Free all sessions. lst:=SessionList.LockList; try for i:=0 to lst.count-1 do DoDestroySession(TWABD_Session(lst.Items[i])); lst.clear; finally SessionList.UnLockList; end; // Delete all global sequences. DeleteAllSequences; // Free remaining variables. FRouteSites.Free; SessionList.Free; GarbageThrd.Free; FVariables.free; FHTMLTimeOut.free; FUniqueList.free; DeleteCriticalSection(SesMgrCSCreate); DeleteCriticalSection(SesMgrCSDestroy); DeleteCriticalSection(SesMgrCSAuth); inherited; end; function TWABD_SessionMgr.GetVersion:string; begin Result:=WABD_VERSION_STR; end; procedure TWABD_SessionMgr.Save; var reg:TRegistry; ini:TIniFile; i,j:integer; s:string; lst:TList; begin case Storage of storeNone: ; storeRegistry: begin reg:=TRegistry.Create; if reg.OpenKey('\Software\'+FStoragePath+'\'+FSectionName,true) then begin reg.WriteInteger('MaxSessions',FMaxSessions); reg.WriteInteger('MaxIdenticalUser',FMaxIdenticalUser); reg.WriteBool('GatherStatistics',FGatherStats); reg.WriteBool('NetworkStatistics',FNetworkStats); reg.WriteInteger('CheckTimeOutInterval',FCheck); reg.WriteBool('GarbageCollection',FGarbage); reg.WriteString('WebAdmin',FWebAdmin); reg.WriteString('SiteName',FSiteName); reg.WriteInteger('SiteID',FSiteID); reg.WriteString('RouteSites',FRouteSites.CommaText); reg.WriteInteger('RouteWhen',ord(FRouteWhen)); reg.WriteInteger('RouteHow',ord(FRouteHow)); reg.WriteInteger('DefaultSessionTimeout',FDefSesTimeout); if assigned(FOnSave) then FOnSave(self,FSectionName,reg,nil); end; // Save persistent sequences. if reg.OpenKey('\Software\'+FStoragePath+'\'+FSectionName+'\Sequences',true) then begin j:=0; lst:=FUniqueList.LockList; try for i:=0 to lst.count-1 do begin with PWABD_SequenceRec(lst.Items[i])^ do begin if Persistent then begin reg.WriteString(inttostr(j),Name+':'+inttostr(Value)); inc(j); end; end; end; finally FUniqueList.UnlockList; reg.WriteInteger('Sequences',j); end; end; reg.free; end; storeIniFile: begin ini:=TIniFile.Create(FStoragePath); if ini<>nil then begin ini.WriteInteger(FSectionName,'MaxSessions',FMaxSessions); ini.WriteInteger(FSectionName,'MaxIdenticalUser',FMaxIdenticalUser); ini.WriteBool(FSectionName,'GatherStatistics',FGatherStats); ini.WriteBool(FSectionName,'NetworkStatistics',FNetworkStats); ini.WriteInteger(FSectionName,'CheckTimeOutInterval',FCheck); ini.WriteBool(FSectionName,'GarbageCollection',FGarbage); ini.WriteString(FSectionName,'WebAdmin',FWebAdmin); ini.WriteString(FSectionName,'SiteName',FSiteName); ini.WriteInteger(FSectionName,'SiteID',FSiteID); ini.WriteString(FSectionName,'RouteSites',FRouteSites.CommaText); ini.WriteInteger(FSectionName,'RouteWhen',ord(FRouteWhen)); ini.WriteInteger(FSectionName,'RouteHow',ord(FRouteHow)); ini.WriteInteger(FSectionName,'DefaultSessionTimeout',FDefSesTimeout); if assigned(FOnSave) then FOnSave(self,FSectionName,nil,ini); end; // Save persistent sequences. s:=FSectionName+' Sequences'; j:=0; lst:=FUniqueList.LockList; try for i:=0 to lst.count-1 do begin with PWABD_SequenceRec(lst.Items[i])^ do begin if Persistent then begin ini.WriteString(s,inttostr(j),Name+':'+inttostr(Value)); inc(j); end; end; end; finally FUniqueList.UnlockList; ini.WriteInteger(s,'Sequences',j); end; ini.free; end; end; end; procedure TWABD_SessionMgr.Load; var reg:TRegistry; ini:TIniFile; s,s1:string; i,j,k:integer; begin case Storage of storeNone: ; storeRegistry: begin reg:=TRegistry.Create; if reg.OpenKey('\Software\'+FStoragePath+'\'+FSectionName,false) then begin FMaxSessions:=reg.ReadInteger('MaxSessions'); FMaxIdenticalUser:=reg.ReadInteger('MaxIdenticalUser'); GatherStatistics:=reg.ReadBool('GatherStatistics'); FNetworkStats:=reg.ReadBool('NetworkStatistics'); FCheck:=reg.ReadInteger('CheckTimeOutInterval'); FGarbage:=reg.ReadBool('GarbageCollection'); FWebAdmin:=reg.ReadString('WebAdmin'); FSiteName:=reg.ReadString('SiteName'); FSiteID:=reg.ReadInteger('SiteID'); FRouteSites.CommaText:=reg.ReadString('RouteSites'); FRouteWhen:=TWABD_RouteWhen(reg.ReadInteger('RouteWhen')); FRouteHow:=TWABD_RouteHow(reg.ReadInteger('RouteHow')); FDefSesTimeout:=reg.ReadInteger('DefaultSessionTimeout'); if assigned(FOnLoad) then FOnLoad(self,FSectionName,reg,nil); end; // Load persistent sequences. if reg.OpenKey('\Software\'+FStoragePath+'\'+FSectionName+'\Sequences',false) then begin j:=reg.ReadInteger('Sequences'); for i:=0 to j-1 do begin s1:=reg.ReadString(inttostr(i)); k:=pos(':',s1); CreateSequence(copy(s1,1,k-1),strtoint(copy(s1,k+1,length(s1))),true); end; end; reg.free; end; storeIniFile: begin ini:=TIniFile.Create(FStoragePath); if ini<>nil then begin FMaxSessions:=ini.ReadInteger(FSectionName,'MaxSessions',-1); FMaxIdenticalUser:=ini.ReadInteger(FSectionName,'MaxIdenticalUser',-1); GatherStatistics:=ini.ReadBool(FSectionName,'GatherStatistics',true); FNetworkStats:=ini.ReadBool(FSectionName,'NetworkStatistics',false); FCheck:=ini.ReadInteger(FSectionName,'CheckTimeOutInterval',60); FGarbage:=ini.ReadBool(FSectionName,'GarbageCollection',true); FWebAdmin:=ini.ReadString(FSectionName,'WebAdmin','the Web administrator'); FSiteName:=ini.ReadString(FSectionName,'SiteName','-'); FSiteID:=ini.ReadInteger(FSectionName,'SiteID',0); FRouteSites.CommaText:=ini.ReadString(FSectionName,'RouteSites',''); FRouteWhen:=TWABD_RouteWhen(ini.ReadInteger(FSectionName,'RouteWhen',0)); FRouteHow:=TWABD_RouteHow(ini.ReadInteger(FSectionName,'RouteHow',0)); FDefSesTimeout:=ini.ReadInteger(FSectionName,'DefaultSessionTimeout',600); if assigned(FOnLoad) then FOnLoad(self,FSectionName,nil,ini); end; // Load persistent sequences. s:=FSectionName+' Sequences'; j:=ini.ReadInteger(s,'Sequences',0); for i:=0 to j-1 do begin s1:=ini.ReadString(s,inttostr(i),''); k:=pos(':',s); if k<=0 then continue; CreateSequence(copy(s,1,k-1),strtoint(copy(s,k+1,length(s))),true); end; ini.free; end; end; end; procedure TWABD_SessionMgr.Loaded; begin inherited; if SiteID<0 then SiteID:=Random(255); // Max. 256 unique sites. if FAutoLoad then Load; end; procedure TWABD_SessionMgr.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation=opRemove) and (AComponent = FAdmin) then FAdmin:=nil; end; procedure TWABD_SessionMgr.SetSiteID(id:integer); begin if (id<-1) or (id>=256) then raise ERangeError.Create('SiteID must be between -1 to 255.'); FSiteID:=id; end; // Called by ISAPI when webserver want to shutdown the DLL. function TWABD_SessionMgr.OnTerminateCallback(Flags:longint):boolean; begin if Assigned(FOnTerminate) then Result:=FOnTerminate(Flags) else Result:=true; free; end; // Create a unique global sequence. procedure TWABD_SessionMgr.CreateSequence(ID:string; StartValue:longint; Persistent:boolean); var p:PWABD_SequenceRec; i:integer; lst:TList; begin // Check if its there allready, dont recreate it but adjust startvalue if > old value. lst:=FUniqueList.LockList; try for i:=0 to lst.count-1 do begin with PWABD_SequenceRec(lst.Items[i])^ do begin if Name=ID then begin if StartValue>Value then Value:=StartValue; exit; end; end; end; finally FUniqueList.UnlockList; end; // Add new member to the list. GetMem(p,sizeof(TWABD_SequenceRec)); p^.Persistent:=Persistent; p^.Name:=StrNew(PChar(ID)); p^.Value:=StartValue; FUniqueList.Add(p); end; // Draw a sequence number from a specified global sequence. // Return -1 if sequence not found. function TWABD_SessionMgr.DrawSequenceValue(ID:string):longint; var i:integer; lst:TList; begin Result:=-1; lst:=FUniqueList.LockList; try for i:=0 to lst.count-1 do begin with PWABD_SequenceRec(lst.Items[i])^ do begin if Name=ID then begin Result:=Value; inc(Value); end; end; end; finally FUniqueList.UnlockList; end; end; // Remove global sequence. procedure TWABD_SessionMgr.DeleteSequence(ID:string); var i:integer; lst:TList; begin lst:=FUniqueList.LockList; try for i:=0 to lst.count-1 do begin with PWABD_SequenceRec(lst.Items[i])^ do begin if Name=ID then begin StrDispose(PChar(Name)); FreeMem(lst.Items[i]); lst.Delete(i); break; end; end; end; finally FUniqueList.UnlockList; end; end; // Remove all global sequences. procedure TWABD_SessionMgr.DeleteAllSequences; var i:integer; lst:TList; begin lst:=FUniqueList.LockList; try for i:=lst.count-1 downto 0 do begin with PWABD_SequenceRec(lst.Items[i])^ do begin StrDispose(PChar(Name)); FreeMem(lst.Items[i]); lst.Delete(i); end; end; finally FUniqueList.UnlockList; end; end; // Setup gathering of statistics. procedure TWABD_SessionMgr.SetGatherStats(b:boolean); begin if b=FGatherStats then exit; if b then begin if FStats=nil then begin FStats:=TWABD_SesStat.create; FStats.AddGroup(WABD_STATGRP_RESPONSE,wabdStatGroupTurnAround,70); FStats.AddGroup(WABD_STATGRP_NETRESPONSE,wabdStatGroupTurnAround,100); FStats.AddGroup(WABD_STATGRP_SENDSIZE,wabdStatGroupValue,50); FStats.AddGroup(WABD_STATGRP_RECVSIZE,wabdStatGroupValue,50); end; end; FGatherStats:=b; end; procedure TWABD_SessionMgr.DoDestroySession(Ses: TWABD_Session); begin if not Assigned(OnDestroySession) then raise Exception.CreateFmt('DestroySession not defined for %s', [Name]); // Trace0('Before Destroy'); EnterCriticalSection(SesMgrCSDestroy); try OnDestroySession(Ses); finally LeaveCriticalSection(SesMgrCSDestroy); end; // Trace0('After Destroy'); end; procedure TWABD_SessionMgr.SetVariables(NewVariables: TStrings); begin FVariables.Assign(NewVariables); end; procedure TWABD_SessionMgr.SetVariableByName(AName,AValue:string); var i:integer; s:string; begin i:=FVariables.IndexOfName(AName); s:=AName+'='+AValue; if i>=0 then FVariables.strings[i]:=s else FVariables.add(s); end; function TWABD_SessionMgr.GetVariableByName(AName:string):string; begin Result:=FVariables.Values[AName]; end; procedure TWABD_SessionMgr.CheckLogOff(Ses: TWABD_Session); begin if Ses.DidLogOff then begin if Assigned(Ses.OnLogOff) then Ses.OnLogOff; SessionList.Remove(Ses); DoDestroySession(Ses); end; end; // Get sessioncount. function TWABD_SessionMgr.GetSessionCount:integer; var lst:TList; begin lst:=SessionList.LockList; try Result:=lst.count; finally SessionList.UnlockList; end; end; // Get next route according to setup. function TWABD_SessionMgr.GetRoute:string; var n:integer; begin Result:=''; n:=FRouteSites.Count; if (FRouteWhen=rwNever) or (n<=0) then exit; // OK, we can route. Determine to which host. case FRouteHow of rhRandom: FRouteLast:=Random(n); rhRoundRobin: begin inc(FRouteLast); if FRouteLast>=n then FRouteLast:=0; end; end; Result:=FRouteSites.Strings[FRouteLast]; end; // Substitute all parameters. function TWABD_SessionMgr.ProcessVariables(HTML:string):string; begin Result:=Process_Variables(HTML,FVariables); end; // Check if user is authenticated by basic method. function TWABD_SessionMgr.Authenticate(Request:TWABD_CustomRequest; Response:TWABD_CustomResponse; LikeToBeAdmin:boolean; var IsAdmin:boolean):boolean; var s:string; r:string; i:integer; auth:boolean; begin IsAdmin:=false; // Check if authentication info is given. s:=Request.Auth; if s<>'' then begin // Is it basic? i:=pos(' ',s); if i>0 then begin r:=UpperCase(copy(s,1,i-1)); if r='BASIC' then begin s:=WABD_DecodeBase64(copy(s,i+1,length(s))); i:=pos(':',s); Request.UserName:=copy(s,1,i-1); Request.Password:=copy(s,i+1,length(s)); r:=Request.RemoteHost; auth:=false; // If user wants to be admin. if LikeToBeAdmin then begin if assigned(FAdmin) and (Admin.AutoLog>=logLevel1) then Admin.LogFmt('REQ:User %s (%s) like to be administrator',[Request.UserName,r]); if Assigned(FAdmin) and assigned(FCreateAdmin) and (lowercase(FAdmin.FAdminUser)=lowercase(Request.UserName)) and (lowercase(FAdmin.FAdminPassword)=lowercase(Request.Password)) then begin auth:=true; IsAdmin:=true; end; end else if Assigned(FOnAuthenticate) then FOnAuthenticate(r,Request.UserName,Request.Password,auth); Result:=auth; if assigned(FAdmin) and (Admin.AutoLog>=logLevel1) then begin if Result then Admin.LogFmt('REQ:User %s (%s) authenticated',[Request.UserName,r]) else Admin.LogFmt('REQ:User %s (%s) NOT authenticated',[Request.UserName,r]); end; if Result then exit; end; end; end; // If application dont want to authenticate, allow normal users to access site. // But potential administrators always have to identify themselfs. if not (LikeToBeAdmin or Assigned(FOnAuthenticate)) then begin if Request.UserName='' then Request.UserName:=Request.RemoteUser; Result:=true; exit; end; // Force authentication dialog. Response.ContentDesc:=SiteName; Response.Status:=WABD_STATUS_AUTH; Result:=false; end; // Count sessions with this userid. function TWABD_SessionMgr.CountIdenticalUser(UserName:string):integer; var i:integer; lst:TList; begin Result:=0; UserName:=lowercase(trim(UserName)); // Look for the username in the list. lst:=SessionList.LockList; try for i:=0 to lst.count-1 do if lowercase(trim(TWABD_Session(lst.Items[i]).UserName)) = UserName then inc(Result); finally SessionList.UnLockList; end; end; function TWABD_SessionMgr.CreateNewSession(Request:TWABD_CustomRequest; Response:TWABD_CustomResponse):TWABD_Session; procedure DoRoute(UserName:string); var Site:string; begin Site:=GetRoute; if Site<>'' then begin if assigned(FAdmin) and (Admin.AutoLog>=logLevel1) then Admin.LogFmt('REQ:Redirecting request for user %s to %s',[UserName,Site]); Response.Response.Clear; Response.Status:=WABD_STATUS_REDIRECT; Response.Location:=Site; exit; end end; function GetRandomSessionID:longint; var i:integer; l:longint; lst:TList; begin lst:=SessionList.LockList; try while true do begin // Draw number, l:=random(1 shl 23); // Check if number already used, then draw another. for i:=0 to lst.count-1 do if TWABD_Session(lst.Items[i]).SessionID = l then break; // No conflict, use the one we have drawn. Result:=l; exit; end; finally SessionList.UnlockList; end; end; var NewSes : TWABD_Session; LikeToBeAdmin,IsAdmin,Authenticated:boolean; stamp:TDateTime; c:integer; s:string; NewSesID:longint; label L_Exit; begin if not Assigned(OnCreateSession) then raise Exception.CreateFmt('CreateSession not defined for %s', [Name]); stamp:=now; NewSes := nil; Request.UserName:=''; Request.Password:=''; Result:=nil; Response.Status:=WABD_STATUS_OK; if assigned(FAdmin) and (Admin.AutoLog>=logLevel2) then Admin.LogFmt('REQ:Creating new session for user %s',[Request.UserName]); // Check if to do sessionmanager based (basic) authentication). LikeToBeAdmin:=(Request.Query.Count>0) and (lowercase(Request.Query.Strings[0])='admin'); EnterCriticalSection(SesMgrCSAuth); try Authenticated:=Authenticate(Request,Response,LikeToBeAdmin,IsAdmin); finally LeaveCriticalSection(SesMgrCSAuth); end; // Check if to reroute allways for everyone except administrator. if (FRouteWhen=rwAllways) and (not (IsAdmin or LikeToBeAdmin)) then begin DoRoute(Request.UserName); exit; end; // Check if not authenticated and no guest session defined, exit. if (not Authenticated) and ((Request.UserName='') or (not Assigned(OnCreateGuestSession))) then goto L_exit; // Check limits. Doesnt apply to the administrator. if not IsAdmin then begin // Check if not accepting sessions here. Either reroute or give error. if FMaxSessions=0 then begin // Check if to route. if FRouteWhen=rwWhenFull then DoRoute(Request.UserName) else Response.Response.Text:='<BODY><P><H1>Welcome</H1></P><P>'+SiteName+'('+inttostr(SiteID)+') is currently not accepting new sessions.</P><P>Please try later.</P></BODY>'; exit; end; // Check if full. Either reroute or give error. if FMaxSessions>0 then begin c:=SessionCount; if c>=FMaxSessions then begin // Check if to route. if FRouteWhen=rwWhenFull then DoRoute(Request.UserName) else Response.Response.Text:='<BODY><P><H1>Welcome</H1></P><P>'+SiteName+'('+inttostr(SiteID)+') is currently fully booked. ('+inttostr(c)+' active sessions).</P><P>Please try later.</P></BODY>'; exit; end; end; // Check if to many logins from identical user. if (FMaxIdenticalUser>0) and (CountIdenticalUser(Request.UserName)>=FMaxIdenticalUser) then begin Response.Response.Text:='<BODY><P><H1>Welcome</H1></P><P>'+SiteName+'('+inttostr(SiteID)+') only allow you to be logged in '+inttostr(FMaxIdenticalUser)+' times with the same username.</P><P>If you cant do a proper logout at this time then please wait another 10-20 minutes, and try to logon again.</P></BODY>'; exit; end; end; EnterCriticalSection(SesMgrCSCreate); try // Check if to show another form if not authenticated. if not Authenticated then OnCreateGuestSession(NewSes,LikeToBeAdmin,Request) // Check if logged in as admin. else if IsAdmin and Assigned(OnCreateAdminSession) then OnCreateAdminSession(NewSes,Request) // Else an ordinary user. else OnCreateSession(NewSes,Request); Inc(FTotalSessionCount); // If to use randomized session ID, get one. if FRandomSessionID then NewSesID:=GetRandomSessionID else NewSesID:=FTotalSessionCount; finally LeaveCriticalSection(SesMgrCSCreate); end; if NewSes=nil then raise Exception.Create('CreateSession Failed'); NewSes.LockSession; try NewSes.FRequest:=Request; NewSes.FResponse:=Response; SessionList.Add(NewSes); // Set properties for new session. NewSes.FInfo:=FInfo; NewSes.FSessionID := (SiteID shl 24) + NewSesID; NewSes.FLastAccess := Now; NewSes.FCreateTime := Now; NewSes.FSessionMgr := self; if NewSes.FTimeLen<0 then NewSes.FTimeLen:=DefaultSessionTimeout; Response.Status:=WABD_STATUS_OK; Result:=NewSes; if Assigned(FOnFirstSes) and (FTotalSessionCount=1) then FOnFirstSes(NewSes); if Assigned(NewSes.BeforeProcessRequest) then NewSes.BeforeProcessRequest(NewSes); Response.Response.Text:=NewSes.ProcessVariables(NewSes.ProcessRequest('',Request)); if Assigned(NewSes.AfterProcessRequest) then NewSes.AfterProcessRequest(NewSes); // Check if stateless sessiontype. Then clearout session. if NewSes.Stateless then NewSes.LogOff; finally NewSes.UnlockSession; end; CheckLogOff(NewSes); L_Exit: if GatherStatistics then begin if NewSes<>nil then s:='Site:'+inttostr(NewSes.SessionID shr 24) + ' Session ID:'+inttostr(NewSes.SessionID and $FFFFFF)+' (New)' else s:='No session'; Stats.AddPoint(WABD_STATGRP_RESPONSE,Request.UserName,s,now-stamp); Stats.AddPoint(WABD_STATGRP_SENDSIZE,Request.UserName,s,length(Response.Response.Text)); Stats.AddPoint(WABD_STATGRP_RECVSIZE,Request.UserName,s,Request.Size); end; end; function TWABD_SessionMgr.LocateSessionByID(ASiteID:integer; ASessionID:longint):TWABD_Session; var sList : TList; i : integer; ts : TWABD_Session; l : longint; begin // We have an existing session l:=(ASiteID shl 24) + ASessionID; Result:=nil; sList:=SessionList.LockList; try for i:=0 to sList.Count-1 do begin ts := TWABD_Session(sList.Items[i]); if ts.SessionID = l then begin Result:=ts; break; end; end; finally SessionList.UnlockList; end; end; function TWABD_SessionMgr.RunExistingSession(const IdStr,BodyName:string; Request:TWABD_CustomRequest; Response:TWABD_CustomResponse):TWABD_Session; var stamp : TDateTime; s : string; sid,sesid: longint; l : longint; begin stamp:=now; // Find session. l:=strtoint(IdStr); sid:=l shr 24; sesid:=l and $FFFFFF; Result:=LocateSessionByID(sid,sesid); // Check if session timedout. if Result=nil then begin // Check if HTML code defined for this, then show that. if FHTMLTimeOut.count>0 then begin Response.Response.Text:=FHTMLTimeOut.Text; Response.Status:=WABD_STATUS_OK; exit; end else raise Exception.CreateFmt('Session ID not Found: %s (Session may have timed out)', [IdStr]); end; Result.FLastAccess:=Now; if assigned(FAdmin) and (Admin.AutoLog>=logLevel2) then Admin.LogFmt('REQ:Request from site %d, session %d. This site is %d',[Result.SessionID shr 24, Result.SessionID and $FFFFFF,SiteID]); Result.LockSession; try Result.FRequest:=Request; Result.FResponse:=Response; Response.Status:=WABD_STATUS_OK; if Assigned(Result.BeforeProcessRequest) then Result.BeforeProcessRequest(Result); Response.Response.Text := Result.ProcessVariables(Result.ProcessRequest(BodyName,Request)); if Assigned(Result.AfterProcessRequest) then Result.AfterProcessRequest(Result); // Check if stateless sessiontype. Then clearout session. if Result.Stateless then Result.LogOff; finally Result.UnlockSession; end; if GatherStatistics then begin s:='Site:'+inttostr(Result.SessionID shr 24) + ' Session ID:'+inttostr(Result.SessionID and $FFFFFF)+' Net address:'+Request.RemoteAddr; Stats.AddPoint(WABD_STATGRP_RESPONSE,Result.UserName,s,now-stamp); Stats.AddPoint(WABD_STATGRP_SENDSIZE,Result.UserName,s,length(Response.Response.Text)); Stats.AddPoint(WABD_STATGRP_RECVSIZE,Result.UserName,s,Request.Size); if NetworkStatistics and (Result.CurBody.FClientProcessTime>=0) then Stats.AddPoint(WABD_STATGRP_NETRESPONSE,Result.UserName,s+' Input:'+Request.Query.Text,Result.FCurBody.FClientProcessTime/MSECS); end; CheckLogOff(Result); end; // Called by interface whenever a request is made from a client. procedure TWABD_SessionMgr.ClientRequest(Request:TWABD_CustomRequest; Response:TWABD_CustomResponse); var s : string; IdStr : string; BodyName : string; ses : TWABD_Session; ok : boolean; cookie : TWABD_Cookie; handled : boolean; begin ses:=nil; FRequest:=Request; FResponse:=Response; try try Request.DetermineRequestType; VariableByName['SERVERAPP']:=Request.DLLName; // Check if to validate contenttype. ok:=true; if Assigned(FOnValidateRequest) then FOnValidateRequest(Request,Response,ok); if not ok then begin if Response.Response.Count=0 then raise Exception.CreateFmt('Content type ''%s'' not accepted.',[Request.ContentType]) else exit; end; // Process request. if assigned(Admin) and (Admin.AutoLog=logAll) then Admin.LogFmt('HEADER:%s, QUERY:%s',[Request.Headers.Text,Request.Query.Text]); // Try to find session string in cookies or form values. IdStr:=''; cookie:=Request.Cookies.GetCookieByName(WABD_SES_ID_STR); if (cookie<>nil) then IdStr:=cookie.Value; s:=Request.Query.Values[WABD_SES_ID_STR]; if s<>'' then IdStr:=s; // Prepare response. case Request.RequestType of WABD_REQUESTTYPE_UNKNOWN,WABD_REQUESTTYPE_HTML: Response.ContentType:='text/html'; WABD_REQUESTTYPE_WML: Response.ContentType:='text/vnd.wap.wml'; else Response.ContentType:='text/html'; end; Response.ContentDesc:=''; Response.Location:=''; Response.Cookies.Assign(Request.Cookies); // Determine if new or old session. SplitSessionID(IdStr,IdStr,BodyName); if IdStr<>'' then Ses := RunExistingSession(IdStr, BodyName, Request,Response) else Ses := CreateNewSession(Request,Response); // Format result to match HTTP protocol. Response.Response.Text:=ProcessVariables(Response.Response.Text); except on e: Exception do begin Response.Status:=WABD_STATUS_OK; Response.Response.Clear; handled:=false; if Assigned(FOnException) then FOnException(self,e,handled); if not handled then begin if Request.RequestType = WABD_REQUESTTYPE_WML then begin Response.Response.Add('<?xml version="1.0"?>'); Response.Response.Add('<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">'); Response.Response.Add('<wml>'); Response.Response.Add('<card name"Exception" title="EXCEPTION" newcontext="true">'); Response.Response.Add('<p><u>OOPS.... An error occured.</u></p><br/>'); Response.Response.Add('<p>Please report this message and what happened to '+WebAdministrator+'.<br/>'); Response.Response.Add(' Site........:<b>'+SiteName+'('+inttostr(SiteID)+')</b><br/>'); Response.Response.Add(' Error.......:<b>'+e.Message+'</b><br/>'); Response.Response.Add(' Application.:<b>'+Request.DLLName+'</b>'); if Ses<>nil then begin Response.Response.Add('<br/> Session site:<b>'+inttostr(Ses.SessionID shr 24)+'</b>'); Response.Response.Add('<br/> Session ID..:<b>'+inttostr(Ses.SessionID and $FFFFFF)+'</b>'); if Ses.NewBody<>nil then Response.Response.Add('<br/> Body........:<b>'+Ses.NewBody.Name+'</b>'); end; Response.Response.Add('</p><hr/><i>'+DateTimeToStr(Now)+'</i>'); Response.Response.Add('</card></wml>'); Response.ContentType:='text/vnd.wap.wml'; end else begin Response.Response.Add('<HTML><BODY><tt><font size=5><u>OOPS.... An error occured.</u></font><br>'+ '<br>Please report this message and what happened to '+WebAdministrator+'.<br>'+ '<br> Site........:<b>'+SiteName+'('+inttostr(SiteID)+')</b>'+ '<br> Error.......:<b>'+e.Message+'</b>'+ '<br> Application.:<b>'+Request.DLLName+'</b>'); if Ses<>nil then begin Response.Response.Add('<br> Session site:<b>'+inttostr(Ses.SessionID shr 24)+'</b>'); Response.Response.Add('<br> Session ID..:<b>'+inttostr(Ses.SessionID and $FFFFFF)+'</b>'); if Ses.NewBody<>nil then Response.Response.Add('<br> Body........:<b>'+Ses.NewBody.Name+'</b>'); end; Response.Response.Add('<br><br><hr><i>'+DateTimeToStr(Now)+'</i><br><hr></tt></BODY></HTML>'); Response.ContentType:='text/html'; end; end; end; end; finally FRequest:=nil; FResponse:=nil; end; end; procedure TGarbageThread.DoGarbageCollection; var sList : TList; i : integer; s : TWABD_Session; Elap : integer; AcceptTimeOut: boolean; s1 : string; begin if SesMgr.GarbageCollection = False then exit; // Clean up stat. records. if SesMgr.FStats<>nil then SesMgr.FStats.Clean; if Assigned(SesMgr.OnGarbageCollection) then SesMgr.OnGarbageCollection(SesMgr); sList := SesMgr.SessionList.LockList; try for i := sList.Count-1 downto 0 do begin s := TWABD_Session(sList.Items[i]); // If the session want to get a garbagecollection signal whether or not it is due to timeout. if Assigned(s.OnGarbageCollection) then s.OnGarbageCollection(SesMgr); // Calculate elapsed time since last access. Elap := Round((Now - s.FLastAccess) * 24.0 * 3600.0); if Elap > s.TimeOutLength then begin // Ask politely if to accept timeout. AcceptTimeOut:=true; if Assigned(s.OnTimeOut) then s.OnTimeOut(SesMgr,Elap,AcceptTimeOut); if not AcceptTimeOut then s1:='NOT ACCEPTED' else s1:='ACCEPTED'; // If session accepts timeout, time it out. if AcceptTimeOut then begin SesMgr.DoDestroySession(s); sList.Delete(i); end; end; end; finally SesMgr.SessionList.UnlockList; end; end; procedure TGarbageThread.Execute; var rc : integer; begin repeat rc := WaitForSingleObject(SesMgr.StopEvent, SesMgr.FCheck * 1000); if rc = WAIT_TIMEOUT then DoGarbageCollection; until rc <> WAIT_TIMEOUT; end; // ************************************************************************ // TWABD_Session // ************************************************************************ constructor TWABD_Admin.Create(AOwner: TComponent); begin inherited; FAdminUser:='admin'; FAdminPassword:='password'; FLogoutHTML:='<CENTER><P><FONT SIZE=5><B>Bye. Have a nice day.</B></FONT></P></CENTER>'; InitializeCriticalSection(LogCS); end; destructor TWABD_Admin.Destroy; begin // Before destruction, save info. if FAutoSave then Save; DeleteCriticalSection(LogCS); inherited; end; procedure TWABD_Admin.Save; var reg:TRegistry; ini:TIniFile; begin // Before destruction, save info. case Storage of storeNone: ; storeRegistry: begin reg:=TRegistry.Create; if reg.OpenKey('\Software\'+FStoragePath+'\'+FSectionName,true) then begin reg.WriteString('LogFile',LogFile); reg.WriteString('AdminUser',AdminUser); reg.WriteString('AdminPassword',AdminPassword); if assigned(FOnSave) then FOnSave(self,FSectionName,reg,nil); end; reg.free; end; storeIniFile: begin ini:=TIniFile.Create(FStoragePath); if ini<>nil then begin ini.WriteString(FSectionName,'LogFile',LogFile); ini.WriteString(FSectionName,'AdminUser',AdminUser); ini.WriteString(FSectionName,'AdminPassword',AdminPassword); if assigned(FOnSave) then FOnSave(self,FSectionName,nil,ini); end; ini.free; end; end; end; procedure TWABD_Admin.Load; var reg:TRegistry; ini:TIniFile; begin case Storage of storeNone: ; storeRegistry: begin reg:=TRegistry.Create; if reg.OpenKey('\Software\'+FStoragePath+'\'+FSectionName,false) then begin LogFile:=reg.ReadString('LogFile'); AdminUser:=reg.ReadString('AdminUser'); AdminPassword:=reg.ReadString('AdminPassword'); if assigned(FOnLoad) then FOnLoad(self,FSectionName,reg,nil); end; reg.free; end; storeIniFile: begin ini:=TIniFile.Create(FStoragePath); if ini<>nil then begin LogFile:=ini.ReadString(FSectionName,'LogFile',''); AdminUser:=ini.ReadString(FSectionName,'AdminUser','admin'); AdminPassword:=ini.ReadString(FSectionName,'AdminPassword','password'); if assigned(FOnLoad) then FOnLoad(self,FSectionName,nil,ini); end; ini.free; end; end; end; procedure TWABD_Admin.Loaded; begin inherited; if FAutoLoad then Load; end; function TWABD_Admin.GetLogging:boolean; begin Result:=FLogging and (LogFile<>''); end; procedure TWABD_Admin.LogFmt(fmt:string; args:array of const); var f:TextFile; begin if not Logging then exit; EnterCriticalSection(LogCS); try assignfile(f,LogFile); try append(f); except rewrite(f); end; writeln(f,datetimetostr(Now)+' '+format(fmt,args)); CloseFile(f); finally LeaveCriticalSection(LogCS); end; end; procedure TWABD_Admin.Log(Text:string); begin LogFmt('%s',[Text]); end; constructor TWABD_Session.Create(AOwner: TComponent); begin inherited; TimeOutLength := 600; FVariables := TStringList.create; FQueryFields:=TStringList.Create; FHitCount := 0; FStateless := false; FEnableCookies := true; FSemaphore:=CreateSemaphore(nil,1,1,nil); FProduce:=prodHTML; end; destructor TWABD_Session.Destroy; begin FVariables.Free; FQueryFields.Free; CloseHandle(FSemaphore); inherited; end; function TWABD_Session.GetVersion:string; begin Result:=WABD_VERSION_STR; end; // Lock this session to synchronize access to it. procedure TWABD_Session.LockSession; var n:DWORD; begin inc(FLockCount); n:=WaitForSingleObject(FSemaphore,WABD_SEMAPHORE_TIMEOUT); if (n=WAIT_TIMEOUT) or (n=WAIT_FAILED) then begin //s:=inttostr(OwnerID)+':'+inttostr(FQueueLength)+':Connection lock timed failed.'; //OutputDebugString(PChar(s)); dec(FLockCount); end; end; procedure TWABD_Session.UnlockSession; begin if FLockCount<=0 then begin FLockCount:=0; exit; end; dec(FLockCount); ReleaseSemaphore(FSemaphore,1,nil); end; // Get username for this session. function TWABD_Session.GetSesUserName:string; begin Result:=FUserName; if (Result='') and (FRequest<>nil) then Result:=FRequest.RemoteUser; end; // Get password for this session. function TWABD_Session.GetSesPassword:string; begin Result:=FPassword; end; // Check if to initiate Form authentication of user. function TWABD_Session.Authenticate:boolean; begin Result:=true; // Dont authenticate. if not Assigned(FAuthBody) then exit; // Show authentication form. FCurBody:=AuthBody; Result:=false; end; procedure TWABD_Session.SendFile(ContentType,FileName,AsFileName:string); var s:string; hf:integer; buffer:string; cbuffer:array [0..2047] of char; n:integer; begin (* CurLocation:=filename; // Redirect page to myself with the DOWNLOAD flag set. CurLocation:=format('%s/%s?%s=%d:&%s=%s&FILE=%s&ASFILE=%s', [DllName,asfilename,WABD_SES_ID_STR,SessionID,WABD_DOWNLOAD_STR,ctype,filename,asfilename]); *) // Open file and figure out its size. hf:=FileOpen(FileName, fmOpenRead+fmShareDenyWrite); {$ifdef LEVEL6} if hf<0 then RaiseLastOSError; {$else} if hf<0 then RaiseLastWin32Error; {$endif} FileSeek(hf,0,2); FileSeek(hf,0,0); // Loop until whole file has been written to webstream. s:=''; while true do begin n:=FileRead(hf,cbuffer,2048); {$ifdef LEVEL6} if n<0 then RaiseLastOSError; {$else} if n<0 then RaiseLastWin32Error; {$endif} if n>0 then begin SetString(buffer,cbuffer,n); s:=s+buffer; end; if n<2048 then break; end; // Done with it, close file. FileClose(hf); // Override normal response. Response.ContentType:=ContentType; Response.ContentDesc:=AsFileName; Response.Response.Text:=s; Response.OverrideStandardResponse:=true; end; procedure TWABD_Session.SetVariables(NewVariables: TStrings); begin FVariables.Assign(NewVariables); end; procedure TWABD_Session.SetVariableByName(AName,AValue:string); var i:integer; s:string; begin i:=FVariables.IndexOfName(AName); s:=AName+'='+AValue; if i>=0 then FVariables.strings[i]:=s else FVariables.add(s); end; function TWABD_Session.GetVariableByName(AName:string):string; begin Result:=FVariables.Values[AName]; end; procedure TWABD_Session.SetCookies(NewCookies: TWABD_Cookies); begin FResponse.Cookies.Assign(NewCookies); end; function TWABD_Session.GetCookies:TWABD_Cookies; begin Result:=FResponse.Cookies; end; procedure TWABD_Session.SetCookieByName(AName,AValue:string); var c:TWABD_Cookie; begin c:=FResponse.Cookies.GetCookieByName(AName); if (c<>nil) then c.Value:=AValue else FResponse.Cookies.Add(AName,AValue); end; function TWABD_Session.GetCookieByName(AName:string):string; var c:TWABD_Cookie; begin c:=FResponse.Cookies.GetCookieByName(AName); if (c<>nil) then Result:=c.Value else Result:=''; end; procedure TWABD_Session.SetQueryFields(NewQueryFields:TStrings); begin FQueryFields.Assign(NewQueryFields); end; procedure TWABD_Session.SetQueryFieldByName(AName,AValue:string); var i:integer; s:string; begin i:=FQueryFields.IndexOfName(AName); s:=AName+'='+AValue; if i>=0 then FQueryFields.strings[i]:=s else FQueryFields.add(s); end; function TWABD_Session.GetQueryFieldByName(AName:string):string; begin Result:=FQueryFields.Values[AName]; end; // Substitute all variables. function TWABD_Session.ProcessVariables(HTML:string):string; begin Result:=Process_Variables(HTML,FVariables); end; procedure TWABD_Session.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation = opRemove) then begin if (AComponent = MainBody) then FMainBody := nil else if (AComponent = AuthBody) then FAuthBody := nil; end; end; function TWABD_Session.ProcessRequest(BodyName:string; Request:TWABD_CustomRequest): string; var b: TWABD_Body; o: TObject; h: boolean; begin inc(FHitCount); FRequest:=Request; if FDetermineBrowser then Request.DetermineBrowser; if BodyName='' then begin // This is a new logon if not Assigned(MainBody) then raise Exception.CreateFmt('MainBody not defined for Session: %s', [Name]); MainBody.FWSession := self; NewBody := MainBody; if Assigned(OnFirstLogon) then OnFirstLogon(FRequest.RemoteHost); // NewBody might change if Assigned(OnRequest) then OnRequest(Self,true); FCurBody := NewBody; // Check if to do session based authentication (form authentication). Authenticate; if CurBody<>nil then begin CurBody.FIsReload:=false; CurBody.FWSession := self; // If an exception occurs, let program intercept. try if (FProduce=prodHTML) or ((FProduce=prodAuto) and (Request.RequestType<>WABD_REQUESTTYPE_WML)) then Result:=CurBody.Object_To_HTML else Result:=CurBody.Object_To_WML; if CurBody.FUseSessionCookie then CurBody.CreateSessionCookie; except h:=false; if assigned(FExcept) then FExcept(self,Exception(ExceptObject),h); if not h then raise; if FNewBody<>FCurBody then begin FCurBody:=FNewBody; if (FProduce=prodHTML) or ((FProduce=prodAuto) and (Request.RequestType<>WABD_REQUESTTYPE_WML)) then Result:=CurBody.Object_To_HTML else Result:=CurBody.Object_To_WML; end; end; end; end else begin // If request procedure, call it. if Assigned(OnRequest) then OnRequest(Self,false); try // Look for body to handle input. assert(Owner<>nil,'Session has no owner: '+Name); o:=FindComponentRecursive(Owner, BodyName); // Look through all datamodules owned by owner to find component matching name. assert(o<>nil,'Body '+BodyName+' couldnt be found for session: '+Name); assert(o is TWABD_Body, BodyName+' is invalid body component.'); b:=TWABD_Body(o); FCurBody:=b; // If just to reload page without submitting new values, do that. CurBody.FIsReload:=(not (Request.Query.Values[WABD_RELOAD_STR]<>'Yes')) or (Request.Query.IndexOfName(WABD_FRAME_STR)>=0); // Let body process the input. NewBody := CurBody; CurBody.FWSession := self; CurBody.ProcessRequest(Request); // If changed body. if Response.OverrideStandardResponse then Result:=Response.Response.Text else begin if CurBody<>nil then begin FCurBody:=NewBody; CurBody.FWSession := self; // If an exception occurs, let program intercept. if (FProduce=prodHTML) or ((FProduce=prodAuto) and (Request.RequestType<>WABD_REQUESTTYPE_WML)) then Result:=CurBody.Object_To_HTML else Result:=CurBody.Object_To_WML; if CurBody.FUseSessionCookie then CurBody.CreateSessionCookie; end else Result:=''; end; except h:=false; if assigned(FExcept) then FExcept(self,Exception(ExceptObject),h); if (not h) or (FNewBody=nil) then raise; if FNewBody<>FCurBody then begin FCurBody:=FNewBody; if (FProduce=prodHTML) or ((FProduce=prodAuto) and (Request.RequestType<>WABD_REQUESTTYPE_WML)) then Result:=CurBody.Object_To_HTML else Result:=CurBody.Object_To_WML; end; end; end; FLastAccess := Now; end; procedure TWABD_Session.LogOff; begin DidLogOff := True; end; procedure TWABD_Session.Loaded; var c : TComponent; i : integer; begin inherited; Assert(Owner<>nil, Format('TWABD_Session %s has no owner', [Name])); for i := 0 to Owner.ComponentCount-1 do begin c := Owner.Components[i]; if c is TWABD_Body then (c as TWABD_Body).Session := self else if c is TWABD_Javascript then (c as TWABD_Javascript).Session:=self; end; end; // ************************************************************************ // TWABD_Object // ************************************************************************ constructor TWABD_Object.Create(AOwner: TComponent); begin inherited; FVisible := True; FOrder := -1; InLoaded := False; end; destructor TWABD_Object.Destroy; begin if FParent<>nil then FParent.FWABD_Objs.Remove(Self); inherited; end; procedure TWABD_Object.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation = opRemove) then begin if AComponent=FDependingOn then FDependingOn:=nil; end; end; // Format a HRef anchor. function TWABD_Object.GetHRef(Body:TWABD_Body; Component:TWABD_Object; WabdType,Data:string):string; begin if Session<>nil then begin if Data<>'' then Data:='&'+WABD_DATA_STR+'='+Data; Result := Format('%s?%s='+WABD_SES_ID_STR_FORMAT+'&%s=%s%s', [DLLName,WABD_SES_ID_STR, Session.SessionID,Body.Name,WabdType,Component.Name,Data]); end else Result:=''; end; procedure TWABD_Object.SetParent(NewParent: TWABD_Parent); begin if NewParent=FParent then exit; if FParent<>nil then begin Assert(FParent.FWABD_Objs<>nil, 'FParent.WABD_Objs = nil'); FParent.FWABD_Objs.Remove(Self); end; FParent := NewParent; if FParent<>nil then begin //showmessage('Inloaded='+inttostr(ord(InLoaded))+' True='+inttostr(ord(true))+' Name='+Name+' Parent='+Parent.name+' Order='+inttostr(Forder)); // if (FOrder<>-1) and (InLoaded) then begin if (FOrder<>-1) then begin Assert(FParent.FWABD_Objs<>nil, 'FParent.WABD_Objs = nil'); if FParent.FWABD_Objs.Count < Forder+1 then FParent.FWABD_Objs.Count := FOrder+1; FParent.FWABD_Objs.Items[FOrder] := Self; end else begin FParent.FWABD_Objs.Add(Self); end; end; end; function TWABD_Object.GetOrder: integer; begin if FParent <> nil then begin Assert(FParent.FWABD_Objs<>nil, 'FParent.WABD_Objs = nil'); Result := FParent.FWABD_Objs.IndexOf(Self); end else begin Result := -1; end; end; procedure TWABD_Object.SetOrder(NewOrder: integer); var Count : integer; CurOrder : integer; begin if csLoading in ComponentState then begin FOrder := NewOrder; end else begin CurOrder := GetOrder; if CurOrder >= 0 then begin Assert(FParent<>nil, 'FParent = nil'); Count := FParent.FWABD_Objs.Count; if NewOrder < 0 then NewOrder := 0; if NewOrder >= Count then NewOrder := Count - 1; if NewOrder <> CurOrder then begin Assert(FParent.FWABD_Objs<>nil, 'FParent.WABD_Objs = nil'); FParent.FWABD_Objs.Delete(CurOrder); FParent.FWABD_Objs.Insert(NewOrder, Self); end; end; end; end; procedure TWABD_Object.SetVisible(b: boolean); begin if b<>FVisible then begin FVisible := b; Changed; end; end; function TWABD_Object.GetVisible:boolean; begin Result:=FVisible; if FDependingOn<>nil then Result:=FDependingOn.Visible; end; procedure TWABD_Object.SetName(const Value: TComponentName); var OldName, NewName : string; ParForm : TWABD_Form; begin OldName := Name; NewName := Value; inherited; Changed; if (not (csLoading in ComponentState)) then begin ParForm := GetParentForm; if ParForm<>nil then begin if Assigned(ParForm.OnChildNameChanged) then ParForm.OnChildNameChanged(Self, OldName, NewName); end; end; end; procedure TWABD_Object.Changed; begin if Assigned(OnChange) then OnChange(Self); end; function TWABD_Object.GetParentForm: TWABD_Form; var tmp : TWABD_Parent; begin tmp := Parent; while (tmp<>nil) and (not (tmp is TWABD_Form)) do tmp := tmp.Parent; Result := TWABD_Form(tmp); end; function TWABD_Object.GetSession: TWABD_Session; var oc:TWABD_Object; begin Result:=nil; oc:=self; while (oc<>nil) do begin if (oc is TWABD_Javascript) then begin Result:=TWABD_Javascript(oc).Session; exit; end else if (oc is TWABD_Form) then begin Result:=TWABD_Form(oc).Session; exit; end else if (oc is TWABD_Frameset) then begin Result:=TWABD_Frameset(oc).Session; exit; end; oc:=oc.Parent; end; { c:=self; while c.Owner<>nil do c:=c.Owner; for i:=0 to c.componentcount do if c.components[i] is TWABD_Session then begin Result:=c.components[i] as TWABD_Session; exit; end; } end; function TWABD_Object.GetSessionID: longint; var ses:TWABD_Session; begin Result:=-1; ses:=Session; if ses=nil then exit; Result:=ses.SessionID; end; function TWABD_Object.GetDLLName: string; var ses: TWABD_Session; begin Result:='Unknown'; ses:=Session; if (ses<>nil) and (ses.Request<>nil) then Result:=extractfilename(ses.Request.DllName); end; procedure TWABD_Object.DefineProperties(Filer: TFiler); begin inherited; Filer.DefineProperty('ParentAndOrder', ReadParentName, WriteParentName, True); end; procedure TWABD_Object.ReadParentName(Reader: TReader); begin Reader.ReadListBegin; FParentName := Reader.ReadString; Order := Reader.ReadInteger; Reader.ReadListEnd; end; procedure TWABD_Object.WriteParentName(Writer: TWriter); begin Writer.WriteListBegin; if Parent<>nil then Writer.WriteString(Parent.Name) else Writer.WriteString(''); Writer.WriteInteger(Order); Writer.WriteListEnd; end; procedure TWABD_Object.Loaded; begin inherited; InLoaded := True; Assert(Owner<>nil, 'Owner = nil'); Parent := Owner.FindComponent(FParentName) as TWABD_Parent; InLoaded := False; end; procedure TWABD_Object.SaveHTMLToFile(AFile:string); var f:TextFile; s:string; begin s:=Object_To_HTML; AssignFile(f,AFile); try Rewrite(f); Write(f,s); finally CloseFile(f); end; end; procedure TWABD_Object.SaveWMLToFile(AFile:string); var f:TextFile; s:string; begin s:=Object_To_WML; AssignFile(f,AFile); try Rewrite(f); Write(f,s); finally CloseFile(f); end; end; function TWABD_Object.Object_To_WML:string; begin Result:=''; end; function TWABD_Object.Object_To_WML_Postfield:string; begin Result:=''; end; // ************************************************************************ // TWABD_Parent // ************************************************************************ constructor TWABD_Parent.Create(AOwner: TComponent); begin inherited; FWABD_Objs := TList.Create; end; destructor TWABD_Parent.Destroy; var i : integer; Child : TWABD_Object; begin // TRACE('BEGIN DESTROYING Parent: %s (%s)', [Name, ClassName]); // This loop MUST go backwards because the child objects remove // *themselves* from the list we are iterating for i := FWABD_Objs.Count-1 downto 0 do begin Child := FWABD_Objs[i]; Child.FParent := nil; // Must use the non-property Parent variable Child.Free; end; // TRACE('END DESTROYING Parent: %s (%s)', [Name, ClassName]); // TRACE0(''); FWABD_Objs.Free; inherited; end; function TWABD_Parent.GetWABDObjects(i: integer): TWABD_Object; begin Assert(i < FWABD_Objs.Count, 'Children: i out of bounds'); Result := FWABD_Objs.Items[i]; end; function TWABD_Parent.GetWABDObjCount: integer; begin Result := FWABD_Objs.Count; end; procedure TWABD_Parent.ChildChanged(Sender: TObject); begin // Default is to do nothing end; function TWABD_Parent.ForEachChild(ForEachProc: TWABD_ForEach; UserData: pointer): boolean; var Stop : boolean; i : integer; tmp : TWABD_Object; par : TWABD_Parent; begin Stop := False; for i := 0 to ChildCount-1 do begin ForEachProc(Children[i], Stop, UserData); if Stop then begin Result := True; exit; end; end; // Search for "grandchildren" if necessary for i := 0 to ChildCount-1 do begin tmp := Children[i]; if (tmp is TWABD_Parent) then begin par := tmp as TWABD_Parent; if par.ForEachChild(ForEachProc, UserData) then begin Result := True; exit; end; end; end; Result := False; end; procedure TWABD_Parent.ChildNameProc(Child: TWABD_Object; var Stop: boolean; UserData: pointer); begin if Child.Name = tmp then begin TheChild := Child; Stop := True; end; end; function TWABD_Parent.ChildByName(ChildName: string): TWABD_Object; begin tmp := ChildName; TheChild := nil; ForEachChild(ChildNameProc, nil); Result := TheChild; end; function TWABD_Parent.GetDefaultButton: TWABD_Button; begin TheChild := nil; ForEachChild(DefButProc, nil); Result := TheChild as TWABD_Button; end; procedure TWABD_Parent.DefButProc(Child: TWABD_Object; var Stop: boolean; UserData: pointer); begin if (Child is TWABD_Button) then if (Child as TWABD_Button).Default then begin TheChild := Child; Stop := True; end; end; procedure TWABD_Parent.ButCapProc(Child: TWABD_Object; var Stop: boolean; UserData: pointer); begin if (Child is TWABD_Button) then if (Child as TWABD_Button).Caption = tmp then begin TheChild := Child; Stop := True; end; end; function TWABD_Parent.ButtonByCaption(Caption: string): TWABD_Button; begin tmp := Caption; TheChild := nil; ForEachChild(ButCapProc, nil); Result := TheChild as TWABD_Button; end; procedure TWABD_Parent.Loaded; begin inherited; end; function TWABD_Parent.Object_To_Control(AOwner: TWinControl): TControl; var np : TPaintPanel; i : integer; c : TWABD_Object; con : TControl; MaxHgt : integer; MaxWid : integer; CurTop : integer; begin np := TPaintPanel.Create(AOwner); np.Parent := AOwner; // Some of the controls need an HWND to set their properties np.Visible := False; // For Performance (no screen updates) np.Name := Name; np.Caption := ''; MaxHgt := 0; MaxWid := 0; CurTop := 0; for i := 0 to ChildCount-1 do begin c := Children[i] as TWABD_Object; if (c.Visible=False) and not (csDesigning in ComponentState) then continue; con := c.Object_To_Control(np); if con<>nil then begin con.Name := c.Name; con.Parent := np; con.Top := CurTop; con.Left := 0; CurTop := CurTop + con.Height; MaxHgt := MaxHgt + con.Height; if con.Width > MaxWid then MaxWid := con.Width; end; end; np.Height := MaxHgt; np.Width := MaxWid; np.BevelOuter := bvNone; np.Visible := True; Result := np; end; // ************************************************************************ // TWABD_Body. Ancestor of TWABD_Frameset, TWABD_Form, TWABD_HTML and TWABD_HTMLFile. // ************************************************************************ constructor TWABD_Body.Create(AOwner:TComponent); begin inherited; FJS_OnUserLoad:=TWABD_JS_Function.Create(jsOnLoad); FJS_OnUserUnload:=TWABD_JS_Function.Create(jsOnUnload); FJS_OnUserEvent:=TWABD_JS_Function.Create(jsOnEvent); FJS_OnUserSubmit:=TWABD_JS_Function.Create(jsOnSubmit); FClientProcessTime:=-1; FClientSubmitTimeStamp:=-1; FClientLoadTimeStamp:=-1; FFieldValues:=TStringList.Create; FUseSessionCookie:=false; end; destructor TWABD_Body.Destroy; begin FFieldValues.Free; FJS_OnUserLoad.free; FJS_OnUserUnload.free; FJS_OnUserEvent.free; FJS_OnUserSubmit.free; inherited; end; procedure TWABD_Body.ProcessRequest(Request:TWABD_CustomRequest); begin if Assigned(FOnSubmit) then FOnSubmit(self,Request); end; procedure TWABD_Body.DoShow; begin if Assigned(OnShow) then OnShow(Self); end; procedure TWABD_Body.CreateSessionCookie; var s:string; c:TWABD_Cookie; begin if (Session<>nil) and (Session.Response<>nil) then begin s:=format(WABD_SES_ID_STR_FORMAT,[Session.SessionID,Name]); c:=Session.Response.Cookies.GetCookieByName(WABD_SES_ID_STR); if c=nil then Session.Response.Cookies.Add(WABD_SES_ID_STR,s) else c.Value:=s; end; end; function TWABD_Body.GetFieldValueCount:integer; begin Result:=FFieldValues.Count; end; function TWABD_Body.GetFieldValue(i:integer):string; begin if (i<0) or (i>=FFieldValues.Count) then raise Exception.CreateFmt('Invalid field value index (%d)',[i]); Result:=FFieldValues.Strings[i]; end; function TWABD_Body.GetFieldValueByName(s:string):string; var i:integer; begin i:=FFieldValues.IndexOfName(s); if (i<0) then raise Exception.CreateFmt('Unknown field value name (%s)',[s]); Result:=FFieldValues.Strings[i]; end; procedure TWABD_Body.SetFieldValue(i:integer; Value:string); begin if (i<0) or (i>=FFieldValues.Count) then raise Exception.CreateFmt('Invalid field value index (%d)',[i]); FFieldValues.Strings[i]:=Value; end; procedure TWABD_Body.SetFieldValueByName(s:string; Value:string); var i:integer; begin i:=FFieldValues.IndexOfName(s); if (i<0) then raise Exception.CreateFmt('Unknown field value name (%s)',[s]); FFieldValues.Strings[i]:=Value; end; // ************************************************************************ // TWABD_Frame/TWABD_Frameset/TWABD_ExternalFrame // ************************************************************************ constructor TWABD_ExternalFrame.Create(AOwner:TComponent); begin inherited; FType:=eftOther; end; procedure TWABD_ExternalFrame.SetFrameType(AType:TWABD_ExternalFrameType); begin case AType of eftBlank: FFrameName:='_blank'; eftParent: FFrameName:='_parent'; eftSelf: FFrameName:='_self'; eftTop: FFrameName:='_top'; eftSearch: FFrameName:='_search'; else if FFrameName='' then FFrameName:=Name; end; FType:=AType; end; procedure TWABD_ExternalFrame.SetFrameName(AName:string); begin if (FType<>eftOther) and (not (csLoading in ComponentState)) then raise Exception.Create('Cannot specify framename when specific frametype chosen.'); FFrameName:=AName; end; function TWABD_ExternalFrame.Object_To_HTML: string; begin Result:=''; end; function TWABD_ExternalFrame.Object_To_Control(AOwner: TWinControl): TControl; begin Result:=nil; end; procedure TWABD_ExternalFrame.HTML_To_Object(FormVal: string); begin end; constructor TWABD_Frame.Create(AOwner: TComponent); begin inherited; FLinkBody:=nil; FMarginHeight:=-1; FMarginWidth:=-1; end; procedure TWABD_Frame.SetName(const Value: TComponentName); begin inherited; FFrameName:=Value; end; procedure TWABD_Frame.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if Operation=opRemove then begin if AComponent=FLinkBody then FLinkBody:=nil else if AComponent=Frameset then Frameset:=nil; end; end; procedure TWABD_Frame.SetLinkBody(body:TWABD_Body); begin FLinkBody:=body; body.FFrame:=self; end; procedure TWABD_Frame.SetFrameset(frameset:TWABD_Frameset); begin Parent:=frameset; end; function TWABD_Frame.GetFrameset:TWABD_Frameset; begin Result:=TWABD_Frameset(Parent); end; constructor TWABD_Frameset.Create(AOwner: TComponent); begin inherited; FDivision:=fdHorizontal; FBorderWidth:=-1; FBorderColor:=clNone; FFrameBorder:=true; FParentFrame:=nil; FEdFrameset:= TWABDEditFrameset.Create; FEdFrameset.ParFrameset := self; end; destructor TWABD_Frameset.Destroy; begin FEdFrameset.ParFrameset:=nil; FEdFrameset.free; inherited; end; procedure TWABD_Frameset.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation=opRemove) and (AComponent=FJavascript) then FJavascript:=nil; end; procedure TWABD_Frameset.Loaded; begin if Assigned(OnCreate) then OnCreate(Self); end; procedure TWABD_Frameset.Show; begin if not Assigned(FWSession) then raise Exception.CreateFmt('TWABD_Frameset "%s" does not have a WABD_Session!', [Name]); FWSession.NewBody := Self; end; procedure TWABD_Frameset.SetEdFrameset(NewEdFrameset: TWABDEditFrameset); begin // Do nothing end; // Generate Pre form javascript code. function TWABD_Frameset.DoPreScript: string; begin Result := ''; // Check if javascript component to be placed before frameset. if Assigned(FJavascript) then with FJavascript do if Placement=jsFirst then Result:=Result+ProcessMacros(Lines.Text)+CR; if Result<>'' then Result:=JS_BEGIN+Result+JS_END+CR; end; // Generate Post frameset javascript code. function TWABD_Frameset.DoPostScript: string; begin Result := ''; // Check if javascript component to be placed after frameset. if Assigned(FJavascript) then with FJavascript do if Placement=jsLast then Result:=Result+JS_BEGIN+ProcessMacros(Lines.Text)+CR+JS_END+CR; end; function TWABD_Frameset.Object_To_HTML: string; var i : integer; s : string; a : string; ID : longint; DLLName : string; pct : integer; Header,Footer:string; onload : string; begin DoShow(); Header:=''; Footer:=''; if (Session<>nil) and (Session.Request<>nil) then begin DLLName := extractfilename(Session.Request.DLLName); ID := Session.SessionID; // Check if this is the main frameset. Then generate header/footer info. if Session.CurBody=self then begin Header := '<HTML><HEAD>' + CR + '<META NAME="Generator" CONTENT="'+WABD_VERSION_STR+'">' + CR + '<TITLE>' + FFramesetTitle + '</TITLE>' + CR; // If to close opener. Footer := '<BODY'+GenEventCode(FJS_OnUserLoad,nil,0,'')+ GenEventCode(FJS_OnUserUnload,nil,0,'')+'>'; if CloseOpener then Footer:=Footer+JS_BEGIN+'window.opener.close();'+CR+JS_END; Footer:=Footer+'</BODY></HTML>' + CR; end; if (Session.MainBody=self) then begin if (owner<>nil) then begin // Check if any top level javascript, add code for it. for i:=0 to owner.ComponentCount-1 do begin if owner.Components[i] is TWABD_MenuTree then Header:=Header+JS_BEGIN+TWABD_MenuTree(owner.Components[i]).Object_To_Top_HTML+JS_END; end; end; Header:=Header+'</HEAD>'+CR; end; end else begin DLLName := 'Unknown_DLL'; ID := -1; end; CloseOpener:=false; // Setup options. s:='<frameset'; if FBorderWidth>=0 then s:=s+format(' Border="%d" Framespacing="%d"',[FBorderWidth,FBorderWidth]); if not FFrameBorder then s:=s+' Frameborder="0"'; if FBorderColor<>clNone then s:=s+' Bordercolor='+ColorToHTML(FBorderColor,'"'); // Setup col/row divison for subframes. if Division=fdVertical then s:=s+' Cols="' else s:=s+' Rows="'; a:=''; pct:=0; onload:=''; for i:=0 to ChildCount-1 do with TWABD_Frame(Children[i]) do begin if FVisible then begin // Define framesizes. s:=s+a; if FSize=0 then begin if (pct<0) or (pct>=100) then s:=s+'*' else s:=s+inttostr(100-pct)+'%'; pct:=-1; end else if FSize<0 then begin s:=s+inttostr(-FSize)+'%'; if pct>=0 then inc(pct,-FSize); end else begin s:=s+inttostr(FSize); pct:=-1; end; a:=','; end; end; s:=s+'">'+CR; onload:=''; // Loop through subframes and generate code. for i:=0 to ChildCount-1 do begin with TWABD_Frame(Children[i]) do begin if FVisible and Assigned(LinkBody) then begin // Build frame. s:=s+'<frame'; s:=s+format(' Src="%s?%s='+WABD_SES_ID_STR_FORMAT+'&%s=%s&%s=%.8f"', [DllName,WABD_SES_ID_STR,ID,LinkBody.Name,WABD_FRAME_STR,Name, WABD_STAMP_STR,now]); // Setup target name. s:=s+' Name="'+Name+'"'; // Build options. if (not FFrameBorder) and (self.FrameBorder) then s:=s+' frameborder="0"'; if (FBorderColor<>clNone) and (self.BorderColor<>FBorderColor) then s:=s+' bordercolor='+ColorToHTML(FBorderColor,'"'); if not FResize then s:=s+' NoResize'; if FScrolling=fsYes then s:=s+' scrolling=Yes' else if FScrolling=fsNo then s:=s+' scrolling=No'; if FMarginHeight>=0 then s:=s+' MarginHeight='+inttostr(FMarginHeight); if FMarginWidth>=0 then s:=s+' MarginWidth='+inttostr(FMarginWidth); s:=s+'>'+CR; end; end; end; s:=s+'</frameset>'+CR; Result:=Header+DoPreScript+s+DoPostScript+Footer; end; // ************************************************************************ // TWABD_Base_HTML // ************************************************************************ constructor TWABD_Base_HTML.Create(AOwner:TComponent); begin inherited; FHTML:=TStringList.Create; FHTML.Add('<HTML>'); FHTML.Add('<META NAME="Generator" CONTENT="'+WABD_VERSION_STR+'">'); FHTML.Add('<HEAD>'); FHTML.Add('<TITLE>ENTER THE TITLE HERE</TITLE>'); FHTML.Add('<BODY>'); FHTML.Add('...ENTER THE HTML HERE...'); FHTML.Add('</BODY>'); FHTML.Add('</HTML>'); FUseSessionCookie:=true; end; destructor TWABD_Base_HTML.Destroy; begin FHTML.free; inherited; end; procedure TWABD_Base_HTML.Show; begin if not Assigned(FWSession) then raise Exception.CreateFmt('TWABD_Base_HTML "%s" does not have a WABD_Session!', [Name]); FWSession.NewBody := Self; end; // ************************************************************************ // TWABD_HTML // ************************************************************************ function TWABD_HTML.Object_To_HTML:string; begin DoShow; Result:=FHTML.Text; end; function TWABD_HTML.Object_To_WML:string; begin Result:=Object_To_HTML; end; procedure TWABD_HTML.HTML_To_Object(FormVal: string); begin // Do nothing. end; // ************************************************************************ // TWABD_HTMLFile // ************************************************************************ constructor TWABD_HTMLFile.Create(AOwner:TComponent); begin inherited; FLoadedWhen:=0; FSecsBeforeReload:=0; FCached:=false; end; destructor TWABD_HTMLFile.Destroy; begin inherited; end; function TWABD_HTMLFile.Object_To_HTML:string; begin // Check if cached and to be reloaded or not loaded yet then load. if (FLoadedWhen = 0) or ((FCached) and (FSecsBeforeReload>0) and (trunc((now - FLoadedWhen)*24.0*3600.0) > FSecsBeforeReload)) then Reload; DoShow; Result:=FHTML.Text; end; function TWABD_HTMLFile.Object_To_WML:string; begin Result:=Object_To_HTML; end; procedure TWABD_HTMLFile.HTML_To_Object(FormVal: string); begin // Do nothing. end; procedure TWABD_HTMLFile.Reload; var fn:string; begin if FSetup=nil then fn:=FFileName else fn:=FSetup.GetLocalFilePath+FFileName; if fn='' then exit; FHTML.LoadFromFile(fn); FLoadedWhen:=now; end; procedure TWABD_HTMLFile.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation=opRemove) then begin if AComponent=FSetup then FSetup:=nil; end; end; // ************************************************************************ // TWABD_Form // ************************************************************************ procedure TWABD_Form.SetEdForm(NewEdForm: TWABDEditForm); begin // Do nothing end; constructor TWABD_Form.Create(AOwner: TComponent); begin inherited; FTextColor := clNone; FLinkColor := clNone; FVLinkColor := clNone; FALinkColor := clNone; FBgndColor := clNone; FSubmitCount:= 0; FEncType := ''; FEdForm := TWABDEditForm.Create; FEdForm.ParForm := self; FFrame := nil; FSubmitTo := nil; FMarginTop :=-1; FMarginBottom:=-1; FMarginLeft :=-1; FMarginRight:=-1; FWidth:=100; FHeight:=100; FCheckOutOfOrder:=false; FJS_OnUserEventSubmit:=TWABD_JS_Function.Create(jsOnSubmit); end; procedure TWABD_Form.Loaded; begin if Assigned(OnCreate) then OnCreate(Self); end; destructor TWABD_Form.Destroy; begin if Assigned(RefNotify) then RefNotify(Self, Self, opRemove); FJS_OnUserEventSubmit.free; FEdForm.ParForm:=nil; FEdForm.free; inherited; end; procedure TWABD_Form.SetName(const Value: TComponentName); begin if (not (csLoading in ComponentState)) and ((FormTitle='') or (FormTitle=Name)) then FormTitle := Value; inherited; end; procedure TWABD_Form.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if Assigned(RefNotify) then RefNotify(Self, AComponent, Operation); if (Operation=opRemove) then begin if (AComponent=FJavascript) then FJavascript:=nil else if (AComponent=FSubmitTo) then FSubmitTo:=nil; end; end; // Check if out of order. function TWABD_Form.OutOfOrder(Request:TWABD_CustomRequest):boolean; var i:integer; s:string; ch:integer; begin Result:=false; s:=trim(Request.Query.Values[WABD_FORMSUBMITCOUNT_STR]); if length(s)>0 then begin // Check if a number. for i:=1 to length(s) do begin ch:=ord(s[i]); if (ch<ord('0')) or (ch>ord('9')) then exit; end; // If a number, check if in sequence. i:=strtoint(s); if i<FSubmitCount then Result:=true; end; end; // Process input strings to handle events and setting properties of objects. procedure TWABD_Form.ProcessRequest(Request:TWABD_CustomRequest); var ProcessEvents,ProcessProperties:boolean; begin ProcessEvents:=true; ProcessProperties:=false; // Check if double submit of same form. Something out of order. Default ignore and redisplay. if FCheckOutOfOrder then begin FOutOfOrder:=OutOfOrder(Request); if FOutOfOrder then begin ProcessEvents:=false; ProcessProperties:=false; if Assigned(FOnOutOfOrder) then FOnOutOfOrder(self,Request,ProcessProperties,ProcessEvents) end; end; inherited; if not (IsReload or ProcessProperties) then SetProperties(Request); if Assigned(OnSubmitForm) then OnSubmitForm(Self,Request,ProcessEvents); // Call the event handlers. if (not IsReload) and ProcessEvents then Call_Handler(Request); end; procedure TWABD_Form.ClearControl(Child: TWABD_Object; var Stop: boolean; UserData: pointer); begin if Child=nil then exit; // 2.24 // Handle if formsection containing list/combo/check/radio is not visible. if Child.Parent<>nil then if not Child.Parent.Visible then exit; // If radio button, clear it. It will be set later on. if (Child is TWABD_RadioButton) then (Child as TWABD_RadioButton).Checked := False; // Handle if not visible. if not Child.Visible then exit; // If checkbox, clear it. It will be set later on. if (Child is TWABD_CheckBox) then (Child as TWABD_CheckBox).Checked := False // If list/combobox, clear selections. They will be set later on. else if (Child is TWABD_SelLinesObject) then with Child as TWABD_SelLinesObject do begin CopyListSelected(FSelList,FOldSelList); ClearListSelected(FSelList); end; end; procedure TWABD_Form.SetProperties(Request:TWABD_CustomRequest); var i,j : integer; OneLine : string; NameVal : string; Value : string; c : TWABD_Object; begin ForEachChild(ClearControl, nil); for i := 0 to Request.Query.Count-1 do begin OneLine:=Request.Query.Strings[i]; j:=pos('=',OneLine); if j>=0 then begin NameVal:=Copy(OneLine,1,j-1); Value:=Copy(OneLine,j+1,length(OneLine)); end else begin NameVal:=OneLine; Value:=''; end; if (NameVal = WABD_CLIENTLOADTIMESTAMP_STR) then begin FClientLoadTimeStamp:=strtofloat(Value); continue; end; if (NameVal = WABD_CLIENTSUBMITTIMESTAMP_STR) then begin FClientSubmitTimeStamp:=strtofloat(Value); continue; end; if (NameVal = WABD_CLIENTPROCESSTIME_STR) then begin FClientProcessTime:=strtofloat(Value); continue; end; if (copy(NameVal,1,length(WABD_RADIO_STR)) = WABD_RADIO_STR) then begin c := ChildByName(Value); Assert(c<>nil, 'Radio Button does not exist! ' + Value); (c as TWABD_RadioButton).Checked := True; continue; end; // Skip Image clicks if (Pos('.X', UpperCase(NameVal)) <> 0) or (Pos('.Y', UpperCase(NameVal)) <> 0) then continue; if (Copy(NameVal,1,6) = '_WABD_') then continue; c := ChildByName(NameVal); if (c<>nil) and (c is TWABD_Table) then continue; Assert(c<>nil, Format('No property named: %s', [NameVal])); c.HTML_To_Object(HTML_To_ASCII(Value)); end; end; function TWABD_Form.GetEventID(var str:string):string; var i:integer; begin i:=pos(';',str); if i<=0 then begin Result:=str; str:=''; end else begin Result:=copy(str,1,i-1); str:=copy(str,i+1,length(str)); end; end; procedure TWABD_Form.SplitEventID(str:string;var EventID:integer; var CtrlName:string; var Data:string); var i:integer; begin i:=pos(':',str); if i<=0 then begin CtrlName:=''; EventID:=0; exit; end; EventID:=strtoint(copy(str,1,i-1)); str:=copy(str,i+1,length(str)); i:=pos(':',str); CtrlName:=copy(str,1,i-1); Data:=copy(str,i+1,length(str)); end; procedure TWABD_Form.ParseImageParams(Request:TWABD_CustomRequest; var ImageName: string; var x,y: integer); var i, p : integer; n : string; begin ImageName := ''; x := -1; y := -1; for i := 0 to Request.Query.Count-1 do begin n := Request.Query.Names[i]; p := Pos('.X', UpperCase(n)); if p<>0 then begin ImageName := Copy(n, 1, p-1); x := StrToInt(Request.Query.Values[n]); end; p := Pos('.Y', UpperCase(n)); if p<>0 then begin y := StrToInt(Request.Query.Values[n]); end; end; end; procedure TWABD_Form.Call_Handler(Request:TWABD_CustomRequest); var i : integer; OneLine : string; NameVal : string; c : TWABD_Object; b : TWABD_Button; wt : TWABD_Table; l : TWABD_Label; ImageName : string; x, y : integer; ct : string; NoDefault : boolean; EvStr : string; EvID : integer; EvCtrl : string; EvData : string; s : string; p : integer; begin // Check if image type. Create event for click. ParseImageParams(Request, ImageName, x, y); if ImageName<>'' then begin c := ChildByName(ImageName); if c<>nil then (c as TWABD_Base_Image).MouseDown(x, y); exit; end; // Other event. NoDefault:=false; for i := 0 to Request.Query.Count-1 do begin OneLine := Request.Query.Strings[i]; NameVal := Request.Query.Names[i]; if (NameVal = WABD_SES_ID_STR) or (NameVal = WABD_STAMP_STR) then continue; if NameVal = WABD_EVENT_ID_STR then begin EvStr := Request.Query.Values[WABD_EVENT_ID_STR]; // Loop for all events. while EvStr<>'' do begin s:=GetEventID(EvStr); SplitEventID(s,EvID,EvCtrl,EvData); case EvID of WABD_EVENT_USERCHANGE,WABD_EVENT_USERCLICK,WABD_EVENT_USERGOTFOCUS,WABD_EVENT_USERLOSTFOCUS: begin // On.... handler. if EvCtrl='' then continue; // Handle the grouping of radiobuttons. if (copy(EvCtrl,1,length(WABD_RADIO_STR)) = WABD_RADIO_STR) then EvCtrl:=EvData; // Look for object of specified name and call event handler. c := ChildByName(EvCtrl); if c=nil then raise Exception.CreateFmt('Event %d - Component ''%s'' not existing', [EvID,EvCtrl]); if c is TWABD_BaseEventSectionObject then with TWABD_BaseEventSectionObject(c) do try case EvID of WABD_EVENT_USERCHANGE: if Assigned(FOnUserChange) then FOnUserChange(c); WABD_EVENT_USERCLICK: if Assigned(FOnUserClick) then FOnUserClick(c); WABD_EVENT_USERGOTFOCUS: if Assigned(FOnUserGotFocus) then FOnUserGotFocus(c); WABD_EVENT_USERLOSTFOCUS: if Assigned(FOnUserLostFocus) then FOnUserLostFocus(c); end; except raise; end; NoDefault:=true; end; WABD_EVENT_CALLBACK: begin // Clientside userdefined event. if Assigned(FOnUserCallback) then FOnUserCallback(self,evData); end; WABD_EVENT_AUTOLOAD: begin // Autoload other frameset/form. Syntax: autoloadname:1/0 close opener/dont close. SplitSessionID(EvData,EvData,s); c:=ChildByName(EvData); if c<>nil then with c as TWABD_Autoload do begin if Frameset<>nil then begin Frameset.FWSession:=FWSession; Frameset.CloseOpener:=(s='1'); Frameset.show; end else if Form<>nil then begin Form.FWSession:=FWSession; Form.CloseOpener:=(s='1'); Form.show; end; NoDefault:=true; end; end; end; end; continue; end; if NameVal = WABD_FRAME_STR then begin NoDefault:=true; continue; end; // Handles button clicking. if (NameVal = WABD_BUTTON_STR) then begin c := ButtonByCaption(Request.Query.Values[NameVal]); if c<>nil then begin b := c as TWABD_Button; if Assigned(b.OnUserClick) then b.OnUserClick(b); exit; end; end; // Handles label anchor clicking. if (NameVal = WABD_LABEL_STR) then begin c := ChildByName(Request.Query.Values[NameVal]); Assert(c<>nil, 'Label does not exist: ' + Request.Query.Values[NameVal]); l := c as TWABD_Label; if Assigned(l.OnUserClick) then l.OnUserClick(l); exit; end; // Handles embedded table cell clicking via anchors. if (NameVal = WABD_TABLE_STR) then begin c := ChildByName(Request.Query.Values[NameVal]); Assert(c<>nil, 'Table does not exist: ' + Request.Query.Values[NameVal]); // Get data for table. s:=Request.Query.Values[WABD_DATA_STR]; p:=pos(':',s); if p>0 then begin x:=strtoint(copy(s,1,p-1)); y:=strtoint(copy(s,p+1,length(s))); end else begin x:=-1; y:=-1; end; if c is TWABD_Table then begin if assigned(TWABD_Table(c).OnUserClickCell) then TWABD_Table(c).OnUserClickCell(c,y,x); end else if c is TWABD_DataTable then begin if assigned(TWABD_DataTable(c).FTable.OnUserClickCell) then TWABD_DataTable(c).FTable.OnUserClickCell(c,y,x); end; exit; end; // Handles table row clicking via button. c := ChildByName(NameVal); if (c<>nil) and (c is TWABD_Table) then begin wt := c as TWABD_Table; ct := Request.Query.Values[NameVal]; ct := Copy(ct, Length(wt.ClickText)+1, Length(ct)); if Assigned(wt.OnUserClick) then wt.OnUserClick(wt, StrToInt(ct)); exit; end; end; // You can get here if the user just presses enter in an Edit box. if not NoDefault then begin b := GetDefaultButton; if b<>nil then begin if Assigned(b.OnUserClick) then b.OnUserClick(b); exit; end; end; // Not sure what to do here, maybe have a form OnUserClick event? -bpz // raise Exception.Create('Could not find an event handler - No Default Button exists'); end; procedure TWABD_Form.ChildChanged(Sender: TObject); begin end; function TWABD_Form.GetFormBody: string; var TextStr : string; LinkStr : string; VLinkStr : string; ALinkStr : string; BGndStr : string; BGColStr : string; TimeStr : string; MarginStr:string; MHeight,MWidth:integer; function HTMLColStr(col: TColor; ColName: string): string; begin if col <> clNone then Result := ' '+ColName+'='+ColorToHTML(col,'"') else Result := ''; end; begin // <BODY TEXT="#00ffff" LINK="#ff00ff" VLINK="#800000" BACKGROUND="Image3.gif"> TextStr := HTMLColStr(FTextColor, 'TEXT'); LinkStr := HTMLColStr(FLinkColor, 'LINK'); VLinkStr := HTMLColStr(FVLinkColor, 'VLINK'); ALinkStr := HTMLColStr(FALinkColor, 'ALINK'); BGColStr := HTMLColStr(FBgndColor, 'BGCOLOR'); MarginStr:=''; MHeight:=0; MWidth:=0; // Setup vertical margins. if FMarginTop>-1 then begin MarginStr:=format('%s TOPMARGIN=%d',[MarginStr,FMarginTop]); inc(MHeight,FMarginTop); end; if FMarginBottom>-1 then begin MarginStr:=format('%s BOTTOMMARGIN=%d',[MarginStr,FMarginBottom]); inc(MHeight,FMarginBottom); end; if MarginStr<>'' then MarginStr:=format('%s MARGINHEIGHT=%d',[MarginStr,MHeight]); // Setup horizontal margins. if FMarginLeft>-1 then begin MarginStr:=format('%s LEFTMARGIN=%d',[MarginStr,FMarginLeft]); inc(MWidth,FMarginLeft); end; if FMarginRight>-1 then begin MarginStr:=format('%s RIGHTMARGIN=%d',[MarginStr,FMarginRight]); inc(MWidth,FMarginRight); end; if MarginStr<>'' then MarginStr:=format('%s MARGINWIDTH=%d',[MarginStr,MWidth]); // Add background image if set. if assigned(FBgrdImage) then begin if RunningLocal then BGndStr := ' BACKGROUND='+'file://'+FBgrdImage.LocalImagePath else BGndStr := ' BACKGROUND='+FBgrdImage.ImagePath; end; // Check if networkstatistics enabled, place javascript. if (Session<>nil) and (Session.SessionMgr<>nil) and (Session.SessionMgr.NetworkStatistics) then TimeStr:='TimeNetworkLoad('+Name+');' else TimeStr:=''; Result := '<BODY'+MarginStr+TextStr+LinkStr+VLinkStr+ALinkStr+BGndStr+BGColStr+ GenEventCode(FJS_OnUserLoad,nil,0,TimeStr)+GenEventCode(FJS_OnUserUnload,nil,0,'')+'>'; end; // Generate Pre form javascript code. function TWABD_Form.DoPreScript: string; var DoTime:boolean; begin Result := ''; // Check if javascript component to be placed before form. if Assigned(FJavascript) then with FJavascript do if Placement=jsFirst then Result:=Result+ProcessMacros(Lines.Text)+CR; // Check if networkstatistics enabled, place javascript. DoTime:=(Session<>nil) and (Session.SessionMgr<>nil) and (Session.SessionMgr.NetworkStatistics); if DoTime then Result:=Result+GenNetworkTimingJS; if FEventHandlersOnForm then Result:=Result+GenEventHandler(DoTime,FJS_OnUserEventSubmit,FJS_OnUserEvent)+CR; if Result<>'' then Result:=JS_BEGIN+Result+JS_END; end; // Generate Post form javascript code. function TWABD_Form.DoPostScript: string; var i : integer; s : string; s1 : string; al : TWABD_AutoLoad; begin Result := ''; for i := 0 to ChildCount-1 do begin if Children[i].Visible then begin // If autoload component. if (Children[i] is TWABD_Autoload) then begin al:=(Children[i] as TWABD_AutoLoad); s:=format('menubar=%d,toolbar=%d,scrollbars=%d,status=%d,titlebar=%d,resizable=%d,location=%d', [ord(al.MenuBar),ord(al.Toolbar),ord(al.Scrollbars),ord(al.Statusbar),ord(al.Titlebar),ord(al.Resizable),ord(al.Locationbar)]); if al.Delay>0 then begin s1:=format('setTimeout("top.open(\"%s?%s='+WABD_SES_ID_STR_FORMAT+'&%s='+inttostr(WABD_EVENT_AUTOLOAD)+'::%s:%d\",\"\",\"%s\")",%d)', [DllName,WABD_SES_ID_STR,SessionID,Name,WABD_EVENT_ID_STR,al.Name,ord(al.Replace),s,al.Delay]); Result:=Result+URL_To_HTML(s1)+CR; end else Result:=Result+URL_To_HTML(format('top.open("%s?%s='+WABD_SES_ID_STR_FORMAT+'&%s='+inttostr(WABD_EVENT_AUTOLOAD)+'::%s:%d","","%s")', [DllName,WABD_SES_ID_STR,SessionID,Name,WABD_EVENT_ID_STR,al.Name,ord(al.Replace),s]))+CR; end; end; end; // Check if javascript component to be placed after form. if Assigned(FJavascript) then with FJavascript do if Placement=jsLast then Result:=Result+ProcessMacros(Lines.Text)+CR; // If to close opener. if CloseOpener then Result:=Result+'window.opener.close();'+CR; CloseOpener:=false; // Send result back. if Result<>'' then Result:=JS_BEGIN+Result+JS_END; end; function TWABD_Form.FormSections_To_HTML: string; var i : integer; fs : TWABD_FormSection_Base; r : string; shalign,svalign : string; o : TWABD_Object; begin Result := '<TABLE COLS=1'+ValueToHTML('HEIGHT',FHeight)+ValueToHTML('WIDTH',FWidth)+'>'; for i := 0 to ChildCount-1 do begin o:=TWABD_Object(Children[i]); if not o.Visible then continue; // Check if formsection type (alignments can be set). if (o is TWABD_FormSection_Base) then begin fs:=TWABD_FormSection_Base(o); begin fs.FEventHandlersOnFormSection:=false; // Setup form section alignment. case fs.FHorzAlign of alhLeft: shalign:=' ALIGN="left"'; alhCenter: shalign:=' ALIGN="center"'; alhRight: shalign:=' ALIGN="right"'; else shalign:=''; end; case fs.FVertAlign of alvTop: svalign:=' VALIGN="top"'; alvMiddle: svalign:=' VALIGN="middle"'; alvBottom: svalign:=' VALIGN="bottom"'; alvBaseline: svalign:=' VALIGN="baseline"'; else svalign:=''; end; r:=ValueToHTML('HEIGHT',fs.FHeight)+ValueToHTML('WIDTH',fs.FWidth)+shalign+svalign; Result:=Result+'<TR'+r+'><TD>' +fs.Object_To_HTML +'</TD></TR>'; // Check if server based event handler on this formsection. if fs.FEventHandlersOnFormSection then FEventHandlersOnForm:=true; end; end // Ordinary type witout any alignments. else Result:=Result+o.Object_To_HTML+CR; end; Result:=Result+'</TABLE>'; end; function TWABD_Form.FormSections_To_WML: string; var i : integer; o : TWABD_Object; begin Result:=''; for i := 0 to ChildCount-1 do begin o:=TWABD_Object(Children[i]); if not o.Visible then continue; if o is TWABD_FormSection_Base then Result:=Result+TWABD_FormSection_Base(o).Object_To_WML else Result:=Result+o.Object_To_WML; end; end; function TWABD_Form.FormSections_To_WML_Postfield: string; var i : integer; o : TWABD_Object; begin Result:=''; for i := 0 to ChildCount-1 do begin o:=TWABD_Object(Children[i]); if not o.Visible then continue; if o is TWABD_FormSection_Base then Result:=Result+TWABD_FormSection_Base(o).Object_To_WML_Postfield else Result:=Result+o.Object_To_WML_Postfield; end; end; function TWABD_Form.Object_To_HTML: string; var Header : string; Footer : string; SesID : string; EventID : string; TimeStamp: string; ID : longint; DLLName : string; TimeStr : string; Main : string; EType : string; begin DoShow; if (Session<>nil) and (Session.Request<>nil) then begin DLLName := Session.Request.DLLName; ID := Session.SessionID; end else begin DLLName := 'Unknown'; ID := -1; end; // Generate html for components on form. FUploadFileOnForm:=false; FEventHandlersOnForm:=Assigned(FOnUserCallback); Main:=FormSections_To_HTML; // Add the Headers and Footers Header := '<HTML>'+ CR + '<HEAD>'+ CR + DoPreScript + CR + '<META NAME="Generator" CONTENT="'+WABD_VERSION_STR+'">' + CR + '<TITLE>' + FormTitle + '</TITLE>'+ CR + '</HEAD>' + GetFormBody + CR + '<FORM NAME="'+Name+'" ACTION=' + extractfilename(DLLName)+' METHOD=POST'; if (Session<>nil) and (Session.Response<>nil) and (Frame<>nil) then Session.Response.Header.Add('Window-target: '+Frame.FFrameName); if FSubmitTo<>nil then Header:=Header+' TARGET="'+FSubmitTo.FFrameName+'"'; if (Session<>nil) and (Session.SessionMgr<>nil) and (Session.SessionMgr.NetworkStatistics) then TimeStr:='TimeNetworkSubmit(this);' else TimeStr:=''; Footer := '</FORM>'+CR + DoPostScript + '</BODY></HTML>' + CR; SesID := Format('<input type=hidden name=%s value='+WABD_SES_ID_STR_FORMAT+'>' + CR, [WABD_SES_ID_STR, ID,Name]); EventID := Format('<input type=hidden name=%s value=>'+CR, [WABD_EVENT_ID_STR]); TimeStamp:=Format('<input_type=hidden name=%s value=%s>',[WABD_SERVERTIMESTAMP_STR,FormatDateTime('mmddyyyyhhnnss',Now)])+CR; // Determine encode type. EType:=trim(FEncType); if (EType='') and FUploadFileOnForm then EType:='multipart/form-data'; if EType<>'' then Header:=Header+' enctype='+EType; // Finish header. Header:=Header+GenEventCode(FJS_OnUserSubmit,nil,0,TimeStr)+'>'+CR; // Build result string. Result := Header + Main + EventID + SesID + TimeStamp; // Add submit counter for this form to tract double submits (IE5.5 BUG) KBM 19.mar. 2001 inc(FSubmitCount); if FCheckOutOfOrder then Result:=Result+Format('<input type=hidden name=%s value=%d>',[WABD_FORMSUBMITCOUNT_STR,FSubmitCount])+CR; if (Session<>nil) and (Session.SessionMgr<>nil) and (Session.SessionMgr.NetworkStatistics) then Result:=Result+ Format('<input type=hidden name=%s value=%f>',[WABD_SERVERPROCESSTIME_STR,(Now - Session.LastAccess)*60*60*24*1000])+CR+ Format('<input type=hidden name=%s value=%f>',[WABD_CLIENTPROCESSTIME_STR,FClientProcessTime])+CR+ Format('<input type=hidden name=%s value=%.0f>',[WABD_CLIENTSUBMITTIMESTAMP_STR,FClientSubmitTimeStamp])+CR+ Format('<input type=hidden name=%s value=%.0f>',[WABD_CLIENTLOADTIMESTAMP_STR,FClientLoadTimeStamp])+CR+ Footer else Result := Result+Footer; end; function TWABD_Form.Object_To_WML:string; var Header : string; Footer : string; Main : string; Post : string; ID : longint; DLLName : string; EType : string; begin DoShow; if (Session<>nil) and (Session.Request<>nil) then begin DLLName := Session.Request.DLLName; ID := Session.SessionID; end else begin DLLName := 'Unknown'; ID := -1; end; // Generate html for components on form. FUploadFileOnForm:=false; FEventHandlersOnForm:=Assigned(FOnUserCallback); Main:=FormSections_To_WML; Post:=FormSections_To_WML_Postfield; // Generate encoding type. EType:=trim(FEncType); if EType<>'' then EType:=' enctype='+EType; // Prepare the Headers and Footers Header := '<?xml version="1.0"?>'+ CR + '<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">' + CR + '<wml>'+ CR + '<card id="'+Name+'" title="'+FormTitle+'" newcontext="true">' + CR; Footer := '</card>'+CR+'</wml>'+CR; // Build result string. Result := Header + Main + Footer; // Add submit counter for this form to tract double submits (IE5.5 BUG) KBM 19.mar. 2001 inc(FSubmitCount); { if FCheckOutOfOrder then Result:=Result+Format('<input type=hidden name=%s value=%d>',[WABD_FORMSUBMITCOUNT_STR,FSubmitCount])+CR; } end; procedure TWABD_Form.HTML_To_Object(FormVal: string); begin // Nothing. end; procedure TWABD_Form.Show; begin if not Assigned(FWSession) then raise Exception.CreateFmt('TWABD_Form "%s" does not have a WABD_Session!', [Name]); FWSession.NewBody := Self; end; // ************************************************************************ // "TOP" Level Objects // ************************************************************************ // TWABD_Header constructor TWABD_Header.Create(AOwner: TComponent); begin inherited; FNum := 1; end; procedure TWABD_Header.SetName(const Value: TComponentName); begin if (not (csLoading in ComponentState)) and ((FCaption='') or (FCaption=Name)) then Caption := Value; inherited; end; procedure TWABD_Header.SetNum(NewNum: integer); begin if NewNum < 1 then NewNum := 1; if NewNum > 6 then NewNum := 6; FNum := NewNum; end; function TWABD_Header.Object_To_HTML: string; begin Result := Format('<H%d>%s</H%d>'+CR, [HeaderNum, ASCII_To_HTML(Caption), HeaderNum]); end; procedure TWABD_Header.HTML_To_Object(FormVal: string); begin Caption := FormVal; // HTML_To_ASCII(FormVal); // Already done before passed here end; function TWABD_Header.Object_To_Control(AOwner: TWinControl): TControl; var nl : TLabel; begin nl := TLabel.Create(AOwner); nl.Name := Name; nl.Caption := Caption; nl.Font.Name := 'Arial'; nl.Font.Size := 9 + (6-HeaderNum) * 4; nl.Height := Round(nl.Height * 1.2); nl.Transparent := True; Result := nl; end; // TWABD_Tree constructor TWABD_TreeNode.Create(AOwner: TComponent); begin inherited Create(AOwner); FJS_OnUserClick:=TWABD_JS_Function.Create(jsOnClick); FLevel:=0; FDefaultOpen:=false; end; destructor TWABD_TreeNode.Destroy; begin FJS_OnUserClick.free; inherited; end; procedure TWABD_TreeNode.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation=opRemove) then begin if AComponent=FImgIconLink then FImgIconLink:=nil else if AComponent=FSubmitTo then FSubmitTo:=nil; end; end; procedure TWABD_TreeNode.SetCaption(s:string); begin FCaption:=s; Changed; end; procedure TWABD_TreeNode.DefineProperties(Filer: TFiler); begin inherited; Filer.DefineProperty('Level', ReadLevel, WriteLevel, True); end; procedure TWABD_TreeNode.WriteLevel(Writer: TWriter); begin Writer.WriteInteger(FLevel); end; procedure TWABD_TreeNode.ReadLevel(Reader: TReader); begin FLevel := Reader.ReadInteger; end; function TWABD_TreeNode.Object_To_HTML: string; begin Result:=''; end; function TWABD_TreeNode.Object_To_Control(AOwner: TWinControl): TControl; begin Result:=nil; end; procedure TWABD_TreeNode.HTML_To_Object(FormVal: string); begin end; constructor TWABD_Tree.Create(AOwner: TComponent); begin inherited; FEdTree:=TWABDEditTree.Create; FEdTree.ParTree:=self; FJS_OnUserClick:=TWABD_JS_Function.Create(jsOnClick); end; destructor TWABD_Tree.Destroy; begin FJS_OnUserClick.free; inherited; end; procedure TWABD_Tree.SetEdTree(NewEdTree: TWABDEditTree); begin // end; function TWABD_Tree.Object_To_HTML: string; begin Result:=''; // end; function TWABD_Tree.Object_To_Control(AOwner: TWinControl): TControl; var nl : TTreeView; begin nl := TTreeView.Create(AOwner); nl.Name := Name; Result := nl; end; procedure TWABD_Tree.HTML_To_Object(FormVal: string); begin // Nothing. end; procedure TWABD_Tree.ProcessRequest(Request:TWABD_CustomRequest); var s:string; n:TWABD_TreeNode; begin inherited; // Find which node has been cliced. s:=Request.Query.Values[WABD_MENUTREE_STR]; if s<>'' then begin n:=TWABD_TreeNode(FindComponentRecursive(Owner,s)); Assert(n<>nil, 'Node does not exist: ' + s); if Assigned(n.OnUserClick) then n.OnUserClick(n); end; end; function TWABD_Tree.NodeByName(NodeName:string):TWABD_TreeNode; var i:integer; begin NodeName:=UpperCase(NodeName); Result:=nil; for i:=0 to ChildCount-1 do begin if UpperCase(TWABD_TreeNode(Children[i]).Name) = NodeName then begin Result:=TWABD_TreeNode(Children[i]); exit; end; end; end; function TWABD_Tree.AddNode(Name:string; RefNode:TWABD_TreeNode; Flags:TWABD_AddTreeNodeFlags):TWABD_TreeNode; var i:integer; RefIndex:integer; ANode:TWABD_TreeNode; InsLevel:integer; begin // Find index of refnode. RefIndex:=-1; if (RefNode<>nil) then begin for i:=0 to ChildCount-1 do begin // Get node info. ANode:=TWABD_TreeNode(Children[i]); if RefNode=ANode then RefIndex:=i; end; end; // Check insertion level. InsLevel:=0; if RefIndex>=0 then begin if atnChild in flags then InsLevel:=RefNode.Level+1 else InsLevel:=RefNode.Level; end; // Check flags for how to insert. if atnFirst in flags then begin // If Refnode given, look for first node in same level. if RefIndex>=0 then begin for i:=RefIndex-1 downto 0 do if TWABD_TreeNode(Children[i]).FLevel<InsLevel then break; end else i:=0; RefIndex:=i; end else if atnLast in flags then begin // If Refnode given, look for last node in same level. if RefIndex>=0 then begin for i:=RefIndex+1 to ChildCount-1 do if TWABD_TreeNode(Children[i]).FLevel<InsLevel then break; end else i:=ChildCount-1; RefIndex:=i; end; // Check if insert before or after found index. if atnBefore in flags then begin if RefIndex<0 then RefIndex:=0; end else //if atnAfter in flags then begin if RefIndex<0 then RefIndex:=0 else inc(RefIndex); end; if RefIndex<0 then RefIndex:=0; // Create a new node and insert it. Result:=TWABD_TreeNode.Create(self); Result.Name:=Name; Result.Parent:=self; Result.Order:=RefIndex; Result.Level:=InsLevel; end; procedure TWABD_Tree.DeleteNode(ANode:TWABD_TreeNode; FreeNode:boolean); begin ANode.Parent:=nil; if FreeNode then ANode.Free; end; procedure TWABD_Tree.Clear(FreeNodes:boolean); var i:integer; node:TWABD_TreeNode; begin for i:=ChildCount-1 downto 0 do begin node:=TWABD_TreeNode(Children[i]); node.Parent:=nil; if FreeNodes then node.free; end; end; // Menu tree. constructor TWABD_MenuTree.Create(AOwner: TComponent); begin inherited; FImages:=TstringList.create; FVariables:=TstringList.create; end; destructor TWABD_MenuTree.Destroy; begin FVariables.free; FImages.free; inherited; end; procedure TWABD_MenuTree.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation=opRemove) then begin if AComponent=FJavascript then FJavascript:=nil else if AComponent=FSubmitTo then FSubmitTo:=nil; end; end; // Define setup javascript of menutree. function TWABD_MenuTree.GenMenuTreeJSSetup:string; var s:string; sclick,target,shint:string; DLLName:string; ID:longint; i,j:integer; NextLevel:integer; ParentNode,ThisNode:TWABD_TreeNode; nItems:integer; img:string; image:TWABD_Image; Session:TWABD_Session; begin // Get identifiers. if (Frame<>nil) and (Frame.Frameset<>nil) then Session:=Frame.Frameset.FWSession else Session:=nil; if (Session<>nil) and (Session.Request<>nil) then begin DLLName := extractfilename(Session.Request.DLLName); ID := Session.SessionID; end else begin DLLName := 'Unknown_DLL'; ID := -1; end; // Nitti gritti standard stuff. s:='function loadData() {'+CR; s:=s+' top.'+Name+'.clear();'+CR; s:=s+' top.'+Name+'.output=self;'; s:=s+' top.'+Name+'.add(new top.RootNode("root","'+Caption+'","","",""));'+CR; // Traverse tree definition. ParentNode:=nil; nItems:=Tree.ParTree.ChildCount; for i := 0 to nItems-1 do begin // Get node info. ThisNode:=TWABD_TreeNode(Tree.ParTree.Children[i]); if i<nItems-1 then NextLevel:=TWABD_TreeNode(Tree.ParTree.Children[i+1]).Level else NextLevel:=-1; if ParentNode=nil then ParentNode:=ThisNode; // Check level of node to determine how to add it. // Prepare icon to show. if assigned(ThisNode.Icon) then // If icon assigned on node, use it together with setup if assigned. image:=ThisNode.Icon else image:=FImgIconLink; if assigned(image) then // If no icon assigned whatsoever, dont show a node. begin if RunningLocal then img:=image.LocalImagePath else img:=image.ImagePath; image.UpdateImage; end else img:=''; // Check if onuserclick handler assigned. sclick:=''; if assigned(ThisNode.OnUserClick) then begin if FJS_OnUserEvent.FScript<>'' then sclick:=sclick+GenJSFunctionCall(FJS_OnUserEvent)+';'; sclick:=sclick+format('HTTP:%s?%s='+WABD_SES_ID_STR_FORMAT+'&%s=%s',[DllName,WABD_SES_ID_STR,ID,Name,WABD_MENUTREE_STR,ThisNode.Name]) end; // Get target name. if assigned(ThisNode.FSubmitTo) then target:=ThisNode.FSubmitTo.FFrameName else if assigned(self.FSubmitTo) then target:=self.FSubmitTo.FFrameName else target:=''; // Get hint. shint:=ThisNode.hint; // If TOP level. if ThisNode.FLevel = 0 then begin // If contains children, create foldernode otherwise create linknode. if NextLevel>ThisNode.FLevel then begin s:=s+' top.'+Name+'.add(new top.FolderNode("'+ThisNode.Name+'","root","'+ThisNode.Caption+'","","'+img+'","'+shint+'",'+inttostr(ord(ThisNode.DefaultOpen))+'));'+CR; ParentNode:=ThisNode; end else s:=s+' top.'+Name+'.add(new top.LinkNode("root","'+ThisNode.Caption+'","'+sclick+'","'+target+'","'+img+'","'+shint+'"));'+CR; end // If CHILD level. else if ThisNode.FLevel > ParentNode.FLevel then begin // If contains children, create foldernode otherwise create linknode. if NextLevel>ThisNode.FLevel then begin s:=s+' top.'+Name+'.add(new top.FolderNode("'+ThisNode.Name+'","'+ParentNode.Name+'","'+ThisNode.Caption+'","","'+img+'","'+shint+'",'+inttostr(ord(ThisNode.DefaultOpen))+'));'+CR; ParentNode:=ThisNode; end else s:=s+' top.'+Name+'.add(new top.LinkNode("'+ParentNode.Name+'","'+ThisNode.Caption+'","'+sclick+'","'+target+'","'+img+'","'+shint+'"));'+CR; end // If SIBLING of another lesser level. else if ThisNode.FLevel <= ParentNode.FLevel then begin // if sibling of another lesser level, backtrack to find parent. j:=i-1; while j>=0 do begin ParentNode:=TWABD_TreeNode(Tree.ParTree.Children[j]); if ParentNode.FLevel<ThisNode.FLevel then break; dec(j); end; // If contains children, create foldernode otherwise create linknode. if NextLevel>ThisNode.FLevel then begin s:=s+' top.'+Name+'.add(new top.FolderNode("'+ThisNode.Name+'","'+ParentNode.Name+'","'+ThisNode.Caption+'","","'+img+'","'+shint+'",'+inttostr(ord(ThisNode.DefaultOpen))+'));'+CR; ParentNode:=ThisNode; end else s:=s+' top.'+Name+'.add(new top.LinkNode("'+ParentNode.Name+'","'+ThisNode.Caption+'","'+sclick+'","'+target+'","'+img+'","'+shint+'"));'+CR; end // if SIBLING of prev node (same level). else begin // If contains children, create foldernode otherwise create linknode. if NextLevel>ThisNode.FLevel then s:=s+' top.'+Name+'.add(new top.FolderNode("'+ThisNode.Name+'","'+ParentNode.Name+'","'+ThisNode.Caption+'","","'+img+'","'+shint+'",'+inttostr(ord(ThisNode.DefaultOpen))+'));'+CR else s:=s+' top.'+Name+'.add(new top.LinkNode("'+ParentNode.Name+'","'+ThisNode.Caption+'","'+sclick+'","'+target+'","'+img+'","'+shint+'"));'+CR; end; end; s:=s+'}'+CR; Result:=s; end; // Setup variables from Setup variable and FLayout stringlist. procedure TWABD_MenuTree.SetupVariables; function DefImg(img:TWABD_Image;V:string):string; begin Result:=V+'='; if assigned(img) then begin if RunningLocal then Result:=Result+'file://' + img.LocalImagePath else Result:=Result+img.ImagePath; end; end; begin // Find path to icons. with FVariables do begin Clear; // Build variablelist of menu tree icons. add(DefImg(fImgIconBlank,WABD_MT_IMG_BLANK)); add(DefImg(FImgIconBranchCont,WABD_MT_IMG_BRANCH_CONT)); add(DefImg(FImgIconBranchEnd,WABD_MT_IMG_BRANCH_END)); add(DefImg(FImgIconFolderClosed,WABD_MT_IMG_FOLDER_CLOSED)); add(DefImg(FImgIconFolderOpen,WABD_MT_IMG_FOLDER_OPEN)); add(DefImg(FImgIconRoot,WABD_MT_IMG_ROOT)); add(DefImg(FImgIconMinusCont,WABD_MT_IMG_MINUS_CONT)); add(DefImg(FImgIconMinusEnd,WABD_MT_IMG_MINUS_END)); add(DefImg(FImgIconPlusCont,WABD_MT_IMG_PLUS_CONT)); add(DefImg(FImgIconPlusEnd,WABD_MT_IMG_PLUS_END)); add(DefImg(FImgIconVertLine,WABD_MT_IMG_VERT_LINE)); add(DefImg(FBgrdImage,WABD_MT_IMG_BG)); // Build variablelist of other info. add(WABD_MT_SIZE_FONT+'='+inttostr(FFontSize)); add(WABD_MT_COLOR_FONT+'='+ColorTOHTML(FFontColor,'''')); add(WABD_MT_COLOR_BG+'='+ColorTOHTML(FBGColor,'''')); add(WABD_MT_COLOR_LINK+'='+ColorTOHTML(FLinkColor,'''')); add(WABD_MT_COLOR_VLINK+'='+ColorTOHTML(FVLinkColor,'''')); add(WABD_MT_COLOR_ALINK+'='+ColorTOHTML(FALinkColor,'''')); add(WABD_MT_FRAME+'='+Frame.Name); if FSubmitto=nil then add(WABD_MT_FRAME_TARGET+'='+Frame.FFrameName) else add(WABD_MT_FRAME_TARGET+'='+FSubmitto.FFrameName); end; end; function TWABD_MenuTree.Object_To_Top_HTML: string; procedure UpdImg(img:TWABD_Image); begin if assigned(img) then img.UpdateImage; end; begin // Make sure images are updated. UpdImg(FImgIconBlank); UpdImg(FImgIconBranchCont); UpdImg(FImgIconBranchEnd); UpdImg(FImgIconFolderClosed); UpdImg(FImgIconFolderOpen); UpdImg(FImgIconRoot); UpdImg(FImgIconMinusCont); UpdImg(FImgIconMinusEnd); UpdImg(FImgIconPlusCont); UpdImg(FImgIconPlusEnd); UpdImg(FImgIconVertLine); UpdImg(FBgrdImage); // Setup variables to be used for dynamically alter the javascript. SetupVariables; // Result is modified standard menu javascript. Result:=CR+'var '+Name+'=new Collection("'+Name+'");'+CR+CR; if Assigned(FJavascript) then Result:=Result+Process_Variables(FJavascript.FLines.Text,FVariables); end; function TWABD_MenuTree.Object_To_HTML: string; var header,footer:string; begin DoShow(); Header := '<HTML><HEAD>' + CR + '<META NAME="Generator" CONTENT="'+WABD_VERSION_STR+'">' + CR + '<TITLE>' + FCaption + '</TITLE>' + CR + JS_BEGIN+GenMenuTreeJSSetup+JS_END+ '</HEAD>'+CR+'<BODY onLoad="loadData(); top.Start(top.'+Name+')">'; Footer := '<P>MENUTREE</P></BODY></HTML>'; Result:=Header+Footer; end; procedure TWABD_MenuTree.HTML_To_Object(FormVal: string); begin // Nothing. end; // ************************************************************************ // TWABD_HTMLSection // ************************************************************************ constructor TWABD_HTMLSection.Create(AOwner: TComponent); begin inherited; FHTML := TStringList.Create; end; destructor TWABD_HTMLSection.Destroy; begin FHTML.Free; inherited; end; procedure TWABD_HTMLSection.SetHTML(NewHTML: TStrings); begin FHTML.Assign(NewHTML); end; procedure TWABD_HTMLSection.SetName(const Value: TComponentName); begin if (not (csLoading in ComponentState)) and ((FHTML.Text='') or (FHTML.Text='<P>'+Name+'</P>')) then FHTML.Text := '<P>'+Value+'</P>'; inherited; end; function TWABD_HTMLSection.Object_To_HTML: string; begin Result:=HTML.Text; end; function TWABD_HTMLSection.Object_To_WML: string; begin Result:=Object_To_HTML; end; procedure TWABD_HTMLSection.HTML_To_Object(FormVal: string); begin HTML.Text := FormVal; end; function TWABD_HTMLSection.Object_To_Control(AOwner: TWinControl): TControl; begin Result := nil; end; // ************************************************************************ // TWABD_HTMLFileSection // ************************************************************************ constructor TWABD_HTMLFileSection.Create(AOwner:TComponent); begin inherited; FLoadedWhen:=0; FSecsBeforeReload:=0; FCached:=false; end; destructor TWABD_HTMLFileSection.Destroy; begin inherited; end; function TWABD_HTMLFileSection.Object_To_HTML:string; begin // Check if cached and to be reloaded or not loaded yet then load. if (FLoadedWhen = 0) or ((FCached) and (FSecsBeforeReload>0) and (trunc((now - FLoadedWhen)*24.0*3600.0) > FSecsBeforeReload)) then Reload; Result:=FHTML.Text; end; function TWABD_HTMLFileSection.Object_To_WML:string; begin Result:=Object_To_HTML; end; procedure TWABD_HTMLFileSection.Reload; var fn:string; begin if FSetup=nil then fn:=FFileName else fn:=FSetup.GetLocalFilePath+FFileName; if fn='' then exit; FHTML.LoadFromFile(fn); FLoadedWhen:=now; end; procedure TWABD_HTMLFileSection.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation=opRemove) then begin if AComponent=FSetup then FSetup:=nil; end; end; // ************************************************************************ // TWABD_HTMLEmbed // ************************************************************************ constructor TWABD_HTMLEmbed.Create(AOwner: TComponent); begin inherited; FHTML := TStringList.Create; Width:=PIXELS_PER_CHAR_X * 10; Height:=PIXELS_PER_CHAR_Y*2; end; destructor TWABD_HTMLEmbed.Destroy; begin FHTML.Free; inherited; end; procedure TWABD_HTMLEmbed.SetWidth(w:integer); begin inherited Width:=w; Changed; end; procedure TWABD_HTMLEmbed.SetHeight(h:integer); begin inherited Height:=h; Changed; end; function TWABD_HTMLEmbed.GetWidth:integer; begin Result:=inherited Width; end; function TWABD_HTMLEmbed.GetHeight:integer; begin Result:=inherited Height; end; procedure TWABD_HTMLEmbed.SetHTML(NewHTML: TStrings); begin FHTML.Assign(NewHTML); Changed; end; procedure TWABD_HTMLEmbed.SetName(const Value: TComponentName); begin if (not (csLoading in ComponentState)) and ((FHTML.Text='') or (FHTML.Text='<P>'+Name+'</P>')) then FHTML.Text := '<P>'+Value+'</P>'; inherited; end; function TWABD_HTMLEmbed.Object_To_HTML: string; begin Result:=FHTML.Text; end; function TWABD_HTMLEmbed.Object_To_WML: string; begin Result:=Object_To_HTML; end; procedure TWABD_HTMLEmbed.HTML_To_Object(FormVal: string); begin HTML.Text := FormVal; end; function TWABD_HTMLEmbed.Object_To_Control(AOwner: TWinControl): TControl; var ne:TMemo; begin ne := TMemo.Create(AOwner); ne.Parent := AOwner; ne.Name := Name; ne.Height := 0; ne.Lines.Assign(FHTML); Result := ne; end; // ************************************************************************ // TWABD_HTMLFileEmbed // ************************************************************************ constructor TWABD_HTMLFileEmbed.Create(AOwner:TComponent); begin inherited; FLoadedWhen:=0; FSecsBeforeReload:=0; FCached:=false; end; destructor TWABD_HTMLFileEmbed.Destroy; begin inherited; end; function TWABD_HTMLFileEmbed.Object_To_HTML:string; begin // Check if cached and to be reloaded or not loaded yet then load. if (FLoadedWhen = 0) or ((FCached) and (FSecsBeforeReload>0) and (trunc((now - FLoadedWhen)*24.0*3600.0) > FSecsBeforeReload)) then Reload; Result:=FHTML.Text; end; function TWABD_HTMLFileEmbed.Object_To_WML:string; begin Result:=Object_To_HTML; end; procedure TWABD_HTMLFileEmbed.Reload; var fn:string; begin if FSetup=nil then fn:=FFileName else fn:=FSetup.GetLocalFilePath+FFileName; if fn='' then exit; FHTML.LoadFromFile(fn); FLoadedWhen:=now; end; procedure TWABD_HTMLFileEmbed.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation=opRemove) then begin if AComponent=FSetup then FSetup:=nil; end; end; // TWABD_JS_Function constructor TWABD_JS_Function.Create(jsType:TWABD_JS_Function_Type); begin inherited Create; FParams:=TStringList.create; FPlacement:=jsfLast; FType:=jsType; end; destructor TWABD_JS_Function.Destroy; begin if FParams<>nil then FParams.free; inherited; end; procedure TWABD_JS_Function.SetScript(scr:string); begin FScript:=trim(scr); if (FScript='') then FParams.Clear; end; // TWABD_Javascript constructor TWABD_Javascript.Create(AOwner: TComponent); begin inherited; FPlacement:=jsFirst; FLines:=TStringList.create; end; destructor TWABD_Javascript.Destroy; begin FLines.free; inherited; end; procedure TWABD_Javascript.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation=opRemove) then begin if AComponent=FSetup then FSetup:=nil; end; end; procedure TWABD_Javascript.SetLines(NewLines: TStrings); begin FLines.Assign(NewLines); end; // Process macros. function TWABD_Javascript.ProcessMacros(JS:string):string; function GetValue(macro:string):string; var args,arge:integer; f,arg:string; par:TStringList; begin // Parameterlist. par:=TStringList.create; try // Split into name and argument. args:=pos('(',macro); arge:=pos(')',macro); if args>0 then begin f:=copy(macro,1,args-1); arg:=copy(macro,args+1,(arge-args)-1); par.CommaText:=arg; end else begin f:=macro; arg:=''; end; f:=UpperCase(f); // Look at name. if f='SESSIONID' then Result:=inttostr(SessionID) else if f='DLLNAME' then Result:=DLLName else if f='IMAGEPATH' then begin if Assigned(FSetup) then Result:=FSetup.GetImagePath else Result:=''; end else if f='FRAMESRC' then begin if par.Count<2 then raise Exception.Create('Syntax: [!--FRAMESRC(Framename,Formname)--!]'); Result:=URL_To_HTML(DLLName+'?SESSIONID='+inttostr(SessionID)+':'+par[1]+'&'+WABD_FRAME_STR+'='+par[0]+'&'+WABD_RELOAD_STR+'=Yes'); end else if f='STAMP' then begin Result:=WABD_STAMP_STR+'='+FloatToStr(Now); end else if f='CALLBACK' then begin Result:='HandleEvent('+inttostr(WABD_EVENT_CALLBACK)+',this.form,this,'''+par.CommaText+''')'; end else raise Exception.Create('Unrecognized WABD macro: '+f+'('+arg+')'); finally par.free; end; end; var s,ss,v:string; j,k:integer; begin s:=''; // Processed string. ss:=JS; // Remaining nonprocessed string. // Loop while there are macros to setup. while true do begin j:=pos('[!--',ss); // Look for startermarker for macro. if j>0 then begin s:=s+copy(ss,1,j-1); // Add the raw data before the startermarker as a result. ss:=copy(ss,j,length(ss)); k:=pos('--!]',ss); // Look for the endmarker for macro. if k>0 then begin v:=copy(ss,5,k-5); // Extract macro. ss:=copy(ss,k+4,length(ss)); // Only process rest of the string. s:=s+GetValue(v); end else raise Exception.CreateFmt('Macro endmarker not found %s', [copy(ss,1,30)]); end else // No startermarker found, just add the rest of the text to result and break. begin s:=s+ss; break; end; end; Result := s; end; // TWAND_AutoRefresh function TWABD_Autorefresh.Object_To_HTML:string; var s:string; f:TWABD_Form; begin Result:=''; f:=GetParentForm; if f=nil then exit; if FURL='' then begin if not FNewSession then s:=';URL='+URL_To_HTML(format('%s?%s='+WABD_SES_ID_STR_FORMAT+'&%s=Yes', [DllName,WABD_SES_ID_STR,SessionID,f.Name,WABD_RELOAD_STR])) else s:=''; end else s:=';URL='+URL_To_HTML(FURL); Result:='<META HTTP-EQUIV="refresh" CONTENT="'+inttostr(FInterval)+s+'">' end; function TWABD_Autorefresh.Object_To_WML:string; var s:string; f:TWABD_Form; begin Result:=''; f:=GetParentForm; if f=nil then exit; if FURL='' then begin if not FNewSession then s:=ASCII_To_HTML(format('%s?%s='+WABD_SES_ID_STR_FORMAT+'&%s=Yes', [DllName,WABD_SES_ID_STR,SessionID,f.Name,WABD_RELOAD_STR])) else s:=''; end else s:=ASCII_To_HTML(FURL); if FInterval>0 then Result := '<onevent type="ontimer">'+CR+ '<go href="'+s+'"/>'+CR+ '</onevent>'+CR+ '<timer value="'+inttostr(FInterval * 10)+'"/>' else Result := '<onevent type="onenterforward">'+CR+ '<go href="'+s+'"/>'+CR+ '</onevent>'; end; function TWABD_Autorefresh.Object_To_Control(AOwner: TWinControl): TControl; begin Result := nil; end; procedure TWABD_Autorefresh.HTML_To_Object(FormVal: string); begin // Nothing. end; // TWAND_Expires constructor TWABD_Expires.Create(AOwner:TComponent); begin inherited; FMaxAge:=-1; end; function TWABD_Expires.Object_To_HTML:string; var s:string; begin if FAlwaysReload or (FMaxAge=0) then s:='0' else s:=formatdatetime('ddd","dd mmm yyyy hh":"nn":"ss',FExpires); if FMaxAge>0 then Result:=Result+CR+'<meta http-equiv="Cache-Control" content="max-age="'+inttostr(FMaxAge)+'" forua="true">'; end; // TWAND_Expires function TWABD_Expires.Object_To_WML:string; begin Result:=''; if (Session=nil) or (Session.Response=nil) then exit; if FAlwaysReload or (FMaxAge=0) then begin Session.Response.Header.Add('Cache-Control: no-cache, must-revalidate'); Session.Response.Header.Add('Pragma: no-cache'); end; Session.Response.Header.Add('Expires: '+formatdatetime('ddd","dd mmm yyyy hh":"nn":"ss',FExpires)); if FMaxAge>0 then Session.Response.Header.Add('Cache-Control: max-age='+inttostr(FMaxAge)+', no-cache'); end; function TWABD_Expires.Object_To_Control(AOwner: TWinControl): TControl; begin Result := nil; end; procedure TWABD_Expires.HTML_To_Object(FormVal: string); begin // Nothing. end; // TWABD_FormSection_Grid constructor TWABD_FormSection_Grid.Create(AOwner: TComponent); begin inherited; FGridX := 16; FGridY := 16; FCellBorder := 0; FCellSpace := 0; FCellPad := 0; end; procedure TWABD_FormSection_Grid.SetGridX(NewX: integer); begin FGridX := NewX; Changed; end; procedure TWABD_FormSection_Grid.SetGridY(NewY: integer); begin FGridY := NewY; Changed; end; function TWABD_FormSection_Grid.FormSection_To_HTML: string; const MX = 256; MY = 256; var i : integer; sx : integer; x, y : integer; x2,y2 : integer; tg : TTableGrid; c : TWABD_SectionObject; MaxX : integer; MaxXW : integer; // Max incl. width. MaxY : integer; MaxYH : integer; // Max incl. height. s : string; r : string; va,ha : string; hs : string; cspan : string; rspan : string; nw : string; p,p1 : PTableCell; NumSkip : integer; eTD,eTR,eTable : string; CtrlsInRow: array[0..MY] of integer; CtrlsInCol: array[0..MX] of integer; O : TWABD_SectionObject; begin eTD:='</TD>'; eTR:='</TR>'; eTable:='</TABLE>'; tg := TTableGrid.Create; tg.SetSize(MX, MY); r:=''; try // Clear controls pr row counter. for i:=0 to MY do CtrlsInRow[i]:=0; for i:=0 to MX do CtrlsInCol[i]:=0; // Plot all controls into a grid and gather info about how much space is taken up. MaxX := -1; MaxXW:= -1; MaxY := -1; MaxYH:= -1; for i := 0 to ChildCount-1 do begin c := Children[i] as TWABD_SectionObject; if c.Visible=False then continue; x := c.LeftPos div GridX; y := c.TopPos div GridY; if x < 0 then x := 0; if y < 0 then y := 0; if x >= MX then x := MX-1; if y >= MY then y := MY-1; p := tg.GetCell(x,y); p.SObj := c; if c.ColSpan <> -1 then p.SpanX := c.ColSpan else p.SpanX := c.Width div GridX + 1; if c.RowSpan <> -1 then p.SpanY := c.RowSpan else p.SpanY := c.Height div GridY + 1; if x+p.SpanX >= MX then p.SpanX:=MX-x+1; if x>MaxX then MaxX:=x; if x+p.SpanX >= MaxXW then MaxXW := x+p.SpanX-1; if y+p.SpanY >= MY then p.SpanY:=MY-y+1; if y>MaxY then MaxY:=y; if y+p.SpanY >= MaxYH then MaxYH := y+p.SpanY-1; inc(CtrlsInRow[y]); inc(CtrlsInCol[x]); // Skip cells that this control cover. for x2 := 0 to p.SpanX-1 do for y2 := 0 to p.SpanY-1 do begin tg.GetCell(x+x2,y+y2).Skip := True; end; end; // Let controls 'flow' to the next absolute control (unless its specified how much space it can take up). for y:=0 to MaxY do begin sx:=0; NumSkip:=0; for x:=0 to MaxX do begin p:=tg.GetCell(x,y); if Assigned(p.SObj) and (p.SObj.ColSpan=0) then continue; if (x<MaxX) and (p.SObj=nil) then begin p.Skip:=true; inc(NumSkip); end else begin // showmessage('NumSkip='+inttostr(NumSkip)+' y='+inttostr(y)+' sx='+inttostr(sx)); p1:=tg.GetCell(sx,y); if p1.Sobj<>nil then inc(NumSkip); if (NumSkip>p1.SpanX) then p1.SpanX:=NumSkip; // showmessage('Spanx='+inttostr(p1.SpanX)); p1.Skip:=false; sx:=x; NumSkip:=0; end; end; end; // Output first thin line describing table layout. if FCellBorder<>0 then // If border shown, show this line clearly for debug purpose. s:=' ' else s:=''; r:='<TR>'; for x:=0 to MaxXW do r:=r+'<TD WIDTH='+inttostr(GridX)+' HEIGHT=0>'+s+'</TD>'; r:=r+eTR+CR; // Output the rest. for y := 0 to MaxY do begin r := r + '<TR>'; for x := 0 to MaxX do begin // Check if still controls to paint, otherwise skip rest of line. if (x>0) and (CtrlsInRow[y]<=0) then continue; // First column governs height of this row. if x=0 then hs:=' HEIGHT='+inttostr(GridY) else hs:=''; p := tg.GetCell(x,y); // Determine width. if p.SpanX > 1 then cspan:=' COLSPAN='+inttostr(p.SpanX) else if p.SpanX=0 then cspan:=' COLSPAN='+inttostr(MaxX+1) // WIDTH=100%'; else cspan:=''; // Determine height. if p.SpanY > 1 then rspan:=' ROWSPAN='+inttostr(p.SpanY) else if p.SpanY=0 then rspan:=' ROWSPAN='+inttostr(MaxY+1) //HEIGHT=100%'; else rspan:=''; // If contents in cell, determine how to output it, and do it. o:=p.SObj; if o<>nil then begin dec(CtrlsInRow[y]); // Determine if allow wrapping. if NoWrap or o.NoWrap then nw:=' NOWRAP' else nw:=''; // Determine horizontal alignment. case o.HorzAlign of alhLeft: ha:=' ALIGN=left'; alhRight: ha:=' ALIGN=right'; alhCenter: ha:=' ALIGN=Center'; else ha:=''; end; // Determine vert. alignment case o.FVertAlign of alvTop: va:=' VALIGN="top"'; alvMiddle: va:=' VALIGN="middle"'; alvBottom: va:=' VALIGN="bottom"'; alvBaseline: va:=' VALIGN="baseline"'; else va:=''; end; //ShowMessage(format('x,y=%d,%d SpanX,SpanY=%d,%d Name=%s, cspan,rspan=%s,%s, ws,hs=%s,%s', // [x,y,p.SpanX,p.SpanY,p.SObj.Name,cspan,rspan,ws,hs])); // Build cell contents. r := r + '<TD'+nw+hs+cspan+rspan+ha+va+'>'; r := r + o.Object_To_HTML; r := r + eTD; // Check if server based event handler on this object. if o is TWABD_BaseEventSectionObject then with TWABD_BaseEventSectionObject(o) do begin if Assigned(FOnUserClick) or Assigned(FOnUserChange) or Assigned(FOnUserLostFocus) or Assigned(FOnUserGotFocus) then FEventHandlersOnFormSection:=true; end; end else begin if (x=0) or (not p.Skip) then begin r := r + '<TD'+hs+cspan+'> '+eTD; end else begin // r := r + '<TD'+hs+cspan+'>Skip'+eTD+CR; end; end; end; // x r:=r+eTR+CR end; // y finally tg.Free; end; Result := r; end; function TWABD_FormSection_Grid.FormSection_To_WML: string; const MX = 256; MY = 256; var i : integer; x,y : integer; tg : TTableGrid; c : TWABD_SectionObject; MaxX : integer; MaxY : integer; r,a : string; p : PTableCell; CtrlsInRow: array[0..MY] of integer; CtrlsInCol: array[0..MX] of integer; O : TWABD_SectionObject; begin tg := TTableGrid.Create; tg.SetSize(MX, MY); r:=''; try // Clear controls pr row counter. for i:=0 to MY do CtrlsInRow[i]:=0; for i:=0 to MX do CtrlsInCol[i]:=0; // Plot all controls into a grid. Dont worry to much about space taken up. WML cannot control it anyway. MaxX:=0; MaxY:=0; for i := 0 to ChildCount-1 do begin c := Children[i] as TWABD_SectionObject; if c.Visible=False then continue; x := c.LeftPos div GridX; y := c.TopPos div GridY; if x < 0 then x := 0; if y < 0 then y := 0; if x >= MX then x := MX-1; if y >= MY then y := MY-1; if x > MaxX then MaxX:=x; if y > MaxY then MaxY:=y; p := tg.GetCell(x,y); p.SObj := c; inc(CtrlsInRow[y]); inc(CtrlsInCol[x]); end; // Output WML. for y := 0 to MaxY do begin if length(r)>0 then r:=r+'<br/>'+CR; a:=''; for x := 0 to MaxX do begin // Check if still controls to paint, otherwise skip rest of line. if (x>0) and (CtrlsInRow[y]<=0) then continue; p := tg.GetCell(x,y); // If contents in cell, determine how to output it, and do it. o:=p.SObj; if o<>nil then begin dec(CtrlsInRow[y]); // Build cell contents. r := r + a + o.Object_To_WML; a:=' '; end; end; end; finally tg.Free; end; Result := r; end; function TWABD_FormSection_Grid.FormSection_To_WML_Postfield: string; var i : integer; c : TWABD_SectionObject; begin Result:=''; for i := 0 to ChildCount-1 do begin c := Children[i] as TWABD_SectionObject; if c.Visible=False then continue; Result:=Result+c.Object_To_WML_Postfield; end; end; function TWABD_FormSection_Grid.Object_To_HTML: string; var header : string; footer : string; begin header := Format('<TABLE BORDER=%d CELLSPACING=%d CELLPADDING=%d',[FCellBorder, FCellSpace, FCellPad]); header := header+ValueToHTML('WIDTH',Width)+ValueToHTML('HEIGHT',Height); header:=header+'>'+CR; footer := '</TABLE>' + CR; Result := header + FormSection_To_HTML + footer; end; function TWABD_FormSection_Grid.Object_To_WML: string; var sHorz:string; sTitle:string; begin case HorzAlign of alhLeft: sHorz:=' align="left"'; alhCenter: sHorz:=' align="center"'; alhRight: sHorz:=' align="right"'; else sHorz:=''; end; sTitle:=trim(FTitle); if sTitle<>'' then sTitle:=' title="'+sTitle+'"'; Result:= '<p'+sHorz+'>'+CR + '<fieldset'+stitle+'>' + CR + FormSection_To_WML+CR +'</fieldset>'+CR +'</p>'; end; function TWABD_FormSection_Grid.Object_To_WML_Postfield: string; begin Result:=FormSection_To_WML_Postfield; end; procedure TWABD_FormSection_Grid.HTML_To_Object(FormVal: string); begin // Nothing. end; procedure TWABD_FormSection_Grid.AutoSizeRowCol; var i, t : integer; c : TWABD_SectionObject; rs, cs : integer; begin if csDesigning in ComponentState then exit; // Place each control into a Cell (Row,Col) and set those protected properties // Determine # of Rows & Cols NumRow := -1; NumCol := -1; for i := 0 to ChildCount-1 do begin c := Children[i] as TWABD_SectionObject; c.Col := c.OrigLeft div GridX; Assert(c.Col < 255, Format('Max 255 Columns per FormSection: %d, %d, %d', [c.LeftPos, GridX, c.Col])); c.Row := c.OrigTop div GridY; Assert(c.Row < 255, 'Max 255 Rows per FormSection'); cs := c.Width div GridX; rs := c.Height div GridY; if c.ColSpan>cs then cs:=c.ColSpan; if c.RowSpan>rs then rs:=c.RowSpan; if c.Col+cs > NumCol then NumCol := c.Col+cs; if c.Row+rs > NumRow then NumRow := c.Row+rs; end; // Init RowSizes and ColSizes to GridX, GridY for i := 0 to NumCol-1 do ColSizes[i] := GridX; for i := 0 to NumRow-1 do RowSizes[i] := GridY; // Loop through each Col (& Row), and set its size to the max control size (+CellBorder) in the Col // Only do autosize for ColSpan & RowSpan = 1 for i := 0 to ChildCount-1 do begin c := Children[i] as TWABD_SectionObject; // Check the ColSize t := c.Width + CellBorder * 2; if (t > ColSizes[c.Col]) and (c.ColSpan = 1) then ColSizes[c.Col] := t; // Check the RowSize t := c.Height + CellBorder * 2; if (t > RowSizes[c.Row]) and (c.RowSpan = 1) then RowSizes[c.Row] := t; end; // Calculate ColTot & RowTot ColTot[0] := 0; for i := 1 to NumCol do // note that this goes 1 past the NumCol ColTot[i] := ColTot[i-1] + ColSizes[i-1]; RowTot[0] := 0; for i := 1 to NumRow do RowTot[i] := RowTot[i-1] + RowSizes[i-1]; // Set each control's LeftPos & TopPos to the new values (+CellBorder) for i := 0 to ChildCount-1 do begin c := Children[i] as TWABD_SectionObject; c.LeftPos := ColTot[c.Col] + CellBorder; c.TopPos := RowTot[c.Row] + CellBorder; end; end; function TWABD_FormSection_Grid.Object_To_Control(AOwner: TWinControl): TControl; var np : TPaintPanel; i : integer; c : TWABD_SectionObject; con : TControl; MaxX, MaxY : integer; x, y : integer; begin AutoSizeRowCol; np := TPaintPanel.Create(AOwner); np.FFormSec := Self; np.Parent := AOwner; np.Name := Name; np.Caption := ''; np.GridX := GridX; np.GridY := GridY; np.CellBorder := CellBorder; for i := 0 to ChildCount-1 do begin c := Children[i] as TWABD_SectionObject; if (c.Visible=False) and not (csDesigning in ComponentState) then continue; con := c.Object_To_Control(np); if con<>nil then begin con.Left := c.LeftPos; con.Top := c.TopPos; con.Width := c.Width; con.Height := c.Height; con.Name := c.Name; con.Parent := np; con.Tag := i + 1; end; end; MaxX := -1; MaxY := -1; for i := 0 to np.ControlCount-1 do begin x := np.Controls[i].Left + np.Controls[i].Width; y := np.Controls[i].Top + np.Controls[i].Height; if x > MaxX then MaxX := x; if y > MaxY then MaxY := y; end; np.Width := MaxX + 2; np.Height := MaxY + 2; np.BevelOuter := bvNone; Result := np; end; function TWABD_FormSection_Grid.AddControl(ControlClass: TWABD_SectionObjectClass; Col, Row: integer): TWABD_SectionObject; begin Result := ControlClass.Create(Self); Result.Parent := Self; Result.LeftPos := Col * GridX; Result.TopPos := Row * GridY; Result.ColSpan := 1; Result.RowSpan := 1; end; procedure TWABD_FormSection_Grid.ControlAtFunc(Child: TWABD_Object; var Stop: boolean; UserData: pointer); var so : TWABD_SectionObject; begin if not (Child is TWABD_SectionObject) then exit; so := TWABD_SectionObject(Child); if (so.Col = FindCol) and (so.Row = FindRow) then begin FindCon := Child as TWABD_SectionObject; Stop := True; end; end; function TWABD_FormSection_Grid.ControlAtPos(Col, Row: integer): TWABD_SectionObject; begin FindCon := nil; ForEachChild(ControlAtFunc, FindCon); Result := FindCon; end; // TWABD_BaseTable constructor TWABD_BaseTable.Create(AOwner: TComponent); begin inherited; FClickText := 'Go'; CanClick := False; end; // TWABD_Table constructor TWABD_Table.Create(AOwner: TComponent); begin inherited; CellBorder := 1; CellSpacing := 1; FixedRows := 1; FWidth := 100; // 100% of browser frame. FStrings := TWABD_Table_Strings.Create; FBGColor := clNone; FShowEmptyRows:=true; FOptimize := true; FFontColor := clNone; FFontSize := 3; FLiteral := false; FJS_OnUserKeyPress:=TWABD_JS_Function.Create(jsOnKeyPress); FJS_OnUserKeyUp:=TWABD_JS_Function.Create(jsOnKeyUp); FJS_OnUserKeyDown:=TWABD_JS_Function.Create(jsOnKeyDown); FJS_OnUserClick:=TWABD_JS_Function.Create(jsOnClick); FJS_OnUserDblClick:=TWABD_JS_Function.Create(jsOnDblClick); FJS_OnUserMouseOver:=TWABD_JS_Function.Create(jsOnMouseOver); FJS_OnUserMouseDown:=TWABD_JS_Function.Create(jsOnMouseDown); FJS_OnUserMouseUp:=TWABD_JS_Function.Create(jsOnMouseUp); FJS_OnUserMouseMove:=TWABD_JS_Function.Create(jsOnMouseMove); FJS_OnUserMouseOut:=TWABD_JS_Function.Create(jsOnMouseOut); end; destructor TWABD_Table.Destroy; begin FStrings.Free; FJS_OnUserKeyPress.free; FJS_OnUserKeyUp.free; FJS_OnUserKeyDown.free; FJS_OnUserClick.free; FJS_OnUserDblClick.free; FJS_OnUserMouseOver.free; FJS_OnUserMouseDown.free; FJS_OnUserMouseUp.free; FJS_OnUserMouseMove.free; FJS_OnUserMouseOut.free; inherited; end; function TWABD_Table.GetBut(Row: integer): string; begin Result := Format('<INPUT TYPE=SUBMIT NAME=%s VALUE="%s %d">', [Name, ClickText, Row]); end; function TWABD_Table.Object_To_HTML: string; var r, c : integer; DataOn, DataOff : string; Data, ws : string; w,h : integer; ha : TWABD_HorzAlignment; va : TWABD_VertAlignment; sha,sva : string; sBGColor,scolor : string; sww : string; s : string; BGcolor,color : TColor; size : integer; fb,fi,fu,ff,fst : boolean; allowwordwrap : boolean; clickable : boolean; fw : integer; show : boolean; eTD,eTR : string; target : TWABD_Base_Frame; mover,mout,mdown : string; mup,mclick,mdblclick : string; mkeypress,mkeydown : string; mkeyup,id : string; mjavascript : string; starget : string; sevent : string; begin // If to optimize, dont send /TD and /TR. if Optimize then begin eTD:=''; eTR:=''; end else begin eTD:='</TD>'; eTR:='</TR>'; end; // If to calculate fixed width. if FWidth=0 then begin fw:=0; for c:=0 to Cells.Cols-1 do inc(fw,ColWidth[c]); fw:=Round(fw * PIXELS_PER_CHAR_X * 1.05); end else fw:=FWidth; // Build HTML code for table. if FBGColor<>clNone then sBGcolor:=' BGCOLOR='+ColorToHTML(FBGcolor,'"') else sBGcolor:=''; if FFontColor<>clNone then scolor:=' COLOR='+ColorToHTML(FFontColor,'"') else scolor:=''; sevent:=GenEventCode(FJS_OnUserKeyPress,nil,0,'')+ GenEventCode(FJS_OnUserKeyUp,nil,0,'')+ GenEventCode(FJS_OnUserKeyDown,nil,0,'')+ GenEventCode(FJS_OnUserClick,nil,0,'')+ GenEventCode(FJS_OnUserDblClick,nil,0,'')+ GenEventCode(FJS_OnUserMouseOver,nil,0,'')+ GenEventCode(FJS_OnUserMouseDown,nil,0,'')+ GenEventCode(FJS_OnUserMouseUp,nil,0,'')+ GenEventCode(FJS_OnUserMouseMove,nil,0,'')+ GenEventCode(FJS_OnUserMouseOut,nil,0,''); Result := '<TABLE BORDER='+inttostr(CellBorder) +ValueToHTML('WIDTH',fw) +ValueToHTML('HEIGHT',Height) +sevent +'>'+CR+'<FONT ' +sBGColor +scolor+ 'SIZE='+inttostr(FFontSize)+'>'; for r := 0 to Cells.Rows-1 do begin // Determine if to show this row. show:=FShowEmptyRows; if not FShowEmptyRows then begin for c := 0 to Cells.Cols-1 do if Trim(Cells[c,r])<>'' then begin show:=true; break; end; end; if not show then continue; // Check if Javascript setup for row. mjavascript:=''; if Assigned(FSetupRowJavascript) then begin mover:=''; mout:=''; mdown:=''; mup:=''; mclick:=''; mdblclick:=''; mkeypress:=''; mkeydown:=''; mkeyup:=''; id:=''; FSetupRowJavascript(self,r,-1,id,mdown,mup,mover,mout,mclick,mdblclick,mkeypress,mkeydown,mkeyup,target); if mover<>'' then mover:=' onmouseover='+mover; if mout<>'' then mout:=' onmouseout='+mout; if mdown<>'' then mdown:=' onmousedown='+mdown; if mup<>'' then mup:=' onmouseup='+mup; if mclick<>'' then mclick:=' onclick='+mclick; if mdblclick<>'' then mdblclick:=' ondblclick='+mdblclick; if mkeypress<>'' then mkeypress:=' onkeypress='+mkeypress; if mkeydown<>'' then mkeydown:=' onkeydown='+mkeydown; if mkeyup<>'' then mkeyup:=' onkeyup='+mkeyup; if id<>'' then id:=' ID='+id; mjavascript:=id+mover+mout+mdown+mup+mclick+mdblclick+mkeypress+mkeydown+mkeyup; end; Result := Result + '<TR '+mjavascript+'>'; if CanClick then begin if r > 0 then Data := GetBut(r) else Data := ' '; Result := Result + '<TD>' + Data + eTD; end; for c := 0 to Cells.Cols-1 do begin fb:=false; fu:=false; fi:=false; fst:=false; ff:=false; w:=ColWidth[c]; Data:=Cells[c,r]; ha:=ColAlign[c]; va:=alvNone; color:=clNone; BGcolor:=clNone; allowwordwrap:=ColWrap[c]; size:=-1; // Check if to render cell differently. if Assigned(FRenderCell) then FRenderCell(self,r,c,Data,ha,va,color,BGcolor,size,fb,fi,fu,ff,fst,w,h,allowwordwrap); // Check if cell should be clickable. clickable:=ColClickable[c]; if (FSubmitTo<>nil) then target:=FSubmitTo else target:=GetParentForm.FSubmitTo; if Assigned(FSetupClickableCell) then FSetupClickableCell(self,r,c,clickable,target); // Check if Javascript setup for cell. mjavascript:=''; if Assigned(FSetupCellJavascript) then begin mover:=''; mout:=''; mdown:=''; mup:=''; mclick:=''; mdblclick:=''; mkeypress:=''; mkeydown:=''; mkeyup:=''; id:=''; FSetupCellJavascript(self,r,c,id,mdown,mup,mover,mout,mclick,mdblclick,mkeypress,mkeydown,mkeyup,target); if mover<>'' then mover:=' onmouseover='+mover; if mout<>'' then mout:=' onmouseout='+mout; if mdown<>'' then mdown:=' onmousedown='+mdown; if mup<>'' then mup:=' onmouseup='+mup; if mclick<>'' then mclick:=' onclick='+mclick; if mdblclick<>'' then mdblclick:=' ondblclick='+mdblclick; if mkeypress<>'' then mkeypress:=' onkeypress='+mkeypress; if mkeydown<>'' then mkeydown:=' onkeydown='+mkeydown; if mkeyup<>'' then mkeyup:=' onkeyup='+mkeyup; if id<>'' then id:=' ID='+id; mjavascript:=id+mover+mout+mdown+mup+mclick+mdblclick+mkeypress+mkeydown+mkeyup; end; // Determine actual cell width. if (w<>0) {and (r = 0)} then begin ws := ' WIDTH='+inttostr(15 + Round(w * PIXELS_PER_CHAR_X * 1.25)); end else begin ws := ''; end; // Specify wordwrap allowed in cell. if not allowwordwrap then sww:=' NOWRAP' else sww:=''; // Determine horz. alignment. case ha of alhLeft: if Optimize then sha:='' else sha:=' ALIGN=left'; alhRight: sha:=' ALIGN=right'; alhCenter: sha:=' ALIGN=center'; else sha:=''; end; // Determine vert. alignment case va of alvTop: sva:=' VALIGN=top'; alvBottom: sva:=' VALIGN=bottom'; alvMiddle: sva:=' VALIGN=middle'; alvBaseline: sva:=' VALIGN=baseline'; else sva:=''; end; // Determine background color. if BGcolor<>clNone then sBGcolor:=' BGCOLOR='+ColorToHTML(BGcolor,'"') else sBGcolor:=''; // Convert data to display. if not FLiteral then begin Data := Ascii_To_HTML(Data); if Data='' then Data := ' '; end; // Determine font color/size. if (color<>clNone) or (size<>-1) then begin s:='<FONT'; if color<>clNone then s:=s+' color='+ColorToHTML(color,'"'); if size<>-1 then s:=s+' size='+inttostr(size); s:=s+'>'; Data:=s+Data+'</FONT>'; end; // Add controls for bold,underlined, italics and fixed font. if fb then Data:='<B>'+Data+'</B>'; if fu then Data:='<U>'+Data+'</U>'; if fi then Data:='<I>'+Data+'</I>'; if ff then Data:='<TT>'+Data+'</TT>'; if fst then Data:='<S>'+Data+'</S>'; // Prepare actual cell HTML code. DataOn := '<TD'+ws+sww+sha+sva+sBGcolor+mJavascript+'>'; DataOff := eTD; // Check if target set. if target<>nil then sTarget:=' TARGET="'+target.FFrameName+'"' else sTarget:=''; if clickable then Data:='<A HREF='+GetHRef(GetParentForm,self,WABD_TABLE_STR,format('%d:%d',[c,r]))+sTarget+'>'+Data+'</A>'; if Assigned(FSetupCellJavascript) then Data:=Data; Result := Result + DataOn + Data + DataOff; end; Result := Result + eTR + CR; end; Result := Result + '</TABLE>'+CR; end; procedure TWABD_Table.HTML_To_Object(FormVal: string); begin // Nothing. end; procedure TWABD_Table.SetStrings(NewStrings: TWABD_Table_Strings); begin FStrings.Assign(NewStrings); end; function TWABD_Table.GetColWidth(i: integer): integer; begin Assert((i >= 0) and (i < FStrings.XSize) and (i <= 255), 'ColWidth Index out of Range'); Result := FColWid[i]; end; procedure TWABD_Table.SetColWidth(i: integer; v: integer); begin Assert((i >= 0) and (i < FStrings.XSize) and (i <= 255), 'ColWidth Index out of Range'); FColWid[i] := v; end; function TWABD_Table.GetColAlign(i: integer): TWABD_HorzAlignment; begin Assert((i >= 0) and (i < FStrings.XSize) and (i <= 255), 'ColAlign Index out of Range'); Result := FColAlign[i]; end; procedure TWABD_Table.SetColAlign(i: integer; v: TWABD_HorzAlignment); begin Assert((i >= 0) and (i < FStrings.XSize) and (i <= 255), 'ColAlign Index out of Range'); FColAlign[i] := v; end; function TWABD_Table.GetColWrap(i: integer): boolean; begin Assert((i >= 0) and (i < FStrings.XSize) and (i <= 255), 'ColWrap Index out of Range'); Result := FColWrap[i]; end; procedure TWABD_Table.SetColWrap(i: integer; v: boolean); begin Assert((i >= 0) and (i < FStrings.XSize) and (i <= 255), 'ColWrap Index out of Range'); FColWrap[i] := v; end; function TWABD_Table.GetColClickable(i: integer): boolean; begin Assert((i >= 0) and (i < FStrings.XSize) and (i <= 255), 'ColClickable Index out of Range'); Result := FColClickable[i]; end; procedure TWABD_Table.SetColClickable(i: integer; v: boolean); begin Assert((i >= 0) and (i < FStrings.XSize) and (i <= 255), 'ColClickable Index out of Range'); FColClickable[i] := v; end; function TWABD_Table.Object_To_Control(AOwner: TWinControl): TControl; var nt : TStringGridEx; x, y : integer; cw, w, tw : integer; begin nt := TStringGridEx.Create(AOwner); nt.ClickText := ClickText; nt.Name := Name; nt.CanClick := CanClick; nt.Options := nt.Options + [goColSizing, goRowSelect]; nt.FixedCols := FixedCols; nt.FixedRows := FixedRows; nt.ColCount := Cells.Cols; nt.RowCount := Cells.Rows; tw := 0; for x := 0 to nt.ColCount-1 do begin cw := -1; if ColWidth[x]=0 then begin // Use the largest column width for y := 0 to nt.RowCount-1 do begin nt.Cells[x,y] := Cells[x,y]; w := Round(Length(Cells[x,y]) * PIXELS_PER_CHAR_X * 1.25); if w > cw then cw := w; end; end else begin cw := Round(ColWidth[x] * PIXELS_PER_CHAR_X * 1.25); end; nt.ColWidths[x] := cw; tw := tw + cw; end; nt.Width := tw + 25; nt.Height := nt.DefaultRowHeight * nt.RowCount + 25; Result := nt; end; // TWABD_DataTable Helper Functions function FieldTypeIsString(ft: TFieldType): boolean; begin Result := True; case ft of ftUnknown, ftBytes, ftVarBytes, ftBlob, ftGraphic, ftFmtMemo, ftMemo, ftParadoxOle, ftDBaseOle, ftTypedBinary: Result := False; end; end; function VisFieldCount(ds: TDataSet): integer; var i : integer; begin Result := 0; for i := 0 to ds.FieldCount-1 do if ds.Fields[i].Visible then Inc(Result); end; function VisField(ds: TDataSet; idx: integer): TField; var i, tmp : integer; begin Result := nil; tmp := 0; for i := 0 to ds.FieldCount-1 do if ds.Fields[i].Visible then begin if (idx = tmp) then Result := ds.Fields[i]; Inc(tmp); end; end; // TWABD_DataLink procedure TWABD_DataLink.ActiveChanged; begin if assigned(FOnActiveChanged) then FOnActiveChanged(self); end; procedure TWABD_DataLink.DatasetChanged; begin if assigned(FOnDatasetChanged) then FOnDatasetChanged(self); end; // TWABD_DataTable constructor TWABD_DataTable.Create(AOwner: TComponent); begin inherited; FShowForm := True; FNavButs := True; FShowTable := True; FMaxRows := 10; FNumCol := 3; FColWidth := 150; FAutoWid := True; FRecordCount:=0; FActiveRec := 0; Stat := ''; DidAppend := False; FCanSelectRecord:=true; FCalcPages := true; FDataLink := TWABD_DataLink.Create; FDataLink.OnActiveChanged:=RecountRecords; FFormSec := TWABD_FormSection.Create(Self); FFormSec.Parent := self; FNavForm := TWABD_FormSection.Create(Self); FNavForm.Parent := self; FTable := TWABD_Table.Create(Self); FTable.Parent := self; FTable.CanClick := FCanSelectRecord; FTable.OnUserClick := TableClick; end; function TWABD_DataTable.GetOptimize:boolean; begin if FTable<>nil then Result:=FTable.Optimize else Result:=false; end; function TWABD_DataTable.GetBGColor:TColor; begin if FTable<>nil then Result:=FTable.BGColor else Result:=clNone; end; function TWABD_DataTable.GetCellBorder:integer; begin if FTable<>nil then Result:=FTable.CellBorder else Result:=0; end; function TWABD_DataTable.GetCellSpacing:integer; begin if FTable<>nil then Result:=FTable.CellSpacing else Result:=0; end; function TWABD_DataTable.GetWidth:integer; begin if FTable<>nil then Result:=FTable.Width else Result:=0; end; function TWABD_DataTable.GetShowEmptyRows:boolean; begin if FTable<>nil then Result:=FTable.ShowEmptyRows else Result:=false; end; function TWABD_DataTable.GetFontColor:TColor; begin if FTable<>nil then Result:=FTable.FontColor else Result:=clNone; end; function TWABD_DataTable.GetFontSize:integer; begin if FTable<>nil then Result:=FTable.FontSize else Result:=3; end; function TWABD_DataTable.GetSubmitTo:TWABD_Base_Frame; begin if FTable<>nil then Result:=FTable.SubmitToFrame else Result:=nil; end; procedure TWABD_DataTable.SetSubmitTo(fr:TWABD_Base_Frame); begin if FTable<>nil then FTable.SubmitToFrame:=fr; end; function TWABD_DataTable.GetJSOnUserKeyPress:TWABD_JS_Function; begin if FTable<>nil then Result:=FTable.JS_OnUserKeyPress else Result:=nil; end; procedure TWABD_DataTable.SetJSOnUserKeyPress(Value:TWABD_JS_Function); begin if FTable<>nil then FTable.JS_OnUserKeyPress:=Value; end; function TWABD_DataTable.GetJSOnUserKeyDown:TWABD_JS_Function; begin if FTable<>nil then Result:=FTable.JS_OnUserKeyDown else Result:=nil; end; procedure TWABD_DataTable.SetJSOnUserKeyDown(Value:TWABD_JS_Function); begin if FTable<>nil then FTable.JS_OnUserKeyDown:=Value; end; function TWABD_DataTable.GetJSOnUserKeyUp:TWABD_JS_Function; begin if FTable<>nil then Result:=FTable.JS_OnUserKeyUp else Result:=nil; end; procedure TWABD_DataTable.SetJSOnUserKeyUp(Value:TWABD_JS_Function); begin if FTable<>nil then FTable.JS_OnUserKeyUp:=Value; end; function TWABD_DataTable.GetJSOnUserClick:TWABD_JS_Function; begin if FTable<>nil then Result:=FTable.JS_OnUserClick else Result:=nil; end; procedure TWABD_DataTable.SetJSOnUserClick(Value:TWABD_JS_Function); begin if FTable<>nil then FTable.JS_OnUserClick:=Value; end; function TWABD_DataTable.GetJSOnUserDblClick:TWABD_JS_Function; begin if FTable<>nil then Result:=FTable.JS_OnUserDblClick else Result:=nil; end; procedure TWABD_DataTable.SetJSOnUserDblClick(Value:TWABD_JS_Function); begin if FTable<>nil then FTable.JS_OnUserDblClick:=Value; end; function TWABD_DataTable.GetJSOnUserMouseOver:TWABD_JS_Function; begin if FTable<>nil then Result:=FTable.JS_OnUserMouseOver else Result:=nil; end; procedure TWABD_DataTable.SetJSOnUserMouseOver(Value:TWABD_JS_Function); begin if FTable<>nil then FTable.JS_OnUserMouseOver:=Value; end; function TWABD_DataTable.GetJSOnUserMouseMove:TWABD_JS_Function; begin if FTable<>nil then Result:=FTable.JS_OnUserMouseMove else Result:=nil; end; procedure TWABD_DataTable.SetJSOnUserMouseMove(Value:TWABD_JS_Function); begin if FTable<>nil then FTable.JS_OnUserMouseMove:=Value; end; function TWABD_DataTable.GetJSOnUserMouseDown:TWABD_JS_Function; begin if FTable<>nil then Result:=FTable.JS_OnUserMouseDown else Result:=nil; end; procedure TWABD_DataTable.SetJSOnUserMouseDown(Value:TWABD_JS_Function); begin if FTable<>nil then FTable.JS_OnUserMouseDown:=Value; end; function TWABD_DataTable.GetJSOnUserMouseUp:TWABD_JS_Function; begin if FTable<>nil then Result:=FTable.JS_OnUserMouseUp else Result:=nil; end; procedure TWABD_DataTable.SetJSOnUserMouseUp(Value:TWABD_JS_Function); begin if FTable<>nil then FTable.JS_OnUserMouseUp:=Value; end; function TWABD_DataTable.GetJSOnUserMouseOut:TWABD_JS_Function; begin if FTable<>nil then Result:=FTable.JS_OnUserMouseOut else Result:=nil; end; procedure TWABD_DataTable.SetJSOnUserMouseOut(Value:TWABD_JS_Function); begin if FTable<>nil then FTable.JS_OnUserMouseOut:=Value; end; procedure TWABD_DataTable.SetOptimize(o:boolean); begin if FTable<>nil then FTable.Optimize:=o; end; procedure TWABD_DataTable.SetBGColor(c:TColor); begin if FTable<>nil then FTable.BGColor:=c; end; procedure TWABD_DataTable.SetCellBorder(i:integer); begin if FTable<>nil then FTable.CellBorder:=i; end; procedure TWABD_DataTable.SetCellSpacing(i:integer); begin if FTable<>nil then FTable.CellSpacing:=i; end; procedure TWABD_DataTable.SetWidth(w:integer); begin if FTable<>nil then FTable.Width:=w; end; procedure TWABD_DataTable.SetShowEmptyRows(s:boolean); begin if FTable<>nil then FTable.ShowEmptyRows:=s; end; procedure TWABD_DataTable.SetFontColor(c:TColor); begin if FTable<>nil then FTable.FontColor:=c; end; procedure TWABD_DataTable.SetFontSize(sz:integer); begin if FTable<>nil then FTable.FontSize:=sz; end; procedure TWABD_DataTable.RecountRecords(Sender:TObject); begin if DataSource<>nil then if DataSource.DataSet<>nil then with FDataLink.DataSource.DataSet do begin if Active then FActiveRec:=1 else FActiveRec:=0; if (Active) and (FCalcPages) then begin Last; First; FRecordCount:=RecordCount; end; end; end; function TWABD_DataTable.GetRenderCell:TWABD_OnRenderCellEvent; begin if FTable<>nil then Result:=FTable.OnRenderCell else Result:=nil; end; procedure TWABD_DataTable.SetRenderCell(Event:TWABD_OnRenderCellEvent); begin if FTable<>nil then FTable.OnRenderCell:=Event; end; function TWABD_DataTable.GetUserClickCell:TWABD_OnUserClickCellEvent; begin if FTable<>nil then Result:=FTable.OnUserClickCell else Result:=nil; end; procedure TWABD_DataTable.SetUserClickCell(Event:TWABD_OnUserClickCellEvent); begin if FTable<>nil then FTable.OnUserClickCell:=Event; end; function TWABD_DataTable.GetSetupClickableCell:TWABD_OnSetupClickableCellEvent; begin if FTable<>nil then Result:=FTable.OnSetupClickableCell else Result:=nil; end; procedure TWABD_DataTable.SetSetupClickableCell(Event:TWABD_OnSetupClickableCellEvent); begin if FTable<>nil then FTable.OnSetupClickableCell:=Event; end; function TWABD_DataTable.GetSetupCellJavascript:TWABD_OnSetupJavascriptEvent; begin if FTable<>nil then Result:=FTable.OnSetupCellJavascript else Result:=nil; end; procedure TWABD_DataTable.SetSetupCellJavascript(Event:TWABD_OnSetupJavascriptEvent); begin if FTable<>nil then FTable.OnSetupCellJavascript:=Event; end; function TWABD_DataTable.GetSetupRowJavascript:TWABD_OnSetupJavascriptEvent; begin if FTable<>nil then Result:=FTable.OnSetupRowJavascript else Result:=nil; end; procedure TWABD_DataTable.SetLiteral(Value:boolean); begin if FTable<>nil then FTable.Literal:=Value; end; function TWABD_DataTable.GetLiteral:boolean; begin if FTable<>nil then Result:=FTable.Literal else Result:=false; end; procedure TWABD_DataTable.SetSetupRowJavascript(Event:TWABD_OnSetupJavascriptEvent); begin if FTable<>nil then FTable.OnSetupRowJavascript:=Event; end; procedure TWABD_DataTable.SetName(const NewName: TComponentName); begin inherited; FTable.Name := Name + '_Tab'; end; destructor TWABD_DataTable.Destroy; begin FDataLink.Free; inherited; end; procedure TWABD_DataTable.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation = opRemove) and (AComponent = FDataLink.DataSource) then FDataLink.DataSource := nil; end; function TWABD_DataTable.GetDataSource: TDataSource; begin Result := FDataLink.DataSource; end; procedure TWABD_DataTable.SetDataSource(NewDataSource: TDataSource); begin FDataLink.DataSource := NewDataSource; if NewDataSource<>nil then NewDataSource.FreeNotification(self); end; function TWABD_DataTable.GetNumPages:integer; begin if FRecordCount<=0 then Result:=0 else if FMaxRows<=0 then Result:=1 else begin Result:=(FRecordCount div FMaxRows); if (FRecordCount mod FMaxRows) > 0 then inc(Result); end; end; function TWABD_DataTable.GetPage:integer; begin Result:=0; if FMaxRows<=0 then Result:=1 else if FActiveRec>0 then Result:=((FActiveRec-1) div FMaxRows)+1; end; function TWABD_DataTable.Object_To_HTML: string; var t1, t2, t3 : string; begin Result := ''; if DataSource = nil then exit; if ShowEditForm then begin InitForm; t1 := FFormSec.Object_To_HTML + '<br>'; end; if ShowNavButs then begin InitNavButs; t2 := FNavForm.Object_To_HTML + '<br>'; end; if ShowTable then begin InitTable; t3 := FTable.Object_To_HTML + '<br>'; end; Result := t1 + t2 + t3; end; procedure TWABD_DataTable.HTML_To_Object(FormVal: string); begin // Nothing. end; procedure TWABD_DataTable.NextPage; begin NextPgClick(self); end; procedure TWABD_DataTable.PrevPage; begin PrevPgClick(self); end; procedure TWABD_DataTable.LastPage; begin LastClick(self); end; procedure TWABD_DataTable.FirstPage; begin FirstClick(self); end; procedure TWABD_DataTable.FirstClick(Sender: TObject); begin DidAppend := False; if (DataSource=nil) or (DataSource.DataSet=nil) then exit; if DataSource.DataSet.BOF then Stat := 'Already at First Record' else Stat := 'Moved to First Record'; DataSource.DataSet.First; if FActiveRec>0 then FActiveRec:=1; end; procedure TWABD_DataTable.LastClick(Sender: TObject); begin if (DataSource=nil) or (DataSource.DataSet=nil) then exit; DidAppend := False; if DataSource.DataSet.EOF then Stat := 'Already at Last Record' else Stat := 'Moved to Last Record'; DataSource.DataSet.Last; if FActiveRec>0 then FActiveRec:=FRecordCount; end; procedure TWABD_DataTable.NextClick(Sender: TObject); begin if (DataSource=nil) or (DataSource.DataSet=nil) then exit; DidAppend := False; DataSource.DataSet.Next; if DataSource.DataSet.EOF then Stat := 'Already at Last Record' else begin Stat := 'Moved to Next Record'; if FActiveRec>0 then inc(FActiveRec); end; end; procedure TWABD_DataTable.PrevClick(Sender: TObject); begin if (DataSource=nil) or (DataSource.DataSet=nil) then exit; DidAppend := False; DataSource.DataSet.Prior; if DataSource.DataSet.BOF then Stat := 'Already at First Record' else begin Stat := 'Moved to Previous Record'; if FActiveRec>0 then dec(FActiveRec); end; end; procedure TWABD_DataTable.NextPgClick(Sender: TObject); begin if (DataSource=nil) or (DataSource.DataSet=nil) then exit; DidAppend := False; if (not DataSource.DataSet.EOF) and (FActiveRec + MaxRows <= FRecordCount) then begin DataSource.DataSet.MoveBy(MaxRows); if FActiveRec>0 then begin if DataSource.DataSet.EOF then FActiveRec:=FRecordCount else inc(FActiveRec,MaxRows); end; Stat := 'Moved to Next Page'; end else Stat := 'Allready at Last Page'; end; procedure TWABD_DataTable.PrevPgClick(Sender: TObject); begin if (DataSource=nil) or (DataSource.DataSet=nil) then exit; DidAppend := False; if (not DataSource.DataSet.BOF) and (FActiveRec - MaxRows > 0) then begin DataSource.DataSet.MoveBy(-MaxRows); if FActiveRec>0 then begin if DataSource.DataSet.BOF then FActiveRec:=1 else dec(FActiveRec,MaxRows); end; Stat := 'Moved to Previous Page'; end else Stat := 'Allready at First Page'; end; procedure TWABD_DataTable.JumpToTableRecord(RowIndex: integer); var r:longint; begin if (DataSource=nil) or (DataSource.DataSet=nil) then exit; DidAppend := False; r:=DataSource.DataSet.MoveBy(RowIndex-1); if FActiveRec>0 then inc(FActiveRec,r); Stat := 'Moved to Record'; end; procedure TWABD_DataTable.TableClick(Sender: TObject; RowIndex: integer); var MoveToRecord : boolean; begin if (DataSource=nil) or (DataSource.DataSet=nil) then exit; MoveToRecord := True; if Assigned(OnRecordClick) then OnRecordClick(Self, RowIndex, MoveToRecord); if MoveToRecord then JumpToTableRecord(RowIndex); end; procedure TWABD_DataTable.AddClick(Sender: TObject); begin if (DataSource=nil) or (DataSource.DataSet=nil) then exit; DidAppend := False; try Assert(not ReadOnly, 'DataSet is Read Only!'); DataSource.DataSet.Append; if FRecordCount>0 then inc(FRecordCount); DidAppend := True; Stat := 'Fields initialized, make changes and then select "Edit" to save'; InitForm; except on e: Exception do begin Stat := e.Message; DataSource.DataSet.Cancel; end; end; end; procedure TWABD_DataTable.EditClick(Sender: TObject); var i : integer; we : TWABD_Edit; EdName : string; f : TField; begin if (DataSource=nil) or (DataSource.DataSet=nil) then exit; try Assert(not ReadOnly, 'DataSet is Read Only!'); if DidAppend then DataSource.DataSet.Append else DataSource.DataSet.Edit; // Read in the Field Values with FFormSec do begin for i := 0 to VisFieldCount(DataSource.DataSet)-1 do begin f := VisField(DataSource.DataSet, i); EdName := Self.Name + '_TFE_' + IntToStr(i); we := ChildByName(EdName) as TWABD_Edit; f.AsString := we.Text; end; end; DataSource.DataSet.Post; Stat := 'Field updated'; DidAppend := False; except on e: Exception do begin Stat := e.Message; DataSource.DataSet.Cancel; DidAppend := False; end; end; end; procedure TWABD_DataTable.DeleteClick(Sender: TObject); begin if (DataSource=nil) or (DataSource.DataSet=nil) then exit; DidAppend := False; try Assert(not ReadOnly, 'DataSet is Read Only!'); DataSource.DataSet.Delete; if FRecordCount>0 then dec(FRecordCount); Stat := 'Deleted Record'; except on e: Exception do Stat := e.Message; end; end; procedure TWABD_DataTable.InitForm; var i : integer; x, y : integer; ds : TDataSet; f : TField; nl : TWABD_Label; ne : TWABD_Edit; begin ds := DataSource.DataSet; with FFormSec do begin // Clear out old Controls for i := ChildCount-1 downto 0 do Children[i].Free; GridX := FColWidth; GridY := 25; x := 0; y := 0; for i := 0 to VisFieldCount(ds)-1 do begin f := VisField(ds, i);; // Create the Label nl := TWABD_Label.Create(Self); nl.Parent := FFormSec; nl.Caption := f.DisplayLabel; nl.LeftPos := x * GridX; nl.TopPos := (y*2) * GridY; nl.ColSpan := 1; // Create the Edit Box ne := TWABD_Edit.Create(Self); ne.Name := Self.Name + '_TFE_' + IntToStr(i); ne.Parent := FFormSec; ne.LeftPos := x * GridX; ne.TopPos := (y*2+1) * GridY; ne.Size := (GridX - 10) div PIXELS_PER_CHAR_X; ne.Text := f.AsString; // go to the next position x := x + 1; if x = FNumCol then begin x := 0; y := y + 1; end; end; end; end; procedure TWABD_DataTable.CreateNavBut(x, y : integer; ButCap: string; OnUserClick: TNotifyEvent); var b : TWABD_Button; begin b := TWABD_Button.Create(Self); b.Parent := FNavForm; b.LeftPos := x; b.TopPos := y; b.Caption := ButCap; b.OnUserClick := OnUserClick; end; procedure TWABD_DataTable.InitNavButs; const X = 50; var i : integer; nl : TWABD_Label; begin // Clear out old Controls for i := FNavForm.ChildCount-1 downto 0 do FNavForm.Children[i].Free; FNavForm.GridX := X; FNavForm.GridY := 35; CreateNavBut(X * 0, 0, 'First', FirstClick); CreateNavBut(X * 1, 0, 'Last', LastClick); CreateNavBut(X * 2, 0, 'Prev', PrevClick); CreateNavBut(X * 3, 0, 'Next', NextClick); CreateNavBut(X * 4, 0, 'Prev+', PrevPgClick); CreateNavBut(X * 5, 0, 'Next+', NextPgClick); if ShowEditForm and (not ReadOnly) then begin CreateNavBut(X * 7, 0, 'Add', AddClick); CreateNavBut(X * 8, 0, 'Edit', EditClick); CreateNavBut(X * 9, 0, 'Delete', DeleteClick); end; nl := TWABD_Label.Create(Self); nl.Parent := FNavForm; nl.LeftPos := 0; nl.TopPos := 35; if Stat='' then Stat := 'Viewing ' + DataSource.DataSet.Name; nl.Caption := Format('Status: %s', [Stat]); end; procedure TWABD_DataTable.InitTable; var ds : TDataSet; i : integer; bm : TBookmark; row : integer; mr : integer; f : TField; begin FTable.CanClick:=FCanSelectRecord; ds := DataSource.DataSet; FTable.Cells.SetSize(0, 0); mr:=FMaxRows; if mr<=0 then mr:=FRecordCount; if mr<=0 then mr:=10; FTable.Cells.SetSize(VisFieldCount(ds), mr + 1); // Set the Column Widths if not AutoWidth then begin for i := 0 to VisFieldCount(ds)-1 do begin FTable.ColWidth[i] := VisField(ds, i).DisplayWidth; // Table will convert Chars to Pixels end; end; // Set the Field Headers and alignment. for i := 0 to VisFieldCount(ds)-1 do begin f:=VisField(ds,i); // Setup header. FTable.Cells[i, 0] := f.DisplayLabel; // If field is datetime, dont allow wrap. FTable.ColWrap[i]:=not (f.DataType in [ftDate,ftTime,ftDateTime]); // Setup alignment. case f.Alignment of taRightJustify: FTable.ColAlign[i]:=alhRight; taCenter: FTable.ColAlign[i]:=alhCenter; else FTable.ColAlign[i]:=alhLeft; end; end; bm := ds.GetBookmark; row := 0; repeat for i := 0 to VisFieldCount(ds)-1 do begin FTable.Cells[i, row+1] := VisField(ds, i).DisplayText; end; ds.Next; row := row + 1; until (row >= mr) or (ds.EOF); ds.GotoBookmark(bm); ds.FreeBookmark(bm); end; // TWABD_Hidden function TWABD_Hidden.Object_To_HTML: string; begin Result := '<input type=hidden name='+Name+' value='+Value+'>' + CR; end; procedure TWABD_Hidden.HTML_To_Object(FormVal: string); begin Value := FormVal; end; function TWABD_Hidden.Object_To_Control(AOwner: TWinControl): TControl; var ne : TEdit; begin ne := TEdit.Create(AOwner); ne.Parent := AOwner; ne.Name := Name; ne.Height := 0; ne.Text := Value; Result := ne; end; // TWABD_BlankLines constructor TWABD_BlankLines.Create(AOwner: TComponent); begin inherited; FNumLines := 1; end; function TWABD_BlankLines.Object_To_HTML: string; var i : integer; begin Result := ''; for i := 0 to FNumLines-1 do begin Result := Result + '<P> </P>'; end; end; function TWABD_BlankLines.Object_To_WML: string; var i:integer; begin Result := ''; for i := 0 to FNumLines-1 do Result := Result + '<br/>'; end; function TWABD_BlankLines.Object_To_Control(AOwner: TWinControl): TControl; var np : TPaintPanel; begin np := TPaintPanel.Create(AOwner); np.BevelOuter := bvNone; np.Height := FNumLines * PIXELS_PER_CHAR_Y; np.Name := Name; np.Caption := ''; Result := np; end; procedure TWABD_BlankLines.HTML_To_Object(FormVal: string); begin // Nothing. end; // ************************************************************************ // Form Level Objects // ************************************************************************ // TWABD_SectionObject constructor TWABD_SectionObject.Create(AOwner: TComponent); begin inherited; FLeftPos := 0; FTopPos := 0; FWidth := 0; FHeight := 0; FColSpan := -1; FRowSpan := -1; end; destructor TWABD_SectionObject.Destroy; begin inherited; end; procedure TWABD_SectionObject.SetLeft(NewLeft: integer); begin if (NewLeft<>OrigLeft) then begin FLeftPos := NewLeft; OrigLeft := NewLeft; Changed; end; end; procedure TWABD_SectionObject.SetTop(NewTop: integer); begin if (NewTop<>OrigTop) then begin FTopPos := NewTop; OrigTop := NewTop; Changed; end; end; function TWABD_SectionObject.GenerateOptionHTML:string; var s:string; begin s:=''; if FTabIndex<>0 then s:=s+' TABINDEX='+inttostr(FTabIndex); if FDisabled then s:=s+' DISABLED'; if FAccessKey<>'' then s:=s+' ACCESSKEY="'+copy(FAccessKey,1,1)+'"'; Result:=s; end; // TWABD_BaseEventSectionObject constructor TWABD_BaseEventSectionObject.Create(AOwner:TComponent); begin inherited; FJS_OnUserKeyPress:=TWABD_JS_Function.Create(jsOnKeyPress); FJS_OnUserKeyUp:=TWABD_JS_Function.Create(jsOnKeyUp); FJS_OnUserKeyDown:=TWABD_JS_Function.Create(jsOnKeyDown); FJS_OnUserClick:=TWABD_JS_Function.Create(jsOnClick); FJS_OnUserDblClick:=TWABD_JS_Function.Create(jsOnDblClick); FJS_OnUserMouseOver:=TWABD_JS_Function.Create(jsOnMouseOver); FJS_OnUserMouseDown:=TWABD_JS_Function.Create(jsOnMouseDown); FJS_OnUserMouseUp:=TWABD_JS_Function.Create(jsOnMouseUp); FJS_OnUserMouseMove:=TWABD_JS_Function.Create(jsOnMouseMove); FJS_OnUserMouseOut:=TWABD_JS_Function.Create(jsOnMouseOut); FJS_OnUserGotFocus:=TWABD_JS_Function.Create(jsOnFocus); FJS_OnUserLostFocus:=TWABD_JS_Function.Create(jsOnBlur); FJS_OnUserChange:=TWABD_JS_Function.Create(jsOnChange); end; destructor TWABD_BaseEventSectionObject.Destroy; begin FJS_OnUserKeyPress.Free; FJS_OnUserKeyUp.Free; FJS_OnUserKeyDown.Free; FJS_OnUserClick.Free; FJS_OnUserDblClick.Free; FJS_OnUserMouseOver.Free; FJS_OnUserMouseDown.Free; FJS_OnUserMouseUp.Free; FJS_OnUserMouseMove.Free; FJS_OnUserMouseOut.Free; FJS_OnUserGotFocus.Free; FJS_OnUserLostFocus.Free; FJS_OnUserChange.Free; inherited; end; function TWABD_BaseEventSectionObject.GenerateEventScript:string; begin Result := GenEventCode(FJS_OnUserChange,FOnUserChange,WABD_EVENT_USERCHANGE,'')+ GenEventCode(FJS_OnUserClick,FOnUserClick,WABD_EVENT_USERCLICK,'')+ GenEventCode(FJS_OnUserGotFocus,FOnUserGotFocus,WABD_EVENT_USERGOTFOCUS,'')+ GenEventCode(FJS_OnUserLostFocus,FOnUserLostFocus,WABD_EVENT_USERLOSTFOCUS,'')+ GenEventCode(FJS_OnUserDblClick,nil,0,'')+ GenEventCode(FJS_OnUserMouseOver,nil,0,'')+ GenEventCode(FJS_OnUserMouseDown,nil,0,'')+ GenEventCode(FJS_OnUserMouseUp,nil,0,'')+ GenEventCode(FJS_OnUserMouseMove,nil,0,'')+ GenEventCode(FJS_OnUserMouseOut,nil,0,'')+ GenEventCode(FJS_OnUserKeyPress,nil,0,'')+ GenEventCode(FJS_OnUserKeyDown,nil,0,'')+ GenEventCode(FJS_OnUserKeyUp,nil,0,''); end; // TWABD_Autoload constructor TWABD_Autoload.Create(AOwner: TComponent); begin inherited; FDelay:=0; FForm:=nil; FFrameset:=nil; FMenubar:=true; FToolbar:=true; end; procedure TWABD_Autoload.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if Operation=opRemove then begin if AComponent=FForm then FForm:=nil else if AComponent=FFrameSet then FFrameset:=nil; end; end; function TWABD_Autoload.Object_To_HTML: string; begin Result := ''; end; function TWABD_Autoload.Object_To_WML: string; var s:string; f:TWABD_Body; begin Result:=''; f:=GetParentForm; if f=nil then exit; s:=ASCII_To_HTML(format('%s?%s='+WABD_SES_ID_STR_FORMAT+'&%s='+inttostr(WABD_EVENT_AUTOLOAD)+'::%s:%d', [DllName,WABD_SES_ID_STR,SessionID,f.Name,WABD_EVENT_ID_STR,f.Name,ord(Replace)])); if Delay>0 then Result := '<onevent type="ontimer">'+CR+ '<go href="'+s+'"/>'+CR+ '</onevent>'+CR+ '<timer value="'+inttostr(Delay div 100)+'"/>' else Result := '<onevent type="onenterforward">'+CR+ '<go href="'+s+'"/>'+CR+ '</onevent>'; end; procedure TWABD_Autoload.HTML_To_Object(FormVal: string); begin // Nothing. end; function TWABD_Autoload.Object_To_Control(AOwner: TWinControl): TControl; begin Result := nil; end; // TWABD_Anchor constructor TWABD_Anchor.Create(AOwner: TComponent); begin inherited; Destination := ''; end; procedure TWABD_Anchor.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation=opRemove) and (AComponent=FSubmitTo) then FSubmitTo:=nil; end; function TWABD_Anchor.Object_To_HTML: string; var r2 : string; s : string; begin if FSubmitTo<>nil then s:=' TARGET="'+FSubmitTo.FFrameName+'"' else s:=''; s:=trim(Destination+s); Result := '<A NAME='+Name; if s<>'' then Result := Result+' HREF='+s; Result:=Result+'>'; r2 := ASCII_To_HTML(Caption); if Bold then r2 := '<B>' + r2 + '</B>'; if Italic then r2 := '<I>' + r2 + '</I>'; if Underline then r2 := '<U>' + r2 + '</U>'; Result := Result + r2 + '</A>'; end; function TWABD_Anchor.Object_To_WML: string; var r2 : string; s : string; begin Result:=''; s:=trim(Destination); if s='' then exit; Result := '<a '; if s<>'' then Result := Result+' href="'+s+'"'; Result:=Result+'>'; r2 := ASCII_To_HTML(Caption); if Bold then r2 := '<b>' + r2 + '</b>'; if Italic then r2 := '<i>' + r2 + '</i>'; if Underline then r2 := '<u>' + r2 + '</u>'; Result := Result + r2 + '</a>'; end; procedure TWABD_Anchor.HTML_To_Object(FormVal: string); begin // Nothing. end; procedure TWABD_Anchor.SetName(const Value: TComponentName); begin if (not (csLoading in ComponentState)) and ((FCaption='') or (FCaption=Name)) then Caption := Value; inherited; end; procedure TWABD_Anchor.SetCaption(NewCaption: string); begin FCaption := NewCaption; FWidth := Length(Caption) * PIXELS_PER_CHAR_X; FHeight := PIXELS_PER_CHAR_Y + 1; Changed; end; function TWABD_Anchor.Object_To_Control(AOwner: TWinControl): TControl; var nl : TJumpLabel; begin nl := TJumpLabel.Create(AOwner); nl.CanClick := True; nl.JumpDest := FDest; {$IFDEF VER100} nl.Cursor := crHandPoint; {$ENDIF} nl.AutoSize := False; nl.Name := Name; nl.Caption := Caption; nl.Font.Style := nl.Font.Style + [fsUnderLine]; nl.Font.Size := 9; nl.Font.Color := clBlue; nl.Transparent := True; nl.JumpOut := True; Result := nl; end; // TWABD_HotSpot destructor TWABD_HotSpot.Destroy; var OldChange : TNotifyEvent; begin OldChange := FChange; inherited; if Assigned(OldChange) then OldChange(nil); end; procedure TWABD_HotSpot.SetX1(i: integer); begin FX1 := i; Changed; end; procedure TWABD_HotSpot.SetY1(i: integer); begin FY1 := i; Changed; end; procedure TWABD_HotSpot.SetX2(i: integer); begin FX2 := i; Changed; end; procedure TWABD_HotSpot.SetY2(i: integer); begin FY2 := i; Changed; end; procedure TWABD_HotSpot.SetName(const Value: TComponentName); begin inherited; end; procedure TWABD_HotSpot.Changed; begin if Assigned(OnChange) then OnChange(Self); end; // TWABD_Base_Image constructor TWABD_Base_Image.Create(AOwner: TComponent); begin inherited; FHotSpots := TWABD_HotSpots.Create; FHotSpots.ParImage := Self; FAutoSize := true; FImgWidth := 0; FImgHeight := 0; FWidth := 150; FHeight := 150; FClickable := true; FSubmitTo := nil; FSetup := nil; FDest := ''; end; destructor TWABD_Base_Image.Destroy; var i:integer; c:TComponent; h:TWABD_Hotspot; begin // Check if any hotspots pointing on this image, delete them. if Owner<>nil then begin for i:=Owner.Componentcount-1 downto 0 do begin c:=Owner.Components[i]; if c is TWABD_Hotspot then begin h:=c as TWABD_Hotspot; if h.FImParent=self then Owner.RemoveComponent(c); end; end; end; FHotspots.Free; inherited; end; function TWABD_Base_Image.LocalImagePath:string; begin if FSetup=nil then Result:=FImageFile else Result:=FSetup.GetLocalImagePath+FImageFile; end; function TWABD_Base_Image.ImagePath:string; begin if FSetup=nil then Result:=FImageFile else Result:=FSetup.GetImagePath+FImageFile; end; procedure TWABD_Base_Image.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation=opRemove) then begin if (AComponent=FSubmitTo) then FSubmitTo:=nil else if AComponent=FSetup then FSetup:=nil; end; end; procedure TWABD_Base_Image.SetHotSpots(HS: TWABD_HotSpots); begin // Do Nothing end; procedure TWABD_Base_Image.SetImageFile(filename:TFileName); begin FImageFile:=ExtractFilename(filename); if FAutoSize then UpdateImageSize; end; function TWABD_Base_Image.Object_To_HTML: string; var p : string; sevent:string; href:string; w,h,t:string; begin if RunningLocal then p := 'file://' + LocalImagePath else p := ImagePath; if FHeight>0 then h:=' HEIGHT='+inttostr(FHeight) else h:=''; if FWidth>0 then w:=' WIDTH='+inttostr(FWidth) else w:=''; if FTitle<>'' then t:=' TITLE="'+FTitle+'"' else t:=''; Result := '<IMG SRC="'+p+'" ALT="'+ASCII_To_HTML(AltText)+'"'+h+w+t+'>'; if FClickable then begin sevent:=GenerateEventScript; if FDest<>'' then href:=FDest else href:=format('%s?%s='+WABD_SES_ID_STR_FORMAT+'&%s.X=0&%s.Y=0', [DLLName,WABD_SES_ID_STR,SessionID,GetParentForm.Name,Name,Name]); if (FSubmitTo<>nil) or (FDest<>'') then Result:=format('<A HREF="%s" TARGET="%s" %s>%s</A>',[href,FSubmitTo.FFrameName,sevent,Result]) else Result := '<INPUT TYPE=IMAGE NAME='+Name+' SRC="'+p+'" ALT="'+ASCII_To_HTML(AltText)+'" '+sevent+h+w+'>'; end; end; function TWABD_Base_Image.Object_To_WML: string; var p : string; w,h:string; a : string; begin if RunningLocal then p := 'file://' + LocalImagePath else p := ImagePath; if FHeight>0 then h:=' height="'+inttostr(FHeight)+'"' else h:=''; if FWidth>0 then w:=' width="'+inttostr(FWidth)+'"' else w:=''; case FVertAlign of alvTop: a:=' align="top"'; alvMiddle: a:=' align="middle"'; alvBottom: a:=' align="bottom"'; alvNone: a:=''; else a:=''; end; Result := '<img src="/'+p+'" alt="'+ASCII_To_HTML(AltText)+'"'+h+w+a+'/>'; end; procedure TWABD_Base_Image.HTML_To_Object(FormVal: string); begin // Nothing. end; procedure TWABD_Base_Image.SetName(const Value: TComponentName); begin if (not (csLoading in ComponentState)) and ((FAltText='') or (FAltText=Name)) then FAltText := Value; inherited; end; procedure TWABD_Base_Image.UpdateImageSize; var f : string; p : TPicture; begin f := LocalImagePath; if FileExists(f) then begin p := TPicture.Create; try p.LoadFromFile(f); FImgWidth := p.Width; FImgHeight := p.Height; FWidth:=p.Width; FHeight:=p.Height; except on e: Exception do begin end; end; p.Free; end; Changed; end; procedure TWABD_Base_Image.SetImgWidth(w: integer); begin FImgWidth := w; Changed; end; procedure TWABD_Base_Image.SetImgHeight(h: integer); begin FImgHeight := h; Changed; end; procedure TWABD_Base_Image.UpdateImage; begin // Do nothing. end; function TWABD_Base_Image.Object_To_Control(AOwner: TWinControl): TControl; var ni : TImage; bm : TBitmap; begin //showmessage('begin Object to control'); ni := TImage.Create(AOwner); ni.Parent := AOwner; ni.Name := Name; try ni.Picture.LoadFromFile(LocalImagePath); { if ni.Picture.Width>0 then begin FImgWidth:=ni.Picture.Width; FImgHeight:=ni.Picture.Height; FWidth:=FImgWidth; FHeight:=FImgHeight; end; } except on e: Exception do begin end; end; if ni.Picture.Width = 0 then begin bm := TBitmap.Create; bm.Width := Width; bm.Height := Height; bm.Canvas.TextOut(0, 0, 'Unable to load Bitmap: '); bm.Canvas.TextOut(0, 25, LocalImagePath); ni.Picture.Bitmap := bm; bm.Free; end; Result := ni; //showmessage('end Object to control'); end; procedure TWABD_Base_Image.MouseDown(x, y: integer); var i : integer; c : TComponent; h : TWABD_HotSpot; R : TRect; pt : TPoint; begin pt := Point(x, y); Assert(Owner<>nil, Format('Image %s has no Owner', [Name])); for i := 0 to Owner.ComponentCount-1 do begin c := Owner.Components[i]; if (c is TWABD_HotSpot) then begin h := c as TWABD_HotSpot; R := Rect(h.X1, h.Y1, h.X2, h.Y2); if (h.ImageParent = Self) and PtInRect(R, pt) then begin if Assigned(h.OnUserClick) then h.OnUserClick(h); exit; end; end; end; if Assigned(OnMouseDown) then OnMouseDown(Self, x, y); if Assigned(OnUserClick) then OnUserClick(Self); end; // TWABD_LiveImage constructor TWABD_LiveImage.Create(AOwner: TComponent); begin inherited; FDirty := True; WroteFile := False; FImgWidth := 200; FWidth := 200; FImgHeight := 100; FHeight := 100; FImgType := liAuto; FSafeBmp := TBitmap.Create; FSafeBmp.PixelFormat := Graphics.pf8bit; // This is the safest format FSafeBmp.Width:=FImgWidth; FSafeBmp.Height:=FImgHeight; FSafeBmp.Handletype := bmDIB; FSafeBmp.Dormant; end; destructor TWABD_LiveImage.Destroy; begin if WroteFile then DeleteFile(PChar(GetFileName)); FSafeBmp.Free; inherited; end; procedure TWABD_LiveImage.SetPixelFormat(pf:TPixelFormat); begin FSafeBmp.PixelFormat:=pf; end; procedure TWABD_LiveImage.SetTransMode(mode:TTransparentMode); begin FSafeBmp.TransparentMode:=mode; end; procedure TWABD_LiveImage.SetTransColor(color:TColor); begin FSafeBmp.TransparentColor:=color; end; function TWABD_LiveImage.GetPixelFormat:TPixelFormat; begin Result:=FSafeBmp.PixelFormat; end; function TWABD_LiveImage.GetTransMode:TTransparentMode; begin Result:=FSafeBmp.TransparentMode; end; function TWABD_LiveImage.GetTransColor:TColor; begin Result:=FSafeBmp.TransparentColor; end; function TWABD_LiveImage.GetFileName: string; begin Result := LocalImagePath; end; procedure TWABD_LiveImage.SetImgWidth(w: integer); begin inherited; if not (csLoading in ComponentState) then begin FSafeBmp.Width:=FImgWidth; FSafeBmp.Height:=FImgHeight; FDirty:=true; end; end; procedure TWABD_LiveImage.SetImgHeight(h: integer); begin inherited; if not (csLoading in ComponentState) then begin FSafeBmp.Width:=FImgWidth; FSafeBmp.Height:=FImgHeight; FDirty:=true; end; end; function TWABD_LiveImage.GetSafeBitmap: TBitmap; begin FDirty := True; // Assume it gets modified Result := FSafeBmp; end; function TWABD_LiveImage.GetCanvas: TCanvas; begin FDirty := True; Result := FSafeBmp.canvas; end; procedure TWABD_LiveImage.Loaded; begin inherited; FSafeBmp.Width:=FImgWidth; FSafeBmp.Height:=FImgHeight; Changed; end; function TWABD_LiveImage.DetermineImageType:TLiveImageType; begin // If specified directly. if ImageType<>liAuto then begin Result:=ImageType; exit; end; // Check if WML request. if (Session<>nil) and (Session.Request<>nil) and (Session.Request.RequestType=WABD_REQUESTTYPE_WML) then Result:=liWBMP // Some sort of HTML request. Determine from image layout. else if PixelFormat in [pf1bit, pf4bit, pf8bit] then Result:=liGIF else Result:=liJPEG; end; function TWABD_LiveImage.GetNewName: string; var ext : string; begin case DetermineImageType of liBMP: ext := '.bmp'; liJPEG: ext := '.jpg'; liGIF: ext := '.gif'; liWBMP: ext := '.wbmp'; end; if (Session<>nil) and (Session.SessionMgr<>nil) then Result := Format('I%7.7x%s', [ Session.SessionMgr.DrawSequenceValue(WABD_IMAGE_SEQUENCE), ext]) else Result := 'I'+Name+ext; end; procedure TWABD_LiveImage.UpdateImage; var gif:TGIFImage; jpg:TJPEGImage; wbmp:TkbmWAPBitmap; Ext:TGIFGraphicControlExtension; i:integer; begin if FDirty then begin try DeleteFile(PChar(GetFileName)); except end; WroteFile := False; FFileName := GetNewName; ImageFile := FFileName; case DetermineImageType of liBMP: FSafeBmp.savetofile(GetFileName); liGIF: begin gif:=TGIFImage.Create; try gif.Assign(FSafeBmp); // Create an extension to set the transparency flag gif.OptimizeColorMap; Ext := TGIFGraphicControlExtension.Create(GIF.Images[0]); if TransparentMode = tmAuto then begin Ext.TransparentColorIndex := gif.Images[0].ActiveColorMap[gif.Images[0].Pixels[0, gif.Height-1]]; Ext.Transparent := true; end else begin i:=gif.GlobalColorMap.IndexOf(TransparentColor and $00FFFFFF); Ext.Transparent:=(i>=0); Ext.TransparentColorIndex := i; //gif.Images[0].ActiveColorMap[i]; end; gif.Images[0].Extensions.Add(Ext); gif.Images[0].Interlaced := FInterlaced; gif.SaveToFile(GetFileName); finally gif.free; end; end; liJPEG: begin jpg:=TJPEGImage.Create; try jpg.Assign(FSafeBmp); jpg.SaveToFile(GetFileName); finally jpg.free; end; end; liWBMP: begin wbmp:=TkbmWAPBitmap.Create; try wbmp.Assign(FSafeBmp); wbmp.PixelFormat:=pf1Bit; wbmp.Monochrome:=true; wbmp.SaveToFile(GetFileName); finally wbmp.free; end; end; end; WroteFile := True; FDirty := False; end; inherited; end; function TWABD_LiveImage.Object_To_HTML: string; begin UpdateImage; if FAutoSize then begin FWidth:=FImgWidth; FHeight:=FImgHeight; end; Result := inherited Object_To_HTML; end; function TWABD_LiveImage.Object_To_WML: string; begin UpdateImage; if FAutoSize then begin FWidth:=FImgWidth; FHeight:=FImgHeight; end; Result := inherited Object_To_WML; end; function TWABD_LiveImage.Object_To_Control(AOwner: TWinControl): TControl; var ni : TImage; bm : Graphics.TBitmap; begin // SaveImage; ni := TImage.Create(AOwner); ni.Parent := AOwner; ni.Name := Name; bm := TBitmap.Create; bm.Width := Width; bm.Height := Height; if not FSafeBMP.Empty then bm.assign(FSafeBMP); with bm.Canvas do begin Font.Name := 'Times New Roman'; Font.Size := 24; Font.Style := Font.Style + [fsItalic, fsBold]; Brush.Style := bsClear; Font.Color := clLtGray; bm.Canvas.TextOut(8, 8, 'Live Image'); Font.Color := clBlue; bm.Canvas.TextOut(5, 5, 'Live Image'); end; ni.Picture.Bitmap:=bm; bm.free; Result := ni; end; // TWABD_Chart procedure TWABD_Chart.Loaded; begin inherited; end; procedure TWABD_Chart.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation=opRemove) and (AComponent=FChart) then FChart:=nil; end; procedure TWABD_Chart.SetChart(Chart: TCustomChart); begin FChart:=Chart; FChart.BufferedDisplay:=false; end; constructor TWABD_Chart.Create(AOwner: TComponent); begin inherited; FChart:=nil; end; destructor TWABD_Chart.Destroy; begin inherited; end; function TWABD_Chart.Object_To_HTML: string; var i:integer; r:TRect; begin if FChart<>nil then begin // Draw the object. FChart.Width:=Width; FChart.Height:=Height; // FChart.Repaint; for i:=0 to FChart.SeriesCount-1 do if FChart.Series[i].Active then FChart.Series[i].RefreshSeries; r:=canvas.ClipRect; FChart.draw(canvas,r); //FChart.SaveToBitmapFile('c:\kbm.bmp'); // KBM DEBUG end; Result:=inherited Object_To_HTML; //ShowMessage('Canvas cliprect='+inttostr(r.Left)+','+inttostr(r.top)+'-'+inttostr(r.right)+','+inttostr(r.bottom)); end; function TWABD_Chart.Object_To_WML: string; var i:integer; r:TRect; begin if FChart<>nil then begin // Draw the object. FChart.Width:=Width; FChart.Height:=Height; // FChart.Repaint; for i:=0 to FChart.SeriesCount-1 do if FChart.Series[i].Active then FChart.Series[i].RefreshSeries; r:=canvas.ClipRect; FChart.draw(canvas,r); //FChart.SaveToBitmapFile('c:\kbm.bmp'); // KBM DEBUG end; Result:=inherited Object_To_WML; end; function TWABD_Chart.Object_To_Control(AOwner: TWinControl): TControl; var img:TImage; i:integer; begin img:=inherited Object_To_Control(AOwner) as TImage; if FChart<>nil then begin for i:=0 to FChart.SeriesCount-1 do FChart.Series[i].RefreshSeries; FChart.ReCalcWidthHeight; FChart.draw(img.picture.bitmap.canvas,img.picture.bitmap.canvas.ClipRect); end else begin with img.picture.bitmap.canvas do begin Font.Name := 'Times New Roman'; Font.Size := 24; Font.Style := Font.Style + [fsItalic, fsBold]; Brush.Style := bsSolid; Font.Color := clLtGray; TextOut(6, 8, 'Chart'); Brush.Style := bsClear; Font.Color := clBlue; TextOut(3, 5, 'Chart'); end; end; Result:=img; end; procedure TWABD_Chart.HTML_To_Object(FormVal: string); begin // Nothing. end; procedure TWABD_Chart.MouseDown(x, y: integer); var i: longint; p: TPoint; lstlabel:TChartValueList; lstvalue:TChartValueList; ser: TChartSeries; begin // Check chart if a bar has been clicked. if (FChart <> nil) and assigned(FOnChartPointClick) then begin ser:=FChart.SeriesList[0]; with FChart,ser do begin p.X:=x; p.Y:=y; i:=Clicked(p.x,p.y); if i>=0 then begin lstValue:=MandatoryValueList; // Some series have inverted X,Y coordinates. This is safe. if lstvalue=YValues then lstlabel:=XValues else lstlabel:=YValues; FOnChartPointClick(self, i, lstlabel.Value[i], lstvalue.Value[i], XLabel[i]); end; end; end; inherited; end; // TWABD_Label constructor TWABD_Label.Create(AOwner: TComponent); begin inherited; FFontSize := 3; FFontColor := clNone; FBold := False; FItalic := False; FUnderline := False; FCanClick := False; end; destructor TWABD_Label.Destroy; begin inherited; end; procedure TWABD_Label.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation=opRemove) and (AComponent=FSubmitTo) then FSubmitTo:=nil; end; function TWABD_Label.Object_To_HTML: string; var SizeStr : string; ColStr : string; s : string; begin Result := ASCII_To_HTML(Caption); if Bold then Result := '<B>' + Result + '</B>'; if Italic then Result := '<I>' + Result + '</I>'; if Underline then Result := '<U>' + Result + '</U>'; if FontSize<>3 then SizeStr := ' SIZE='+IntToStr(FontSize); if FontColor<>clNone then ColStr := ' COLOR='+ColorToHTML(FontColor,'"'); if (SizeStr<>'') or (ColStr<>'') then Result := '<FONT'+SizeStr+ColStr+'>' + Result + '</FONT>'; if CanClick then begin if FSubmitTo<>nil then s:=' TARGET="'+FSubmitTo.FFrameName+'"' else s:=''; Result := '<A HREF='+GetHRef(GetParentForm,self,WABD_LABEL_STR,Name)+s+'>'+Result+'</A>'; end; end; function TWABD_Label.Object_To_WML: string; begin Result := ASCII_To_HTML(Caption); if Bold then Result := '<b>' + Result + '</b>'; if Italic then Result := '<I>' + Result + '</i>'; if Underline then Result := '<u>' + Result + '</u>'; if FontSize<3 then Result := ' <small>' + Result + '</small>'; if FontSize>3 then Result := ' <big>' + Result + '</big>'; if FontColor=clRed then Result := ' <em>' + Result + '</em>' else if FontColor=clBlue then Result := ' <strong>' + Result + '</strong>'; end; procedure TWABD_Label.HTML_To_Object(FormVal: string); begin // Nothing. end; procedure TWABD_Label.SetName(const Value: TComponentName); begin if (not (csLoading in ComponentState)) and ((FCaption='') or (FCaption=Name)) then Caption := Value; inherited; end; procedure TWABD_Label.SetBold(NewBold: boolean); begin FBold := NewBold; UpdateWidHgt; Changed; end; procedure TWABD_Label.UpdateWidHgt; var m : double; begin // FWidth := Length(FCaption) * (PIXELS_PER_CHAR_X + 1); // FHeight := PIXELS_PER_CHAR_Y - 3; if FBold then m := 1.25 else m := 1.0; // Now update based on the FontSize FWidth := Round(Length(FCaption) * XLabPointSizes[FFontSize] * m); FHeight := Round(YLabPointSizes[FFontSize] * m); end; procedure TWABD_Label.SetCaption(NewCaption: string); begin FCaption := NewCaption; UpdateWidHgt; Changed; end; function TWABD_Label.Object_To_Control(AOwner: TWinControl): TControl; var nl : TJumpLabel; begin nl := TJumpLabel.Create(AOwner); nl.AutoSize := True; nl.Font.Size := LabPointSizes[FontSize]; nl.Font.Name := 'Arial'; if FontColor<>clNone then nl.Font.Color := FontColor; if Bold then nl.Font.Style := nl.Font.Style + [fsBold]; if Italic then nl.Font.Style := nl.Font.Style + [fsItalic]; if Underline then nl.Font.Style := nl.Font.Style + [fsUnderline]; nl.Name := Name; nl.Caption := Caption; nl.Transparent := True; nl.CanClick := CanClick; nl.JumpOut := False; Result := nl; end; procedure TWABD_Label.SetFontSize(NewSize: integer); begin if NewSize < 1 then NewSize := 1; if NewSize > 7 then NewSize := 7; FFontSize := NewSize; UpdateWidHgt; Changed; end; // TWABD_LinesObject constructor TWABD_LinesObject.Create(AOwner: TComponent); begin inherited; FLines := TStringList.Create; end; destructor TWABD_LinesObject.Destroy; begin FLines.Free; inherited; end; procedure TWABD_LinesObject.SetLines(NewLines: TStringList); begin FLines.Assign(NewLines); end; procedure TWABD_LinesObject.SetName(const Value: TComponentName); begin if (not (csLoading in ComponentState)) and ((FLines.Text='') or (FLines.Text=Name)) then FLines.Text := Value; inherited; end; // TWABD_SelLinesObject constructor TWABD_SelLinesObject.Create(AOwner: TComponent); begin inherited; FSelList:=TList.Create; FOldSelList:=TList.Create; FLines.OnChange:=OnChangeHandler; end; destructor TWABD_SelLinesObject.Destroy; begin FSelList.Free; FOldSelList.Free; inherited; end; procedure TWABD_SelLinesObject.Clear; begin ClearListSelected(FSelList); ClearListSelected(FOldSelList); Lines.Clear; end; procedure TWABD_SelLinesObject.OnChangeHandler(Sender:TObject); begin ClearListSelected(FSelList); if Assigned(FOnChange) then FOnChange(Sender); end; function TWABD_SelLinesObject.GetChanged:boolean; begin Result:=not EqualListSelected(FSelList,FOldSelList); end; function TWABD_SelLinesObject.GetText(Index:integer):string; var j:integer; s:string; begin if (Index>=0) and (Index<Lines.Count) then begin s:=Lines[Index]; j:=pos('=',s); if j<>0 then Result:=copy(s,1,j-1) else Result:=s; end else Result:=''; end; function TWABD_SelLinesObject.GetSelText:string; begin Result:=GetText(SelIndex); end; function TWABD_SelLinesObject.GetSelDesc:string; begin Result:=GetDesc(SelIndex); end; function TWABD_SelLinesObject.GetOldSelText:string; begin Result:=GetText(OldSelIndex); end; function TWABD_SelLinesObject.GetOldSelDesc:string; begin Result:=GetDesc(OldSelIndex); end; function TWABD_SelLinesObject.GetDesc(Index:integer):string; var j:integer; s:string; begin if (Index>=0) and (Index<Lines.Count) then begin s:=Lines[Index]; j:=pos('=',s); Result:=''; if j<>0 then Result:=copy(s,j+1,length(s)); if Result='' then Result:=s; end else Result:=''; end; procedure TWABD_SelLinesObject.SetSelIndex(i:integer); begin ClearListSelected(FSelList); SetListSelected(FSelList,i,true); end; function TWABD_SelLinesObject.GetSelIndex:integer; var i:integer; begin Result:=-1; for i:=0 to FSelList.Count-1 do if FSelList.Items[i]=Pointer(1) then begin Result:=i; break; end; end; procedure TWABD_SelLinesObject.SetOldSelIndex(i:integer); begin ClearListSelected(FSelList); SetListSelected(FSelList,i,true); end; function TWABD_SelLinesObject.GetOldSelIndex:integer; var i:integer; begin Result:=-1; for i:=0 to FOldSelList.Count-1 do if FOldSelList.Items[i]=Pointer(1) then begin Result:=i; break; end; end; procedure TWABD_SelLinesObject.SetSelText(s:string); var i,j:integer; v,v1,v2:string; begin for i:=0 to Lines.Count-1 do begin v:=Lines[i]; j:=pos('=',v); if j<>0 then begin v2:=copy(v,j+1,length(v)); v1:=copy(v,1,j-1); end else begin v2:=v; v1:=v; end; if (s=v1) or (s=v2) then begin SelIndex:=i; exit; end; end; SelIndex:=-1; end; procedure TWABD_SelLinesObject.SetListSelected(AList:TList; Index:integer; Value:boolean); begin if (Index<0) or (Index>=Lines.Count) then exit; if AList.Count<=Index then AList.Count:=Index+1; if Value then AList.Items[Index]:=pointer(1) else AList.Items[Index]:=pointer(0); end; function TWABD_SelLinesObject.GetListSelected(AList:TList; Index:integer):boolean; begin Result:=false; if (Index<0) or (Index>=Lines.Count) then exit; if AList.Count<=Index then exit; Result:=AList.Items[Index] = pointer(1); end; procedure TWABD_SelLinesObject.ClearListSelected(AList:TList); begin AList.Clear; end; procedure TWABD_SelLinesObject.CopyListSelected(Src,Dst:TList); var i:integer; begin Dst.Count:=Src.Count; for i:=0 to Src.Count-1 do Dst.Items[i]:=Src.Items[i]; end; function TWABD_SelLinesObject.EqualListSelected(AList1,AList2:TList):boolean; var i:integer; begin Result:=false; if AList1.Count<>AList2.Count then exit; Result:=true; for i:=0 to AList1.Count-1 do begin if AList1.Items[i]<>ALIst2.Items[i] then begin Result:=false; break; end; end; end; procedure TWABD_SelLinesObject.SetSelected(Index:integer; Value:boolean); begin SetListSelected(FSelList,Index,Value); end; function TWABD_SelLinesObject.GetSelected(Index:integer):boolean; begin Result:=GetListSelected(FSelList,Index); end; procedure TWABD_SelLinesObject.SetOldSelected(Index:integer; Value:boolean); begin SetListSelected(FOldSelList,Index,Value); end; function TWABD_SelLinesObject.GetOldSelected(Index:integer):boolean; begin Result:=GetListSelected(FOldSelList,Index); end; // TWABD_Memo constructor TWABD_Memo.Create(AOwner: TComponent); begin inherited; Rows := 5; Cols := 20; end; function TWABD_Memo.Object_To_HTML: string; var i : integer; s : string; begin s := Format('<TEXTAREA NAME=%s COLS=%d ROWS=%d', [Name, Cols, Rows]); s:=s+GenerateOptionHTML+GenerateEventScript; s:=s+' WRAP='; if WordWrap=taOff then s:=s+'OFF' else if WordWrap=taOut then s:=s+'VIRTUAL' else s:=s+'PHYSICAL'; if FTitle<>'' then s:=s+' TITLE="'+FTitle+'"'; s:=s+'>'+CR; for i := 0 to Lines.Count-1 do begin s := s + ASCII_To_HTML(Lines[i]) + CR; end; Result := s + '</TEXTAREA>'; end; function TWABD_Memo.Object_To_WML: string; var r : string; begin r := '<input type="text" name="' + Name + '" '; r := r + 'value="' + ASCII_To_HTML(FLines.Text) + '" '; r := r + 'size="20"'; if trim(FTitle)<>'' then r:=r+' title="'+FTitle+'"'; r := r + ' emptyok="true"'; r := r + '/>'; Result := r; end; function TWABD_Memo.Object_To_WML_Postfield: string; begin Result:='<postfield name="'+Name+'" value="$('+Name+')"/>'+CR; end; procedure TWABD_Memo.HTML_To_Object(FormVal: string); begin Lines.Text := FormVal; end; procedure TWABD_Memo.SetCols(NewCols: integer); begin FCols := NewCols; FWidth := FCols * PIXELS_PER_CHAR_X; Changed; end; procedure TWABD_Memo.SetRows(NewRows: integer); begin FRows := NewRows; FHeight := FRows * PIXELS_PER_CHAR_Y; Changed; end; function TWABD_Memo.Object_To_Control(AOwner: TWinControl): TControl; var nm : TMemo; begin nm := TMemo.Create(AOwner); nm.Parent := AOwner; nm.Name := Name; nm.Lines.Text := Lines.Text; Result := nm; end; // TWABD_Edit constructor TWABD_Edit.Create(AOwner: TComponent); begin inherited; Size := 10; FPass := False; FOldText := ''; FFormat := ''; FEmptyOK := true; end; destructor TWABD_Edit.Destroy; begin inherited; end; function TWABD_Edit.Object_To_HTML: string; var r : string; begin if not IsPassword then r := '<INPUT TYPE=TEXT ' else r := '<INPUT TYPE=PASSWORD '; r := r + 'NAME=' + Name + ' '; r := r + 'VALUE="' + ASCII_To_HTML(Text) + '" '; r := r + 'SIZE='+inttostr(Size); if FTitle<>'' then r:=r+' TITLE="'+FTitle+'"'; if FReadOnly and (not FDisabled) then begin if (Session<>nil) and (Session.Request<>nil) and (Session.Request.Browser=WABD_BrowserIExplorer) and (Session.Request.BrowserVersion>=4.0) then r := r + ' READONLY' else r := r + ' DISABLED'; end; r := r + GenerateOptionHTML+GenerateEventScript; if MaxLength > 0 then r := r + ' MAXLENGTH='+inttostr(MaxLength); r := r + '>'; Result := r; end; function TWABD_Edit.Object_To_WML: string; var r : string; begin if not IsPassword then r := '<input type="text" ' else r := '<input type="password" '; r := r + 'name="' + Name + '" '; r := r + 'value="' + ASCII_To_HTML(Text) + '" '; r := r + 'size="'+inttostr(Size)+'"'; if trim(FTitle)<>'' then r:=r+' title="'+FTitle+'"'; if MaxLength > 0 then r := r + ' maxlength="'+inttostr(MaxLength)+'"'; if EmptyOK then r := r + ' emptyok="true"'; if trim(FFormat)<>'' then r := r + ' format="'+FFormat+'"'; r := r + '/>'; Result := r; end; function TWABD_Edit.Object_To_WML_Postfield: string; begin Result:='<postfield name="'+Name+'" value="$('+Name+')"/>'+CR; end; procedure TWABD_Edit.HTML_To_Object(FormVal: string); begin Text := FormVal; end; procedure TWABD_Edit.SetName(const Value: TComponentName); begin if (not (csLoading in ComponentState)) and ((FText = '') or (FText=Name)) then Text := Value; inherited; end; procedure TWABD_Edit.SetText(s:string); begin FOldText:=Text; FText:=s; end; procedure TWABD_Edit.SetSize(NewSize: integer); begin FSize := NewSize; FWidth := FSize * PIXELS_PER_CHAR_X + 8; FHeight := PIXELS_PER_CHAR_Y + 6; Changed; end; function TWABD_Edit.Object_To_Control(AOwner: TWinControl): TControl; var ne : TEdit; begin ne := TEdit.Create(AOwner); ne.Parent := AOwner; ne.Name := Name; // Just in case Text is blank, so it doesn't get reset to the Name in SetName ne.Text := Text; if IsPassword then ne.PasswordChar := '*'; Result := ne; end; // TWABD_UploadFile constructor TWABD_UploadFile.Create(AOwner: TComponent); begin inherited; Size:=10; FAcceptMimeTypes:=TStringList.Create; end; destructor TWABD_UploadFile.Destroy; begin FAcceptMimeTypes.free; inherited; end; procedure TWABD_UploadFile.SetSize(NewSize: integer); begin FSize := NewSize; FWidth := FSize * PIXELS_PER_CHAR_X + 8; FHeight := PIXELS_PER_CHAR_Y + 6; Changed; end; function TWABD_UploadFile.Object_To_HTML: string; var r : string; begin r := '<INPUT TYPE=FILE '; r := r + 'NAME=' + Name + ' '; r := r + 'VALUE="' + ASCII_To_HTML(ClientFileName) + '" '; r := r + 'ACCEPT="'+FAcceptMimeTypes.Text+'" '; r := r + 'SIZE='+inttostr(Size); if FReadOnly and (not FDisabled) then begin if (Session<>nil) and (Session.Request<>nil) and (Session.Request.Browser=WABD_BrowserIExplorer) and (Session.Request.BrowserVersion>=4.0) then r := r + ' READONLY' else r := r + ' DISABLED'; end; if FTitle<>'' then r:=r+' TITLE="'+FTitle+'"'; r := r + GenerateOptionHTML + GenerateEventScript; r := r + '>'; // Set flag on form that encoding type should be changed. GetParentForm.FUploadFileOnForm:=true; Result := r; end; procedure TWABD_UploadFile.HTML_To_Object(FormVal: string); var lst:TStringList; begin // Set parameters. lst:=TStringList.Create; try WABD_SplitString(PChar(FormVal),';',lst); if lst.Count<=0 then exit; FLocalFileName:=lst.Strings[0]; FClientFileName:=lst.Values['filename']; FMimeType:=lst.Values['Mime']; finally lst.Free; end; end; function TWABD_UploadFile.Object_To_Control(AOwner: TWinControl): TControl; var ne : TEdit; begin ne := TEdit.Create(AOwner); ne.Parent := AOwner; ne.Name := Name; // Just in case Text is blank, so it doesn't get reset to the Name in SetName // ne.Text := Value; Result := ne; end; // TWABD_ComboBox constructor TWABD_ComboBox.Create(AOwner: TComponent); begin inherited; FWidth := PIXELS_PER_CHAR_X * 15; FHeight := PIXELS_PER_CHAR_Y + 6; end; destructor TWABD_ComboBox.Destroy; begin inherited; end; function TWABD_ComboBox.Object_To_HTML: string; var i,j : integer; s,s1 : string; begin s:='<SELECT NAME='+Name+' SIZE=1'; s:=s+GenerateOptionHTML+GenerateEventScript; if FTitle<>'' then s:=s+' TITLE="'+FTitle+'"'; s:=s+'>'+CR; for i := 0 to Lines.Count-1 do begin s := s + '<OPTION'; if Selected[i] then s := s+' SELECTED'; s1:=Lines[i]; j:=pos('=',s1); if j<>0 then s:=s+' VALUE="'+copy(s1,1,j-1)+'">' + ASCII_To_HTML(copy(s1,j+1,length(s1))) + CR else s:=s+'>' + ASCII_To_HTML(s1) + CR; end; if Lines.Count = 0 then s:=s + '<OPTION> ' + CR; // otherwise there will be no ComboBox! Result := s + '</SELECT>'+CR; if (Button<>nil) and (AutoButton) then Result:=Result+Button.Object_To_HTML; end; function TWABD_ComboBox.Object_To_WML: string; var i,j : integer; s,s1 : string; opt : string; begin s:='<select name="'+Name+'"'; if FTitle<>'' then s:=s+' title="'+FTitle+'"'; s:=s+' ivalue="'+inttostr(SelIndex+1)+'"'; opt:=''; for i := 0 to Lines.Count-1 do begin s1:=Lines[i]; opt:=opt + '<option'; j:=pos('=',s1); if j<>0 then opt:=opt+' value="'+copy(s1,1,j-1)+'">' + ASCII_To_HTML(copy(s1,j+1,length(s1))) else opt:=opt+'>'+ASCII_To_HTML(s1); opt:=opt+'</option>'+CR; end; s:=s+'>'+CR +opt +'</select>'; Result:=s; end; function TWABD_ComboBox.Object_To_WML_Postfield: string; begin Result:='<postfield name="'+Name+'" value="$('+Name+')"/>'+CR; end; procedure TWABD_ComboBox.HTML_To_Object(FormVal: string); var i,j:integer; v,v1,v2:string; begin for i:=0 to Lines.Count-1 do begin v:=Lines[i]; j:=pos('=',v); if j<>0 then begin v2:=copy(v,j+1,length(v)); v1:=copy(v,1,j-1); end else begin v2:=v; v1:=v; end; if (FormVal=v1) or (FormVal=v2) then begin Selected[i]:=true; exit; end; end; end; function TWABD_ComboBox.Object_To_Control(AOwner: TWinControl): TControl; var ncb : TComboBox; begin ncb := TComboBox.Create(AOwner); ncb.Parent := AOwner; ncb.Name := Name; ncb.Items.Text := Lines.Text; ncb.ItemIndex := SelIndex; Result := ncb; end; // TWABD_Button constructor TWABD_Button.Create(AOwner:TComponent); begin inherited; end; destructor TWABD_Button.Destroy; begin inherited; end; function TWABD_Button.Object_To_HTML: string; var s,s1:string; begin // Depends on if containing Javascript or not. s1:=GenerateEventScript; s:='<INPUT TYPE="SUBMIT" NAME='; if length(s1)>0 then s:=s+Name else s:=s+WABD_BUTTON_STR; s:=s+' VALUE="'+Caption+'"'+GenerateOptionHTML+s1; if FTitle<>'' then s:=s+' TITLE="'+FTitle+'"'; s:=s+'>'; Result:=s; end; function TWABD_Button.Object_To_WML: string; var f:TWABD_Form; s,s1:string; begin f:=GetParentForm; if f<>nil then begin // s1:=URL_To_HTML(format('%s?%s='+WABD_SES_ID_STR_FORMAT+'&%s='+inttostr(WABD_EVENT_USERCLICK)+':%s:&%s=%d', // [DllName,WABD_SES_ID_STR,SessionID,f.Name,WABD_EVENT_ID_STR,Name,WABD_STAMP_STR,Random(100000)])); s1:=DllName; s:='<go href="'+s1+'" method="post">'+CR+ format('<postfield name="%s" value="'+WABD_SES_ID_STR_FORMAT+'"/>',[WABD_SES_ID_STR,SessionID,f.Name])+CR+ format('<postfield name="%s" value="%d:%s:"/>',[WABD_EVENT_ID_STR,WABD_EVENT_USERCLICK,Name])+CR+ format('<postfield name="%s" value="%d"/>',[WABD_STAMP_STR,Random(999999)])+CR+ f.FormSections_To_WML_Postfield+ '</go>'+CR; end else s:=''; Result:='<do type="accept" label="'+Caption+'" name="'+Name+'">'+CR+ s+ '</do>'; end; procedure TWABD_Button.HTML_To_Object(FormVal: string); begin // Nothing. end; procedure TWABD_Button.SetName(const Value: TComponentName); begin if (not (csLoading in ComponentState)) and ((FCaption='') or (FCaption=Name)) then Caption := Value; inherited; end; procedure TWABD_Button.SetCaption(NewCaption: string); begin FCaption := NewCaption; FWidth := PIXELS_PER_CHAR_X * Length(FCaption) + 5; FHeight := PIXELS_PER_CHAR_Y + 10; Changed; end; function TWABD_Button.Object_To_Control(AOwner: TWinControl): TControl; var nb : TButton; begin nb := TButton.Create(AOwner); nb.Name := name; nb.Caption := Caption; nb.Default := Default; Result := nb; end; // TWABD_ListBox constructor TWABD_ListBox.Create(AOwner: TComponent); begin inherited; Size := 6; FMultiple:=false; end; destructor TWABD_ListBox.Destroy; begin inherited; end; function TWABD_ListBox.Object_To_HTML: string; var i,j : integer; s,s1 : string; begin s:='<SELECT NAME='+Name+' SIZE='+inttostr(Size); if FMultiple then s:=s+' MULTIPLE'; s:=s+GenerateOptionHTML+GenerateEventScript; if FTitle<>'' then s:=s+' TITLE="'+FTitle+'"'; s:=s+'>'+CR; for i := 0 to Lines.Count-1 do begin s1:=Lines[i]; s := s + '<OPTION'; if Selected[i] then s := s+' SELECTED'; j:=pos('=',s1); if j<>0 then s:=s+' VALUE='+copy(s1,1,j-1)+'>' + ASCII_To_HTML(copy(s1,j+1,length(s1))) + CR else s:=s+'>'+ASCII_To_HTML(s1) + CR; end; Result := s + '</SELECT>'+CR; if Button<>nil then Result:=Result+Button.Object_To_HTML; end; function TWABD_ListBox.Object_To_WML: string; var i,j : integer; s,s1,s2,s3 : string; opt : string; sel : string; begin s:='<select name="'+Name+'" iname="i'+Name+'"'; if FTitle<>'' then s:=s+' title="'+FTitle+'"'; opt:=''; sel:=''; for i := 0 to Lines.Count-1 do begin s1:=Lines[i]; j:=pos('=',s1); if j<>0 then begin s2:=copy(s1,1,j-1); s3:=copy(s1,j+1,length(s1)); end else begin s2:=s1; s3:=s1; end; opt:=opt+'<option value="'+s2+'">' + ASCII_To_HTML(s3)+'</option>'+CR; if Selected[i] then begin if sel<>'' then sel:=sel+';'; sel:=sel+inttostr(i+1); end; end; s:=s+' ivalue="'+sel+'"'; if FMultiple then s:=s+' multiple="true"'; s:=s+'>'+CR +opt +'</select>'; Result:=s; end; function TWABD_ListBox.Object_To_WML_Postfield: string; begin Result:='<postfield name="'+Name+'" value="$('+Name+')"/>'+CR; end; procedure TWABD_ListBox.HTML_To_Object(FormVal: string); var i,j,k:integer; v,v1,v2:string; lst:TStringList; begin lst:=TStringList.Create; try // Support multiple selections in one name=value pair. WABD_SplitString(PChar(FormVal),';',lst); for k:=0 to lst.Count-1 do begin FormVal:=lst.Strings[k]; for i:=0 to Lines.Count-1 do begin v:=Lines[i]; j:=pos('=',v); if j<>0 then begin v2:=copy(v,j+1,length(v)); v1:=copy(v,1,j-1); end else begin v2:=v; v1:=v; end; if (FormVal=v1) or (FormVal=v2) then Selected[i]:=true; end; end; finally lst.free; end; end; procedure TWABD_ListBox.SetSize(NewSize: integer); begin FSize := NewSize; FWidth := PIXELS_PER_CHAR_X * 15; FHeight := PIXELS_PER_CHAR_Y * FSize + 8; Changed; end; function TWABD_ListBox.Object_To_Control(AOwner: TWinControl): TControl; var nlb : TListBox; begin nlb := TListBox.Create(AOwner); nlb.Parent := AOwner; nlb.Name := Name; nlb.Items.Text := Lines.Text; nlb.ItemIndex := SelIndex; Result := nlb; end; // TWABD_RadioButton constructor TWABD_RadioButton.Create(AOwner: TComponent); begin inherited; FGroup:=0; end; destructor TWABD_RadioButton.Destroy; begin inherited; end; function TWABD_RadioButton.Object_To_HTML: string; var ck : string; s : string; begin if Checked then ck := 'CHECKED ' else ck := ''; s := Format('<INPUT TYPE=RADIO NAME=%s_%d VALUE=%s %s',[WABD_RADIO_STR, Group, Name, ck]); s:=s+GenerateOptionHTML + GenerateEventScript; if FTitle<>'' then s:=s+' TITLE="'+FTitle+'"'; s:=s+'>'+ASCII_To_HTML(Caption); Result:=s; end; procedure TWABD_RadioButton.HTML_To_Object(FormVal: string); begin Checked := (FormVal<>''); end; procedure TWABD_RadioButton.SetName(const Value: TComponentName); begin if (not (csLoading in ComponentState)) and ((FCaption='') or (FCaption=Name)) then Caption := Value; inherited; end; procedure TWABD_RadioButton.SetCaption(NewCaption: string); begin FCaption := NewCaption; FWidth := PIXELS_PER_CHAR_X * Length(FCaption) + 15; FHeight := PIXELS_PER_CHAR_Y + 4; Changed; end; procedure TWABD_RadioButton.SetChecked(value:boolean); begin // If setting check to true, remove checked from other radiobuttons in group. if (not (csLoading in ComponentState)) and value and assigned(parent) then parent.ForEachChild(ResetCheckedProc, pointer(FGroup)); FCheck:=value; end; procedure TWABD_RadioButton.ResetCheckedProc(Child: TWABD_Object; var Stop: boolean; UserData: pointer); begin if Child is TWABD_RadioButton then begin if integer(UserData) = (Child as TWABD_RadioButton).Group then (Child as TWABD_RadioButton).FCheck:=false; end; end; function TWABD_RadioButton.Object_To_Control(AOwner: TWinControl): TControl; var nrb : TRadioButton; begin nrb := TRadioButton.Create(AOwner); nrb.Parent := AOwner; nrb.Name := Name; nrb.Caption := Caption; nrb.Checked := Checked; Result := nrb; end; // TWABD_CheckBox constructor TWABD_CheckBox.Create(AOwner:TComponent); begin inherited; end; destructor TWABD_CheckBox.Destroy; begin inherited; end; function TWABD_CheckBox.Object_To_HTML: string; var ck : string; s : string; begin if Checked then ck := 'CHECKED ' else ck := ''; s := '<INPUT TYPE=CHECKBOX NAME='+Name+' '+ck+' VALUE='+Name; s:=s+GenerateOptionHTML + GenerateEventScript; if FTitle<>'' then s:=s+' TITLE="'+FTitle+'"'; s:=s+'>'+ASCII_To_HTML(Caption); Result:=s; end; function TWABD_CheckBox.Object_To_WML: string; var s : string; ck : string; begin if Checked then ck:='1' else ck:='2'; s := Caption+'<select name="'+Name+'" iname="i'+Name+'" ivalue="'+ck+'"'; if FTitle<>'' then s:=s+' title="'+FTitle+'"'; s:=s+'>'+CR; s:=s+'<option value="'+Name+'">X</option>'+CR+ '<option value="_N">-</option>'+CR; s:=s+'</select>'; Result:=s; end; function TWABD_CheckBox.Object_To_WML_Postfield: string; begin Result:='<postfield name="'+Name+'" value="$('+Name+')"/>'+CR; end; procedure TWABD_CheckBox.HTML_To_Object(FormVal: string); begin if FormVal=Name then Checked := true; end; procedure TWABD_CheckBox.SetName(const Value: TComponentName); begin if (not (csLoading in ComponentState)) and (FCaption = '') then Caption := Value; inherited; end; procedure TWABD_CheckBox.SetChecked(Check:boolean); begin FCheck:=Check; end; procedure TWABD_CheckBox.SetCaption(NewCaption: string); begin FCaption := NewCaption; FWidth := PIXELS_PER_CHAR_X * Length(FCaption) + 15; FHeight := PIXELS_PER_CHAR_Y + 6; Changed; end; function TWABD_CheckBox.Object_To_Control(AOwner: TWinControl): TControl; var nck : TCheckBox; begin nck := TCheckBox.Create(AOwner); nck.Parent := AOwner; nck.Name := Name; nck.Caption := Caption; nck.Checked := Checked; Result := nck; end; initialization Randomize; end.