You can subscribe to this list here.
2003 |
Jan
(69) |
Feb
(122) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
|
Feb
|
Mar
(56) |
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(237) |
Jul
|
Aug
|
Sep
(1) |
Oct
(14) |
Nov
(72) |
Dec
|
2007 |
Jan
(2) |
Feb
(37) |
Mar
(5) |
Apr
|
May
(2) |
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Andrey C. <sku...@us...> - 2006-06-02 14:37:44
|
Update of /cvsroot/eas-dev/ocmng/components/equipment In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv13770/equipment Log Message: Directory /cvsroot/eas-dev/ocmng/components/equipment added to the repository |
From: Andrey C. <sku...@us...> - 2006-06-02 14:37:44
|
Update of /cvsroot/eas-dev/ocmng/components/ref2 In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv13770/ref2 Log Message: Directory /cvsroot/eas-dev/ocmng/components/ref2 added to the repository |
From: Andrey C. <sku...@us...> - 2006-06-02 14:37:44
|
Update of /cvsroot/eas-dev/ocmng/components/ocmng In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv13770/ocmng Log Message: Directory /cvsroot/eas-dev/ocmng/components/ocmng added to the repository |
From: Andrey C. <sku...@us...> - 2006-06-02 14:37:44
|
Update of /cvsroot/eas-dev/ocmng/components/acc-pdoc In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv13770/acc-pdoc Log Message: Directory /cvsroot/eas-dev/ocmng/components/acc-pdoc added to the repository |
From: Andrey C. <sku...@us...> - 2006-06-02 14:37:44
|
Update of /cvsroot/eas-dev/ocmng/components/CORE In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv13770/CORE Log Message: Directory /cvsroot/eas-dev/ocmng/components/CORE added to the repository |
From: Andrey C. <sku...@us...> - 2006-06-02 14:36:48
|
Update of /cvsroot/eas-dev/ocmng/components In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv13333/components Log Message: Directory /cvsroot/eas-dev/ocmng/components added to the repository |
From: Andrey C. <sku...@us...> - 2006-06-02 14:32:50
|
Update of /cvsroot/eas-dev/eas In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv11504 Added Files: AUTHORS COPYING ChangeLog INSTALL Makefile README TODO VERSION configure mkinstalldirs Log Message: Add files --- NEW FILE: INSTALL --- STEP 1: Obtain sources ====================== 1. Go to http://eas.lrn.ru/index.php?module=download and download latest versions: - eas - clip-prg - ocmng 2. Unpack downloaded packages 3. Check libraries: - GTK+ (both libgtk+ and libgtk+-devel) - Expat (both libexpat and libexpat-devel) Note: on your system package may have another (but similar) names. STEP 2: Install CLIP ==================== 1. Prepare environment variable: export CLIPROOT=/usr/local/clip export PATH=$PATH:$CLIPROOT/bin On system with Unicode locale: export CLIP_HOSTCS=KOI8-R export CLIP_CLIENTCS=UTF-8 Note: there is best solution add this commands to /etc/profile or ~/.bash_profile 2. Got to unpacked clip-prg directory and run: make system Note: if you cannot install system-wide, set CLIPROOT to directory in your home directory and build CLIP by 'make local'. 3. Check if exist libraries in $CLIPROOT/lib: libclip-codb.so libclip-gtk.so libclip-ui.so libclip-xml.so If any library is absent, check error messages and rebuild CLIP 4. Set path to CLIP libraries: echo "$CLIPROOT/lib" >> /etc/ld.so.conf /sbin/ldconfig STEP 3: Install E/AS ==================== 1. Got to unpacked eas directory and run: ./configure && make && make install NOTE: It's strongly recommended to build E/AS under root privileges and check system configuration after E/AS install (new user 'easserver' will be created, install startup scripts and PAM modules) 2. Possible, you want to run E/AS server on system startup: chkconfig easd on Note: you can disable 'easd' on system startup by command: chkconfig easd off STEP 4: Install ocmng and components ==================================== 1. Set path to created CODB databases: export CODBROOT=/var/db/eas Note: there is best solution add this command to /etc/profile or ~/.bash_profile Note: if you cannot install system-wide, set CODBROOT to directory in your home directory. 2. Go to unpacked ocmng directory and run command: make && make install 3. Install components: ocmng install components/ALL.xmo ocmng install components/ocmng/ALL.xmo NOTES ===== 1. CLIP doesn't support Unicode correctly. For successful building and usage CLIP program (include E/AS) set locale to 8-bit encoding (like LANG=ru_RU.KOI8-R). Set locale in terminal: export LANG=ru_RU.KOI8-R or put this locale in file /etc/sysconfig/i18n. 2. CLIP perfectly works on any terminal type (linux, rxvt) except 'xterm'. Set terminal type (if 'echo $TERM' returns 'xterm') by command: export TERM=linux |
From: Andrey C. <sku...@us...> - 2006-06-02 14:32:49
|
Update of /cvsroot/eas-dev/eas/libcodb_query In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv11504/libcodb_query Added Files: Makefile codb.prg command.prg formatter.prg Log Message: Add files --- NEW FILE: Makefile --- # This is a part of E/AS project # # Copyright (C) 2003-2005 by E/AS Software Foundation # Author: Andrey Cherepanov <sk...@ea...> ifndef CLIPROOT CLIPROOT=$(shell cd ../../../; pwd)/cliproot endif include $(CLIPROOT)/include/Makefile.inc CLIPINCLUDE = -I$(CLIPROOT)/include CLIP = $(CLIPROOT)/bin/clip CLIPLIBS = -L$(CLIPROOT)/lib -lclip-codb CODBLIBS = -lcodb_query .SUFFIXES: .prg .o .po # Here you can define appropriate compile settings #C_FLAGS=-Wall -g -I. $(CLIPINCLUDE) #CC=gcc TARGET = libcodb_query$(DLLSUFF) RTARGET = libcodb_query$(DLLREALSUFF) BIN_TARGET = codb OBJS = command.o formatter.o BIN_OBJS = codb.o .PHONY: all clean uninstall distclean all: $(TARGET) $(TARGET): $(OBJS) $(CLIPROOT)/bin/clip_makeslib $(TARGET) $(OBJS) $(BIN_TARGET): $(BIN_OBJS) $(CLIP) $(CLIPFLAGS) -eslM $(CLIPINCLUDE) -o $(BIN_TARGET) $(BIN_OBJS) $(CLIPLIBS) $(CODBLIBS) clean: rm -f $(OBJS) $(BIN_OBJS) $(TARGET) $(BIN_TARGET) *.bak *.nm *.ex *.ppo *.dll.a *.log *.dll *.so install: all install_lib $(BIN_TARGET) mkdir -p $(DESTDIR)$(CLIPROOT)/bin $(CLIPROOT)/bin/clip_cp $(BIN_TARGET) $(DESTDIR)$(CLIPROOT)/bin install_lib: mkdir -p $(DESTDIR)$(CLIPROOT)/lib $(CLIPROOT)/bin/clip_cp $(TARGET) $(DESTDIR)$(CLIPROOT)/lib $(CLIPROOT)/bin/clip_cp $(RTARGET) $(DESTDIR)$(CLIPROOT)/lib uninstall: rm -f $(CLIPROOT)/lib/$(TARGET) $(CLIPROOT)/lib/$(RTARGET) $(CLIPROOT)/bin/$(BIN_TARGET) distclean: clean dist: distclean .prg.o: $(CLIP) $(CLIPINCLUDE) $< commit: _cvs commit update: _cvs update -dP ucommit: _cvs update -dP && _cvs commit shell: sh --- NEW FILE: codb.prg --- /*-------------------------------------------------------------------------*/ /* This is part of console client for CODB database */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #define FILE_BUFFER 4096 static clientVersion := "0.1" static db, dbname:="", fmt /* TODO: - connection string for connect via COBrA server (-u, -p, -s) - exit function for correct connection shutdown - 'set <param>=<mode>' command needed */ /* Main function */ function main(p1) local e, i, h, s:='', ss, params:=array(0), ret set cancel off // Read from pipe h := fopen("-|") while .T. ss := freadstr(h,256) s := s + ss if empty(ss) exit endif end fclose(h) fmt := CODB_Formatter() for i:=1 to pcount() if ascan({'-h','--help','-?'}, param(i)) > 0 printUsage(1) // help return 0 elseif param(i)=='--version' printUsage(2) // version return 0 elseif param(i) == '--hide-titles' fmt:options:hide_titles := .T. elseif left(param(i),8) == "--delim=" fmt:options:delim := substr(param(i),9) elseif left(param(i),1) == '-' .and. param(i) != '-c' ?? "Unknown parameter: "+param(i),chr(10) else aadd(params, param(i)) endif next for i:=1 to len(params) if params[i] == '-c' .and. i < len(params) s := params[i+1] if right(rtrim(s),1) != ';' s += ';' endif adel(params,i) adel(params,i) asize(params,len(params)-2) endif next // TODO: connect if needed db := codb_connect() e := codb_get_error( db ) if e != NIL ?? "ERROR codb_connect(): " + e + chr(10) return 1 endif //?? params, s,chr(10) if len(params) > 0 // Database name // possible use in form DB:DEP params[len(params)] := strtran(params[len(params)], ":", " ") //?? "USE",params[len(params)],";&\n" ret := codb_execute( db, "use "+params[len(params)]+";" ) // Database name change e := codb_get_error( ret ) if e == NIL dbname := codb_get_answer( ret ) else ?? "ERROR: " + e + "&\n" return 1 endif endif if empty(s) printUsage(0) consoleMode() else executeCommand( s ) endif // TODO: correct disconnect from database codb_close( db ) return 0 /* Print usage information */ static function printUsage(mode) // TODO: i18n for printUsage() if mode == 0 // console mode ?? "codb Ver. " + clientVersion + " Console client for CODB database.&\n&\n" ?? "Type 'help' for list of commands or 'quit' for exit&\n&\n" elseif mode == 2 // version ?? clientVersion,"&\n" else // help ?? "codb Ver. " + clientVersion + " Console client for CODB database.&\n" ?? "Copyright (C) 2005 E/AS Software Foundation&\n" ?? "This software comes with ABSOLUTELY NO WARRANTY. This is free software,&\n" ?? "and you are welcome to modify and redistribute it under the GPL license&\n" ?? "&\n" // TODO: full list of command options ?? "Usage: codb [OPTIONS] [dbname[:depository]]&\n&\n" ?? "Options:&\n" ?? " -?, -h, --help Display this help and exit.&\n" ?? " --version Display program version and exit.&\n" ?? " -c 'command' Run command and exit.&\n" ?? " --hide-titles Suppress column names.&\n" ?? " --delim='DELIM' Set columns delimiter.&\n" endif return /* Console mode. Using readline library */ static function consoleMode() local comm:='', ret, prompt, buffer:='', cont:=.F., oErr // TODO: set key '\d' for exit prompt := dbname + "> " oErr := ErrorBlock({|e| break(e) }) while .T. begin sequence ?? prompt ACCEPT TO comm // TODO: Ctrl-C handle! if .not. cont if alltrim(upper(comm)) == 'QUIT' exit elseif upper(comm) == 'HELP' ret := codb_execute( db, comm+";" ) ?? fmt:show( ret ) // TODO: show console specific commands loop endif endif ret := executeCommand(buffer+comm) if empty(ret) prompt := dbname + "> " cont := .F. buffer := '' else // Uncomplete command prompt += iif(dbname!='',replicate('-',len(dbname)),'-') + "> " cont := .T. buffer := ret + ' ' endif recover using oErr ?? "INTERNAL ERROR:", oErr:description+' ('+oErr:fileName+')', chr(10) end sequence enddo return /* Execute command with check delimiters */ static function executeCommand(comm) local i:=0, pos, string:=.F., buffer:='', ret:=NIL, is_filename:=.F. local j, ampos, fileNames:=array(0), files, fH, s, ss local fBuf:=space(FILE_BUFFER), rTotal // ?? 'EXECUTE:',comm,chr(10) while len(comm) > 0 .and. i<=len(comm) i := i + 1 if comm[i]=="'" .and. (i==1 .or. comm[i-1]!='&\\') string := .not. string elseif .not. string .and. .not. is_filename .and. comm[i]=='@' ampos := i is_filename := .T. elseif .not. string .and. is_filename .and. comm[i]=='@' aadd( fileNames, substr(comm, ampos+1, i-ampos-1) ) is_filename := .F. elseif .not. string .and. comm[i]==';' // command end // ?? "EXEC:",left(comm,i-1),chr(10) // Process file names in command files := array(0) for j=1 to len(fileNames) fH := fopen(fileNames[j], 0) s := '' if ferror() == 0 rTotal := 0 while .T. ss := fread(fH, @fBuf, FILE_BUFFER) s := s + left(fBuf, ss) rTotal += ss if ss == 0 exit endif end fclose(fH) //?? "Append file '"+fileNames[j]+"':",rTotal,len(s),chr(10) aadd( files, { fileNames[j], s } ) else ?? "Error opening '"+fileNames[j]+"'.&\n" endif next fileNames := array(0) //?? files,chr(10) ret := codb_execute( db, left(comm,i-1), NIL, files ) ?? fmt:show( ret ) // Database name change if lower(left(comm, 4)) == 'use ' .and. .not. "ERROR" $ ret dbname := ret:answer endif if i<len(comm) comm := substr(comm,i+1) i := 0 else return '' endif endif enddo return comm --- NEW FILE: command.prg --- /*-------------------------------------------------------------------------*/ /* This is part of console client for CODB database */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #include <codb_dbf.ch> /** Class for database manipulation in console mode */ /* TODO: - BUG: cannot create EXTENT normally (need close depositories before creation) - WHERE in SELECT statement: translate logical operation and quotes - export/import [...1243 lines suppressed...] endif //?? "got", o, chr(10) for j:=1 to len(attrs) field := attrs[j] if upper(field) $ o value := o[upper(field)] else value := NIL endif row[j] := value next aadd( res:data, row ) next next recover using oErr return "Error select: "+errorMessage(oErr) end sequence return NIL --- NEW FILE: formatter.prg --- /*-------------------------------------------------------------------------*/ /* This is part of console client for CODB database */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ /** Class for CODB_Result object formatted for show in console */ /* TODO: - --format (text, csv, xml) - use only codb_* functions, not class hack */ #define DEF_DELIMITER ' ' function CODB_Formatter() local obj obj := map() obj:className := "CODB_Formatter" obj:options := map() obj:options:hide_titles := .F. obj:options:delim := DEF_DELIMITER _recover_CODBFORMATTER(obj) return obj function _recover_CODBFORMATTER(obj) obj:show := @c_show() return /* Show formatted output */ static function c_show(self, res) local e, d, s:="", c_len, k, j, total:=0, val, s_val, s_str if valtype(res) != "O" .or. .not. "ANSWER" $ res .or. .not. "DATA" $ res return "ERROR: bad returned object.&\n" endif // Check error e := codb_get_error(res) if e != NIL return "ERROR: " + e + chr(10) endif // Check empty data d := codb_get_result( res ) if d == NIL .or. (valtype(d)=="A" .and. len(d)==0) return "" endif // Generate value length for each columns of data c_len := array(len(d[1])) afill(c_len, 0) for k:=1 to len(d) for j:=1 to len(d[k]) if len(d[k][j]) > c_len[j] c_len[j] := len(d[k][j]) endif next next // Print fields if exists if .not. self:options:hide_titles .and. "FIELDS" $ res .and. valtype(res:fields)=="A" .and. len(res:fields)==len(c_len) for k:=1 to len(res:fields) c_len[k] := iif(c_len[k]<=len(res:fields[k]),len(res:fields[k]),c_len[k]) s += res:fields[k] + space(c_len[k]-len(res:fields[k])) + self:options:delim total += c_len[k] + len(self:options:delim) next s = left(s,len(s)-len(self:options:delim)) + chr(10) + replicate('-', total-len(self:options:delim)) + chr(10) endif // Output data for k:=1 to len(d) s_str := "" for j:=1 to len(d[k]) val := d[k][j] s_val := f_val2str(val) if c_len[j] > len(s_val) s_val := s_val + space(c_len[j]-len(s_val)) endif s_str += s_val + self:options:delim next s += left(s_str,len(s_str)-len(self:options:delim)) + chr(10) next return s /* f_val2str() - convert value to string */ static function f_val2str(val) local i, s_val switch valtype(val) case 'U' s_val := "<NIL>" case 'B' s_val := "<NIL>" case 'C' s_val := val case 'N' s_val := alltrim(str(val)) case 'L' s_val := iif(val,'.T.','.F.') case 'D' s_val := dtoc(val) case 'A' s_val := "{" for i:=1 to len(val) s_val += f_val2str(val[i])+"," next s_val := iif(len(val)>0,left(s_val,len(s_val)-1),s_val)+"}" case 'O' s_val := '<OBJECT>' otherwise s_val := '<UNKNOWN ('+valtype(val)+')='+varToString(val)+">" endswitch return s_val |
From: Andrey C. <sku...@us...> - 2006-06-02 14:32:48
|
Update of /cvsroot/eas-dev/eas/libeas In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv11504/libeas Added Files: Makefile componentmanager.prg config.prg connection.prg dbmanager.prg execmanager.prg functions.prg messagemanager.prg protocol_raw.prg session.prg transportmanager.prg uimanager.prg Log Message: Add files --- NEW FILE: Makefile --- # This is a part of E/AS library # # Copyright (C) 2005 by E/AS Software Foundation # Author: Andrey Cherepanov <sk...@ea...> include $(CLIPROOT)/include/Makefile.inc CLIPINCLUDE = -I$(CLIPROOT)/include CLIP = $(CLIPROOT)/bin/clip .SUFFIXES: .prg .o .po # Here you can define appropriate compile settings #C_FLAGS=-Wall -g -I. $(CLIPINCLUDE) #CC=gcc TARGET = libeas$(DLLSUFF) RTARGET = libeas$(DLLREALSUFF) OBJS = componentmanager.o config.o connection.o dbmanager.o execmanager.o \ messagemanager.o protocol_raw.o session.o transportmanager.o \ uimanager.o functions.o .PHONY: all clean uninstall distclean all: $(TARGET) $(TARGET): $(OBJS) $(CLIPROOT)/bin/clip_makeslib $(TARGET) $(OBJS) clean: rm -f $(OBJS) $(TARGET) *.bak *.nm *.ex *.ppo *.dll.a *.log *.dll *.so install: all mkdir -p $(DESTDIR)$(CLIPROOT)/lib $(CLIPROOT)/bin/clip_cp $(TARGET) $(DESTDIR)$(CLIPROOT)/lib $(CLIPROOT)/bin/clip_cp $(RTARGET) $(DESTDIR)$(CLIPROOT)/lib /sbin/ldconfig -n $(DESTDIR)$(CLIPROOT)/lib uninstall: rm -rf $(CLIPROOT)/lib/$(TARGET) $(CLIPROOT)/lib/$(RTARGET) distclean: clean dist: distclean .prg.o: clip-ui.ch $(CLIP) $(CLIPINCLUDE) $< commit: _cvs commit update: _cvs update -dP ucommit: _cvs update -dP && _cvs commit shell: sh --- NEW FILE: componentmanager.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of library eas */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ /** EASComponentManager - component manager */ #define OCMNG_REPOSITORY 'ETC0101' #define OCMNG_COMMANDS_CLASS 'mng_command' #define COMPONENT_SECTION 'COMPONENT_MANAGER' function EASComponentManager( params ) local obj := map() obj:className := "EASComponentManager" obj:lastError := NIL obj:repository := '' obj:dbPath := '' _recover_EASCOMPONENTMANAGER(obj) setCommand(, 'sys.components', 'list', {|p| obj:list(p) } ) setCommand(, 'sys.components', 'commands', {|p| obj:commands(p) } ) setCommand(, 'sys.components', 'get', {|p| obj:get(p) } ) return obj function _recover_EASCOMPONENTMANAGER(obj) obj:open := @c_open() obj:lookup := @c_lookup() obj:execute := @c_execute() obj:list := @c_list() obj:commands := @c_commands() obj:get := @c_get() return obj /** Open tables */ static function c_open( self, params ) // TODO local cfg eDebug(15, "Component manager (CM): open") // Check config file cfg := EASGetConfig() // Set default properties from config if COMPONENT_SECTION $ cfg:sections() self:repository := cfg:getValue(COMPONENT_SECTION, 'REPOSITORY') self:dbPath := cfg:getValue(COMPONENT_SECTION, 'DBPATH') endif return NIL /** Lookup specified component name */ static function c_lookup( self, params ) local q:=map(), component, method, a, i, cmds component := params:receiver method := params:command // eDebug(5, "COMPONENT LOOKUP","DB" $ params:args, params:args) if .not. "ARGS" $ params .or. valtype(params:args)!="O" return NIL endif eDebug(15, "CM lookup:", component, method) // Query database q:db := OCMNG_REPOSITORY q:query := 'select id from '+OCMNG_COMMANDS_CLASS+' where component=="'+component+'" .and. name=="'+method+'";' cmds := sendMessage(,'sys.db', 'execute', q ) eDebug(17, "DB returns:", cmds) // TODO: ACL check if len(cmds) > 0 eDebug(10, "CM found", cmds[1][1]) return cmds[1][1] else self:lastError := "Method '"+method+"' of component '"+component+"' was not found" return NIL endif return NIL /** Execute component command found by ::lookup() */ static function c_execute( self, params ) local oErr, component, method, id, q:=map(), obj local fName, f, fBlock, p, ret:=NIL, i, codeFile:=NIL component := params:receiver method := params:command if .not. "ARGS" $ params .or. .not. "__ID" $ params return .F. endif id := params:__id eDebug(15, "CM execute", "'"+component+'.'+method+"'",', DB ID:', id) oErr := ErrorBlock({|e| break(e) }) begin sequence q:id := id q:db := OCMNG_REPOSITORY obj := sendMessage(,'sys.db', 'get', q ) eDebug(25, "CM object:", obj) // Run method q:id := obj:form codeFile := sendMessage(,'sys.db', 'get', q ) if empty(codeFile) eDebug(2, "CM: code file doesn't loaded to database") return .F. else // Put code to temporary file or use existing file fName := "."+PATH_DELIM+"cache"+PATH_DELIM+codeFile:id+".po" eDebug(15, "CM opens", fName) endif if .T. //.not. file(fName) // DEBUG: all occurences f := fcreate(fName, 0) fwrite(f, codeFile:content) fclose(f) endif // Use code fBlock := loadBlock(fName) if valType(fBlock) != "B" eDebug(2, "CM: Error load codeblock from:",fName) return NIL endif eDebug(15, "CM eval:", method) ret := eval(fBlock, method, params:args) eDebug(19, "CM returns:", ret) recover using oErr eDebug(1, "CM error:", errorMessage(oErr)) return "Error execute: "+errorMessage(oErr) end sequence return ret /** Get component list */ static function c_list( self, params ) local q:=map(), a eDebug(15, "CM list") // Query database q:db := OCMNG_REPOSITORY q:query := "select name from "+OCMNG_COMPONENT_CLASS+";" a := sendMessage(,'sys.db', 'execute', q ) eDebug(17, "DB returns:", a) return a /** Get component commands list */ static function c_commands( self, params ) local q:=map(), a, i, j, name, res:=array(0), cname eDebug(15, "CM commands") // Query database q:db := OCMNG_REPOSITORY q:query := "select name,component from "+OCMNG_COMMANDS_CLASS+";" a := sendMessage(,'sys.db', 'execute', q ) eDebug(17, "DB returns:", a) for i in a name := i[1] q:id := i[2] q:db := OCMNG_REPOSITORY obj := sendMessage(,'sys.db', 'get', q ) eDebug(25, "CM object:", obj) cname := iif( valtype(obj)=='O', cname:name, NIL ) aadd( res, { name, cname } ) next return res /** Get component object */ static function c_get( self, params ) local q:=map(), component, a, obj:=NIL eDebug(15, "CM get") if 'ARGS' $ params .and. 'NAME' $ params:args component := params:args:name else return NIL endif // Query database q:db := OCMNG_REPOSITORY q:query := 'select id from '+OCMNG_COMPONENT_CLASS+' where name=="'+component+'";' a := sendMessage(,'sys.db', 'execute', q ) eDebug(17, "DB returns:", a) if len(a) == 0 self:lastError := "Component '"+component+"' was not found" return NIL endif q:id := a[1] q:db := OCMNG_REPOSITORY obj := sendMessage(,'sys.db', 'get', q ) eDebug(25, "CM object:", obj) return obj --- NEW FILE: config.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of library eas */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ /** EASConfig - config manager */ #define DEFAULT_DEBUG_LEVEL 1 #define MAX_DEBUG_LEVEL 255 #define SPACER ' ' static config static debugLevel:=MAX_DEBUG_LEVEL function EASGetConfig() return config function EASConfig( params, check_load, description ) local obj, file:=NIL, i local driver:=NIL, connection:=NIL, exec:=0, repo:='' local debug:=NIL // Scan parameters for help if ascan(params, "-h") > 0 .or. ascan(params, "--help") > 0 config_help(description) endif // Extract from command line parameters config file (-c config) for i=1 to len(params)-1 if params[i] == '-c' file := params[i+1] endif if params[i] == '-d' driver := params[i+1] endif if params[i] == '-o' connection := params[i+1] endif if params[i] == '-debug' debug := val(params[i+1]) eSetDebugLevel( debug ) endif if params[i] == '-repo' repo := params[i+1] endif if params[i] == '-e' exec := i+1 endif next // Inherit from INIFILE class obj := iniFileNew( file ) obj:file := file // Attributes and methods obj:className := "EASConfig" obj:driver := driver obj:connection := connection obj:params := params obj:execute := exec obj:repo := repo obj:debug := debug _recover_EASCONFIG(obj) // Open config file if .not. obj:load() .and. check_load == .T. eDebug( 1, 'Cannot open config file:', obj:error ) return NIL endif // Set config as global config := obj return obj /* Virtual methods */ function _recover_EASCONFIG(obj) return obj /* Put params help on stdout */ static function config_help(description) if valtype(description) == 'C' ?? description+chr(10)+chr(10) endif ?? "Usage:&\n" ?? "&\t-h, --help This help&\n" ?? "&\t-c <config> Uses configuration from file <config>&\n" ?? "&\t-d <driver> Uses specified <driver> for user interface&\n" ?? "&\t-debug <n> Set debug output level (0-255: none-max)&\n" ?? "&\t-o <connection> Establish specified connection&\n" ?? "&\n" ?? "Connection example: raw://user:password@localhost:3000/EAS01&\n" ?? "&\n" CANCEL return /* Put value to debug output */ function eDebug() // level, values... local pC, level, i, s:='' pC := pcount() // No parameters: do nothing if pC < 2 return NIL endif level := param(1) if valtype(level) != 'N' level := DEFAULT_DEBUG_LEVEL endif if level <= debugLevel // Put on stdout for i:=2 to pC s := s + var2log( param(i) ) + ' ' next s := left(s, len(s)-1) ?? s + chr(10) endif return NIL /* Show variable in human readable format */ function var2log(var, level, decorate, base_level) local s:='', i, k, kn, sp, sp2, cr if valtype(level) == 'U' level := 1 endif if valtype(base_level) == 'U' base_level := level endif if valtype(decorate) == 'U' decorate := .F. endif sp := iif(decorate,replicate(SPACER, base_level-level),'') sp2 := iif(decorate,replicate(SPACER, base_level-level+1),'') cr := iif(decorate,chr(10),'') switch valtype(var) case 'A' if level <= 0 s := '<ARRAY>' else s := '{ ' + cr for i:=1 to len(var) s := s + sp2 + var2log(var[i], level-1, decorate, base_level) + iif(i==len(var),'',', ') + cr next s := s + sp + iif(decorate,'}', ' }') endif case 'B' s := '<CODE>' case 'C' if level != base_level s := "'"+var+"'" elseif var == '' s := "''" else s := var endif case 'D' s := dtoc(var) case 'L' s := iif(var, '.T.', '.F.') case 'M' if level != base_level s := "'"+var+"'" elseif var == '' s := "''" else s := var endif case 'N' s := alltrim(str(var)) case 'O' if level <= 0 s := '<OBJECT>' else s := '{ ' + cr k := array(0) aeval(mapkeys(var), {|e| aadd(k, { hashname(e), e }) }) asort(k,,, {|x,y| x[1] < y[1] }) for i:=1 to len(k) s := s + sp2 + k[i][1] + ':' + var2log(var[k[i][2]], level-1, decorate, base_level) + iif(i==len(k),'',', ') + cr next s := s + sp + iif(decorate,'}', ' }') endif case 'U' s := '<NIL>' otherwise s := '<UNKNOWN:'+valtype(var)+'>' endswitch return s /* Set level for debug output */ function eSetDebugLevel( level ) local old := debugLevel if valtype(level) == 'N' debugLevel := level endif return old --- NEW FILE: connection.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of library eas */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ /** EASConnection - connection manager */ /* TODO: thread support */ function EASConnection( params ) local obj if valtype(params) != "O" .or. .not. "PROTOCOL" $ params return NIL endif // Get protocol class from named value 'protocol' switch lower(params:protocol) case "raw" // Base raw protocol obj := EASRAWProtocol( params ) otherwise eDebug(5, "WARNING: unknown protocol '"+params:protocol+"'") obj := NIL endswitch if "NAME" $ params .and. obj != NIL // Connection created setCommand(, 'sys.transport.'+params:name, 'open', {|p| obj:open(p) } ) setCommand(, 'sys.transport.'+params:name, 'close', {|p| obj:close(p) } ) endif return obj --- NEW FILE: dbmanager.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of library eas */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ /** EASDatabaseManager - database manager */ function EASDatabaseManager( params ) local obj := map() obj:databases := array(0) obj:className := "EASDatabaseManager" obj:db := NIL _recover_EASDATABASEMANAGER(obj) return obj function _recover_EASDATABASEMANAGER(obj) obj:open := @c_open() obj:close := @c_close() obj:execute := @c_execute() obj:executeExt := @c_executeExt() obj:get := @c_get() obj:put := @c_put() obj:getAttr := @c_getAttr() return obj /** Open databases */ static function c_open( self, params ) local openDBs:=array(0), i // Connect to local database self:db := codb_connect() // Set database commands setCommand(, 'sys.db', 'execute', {|p| self:execute(p) } ) setCommand(, 'sys.db', 'executeExt', {|p| self:executeExt(p) } ) setCommand(, 'sys.db', 'get', {|p| self:get(p) } ) setCommand(, 'sys.db', 'put', {|p| self:put(p) } ) setCommand(, 'sys.db', 'getAttr', {|p| self:getAttr(p) } ) for i in self:db:dict_list aadd(openDBs, i[1]) next eDebug(15, "Open databases:", openDBs) return NIL /** Close databases */ static function c_close( self, params ) codb_close(self:db) return NIL /** Execute query */ static function c_execute( self, params ) return codb_get_result( self:executeExt(params) ) /** Execute query (return object instead array as in execute()) */ static function c_executeExt( self, params ) local res if assertParameters( params, { 'query:C', 'db:C' } ) return res endif //eDebug(15, "sys.db.executeExt.db", params:db ) res := codb_execute( self:db, params:query, params:db ) if codb_get_error( res ) != NIL eDebug(2, "sys.db.failed:", codb_get_error( res )) sendMessage(,,'sys.db.failed', res ) return array(0) endif return res /** Get object from database */ static function c_get( self, params ) local res if assertParameters( params, { 'id:C', 'db:C' } ) return NIL endif res := codb_get_object( self:db, params:id, params:db ) if codb_get_error( res ) != NIL eDebug(2, "sys.db.failed:", codb_get_error( res )) sendMessage(,,'sys.db.failed', res ) return array(0) endif return codb_get_result( res ) /** Put object to database */ static function c_put( self, params ) local res if assertParameters( params, { 'obj:O', 'db:C', 'class:C' } ) return NIL endif res := codb_put_object( self:db, params:obj, params:db, params:class ) if codb_get_error( res ) != NIL eDebug(2, "sys.db.failed:", codb_get_error( res )) sendMessage(,,'sys.db.failed', res ) return array(0) endif return codb_get_result( res ) /** Get object attribute from database */ static function c_getAttr( self, params ) local res, obj if assertParameters( params, { 'id:C', 'attr:C', 'db:C' } ) return res endif res := codb_get_object( self:db, params:id, params:db) if codb_get_error( res ) != NIL eDebug(2, "sys.db.failed:", codb_get_error( res )) sendMessage(,,'sys.db.failed', res ) return NIL endif obj := codb_get_result( res ) if valtype(obj) != 'O' .or. .not. upper(params:attr) $ obj eDebug(2, "sys.db.failed:", codb_get_error( res )) sendMessage(,,'sys.db.failed', res ) return NIL endif return obj[upper(params:attr)] --- NEW FILE: execmanager.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of library eas */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ /** EASExecuteManager - execute manager */ function EASExecuteManager( params ) local obj := map() obj:commands := array(0) obj:events := array(0) obj:className := "EASExecuteManager" obj:lastError := NIL obj:cManager := EASComponentManager( params ) _recover_EASEXECUTEMANAGER(obj) return obj function _recover_EASEXECUTEMANAGER(obj) obj:open := @c_open() obj:close := @c_close() obj:execute := @c_execute() obj:getCommands := @c_getCommands() obj:connect := @c_connect() obj:disconnect := @c_disconnect() return obj /** Open manager */ static function c_open( self, params ) eDebug(15, "Execute layer: open") self:cManager:open( params ) eDebug(15, "Execute layer: opened") return NIL /** Close manager */ static function c_close( self, params ) // TODO // params: ignored return NIL /** Execute command */ static function c_execute( self, params ) // params: receiver:C, command:C, args:AO, sender:C local i, j, bCode, vRet, id self:lastError := NIL // Check params if assertParameters( params, { 'receiver:UC', 'command:C', 'args:UAO', 'sender:UC' } ) return NIL endif // Lookup receiver name if valtype(params:receiver) == 'C' i := ascan( self:commands, {|e| e[1]==params:receiver } ) if i > 0 i := ascan( self:commands, {|e| e[1]==params:receiver .and. e[2]==params:command } ) if i > 0 // Execute command eDebug(15, "EXEC COMMAND '"+params:receiver+"."+params:command+"'...") bCode := self:commands[i][3] vRet := eval( bCode, params:args ) eDebug(20, "EXEC '"+params:receiver+"."+params:command+"' returns:", vRet) return vRet else self:lastError := "ERROR: command '"+params:command+"' for '"+params:receiver+"' not found" eDebug(2, self:lastError) return NIL endif elseif .not. empty (id:=self:cManager:lookup( params )) eDebug(15, "EXEC COMPONENT COMMAND: ",params:receiver,params:command,"...") params:__id := id vRet := self:cManager:execute( params ) eDebug(20, "EXEC COMPONENT '"+params:command+"' returns:", vRet) return vRet else self:lastError := iif(empty(self:cManager:lastError),"ERROR: component '"+params:receiver+"' not found",self:cManager:lastError) eDebug(2, "EXEC:", self:lastError) //eDebug(5, var2log(self:getCommands(),2,.T.)) return NIL endif endif // Execute signal handler eDebug(15, "EXEC EVENT:", params:command) i := ascan( self:events, {|e| e[1]==params:command } ) if i > 0 slot_list := self:events[i][2] for j:=1 to len(slot_list) eDebug(15, "EVENT: ",params:command) bCode := slot_list[j] eval( bCode, params:args ) next else eDebug(5, "WARNING: there are no handlers for event '"+params:command+"'") endif return NIL /** Get commands list */ static function c_getCommands( self, params ) // TODO local a:=array(0), i, cmp, ev // Clone component commands list for i:=1 to len(self:commands) cmp := self:commands[i][1] ev := ascan(a, {|e| e[1] == cmp }) if ev > 0 aadd( a[ev][2], self:commands[i][2] ) else aadd(a, array(2)) ev := len(a) a[ev][1] := cmp a[ev][2] := array(0) aadd( a[ev][2], self:commands[i][2] ) endif next // Append events aadd(a, array(2)) ev := len(a) a[ev][1] := NIL a[ev][2] := array(0) for i:=1 to len(self:events) aadd( a[ev][2], self:events[i][1] ) next // Sort array asort(a,,, {|x,y| valtype(x[1]) > valtype(y[1]) .and. x[1] < y[1] }) for i:=1 to len(a) asort(a[i][2]) next return a /** Connect code to signal */ static function c_connect( self, params ) // params: event:C, action:B or component:C, command:C, action:B local i if 'COMMAND' $ params if assertParameters( params, { 'component:C', 'command:C', 'action:B' } ) return NIL endif // Single command i := ascan( self:events, {|e| e[1]==params:component .and. e[2]==params:command} ) if i > 0 self:commands[i][3] := params:action else aadd(self:commands, { params:component, params:command, params:action } ) endif else if assertParameters( params, { 'event:C', 'action:B' } ) return NIL endif // Slot for event i := ascan( self:events, {|e| e[1]==params:event } ) if i > 0 aadd(self:events[i][2], params:action) else aadd(self:events, { params:event, { params:action } }) endif endif return NIL /** Disconnect code from signal */ static function c_disconnect( self, params ) // params: event:C local i // Check params if assertParameters( params, { 'event:C' } ) return NIL endif i := ascan( self:events, {|e| e[1]==params:event } ) if i > 0 adel(self:events, i) asize(self:events, len(self:events)-1 ) endif return NIL --- NEW FILE: functions.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of library eas */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #define EASVERSION '0.2.1a' static l10nModule := NIL /* Send message to remote component */ function component() local tm:=seconds(), msg, ret, args, pc:=pcount(), i, params:=NIL, p1, p2 if pc == 1 .and. valtype(param(1)) == 'A' params := param[1] pc := len(params) endif if pc < 2 eDebug(3, "Error in component(): must be 2 or more parameters") return NIL elseif pc == 3 args := iif(empty(params), param(3), params[3]) elseif pc > 3 args := map() for i:=3 to pc step 2 args[upper(iif(empty(params), param(i), params[i] ))] := iif(i+1>pc,NIL,iif(empty(params), param(i+1), params[i+1])) next endif // Prepare message contents p1 := iif(empty(params), param(1), params[1] ) p2 := iif(empty(params), param(2), params[2] ) msg := messageNew( p1, p2, args, NIL ) // Send message sendMessage(,'sys.transport.default', 'write', msg ) // Read answer from server ret := sendMessage(,'sys.transport.default', 'read') eDebug(15, "component '"+p1+"."+p2+"':", seconds()-tm) return ret /* Send message to local component */ function lcomponent() local ret, args, pc:=pcount(), i //eDebug(7, "lcomponent() call") if pc < 2 eDebug(3, "Error in component(): must be 2 or more parameters") return NIL elseif pc == 3 .and. valtype() == 'O' //eDebug(7, "lcomponent() - pass map as argument") args := param(3) elseif pc > 3 args := map() //eDebug(7, "lcomponent() - pass",pc,"parameters") for i:=3 to pc step 2 args[upper(param(i))] := iif(i+1>pc,NIL,param(i+1)) next endif //eDebug(5, "lcomponent():", args, iif("PARAMS" $ args, args:params, "") ) // Prepare message contents ret := sendMessage( , param(1), param(2), args, NIL ) return ret /* Check required named parameters and their types */ function assertParameters( value, template ) // template format: { { name, allowed_type }, ... } local i, l, e, name_r, name, types, sep // value must have map type, template - array if valtype(value) != 'O' .or. valtype(template) != 'A' return .T. endif l := len( template ) for i:=1 to l e := template[i] if valtype(e) != 'C' // Checked value must be string return .T. endif sep := at(':', e) if sep == 0 return .T. else name_r := left( e, sep-1 ) name := upper(name_r) types := upper(substr(e, sep+1 )) endif if .not. name $ value // Check named parameter in value eDebug(5, "ASSERT: not parameter '"+name_r+"':",value) return .T. endif if .not. valtype(value[name]) $ types // Check allowed types of parameters eDebug(5, "ASSERT: bad type of '"+name_r+"': "+valtype(value[name])+", expected '"+types+"':",value[name]) return .T. endif next return .F. /*===========================================================================*/ /* PREDEFINED COMPONENT CALL */ /*===========================================================================*/ /* Execute local database query */ function lquery(params, query) return lcomponent('sys.db', 'execute', 'db', iif(valtype(params)=='O' .and. 'DB' $ params, params:db,''), 'query', query) /* Opens form from server */ function openForm(name, type, id) return lcomponent('sys.ui', 'openForm', 'name', name, 'type', type, "id", id) /* Save data from form */ function saveForm(window, class) return lcomponent('sys.ui', 'saveForm', 'window', window, 'class', class) /* Save data from form and close if object is saved */ function saveFormAndClose(window, class) return lcomponent('sys.ui', 'saveFormAndClose', 'window', window, 'class', class) /* Delete object by id */ function deleteObject(id) return component('sys.db', 'execute', 'query', 'delete '+id) /* Set object attributes to form fields */ function setFormObject(window, obj) return lcomponent('sys.ui', 'setFormObject', 'window', window, 'obj', obj) /* Dialog box with confirmation of changed document close */ function dialogBoxConfirmClose(window, class) return lcomponent('sys.ui', 'dialogBoxConfirmClose', 'window', window, 'class', class) /* Opens view from server */ function openView(widget, name, timeout, window) return lcomponent('sys.ui', 'openView', 'widget', widget, 'name', name, 'timeout', timeout, 'window', window) /* Network transparent resource retrieving and caching */ function getResource(name) local oErr, real, content, f, l, lFile // Translate path real := strtran(name, "/", "_") // Get file from server eDebug(15, "getResource(): retrieve", name) oErr := errorBlock({|e| break(e) }) begin sequence lFile := file(real) lFile := .F. // TODO: not use cache if .not. lFile eDebug(15, "getResource(): load to file", real) content := component('form', 'get', 'name', name) if valtype(content) <> 'C' .or. len(content) == 0 return NIL endif f := fcreate(real) if f < 0 eDebug(2, "getResource(): Error open file for writing:", ferror(), ferrorstr()) return NIL endif l := fwrite(f, content) eDebug(15, "getResource(): wrote", real, l, "bytes") fclose(f) else eDebug(15, "getResource():", real, "(cached)") endif recover using oErr eDebug(2, "RESOURCE: Internal error:",errorMessage(oErr)) return o end sequence return real /* Open localization resources and setup module */ function l10nOpen(module, mo) l10nModule := module loadModuleMsg(module, mo) return NIL /* Return localized string */ function i18n(string) return gettext( string, l10nModule ) /* Safe output function for debug */ function testout(w) local oErr oErr := errorBlock({|e| break(e) }) begin sequence eDebug(5, "TESTOUT():", w:getSelectionId()) recover using oErr eDebug(2, "TESTOUT(): Internal error:",errorMessage(oErr)) end sequence return NIL /* Get E/AS version */ function EASGetVersion() return EASVERSION /* Get array { dep, class_name } from "dep:class_name" */ function form_splitClass( s ) local i, dep, class i := at( ':', s ) if i==0 return { '', s } endif dep := left( s, i-1 ) class := substr( s, i+1 ) return { dep, class } --- NEW FILE: messagemanager.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of library eas */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #define EAS_SERVER 0 #define EAS_CLIENT 1 /** EASMessageManager - message manager */ static global_msg /** TODO: - isolated MM interaction by gate mechanism */ function EASMessageManager( params ) local obj:=map(), tparams:=map() obj:className := "EASMessageManager" obj:type := iif( valtype(params)=='C' .and. lower(params)=='server', ; EAS_SERVER, EAS_CLIENT ) _recover_EASMESSAGEMANAGER(obj) global_msg := obj // Init other objects if obj:type == EAS_SERVER // Server tparams:role := EAS_SERVER obj:db := EASDatabaseManager() obj:exec := EASExecuteManager() obj:transport := EASTransportManager(tparams) else // Client tparams:role := EAS_CLIENT obj:db := EASDatabaseManager() obj:ui := EASUIManager() obj:exec := EASExecuteManager() obj:transport := EASTransportManager(tparams) endif setCommand(, 'sys.manager', 'commands', {|p| obj:exec:getCommands(p) } ) return obj function _recover_EASMESSAGEMANAGER(obj) obj:open := @c_open() obj:close := @c_close() obj:process := @c_process() return obj /** Open manager */ static function c_open( self, params ) // params: ignored eDebug(10, "MM: Activate layers...") if self:type == EAS_SERVER // Server eDebug(10, "RUN SERVER...") eDebug(15, "Database layer...") self:db:open(params) eDebug(15, "Execute layer...") self:exec:open(params) eDebug(15, "Transport layer...") self:transport:open(params) else // Client eDebug(10, "RUN CLIENT...") // eDebug(15, "Database layer...") // self:db:open(params) eDebug(15, "Execute layer...") self:exec:open(params) eDebug(15, "UI layer...") self:ui:open(params) eDebug(15, "Transport layer...") self:transport:open(params) endif eDebug(10, "MM: Layers are activated.") return NIL /** Close manager */ static function c_close( self, params ) // params: ignored eDebug(10, "MM: Close layers...") if self:type == EAS_SERVER // Server self:transport:close(params) self:exec:close(params) self:db:close(params) else // Client self:transport:close(params) self:exec:close(params) self:ui:close(params) self:db:close(params) endif eDebug(10, "MM: Layers are closed.") return NIL /** Process message from sender */ static function c_process( self, params ) // params: receiver:C, command:C, args:AO, sender:C local ret, msg:= map() if assertParameters( params, { 'receiver:UC', 'command:C', 'args:UAO', 'sender:UC' } ) return NIL endif if valtype(self:exec) == 'O' // Run command on execute layer ret := self:exec:execute( params ) eDebug(25, "MM:process() on execute returns:", ret) if ret == NIL .and. self:exec:lastError != NIL ret := map() ret:error := self:exec:lastError endif // If it isn't event (defined receiver): return result if valtype(params:receiver) != 'U' // Send answer to sender if valtype(params:sender) != 'U' msg:receiver := params:sender msg:command := NIL msg:args := ret eDebug(15, "MM:process(): pass result to sender") self:process( msg ) else // Sender undefined: straight return return ret endif else return NIL endif endif return NIL /*-------------------------------------------------------------------------*/ /* Global functions */ /*-------------------------------------------------------------------------*/ /** Set slot for event */ function setSlot( msg_m, event, action ) local params:=map() msg_m := iif(valtype(msg_m) != 'O', global_msg, msg_m) if valtype(msg_m) == 'O' .and. valtype(msg_m:exec) == 'O' params:event := event params:action := action return msg_m:exec:connect( params ) endif return NIL /** Set command for specified component */ function setCommand( msg_m, component, command, action ) local params:=map() msg_m := iif(valtype(msg_m) != 'O', global_msg, msg_m) eDebug(11, "setCommand():", component, command) if valtype(msg_m) == 'O' .and. valtype(msg_m:exec) == 'O' params:component := component params:command := command params:action := action return msg_m:exec:connect( params ) endif return NIL /** Send message */ function sendMessage( msg_m, receiver, command, args, sender ) local params:=map(), ret msg_m := iif(valtype(msg_m) != 'O', global_msg, msg_m) params:receiver := receiver params:command := command params:args := args params:sender := sender eDebug(10, "MM: sendMessage():", params ) if "ARGS" $ params eDebug(17, "MM: parameters:", params:args ) endif ret := msg_m:process( params ) eDebug(25, "MM: sendMessage() returns:", ret) return ret /** Create empty message */ function messageNew( receiver, command, args, sender ) local msg:=map(), obj:=map() msg:receiver := receiver msg:command := command msg:args := args msg:sender := sender obj:data := msg return obj --- NEW FILE: protocol_raw.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of library eas */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #include <tcp.ch> #define TCP_READ_TIMEOUT 6000 #define TCP_WRITE_TIMEOUT 600 /** EASRAWProtocol - base raw procotol for connection */ function EASRAWProtocol( params ) local obj := map() obj:type := "raw" obj:socket := map() obj:socket:handle := NIL obj:sessions := array(0) obj:className := "EASRAWProtocol" obj:params := params obj:errno := 0 _recover_EASRAWPROTOCOL(obj) return obj function _recover_EASRAWPROTOCOL(obj) obj:open := @c_open() obj:close := @c_close() obj:closeSession := @c_closeSession() obj:read := @c_read() obj:write := @c_write() obj:serialize := @c_serialize() obj:deserialize := @c_deserialize() return obj /** Open connection */ static function c_open( self, params ) // params: name:C, transport:C, port:C, role:C local args:=map(), session, threadId if empty(params) // Get parameters given in class constuctor params := self:params else self:params := params endif // Check params if assertParameters( params, { 'name:C', 'transport:C', 'port:N', 'role:C' } ) return NIL endif // Set socket parameters self:socket := map() self:socket:name := params:name self:socket:port := params:port self:socket:type := params:transport self:socket:role := lower(params:role) eDebug(15, "Open RAW connection:", params) if 'LISTENTIMEOUT' $ params self:socket:lTimeout := params:listenTimeout else self:socket:lTimeout := TCP_LISTEN_TIMEOUT endif if 'ACCEPTTIMEOUT' $ params self:socket:aTimeout := params:acceptTimeout else self:socket:aTimeout := TCP_ACCEPT_TIMEOUT endif if 'READBLOCK' $ params .and. params:readBlock > 0 self:socket:readBlock := params:readBlock else self:socket:readBlock := TCP_BUFLEN endif if 'READTIMEOUT' $ params self:socket:rTimeout := params:readTimeout else self:socket:rTimeout := TCP_READ_TIMEOUT endif if 'WRITETIMEOUT' $ params self:socket:wTimeout := params:writeTimeout else self:socket:wTimeout := TCP_WRITE_TIMEOUT endif // Open connection if self:socket:role == 'server' // Server mode: accept clients connections // Bind to port eDebug(10, "NETWORK: Bind to port...") if (self:socket:handle := tcpListen( self:socket:port, self:socket:lTimeOut )) == -1 self:error := self:socket:name+": error listen on port "+toString(self:socket:port)+": "+ferrorStr() args:error := self:error sendMessage(,,"sys.transport.failed",args) eDebug(2, self:error) return .F. endif eDebug(10, "NETWORK: Accept connections...") /*===================================================================*/ /* Main server loop */ /*===================================================================*/ do while( .T. ) if (session := tcpAccept( self:socket:handle, self:socket:aTimeOut )) != -1 // Create new session eDebug(10, "Start session: ", session) oSession := EASSession( self, session ) //session_open(oSession) threadId := start(@session_open(), oSession) // Begin new thread eDebug(15, "Stop session") endif sleep(0.01) enddo /*====================================================================*/ else // Client mode: connect to server if .not. 'HOST' $ params return .F. else self:socket:host := params:host endif if( (self:socket:handle := tcpConnect( self:socket:host, self:socket:port, self:socket:lTimeout )) == -1 ) eDebug(1, "NETWORK: Failed to open client connection:", ferrorStr()) self:error := self:socket:name+": error connect: "+ferrorStr() args:error := self:error sendMessage(,,"sys.transport.failed",args) return .F. else eDebug(10, "NETWORK: Open client connection:", self:socket:handle) setCommand(, 'sys.transport.'+params:name, 'read', {|p| self:deserialize(self:read(p)) } ) setCommand(, 'sys.transport.'+params:name, 'write', {|p| self:write(self:serialize(p)) } ) setCommand(, 'sys.transport.default', 'read', {|p| self:deserialize(self:read(p)) } ) setCommand(, 'sys.transport.default', 'write', {|p| self:write(self:serialize(p)) } ) endif endif return .T. /* Thread function for session open */ static function session_open(session) set deleted on set translate path off return session:open() /** Close connection */ static function c_close( self, params ) if self:socket:handle != NIL tcpClose( self:socket:handle ) endif return NIL /** Close session */ static function c_closeSession( self, params ) if assertParameters( params, { 'handle:N' } ) return NIL endif tcpClose( params:handle ) return NIL /** Serialize packet */ static function c_serialize( self, params ) // params: data:O local oRet := map() /* if assertParameters( params, { 'data:AO' } ) return NIL endif */ oRet:data := var2str( params:data ) oRet:size := len(oRet:data) eDebug(20, "NETWORK: serialize:", oRet) return oRet /** Deserialize packet */ static function c_deserialize( self, params ) // params: data:O local oRet := NIL, sec:=seconds() if assertParameters( params, { 'data:C', 'size:N' } ) return NIL endif oRet := str2var(params:data) eDebug(20, "NETWORK: deserialize:", oRet) eDebug(10, "NETWORK: deserialize:", seconds()-sec, "sec") return oRet /** Read data */ static function c_read( self, params ) // params: session:N local oData:=map(), cBuf, nSize, nRead, err:=map() local cBuffer:='', nTotal:=0 local oErr, sec:=seconds() self:socket:rTimeout := 6000 self:errno := 0 if self:socket:role != 'server' if valtype(params) != 'O' params := map() endif params:session := self:socket:handle endif eDebug(20, "NETWORK: Read from socket...") // Check params if assertParameters( params, { 'session:N' } ) return NIL endif nSize := self:socket:readBlock nSize := 6000 //eDebug(20, "NETWORK: buffer length:", nSize) cBuf := space(nSize) oErr := ErrorBlock({|e| break(e) }) begin sequence nRead := tcpRead( params:session, @cBuf, nSize, self:socket:rTimeout ) self:errno := ferror() if nRead == -1 // Empty socket return NIL else eDebug(20, "NETWORK: Read to buffer:", params:session, nRead, left(cBuf, nRead)) cBuffer := left(cBuf, nRead) nTotal := nRead if nRead == nSize //do while (nRead := tcpRead( params:session, @cBuf, nSize, self:socket:rTimeout )) != -1 do while (nRead := tcpRead( params:session, @cBuf, nSize, 10 )) != -1 cBuffer += left(cBuf, nRead) nTotal += nRead enddo endif endif recover using oErr eDebug(2, "NETWORK: read error") cBuffer := '' nTotal := 0 end sequence oData:data := cBuffer oData:size := nTotal eDebug(10, "NETWORK: Read", oData:size, "bytes,", seconds()-sec, "sec") return oData /** Write data*/ static function c_write( self, params ) // params: session:N, data:O local nSended, err:=map() local oErr if self:socket:role != 'server' .and. valtype(params) == 'O' params:session := self:socket:handle endif // Check params if assertParameters( params, { 'session:N', 'data:C', 'size:N' } ) return .F. endif eDebug(10, "NETWORK: Write to socket...") oErr := ErrorBlock({|e| break(e) }) begin sequence nSended := tcpWrite( params:session, params:data, params:size, self:socket:wTimeout ) if nSended != params:size // Error send data err:error := "Cannot write data to socket: length="+toString(params:size)+', wrote='+toString(nSended) params:session:SendMessage("error.write",err) return .F. endif recover using oErr err:error := "write error" params:session:SendMessage("error.write",err) return .F. end sequence eDebug(10, "NETWORK: Wrote",nSended,"bytes") return .T. --- NEW FILE: session.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of library eas */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ /** EASSession - session manager */ function EASSession( connection, handle ) local obj := map() obj:name := "session_"+ltrim(str(handle)) obj:connection := connection obj:handle := handle obj:messages := NIL // TODO: Message manager per session. Only for server obj:attributes := array(0) obj:access := .F. obj:className := "EASSession" _recover_EASSESSION(obj) setCommand(, 'sys.transport.'+obj:name, 'login', {|p| obj:login(p) } ) setCommand(, 'sys.transport.default', 'login', {|p| obj:login(p) } ) setCommand(, 'sys.transport.'+obj:name, 'close', {|p| obj:close(p) } ) setCommand(, 'sys.transport.default', 'close', {|p| obj:close(p) } ) return obj function _recover_EASSESSION(obj) obj:open := @c_open() obj:login := @c_login() obj:close := @c_close() obj:read := @c_read() obj:write := @c_write() obj:sendMessage := @c_sendMessage() return obj /** Open session */ static function c_open( self, params ) local cRead /*===================================================================*/ /* Main session loop */ /*===================================================================*/ do while( .T. ) if self:read() > 1 exit endif sleep(0.01) enddo /*===================================================================*/ self:close() return NIL /** Authenticate login */ static function c_login( self, params ) local oWrite := map() eDebug( 5, "LOGIN:", params) self:access := .F. // Authenticate user if empty( lcomponent('auth', 'authenticate', 'params', params ) ) self:access := .T. endif eDebug(10, "Access: ",self:access ) oWrite:answer := self:access eDebug(16, "Answer:", oWrite:answer) return oWrite /** Close session */ static function c_close( self, params ) self:connection:closeSession( self ) eDebug(15, "Session closing.") return NIL /** Read data */ static function c_read( self, params ) local oRaw, obj, oWrite:=map(), oMsg, oRet, attr if valtype( params ) != 'O' params := map() endif params:session := self:handle oRaw := self:connection:read( params ) if self:connection:errno == 32 // Client connection was broken eDebug(13, "Connection was broken from client" ) return 2 endif if empty(oRaw) return 0 endif eDebug( 20, "Session read:", oRaw) // Deserialize answer obj := self:connection:deserialize( oRaw ) if .not. empty(obj) .and. .not. assertParameters( obj, { 'receiver:UC', 'command:C', 'args:UAO', 'sender:UC' } ) // Send message to message manager // TODO: use isolated message managers per session oMsg := NIL // Use global message manager eDebug(10, "ARGS:", obj:args) // Check for session.close if lower(obj:receiver) == 'session' .and. lower(obj:command) == 'close' return 2 // Close session endif // Process query oRet := sendMessage( oMsg, obj:receiver, obj:command, obj:args, obj:sender ) // Write answer to socket oWrite:data := oRet self:write( oWrite ) // If access denied then close connection //eDebug(2, "ACCESS:",self:access) if .not. self:access return 2 // Close session endif else eDebug(1, "Session: Invalid object received.") endif return 1 /** Write data */ static function c_write( self, params ) // params: data:O local oData, oError eDebug( 20, "Session write") if params == NIL params := map() params:data := NIL endif if .not. valtype( params ) $ 'AO' .or. ( (oData := self:connection:serialize( params )) == NIL ) eDebug( 1, "ERROR preparing data for write. Sending message with data.") oError := map() oError:data := params oData := self:connection:serialize( oError ) oData:session := self:handle return self:connection:write( oData ) endif oData:session := self:handle return self:connection:write( oData ) /** Write data */ static function c_sendMessage( self, receiver, command, args, sender ) local ret if valtype(self:messages) == 'O' ret := sendMessage(self:messages, receiver, command, args, sender ) else eDebug( 1, "Session error:",command,args ) endif return --- NEW FILE: transportmanager.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of library eas */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ /** EASTransportManager - Transport manager */ static oCurConn function EASTransportManager( params ) local obj := map(), i, cfg, sections, pkeys, pset, j, c, cstr, a obj:connections := array(0) obj:connectionNames := array(0) obj:active := .F. obj:role := iif(valtype(params)=='O' .and. 'ROLE' $ params, params:role, 1) obj:className := "EASTransportManager" _recover_EASTRANSPORTMANAGER(obj) setCommand(, 'sys.transport', 'open', {|p| obj:open(p) } ) setCommand(, 'sys.transport', 'close', {|p| obj:close(p) } ) setCommand(, 'sys.transport', 'addConnection', {|p| obj:addConnection(p) } ) // Read from config file cfg := EASGetConfig() if valtype(cfg) != 'O' .or. cfg:className != "EASConfig" return NIL endif eDebug(10, "TRANSPORT: Connection from command line:",cfg:connection) if cfg:connection != NIL // Connection in command line eDebug(10, "TRANSPORT: Create connection from string:",cfg:connection) // Fill connection parameters // Parse string: protocol://user:password@host:port/db cstr := alltrim(cfg:connection) pset := map() pset:name := 'CONNECTION_1' pset:transport := 'TCP' pset:role := 'client' j := at('://', cstr) if j > 1 pset:protocol := upper(left(cstr,j-1)) else pset:protocol := 'RAW' // default protocol endif cstr := substr(cstr,j+3) a := split(cstr,"[@:/]") asize(a, 5) pset:user := iif(empty(a[1]),'anonymous',a[1]) pset:password := a[2] pset:host := iif(empty(a[3]),'localhost',a[3]) pset:port := iif(empty(a[4]),3000,val(a[4])) cfg:connection := pset // Create connection object c := EASConnection( pset ) if c != NIL eDebug(10, "TRANSPORT: Connection from string is created") aadd(obj:connectionNames, pset:name) aadd(obj:connections, c) else eDebug(1, "TRANSPORT: Failed to create connection from command line") endif endif // Load sections from config file and create EASConnection objects sections := cfg:sections() for i in sections if ascan(cfg:keys(i), "PROTOCOL") > 0 pset := map() pset:name := i pkeys := cfg:keys(i) for j in pkeys pset[j] := cfg:getValue(i, j) next c := EASConnection( pset ) if c != NIL aadd(obj:connectionNames, i) aadd(obj:connections, c) endif endif next return obj function _recover_EASTRANSPORTMANAGER(obj) obj:open := @c_open() obj:addConnection := @c_addConnection() obj:close := @c_close() return obj /** Open manager */ static function c_open( self, params ) // params: ignored local oErr, c, threadId oErr := errorBlock({|e| break(e) }) begin sequence // No connections: send event 'sys.transport.failed' if len( self:connections ) == 0 eDebug(1, "TRANSPORT: no connections") sendMessage(,,'sys.transport.failed') return NIL endif if self:role == 0 // Server // Open each connection for c in self:connections oCurConn := c threadId := start( @connection_open() ) // Begin thread for each connection next // Infinity loop for child thread do while( .T. ) sleep(0.01) enddo else // Open each connection for c in self:connections oCurConn := c connection_open() next endif recover using oErr eDebug(1, "Open connection error:",errorMessage(oErr)) return o end sequence return .F. // Thread function for connection open static function connection_open() local oErr, ret, connection set deleted on set translate path off oErr := errorBlock({|e| break(e) }) begin sequence eDebug(10, "Begin thread in connection_open()") connection := oCurConn ret := connection:open() recover using oErr eDebug(1, "Open connection:",errorMessage(oErr)) return o end sequence return ret /** Add connection */ static function c_addConnection( self, params ) // params: name:C, transport:C, port:N, role:C local c // Check params if assertParameters( params, { 'name:C', 'transport:C', 'port:N', 'role:C' } ) return NIL endif c := EASConnection( params ) if c != NIL aadd(self:connectionNames, params:name) aadd(self:connections, c) endif return c /** Close manager: stop all connections */ static function c_close( self, params ) // params: ignored local c // Close each connection for c in self:connections c:close() next return NIL --- NEW FILE: uimanager.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of library eas */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #include <clip-ui.ch> #define SHOW_FORMS .T. /** EASUIManager - UI (User Interface) manager */ /** TODO: - using and clean cache for form and orginary files */ function EASUIManager( params ) local obj := map() obj:forms := array(0) obj:className := "EASUIManager" obj:main := NIL _recover_EASUIMANAGER(obj) // Init workspace c_init(obj, params) return obj function _recover_EASUIMANAGER(obj) obj:open := @c_open() obj:run := @c_run() obj:close := @c_close() obj:openForm := @c_openForm() obj:closeForm := @c_closeForm() obj:saveForm := @c_saveForm() obj:saveFormAndClose := @c_saveFormAndClose() obj:openView := @c_openView() obj:setFormObject := @c_setFormObject() obj:dialogBoxConfirmClose := @c_dialogBoxConfirmClose() return obj /** Init UI manager */ static function c_init( self, params ) // Check config file cfg := EASGetConfig() if valtype(cfg) == 'O' .and. cfg:className == "EASConfig" .and. .not. empty(cfg:driver) eDebug(10, "UI: Used driver:", cfg:driver) useDriver( cfg:driver ) endif self:ws := UIWorkSpace() // TODO: params return NIL /** Open manager */ static function c_open( self, params ) // TODO setCommand(, 'sys.ui', 'openForm', {|p| self:openForm(p) } ) setCommand(, 'sys.ui', 'saveForm', {|p| self:saveForm(p) } ) setCommand(, 'sys.ui', 'saveFormAndClose', {|p| self:saveFormAndClose(p) } ) setCommand(, 'sys.ui', 'openView', {|p| self:openView(p) } ) setCommand(, 'sys.ui', 'setFormObject', {|p| self:setFormObject(p) } ) setCommand(, 'sys.ui', 'dialogBoxConfirmClose', {|p| self:dialogBoxConfirmClose(p) } ) return NIL /** Run manager */ static function c_run( self, params ) self:running = .T. self:ws:run() return NIL /** Close manager */ static function c_close( self, params ) if "RUNNING" $ self .and. self:running self:ws:quit() else CANCEL endif return NIL /** Open form */ static function c_openForm( self, params ) // params: form:C local oErr, name, vRet, form, parent, t local formType, objId, action, class // Check params if assertParameters( params, { 'name:C' } ) return NIL endif name := params:name formType := iif("TYPE" $ params, params:type, NIL) objId := iif("ID" $ params, params:id, NIL) action := iif("ACTION" $ params, params:action, NIL) // Get form from server vRet := component('form', 'get', params) eDebug(10, "UI: open form '"+name+"':", len(vRet), 'bytes. ID:', objId) //eDebug(19, vRet) if empty(vRet) eDebug(1, "ERROR: cannot open empty form") return .F. endif if valtype(vRet) == 'O' .and. 'ERROR' $ vRet eDebug(1, "ERROR on form open:", vRet:error) return .F. endif if valtype(vRet) <> 'C' eDebug(1, "ERROR on form open: return value must be string") return .F. endif oErr := errorBlock({|e| break(e) }) begin sequence //eDebug(10, "UI parent:", self:main) if valtype(self:main) == 'O' .and. self:main:className != "UIMainWindow" .and. "PARENT" $ self:main parent := self:main:parent else parent := self:main endif // Process and show form form := UIForm( name, parent ) if SHOW_FORMS eDebug(17, "UI: FORM CONTENT:", vRet ) endif win := form:parseString(vRet) if win == NIL eDebug(3, "UI: Error parse form") return .F. elseif self:main == NIL self:main := win endif win:objId := objId win:creator := parent win:returnAction := action // eDebug(15, "FORM name:", formName, "type:", formType, "id:", objId, "action:", action) // Get class name t := form:oXml:XPath("/head/class") if len(t) > 0 win:objClass := t[1]:attribute("name") else win:objClass := NIL endif //?? "SET WINDOW OBJECT ID:", win:objId, "CLASS:", win:objClass, chr(10) // Set pre actions t := form:oXml:XPath("/head") form:setPreAction(t[1], NIL) win:show() recover using oErr eDebug(1, "UI EXCEPTION:",errorMessage(oErr)) return o end sequence eDebug(10, "UI: end open form") return .T. /** Close form */ static function c_closeForm( self, params ) // TODO local win // Lookup for form name and close it... return .F. /** Save values from form */ static function c_saveForm( self, params ) local window, o, class, id:=NIL, ddb // Check params if assertParameters( params, { 'window:O', 'class:C' } ) return NIL endif window := params:window // Get values from form o := window:getObj() ddb := form_splitClass( params:class ) // Put object to server id := component('sys.db', 'put', 'obj', o, 'class', ddb[2], 'db', ddb[1] ) eDebug(5, "Form is saved:", id, o) window:objId := id window:origObj := o if 'ONSAVE' $ window eval(window:onSave, window, o) endif return id /** Save values from form */ static function c_saveFormAndClose( self, params ) local id id := self:saveForm( params ) if .not. empty(id) params:window:close() endif return /** Open view from server and fill table*/ static function c_openView( self, params ) local name, fields:='', d, i, l, id, timeout:=NIL, timer, window:=NIL, pos:=NIL // Check params if assertParameters( params, { 'widget:O', 'name:C' } ) .or. .not. 'COLUMNS' $ params:widget return NIL endif if 'TIMEOUT' $ params timeout := params:timeout endif if 'WINDOW' $ params window := params:window endif eDebug(10, "UI: Open view '"+params:name+"'") // Define name and columns name := params:name for i in params:widget:columns fields += i+',' next fields += 'id' // Get content from server d := component('form', 'getView', 'name', name, 'fields', fields) // Apply data to widget pos := iif('SAVEPOSITION' $ params:widget, params:widget:savePosition(), NIL) eDebug(5, "CURRENT ROW:", pos ) params:widget:clear() //eDebug(10, "OPENVIEW():", d:data) for i in d:data l := len(i) id := i[l] //eDebug(14, "ADD ROW:", i, id) asize(i,l-1) params:widget:addRow(i,id) if 'RESTOREPOSITION' $ params:widget params:widget:restorePosition(pos) endif next // Autorefresh on timer if .not. empty(timeout) .and. valtype(window) == 'O' .and. 'TIMERS' $ window timeout := iif(valtype(timeout)!='N', val(timeout), timeout) eDebug(5, "Set update timer for view '"+params:name+"' (", timeout, "second(s) )") timer := UITimer(timeout, {|| openView(params:widget, params:name) } ) aadd(window... [truncated message content] |
From: Andrey C. <sku...@us...> - 2006-06-02 14:29:51
|
Update of /cvsroot/eas-dev/eas/libeas In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv10085/libeas Log Message: Directory /cvsroot/eas-dev/eas/libeas added to the repository |
From: Andrey C. <sku...@us...> - 2006-06-02 14:29:32
|
Update of /cvsroot/eas-dev/eas/libcodb_query In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv10059/libcodb_query Log Message: Directory /cvsroot/eas-dev/eas/libcodb_query added to the repository |
From: Andrey C. <sku...@us...> - 2006-06-02 14:21:17
|
Update of /cvsroot/eas-dev/clip-ui In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv6909 Added Files: .clipcharset Log Message: Add file --- NEW FILE: .clipcharset --- koi8-r |
Update of /cvsroot/eas-dev/clip-xml/example In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv4527 Added Files: Makefile XPath_tests.tar.gz c.xml component.dtd component.xml currency.xml test-koi8-r.xml test.prg test_xml.prg Log Message: Add files --- NEW FILE: Makefile --- # CLIP-XML library examples Makefile # Copyright (C) 2006, E/AS Software Foundation # Web: http://eas.lrn.ru # Copyright (C) 2006, ITK # Web: http://www.itk.ru ifndef CLIPROOT CLIPROOT=$(shell cd ../../../../; pwd)/cliproot endif include $(CLIPROOT)/include/Makefile.inc CLIPINCLUDE = -I$(CLIPROOT)/include CLIP = $(CLIPROOT)/bin/clip C_FLAGS=-g .SUFFIXES: .prg .o .po .PHONY: all clean # Widget tests LIBS=-lclip-xml PROGS=test_xml test EXTRALIBS= all: $(PROGS) clean: rm -f *.o core* *core $(PROGS) *.log *.nm *.ex *.exe $(OUTPUT) rm -f *.exe *.c *.o *.a *.so *.po *.log *.pa *.b *.BAK *.bak *~ core* *core rm -rf *.ex *.nm test_xml: test_xml.prg $(CLIP) -ewsln $(C_FLAGS) $(CLIPINCLUDE) test_xml.prg $(LIBS) $(EXTRALIBS) test: test.prg clip -esg test.prg $(LIBS) --- NEW FILE: XPath_tests.tar.gz --- (This appears to be a binary file; contents omitted.) --- NEW FILE: c.xml --- (This appears to be a binary file; contents omitted.) --- NEW FILE: component.dtd --- <!-- DTD for CLIP component format Version: 1.0rc Date: 06 Apr 2006 Author: Andrey Cherepanov <sib...@ma...> Last version: http://eas.lrn.ru/dtd/component.dtd For check component XML type: xmllint -noout -dtdvalid component.dtd <component.xml> (replace '-' by double '-') --> <!-- Root tag --> <!ELEMENT component ( name, version, category*, description?, license?, created?, modified?, author*, property*, requires?, commands?, files?, dictionary?, meta*, data*, install?, uninstall?, locale* )* > <!-- Component name. Required. --> <!ELEMENT name (#PCDATA)> <!-- Component category (path delimited by '/': Base/Directories/Finance). Optional. --> <!ELEMENT category (#PCDATA)> <!-- Component brief description. Optional. --> <!ELEMENT description (#PCDATA)> <!-- Component version. Required. --> <!ELEMENT version (#PCDATA)> <!-- Component license. Optional. --> <!ELEMENT license (#PCDATA)> <!-- Component creation date (yyyy-mm-dd). Optional. --> <!ELEMENT created (#PCDATA)> <!-- Component modification date (yyyy-mm-dd). Optional. --> <!ELEMENT modified (#PCDATA)> <!-- Component author. Optional. --> <!ELEMENT author (#PCDATA|name|email|copyright)*> <!ELEMENT email (#PCDATA)> <!ELEMENT copyright (#PCDATA)> <!-- Custom property. Optional. --> <!ELEMENT property (#PCDATA)> <!ATTLIST property name CDATA #REQUIRED > <!-- Component requirements. Optional. --> <!ELEMENT requires (dependence*)> <!ELEMENT dependence (#PCDATA)> <!ATTLIST dependence type CDATA #REQUIRED version CDATA #IMPLIED > <!ELEMENT function (#PCDATA)> <!-- Component requires. Optional. --> <!ELEMENT commands (plugin*)> <!ELEMENT plugin (code?, command+)> <!ATTLIST plugin name CDATA #IMPLIED > <!ELEMENT code (#PCDATA)> <!ELEMENT command (#PCDATA)> <!-- Component files. Optional. --> <!ELEMENT files (file*)> <!ELEMENT file (#PCDATA)> <!ATTLIST file name CDATA #REQUIRED form CDATA #IMPLIED type CDATA #IMPLIED > <!-- Dictionary --> <!ELEMENT dictionary ( id, name, type?, path, dbUser? )> <!ELEMENT id (#PCDATA)> <!ELEMENT type (#PCDATA)> <!ELEMENT path (#PCDATA)> <!ELEMENT dbUser (#PCDATA)> <!-- Database structure and data. Optional. --> <!ELEMENT meta ( depository| extent| attribute| index| class| counter| tcolumn| tview| report| plugin| user| group)*> <!ATTLIST meta dictionary CDATA #REQUIRED > <!-- Depository --> <!ELEMENT depository (#PCDATA)> <!ATTLIST depository id ID #IMPLIED name CDATA #REQUIRED number CDATA #IMPLIED memoSize CDATA #IMPLIED > <!-- Extent --> <!ELEMENT extent (#PCDATA)> <!ATTLIST extent id ID #IMPLIED name CDATA #REQUIRED > <!-- Attribute --> <!ELEMENT attribute (#PCDATA)> <!ATTLIST attribute id ID #IMPLIED name CDATA #REQUIRED type (string|number|date|logical|text|object|any|ref|classref|array|code) #REQUIRED len CDATA #IMPLIED dec CDATA #IMPLIED lenType (ignore|rtrim|alltrim|fill) #IMPLIED refTo CDATA #IMPLIED defValue CDATA #IMPLIED counter CDATA #IMPLIED notNull (yes|no|true|false) #IMPLIED notEmpty (yes|no|true|false) #IMPLIED mask CDATA #IMPLIED source CDATA #IMPLIED code CDATA #IMPLIED count CDATA #IMPLIED > <!-- Index --> <!ELEMENT index (#PCDATA)> <!ATTLIST index id ID #IMPLIED name CDATA #REQUIRED expression CDATA #REQUIRED > <!-- Class --> <!ELEMENT class (#PCDATA|object)*> <!ATTLIST class id ID #IMPLIED name CDATA #REQUIRED superClass CDATA #IMPLIED extent CDATA #IMPLIED essence CDATA #IMPLIED expression CDATA #IMPLIED uniqueKey CDATA #IMPLIED logNeed (yes|no|true|false) #IMPLIED hasCounters (yes|no|true|false) #IMPLIED attributes CDATA #IMPLIED indices CDATA #IMPLIED > <!-- Counter --> <!ELEMENT counter (#PCDATA)> <!ATTLIST counter id ID #IMPLIED name CDATA #REQUIRED value CDATA #REQUIRED type CDATA #IMPLIED depository CDATA #IMPLIED maxValue CDATA #IMPLIED lastValue CDATA #IMPLIED > <!-- TColumn --> <!ELEMENT tcolumn (#PCDATA)> <!ATTLIST tcolumn id ID #IMPLIED name CDATA #REQUIRED header CDATA #IMPLIED footer CDATA #IMPLIED width CDATA #IMPLIED expression CDATA #IMPLIED depend CDATA #IMPLIED ref CDATA #IMPLIED > <!-- TView --> <!ELEMENT tview (#PCDATA)> <!ATTLIST tview id ID #IMPLIED name CDATA #REQUIRED class CDATA #IMPLIED extent CDATA #IMPLIED group CDATA #IMPLIED user CDATA #IMPLIED header CDATA #IMPLIED footer CDATA #IMPLIED columns CDATA #IMPLIED > <!-- Report--> <!ELEMENT report (#PCDATA)> <!ATTLIST report id ID #IMPLIED name CDATA #REQUIRED type CDATA #IMPLIED file CDATA #IMPLIED class CDATA #IMPLIED extent CDATA #IMPLIED group CDATA #IMPLIED user CDATA #IMPLIED > <!-- Plugin --> <!ELEMENT plugin (#PCDATA)> <!ATTLIST plugin id ID #IMPLIED name CDATA #REQUIRED class CDATA #IMPLIED type CDATA #IMPLIED file CDATA #IMPLIED function CDATA #IMPLIED > <!-- User --> <!ELEMENT user (#PCDATA)> <!ATTLIST user id ID #IMPLIED name CDATA #REQUIRED group CDATA #IMPLIED access CDATA #IMPLIED > <!-- Group --> <!ELEMENT group (#PCDATA)> <!ATTLIST group id ID #IMPLIED name CDATA #REQUIRED > <!-- Default data --> <!ELEMENT data ( objects* )> <!ELEMENT objects (object+)> <!ATTLIST objects class CDATA #REQUIRED depository CDATA #REQUIRED > <!-- Object contents --> <!ELEMENT object (attr+)> <!ATTLIST object id ID #IMPLIED > <!ELEMENT attr (#PCDATA|value)*> <!ATTLIST attr name CDATA #REQUIRED refTo CDATA #IMPLIED > <!ELEMENT value (#PCDATA|value)*> <!ATTLIST value type (string|number|date|logical|text|object|any|ref|classref|array|code) #REQUIRED refTo CDATA #IMPLIED meta CDATA #IMPLIED > <!-- Install actions. Optional. --> <!ELEMENT install (#PCDATA)> <!-- Uninstall actions. Optional. --> <!ELEMENT uninstall (#PCDATA)> <!-- Component l10n. Optional. --> <!ELEMENT locale (name?, description?, message*)> <!ATTLIST locale lang CDATA #REQUIRED > <!ELEMENT message (#PCDATA)> <!ATTLIST message id CDATA #REQUIRED > --- NEW FILE: component.xml --- <?xml version="1.0" encoding="utf-8" standalone="no" ?> <component> <name>currency</name> <version>1.0</version> <category>Base/Directories/Finance</category> <description>Currency directory</description> <license>This component in released under the GNU/GPL License</license> <created>2005-12-21</created> <modified>2006-01-16</modified> <author> <name>Andrey Cherepanov</name> <email>su...@ea...</email> <copyright>2006</copyright> </author> <author>uri</author> <property name="policy">ru.Ru</property> <property name="info">http://eas.lrn.ru/components/currency.xml</property> <property name="download">http://eas.lrn.ru/components/currency.component</property> <property name="documentation"><![CDATA[ This is documentation on component currency ]]></property> <requires> <dependence type="component">forms</dependence> </requires> <commands> <plugin name="currency.po"> <command>getCourse</command> </plugin> </commands> <files> <file name="create.xpm">Icon for create action</file> <file name="edit.xpm">edit.xpm</file> <file name="delete.xpm">delete.xpm</file> <file form="list/currency" name="currency_list.xfl"></file> <file form="object/currency" name="currency.xfl"></file> <file name="currency.xpm">currency.xpm</file> </files> <meta dictionary="ETC01"> <!-- Depositories --> <depository name="ETC0101" /> <!-- Attributes --> <attribute name="name" type="string" len="30" notNull="yes" notEmpty="yes"> Currency name </attribute> <attribute name="ncode" type="string" len="3" /> <attribute name="code" type="string" len="3" /> <!-- Indeces --> <index name="ncode" expression="ncode" /> <index name="code" expression="code" /> <!-- Classes --> <class name="currency" attributes="ncode,code,name" indices="ncode,code"> Class for currencies </class> </meta> <!-- Default data --> <data> <objects class="currency" depository="ETC0101"> <object> <attr name="ncode">001</attr> <attr name="code">USD</attr> <attr name="name">ÐÐ¾Ð»Ð»Ð°Ñ Ð¡Ð¨Ð</attr> </object> </objects> </data> <install> <!-- custom install actions --> </install> <uninstall> <!-- custom uninstall actions --> </uninstall> <locale lang="ru"> <name>ÐалÑÑÑ</name> <description>СпÑавоÑник валÑÑ</description> <message id="Currency name">Ðазвание валÑÑÑ</message> <message id="Class for currencies">ÐалÑÑÑ</message> </locale> </component> --- NEW FILE: currency.xml --- <?xml version="1.0" encoding="koi8-r" ?> <package> <name>currency</name> <category>goscomstatinfo</category> <documentation> lalala1 lalala2 </documentation> <version>1.0</version> <license>GNU/GPL</license> <creationDate>2006-03-10</creationDate> <author> <authorName>ITK</authorName> <authorEmail>ur...@it...</authorEmail> </author> [...1147 lines suppressed...] <attr name="name">ìÁÒÉ</attr> <attr name="smallname">çÒÕÚÉÑ</attr> </object> <object> <attr name="code">985</attr> <attr name="unit">òLN</attr> <attr name="name">úÌÏÔÙÊ</attr> <attr name="smallname">ðÏÌØÛÁ</attr> </object> <object> <attr name="code">986</attr> <attr name="unit">BRL</attr> <attr name="name">âÒÁÚÉÌØÓËÉÊ ÒÅÁÌ</attr> <attr name="smallname">âÒÁÚÉÌÉÑ</attr> </object> </class> </data> </package> --- NEW FILE: test-koi8-r.xml --- (This appears to be a binary file; contents omitted.) --- NEW FILE: test.prg --- #include <clip-expat.ch> function main() local parser, aa if pcount() == 0 ? "Call test <filename.xml>" return endif filename = param(1) if empty(filename) filename = "component.xml" endif tm := seconds() parser = xml_ParserCreate() ? "parser:",parser aa = 0 xml_SetUserData(parser, @aa) xml_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_NEVER) xml_SetCharacterDataHandler(parser, @myfunc()) //xml_SetStartElementHandler(parser, @myStartElement()) //xml_SetEndElementHandler(parser, @myEndElement()) xml_SetElementHandler(parser, @myStartElement(), @myEndElement()) xml_SetCommentHandler(parser, @myComment()) xml_SetCdataSectionHandler(parser, @myStartCdata(), @myEndCdata()) file = fopen(filename) do while !fileeof(file) buf = filegetstr(file, 1024) //? "buf=", buf xml_Parse(parser, buf, len(buf), fileeof(file)) if xml_GetErrorCode(parser) <> 0 ? "Error in XML (" + alltrim(str(xml_GetErrorCode(parser))) + "): " + xml_ErrorString(parser) ?? " at line "+alltrim(str(xml_GetCurrentLineNumber(parser))) ?? ", column "+alltrim(str(xml_GetCurrentColumnNumber(parser))) endif enddo //? "end parse line",xml_GetCurrentLineNumber(parser) fclose(file) xml_ParserFree(parser) ? "" ? "free" ? "Processed time:", seconds()-tm, "sec" ? return function myfunc(aa, str, len) ? replicate("&\t", aa), '"'+str+'"' return function myStartElement(aa, name, arrAttr) ? replicate("&\t", aa),"<"+name+">" for i=1 to len(arrAttr) ? replicate("&\t", aa+1), arrAttr[i] next aa++ return function myEndElement(aa, name) aa-- ? replicate("&\t", aa),"</"+ name+">" return function myComment(aa, data) ? replicate("&\t", aa),"/* "+ data+ "*/" return function myStartCdata(aa) ? replicate("&\t", aa),"<![CDATA[" aa++ return function myEndCdata(aa) aa-- ? replicate("&\t", aa),"]]>" return --- NEW FILE: test_xml.prg --- /** Test program for XMLTree */ #define SPACER ' ' #define VERBOSE .F. /* TODO: decorated output for XPath result */ function main( cmd, path ) local f, tm, c, t1, t2, t3, i, node, tstr, attr tm := seconds() // Create XMLTree object f := XMLTree() // "koi8-r" ) if cmd != 'dump' .and. cmd != 'create' if VERBOSE; ?? "XMLTree() created&\n"; endif endif if cmd != 'create' // Parse file if .not. f:parseFile( "component.xml" ) // Output error description and exit ?? "ERROR:", f:getError(), chr(10) return 1 endif else // Create root tag t1 := XMLTag( "languages" ) f:setRoot( t1 ) // Create two child tags and fill texts and attributes t2 := XMLTag( "lang" ) t2:setAttribute( "code", "en" ) t2:setText( "English" ) t3 := XMLTag( "lang" ) t3:setAttribute( "code", "ru" ) t3:setText( "òÕÓÓËÉÊ" ) // Add child tags t1:addChild( t2 ) t1:addChild( t3 ) endif if cmd != 'dump' .and. cmd != 'create' if VERBOSE; ?? "parseFile(&\"component.xml&\") done&\n"; endif endif switch cmd case 'count' c := map() c:tags := 0 c:text := 0 countTags( f:getRoot(), c ) ?? "Tags:", c:tags, chr(10) ?? "Text:", c:text, "characters", chr(10) case 'dump' ?? f:dump() case 'create' ?? f:dump() case 'path' c := f:XPath( path ) if .not. empty( xml_XPathError() ) ?? "ERROR:", xml_XPathError(),chr(10) return 1 endif if valtype(c) == 'A' for i:=1 to len(c) node := c[i] if valtype(node) == 'O' tstr := "<" + node:getName() for attr in node:getAttributes() tstr += " " + attr[1] + '="' + attr[2] + '"' next tstr += ">" + node:getText() + "</" + node:getName() + ">" ?? tstr + chr(10) else ?? c,chr(10) endif next else ?? c,chr(10) endif otherwise ?? "Available commands:&\n" ?? " count Count all tags and text characters&\n" ?? " create Manually create simple XML file &\n" ?? " dump Dump tree as XML file&\n" ?? " path <XPath> Show elements selected by XPath&\n" endswitch if cmd != 'dump' .and. cmd != 'create' if VERBOSE; ?? "Processed time:", alltrim(str(seconds()-tm)), "sec&\n"; endif endif return 0 function countTags( tag, counter ) local i counter:tags++ counter:text += len(tag:text) for i in tag:childs countTags( i, counter ) next return |
From: Andrey C. <sku...@us...> - 2006-06-02 14:14:24
|
Update of /cvsroot/eas-dev/clip-xml In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv4078 Added Files: AUTHORS ChangeLog Makefile.empty Makefile.in TODO _hashxml.h clip-expat.ch clip-expat.h configure expat.c hashxml.h xmltag.prg xmltree.prg xpath.prg Log Message: Add files --- NEW FILE: AUTHORS --- Andrey (Skull) Cherepanov <sk...@ea...> xPath,xmlTree,xmlTag Alena <al...@it...> expat.c --- NEW FILE: ChangeLog --- 2006-16-01 - create xPath, xmlTree 2006-10-01 - create expat.c --- NEW FILE: Makefile.empty --- SSSS = "Warning: package expat-dev not installed" all: echo $(SSSS) install: echo $(SSSS) clean: rm -rf Makefile *.o *.s *.b *.bak *.a *.so *.ex *.nm echo $(SSSS) --- NEW FILE: Makefile.in --- # This is a part of CLIP-XML library # # Copyright (C) 2006 by E/AS Software Foundation # Author: Andrey Cherepanov <sk...@ea...> # # Copyright (C) 2006 by ITK # Author: Alena <al...@it...> # ifndef CLIPROOT CLIPROOT=$(shell cd ../../../; pwd)/cliproot endif include $(CLIPROOT)/include/Makefile.inc CLIPINCLUDE = -I$(CLIPROOT)/include CLIP = $(CLIPROOT)/bin/clip .SUFFIXES: .prg .o .po COMPILER=gcc C_FLAGS=-Wall -g -I. -I$(CLIPROOT)/include -I/usr/include LIBS= -lexpat CC = $(COMPILER) CFLAGS = $(C_FLAGS) XLIB=libclip-xml.a XSLIB=libclip-xml$(DLLSUFF) XSLIBREAL=libclip-xml$(DLLREALSUFF) XTARGETS=$(XLIB) $(XSLIB) SRC = expat.c OBJ = expat.o XLIBOBJS = $(OBJ) OBJS = xmltag.o xmltree.o xpath.o HDRS = clip-expat.ch HASHSRCS = $(SRC) $(HDRS) .PHONY: all clean uninstall distclean all: hash $(SRC) $(OBJS) $(XTARGETS) hash: _hashxml.h _hashxml.h: $(HASHSRCS) $(CLIPROOT)/bin/clip_hashextract $(HASHSRCS) | sort -u > _hashxml.h cmp _hashxml.h hashxml.h 2>/dev/null || cp _hashxml.h hashxml.h $(XLIB): $(XLIBOBJS) $(OBJS) rm -f $(XLIB) $(CLIPROOT)/bin/clip_makelib $(XLIB) $(XLIBOBJS) $(OBJS) ranlib $(XLIB) $(XSLIB): $(XLIB) $(OBJS) $(CLIPROOT)/bin/clip_makeslib $(XSLIB) $(XLIB) $(LIBS) $(OBJS) install: all $(CLIPROOT)/bin/clip_cp $(XLIB) $(XSLIB) $(DESTDIR)$(CLIPROOT)/lib chmod 0644 $(DESTDIR)$(CLIPROOT)/lib/$(XLIB) chmod 0755 $(DESTDIR)$(CLIPROOT)/lib/$(XSLIB) cp clip-expat.ch $(DESTDIR)$(CLIPROOT)/include/ cp clip-expat.h $(DESTDIR)$(CLIPROOT)/include/ mkdir -p $(DESTDIR)$(CLIPROOT)/doc/example/clip-xml cp -R example/* $(DESTDIR)$(CLIPROOT)/doc/example/clip-xml/ clean: cd example && $(MAKE) clean rm -rf Makefile *.o *.s *.b *.bak *.a *.so *.ex *.nm commit: _cvs commit update: _cvs update -dP ucommit: _cvs update -dP && _cvs commit shell: sh .prg.o: $(CLIP) -wn $(CLIPINCLUDE) $< .c.o: @echo $(CC) $(CDBGFLAGS) $(CFLAGS) -c $< @$(CC) $(CDBGFLAGS) $(CFLAGS) $(XCFLAGS) -c $< --- NEW FILE: TODO --- TODO ==== Last change: 18 Apr 2006 - full realization of XPath (attributes, expressions, functions) - SOAP and WSDL - RSS --- NEW FILE: _hashxml.h --- #define HASH_HANDLE 0xD0BA46FC --- NEW FILE: clip-expat.ch --- #define EG_NOPARSER 108 #define XML_PARAM_ENTITY_PARSING_NEVER 0 #define XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE 1 #define XML_PARAM_ENTITY_PARSING_ALWAYS 2 /* Error code */ #define XML_ERROR_NONE 0 #define XML_ERROR_NO_MEMORY 1 #define XML_ERROR_SYNTAX 2 #define XML_ERROR_NO_ELEMENTS 3 #define XML_ERROR_INVALID_TOKEN 4 #define XML_ERROR_UNCLOSED_TOKEN 5 #define XML_ERROR_PARTIAL_CHAR 6 #define XML_ERROR_TAG_MISMATCH 7 #define XML_ERROR_DUPLICATE_ATTRIBUTE 8 #define XML_ERROR_JUNK_AFTER_DOC_ELEMENT 9 #define XML_ERROR_PARAM_ENTITY_REF 10 #define XML_ERROR_UNDEFINED_ENTITY 11 #define XML_ERROR_RECURSIVE_ENTITY_REF 12 #define XML_ERROR_ASYNC_ENTITY 13 #define XML_ERROR_BAD_CHAR_REF 14 #define XML_ERROR_BINARY_ENTITY_REF 15 #define XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF 16 #define XML_ERROR_MISPLACED_XML_PI 17 #define XML_ERROR_UNKNOWN_ENCODING 18 #define XML_ERROR_INCORRECT_ENCODING 19 #define XML_ERROR_UNCLOSED_CDATA_SECTION 20 #define XML_ERROR_EXTERNAL_ENTITY_HANDLING 21 #define XML_ERROR_NOT_STANDALONE 22 #define XML_ERROR_UNEXPECTED_STATE 23 #define XML_ERROR_ENTITY_DECLARED_IN_PE 24 #define XML_ERROR_FEATURE_REQUIRES_XML_DTD 25 #define XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING 26 /* Added in 1.95.7. */ #define XML_ERROR_UNBOUND_PREFIX 27 /* Added in 1.95.8. */ #define XML_ERROR_UNDECLARING_PREFIX 28 #define XML_ERROR_INCOMPLETE_PE 29 #define XML_ERROR_XML_DECL 30 #define XML_ERROR_TEXT_DECL 31 #define XML_ERROR_PUBLICID 32 #define XML_ERROR_SUSPENDED 33 #define XML_ERROR_NOT_SUSPENDED 34 #define XML_ERROR_ABORTED 35 #define XML_ERROR_FINISHED 36 #define XML_ERROR_SUSPEND_PE 37 --- NEW FILE: clip-expat.h --- #ifndef _CLIP_EXPAT_ #define _CLIP_EXPAT_ #include <expat.h> #include <clip.h> #include <error.ch> typedef struct _C_parser C_parser; typedef struct _C_parser { XML_Parser parser; ClipVar obj; ClipMachine *cmachine; ClipVar *userData; int handle; void *data; ClipVar characterDataHandler; /* start function */ ClipVar startElementHandler; /* start function */ ClipVar endElementHandler; /* end function */ ClipVar commentHandler; /* start function */ ClipVar startCdataSectionHandler; /* start function */ ClipVar endCdataSectionHandler; /* end function */ ClipVar defaultHandler; /* start function */ } _C_parser; #define NEW(type) ((type*)calloc(sizeof(type),1)) C_parser *_fetch_c_arg(ClipMachine* cm); C_parser *_register_parser(ClipMachine * cm, XML_Parser parser); C_parser *_list_get_cparser(ClipMachine * cm, void *pointer); void _list_put_cparser(ClipMachine * cm, void *pointer, C_parser * cpar); void _list_remove_cparser(ClipMachine * cm, void * pointer); #define CHECKCPARSER(cpar) \ if(!cpar || !cpar->parser) { \ char err[100]; \ sprintf(err,"No parser object"); \ _clip_trap_err(cm,EG_ARG,0,0,"CLIP_EXPAT",EG_NOPARSER,err); \ goto err; \ } #define CHECKARG(n,t) \ if((_clip_parinfo(cm,n)!=t)){ \ char err[100]; \ sprintf(err,"Bad argument (%d), must be a "#t" type",n); \ _clip_trap_err(cm,EG_ARG,0,0,"CLIP_EXPAT",EG_ARG,err); \ goto err; \ } #define CHECKARG2(n,t,t2) \ if((_clip_parinfo(cm,n)!=t) && (_clip_parinfo(cm,n)!=t2)){ \ char err[100]; \ sprintf(err,"Bad argument (%d), must be a "#t" or "#t2" type",n); \ _clip_trap_err(cm,EG_ARG,0,0,"CLIP_EXPAT",EG_ARG,err); \ goto err; \ } #define CHECKOPT(n,t) \ if((_clip_parinfo(cm,n)!=t)&&(_clip_parinfo(cm,n)!=UNDEF_t)){ \ char err[100]; \ sprintf(err,"Bad argument (%d), must be a "#t" type or NIL",n); \ _clip_trap_err(cm,EG_ARG,0,0,"CLIP_EXPAT",EG_ARG,err); \ goto err; \ } #define CHECKOPT2(n,t,t2) \ if((_clip_parinfo(cm,n)!=t)&&(_clip_parinfo(cm,n)!=t2)&&(_clip_parinfo(cm,n)!=UNDEF_t)){ \ char err[100]; \ sprintf(err,"Bad argument (%d), must be a "#t" or "#t2" type or NIL",n); \ _clip_trap_err(cm,EG_ARG,0,0,"CLIP_EXPAT",EG_ARG,err); \ goto err; \ } #endif --- NEW FILE: configure --- #!/bin/sh exitf() { rm -f test_expat.c test_expat exit $1 } cp Makefile.empty Makefile cat <<EOF >test_expat.c #include <stdio.h> #include "expat.h" static void startElement(void *userData, const char *name, const char **atts) { } static void endElement(void *userData, const char *name) { } int main(int argc, char *argv[]) { char buf[BUFSIZ]; XML_Parser parser = XML_ParserCreate(NULL); int done; int depth = 0; XML_SetUserData(parser, &depth); XML_SetElementHandler(parser, startElement, endElement); done = XML_STATUS_ERROR; XML_ParserFree(parser); return 0; } EOF EXPAT_EXIST='' gcc -o test_expat test_expat.c -I/usr/include -lexpat >/dev/null 2>&1 && EXPAT_EXIST="yes"] if [ -z $EXPAT_EXIST ] then echo "Warning: package expat-dev not installed or have old version" exitf 1 fi cp Makefile.in Makefile exitf 0 --- NEW FILE: expat.c --- /* Copyright (C) 2005 ITK Author : Kornilova E.V. <al...@it...> License : (GPL) http://www.itk.ru/clipper/license.html */ #include <string.h> #include <errno.h> #include <expat.h> #include "clip.h" #include "screen/charset.h" #include "hashxml.h" #include "clip-expat.h" #include "clip-expat.ch" static ClipVar _xml_list; static ClipVar *xml_list = &_xml_list; CLIP_DLLEXPORT C_parser* _list_get_cparser(ClipMachine * cm, void *pointer) { double d; if (pointer && xml_list->t.type == MAP_t) if (_clip_mgetn(cm, xml_list, (long) pointer, &d) == 0) return (C_parser *) ((long) d); return NULL; } CLIP_DLLEXPORT void _list_put_cparser(ClipMachine * cm, void *pointer, C_parser * cpar) { if (xml_list->t.type != MAP_t) _clip_map(cm, xml_list); if (pointer) _clip_mputn(cm, xml_list, (long) pointer, (long) cpar); } CLIP_DLLEXPORT void _list_remove_cparser(ClipMachine * cm, void * pointer) { if (pointer && xml_list->t.type == MAP_t) _clip_mdel(cm, xml_list, (long) pointer); } CLIP_DLLEXPORT void _destroy_c_parser(void *obj) { C_parser * cpar = (C_parser *)obj; _list_remove_cparser(cpar->cmachine, cpar->parser); _clip_destroy(cpar->cmachine, cpar->userData); _clip_destroy(cpar->cmachine, &cpar->characterDataHandler); _clip_destroy(cpar->cmachine, &cpar->startElementHandler); _clip_destroy(cpar->cmachine, &cpar->endElementHandler); _clip_destroy(cpar->cmachine, &cpar->startCdataSectionHandler); _clip_destroy(cpar->cmachine, &cpar->endCdataSectionHandler); _clip_destroy(cpar->cmachine, &cpar->commentHandler); _clip_destroy(cpar->cmachine, &cpar->defaultHandler); _clip_destroy_c_item(cpar->cmachine, cpar->handle, _C_ITEM_TYPE_XML_PARSER); free(cpar); } CLIP_DLLEXPORT C_parser * _register_parser(ClipMachine * cm, XML_Parser parser) { int handle = -1; C_parser * cpar = (C_parser*)calloc(1,sizeof(C_parser)); cpar->cmachine = cm; cpar->parser = parser; _clip_map(cm, &cpar->obj); /* Saving widget info into CLIP state machine * and it`s handle to a map HANDLE property */ handle = _clip_store_c_item(cm, cpar, _C_ITEM_TYPE_XML_PARSER, NULL); cpar->handle = handle; _clip_mputn(cm, &cpar->obj, HASH_HANDLE, handle); /* Store C_parser pointer in list of parsers */ _list_put_cparser(cm, parser, cpar); return cpar; } CLIP_DLLEXPORT C_parser* _fetch_c_arg(ClipMachine* cm) { C_parser* cpar; if (_clip_parinfo(cm,1)==NUMERIC_t) { cpar = (C_parser*)_clip_fetch_c_item(cm,_clip_parni(cm,1), _C_ITEM_TYPE_XML_PARSER); } else { if (_clip_parinfo(cm,1)==MAP_t) { double h; _clip_mgetn(cm, _clip_spar(cm,1), HASH_HANDLE, &h); cpar = (C_parser *) _clip_fetch_c_item(cm, (int) h, _C_ITEM_TYPE_XML_PARSER); } else { _clip_trap_err(cm,EG_ARG,0,0,"CLIP_EXPAT", EG_ARG,"Bad parser descriptor"); return NULL; } } if(!cpar) { _clip_trap_err(cm,EG_ARG,0,0,"CLIP_EXPAT", EG_ARG,"Bad parser descriptor"); return NULL; } return cpar; } static int XMLCALL unknownEncoding(void *encodingHandlerData, const XML_Char *name, XML_Encoding *info) { int i,len1 = 0; cons_CharsetEntry *cs1 = 0; if (load_charset_name((char*) name, &cs1, &len1)) { _clip_logg(2, "translate_charset: cannot load charset file '%s': %s", (char *)name, strerror(errno)); return XML_STATUS_ERROR; } for(i=0; i<256; i++) info->map[i] = i; for (i = 0; i < len1; i++) { int ch; unsigned long unich; cons_CharsetEntry *cp; cp = cs1 + i; ch = cp->ch; unich = cp->unich; if (ch >= 256 || ch<0x80) continue; info->map[i] = unich ; } free(cs1); for (i = 0; i < 32; i++) info->map[i] = i; info->data = 0; info->convert = 0; info->release = 0; return XML_STATUS_OK; } int clip_XML_PARSERCREATE(ClipMachine *cm) { char * encoding = _clip_parc(cm, 1); XML_Parser parser = NULL; C_parser *cpar; CHECKOPT(1,CHARACTER_t); parser = XML_ParserCreate((encoding?encoding:NULL)); XML_SetUnknownEncodingHandler(parser, unknownEncoding, NULL); XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_NEVER); cpar = _register_parser(cm, parser); _clip_mclone(cm,RETPTR(cm),&cpar->obj); return 0; err: return 1; } int clip_XML_PARSERFREE(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); XML_Parser parser = cpar->parser; CHECKCPARSER(cpar); _destroy_c_parser(cpar); XML_ParserFree(parser); return 0; err: return 1; } int clip_XML_SETUSERDATA(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *userData = _clip_par(cm, 2); CHECKCPARSER(cpar); cpar->userData = userData; XML_SetUserData(cpar->parser, cpar); return 0; err: return 1; } int clip_XML_SETPARAMENTITYPARSING(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); int flag = _clip_parni(cm, 2); CHECKCPARSER(cpar); XML_SetParamEntityParsing(cpar->parser, flag); return 0; err: return 1; } int clip_XML_PARSE(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); const char *str = _clip_parc(cm, 2); int len = _clip_parni(cm, 3); int isFinal = _clip_parl(cm, 4); CHECKCPARSER(cpar); CHECKARG(2, CHARACTER_t); CHECKARG(3, NUMERIC_t); CHECKARG(4, LOGICAL_t); _clip_retni(cm, (int)XML_Parse(cpar->parser, str, len, isFinal)); return 0; err: return 1; } int clip_XML_GETERRORCODE(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); CHECKCPARSER(cpar); _clip_retni(cm,XML_GetErrorCode(cpar->parser)); return 0; err: return 1; } int clip_XML_ERRORSTRING(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); CHECKCPARSER(cpar); _clip_retc(cm,(char *) XML_ErrorString(XML_GetErrorCode(cpar->parser))); return 0; err: return 1; } int clip_XML_GETCURRENTLINENUMBER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); CHECKCPARSER(cpar); _clip_retni(cm,XML_GetCurrentLineNumber(cpar->parser)); return 0; err: return 1; } int clip_XML_GETCURRENTCOLUMNNUMBER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); CHECKCPARSER(cpar); _clip_retni(cm,XML_GetCurrentColumnNumber(cpar->parser)); return 0; err: return 1; } static int _character_data_handler(void * userData, const XML_Char * s, int len) { C_parser *cud = (C_parser *)userData; ClipVar str; ClipVar n; ClipVar stack[3], *app, *nv = 0; ClipVar res; int ret=1; unsigned l=0; memset(&stack,0,sizeof(stack)); memset( &res, 0, sizeof(ClipVar) ); memset(&res, 0, sizeof(ClipVar)); memset(&str, 0, sizeof(ClipVar)); memset(&n, 0, sizeof(ClipVar)); _clip_var_str(s, len, &str); n.t.type = NUMERIC_t; n.n.d = len; app = cud->userData; if (!(app->t.flags & F_MREF)) { l =1; nv = NEW(ClipVar); *nv = *app; nv->t.count = 2; app->t.flags = F_MREF; app->p.vp = nv; app->t.field = 0; app->p.fp = 0; } stack[0] = *app; _clip_mclone(cud->cmachine, &stack[1], &str); _clip_mclone(cud->cmachine, &stack[2], &n); if ( _clip_eval( cud->cmachine, &(cud->characterDataHandler), 3, stack, &res ) == 0 ) ret = res.t.type == LOGICAL_t ? res.l.val : ret; _clip_destroy(cud->cmachine, &res); if (l) --(nv->t.count); _clip_destroy(cud->cmachine, &stack[1]); _clip_destroy(cud->cmachine, &stack[2]); _clip_destroy(cud->cmachine, &str); _clip_destroy(cud->cmachine, &n); return ret; } int clip_XML_SETCHARACTERDATAHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *func = _clip_spar(cm, 2); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->characterDataHandler, func); XML_SetCharacterDataHandler(cpar->parser, (XML_CharacterDataHandler)_character_data_handler); return 0; err: return 1; } static int _start_element_handler(void * userData, const XML_Char * name, const XML_Char ** attrs) { C_parser *cud = (C_parser *)userData; ClipVar str; ClipVar *eattr, *item; ClipVar stack[3], *app, *nv = 0; ClipVar res; int ret=1, i, j; unsigned l=0; long vect[2]; memset(&stack,0,sizeof(stack)); memset( &res, 0, sizeof(ClipVar) ); memset(&str, 0, sizeof(ClipVar)); eattr = malloc(sizeof(ClipVar)); _clip_var_str(name, strlen(name), &str); vect[0] = 0; vect[1] = 0; _clip_array(cud->cmachine, eattr, 1, vect); for(i=0, j=0; attrs[i]; i+=2, j++) { ClipVar var; item = malloc(sizeof(ClipVar)); vect[0] = 2; _clip_array(cud->cmachine, item, 1, vect); vect[0] = j+1; _clip_asize(cud->cmachine, eattr, 1, vect); vect[0] = j; _clip_aset(cud->cmachine, eattr, item, 1, vect); memset(&var, 0, sizeof(var)); var.t.type = CHARACTER_t; var.s.str.buf = (char *)attrs[i]; var.s.str.len = strlen(attrs[i]); vect[1] = 0; _clip_aset(cud->cmachine, eattr, &var, 2, vect); memset(&var, 0, sizeof(var)); var.t.type = CHARACTER_t; var.s.str.buf = (char *)attrs[i+1]; var.s.str.len = strlen(attrs[i+1]); vect[1] = 1; _clip_aset(cud->cmachine, eattr, &var, 2, vect); _clip_destroy(cud->cmachine, item); free(item); } app = cud->userData; if (!(app->t.flags & F_MREF)) { l =1; nv = NEW(ClipVar); *nv = *app; nv->t.count = 2; app->t.flags = F_MREF /*mptr?F_MPTR:F_MREF */ ; app->p.vp = nv; app->t.field = 0; app->p.fp = 0; } stack[0] = *app; _clip_mclone(cud->cmachine, &stack[1], &str); _clip_mclone(cud->cmachine, &stack[2], eattr); if ( _clip_eval( cud->cmachine, &(cud->startElementHandler), 3, stack, &res ) == 0 ) ret = res.t.type == LOGICAL_t ? res.l.val : ret; _clip_destroy(cud->cmachine, &res); if (l) --(nv->t.count); _clip_destroy(cud->cmachine, &stack[1]); _clip_destroy(cud->cmachine, &stack[2]); _clip_destroy(cud->cmachine, &str); _clip_destroy(cud->cmachine, eattr); free(eattr); return ret; } int clip_XML_SETSTARTELEMENTHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *func = _clip_spar(cm, 2); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->startElementHandler, func); XML_SetStartElementHandler(cpar->parser, (XML_StartElementHandler)_start_element_handler); return 0; err: return 1; } static int _end_element_handler(void * userData, const XML_Char * name) { C_parser *cud = (C_parser *)userData; ClipVar str; ClipVar stack[2], *app, *nv = 0; ClipVar res; int ret=1; unsigned l=0; memset(&stack,0,sizeof(stack)); memset( &res, 0, sizeof(ClipVar) ); memset(&str, 0, sizeof(ClipVar)); _clip_var_str(name, strlen(name), &str); app = cud->userData; if (!(app->t.flags & F_MREF)) { l =1; nv = NEW(ClipVar); *nv = *app; nv->t.count = 2; app->t.flags = F_MREF /*mptr?F_MPTR:F_MREF */ ; app->p.vp = nv; app->t.field = 0; app->p.fp = 0; } stack[0] = *app; _clip_mclone(cud->cmachine, &stack[1], &str); if ( _clip_eval( cud->cmachine, &(cud->endElementHandler), 2, stack, &res ) == 0 ) ret = res.t.type == LOGICAL_t ? res.l.val : ret; _clip_destroy(cud->cmachine, &res); if (l) --(nv->t.count); _clip_destroy(cud->cmachine, &stack[1]); _clip_destroy(cud->cmachine, &str); return ret; } int clip_XML_SETENDELEMENTHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *func = _clip_spar(cm, 2); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->endElementHandler, func); XML_SetEndElementHandler(cpar->parser, (XML_EndElementHandler)_end_element_handler); return 0; err: return 1; } int clip_XML_SETELEMENTHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *sfunc = _clip_spar(cm, 2); ClipVar *efunc = _clip_spar(cm, 3); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); CHECKARG2(3, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->startElementHandler, sfunc); _clip_mclone(cm, &cpar->endElementHandler, efunc); XML_SetElementHandler(cpar->parser, (XML_StartElementHandler)_start_element_handler, (XML_EndElementHandler)_end_element_handler); return 0; err: return 1; } static int _comment_handler(void * userData, const XML_Char * data) { C_parser *cud = (C_parser *)userData; ClipVar str; ClipVar stack[2], *app, *nv = 0; ClipVar res; int ret=1; unsigned l=0; memset(&stack,0,sizeof(stack)); memset( &res, 0, sizeof(ClipVar) ); memset(&str, 0, sizeof(ClipVar)); _clip_var_str(data, strlen(data), &str); app = cud->userData; if (!(app->t.flags & F_MREF)) { l =1; nv = NEW(ClipVar); *nv = *app; nv->t.count = 2; app->t.flags = F_MREF /*mptr?F_MPTR:F_MREF */ ; app->p.vp = nv; app->t.field = 0; app->p.fp = 0; } stack[0] = *app; _clip_mclone(cud->cmachine, &stack[1], &str); if ( _clip_eval( cud->cmachine, &(cud->commentHandler), 2, stack, &res ) == 0 ) ret = res.t.type == LOGICAL_t ? res.l.val : ret; _clip_destroy(cud->cmachine, &res); if (l) --(nv->t.count); _clip_destroy(cud->cmachine, &stack[1]); _clip_destroy(cud->cmachine, &str); return ret; } int clip_XML_SETCOMMENTHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *func = _clip_spar(cm, 2); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->commentHandler, func); XML_SetCommentHandler(cpar->parser, (XML_CommentHandler)_comment_handler); return 0; err: return 1; } static int _start_cdata_section_handler(void * userData) { C_parser *cud = (C_parser *)userData; ClipVar stack[1], *app, *nv = 0; ClipVar res; int ret=1; unsigned l=0; memset(&stack,0,sizeof(stack)); memset( &res, 0, sizeof(ClipVar) ); app = cud->userData; if (!(app->t.flags & F_MREF)) { l =1; nv = NEW(ClipVar); *nv = *app; nv->t.count = 2; app->t.flags = F_MREF /*mptr?F_MPTR:F_MREF */ ; app->p.vp = nv; app->t.field = 0; app->p.fp = 0; } stack[0] = *app; if ( _clip_eval( cud->cmachine, &(cud->startCdataSectionHandler), 1, stack, &res ) == 0 ) ret = res.t.type == LOGICAL_t ? res.l.val : ret; _clip_destroy(cud->cmachine, &res); if (l) --(nv->t.count); return ret; } int clip_XML_SETSTARTCDATASECTIONHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *func = _clip_spar(cm, 2); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->startCdataSectionHandler, func); XML_SetStartCdataSectionHandler(cpar->parser, (XML_StartCdataSectionHandler)_start_cdata_section_handler); return 0; err: return 1; } static int _end_cdata_section_handler(void * userData) { C_parser *cud = (C_parser *)userData; ClipVar stack[1], *app, *nv = 0; ClipVar res; int ret=1; unsigned l=0; memset(&stack,0,sizeof(stack)); memset( &res, 0, sizeof(ClipVar) ); app = cud->userData; if (!(app->t.flags & F_MREF)) { l =1; nv = NEW(ClipVar); *nv = *app; nv->t.count = 2; app->t.flags = F_MREF /*mptr?F_MPTR:F_MREF */ ; app->p.vp = nv; app->t.field = 0; app->p.fp = 0; } stack[0] = *app; if ( _clip_eval( cud->cmachine, &(cud->endCdataSectionHandler), 1, stack, &res ) == 0 ) ret = res.t.type == LOGICAL_t ? res.l.val : ret; _clip_destroy(cud->cmachine, &res); if (l) --(nv->t.count); return ret; } int clip_XML_SETENDCDATASECTIONHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *func = _clip_spar(cm, 2); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->endCdataSectionHandler, func); XML_SetEndCdataSectionHandler(cpar->parser, (XML_EndCdataSectionHandler)_end_cdata_section_handler); return 0; err: return 1; } int clip_XML_SETCDATASECTIONHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *sfunc = _clip_spar(cm, 2); ClipVar *efunc = _clip_spar(cm, 3); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); CHECKARG2(3, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->startCdataSectionHandler, sfunc); _clip_mclone(cm, &cpar->endCdataSectionHandler, efunc); XML_SetCdataSectionHandler(cpar->parser, (XML_StartCdataSectionHandler)_start_cdata_section_handler, (XML_EndCdataSectionHandler)_end_cdata_section_handler); return 0; err: return 1; } static int _default_handler(void * userData, const XML_Char * s, int len) { C_parser *cud = (C_parser *)userData; ClipVar str; ClipVar n; ClipVar stack[3], *app, *nv = 0; ClipVar res; int ret=1; unsigned l=0; memset(&stack,0,sizeof(stack)); memset( &res, 0, sizeof(ClipVar) ); memset(&str, 0, sizeof(ClipVar)); memset(&n, 0, sizeof(ClipVar)); _clip_var_str(s, len, &str); n.t.type = NUMERIC_t; n.n.d = len; app = cud->userData; if (!(app->t.flags & F_MREF)) { l =1; nv = NEW(ClipVar); *nv = *app; nv->t.count = 2; app->t.flags = F_MREF /*mptr?F_MPTR:F_MREF */ ; app->p.vp = nv; app->t.field = 0; app->p.fp = 0; } stack[0] = *app; _clip_mclone(cud->cmachine, &stack[1], &str); _clip_mclone(cud->cmachine, &stack[2], &n); if ( _clip_eval( cud->cmachine, &(cud->defaultHandler), 3, stack, &res ) == 0 ) ret = res.t.type == LOGICAL_t ? res.l.val : ret; _clip_destroy(cud->cmachine, &res); if (l) --(nv->t.count); _clip_destroy(cud->cmachine, &stack[1]); _clip_destroy(cud->cmachine, &stack[2]); _clip_destroy(cud->cmachine, &str); _clip_destroy(cud->cmachine, &n); return ret; } int clip_XML_SETDEFAULTHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *func = _clip_spar(cm, 2); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->defaultHandler, func); XML_SetDefaultHandler(cpar->parser, (XML_DefaultHandler)_default_handler); return 0; err: return 1; } --- NEW FILE: hashxml.h --- #define HASH_HANDLE 0xD0BA46FC --- NEW FILE: xmltag.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-XML library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #define TAGSPACER ' ' /* Base class for XML tag */ function XMLTag( name ) local obj := map() obj:className := "XMLTag" obj:name := name obj:text := "" obj:offset := 0 obj:attributes := array(0) obj:parent := NIL obj:childs := array(0) obj:o := NIL _recover_XMLTAG(obj) return obj function _recover_XMLTAG( obj ) obj:getName := @xml_TagGetName() obj:addChild := @xml_TagAddChild() obj:removeChild := @xml_TagRemoveChild() obj:countChilds := @xml_TagCountChilds() obj:getChild := @xml_TagGetChild() obj:getChilds := @xml_TagGetChilds() obj:setAttribute := @xml_TagSetAttribute() obj:attribute := @xml_TagGetAttribute() obj:getAttributes := @xml_TagGetAttributes() obj:removeAttribute := @xml_TagRemoveAttribute() obj:setText := @xml_TagSetText() obj:getText := @xml_TagGetText() obj:getParent := @xml_TagGetParent() obj:dump := @xml_TagDump() obj:XPath := @xml_TagXPath() return obj /* Get tag name */ static function xml_TagGetName( self ) return self:name /* Add child tag */ static function xml_TagAddChild( self, tag, position ) if valtype(tag) != "O" .or. tag:className != "XMLTag" return .F. endif if empty(position) .or. self:countChilds() < position aadd( self:childs, tag ) else self:childs[ position ] := tag endif tag:parent := self return .T. /* Remove child tag by its number */ static function xml_TagRemoveChild( self, position ) if empty(position) .or. self:countChilds() > position return .F. endif adel( self:childs, position ) asize( self:childs, self:countChilds()-1 ) return .T. /* Number of child tags */ static function xml_TagCountChilds( self ) return len(self:childs) /* Get child tag by its number */ static function xml_TagGetChild( self, position ) if empty(position) .or. self:countChilds() > position return NIL endif return self:childs[ position ] /* Get all childs */ static function xml_TagGetChilds( self ) return self:childs /* Set tag attribute */ static function xml_TagSetAttribute( self, attrName, attrValue ) local p, sValue // Transform attrValue to string switch valtype(attrValue) case 'C' sValue := attrValue case 'N' sValue := ltrim( str( attrValue ) ) case 'L' sValue := iif( attrValue, "true", "false" ) case 'D' sValue := dtoc( attrValue ) otherwise sValue := attrValue endswitch // Lookup attribute name p := ascan( self:attributes, {|e| e[1]==attrName } ) if p == 0 aadd( self:attributes,{ attrName, sValue } ) else self:attributes[ p ] := { attrName, sValue } endif //?? "set attribute", attrName, valtype(sValue), chr(10) return .T. /* Get attribute value */ static function xml_TagGetAttribute( self, attrName, defVal ) local p p := ascan( self:attributes, {|e| e[1]==attrName } ) if p == 0 return defVal endif return self:attributes[p][2] /* Get all attributes */ static function xml_TagGetAttributes( self ) return self:attributes /* Remove tag attribute */ static function xml_TagRemoveAttribute( self, attrName ) local p p := ascan( self:attributes, {|e| e[1]==attrName } ) if p == 0 return .F. endif adel( self:attributes, p ) asize( self:attributes, len(self:attributes)-1 ) return .T. /* Set tag text */ static function xml_TagSetText( self, text ) self:text := text return /* Get tag text */ static function xml_TagGetText( self ) return self:text /* Get parent of tag */ static function xml_TagGetParent( self ) return self:parent /* Dump tag and its childs */ static function xml_TagDump( self, encoding, level ) local indent:='', s:='', a, lastOffset:=1, hasInlineTags:=.F., ct, a2 //?? self:name,chr(10) // Set indentation if empty(level) level := 0 endif if level > 0 indent := replicate(TAGSPACER, level) endif //?? "attrs&\n" // Print tag and attributes s := indent + "<" + self:name + " " //?? self:attributes,chr(10) for a in self:attributes s += a[1] + '="' + xmlText( a[2] ) + '" ' next //?? "childs&\n" if len(self:childs) == 0 if .not. empty(self:text) s := rtrim(s) + ">" + xmlText( self:text ) + "</" + self:name + ">&\n" else s += "/>&\n" endif else s := rtrim(s) + ">" // Look for inline tags (mixed tags and text) for a in self:childs if a:offset > 0 hasInlineTags := .T. exit endif next if hasInlineTags for a in self:childs ct := ltrim( a:dump( encoding, level+1 ) ) ct := left( ct, len(ct)-1 ) if a:offset > 0 s += xmlText( substr( self:text, lastOffset, a:offset-lastOffset+1 ) ) lastOffset := a:offset endif s += ct next s += xmlText( substr(self:text, lastOffset+1 ) ) + "</" + self:name + ">&\n" else s += "&\n" for a in self:childs s += a:dump( encoding, level+1 ) next s += indent + xmlText( self:text ) + "</" + self:name + ">&\n" endif endif return s static function xmlText( text ) text := strtran( text, '&', '&' ) text := strtran( text, '>', '>' ) text := strtran( text, '<', '<' ) text := strtran( text, '"', '"' ) text := strtran( text, "'", ''' ) return text /* Get tag(s) by XPath */ static function xml_TagXPath( self, path ) return xml_XPath( self, path ) --- NEW FILE: xmltree.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-XML library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #include <clip-expat.ch> #define FILEBLOCK 1024 /* XMLTree class */ function XMLTree( encoding ) local obj := map() obj:className := "XMLTree" obj:encoding := iif( empty(encoding), "utf-8", encoding ) obj:error := "" obj:root := NIL _recover_XMLTREE(obj) return obj function _recover_XMLTREE( obj ) obj:parseFile := @xml_ParseFile() obj:parseString := @xml_ParseString() obj:getRoot := @xml_GetRoot() obj:setRoot := @xml_setRoot() obj:getError := @xml_GetError() obj:XPath := @xml_GetXPath() obj:dump := @xml_Dump() return obj /* Parse XML from file */ static function xml_ParseFile( self, filename ) local parser, file, buf:=space(1024), var, nRead // Create parser parser := xml_ParserCreate() // Set handler functions var:=map() var:ct := NIL var:pt := NIL var:root := NIL xml_SetUserData(parser, @var) xml_SetCharacterDataHandler( parser, @xml_handleText() ) xml_SetElementHandler( parser, @xml_handleElementStart(), @xml_handleElementEnd() ) file = fopen(filename) do while !fileeof(file) nRead := fread(file, @buf, 1024) // Parse buffer xml_Parse(parser, @buf, nRead, fileeof(file)) // Handle buffer if xml_GetErrorCode(parser) <> 0 self:error := xml_ErrorString(parser) + ; " at line "+alltrim( str(xml_GetCurrentLineNumber(parser)) ) + ; ", column "+alltrim( str(xml_GetCurrentColumnNumber(parser)) ) return .F. endif enddo // Close file and free Expat parser self:root := var:root fclose(file) xml_ParserFree(parser) return .T. /* Parse XML from string */ static function xml_ParseString( self, string ) local parser, var // Create parser parser := xml_ParserCreate() // Set handler functions var:=map() var:ct := NIL var:pt := NIL var:root := NIL xml_SetUserData(parser, @var) xml_SetCharacterDataHandler( parser, @xml_handleText() ) xml_SetElementHandler( parser, @xml_handleElementStart(), @xml_handleElementEnd() ) // Parse string xml_Parse(parser, string, len(string), .T.) // Handle buffer if xml_GetErrorCode(parser) <> 0 self:error := xml_ErrorString(parser) + ; " at line "+alltrim( str(xml_GetCurrentLineNumber(parser)) ) + ; ", column "+alltrim( str(xml_GetCurrentColumnNumber(parser)) ) return .F. endif // Free Expat parser self:root := var:root xml_ParserFree(parser) return .T. /* Get root tag */ static function xml_GetRoot( self ) return self:root /* Set XMLTag as root tag */ static function xml_SetRoot( self, tag ) if valtype(tag) != "O" .or. tag:className != "XMLTag" return NIL endif self:root := tag return tag /* Get parse error */ static function xml_GetError( self ) return self:error /* Get tag(s) by XPath */ static function xml_getXPath( self, path, tag ) local t:=NIL if valtype(tag) == "O" .and. tag:className == "XMLTag" t := tag else t := self:root endif return xml_XPath( t, path ) /* Dump tree as XML string */ static function xml_Dump( self, tag ) local t, s, header:="", localEncoding //?? valtype(self:root),chr(10) if valtype(tag) == "O" .and. tag:className == "XMLTag" t := tag elseif .not. empty(self:root) t := self:root header := '<?xml version="1.0" encoding="'+self:encoding+'" ?>'+chr(10)+chr(10) else return "" endif s := self:root:dump() // encode all file: s and self:encoding localEncoding := host_charset() //?? "BEFORE ",self:encoding, localEncoding,":", s, chr(10) if self:encoding != localEncoding s := translate_charset( localEncoding, self:encoding, s) endif //?? "AFTER", s, chr(10) s := header + s return s /**=========================================================================== Handler function for Expat */ /* Handler function for start tag */ function xml_handleElementStart( vUser, name, aAttr ) // Create new XMLTag object //?? "<"+name+">&\n" vUser:ct := XMLTag( name ) vUser:ct:parent := vUser:pt aeval( aAttr, {|e| e[2]:=translate_charset( "utf-8", host_charset(), e[2]) } ) vUser:ct:attributes := aAttr // Append child to parent tag if valtype(vUser:pt) == "O" .and. "CHILDS" $ vUser:pt aadd(vUser:pt:childs, vUser:ct) vUser:ct:offset := len(vUser:pt:text) else vUser:root := vUser:ct endif vUser:pt := vUser:ct return /* Handler function for close tag */ function xml_handleElementEnd( vUser, name ) vUser:pt := vUser:pt:parent vUser:ct := vUser:pt return /* Handler function for text processing */ function xml_handleText( vUser, sStr, nLen ) local s s := translate_charset( "utf-8", host_charset(), alltrim(sStr) ) /* if .not. empty(sStr) ?? "TEXT:", host_charset(), sStr, translate_charset( "utf-8", "koi8-r", alltrim(sStr) ), chr(10) endif */ if .not. empty(s) .and. .not. empty(vUser:ct) vUser:ct:text += s endif return --- NEW FILE: xpath.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-XML library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ /* This function support Xpath by following version: XML Path Language (XPath) Version 1.0 W3C Recommendation 16 November 1999 [...1043 lines suppressed...] childs := b:childs otherwise s := '[UNKNOWN]' if 'TOKEN' $ b switch valtype( b:token ) case 'C' s := '"' + b:token + '"' case 'N' s := alltrim( str( b:token ) ) case 'L' s := iif( b:token, '.T.', '.F.' ) endswitch endif endswitch ?? l + s + chr( 10 ) for cN in childs _xpath_dumpBlock( cN, level + 1 ) next return NIL |
From: Andrey C. <sku...@us...> - 2006-06-02 14:13:37
|
Update of /cvsroot/eas-dev/clip-xml/example In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv3697/example Log Message: Directory /cvsroot/eas-dev/clip-xml/example added to the repository |
From: Andrey C. <sku...@us...> - 2006-06-02 14:13:12
|
Update of /cvsroot/eas-dev/clip-ui/drivers In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv3665 Added Files: Makefile driver-gtk.prg driver-gtk2.prg Log Message: Add files --- NEW FILE: Makefile --- # This is a part of CLIP-UI library # # Copyright (C) 2003-2005 by E/AS Software Foundation # Author: Andrey Cherepanov <sk...@ea...> ifndef CLIPROOT CLIPROOT=$(shell cd ../../../../; pwd)/cliproot endif include $(CLIPROOT)/include/Makefile.inc CLIPINCLUDE = -I$(CLIPROOT)/include CLIP = $(CLIPROOT)/bin/clip OBJS = driver-gtk.po driver-gtk2.po .PHONY: all clean uninstall distclean all: $(OBJS) clean: rm -f $(OBJS) *.bak *.nm *.ex *.ppo *.dll.a *.log *.dll install: all mkdir -p $(DESTDIR)$(CLIPROOT)/lib/drivers $(CLIPROOT)/bin/clip_cp $(OBJS) $(DESTDIR)$(CLIPROOT)/lib/drivers uninstall: rm -f $(CLIPROOT)/lib/drivers/$(OBJS) distclean: clean dist: distclean driver-gtk.po: driver-gtk.prg $(CLIP) $(CLIPINCLUDE) -I../../clip-gtk -nw -p driver-gtk.prg || exit 0 driver-gtk2.po: driver-gtk2.prg $(CLIP) $(CLIPINCLUDE) -I../../clip-gtk2 -nw -p driver-gtk2.prg || exit 0 --- NEW FILE: driver-gtk.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-UI library */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Authors: */ /* Andrey Cherepanov <sk...@ea...> */ /* Igor Satsyuk <sa...@tu...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #include <clip-gtk.ch> #include "../clip-ui.ch" static drv := NIL /* GTK+ 1.x driver. */ [...1732 lines suppressed...] return cd static function conv_color_to_str(red, green, blue) local color := '#' if red > 0 color += ntoc((red + 1) / 256 - 1, 16, 2, '0') else color += '00' endif if green > 0 color += ntoc((green + 1) / 256 - 1, 16, 2, '0') else color += '00' endif if blue > 0 color += ntoc((blue + 1) / 256 - 1, 16, 2, '0') else color += '00' endif return color --- NEW FILE: driver-gtk2.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-UI library */ /* */ /* Copyright (C) 2005 by E/AS Software Foundation */ /* Authors: */ /* Andrey Cherepanov <sk...@ea...> */ /* Igor Satsyuk <sa...@tu...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #include <clip-gtk2.ch> //#include <gtk2-stock.ch> #include "../clip-ui.ch" static drv := NIL [...1780 lines suppressed...] return cd static function conv_color_to_str(red, green, blue) local color := '#' if red > 0 color += ntoc((red + 1) / 256 - 1, 16, 2, '0') else color += '00' endif if green > 0 color += ntoc((green + 1) / 256 - 1, 16, 2, '0') else color += '00' endif if blue > 0 color += ntoc((blue + 1) / 256 - 1, 16, 2, '0') else color += '00' endif return color |
From: Andrey C. <sku...@us...> - 2006-06-02 14:12:16
|
Update of /cvsroot/eas-dev/clip-ui/example In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv3248/example Added Files: Makefile form_ui.prg testWindow.xfl test_ui.prg Log Message: Add files --- NEW FILE: Makefile --- # CLIP-UI library examples Makefile # Copyright (C) 2003-2006, E/AS Software Foundation # Web: http://eas.lrn.ru ifndef CLIPROOT CLIPROOT=$(shell cd ../../../../; pwd)/cliproot endif include $(CLIPROOT)/include/Makefile.inc CLIPINCLUDE = -I$(CLIPROOT)/include CLIP = $(CLIPROOT)/bin/clip .SUFFIXES: .prg .o .po .PHONY: all clean # Widget tests PRG1=test_ui PRG2=form_ui LIBS=-lclip-ui -lclip-xml -lexpat EXTRALIBS= all: $(PRG1) $(PRG2) clean: rm -f *.o *.bak core* *core $(PRG1) $(PRG2) *.log *.nm *.ex *.exe $(OUTPUT) $(PRG1): test_ui.prg $(CLIP) -ewslM $(CLIPINCLUDE) test_ui.prg $(LIBS) $(EXTRALIBS) $(PRG2): form_ui.prg $(CLIP) -ewsl $(CLIPINCLUDE) form_ui.prg $(LIBS) $(EXTRALIBS) #.prg.o: # $(CLIP) -l $(CLIPINCLUDE) $< --- NEW FILE: form_ui.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-UI library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #include <clip-ui.ch> #define PRGVERSION "0.1.2.4" static ws, win function main() local i,form local fileName,driver local params := array(0) driver := "gtk" i := 1 while i <= pcount() if left(param(i),9) == "--driver=" driver := substr(param(i),10) elseif param(i) == "-driver" .and. i+1<=pcount() driver := param(i+1) i += 2 loop else aadd(params, param(i)) endif i++ enddo // Get fileName from parameters if len(params) == 0 ?? "Usage: ./form_ui [--driver=<DRIVER>] <form.xfl>&\n" CANCEL else fileName := params[1] endif /* Use driver for GTK+ 2.x */ ?? "Used driver: "+driver,chr(10) useDriver( driver ) ws := UIWorkSpace( params ) form := UIForm( fileName ) win := form:parseFile() if win == NIL CANCEL endif win:show() ws:run() ws:quit() return 0 --- NEW FILE: testWindow.xfl --- <?xml version="1.0" encoding="koi8-r" ?> <!-- Test interface form --> <!-- Web: http://eas.lrn.ru --> <form> <head> <call widget="mainWindow" method="setCaption"> <param><call method="getClipUIVersion" /></param> </call> </head> <interface> <widget class="mainWindow" name="mainWindow" label="clip-ui test form"> <!-- Menu --> <widget class="menuBar"> <widget class="popupMenu" name="journal_menu" label="&Journal"> <widget class="menuItem" label="&Payment orders" name="Menu.Bank.PaymentOrder.List"> <property name="icon" value="icons/journal_bank_pp.xpm"/> </widget> <widget class="menuItem" label="&Create payment order" name="Menu.Bank.PaymentOrder.Create"> <property name="icon" value="icons/doc_bank_pp.xpm"/> </widget> <widget class="menuSeparator"/> <widget class="menuItem" label="&Exit" name="Menu.Quit"/> </widget> <widget class="popupMenu" name="cfg_menu" label="&Settings"> <widget class="menuCheckedItem" name="showTB" label="Show &toolbar" /> <widget class="menuCheckedItem" name="showSB" label="Show &statusbar" /> <widget class="menuSeparator"/> <widget name="Settings" class="menuItem" label="&Configure..."/> </widget> </widget> <!-- Toolbar --> <widget class="toolBar" name="main_toolBar"> <widget name="TB.Bank.PaymentOrder.List" class="toolButton" label="Payment orders"> <property name="icon" value="icons/journal_bank_pp.xpm"/> </widget> <widget name="TB.Bank.PaymentOrder.Create" class="toolButton" label="Create payment order"> <property name="icon" value="icons/doc_bank_pp.xpm"/> </widget> <widget name="TB.Partner.List" class="toolButton" label="Partners"> <property name="icon" value="icons/reference_partner.xpm"/> </widget> </widget> <widget class="vsplitter"> <widget class="hsplitter"> <widget class="tree" > <column name="n1" title="N1"/> <column name="n2" title="N2"/> <property name="row" element="node1" value="'Node1', 'node1111'" /> <property name="row" element="node11" value="'Node2'" /> <property name="row" element="node2.node1" value="'Leaf1'" /> <property name="row" element="node3.node1" value="'Leaf2'" /> <property name="row" element="node5.node1" value="'Leaf5', 'Leaf5'" /> <property name="row" element="node4.node1.node3" value="'Leaf3'" /> <property name="row" element="node44.node11" value="'Leaf3333'" /> <property name="row" element="node55.node44" value="'Leaf333'" /> <property name="row" element=".node55" value="'Leaf33'" /> </widget> <widget class="table"> <column name="num" title="#"/> <column name="date" title="Date"/> <column name="payee" title="Payee"/> <column name="sum" title="Sum"/> <property name="altColor" value="#cbe8ff" /> <property name="row" element="1" value="'1','20.10.03','JSC "Lighthouse"','20000.00'" /> <property name="row" element="2" value="'2','20.10.03','JSC "Phoenix"','5689.20'" /> <property name="row" element="3" value="'3','21.10.03','JSC "Phoenix"','1500.00'" /> <property name="row" element="4" value="'4','25.10.03','JSC "Phoenix"','99.00'" /> </widget> </widget> <widget class="vbox"> <property name="spacing" value="3" /> <property name="padding" value="3" /> <widget name="tax" class="checkbox" label="Use &tax"> <property name="value" value="false" /> </widget> <widget class="radiogroup"> <widget class="radioButton" name="button1" label="button1" /> <widget class="radioButton" name="button2" label="button2" /> </widget> <widget class="slider" > <property name="value" value="10" /> <property name="range" value="5-60" /> <property name="step" value="5" /> </widget> <widget class="progressbar" label="Progress: " /> <widget class="hbox"> <property name="padding" value="3" /> <widget class="label" label="Payment order N "> <property name="font.style" value="bold" /> <property name="font.size" value="16" /> <property name="color.fg" value="#FF1790" /> </widget> <widget name="number" class="edit" label=""> <property name="geometry.width" value="50" /> <property name="value" value="11" /> </widget> <widget class="label" label=" from " /> <widget name="date" class="editdate" label=""> <property name="geometry.width" value="70" /> <property name="value" value="20.10.03" /> </widget> </widget> <widget name="color" class="editcolor" label=""> <property name="value" value="#91FF40" /> </widget> <widget name="file" class="editfilename" label=""> <property name="value" value="testWindow.xfl" /> </widget> <!-- Payer --> <widget class="frame" label="Payer"> <property name="color.bg" value="darkblue" /> <property name="type" value="raised" /> <widget class="vbox"> <property name="padding" value="3" /> <widget class="combobox" name="payer"> <property name="values" value="'JSC "Brown and son"'" /> </widget> </widget> </widget> <!-- Payee --> <widget class="frame" label="Payee"> <property name="type" value="sunken" /> <widget class="vbox"> <property name="padding" value="3" /> <widget class="combobox" name="payee"> <property name="values" value="'JSC "Lighthouse"','JSC "Ronal"','JSC "Porechnoye"'" /> <property name="selection" value="2" /> </widget> </widget> </widget> <!-- Sum --> <widget class="hbox"> <widget class="label" label="&Sum: " /> <widget class="edit" name="sum"> <property name="value" value="20000.00" /> <property name="color.base" value="#C2D2FF" /> <property name="color.bg" value="red" /> </widget> </widget> <widget class="label" label="Description:" /> <widget class="edittext" name="reason" > <property name="value" value="For delivered goods." /> </widget> <!-- Bottom panel --> <widget class="hbox"> <widget class="layout"> <widget class="button" name="save" label="Save" /> <widget class="button" name="print" label="Print" pos="60,0" /> <widget class="button" name="close" label="Close" pos="120,10" /> </widget> </widget> </widget> </widget> <!-- Statusbar --> <widget class="statusBar" name="main_statusBar" label="Ready." /> </widget> </interface> <!-- Widget properties --> <style> <property widget="mainWindow" name="geometry" value="600,550,35,15" /> <property widget="mainWindow" name="position" value="center" /> <property widget="mainWindow" name="icon" value="icons/eas-logo.xpm" /> </style> <!-- Actions --> <actions> <!-- System actions --> <rule> <event widget="Menu.Quit" signal="activate"/> <event widget="close" signal="activate"/> <action><call widget="mainWindow" method="close"/></action> </rule> <rule> <event widget="showTB" signal="activate"/> <action><call widget="main_toolBar" method="show"> <param><call widget="showTB" method="isChecked" /></param> </call> </action> </rule> <rule> <event widget="showSB" signal="activate"/> <action> <call widget="main_statusBar" method="show"> <param><call widget="showSB" method="isChecked" /></param> </call> </action> </rule> <rule> <event widget="TB.Bank.PaymentOrder.List" signal="clicked"/> <action><call method="qout"> <param value="List of payment orders" /></call> </action> </rule> <rule> <event widget="TB.Bank.PaymentOrder.Create" signal="clicked"/> <action><call method="qout"> <param value="Create payment order" /></call> </action> </rule> <rule> <event widget="Settings" signal="activate"/> <action><call method="Configuration"/></action> </rule> </actions> </form> --- NEW FILE: test_ui.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-UI library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #include <clip-ui.ch> /* Test of clip-ui library usage */ static ws static wnd := NIL, ww1, ww2 static childToolbar static timer, tbState, iteration /* Declaration */ local menu, i, sp, b, cff local journal_menu, action_menu, doc_menu local ref_menu, cfg_menu, window_menu, help_menu local main_tbar, statusbar local accel_group, driver local win := NIL, params:=array(0) driver := "gtk" for i:=1 to pcount() if left(param(i),9) == "--driver=" driver := substr(param(i),10) elseif param(i) == "-driver" .and. i+1<=pcount() driver := param(i+1) else aadd(params, param(i)) endif next /* Use driver for GTK+ 2.x */ ?? "Used driver: "+driver,chr(10) useDriver( driver ) /* create workspace */ ws := UIWorkSpace( params ) /*--------------------------------------------------------------------*/ /* create main window */ win := UIMainWindow("E/AS " + getClipUIVersion(), NIL, "mainWindow" ) // create menu of main window menu := UIMenu() journal_menu := UIPopupMenu() action_menu := UIPopupMenu() doc_menu := UIPopupMenu() ref_menu := UIPopupMenu() cfg_menu := UIPopupMenu() window_menu := UIPopupMenu() help_menu := UIPopupMenu() menu:add(,"&Journal", journal_menu) i := journal_menu:add( UIImage("icons/journal_bank_pp.xpm"),"&Payment orders", {|| qout("Payment orders") } ) journal_menu:disable(i) i := journal_menu:add( UIImage("icons/doc_bank_pp.xpm"),"&Create payment order", {|| qout("Create payment order") } ) journal_menu:add(,"Submenu",help_menu) help_menu:add(UIImage("icons/journal_bank_pp.xpm"),"Item",{|| qout("Item") }) help_menu:add(,"Item2",{|| qout("Item2") }) journal_menu:setKey(i,"F5") journal_menu:addSeparator() journal_menu:add(,"&Exit", @quit()) menu:add(,"&Settings", cfg_menu) cff := @cfg_menu win:widget["showTB"] := cfg_menu:addChecked(.T., "Show &toolbar", {|w,e| showToolBar(win, "showTB", cfg_menu) } ) win:widget["showSB"] := cfg_menu:addChecked(.T., "Show &statusbar", {|w,e| showStatusBar(win, "showSB", cfg_menu) } ) cfg_menu:addSeparator() cfg_menu:add(,"&Configure...", NIL) //journal_menu:clear() // ToolBars main_tbar := UIToolBar() main_tbar:addButton( UIImage("icons/journal_bank_pp.xpm"), "List of payment orders", {|| qout("List of payment orders") } ) main_tbar:addButton( UIImage("icons/doc_bank_pp.xpm"), "Create payment order", {|| qout("Create payment order") }) main_tbar:addSeparator() main_tbar:addButton( UIImage("icons/reference_partner.xpm"), "Partners", NIL ) //main_tbar:remove(1) statusbar := UIStatusBar() statusbar:setText("Ready.") win:setPanels( menu, main_tbar, statusbar ) win:setMDI() ww1 := UIDocument("Core widgets", win) /* Test widgets */ sp := UISplitter(SPLITTER_VERTICAL) ww1:add(sp, .T., .T.) sp:setPosition( 200 ) BankRefReq( sp ) b := UIVBox(,3,3) sp:addEnd(b) BankDocReq( ww1, b ) ww2 := UIChildWindow("", win) OtherWidget(ww2) ww1:show() ww2:setCaption("Other widgets") ww2:show() ww1:show() // Assign icon to window. win:setIcon( UIImage("icons/eas-logo.xpm") ) // Put window to screen center win:setPlacement( .T. ) // Set size to 600x450 win:setGeometry( { 600, 550, 35, 15 } ) //----------------------------------------------------------------------------- /* show window */ win:show() /* run infinitive application loop */ ws:run() ws:quit() /**================== FUNCTIONS ==================**/ static function quit() ws:quit() return 0 /* Show/hide tool bar */ static function showToolBar(window, id, menu) if window:toolbar != NIL if menu:isChecked(window:widget[id]) window:toolbar:show() else window:toolbar:hide() endif endif return 0 /* Show/hide status bar */ static function showStatusBar(window, id, menu) if window:statusbar != NIL if menu:isChecked(window:widget[id]) window:statusbar:show() else window:statusbar:hide() endif endif return 0 /* Tree and table widgets */ static function BankRefReq( sp ) local splitter, tree, table, vb local node66, node67 splitter := UISplitter(SPLITTER_HORIZONTAL) sp:add(splitter, .T., .T.) tree := UITree(, {"N1","N2"}) tree:setAction("selected",{|w,e| listEventTree(tree, e) }) splitter:add( tree ) table := UITable({"#","Date","Payee","Sum"}) table:setAltRowColor("#cbe8ff") // Fill tree and table updateTable(tree, table) node66 := tree:addNode({"Parent_Last"}) node67 := tree:addNode({"Last Leaf"},, node66) table:addRow({"8","25.10.03",'Last: JSC "Phoenix"',"99.00"}) vb := UIVbox() table:setAction("selected",{|w,e| listEvent(table, e) }) vb:add(table, .T., .T.) vb:addEnd(UIButton("&Update views", {|| updateTable(tree, table) })) splitter:addEnd( vb ) return NIL static function listEventTree(tree, c) ?? "Select in tree:",c,"(id =",tree:getSelectionId(),")",chr(10) return function listEvent(table, c) ?? "Select in table:",c,"(id =",table:getSelectionId(),")",chr(10) return function updateTable(tree, table) local pos local node1,node2,node3,node4,node5 local node11, node44, node55, node66, node67 // Tree data pos := tree:savePosition() ?? "Tree pos:", pos, chr(10) tree:clear() node1 := tree:addNode({"Node1", "node1111"}) node11 := tree:addNode({"Node2"}) node2 := tree:addNode({"Leaf1"},, node1) node3 := tree:addNode({"Leaf2"},, node1) node5 := tree:addNode({"Leaf5", "Leaf5"},, node1) node4 := tree:addNode({"Leaf3"},, node1, node3) node44 := tree:addNode({"Leaf3333"},, node11) node55 := tree:addNode({"Leaf333"},, node44) tree:restorePosition( pos ) // Table data pos := table:savePosition() ?? "Table pos:", pos, chr(10) table:clear() table:addRow({"1","20.10.03",'JSC "Lighthouse"',"20000.00"},"DB0101000588") table:addRow({"2","20.10.03",'JSC "Phoenix"',"5689.20"}) table:addRow({"3","21.10.03",'JSC "Phoenix"',"1500.00"}) table:addRow({"4","25.10.03",'JSC "Phoenix"',"99.00"}) table:addRow({"5","20.10.03",'JSC "Lighthouse"',"20000.00"},"DB0101000589") table:addRow({"6","20.10.03",'JSC "Phoenix"',"5689.20"}) table:addRow({"7","21.10.03",'JSC "Phoenix"',"1500.00"}) table:restorePosition( pos ) return /* Form widgets */ static function BankDocReq(w,grid) local drv, lab, data, top, bottomLine, sd, pol, plat, i, t, f1, f2, t1, t2, b1, b2, b3, e1, e2, cb1, cb2, sum, hbsum, rs, rg drv := getDriver() data := map() data:num := "11" data:date :="20.10" data:client := 'JSC "Brown and son"' data:sum := "20000.00" data:reason := "For delivered goods.&\n" for i:=1 to 10 data:reason += alltrim(str(i))+" line.&\n" next plat := map() plat:name := 'JSC "Brown and son"' plat:bank := 'JSC "MENATEP"' plat:bankCity := "Krasnoyarsk" plat:BIK := "54521724647" plat:korAccount := "86768348914" plat:account := "7683187443445276" plat:INN := "1234567890" pol := map() pol:name := 'JSC "Lighthouse"' pol:bank := 'JSC "MENATEP"' pol:bankCity := "Moscow" pol:BIK := "54521724647" pol:korAccount := "86768348914" pol:account := "7683187443445276" pol:INN := "1212145436" w:setName("usetax",grid:add(UICheckBox(.F.,"Use &tax"))) rg := UIRadioGroup() w:setName("button1", grid:add(rg:addButton("button1"))) w:setName("button2", grid:add(rg:addButton("button2"))) // Slider sd := UISlider(10, 5, 60, 5) w:setName("slider", grid:add(sd)) // Title top := UIHBox(,0,3) lab := UILabel("Payment order N ") drv:setStyle(lab,"font.style","bold") drv:setStyle(lab,"font.size","14") drv:setStyle(lab,"color.bg","red") drv:setStyle(lab,"color.light","white") drv:setStyle(lab,"color.dark","white") drv:setStyle(lab,"color.mid","white") drv:setStyle(lab,"color.text","white") drv:setStyle(lab,"color.base","white") drv:setStyle(lab,"color.white","white") drv:setStyle(lab,"color.fg","#FF1790") // drv:setStyle(lab,"color.text","blue") // drv:setStyle(lab,"color.bg","#ff0000") // drv:setStyle(lab,"color.base","#0000ff") top:add(lab) e1 := UIEdit() e1:setValue(data:num) e1:setGeometry(50) e1:readOnly() w:setName("number", e1) drv:setStyle(top, "background", "icons/tick.xpm") top:add(e1) top:add(UILabel(" from ")) e2 := UIEditDate() e2:setValue(data:date) e2:appendText(".2005") w:setFocus(e2) e2:setGeometry(75) w:setName("date", e2) top:add(e2) grid:add(top) // Payer f1 := UIFrame() grid:add(f1) drv:setStyle(f1,"color.bg","darkblue") f1:setLabel("Payer") f1:setType(FRAME_RAISED) t1 := UIVBox(,,3) f1:add( t1 ) cb1 := UIComboBox({'JSC "Brown and son"'},1) w:setName("payer", cb1) t1:add(cb1) // Payee f2 := UIFrame("Payee",FRAME_SUNKEN) grid:add(f2) t2 := UIVBox(,,3) f2:add( t2 ) cb2 := UIComboBox() cb2:setList({'JSC "Lighthouse"','JSC "Ronal"','JSC "Porechnoye"'}) cb2:setValue(2) cb2:setValueInList(.T.) w:setName("payee", cb2) t2:add(cb2) // Sum hbsum := UIHBox(,3) hbsum:add(UILabel("&Sum: ")) sum := UIEdit(data:sum) drv:setStyle(sum,"color.base","#C2D2FF") drv:setStyle(sum,"color.bg","red") w:setName("sum", sum) hbsum:add(sum) hbsum:add(w:setName("tax", UILabel(""))) grid:add(hbsum) // Fill tax calculation sum:setAction("changed", {|| fieldChanged(w) }) fieldChanged(w) grid:add(UILabel("Description:")) rs := UIEditText(data:reason) rs:appendText("&\nEND.") rs:setGeometry({,30}) w:setName("reason", rs) grid:add(rs, .T., .T.) // Bottom panel bottomLine := w:actions b1 := UIButton( "Save", {|o,e| pp_save(w) } ) b2 := UIButton( "Print", {|| w:dialogBox("Print","Print function isn't implemented yet.","'Ok','Cancel'",NIL,NIL,IMG_OK) } ) b3 := UIButton( "Close", {|o,e| w_close(w) } ) bottomLine:add(b1) bottomLine:add(b2) bottomLine:add(b3) return NIL /* Close specified window */ static function w_close(window) window:close() return 0 /* Show all stored values from document */ static function pp_save(wnd) local val,i val := wnd:getValues() ?? "Form values:"+CHR(10) for i in val ?? CHR(9)+i[1]+" =",i[2],CHR(10) next return 0 static function fieldChanged(win) local s, tax, label, i if valtype(win) != 'O' return endif s := win:val("sum") tax := round(val(s)*0.2,2) label := iif("tax" $ win:value,win:value["tax"],NIL) tax := alltrim(str(tax)) if valtype(label) == 'O' label:setText("Tax: "+tax) endif return static function OtherWidget(w) local hp, pb, bt, percent := 0, lt, g, co, fn, tg, t, tl, tb hp := UIHBox(,3) hp:setPadding(5) hp:add(UILabel("Predefined icons:")) hp:add(UIImage(1)) hp:add(UIImage(2)) hp:add(UIImage(3)) hp:add(UIImage(4)) hp:add(UIImage(5)) // Layout lt := UILayout() hp:add(lt) // Progress Bar pb := UIProgressBar("Progress Bar") lt:add(pb) bt := UIButton( "Change ProgressBar", {|o,e| percent += 0.05, percent := iif(percent > 1, 0, percent),; pb:setPercent(percent, "Progress: "+alltrim(str(percent*100,0))+" %") } ) lt:add(bt, "10,30") w:add( hp ) g := UIHBox(,5) // Get FileName g:add(UILabel("File name: ")) fn := UIEditFileName('') g:add(fn) // Get Color g:add(UILabel("Color: ")) co := UIEditColor('#91FF40') co:setGeometry(60) g:add(co) w:add( g ) // Timer tg := UIHBox(,5) tg:add(UILabel("Timer:")) tl := UILabel("<time>") tbState := 0 timer := NIL tb := UIButton("Start timer", {|| startTimer(tb, tl) }) tg:add(tl) tg:add(tb) w:add( tg ) return /* Start timer */ static function startTimer(tb, tl) if tbState == 0 // start tbState := 1 tb:setText("Stop timer") if empty(timer) timer := UITimer(1, {|| timerEvent(tl) }) else timer:start() endif iteration := 0 else // stop tbState := 0 tb:setText("Start timer") if .not. empty(timer) timer:stop() endif endif return /* Timer event */ static function timerEvent(l) local t, w iteration++ if iteration == 15 w := getMainWindow() if .not. empty(w) w:dialogBox("Timer","Timer works 15 seconds.","'Ok'",NIL,NIL,IMG_OK) else ?? "getMainWindow failed.&\n" endif endif t := time() ?? "Event:", t, chr(10) l:setText(t) return |
Update of /cvsroot/eas-dev/clip-ui In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv3248 Added Files: AUTHORS ChangeLog LICENSE Makefile.in TODO button.prg checkbox.prg clip-ui.ch color.prg combobox.prg configure edit.prg font.prg form.prg frame.prg grid.prg image.prg label.prg layout.prg menu.prg progressbar.prg project.kateproject radiobutton.prg slider.prg special.prg table.prg timer.prg toolbar.prg tree.prg utils.prg window.prg workspace.prg Log Message: Add files --- NEW FILE: AUTHORS --- Andrey (Skull) Cherepanov <sk...@ea...> Igor Satsyuk <sa...@tu...> --- NEW FILE: ChangeLog --- 2006-06-02 - UIGrid: add expand flags to pos (+ at axes end) - small fixes in UIForm - UIFont now supports font size in form +XX or -XX 2006-04-06 clip-ui 0.1.2.4 - configure stript - remove XMLTag() and use clip-xml for XML parsing 2005-11-14 clip-ui 0.1.2.3 - new methods: UIButton: setText() UITable: savePosition(), restorePosition() UITree: savePosition(), restorePosition() - new function: getMainWindow() - fix alignment for UIGrid - UIForm support "Image" widget class (UIImage) 2005-07-01 - FIX: put in scrolled window by gtk_ScrolledWindowAddWithViewport() 2005-04-04 - new classes: UIEditColor, UIEditDate, UIEditFileName - methods: setFocus() [UIChildWindow,UIDocument], setAction() [UIWorkSpace] - support signal names in setAction() methods 2005-03-18 - new predefined icons: IMG_WARNING, IMG_QUESTION - new classes: UILayout, UIProgressBar, UIRadioGroup, UIRadioButton, UISlider, UITableItem, UITreeItem - new methods: appendText() [UIEdit,UIEditText], setCaption() [UIChildWindow] 2005-02-25 clip-ui 0.1.2.2 - new function useDriver() for driver choose - new driver: gtk2 (GTK+ 2.xx driver) 2005-02-03 - fix Makefile 2005-02-01 - new method setAction() for UIEdit/UIEditText (on changed) 2005-01-31 - new method clear() in UIMenuBar/UIPopupMenu/UIToolBar --- NEW FILE: LICENSE --- GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS --- NEW FILE: Makefile.in --- # This is a part of CLIP-UI library # # Copyright (C) 2003 by E/AS Software Foundation # Author: Andrey Cherepanov <sk...@ea...> ifndef CLIPROOT CLIPROOT=$(shell cd ../../../; pwd)/cliproot endif include $(CLIPROOT)/include/Makefile.inc DRIVERSDIR = $(DESTDIR)$(CLIPROOT)/lib/drivers CLIPINCLUDE = -I$(CLIPROOT)/include CLIP = $(CLIPROOT)/bin/clip .SUFFIXES: .prg .o .po # Here you can define appropriate compile settings #C_FLAGS=-Wall -g -I. $(CLIPINCLUDE) #CC=gcc TARGET = libclip-ui$(DLLSUFF) RTARGET = libclip-ui$(DLLREALSUFF) OBJS = button.o checkbox.o color.o combobox.o edit.o font.o form.o \ frame.o grid.o image.o label.o layout.o menu.o \ progressbar.o radiobutton.o slider.o special.o table.o timer.o \ toolbar.o tree.o utils.o window.o workspace.o .PHONY: all clean uninstall distclean all: var.ch driver $(TARGET) var.ch: echo "#define DRIVERSDIR \"$(DRIVERSDIR)\"" >var.ch driver: cd drivers && $(MAKE) all $(TARGET): $(OBJS) $(CLIPROOT)/bin/clip_makeslib $(TARGET) $(OBJS) clean: cd drivers && $(MAKE) clean cd example && $(MAKE) clean rm -f Makefile $(OBJS) $(TARGET) var.ch *.bak *.nm *.ex *.ppo *.dll.a *.log *.dll clear: clean install: all cd drivers && $(MAKE) install mkdir -p $(DESTDIR)$(CLIPROOT)/lib mkdir -p $(DESTDIR)$(CLIPROOT)/include $(CLIPROOT)/bin/clip_cp $(TARGET) $(DESTDIR)$(CLIPROOT)/lib $(CLIPROOT)/bin/clip_cp $(RTARGET) $(DESTDIR)$(CLIPROOT)/lib $(CLIPROOT)/bin/clip_cp clip-ui.ch $(DESTDIR)$(CLIPROOT)/include mkdir -p $(DESTDIR)$(CLIPROOT)/doc/example/clip-ui cp -R example/* $(DESTDIR)$(CLIPROOT)/doc/example/clip-ui/ uninstall: cd drivers && $(MAKE) uninstall rm -rf $(CLIPROOT)/lib/$(TARGET) $(CLIPROOT)/lib/$(RTARGET) $(CLIPROOT)/doc/example/clip-ui/ rm -f $(CLIPROOT)/include/clip-ui.ch distclean: clean dist: distclean cd .. && tar cvfz clip-ui.tgz clip-ui .prg.o: clip-ui.ch $(CLIP) -w $(CLIPINCLUDE) $< commit: _cvs commit update: _cvs update -dP ucommit: _cvs update -dP && _cvs commit shell: sh --- NEW FILE: TODO --- TODO ==== Last change: 06 Apr 2006 CLIP-UI ------- - Debug function for UIForm and debug lebel for library (possible, CLIP-wide) - Spreadsheet widget - Set slot functions for window open, activation, close - New widgets: - UIChoice (for select object) - UITab - DnD methods for UITable/UITree - Deletion of widget from comtainers - Disallow editing in UIComboBox field - Using ID in UIComboBox - gtk_ScrolledWindowNew() make child widget too small - sent command line parameters to gtk_Init() - Default selection needed for UIComboBox in forms - usablity issues for UISlider: value should be step multiple, step indication under slider - icons for UIChildWindow - wrong setFocus() behaviour for widgets in UIChildWindow/UIDocument - UIEditDate should display calendar in popup window - UIEditDate: date should be selected by keyboard - add method setProperty() for each widget - calendar for UIDateEdit should be placed in popup window with buttons 'select' and 'close' FORM ---- - debug unclosed tags (<form /></form>) - "alignment.vertical" and "alignment.horizonal" widget properties - program for test form (include child window too) - fix bug in HTTP parser with unknown locales (C, ru_RU.UTF-8) - empty tag names GTK --- - Input numero sign or typographic quotes - unscrollable position of column header (GTK/GTK2) Documentation ------------- - separate section "CLIP-UI" in CLIP documentation - XFL format description - list support (and any other Docbook tags) in .txt class/funcs description files - UIDriver class - full attribute list of window classes ------------------------------------------------------------------------------- See TODOs on web-site: http://eas.lrn.ru/index.php?module=request (on Russian) ------------------------------------------------------------------------------- --- NEW FILE: button.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-UI library */ /* */ /* Copyright (C) 2003 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ static driver := getDriver() /* Button class */ function UIButton( label, action, val ) local obj := driver:createButton(label, action) obj:className := "UIButton" obj:val := val _recover_UIBUTTON(obj) return obj function _recover_UIBUTTON( obj ) obj:setText := @ui_setText() obj:setAction := @ui_setAction() obj:setPadding := @ui_setPadding() obj:setValue := @ui_setValue() obj:getValue := @ui_getValue() return obj /* Button bar class */ function UIButtonBar() local obj := UIHBox(, 5, 3 ) obj:className := "UIButtonBar" obj:setEqualSize( .T. ) obj:setAlignment( 0 ) return obj /* Change button label */ static function ui_setText(self, text) driver:setButtonText(self, text) return NIL /* Connect action to button */ static function ui_setAction(self, signal, action) if signal=='clicked' .and. valtype(action)=='B' driver:setAction( self, "clicked", action) driver:enableWidget( self, .T. ) endif return NIL /* Set button padding */ static function ui_setPadding(self, padding) driver:setPadding( self, padding ) return NIL /* Set value */ static function ui_setValue(self, value) self:val := value return NIL /* Get value */ static function ui_getValue(self) return self:val --- NEW FILE: checkbox.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-UI library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ static driver := getDriver() /* Checkbox class */ function UICheckBox( value, label ) local obj := driver:createCheckBox(value, label) obj:className := "UICheckBox" _recover_UICHECKBOX(obj) return obj function _recover_UICHECKBOX( obj ) obj:setValue := @ui_setValue() obj:getValue := @ui_getValue() return obj /* Set value */ static function ui_setValue(self, value) driver:setValue( self, value ) return NIL /* Get value */ static function ui_getValue(self) return driver:getValue( self ) --- NEW FILE: clip-ui.ch --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-UI library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ /* Header file for common CLIP-UI definition */ #define lib_version "0.1.2.4" /* Default driver name */ #define DEFAULT_DRIVER "gtk" /* Page settings for UIPrinter. TODO: need to move in client sources */ /* Measurement units */ #define PRINT_PT 0 #define PRINT_CM 1 #define PRINT_MM 2 #define PRINT_INCH 3 /* Page orientation */ #define PAGE_PORTRAIT 0 #define PAGE_LANDSCAPE 1 /* Page size */ #define PAGE_A4 0 /* Cell anchoring */ #define CELL_ABOVE 0 #define CELL_BELOW 1 #define CELL_LEFT 2 #define CELL_RIGHT 3 /* Cell align */ #define ALIGN_LEFT 0 #define ALIGN_CENTER 1 #define ALIGN_RIGHT 2 #define ALIGN_JUSTIFY 3 #define ALIGN_TOP 0 #define ALIGN_MIDDLE 1 #define ALIGN_BOTTOM 2 /* Cell side anchoring */ #define CELL_SIDE_BOTTOM 0 #define CELL_SIDE_LEFT 1 /* Points in mm */ /* Note: if you use ps2pdf command for covert to PDF PT_IN_MM is equal 2.946 */ /* PT_MARGIN is 12 */ #define PT_IN_MM 2.83465 #define PT_MARGIN 0 /* COLOR */ #define ALT_TABLE_ROW_COLOR "#eef6ff" /* Preview programs */ #define WINDOWS_PRINT_PREVIEW "start" #define UNIX_PRINT_PREVIEW "ggv" /* SPLITTER DIRECTION */ #define SPLITTER_HORIZONTAL 0 #define SPLITTER_VERTICAL 1 /* IMAGES */ #define IMG_EMPTY 1 // Empty transparent pixmap #define IMG_OK 2 // i #define IMG_ERROR 3 // Error (cross on red field) #define IMG_WARNING 4 // Exclamation mark #define IMG_QUESTION 5 // ? /* FRAME TYPES */ #define FRAME_PLAIN 0 #define FRAME_SUNKEN 1 #define FRAME_RAISED 2 #define FRAME_IN 3 #define FRAME_OUT 4 --- NEW FILE: color.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-UI library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ static driver := getDriver() /* UIColor class */ function UIColor( color, opacity ) local r, g, b, o local obj := map() color := iif(empty(color),"#000000",color) if left(color,1) != '#' obj = driver:colorParse(color) else o := iif(empty(opacity),255,opacity) r := cton(substr(color,2,2),16) g := cton(substr(color,4,2),16) b := cton(substr(color,6,2),16) obj:red := iif(r==0,0,(r+1)*256-1) obj:green := iif(g==0,0,(g+1)*256-1) obj:blue := iif(b==0,0,(b+1)*256-1) obj:opacity := iif(o==0,0,(o+1)*256-1) endif obj:className := "UIColor" return obj --- NEW FILE: combobox.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-UI library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ static driver := getDriver() /* Combobox class */ function UIComboBox( values, defaultItem ) local obj := driver:createComboBox( values ) obj:className := "UIComboBox" obj:list := values _recover_UICOMBOBOX(obj) if .not. empty( defaultItem ) driver:setValue( obj, defaultItem ) endif return obj function _recover_UICOMBOBOX( obj ) obj:setList := @ui_setList() obj:setValue := @ui_setValue() obj:getValue := @ui_getValue() obj:setValueInList := @ui_setValueInList() return obj /* Set list of strings */ static function ui_setList(self, values) self:list := values driver:setComboBoxList( self, values ) return NIL /* Set value */ static function ui_setValue(self, value) driver:setValue( self, value ) return NIL /* Get value */ static function ui_getValue(self) return driver:getValue( self ) /* Value entered in the text entry field must match one of the values in the list */ static function ui_setValueInList(self, flag) return driver:setComboBoxValueInList(self, flag) --- NEW FILE: configure --- #!/bin/sh libdir="$CLIPROOT/lib" if [ ! -f "$libdir/libclip-xml.so" ] then echo "Warning: library clip-xml does not installed on your system" exit 1 fi cp Makefile.in Makefile exit 0 --- NEW FILE: edit.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-UI library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ static driver := getDriver() /* TODO: control wordwrap for UIEditText */ /* EditText class */ function UIEdit(value) local obj := driver:createEdit() obj:className := "UIEdit" _recover_UIEDIT(obj) obj:setValue( value ) obj:setPassword := @ui_editSetPassword() return obj /* EditText class */ function UIEditText(value) local obj := driver:createEditText(value) obj:className := "UIEditText" if .not. empty(value) ui_setValue(obj, value) endif _recover_UIEDIT(obj) return obj function _recover_UIEDIT( obj ) obj:getGeometry := @ui_getGeometry() obj:setGeometry := @ui_setGeometry() obj:setValue := @ui_setValue() obj:getValue := @ui_getValue() obj:readOnly := @ui_setReadOnly() obj:setAction := @ui_setEditAction() obj:appendText := @ui_appendText() return obj /* Get widget geometry: position and size */ static function ui_getGeometry( self ) local geom geom := driver:getGeometry( self ) return( geom ) /* Set widget geometry: position and size */ static function ui_setGeometry( self, geom ) driver:setGeometry( self, geom ) return NIL /* Set value */ static function ui_setValue(self, value) driver:setValue( self, val2str(value) ) return NIL /* Get value */ static function ui_getValue(self) return driver:getValue( self ) /* Set state to read-only */ static function ui_setReadOnly(self, flag) if empty(flag) flag := .T. endif driver:editSetReadOnly(self,flag) return /* Set state to password mode (if TRUE) */ static function ui_editSetPassword(self, flag) flag := iif(valtype(flag)=="U",.T.,flag) driver:editSetPassword(self,flag) return /* Set action for edit entry */ static function ui_setEditAction(self, signal, action) if signal=='changed' .and. valtype(action)=='B' driver:setAction( self, "changed", action) endif return .T. /* Append text to the end of current text */ static function ui_appendText(self, text) driver:setValue( self, val2str(text), .T.) return .T. /* EditDate class */ function UIEditDate(value, caption) local button, obj obj := UIEdit(value) caption := iif(empty(caption),"Select Date",caption) button := UIButton("...", {|| driver:showCalendar(caption, obj:getValue(), obj) }) obj:stick := map() obj:stick:right := button return obj /* EditFileName class */ function UIEditFileName(value, caption) local button, obj obj := UIEdit(value) caption := iif(empty(caption),"Select File",caption) button := UIButton("...", {|| driver:selectFileName(caption, obj:getValue(), obj) }) obj:stick := map() obj:stick:right := button return obj /* EditColor class */ function UIEditColor(value, caption) local button, obj obj := UIEdit(value) caption := iif(empty(caption),"Select Color",caption) button := UIButton("...", {|| driver:selectColor(caption, obj:getValue(), obj) }) obj:stick := map() obj:stick:right := button return obj /* EditNumber class */ /*????*/ /* EditReference class */ /*????*/ --- NEW FILE: font.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-UI library */ /* */ /* Copyright (C) 2004-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ static driver := getDriver() /* UIFont class */ function UIFont( family, style, size, encoding ) local obj := map() obj:className := "UIFont" obj:font := "" obj:family := family obj:style := style obj:size := size obj:encoding := encoding _recover_UIFONT(obj) if driver:driver == "gtk" if left(family,1) == '-' obj:font := obj:parseFont( family ) else obj:font := obj:parseFont() endif else if style == NIL .and. size == NIL obj:font := obj:parseFont2( family ) else obj:font := obj:parseFont2() endif endif return obj function _recover_UIFONT( obj ) obj:setProperty := @ui_setProperty() obj:parseFont := @ui_parseFont() obj:parseFont2 := @ui_parseFont2() return obj /* Set property for font */ static function ui_setProperty(self, property, value) switch upper(property) case 'FAMILY' self:family := value case 'STYLE' self:style := value case 'SIZE' //?? "Size before:", valtype(self:size), self:size,chr(10) if empty(self:size) self:size := 10 endif if valtype( value ) == 'C' if left( value, 1 ) == '+' value := self:size + val(substr(value,2))*2 elseif left( value, 1 ) == '-' value := self:size - val(substr(value,2))*2 else value := val( value ) endif endif self:size := value case 'ENCODING' self:encoding := value endswitch if driver:driver == "gtk" self:font := self:parseFont() else self:font := self:parseFont2() endif //?? "NEW FONT:", self:font,chr(10) return /* Parse font (XWindow font name) */ static function ui_parseFont(self, string) local a, ff, fn, fs, fe, lang if .not. empty(string) // Font string like -monotype-arial-medium-r-normal--12-0-0-0-p-0-koi8-r a = split(string,'-') self:family := a[3] if a[4] == 'bold' self:style := 'bold' if a[5] == 'i' self:style := 'bolditalic' endif elseif a[5] == 'i' self:style := 'italic' else self:style := 'normal' endif self:size := val(a[9])/10 self:encoding := a[14]+'-'+a[15] return string else // Composite font ff := iif( empty(self:family), 'helvetica', self:family ) fn := iif( empty(self:style), 'normal', lower(self:style) ) fs := iif( empty(self:size), '', alltrim(str(self:size)) ) lang := split(getenv("LANG"),'\.') if len(lang) > 1 fe := lower(lang[2]) else fe := 'iso8859-1' endif string := '-*-'+ff+'-'+iif(left(fn,4)=='bold','bold','medium') string += '-'+iif(right(fn,6)=='italic','i','r')+'-'+'normal'+'-' string += '-'+fs+'-*-*-*-*-*-'+fe return string endif return /* Parse font (GTK2 font name) */ static function ui_parseFont2(self, string) local a, l, i, ff, fn, fs, fe if .not. empty(string) // Font string like "Sans Medium 10" a = split(string,' ') l := len(a) if l == 2 // Only family and size self:style := "Medium" else self:style := a[l-1] adel(a, l-1) l := l-1 endif self:size := val(a[l]) l := l-1 self:family := "" for i:=1 to l self:family += " "+a[i] next self:family := alltrim(self:family) return string else // Composite font ff := iif( empty(self:family), 'Sans', self:family ) fn := iif( empty(self:style) .or. upper(self:style)=="NORMAL", 'Medium', lower(self:style) ) fs := iif( empty(self:size), '10', alltrim(str(self:size)) ) string := ff+" "+fn+" "+fs return string endif return --- NEW FILE: form.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-UI library */ /* */ /* Copyright (C) 2003-2006 by E/AS Software Foundation */ /* Authors: */ /* Andrey Cherepanov <sk...@ea...> */ /* Igor Satsyuk <sa...@tu...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #include "clip-ui.ch" #define DEBUG .F. static driver := getDriver() /* Interface form class */ function UIForm( fileName, parent ) local obj := map() obj:parent := parent obj:className := "UIForm" obj:fileName := fileName obj:oXml := NIL obj:widgets := map() obj:names := array(0) obj:actions := array(0) obj:src := NIL obj:locale := map() _recover_UIFORM(obj) return obj function _recover_UIFORM( obj ) obj:parseFile := @ui_parseFile() obj:parseString := @ui_parseString() obj:parse := @ui_parse() obj:createWidget := @ui_createWidget() obj:setProperty := @ui_setProperty() obj:getPropertyValue := @ui_getPropertyValue() obj:setAction := @ui_setAction() obj:setPreAction := @ui_setPreAction() obj:actionHandler := @ui_actionHandler() obj:subActionHandler := @ui_subActionHandler() obj:i18n := @ui_form_i18n() return obj /* Parse form from file */ static function ui_parseFile(self) local fileName fileName := self:fileName set translate path off if DEBUG ?? "UIForm: file parsing...&\n" endif // Parse file self:oXml := XMLTree() if .not. self:oXml:parseFile( fileName ) ?? "ERROR: Cannot open form file '"+fileName+"': "+self:oXml:getError()+chr(10) return NIL endif if DEBUG ?? "UIForm: file parsing complete&\n" endif return self:parse() /* Parse form from string */ static function ui_parseString(self, str) if DEBUG ?? "UIForm: string parsing...&\n" endif // Parse string self:oXml := XMLTree() if .not. self:oXml:parseString( str ) ?? "ERROR: Cannot open form file: "+self:oXml:getError()+chr(10) return NIL endif if DEBUG ?? "UIForm: string parsing complete&\n" endif return self:parse() /* Parse form */ static function ui_parse(self) local win := NIL, res, t, i if DEBUG ?? "UIForm: form parsing...&\n" endif if self:oXml:getRoot() == NIL ?? "ERROR: there isn't root element.&\n" return win else self:root := self:oXml:getRoot() endif /* Locale */ self:locale := getLocaleStrings(self:root) /* Root widget */ res := self:oXml:XPath("/interface/widget") if empty(res) .or. len(res) == 0 ?? "ERROR: no root widget!&\n" return NIL endif t := res[1] //?? "PARENT window for form: ",valtype(self:parent),chr(10) if DEBUG ?? "UIForm: create widgets...&\n" endif win := ui_createWidget(self, t, self:parent) if empty(win) return NIL endif if DEBUG ?? "UIForm: set properties...&\n" endif /* Set properties */ t := self:oXml:XPath("/style/*") for i in t ui_setProperty(self, i, NIL) next if DEBUG ?? "UIForm: set actions...&\n" endif /* Set actions */ t := self:oXml:XPath("/actions/*") for i in t ui_setAction(self, i, NIL) next if DEBUG ?? "UIForm: set preliminary actions...&\n" endif /* Set pre actions */ res := self:oXml:XPath("/head") if empty(res) .or. len(res) == 0 ?? "ERROR: no <head> tag!&\n" return NIL endif self:setPreAction(res[1], NIL) if DEBUG ?? "UIForm: form parsing complete&\n" endif return win /* Return created widget from tag */ static function ui_createWidget(self, tag, parent ) local o:=NIL, class, name, label, c, i, a, e, w, box, t:=tag local add:=.F., gCol:=1, gRow:=1, gClass, rule class := t:attribute("class","") name := t:attribute("name","") label := self:i18n( t:attribute("label","") ) rule := t:attribute("rule",NIL) switch upper(class) /* Grid */ case "HBOX" o := UIHBox() add := .T. case "VBOX" o := UIVBox() add := .T. case "HSPLITTER" o := UISplitter(SPLITTER_HORIZONTAL) add := .T. case "VSPLITTER" o := UISplitter(SPLITTER_VERTICAL) add := .T. case "GRID" gCol := val(getProperty(self:root, t, "cols")) gRow := val(getProperty(self:root, t, "rows")) o := UIGrid(, gRow, gCol) add := .T. case "LAYOUT" o := UILayout() add := .T. /* Widgets */ case "MAINWINDOW" o := UIMainWindow(label,name) self:w := o if empty(o) return NIL endif case "WINDOW" o := UIWindow(label,parent,name,.F.) self:w := o if empty(o) return NIL endif case "CHILDWINDOW" o := UIChildWindow(label,parent,name) self:w := o if empty(o) return NIL endif case "DOCUMENT" o := UIDocument(label,parent,name) self:w := o if empty(o) return NIL endif case "MENUBAR" o := UIMenu() parent:setPanels(o,,) case "MENUITEM" if ascan(t:childs,{|e| e:getName() == "widget" }) == 0 i := parent:add(,label,) o := parent:elem[i] endif case "MENUCHECKEDITEM" i := parent:addChecked(,label,NIL) o := parent:elem[i] case "POPUPMENU" o := UIPopupMenu() parent:add(,label,o) case "MENUSEPARATOR" parent:addSeparator() return NIL case "TOOLBAR" o := UIToolBar() parent:setPanels(,o,) case "TOOLBUTTON" i := parent:addButton(NIL,label,NIL) o := parent:elem[i] case "STATUSBAR" o := UIStatusBar() parent:setPanels(,,o) o:setText(label) case "TABLE" a := array(0) for e in t:getChilds() if e:getName() == "column" aadd( a, self:i18n(e:attribute("title",""))) endif next if len(a) > 0 o := UITable( a ) add = .T. else ?? "No defined columns for Table widget&\n" endif case "TREE" a := array(0) for e in t:getChilds() if e:getName() == "column" aadd( a, self:i18n(e:attribute("title",""))) endif next if len(a) > 0 o := UITree( 1, a ) add = .T. else ?? "No defined columns for Tree widget&\n" endif /* case "SHEET" a := array(0) for e in t:childs if e:name == "COLUMN" aadd( a, self:i18n(e:attr["TITLE"])) endif next o := UISheet( a ) add = .T. */ case "BUTTONBAR" if "ACTIONS" $ parent o := parent:actions else o := UIButtonBar( parent ) add = .T. endif case "BUTTON" o := UIButton( label, NIL) add = .T. case "LABEL" o := UILabel(label) add = .T. case "EDIT" o := UIEdit() add = .T. case "EDITTEXT" o := UIEditText() add = .T. case "EDITDATE" o := UIEditDate() add = .T. case "EDITFILENAME" o := UIEditFileName() add = .T. case "EDITCOLOR" o := UIEditColor() add = .T. case "CHECKBOX" o := UICheckBox(,label) add = .T. case "COMBOBOX" o := UIComboBox() add = .T. case "IMAGE" o := UIImage( iif(isfunction("GETRESOURCE"), ; clip("GETRESOURCE", label), label) ) add = .T. case "RADIOGROUP" o := UIRadioGroup() o:box := parent case "RADIOBUTTON" if parent:className == "UIRadioGroup" o := parent:addButton(label) parent := parent:box add = .T. else ?? "WARNING: radiobutton must be placed into radiogroup&\n" endif case "FRAME" o := UIFrame(label) add = .T. case "PROGRESSBAR" o := UIProgressBar(label) add = .T. case "SLIDER" o := UISlider() add = .T. otherwise ?? "WARNING: Unknown class:",class,chr(10) endswitch if .not. empty(name) aadd(self:names,name) self:widgets[name] := o if "W" $ self w := self:w w:setName(name,o) w:valueTypes[name] := t:attribute("type",NIL) endif endif if .not. empty(rule) .and. .not. empty(self:w) .and. "SYSMENUS" $ self:w self:w:sysMenus[rule] := o // ?? "SYSMENU:",rule,"=",valtype(o),chr(10) endif /* Add to grid */ if add == .T. gClass := iif("O" $ parent, parent:o, parent) box := iif("USERSPACE" $ parent,parent:userSpace,parent) if gClass:className == "UIGrid" .or. gClass:className == "UILayout" gRow := t:attribute("pos","") parent:add( o, gRow ) elseif gClass:className == "UISplitter" if empty( parent:first ) parent:add( o ) else parent:addEnd( o ) endif else if class=="table" .or. o:className=="UISplitter" .or. o:className=="UIEditText" box:add( o, .T., .T. ) else box:add( o, .F., iif(box:className=="UIButtonBar",.T.,.F.) ) endif endif endif t:o := o /* Loop child widgets */ if o == NIL o := parent endif for c in t:getChilds() if c:getName() == "widget" ui_createWidget(self, c, o) elseif c:getName() == "property" ui_setProperty(self, c, o) elseif c:getName() == "rule" ui_setAction(self, c, o) elseif ascan({"column"},{|ev| ev==c:getName()}) != 0 // Nothing do else ?? "WARNING: tag "+c:getName()+" is ignored&\n" endif next return o /* Set property for widget */ static function ui_setProperty(self, tag, obj, value) local class, name, widget, row, block, t:=tag, elem, node, nName, nParent, nSibling, nArr if t != NIL class := t:attribute("class","") name := t:attribute("name","") widget := t:attribute("widget","") value := iif(value==NIL,t:attribute("value",""),value) //?? name, value, chr(10) if ascan({"rows","cols"},{|ev| ev==name}) > 0 return .F. endif endif if DEBUG ?? "UIForm: setProperty() for "+widget+':'+name+' = '+value,chr(10) endif obj := iif(obj==NIL,mapget(self:widgets,widget,NIL),obj) if obj == NIL return .F. endif switch name case "altColor" if .not. "SETALTROWCOLOR" $ obj; return .F.; endif obj:setAltRowColor(value) case "label" if .not. "SETTEXT" $ obj; return .F.; endif obj:setText(value) case "value" if .not. "SETVALUE" $ obj; return .F.; endif if obj:className == "UICheckBox" if ascan({"YES","TRUE"}, {|ev| ev==upper(value)}) > 0 value := .T. elseif ascan({"NO","FALSE"}, {|ev| ev==upper(value)}) > 0 value := .F. else return .F. endif endif obj:setValue(value) case "geometry" if .not. "SETGEOMETRY" $ obj; return .F.; endif obj:setGeometry(splitGeom(value,4)) case "geometry.width" if .not. "SETGEOMETRY" $ obj; return .F.; endif obj:setGeometry(val(value)) case "geometry.height" if .not. "SETGEOMETRY" $ obj; return .F.; endif obj:setGeometry({,val(value)}) case "MDI" if .not. "SETMDI" $ obj; return .F.; endif if value == "true" obj:setMDI() endif case "spacing" if .not. "SETSPACING" $ obj; return .F.; endif obj:setSpacing(val(value)) case "padding" if .not. "SETPADDING" $ obj; return .F.; endif obj:setPadding(val(value)) case "position" if .not. "SETPLACEMENT" $ obj; return .F.; endif if value == "center" obj:setPlacement( .T. ) endif case "readOnly" if .not. "READONLY" $ obj; return .F.; endif if value == "true" obj:readOnly( .T. ) endif case "values" if .not. "SETLIST" $ obj; return .F.; endif block := "{|| {"+value+"} }" row := eval(&block) obj:setList( row ) case "selection" if obj:className != "UIComboBox"; return .F.; endif obj:setValue( val(value) ) case "type" if obj:className != "UIFrame"; return .F.; endif switch upper(value) case "PLAIN" obj:setType(FRAME_PLAIN) case "RAISED" obj:setType(FRAME_RAISED) case "SUNKEN" obj:setType(FRAME_SUNKEN) case "IN" obj:setType(FRAME_IN) case "OUT" obj:setType(FRAME_OUT) endswitch case "icon" if .not. "SETICON" $ obj; return .F.; endif obj:setIcon(UIImage( iif(isfunction("GETRESOURCE"), ; clip("GETRESOURCE", value), value) ) ) case "row" if obj:className != 'UITable' .and. obj:className != 'UITree'; return .F.; endif block := "{|| {"+value+"} }" row := eval(&block) elem := t:attribute("element",NIL) if obj:className == 'UITable' obj:addRow( row, elem ) else if .not. 'NODENAMES' $ obj obj:nodeNames := map() endif nArr := split(elem, "\.") nName := '' nParent := NIL nSibling := NIL switch len(nArr) case 1 nName := nArr[1] case 2 nName := nArr[1] nParent := mapget(obj:nodeNames,nArr[2],NIL) case 3 nName := nArr[1] nParent := mapget(obj:nodeNames,nArr[2],NIL) nSibling := mapget(obj:nodeNames,nArr[3],NIL) endswitch //?? nArr, nName, nParent, nSibling,chr(10) obj:nodeNames[nName] := obj:addNode (row, nName, nParent, nSibling) // (columns,id,parent,sibling) endif case "range" if obj:className != "UISlider"; return .F.; endif obj:setRange(value) case "step" if obj:className != "UISlider"; return .F.; endif obj:setStep(value) otherwise driver:setStyle(obj, name, value, t:attribute("element",NIL)) endswitch return .T. /* Get property value. Lookup under current tag and style */ static function getProperty(tree, obj, name, def) local e, widget, class, ret:=def if valtype(obj) != "O" .or. obj:className != "XMLTag" ?? "ERROR: object is broken&\n" return def endif // Child properties widget := obj:attribute("name","") for e in obj:getChilds() if e:attribute("name","")==name ret := e:attribute("value",def) endif next return ret /* Return widget property value */ static function ui_getPropertyValue(self, tagObj) local val:=NIL, widget, prop, obj if valtype(tagObj) != "O" .or. tagObj:className != "XMLTag" ?? "ERROR: object is broken&\n" return NIL endif widget := tagObj:attribute("widget","") prop := tagObj:attribute("name","") obj := mapget(self:widgets,widget,NIL) if empty(obj) ?? "ERROR get property for widget '"+widget+"': widget not found&\n" return NIL endif if prop == "object" return obj endif if obj:className == "UIMenuItem" .and. prop == "isChecked" return driver:isCheckedMenuItem( obj ) endif return val /* Set action for widget */ static function ui_setAction(self, tag, lObj) local e, obj, widget, signal, events, actions, j, id, labelRule, t:=tag local cWidget if t:getName() != "rule" ?? "WARNING: rule tag must be <rule>. Rule is ignored.&\n" return .F. endif if len(t:getChilds()) == 0 ?? "WARNING: rule is empty. Ignored.&\n" return .F. endif // TODO: labelled form rule support on menu labelRule := self:i18n( t:attribute("label",NIL) ) if .not. empty(labelRule) // ?? "Action:",labelRule,chr(10) endif // Retrieve data events := array(0) actions := array(0) for e in t:getChilds() if e:getName() == "event" // Event condition widget := e:attribute("widget","") signal := e:attribute("signal","") obj := iif(lObj==NIL,mapget(self:widgets,widget,NIL),lObj) if obj == NIL .or. empty(widget) .or. empty(signal) ?? "WARNING: widget '"+widget+"' is not found. Ignored&\n" return .F. endif aadd(events,{ obj, signal }) elseif e:getName() == "action" // Actions if len(events) == 0 ?? "WARNING: condition is not found. Ignored&\n" return .F. endif for j in e:getChilds() widget := j:attribute("widget",NIL) /*if valtype(widget) == 'C' cWidget := widget elseif valtype(widget) == 'O' cWidget := '{'+widget:className+'}' else cWidget := '<unknown>' endif //?? "set action for widget "+cWidget,chr(10) if .not. empty(widget) j:setAttribute( "widget", mapget(self:widgets,widget,NIL) ) endif*/ aadd(actions, j) next else ?? "WARNING: unknown tag "+e:getName()+" in '"+self:fileName+"'. Ignored&\n" endif next // Set actions aadd(self:actions, actions) id := len(self:actions) for e in events obj := e[1] signal := e[2] if "SETACTION" $ obj obj:setAction(signal,{|| self:actionHandler( id ) }) else ?? "WARNING: cannot link action to widget class '",obj,"'&\n" endif next return .T. /* Set pre action for form */ static function ui_setPreAction(self, tag, lObj) local e, widget, actions, id, t:=tag, cWidget // Retrieve data actions := array(0) for e in t:getChilds() if e:getName() == "call" widget := e:attribute("widget",NIL) /*if valtype(widget) == 'C' cWidget := widget elseif valtype(widget) == 'O' cWidget := '{'+widget:className+'}' else cWidget := '<unknown>' endif //?? "set pre action for widget "+cWidget,chr(10) if .not. empty(widget) e:setAttribute( "widget", mapget(self:widgets,widget,NIL) ) endif*/ //?? "post widget:",valtype(e:attribute("widget")),chr(10) aadd(actions, e) endif next aadd(self:actions, actions) id := len(self:actions) self:actionHandler( id ) return .T. /* Form action handler */ static function ui_actionHandler(self, id, addVal) local i, acts /* DEBUG print if valtype(id) != "O" ?? "Action handler:",valtype(id), id, addVal,chr(10) else ?? "Action handler:",valtype(id), id:name, addVal,chr(10) endif */ if valtype(id) == "N" acts := self:actions[id] else acts := id:getChilds() //?? "returned:",addVal,chr(10) endif for i in acts self:subActionHandler(i, addVal) next return NIL /* Recursive action execution */ static function ui_subActionHandler(self, tag, addVal) local widget, method, ret, subItem, retAction, value, i, condVal, chkVal local iArr local e, c, p, params:=array(0) if tag:getName() == "returnedvalue" // ?? "returned value:", addVal, chr(10) return addVal endif if tag:getName() == "property" if len(tag:getChilds()) > 0 // ?? "val ->",addVal,chr(10) value := self:subActionHandler(tag:getChild(1),addVal) // ?? "SET PROPERTY", valtype(value), chr(10) self:setProperty(tag, NIL, value) return NIL else return self:getPropertyValue( tag ) endif endif if tag:getName() == "condition" // Form condition condVal := NIL iArr := tag:getChilds() // ?? "CONDITION CHECK...&\n" for i=1 to len(iArr) e := iArr[i] if e:getName() == "param" .and. len(e:getChilds()) == 1 condVal := self:subActionHandler(e:getChild(1), addVal) // ?? "checked value:",condVal,chr(10) endif if e:getName() == "case" chkVal := e:attribute("value", NIL) if valtype(condVal) == "L" chkVal := iif(ascan({"TRUE",".T.","YES"},upper(chkVal))>0,.T.,.F.) endif // ?? "case value:",condVal,"?",chkVal,chr(10) if chkVal == condVal // ?? "CASE:",chkVal,"executing...&\n" return self:actionHandler(e,addVal) endif endif next return NIL endif widget := tag:attribute("widget","") method := upper(tag:attribute("method","")) //?? "call "+iif(valtype(widget)=='C',widget,"")+":"+method+"()",tag:getAttributes(),"&\n" c := tag:getChilds() for p in c switch p:getName() case "param" if p:attribute("value") != NIL // Constant value aadd(params,p:attribute("value")) else // Recursive call if len(p:getChilds()) > 0 aadd(params, self:subActionHandler(p:getChild(1),addVal)) else ?? "WARNING: parameter has no value&\n" aadd(params, NIL) endif endif case "return" // Bind action on form creation // ?? "SET RETURN HANDLER", self:fileName, ret, chr(10) retAction := {|ret| self:actionHandler(p,ret)} if method == "OPEN" asize(params, 2) endif if method == "DIALOGBOX" asize(params, 4) endif aadd(params, retAction) otherwise ?? "WARNING: unknown tag",p:name,"&\n" endswitch next outlog("CALL", method, "...") if valtype(widget) == "C" widget := mapget(self:widgets, widget, NIL) endif //?? "call widget: ", valtype(widget), iif(valtype(widget)=='O',widget:className,""),chr(10) if widget != NIL .and. valtype(widget) == "O" if method $ widget .and. valtype(widget[method]) == "B" /* TODO: use clipa() or similar function aadd( params, NIL ) ains( params, 1 ) params[1] := widget ret := clipa("func", params) */ switch len(params) case 1 ret := eval(widget[method], widget, params[1]) case 2 ret := eval(widget[method], widget, params[1], params[2]) case 3 ret := eval(widget[method], widget, params[1], params[2], params[3]) case 4 ret := eval(widget[method], widget, params[1], params[2], params[3], params[4]) case 5 ret := eval(widget[method], widget, params[1], params[2], params[3], params[4], params[5]) case 6 ret := eval(widget[method], widget, params[1], params[2], params[3], params[4], params[5], params[6]) otherwise ret := eval(widget[method], widget) endswitch else ?? "ERROR: no method '"+method+"'&\n" return NIL endif else if isfunction( method ) ret := clipA( method, params ) else ?? "ERROR: no function '"+method+"'&\n" return NIL endif endif // ?? "RETURN:",iif(valtype(ret)=="O","<OBJECT>",ret),chr(10) return ret /* Try to localize current string */ static function ui_form_i18n(self, str) local lstr:="" if str == NIL return NIL endif if valtype(self:locale)=="O" .and. str $ self:locale lstr := self:locale[str] elseif .not. empty(str) // TODO: show untranslated string in debug mode //?? self:fileName+": untranslated '"+str+"'&\n" lstr := str endif // ?? "i18n:",str,"=>",lstr,chr(10) return lstr --- NEW FILE: frame.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-UI library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ static driver := getDriver() /* Frame class */ function UIFrame(caption, type) local obj := driver:createFrame(caption, type) obj:className := "UIFrame" _recover_UIFRAME(obj) return obj function _recover_UIFRAME( obj ) obj:add := @ui_add() obj:setLabel := @ui_setLabel() obj:setType := @ui_setType() return obj /* Set grid for frame */ static function ui_add(self, grid) driver:setFrameGrid(self, grid) return NIL /* Set label for frame */ static function ui_setLabel(self, label) driver:setFrameLabel(self, label) return NIL /* Set frame type */ static function ui_setType(self, type) driver:setFrameType(self, type) return NIL --- NEW FILE: grid.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-UI library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* ... [truncated message content] |
From: Andrey C. <sku...@us...> - 2006-06-02 14:12:13
|
Update of /cvsroot/eas-dev/clip-ui/example/icons In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv3248/example/icons Added Files: doc_bank_pp.xpm eas-logo.xpm journal_bank_pp.xpm reference_partner.xpm tick.xpm Log Message: Add files --- NEW FILE: doc_bank_pp.xpm --- /* XPM */ static char * doc_bank_pp_xpm[] = { "16 16 47 1", " c None", ". c #777777", "+ c #FFFFFF", "@ c #747474", "# c #F9F9F9", "$ c #3A3A3A", "% c #FAFAFA", "& c #FDFDFD", "* c #878787", "= c #A6A67F", "- c #B4B482", "; c #737373", "> c #8F8F8F", ", c #000000", "' c #666666", ") c #959481", "! c #A6A527", "~ c #E2E036", "{ c #FFFD3D", "] c #C7C52F", "^ c #76751B", "/ c #585814", "( c #EDEDED", "_ c #656565", ": c #818181", "< c #BFBE86", "[ c #5D5C15", "} c #8D8B21", "| c #636363", "1 c #444444", "2 c #C9C9C9", "3 c #403F58", "4 c #C7C7C7", "5 c #141447", "6 c #7675A3", "7 c #838383", "8 c #6C6C6C", "9 c #F8F8F8", "0 c #333333", "a c #5D5D5D", "b c #B1B2B1", "c c #5B5A15", "d c #414141", "e c #707170", "f c #9D9E9D", "g c #717271", "h c #5B5B5B", " ", " ........... ", " .+++++++++. ", " @#$%&+++*+. ", " =-;-;>,,'''+. ", " )!~{]^/@(_+:+. ", " <[^,^,},,|':+. ", " )!~{]^/12|+:+. ", " <[^,^,},,|''+. ", " )!~{]^/34|+:+. ", " <[^,^,}56|+7+. ", " )!~{]^/34|+7+. ", " <[^,^,}849+++. ", " )!~{]^/0a;.... ", " b[ccc,deb ", " fgahagf "}; --- NEW FILE: eas-logo.xpm --- /* XPM */ static char * eas_logo_xpm[] = { "16 16 155 2", " c None", ". c #82A1C2", "+ c #6294C6", "@ c #558EC7", "# c #6492C0", "$ c #8EA0B3", "% c #6797C8", "& c #3785D4", "* c #3284D7", "= c #3383D5", "- c #5C86B1", "; c #A3A3A4", "> c #92AAC1", ", c #3E87D2", "' c #3184D7", ") c #3385D5", "! c #3384D2", "~ c #3382CF", "{ c #3282CF", "] c #2F80D1", "^ c #3080D0", "/ c #667D8F", "( c #9CA1A4", "_ c #83A3C4", ": c #3585D5", "< c #3688D4", "[ c #5EBBE8", "} c #62C0EA", "| c #62C1EA", "1 c #62C1EB", "2 c #5EBAE5", "3 c #2C73B6", "4 c #3381C8", "5 c #5FBAE3", "6 c #6D93A4", "7 c #95ABC1", "8 c #3584D5", "9 c #5EBBE7", "0 c #61C0EA", "a c #61C1EA", "b c #61C0E9", "c c #62C0E9", "d c #4996BF", "e c #265F91", "f c #63C4EE", "g c #5A9FBF", "h c #3D87D2", "i c #3486D5", "j c #63C5F0", "k c #2A608B", "l c #1E4C70", "m c #1F4A6C", "n c #1F496C", "o c #1A456B", "p c #265E8E", "q c #63C3EF", "r c #5CB6E0", "s c #394043", "t c #6596C8", "u c #3687D1", "v c #63C6F0", "w c #6AD0FC", "x c #62C0E8", "y c #58AED9", "z c #5EBAE4", "A c #233C4E", "B c #3D3E3E", "C c #ABB4BE", "D c #69CFFB", "E c #5DB6DF", "F c #205077", "G c #276091", "H c #5CB7E2", "I c #232E33", "J c #565656", "K c #7EA0C3", "L c #64C5F0", "M c #224D6C", "N c #1B4360", "O c #1E4667", "P c #1A4165", "Q c #225580", "R c #5DBAE3", "S c #1F3F55", "T c #2E2F2F", "U c #757575", "V c #5E92C7", "W c #5DB6E1", "X c #265E8D", "Y c #5EB9E3", "Z c #5DB7E0", "` c #222B30", " . c #4E4E4E", ".. c #959595", "+. c #538DC8", "@. c #55ADDD", "#. c #4D9AC3", "$. c #255987", "%. c #5DB9E3", "&. c #5CB8E2", "*. c #1F323F", "=. c #323333", "-. c #767676", ";. c #ADADAD", ">. c #5F90C2", ",. c #2C74B8", "'. c #23598D", "). c #1C466D", "!. c #1A4267", "~. c #1B456D", "{. c #1E5182", "]. c #255E94", "^. c #213648", "/. c #616161", "(. c #9E9E9E", "_. c #869DB4", ":. c #3283D6", "<. c #3182D5", "[. c #2F7CCA", "}. c #2A6FB5", "|. c #2666A6", "1. c #2563A2", "2. c #2767A7", "3. c #28639F", "4. c #2F3E4E", "5. c #464646", "6. c #696969", "7. c #989898", "8. c #5585B5", "9. c #3283D5", "0. c #3080D1", "a. c #307ECE", "b. c #2F79C4", "c. c #305B86", "d. c #3F4347", "e. c #5C5C5C", "f. c #818181", "g. c #A1A1A1", "h. c #A0A0A1", "i. c #64798E", "j. c #3F6E9E", "k. c #366EA6", "l. c #356799", "m. c #385675", "n. c #444A51", "o. c #585858", "p. c #737373", "q. c #929292", "r. c #ACACAC", "s. c #A2A2A2", "t. c #888888", "u. c #6C6C6C", "v. c #707070", "w. c #7F7F7F", "x. c #A5A5A5", " . + @ # $ ", " % & * * * * = - ; ", " > , ' ) ! ~ ~ { ] ^ / ( ", " _ : ' < [ } | 1 2 3 4 5 6 ", " 7 8 ' < 9 0 a b c d e 2 f g ", " h * i [ j k l m n o p q r s ", " t * ' u v w 1 b x y e z q A B ", "C : * i 9 D 1 b c E F G q H I J ", "K * ' u v L M N O P Q R q S T U ", "V * i 9 w w 1 b W X Y D Z ` ...", "+.* ! @.0 } } } #.$.%.&.*.=.-.;.", ">.* ] ,.'.).P !.~.{.].^.T /.(. ", "_.:.<.[.}.|.1.1.2.3.4.5.6.7. ", " 8.9.<.0.a.a.b.c.d.e.f.g. ", " h.i.j.k.l.m.n.o.p.q.r. ", " s.t.p.u.v.w.q.x. "}; --- NEW FILE: journal_bank_pp.xpm --- /* XPM */ static char * journal_bank_pp_xpm[] = { "16 16 46 1", " c None", ". c #6238B6", "+ c #F5E15E", "@ c #183196", "# c #A29EF6", "$ c #5F36B1", "% c #6036B2", "& c #6137B4", "* c #A6A67F", "= c #B4B482", "- c #737373", "; c #D5D5D5", "> c #6E6E6E", ", c #FCFCFC", "' c #FFFFFF", ") c #777777", "! c #959481", "~ c #A6A527", "{ c #E2E036", "] c #FFFD3D", "^ c #C7C52F", "/ c #76751B", "( c #585814", "_ c #585858", ": c #767676", "< c #BFBE86", "[ c #5D5C15", "} c #000000", "| c #8D8B21", "1 c #3F3F3F", "2 c #F9F9F9", "3 c #343434", "4 c #5D5D5D", "5 c #323232", "6 c #C7C7C7", "7 c #F8F8F8", "8 c #5C5C5C", "9 c #2A184F", "0 c #4D2C8F", "a c #B1B2B1", "b c #5B5A15", "c c #414141", "d c #707170", "e c #9D9E9D", "f c #717271", "g c #5B5B5B", " ", " ........... ", " .+@##@@@@@. ", " $$$%&...... ", " *=-=-;>,')''. ", " !~{]^/(_>:))). ", " <[/}/}|1;2)''. ", " !~{]^/(34-))). ", " <[/}/}|567)''. ", " !~{]^/(58-))). ", " <[/}/}|567)''. ", " !~{]^/(58-))). ", " <[/}/}|567)''. ", " !~{]^/(90$.... ", " a[bbb}cda ", " ef4g4fe "}; --- NEW FILE: reference_partner.xpm --- /* XPM */ static char * reference_clients_xpm[] = { "16 16 230 2", " c None", ". c #989ABB", "+ c #9BA1C9", "@ c #A9AED4", "# c #A1A3C9", "$ c #8687AB", "% c #A3A4AB", "& c #C7AFA5", "* c #C29E8E", "= c #BFA397", "- c #BDB3B0", "; c #8285B0", "> c #A7B1E0", ", c #B1BBE3", "' c #AEB4DA", ") c #ABAFD5", "! c #A4A8D4", "~ c #907285", "{ c #C58F77", "] c #EABAA3", "^ c #E7C3B1", "/ c #DEBDAC", "( c #C29F90", "_ c #947D73", ": c #BEBEBD", "< c #8E90AE", "[ c #5F6BB9", "} c #7581C4", "| c #727EC0", "1 c #6A77BD", "2 c #646FB7", "3 c #795C7B", "4 c #D7875F", "5 c #EEA783", "6 c #E69F7E", "7 c #DC9D7E", "8 c #CF997F", "9 c #C49B86", "0 c #B49180", "a c #775E55", "b c #C0C1C0", "c c #3E4391", "d c #4C4E9A", "e c #C6A79B", "f c #C3A499", "g c #3D479D", "h c #2B308B", "i c #8C3C25", "j c #C66532", "k c #D0774A", "l c #CE7345", "m c #C2653A", "n c #B0643E", "o c #995C3E", "p c #875B44", "q c #613D2B", "r c #746D69", "s c #7B6F8F", "t c #D5A990", "u c #FFD09B", "v c #FFCE9D", "w c #C1A39A", "x c #795A6D", "y c #7D2100", "z c #BC6A3C", "A c #F2BF93", "B c #E2A276", "C c #9F4113", "D c #832D07", "E c #6A2707", "F c #511F08", "G c #3C1605", "H c #4E4441", "I c #C1B2A3", "J c #FFCC9A", "K c #F7C8A2", "L c #FCCFAA", "M c #FFDDB2", "N c #F5C599", "O c #BB7D57", "P c #F0BE94", "Q c #FDCDA3", "R c #FFCFA4", "S c #DDA87F", "T c #B57A55", "U c #A26D4B", "V c #A37656", "W c #BE9470", "X c #81756B", "Y c #C2C2C0", "Z c #E9BF9C", "` c #FDD0AB", " . c #FBD4B4", ".. c #FED8B9", "+. c #FFDDBF", "@. c #F8CAA2", "#. c #F2C197", "$. c #F8C9A3", "%. c #FFD9B4", "&. c #FFDDB8", "*. c #FFDCB7", "=. c #FFDFB8", "-. c #FFDFB6", ";. c #88817A", ">. c #ACA6A4", ",. c #DAB4A0", "'. c #FED3BC", "). c #FFDBC5", "!. c #FFDECD", "~. c #F1C9B2", "{. c #F1C098", "]. c #F9CEAA", "^. c #FBD3B3", "/. c #FDD8B9", "(. c #FEDABB", "_. c #FFDBBC", ":. c #FFE7C6", "<. c #C1A791", "[. c #8A8B8A", "}. c #ABB0A8", "|. c #76AE60", "1. c #A3DF89", "2. c #8DCF76", "3. c #6B7F64", "4. c #A28E85", "5. c #F4D0AD", "6. c #FDE2C2", "7. c #FCE2C6", "8. c #FFE8CD", "9. c #FFEDD1", "0. c #C9B5A2", "a. c #767573", "b. c #B8B9B8", "c. c #5BAE57", "d. c #5FCE66", "e. c #79DB7E", "f. c #71D977", "g. c #47AF48", "h. c #8F9E90", "i. c #A39897", "j. c #CC7F73", "k. c #F2A997", "l. c #E59788", "m. c #917571", "n. c #838584", "o. c #B5B6B5", "p. c #78B071", "q. c #5ABD5D", "r. c #70D072", "s. c #68D36A", "t. c #6BD36D", "u. c #6DDE73", "v. c #489E44", "w. c #975051", "x. c #CF585C", "y. c #DC7B7C", "z. c #D86C6D", "A. c #A43F44", "B. c #A19898", "C. c #BFCCBC", "D. c #399D38", "E. c #4FC552", "F. c #49E04C", "G. c #49ED4C", "H. c #49EE4C", "I. c #45EF4E", "J. c #777031", "K. c #C5575D", "L. c #D37B7B", "M. c #D37373", "N. c #D37777", "O. c #DC7675", "P. c #A24549", "Q. c #B7B6B5", "R. c #84B37D", "S. c #24A728", "T. c #2FE032", "U. c #33FF37", "V. c #3DFF40", "W. c #3BFF44", "X. c #45CB2F", "Y. c #A03633", "Z. c #C8595D", "`. c #D65555", " + c #E05555", ".+ c #E05454", "++ c #DD5959", "@+ c #DB4E4E", "#+ c #8A5D60", "$+ c #5CA458", "%+ c #12A617", "&+ c #1ADF1D", "*+ c #2EEB30", "=+ c #3AEB3D", "-+ c #36EB40", ";+ c #656B22", ">+ c #B12733", ",+ c #D53C3B", "'+ c #F43B3B", ")+ c #FC3F3F", "!+ c #FD4040", "~+ c #FA3E3E", "{+ c #FB3E3D", "]+ c #B92C30", "^+ c #ACACAB", "/+ c #B4BAB3", "(+ c #889288", "_+ c #838F83", ":+ c #859085", "<+ c #83857C", "[+ c #8F1719", "}+ c #CA2020", "|+ c #FF2323", "1+ c #FF3434", "2+ c #FF3F3F", "3+ c #FF4242", "4+ c #FF3D3D", "5+ c #FF3333", "6+ c #FF1C1E", "7+ c #8D7173", "8+ c #886263", "9+ c #804342", "0+ c #934847", "a+ c #945050", "b+ c #945453", "c+ c #945454", "d+ c #945353", "e+ c #944F4E", "f+ c #944544", "g+ c #877475", " . + @ # $ % & * = - ", " ; > , ' ) ! ~ { ] ^ / ( _ : ", "< [ } | 1 2 3 4 5 6 7 8 9 0 a b ", "c d e f g h i j k l m n o p q r ", "s t u v w x y z A B C D E F G H ", "I J K L M N O P Q R S T U V W X ", "Y Z ` ...+.@.#.$.` %.&.*.=.-.;.", " >.,.'.).!.~.{.].^./.(._.:.<.[.", " }.|.1.2.3.4.5.6.7.8.9.0.a.b.", " c.d.e.f.g.h.i.j.k.l.m.n.o. ", " p.q.r.s.t.u.v.w.x.y.z.A.B. ", "C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q. ", "R.S.T.U.V.W.X.Y.Z.`. +.+++@+#+ ", "$+%+&+*+=+-+;+>+,+'+)+!+~+{+]+^+", "/+(+_+:+(+<+[+}+|+1+2+3+4+5+6+7+", " 8+9+0+a+b+c+d+e+f+g+"}; --- NEW FILE: tick.xpm --- /* XPM */ static char * tick_xpm[] = { "10 15 5 1", " c #FFFFFF", ". c #FF7B7B", "+ c #FF8F8F", "@ c #FFA4A4", "# c #FFBBBB", " ", " . ", " + +. ", " .+ +.. ", " ..@ @..# ", " @..#..@ ", " +...+ ", " +.+ ", " . ", " ", " ", " ", " ", " ", " "}; |
From: Andrey C. <sku...@us...> - 2006-06-02 14:09:20
|
Update of /cvsroot/eas-dev/clip-ui/example/icons In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv2060/icons Log Message: Directory /cvsroot/eas-dev/clip-ui/example/icons added to the repository |
From: Andrey C. <sku...@us...> - 2006-06-02 14:08:44
|
Update of /cvsroot/eas-dev/clip-ui/example In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv1671/example Log Message: Directory /cvsroot/eas-dev/clip-ui/example added to the repository |
From: Andrey C. <sku...@us...> - 2006-06-02 14:08:43
|
Update of /cvsroot/eas-dev/clip-ui/drivers In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv1671/drivers Log Message: Directory /cvsroot/eas-dev/clip-ui/drivers added to the repository |
From: Andrey C. <sku...@us...> - 2006-06-02 14:07:28
|
Update of /cvsroot/eas-dev/CVSROOT In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv1261 Modified Files: modules Log Message: Set module list Index: modules =================================================================== RCS file: /cvsroot/eas-dev/CVSROOT/modules,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- modules 19 Jun 2001 16:10:47 -0000 1.1 +++ modules 2 Jun 2006 14:07:23 -0000 1.2 @@ -24,3 +24,7 @@ # character to interpose another module into the current module. This # can be useful for creating a module that consists of many directories # spread out over the entire source repository. +clip-ui clip-ui +clip-xml clip-xml +eas eas +ocmng ocmng |
From: Andrey C. <sku...@us...> - 2006-06-02 14:02:11
|
Update of /cvsroot/eas-dev/clip-xml/ocmng/components/ref1/ru In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv31265/ocmng/components/ref1/ru Removed Files: ALL.xml GBL01.xml _a1 country.xml currency.xml taxcause.xml taxcode.xml taxtype.xml unit2unit.prg unit2unit.xml units.xml void.xml Log Message: Remove duplicate files --- ALL.xml DELETED --- --- GBL01.xml DELETED --- --- _a1 DELETED --- --- country.xml DELETED --- --- currency.xml DELETED --- --- taxcause.xml DELETED --- --- taxcode.xml DELETED --- --- taxtype.xml DELETED --- --- unit2unit.prg DELETED --- --- unit2unit.xml DELETED --- --- units.xml DELETED --- --- void.xml DELETED --- |
From: Andrey C. <sku...@us...> - 2006-06-02 14:02:11
|
Update of /cvsroot/eas-dev/clip-xml/ocmng/components/tests In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv31265/ocmng/components/tests Removed Files: CORE.xml testclass1.xml testclass2.xml testplugin.prg Log Message: Remove duplicate files --- CORE.xml DELETED --- --- testclass1.xml DELETED --- --- testclass2.xml DELETED --- --- testplugin.prg DELETED --- |