/*******************************************
Module DBeditor 
Editor
Version: 1.0
Author: Thierry LEFORT
Last update: 05/21/2001

*******************************************/

typeof EditorWin = 			ObjWin 	;; 			/*The editor Window*/
typeof font =					ObjFont  ;;
typeof ed = 					Editor	;;

typeof Alias = 				S			;;				/*ODBC variables*/
typeof Login = 				S			;;
typeof Password = 			S			;;
typeof db=						SqlDB		;;				/*Data Base*/
typeof table = 				S 			;;

/*Labels*/
typeof AliasTexte =			ObjText	;;
typeof AliasEditTexte =		ObjText	;;
typeof TableTexte =			ObjText	;;
typeof MetaTable  	= 		S			;;
typeof MetaTableAttr = 		S			;;

typeof labelMetaInd =		ObjText	;;
typeof labelMetaTable =		ObjText	;;

/*Buttons for DB acces*/
typeof FullAccessBttn = 	ObjButton ;;
typeof ReadAccessBttn = 	ObjButton ;;
typeof NoAccessBttn = 		ObjButton ;;
typeof PrimariKeyBttn = 	ObjButton ;;
typeof ConnectBtn 	=		ObjButton ;;


typeof comboBoxindTab = 	ObjBox;;
typeof comboBoxindAttr = 	ObjBox;;
typeof comboBox = 			ObjBox;;
typeof TableModifButtn =	ObjButton ;;
typeof OdbcModifButtn =		ObjButton ;;

typeof MultiListe = 			ObjListTab ;;
typeof ListAccess = 			[I r1] ;;

typeof listsel = 				[I r1] ;;

typeof LISTEATTRIBUTSBDD = [[S r1] r1];;

typeof check = 				ObjCheck ;;

/*typeof PopUpMenu = 			ObjMenu ;;*/

var FULLACCESS  	= 0	;;
var READONLY 		= 1 	;;
var NOACCESS 		= 2 	;;
var KEY  			= 3	;;

var OnOff = 1;;

var firstuse = 0;;								/*0 if it's the first openning of the editor, 1 if not*/

/*Looks in a SR1R1 if the first element of each list is the same of "table"*/
fun IsThisTableExist (table, liste)=
  if liste == nil then 0 else
    let hd hd liste -> tableToCmp 	in
      if !strcmp table tableToCmp then
        1
      else
        IsThisTableExist table tl liste
;;


fun convertIR1TOSR1R1 (listIR1) =
if listIR1 == nil then nil else
  ((itoa hd listIR1)::nil)::(convertIR1TOSR1R1 tl listIR1)
;;
fun convertSR1R1TOIR1 (listSR1R1) =
if listSR1R1 == nil then nil else
  (atoi hd hd listSR1R1)::(convertSR1R1TOIR1 tl listSR1R1)
;;

/*fill a line with a Sr1*/
fun fill_Line (theListe, listSR1, column, line, type) = 

  if listSR1 == nil then 1 else
  (
    if type == 1 then 
    (
      _ADDlistTabItem 	theListe line column hd listSR1
    )
    else
    (
      _SETlistTabItem 	theListe line column hd listSR1;
    );
    fill_Line theListe  tl listSR1 column+1 line 0;
    0
  )
;;
fun MakeAccessListe (AccessListe) =
  if AccessListe ==nil then nil 
  else
  (
    let hd AccessListe -> Access in
      if Access == FULLACCESS then
        ((_locEditor "DB_FULLACCESS" nil)::nil)::(MakeAccessListe tl AccessListe)
      else 
        if Access == READONLY then
          ((_locEditor "DB_READONLY" nil)::nil)::(MakeAccessListe tl AccessListe)
        else
          if Access == NOACCESS then
            ((_locEditor "DB_NOACCESS" nil)::nil)::(MakeAccessListe tl AccessListe)
          else
            if  Access == KEY then
              ((_locEditor "DB_KEY" nil)::nil)::(MakeAccessListe tl AccessListe)
            else 
              nil
  )
;;

/*Fill the ListTab with a Sr1r1*/
fun fill_Multi_Liste (TheListe, listSR1R1, column, line, type) =

  if listSR1R1 == nil then 1 else 
  (
    fill_Line 				TheListe 	hd listSR1R1 	column 	line type;
    fill_Multi_Liste 	TheListe 	tl listSR1R1 	column 	line+1 type;
    0
  )
;;
/***************************************************************************
  Renvoie le login ou le password d'une base de donnees, on specifie l'alias
dans
  odbcAlias, l'info que l'on souhaite reccueillir dans info ("login" ou
"password")
  les valeurs sont recuperees dans usmress.ini
  format :
    odbc.odbcAlias.login
    odbc.odbcAlias.password
  attention :
    odbcAlias, infos ne doivent pas contenir les caracteres suivants : ".*?"
****************************************************************************/
fun GetODBCInfos(odbcAlias,info)=
  hd switchstr strextr _loadressini strcatn
    "odbc."::odbcAlias::"."::info::nil
;;

/*Initialise the DBACCESSLISTE with READ & WRITE*/
fun InitAccessListe(len) = 
  if len <= 0 then nil else
    0::(InitAccessListe len-1)
;;

fun fill_combo(combo, list, ind)=
  if list == nil then 0
  else
  (
    fill_combo (_ADDcombo combo 1 hd hd list ) (tl list) (ind+1);
    1
  )
;;


/*CallBack for DLGmessagebox DBsuccess*/
fun _dbconnect (msgBox, param, ok) =
  let param -> [tmpAlias tmpLogin tmpPassword win] in
  (
    set Alias = tmpAlias;
    set Login = tmpLogin;
    set Password = tmpPassword;
    
    let SqlRequest db "GET_TABLES" nil -> tmp in
    (
      fill_combo comboBox tmp 1;
      fill_combo comboBoxindTab tmp 1
    );
    _PAINTcombo _SHOWcombo comboBox WINDOW_UNHIDDEN
  ) 
;;


fun _comboTable (combo, param, ind, texte) =
  _RSTlistTab MultiListe ;
  let SqlRequest db "GET_COLUMNS" (SQL_NIL texte)::nil -> listATTR in
    (
      set LISTEATTRIBUTSBDD = listATTR;
      fill_Multi_Liste MultiListe listATTR 0 0 1;
      fill_Multi_Liste MultiListe MakeAccessListe set ListAccess = InitAccessListe listlength listATTR 3 0 0
    );
  _SETtext TableTexte strcatn (_locEditor "DB_TABLE" nil)::" "::table::nil
;;

fun _comboMetaTable (combo, param, ind, texte) =
  _RSTcombo comboBoxindAttr;
  let SqlRequest db "GET_COLUMNS" (SQL_NIL texte)::nil -> listMETAATTR in
    fill_combo comboBoxindAttr listMETAATTR 1
;;

fun _comboMetaAttrTable (combo, param, ind, texte) =
  0
;;

fun new_access_liste (list, listind, value) =
  if listind == nil then list else
    new_access_liste (replace_nth_in_list list hd listind value) tl listind value
;;
  


/*Modif DB access : full access */ 
fun _DbFullAccess (bttn, param) =
  set ListAccess = new_access_liste ListAccess listsel FULLACCESS;
  fill_Multi_Liste MultiListe MakeAccessListe ListAccess  3 0 0
;;
/*Modif DB access : Read Only access */ 
fun _DbReadAccess (bttn, param) =
  set ListAccess = new_access_liste ListAccess listsel READONLY;
  fill_Multi_Liste MultiListe MakeAccessListe ListAccess  3 0 0
;;
/*Modif DB access : No access */ 
fun _DbNoAccess (bttn, param) =
  set ListAccess = new_access_liste ListAccess listsel NOACCESS;
  fill_Multi_Liste MultiListe MakeAccessListe ListAccess  3 0 0
;;
fun icomp( i1, i2) =
  i1==i2
;;

fun cherche (list, cle) =
  if list == nil then 0 else
    if (hd list) == cle then 1
    else cherche tl list cle
;;

/*Primary Key*/
fun _DbKey (bttn, param) =
  if (cherche ListAccess KEY) == 1 then
  (
    _DLGMessageBox _channel EditorWin (_locEditor "KEY_TITLE" nil) (_locEditor "KEY_MESSAGE" nil) 0;
    0
  )
  else 
  if  (listlength listsel) != 1 then 
    (
      _DLGMessageBox _channel EditorWin (_locEditor "KEY_TITLE" nil) (_locEditor "KEY_MESSAGE" nil) 0;
      0
    )
    else
    (
      set ListAccess = new_access_liste ListAccess listsel KEY;
      fill_Multi_Liste MultiListe MakeAccessListe ListAccess  3 0 0;
      1
    )
;;

fun cbSave (filename, n)=

let _GETcombo comboBox -> [_ table] in
let _GETcombo comboBoxindTab -> [_ MetaTable] in
let _GETcombo comboBoxindAttr -> [_ MetaTableAttr] in
let _GETtext	 AliasEditTexte	-> AliasDB  in
let itoa _GETcheck check -> tmp in
  ("action"::		"start"				::nil)::
  ("action"::		"refreshfromDB"	::nil)::
  ("actionC"::		"show"				::nil)::
  ("actionC"::		"hide"				::nil)::
  ("event"::		"out"					::nil)::
  ("event"::		"entering"			::nil)::
  ("eventC"::  	"querySQL"			::nil)::
  ("eventC"::  	"refresh"			::nil)::
  ("eventC"::		"shown"				::nil)::
  ("eventC"::  	"hidden"				::nil)::
  ("eventC"::		"in"					::nil)::
  ("insert"::		tmp					::nil)::
  ("alias"::		AliasDB				::nil)::
  ("table"::		table					::nil)::
  ("MetaTable"::	MetaTable			::nil)::
  ("MetaTableAttr"::	MetaTableAttr	::nil)::
  ("accessList"::(strbuild convertIR1TOSR1R1 ListAccess)::nil)::
  nil
  
;;

fun _check (objet, param, state) =
  if state == 1 then 
  (
    _ENcombo comboBoxindTab 0;
    _ENcombo comboBoxindAttr 0
  ) 
  else
  (
    _ENcombo comboBoxindTab 	1;
    _ENcombo comboBoxindAttr 	1
  )
;;

fun ISELEMINSR1R1 (elem, SR1R1, ind) =
  if SR1R1 == nil then nil else
   let hd hd SR1R1 -> tmpELEM in
   let _fooS strcatn "les deux éléments sont identiques ??? : "::elem::" "::tmpELEM::nil -> _ in
     if !strcmp elem tmpELEM then 
     (

       ind 
     )
     else
     (
       ISELEMINSR1R1 elem tl SR1R1 ind+1
     )
;;

fun UpDateAccessListe (listATTRNEW, listATTROLD, listACCES) =
  if listATTRNEW ==nil then nil else
    let hd hd listATTRNEW -> NewElem in
    let _fooS strcatn "NewElem = "::NewElem::nil -> _ in
    let ISELEMINSR1R1 NewElem listATTROLD 0 -> value in
    let _fooS strcatn "Valeur de l'index = "::(itoa value)::nil -> _ in
    if value == nil then 
      0::(UpDateAccessListe tl listATTRNEW listATTROLD listACCES)
    else
      (nth_list listACCES value)::(UpDateAccessListe tl listATTRNEW listATTROLD listACCES)
;;


fun connectionDB (aliasDB, loginDB, pwdDB)=
  let if aliasDB ==nil 	then "" else aliasDB 	-> al 	in
  let if loginDB ==nil 	then "" else loginDB 	-> lo 	in
  let if pwdDB ==nil 	then "" else pwdDB 		-> pwd 	in
  let SqlCreate _channel al lo pwd 				-> dbtmp in
  if db == nil then
  (
    set db = dbtmp;
    _DLGrflmessage 
      _DLGMessageBox _channel EditorWin (_locEditor "WINDOW_NAME_DBCONNECT" nil) (_locEditor "DBCONNECT_SUCCESS" nil) 0
        @_dbconnect
        [al lo pwd EditorWin];
    0
  )
  else /*Il y a déjà une base*/
  (
    let _GETcombo comboBox 				-> [_ table] 	in
    let SqlRequest dbtmp "GET_TABLES" nil 	-> sqlreq in
    if (IsThisTableExist table sqlreq) == 1 then
    (/*The last table exist in the new DataBase*/
      let SqlRequest dbtmp "GET_COLUMNS" (SQL_NIL table)::nil -> listATTR in
      (
        _RSTlistTab MultiListe;
        fill_Multi_Liste MultiListe listATTR 0 0 1;
        
        
        _fooS "\n\n\n\n\n\nmessage de DEGUB debut µµµµ ::: \n\n";
        _fooIList ListAccess;
        _fooS "\n\n\n\n\n\nmessage de DEGUB FIN \n\n";
        
        _fooS strcat "Liste ancienne version = "  strbuild LISTEATTRIBUTSBDD;
                
        let  UpDateAccessListe listATTR LISTEATTRIBUTSBDD ListAccess -> tmpListAcces in
        /*
        set LISTEATTRIBUTSBDD = listATTR
        */
        (
          set ListAccess = tmpListAcces;
          _fooS "\n\n\n\n\n\nmessage de DEGUB debut µµµµ ::: \n\n";
          _fooIList ListAccess;
          _fooS "\n\n\n\n\n\nmessage de DEGUB FIN \n\n";

          fill_Multi_Liste MultiListe MakeAccessListe ListAccess 3 0 0;
          
        )
      );
    )
    else
    (/*The Last Table doesnt exist in the new DataBase*/
      /*set dbSource = dbtmp;*/
      _DLGrflmessage 
        _DLGMessageBox _channel EditorWin (_locEditor "WINDOW_NAME_DBCONNECT" nil) (_locEditor "DBCONNECT_SUCCESS" nil) 0
          @_dbconnect
          [al lo pwd EditorWin];
      0
    )
  )
      /*
      
      if dbtmp != nil then  	/*DB success*/
      (
        set db = dbtmp;
         _DLGrflmessage 
           _DLGMessageBox _channel EditorWin (_locEditor "WINDOW_NAME_DBCONNECT" nil) (_locEditor "DBCONNECT_SUCCESS" nil) 0
           @_dbconnect
           [al lo pwd EditorWin];
        0
      )
      else 							/*DB failed*/
      (
        _DLGMessageBox _channel EditorWin (_locEditor "WINDOW_NAME_DBCONNECT" nil) (_locEditor "DBCONNECT_FAILURE" nil) 0;
        0
      )
      */
;;

fun cbConnect (btn, param) =
  let _GETtext param 						-> tmpAlias 	in
  let GetODBCInfos tmpAlias "login" 	-> tmpLogin 	in
  let GetODBCInfos tmpAlias "password" -> tmpPwd 		in
  
    connectionDB tmpAlias tmpLogin tmpPwd
    
;;

fun _OdbcOk(Otext, param, truc)=
  let _GETtext Otext 						-> tmpAlias 	in
  let GetODBCInfos tmpAlias "login" 	-> tmpLogin 	in
  let GetODBCInfos tmpAlias "password" -> tmpPwd 		in
  
    connectionDB tmpAlias tmpLogin tmpPwd
    
;;
fun cbLoad(list)=

if firstuse == 0 
then (
  set firstuse= firstuse+1;
  _RSTlistTab MultiListe ;
  set db = nil;
  _SETtext  AliasEditTexte
  set Alias = 				(getInfo list "alias");
  set Login=     			GetODBCInfos Alias "login";
  set Password =  		GetODBCInfos Alias "password";
  set table = 				hd hd strextr (getInfo list "table");
  set MetaTable = 		hd hd strextr (getInfo list "MetaTable");
  set MetaTableAttr = 	hd hd strextr (getInfo list "MetaTableAttr");
  

  set ListAccess = convertSR1R1TOIR1 strextr (getInfo list "accessList");
  _SETcheck check atoi hd hd strextr (getInfo list "insert");
  _check check nil atoi hd hd strextr (getInfo list "insert");

/*  if Alias==nil && Login == nil && Password==nil && table == nil then */
  if Alias==nil then
    0
  else
  (
    let SqlCreate _channel Alias (if !strcmp Login nil then "" else Login) (if !strcmp Password nil then "" else Password) -> dbtmp in
      if dbtmp != nil then  	/*DB success*/
      (
        set db = dbtmp;
        let SqlRequest db "GET_TABLES" nil -> tmp in
        (
          fill_combo comboBox tmp 1;
          fill_combo comboBoxindTab tmp 1
        );
        0
      )
      else 							/*DB failed*/
      (
        _DLGMessageBox _channel EditorWin (_locEditor "WINDOW_NAME_DBCONNECT" nil) (_locEditor "DBCONNECT_FAILURE" nil) 0;
        0
      );
    let SqlRequest db "GET_COLUMNS" (SQL_NIL table)::nil -> listATTR in
    let SqlRequest db "GET_COLUMNS" (SQL_NIL MetaTable)::nil -> listMETAATTR in
    (
      set LISTEATTRIBUTSBDD = listATTR;
      _SETtext AliasTexte strcatn (_locEditor "DB_ALIAS" nil)::" "::Alias::nil;
      fill_combo comboBoxindAttr listMETAATTR 1;
      _SSELcombo comboBox table;
      _SSELcombo comboBoxindTab MetaTable;
      _SSELcombo comboBoxindAttr MetaTableAttr;
      fill_Multi_Liste MultiListe listATTR 0 0 1;
      fill_Multi_Liste MultiListe MakeAccessListe ListAccess  3 0 0
    )
  )
)
else 0
;;

fun multi_select ( list, int) =
  if is_in_list list int then
    removef_from_list list @icomp int
  else
    int::list
;;

fun addSel (ind, list) =
  if is_in_list list ind then
    list
  else
    ind::list
;;

fun shiftSelMaj (deb, fin, list) =
  if deb > fin then list else
     shiftSelMaj deb+1  fin addSel deb list
;;

fun shiftSelInf (deb, fin, list) =
  if deb < fin then list else
     shiftSelInf deb-1  fin addSel deb list
;;

fun _SelectMListe (Liste, param, i1) =
  _ENbutton NoAccessBttn 1;
  _ENbutton FullAccessBttn 1;
  _ENbutton ReadAccessBttn 1;
  _ENbutton PrimariKeyBttn 1;
  set listsel =
    if i1 != -1 then
      /*Control*/
      if _keybdstate == 2 then
        multi_select listsel i1
      else
      /*Shift*/
      if _keybdstate == 1 then
      (
        let hd listsel -> lastone in
        (
          set listsel = nil;
          if lastone <= i1 then
            shiftSelMaj lastone i1 listsel
          else
            shiftSelInf lastone i1 listsel
        )
      )
      else
        i1::nil
    else
      nil
;;

fun _ReSizeEditor ( win, param, width, height ) =
  let width -> Wt in
  let height -> Ht in
  let 10 -> step in
  let 20 -> Tstep in
  let 50 -> Lbtn in
  let (Wt/2)-3*step/2-Lbtn -> endlabel in
  let Wt-2*step -> Llist in
  let Ht-5*step-5*Tstep -> Hlist in
  let 80 -> endlabelTable in  
  (
      /*DB alias*/
    _SIZEtext AliasTexte 				100   		2*Tstep  step	 step+5;
    _SIZEtext AliasEditTexte			Wt/2-(2*step+175)	Tstep  step+100 step+10;
    _SIZEbutton ConnectBtn	70 Tstep step+90+ Wt/2-(2*step+160) step+10;

   /*Label for Table :*/
    _SIZEtext TableTexte 	Lbtn 			Tstep 		2*step+endlabel+Lbtn   step+Tstep/2;
    
    _SIZEbutton OdbcModifButtn Lbtn 	Tstep 	step+endlabel 				step+Tstep/2;
    /*_SIZEbutton TableModifButtn Lbtn 	Tstep 	2*step+2*endlabel+Lbtn 	step+Tstep/2;*/
    _SIZEcombo comboBox width-(2*step+endlabel+2*Lbtn)-step 500 2*step+endlabel+2*Lbtn step+Tstep/2;
    
    _SIZElistTab MultiListe Llist Hlist step 2*step+2*Tstep;
  
    let Ht-step-Tstep -> ybottom in
    let (Wt-5*step-2*Lbtn)/2 -> Lcombo in
    (
      _SIZEcheck check 400 Tstep step ybottom-Tstep ;
      _SIZEtext labelMetaTable 		Lbtn  	Tstep 	step	 						ybottom;
      _SIZEtext labelMetaInd			Lbtn  	Tstep		3*step+Lbtn+Lcombo	 	ybottom;
      _SIZEcombo comboBoxindTab 		Lcombo  	100 		2*step+Lbtn 				ybottom;
      _SIZEcombo comboBoxindAttr 	Lcombo  	100		4*step+2*Lbtn+Lcombo	 	ybottom
    );    
    let Ht-2*step-3*Tstep -> Ystart in
    let 100 -> LargeLbtn in
    (
      _SIZEbutton FullAccessBttn 	LargeLbtn 	Tstep 	step						Ystart;
      _SIZEbutton ReadAccessBttn 	LargeLbtn 	Tstep 	2*step+LargeLbtn		Ystart;
      _SIZEbutton NoAccessBttn 		LargeLbtn 	Tstep 	3*step+2*LargeLbtn	Ystart;
      _SIZEbutton PrimariKeyBttn 	LargeLbtn 	Tstep 	4*step+3*LargeLbtn	Ystart
    )
  )
;;



fun cbPro () =
  let BigToAsc BigInvn BigFromAsc _getpack _checkpack "dms/db/dbeditor/dbeditor.conf"  BigFromAsc "c8aa22856afe3a01"
  -> s in
  let
    if (strlen s)!=9 then
      nil
    else
      [htoi substr s 1 4 htoi substr s 5 4]
  -> [datedebut periode] in
    if periode==nil then
      (_DLGMessageBox _channel nil _locEditor "PRO_WARNING" nil _locEditor "PRO_INVALID_MSG" nil 0;0)        
    else
      if periode==0 then
        1
      else              
        let ((time>>1)&0x3fffffff)/43200-datedebut -> x in
          if x<0 then
            (_DLGMessageBox _channel nil _locEditor "PRO_WARNING" nil _locEditor "PRO_INVALID_MSG" nil 0;0)
          else if x<=periode then
            (_DLGMessageBox _channel nil _locEditor "PRO_WARNING" nil _locEditor "PRO_LIMITED_MSG" (itoa (periode-x))::nil 0;1)
          else
            (_DLGMessageBox _channel nil _locEditor "PRO_WARNING" nil _locEditor "PRO_ENDLIMITED_MSG" nil 0;0)      
;;


fun CreateApi(filename)=

  set font = _CRfont _channel 14 0 FF_WEIGHT "Arial";
  
  set ed = _StartEditor _channel nil 0 0 640 480 WN_NORMAL EDITOR_NORMAL @cbLoad @cbSave @cbPro;
  
  set EditorWin = getEditWin ed ;
  
  let _GETwindowSizePosition EditorWin -> [Wt Ht _ _] in
  let 10 -> step in
  let 20 -> Tstep in
  let 50 -> Lbtn in
  let (Wt/2)-3*step/2-Lbtn -> endlabel in
  let Wt-2*step -> Llist in
  let Ht-5*step-5*Tstep -> Hlist in
  (
    /*DB alias*/
    set AliasTexte = 		_CRtext 
    									_channel EditorWin     
    									step	 
    									step+5
    									100
    									2*Tstep 
    									ET_ALIGN_LEFT (_locEditor "DB_ALIAS" nil);
    set AliasEditTexte = 	_CReditLine
    									_channel EditorWin
    									step+100
    									step+10
    									Wt/2-(2*step+175)
    									Tstep ET_BORDER|ET_TABFOCUS|ET_AHSCROLL "";
    _CBlineOk AliasEditTexte 	@_OdbcOk [];
    
    set ConnectBtn 	=		_CRbutton 
    									_channel EditorWin
    									step+90+ Wt/2-(2*step+160)
    									step+10
    									70
    									Tstep
    									0
    									(_locEditor "DB_CONECTION" nil);
    _CBbutton ConnectBtn @cbConnect AliasEditTexte;
    /*Label for Table :*/
    set TableTexte = _CRtext _channel EditorWin     2*step+endlabel+Lbtn   step+Tstep/2	Lbtn   Tstep*2 ET_ALIGN_LEFT (_locEditor "DB_TABLE" nil);
    
    /*Modif DB Table*/
    set comboBox =
    _CBcombo 
      _CRcombo _channel EditorWin 2*step+endlabel+2*Lbtn 	step+Tstep/2 	Wt-(2*step+endlabel+2*Lbtn)-step 500 CB_NOEDIT|CB_AHSCROLL|CB_DOWN ""
      @_comboTable
      nil;
      
    let Ht-step-Tstep -> ybottom in
    let (Wt-5*step-2*Lbtn)/2 -> Lcombo in
    (
      /*Label et combo pour récéption de la Méta table*/
      set check =
      _SETcheck 
        _CBcheck
	       _CRcheck _channel EditorWin step ybottom-Tstep 400 Tstep 0 (_locEditor "DB_INSERTMETATABLE" nil)
	     @_check
	     nil
	   1;

      set labelMetaTable =
      _CRtext _channel EditorWin     	step	 			ybottom		Lbtn  	Tstep ET_ALIGN_LEFT (_locEditor "DB_INDTABLE" nil);
      
      set comboBoxindTab =
      _ENcombo
        _CBcombo 
          _CRcombo _channel EditorWin 	2*step+Lbtn 	ybottom 		Lcombo  	100 CB_NOEDIT|CB_AHSCROLL|CB_DOWN ""
          @_comboMetaTable
          nil
        0;
	   /*Label et combo pout récéption de l'attribut Max id*/
	   set labelMetaInd = 
	   _CRtext _channel EditorWin     	3*step+Lbtn+Lcombo	 	ybottom		Lbtn  	Tstep ET_ALIGN_LEFT (_locEditor "DB_INDATTR" nil);
      
      set comboBoxindAttr =
      _ENcombo
        _CBcombo 
          _CRcombo _channel EditorWin  	4*step+2*Lbtn+Lcombo	 	ybottom 		Lcombo  	100 CB_NOEDIT|CB_AHSCROLL|CB_DOWN ""
          @_comboMetaAttrTable
          nil
        0
    );
/*    set TableModifButtn =
    _CBbutton 
        _CRbutton _channel EditorWin 2*step+2*endlabel+Lbtn step+Tstep/2 Lbtn Tstep nil  (_locEditor "DB_MODIF" nil)
        @_buttnModifTable
        nil;*/
    /*Multi_Liste des attributs*/
    set MultiListe = _CRlistTab _channel EditorWin step 2*step+2*Tstep Llist Hlist LV_BORDER;
    _ADDlistTabColumn MultiListe 0 100 ET_ALIGN_LEFT (_locEditor "ATTR_NAME" nil);
    _ADDlistTabColumn MultiListe 1 100 ET_ALIGN_LEFT (_locEditor "ATTR_TYPE" nil);
    _ADDlistTabColumn MultiListe 2 100 ET_ALIGN_LEFT (_locEditor "ATTR_WIDTH" nil);
    _ADDlistTabColumn MultiListe 3 100 ET_ALIGN_LEFT (_locEditor "ATTR_USE" nil);
    
    _CBlistTabSelect MultiListe @_SelectMListe nil ;
/*    _CBlistTabRSelect MultiListe @_RSelectMListe nil ;*/

    let Ht-2*step-3*Tstep -> Ystart in
    let 100 -> LargeLbtn in
    (
      /*Full DB access*/
      set FullAccessBttn =
      _ENbutton 
        _CBbutton 
          _CRbutton _channel EditorWin  	step 				Ystart 		LargeLbtn 		Tstep nil  (_locEditor "DB_FULLACCESS" nil)
          @_DbFullAccess
          nil
      0;
      /*Read DB Access*/
      set ReadAccessBttn =
      _ENbutton 
        _CBbutton 
          _CRbutton _channel EditorWin 	2*step+LargeLbtn 	Ystart 		LargeLbtn 		Tstep nil  (_locEditor "DB_READONLY" nil)
          @_DbReadAccess
          nil
        0;
      /*NO DB Access*/
      set NoAccessBttn =
      _ENbutton 
        _CBbutton 
          _CRbutton _channel EditorWin 	3*step+2*LargeLbtn 	Ystart 		LargeLbtn 		Tstep nil  (_locEditor "DB_NOACCESS" nil)
          @_DbNoAccess
          nil
        0;
      set PrimariKeyBttn =
      _ENbutton 
        _CBbutton 
          _CRbutton _channel EditorWin 	4*step+3*LargeLbtn 	Ystart 		LargeLbtn 		Tstep nil  (_locEditor "DB_KEY" nil)
          @_DbKey
          nil
        0
    )
  );

  _CBwinSize EditorWin @_ReSizeEditor nil;
  _PAINTwindow _SHOWwindow EditorWin WINDOW_UNHIDDEN
;;

fun IniEditor(filename)=

CreateApi filename;

if filename==nil then nil else openDMI ed;
0;;