Browse Source

More functionality implemented.

mingodad 13 years ago
parent
commit
72c72c7710
4 changed files with 885 additions and 12 deletions
  1. 355 0
      SquiLu-ourbiz/db-updater.nut
  2. 352 0
      SquiLu-ourbiz/delivery-info.json
  3. 177 12
      SquiLu-ourbiz/ourbiz-fltk.nut
  4. 1 0
      SquiLu/squilu.cbp

+ 355 - 0
SquiLu-ourbiz/db-updater.nut

@@ -0,0 +1,355 @@
+local globals = getroottable();
+
+if(!globals.get("HTTPConn", false)) dofile("ourbiz-client.nut");
+
+enum edbAction {e_none, e_insert, e_update, e_delete};
+
+class DBTableUpdateBase {
+	table_name = null;
+	_field_changes = null;
+	edit_id = null;
+	version = null;
+	_dbChanges = null;
+	dbAction = null;
+	hasVersion = null;
+	hasMdate = null;
+	useMultiPart = null;
+	useSLE = null;
+	static boundary = "----OurbizZ1X2c3LkUw";
+
+	constructor() {
+		table_name = "no_table_name";
+		edit_id = 0;
+		_dbChanges = 0;
+		dbAction = edbAction.e_none;
+		hasVersion = hasMdate = true;
+		useMultiPart = false;
+		useSLE = true;
+		_field_changes = [];
+	}
+
+	function get_fields_map_name(){return table_name;}
+
+	function add_http_param(httpBody, field, value){
+		if(useSLE){
+		    _field_changes.push([field, value.tostring()]);
+		}
+		else if(useMultiPart){
+		    httpBody.write(boundary);
+		    httpBody.write("\r\nContent-Disposition: form-data; name=\"");
+		    httpBody.write(field, "\"\r\n\r\n", value, "\r\n");
+		}
+		else
+		{
+		    if(httpBody.size() > 0) httpBody.write("&");
+		    httpBody .write(field, "=", url_encode(value));
+		}
+	}
+
+	function get_http_params(httpBody){
+		local key, value;
+		key = "__table__";
+		value = table_name;
+		add_http_param(httpBody, key, value);
+
+		key = "__action__";
+		switch(dbAction)
+		{
+		case edbAction.e_insert:
+		    value = "insert";
+		    break;
+		case edbAction.e_update:
+		    value = "update";
+		    break;
+		case edbAction.e_delete:
+		    value = "delete";
+		    break;
+		}
+		add_http_param(httpBody, key, value);
+
+		if(dbAction != edbAction.e_insert)
+		{
+		    key = "__id__";
+		    value = edit_id.tostring();
+		    add_http_param(httpBody, key, value);
+		}
+		if(hasVersion)
+		{
+		    key = "__version__";
+		    value = version.tostring();
+		    add_http_param(httpBody, key, value);
+		}
+	}
+
+	function afterDbActionHttpConn(request_result){}
+    
+	function doDbActionHttpConn(){
+		local my_result;
+		local httpRequest = HTTPConn(my_result);
+		appServer.httpcon_setup(httpRequest);
+
+		local httpBody = blob(0, 8192);
+		local url = "/DB/Action";
+		get_http_params(httpBody);
+
+		local body_str = null;
+		local nchanges = _field_changes.size();
+		if(useSLE){
+			httpBodyMemBuf = blob(0, 8192);
+			httpBodyMemBuf.write("[[");
+			for(local i=0; i<nchanges; ++i)
+			{
+				//printf("%s : %s\n", _field_changes[i].key,  _field_changes[i].val);
+				add2sle(httpBodyMemBuf, _field_changes[i][0]);
+			}
+			httpBodyMemBuf.write(SLEEND);
+			httpBodyMemBuf.write("][");
+			for(local i=0; i<nchanges; ++i)
+			{
+				add2sle(httpBodyMemBuf, _field_changes[i][1]);
+			}
+			httpBodyMemBuf.write(SLEEND);
+			httpBodyMemBuf.write("]]");
+
+			body_str = httpBodyMemBuf.tostring();
+		}
+		else
+		{
+			for(local i=0; i<nchanges; ++i)
+			{
+				add_http_param(httpBody, _field_changes[i][0], _field_changes[i][1]);
+			}
+			if(useMultiPart){
+				httpBody.write(boundary, "--\r\n");
+			}
+
+			body_str = httpBody.tostring();
+		}
+
+		httpRequest.send_my_request("POST", url, body_str, body_str.len(),
+					 useMultiPart ? boundary + 2 : 0, //+2 to discount "--"
+					 useSLE);
+		//local check_idle = globals.get("Fl", false);
+		while( httpRequest.outstanding() )
+		{
+			httpRequest.pump();
+			//if(check_idle) Fl.check();
+		}
+
+		if(httpRequest.my_status != 200){throw(my_result);}
+		switch(dbAction)
+		{
+		case edbAction.e_insert:
+		{
+			version = 0;
+			local rec = {};
+			sle2map(my_result, rec);
+			local new_id = rec.get("id", 0);
+			if(new_id == 0) throw("Could not update this record !");
+			edit_id = new_id;
+		}
+		break;
+		case edbAction.e_update:
+		case edbAction.e_delete:
+		{
+			local rec = {};
+			sle2map(my_result, rec);
+			local changes = rec.get("changes", 0);
+			if(changes == 0) {
+				if(dbAction == e_update) throw("Could not update this record !");
+				else throw("Could not delete this record !");
+			}
+			if(dbAction == edbAction.e_update) ++version;
+			else edit_id = version = 0;
+		}
+		break;
+		}
+		afterDbActionHttpConn(my_result);
+	}
+
+	function clear(){ _field_changes.clear();}
+
+	function value_extra(fld_name, fld_value)
+	{
+		_field_changes.push([fld_name, fld_value.tostring()]);
+	}
+
+	function value_for_insert(fld_name, fld_value)
+	{
+		if(dbAction == edbAction.e_insert) value_extra(fld_name, fld_value);
+	}
+
+	function getWhereClause(){return " where id=? ";}
+
+	function bindWhereClause(stmt, lastParam)
+	{
+		stmt.bind(++lastParam, edit_id);
+		return lastParam;
+	}
+
+	function get_db(){return null;}
+
+	function bind_field(stmt, pos, field, value){
+		local val = value.tostring();
+		//printf("%s\n", val);
+		if(val) stmt.bind(pos, val);
+		else stmt.bind_null(pos);
+	}
+
+	function insert_table(){
+		local nchanges = _field_changes.size();
+		if(nchanges)
+		{
+		    _dbChanges = 0;
+		    local db = get_db();
+		    if(!db) return;
+		    local sql = "insert into ";
+		    local sql2 = ") values(";
+		    sql += table_name + "(";
+		    for(local i=0; i<nchanges; ++i)
+		    {
+			sql += _field_changes[i][0] + "," + "?,";
+		    }
+		    //erase last comma
+		    sql = sql.slice(0, -1);
+		    sql2 = sql2.slice(0, -1);
+
+		    sql2 += ")";
+		    sql += sql2;
+
+		    //printf("%s\n", sql.c_str());
+
+		    local stmt = db.preapre(sql);
+		    for(local i=0; i<nchanges; ++i)
+		    {
+			local kv = _field_changes[i];
+			bind_field(stmt, i+1, kv[0], kv[1]);
+		    }
+		    _dbChanges = stmt.exec_dml();
+		    if(_dbChanges)
+		    {
+			edit_id = db->last_row_id();
+			version = 0;
+			clear();
+		    }
+		    else
+		    {
+			throw("Could not insert the record !");
+		    }
+		}
+	}
+
+	function update_table()
+	{
+		if(!edit_id) return;
+
+		local nchanges = _field_changes.size();
+		if(nchanges)
+		{
+		    _dbChanges = 0;
+		    local db = get_db();
+		    if(!db) return;
+
+		    local sql = "update "  + table_name + " set ";
+		    for(local i=0; i<nchanges; ++i)
+		    {
+			sql += _field_changes[i][0] + "=?,";
+		    }
+		    //erase last comma
+		    sql = sql.slice(0, -1);
+
+		    if(hasMdate) sql += " ,mdate=CURRENT_TIMESTAMP ";
+		    if(hasVersion) sql += " ,_version_ = _version_ + 1 ";
+		    sql += getWhereClause();
+		    if(hasVersion) sql += " and _version_=? ";
+		    //printf("%s\n", sql.c_str());
+
+		    local stmt = db.prepare(sql);
+		    for(local i=0; i<nchanges; ++i)
+		    {
+			local kv = _field_changes[i];
+			bind_field(stmt, i+1, kv[0], kv[1]);
+		    }
+		    local lastParam = bindWhereClause(stmt, nchanges);
+		    if(hasVersion) stmt.bind(lastParam+1, version);
+		    //printf("%d\n", version);
+		    _dbChanges = stmt.exec_dml();
+		    if(_dbChanges)
+		    {
+			version++;
+			clear();
+		    }
+		    else
+		    {
+			throw("Could not update the record !");
+		    }
+		}
+	}
+
+	function delete_record()
+	{
+		if(!edit_id) return;
+
+		local db = get_db();
+		if(!db) return;
+
+		_dbChanges = 0;
+		local sql = "delete from " + table_name + getWhereClause();
+		if(hasVersion) sql += " and _version_=? ";
+		local stmt = db.prepare(sql);
+		local lastParam = bindWhereClause(stmt, 0);
+		if(hasVersion) stmt.bind(lastParam+1, version);
+		_dbChanges = stmt.exec_dml();
+		if(_dbChanges)
+		{
+		    version = 0;
+		    edit_id = 0;
+		    clear();
+		}
+		else
+		{
+		    throw("Could not delete the record !");
+		}
+	}
+
+	function execAction()
+	{
+		switch(dbAction)
+		{
+		case edbAction.e_insert:
+		    insert_table();
+		    break;
+		case edbAction.e_update:
+		    update_table();
+		    break;
+		case edbAction.e_delete:
+		    delete_record();
+		    break;
+		}
+	}
+};
+
+class DBTableUpdateByDB extends DBTableUpdateBase {
+	_db = null;
+
+	constructor(){
+		base.constructor();
+	}
+	function get_db(){return _db;}
+};
+
+class DBTableUpdate extends DBTableUpdateBase {
+
+	constructor(){
+		base.constructor();
+	}
+	function get_db(){
+		local appServer = AppServer.getAppServer();
+		if(appServer.get_conn_type() == AppServer.e_conn_http)
+		{
+			doDbActionHttpConn();
+			return 0;
+		}
+		return appServer.get_db();
+	}
+};

+ 352 - 0
SquiLu-ourbiz/delivery-info.json

@@ -0,0 +1,352 @@
+{
+"provincias" : [
+[1,4,"ALAVA", "Victoria"],
+[2,4,"ALBACETE", "Albacete"],
+[3,3,"ALICANTE", "Alicante", "Crevillente", "Elche", "Elda", "Matola", "San Felipe Neri", "San Juan", "San Vicente de Raspeig", "Torrellano", "Valverde"],
+[4,8,"ALMERIA", "Almeria", "Aguadulce", "Benahadux", "El Ejido", "Huercal de Almería", "La Cañada", "Pechina", "Viator", "Vicar"],
+[33,4,"ASTURIAS", "Oviedo", "Gijón", "Avilés"],
+[5,4,"AVILA", "Ávila"],
+[6,3,"BADAJOZ", "Badajoz"],
+[7,13,"BALEARES, ISLAS", "Palma de Mallorca"],
+[8,1,"BARCELONA", "Barcelona", "Badalona", "Badia", "Cornella de Llobregat", "Hospitalet de Llobregat", "La Florida", "La Llagosta", "Mollet del Valles", "Moncada y Reixach", "Parets del Valles", "San Adrián del Besós", "San Justo Desvern", "Santa Coloma de Gramanet", "Santa Perpetua de Mogoda"],
+[9,1,"BURGOS", "Burgos"],
+[10,3,"CACERES", "Cáceres"],
+[11,9,"CADIZ", "Cadiz", "Jerez", "Puerto Real", "Puerto de Santa María", "San Fernando"],
+[112,8,"CADIZ-Algeciras", "Algeciras", "Estación de San Roque", "La Línea", "Los Barrios", "Palmones", "San Roque"],
+[39,4,"CANTABRIA", "Santander", "Torrelavega"],
+[12,4,"CASTELLON", "Castellón", "Almazora", "El Grao", "Villarreal de los Infantes"],
+[51,-1,"CEUTA", "Ceuta"],
+[13,4,"CIUDAD REAL", "Ciudad Real"],
+[14,8,"CORDOBA", "Córdoba", "Cabra", "Albedín", "Alcolea", "El Higuerón", "Monturque", "Priego de Córdoba", "Santa Cruz", "Villarrubia", "Villaviciosa"],
+[15,4,"CORUÑA, LA", "La Coruña", "Arteixo", "Bergondo", "Betanzos", "Cambre", "Culleredo", "El Ferrol", "Oleiros", "Padrón y Santiago"],
+[16,4,"CUENCA", "Cuenca"],
+[17,4,"GERONA", "Gerona", "Aiguaviva", "El Perelló", "Salt", "Vilablareix"],
+[18,8,"GRANADA", "Granada", "Albolote", "Armilla", "Atarfe", "Cerrillo de Maracena", "Huetor Vega", "Maracena", "Ogijares", "Peligros", "Pinos Puente", "Pulianas", "Santa Fe"],
+[19,4,"GUADALAJARA", "Guadalajara"],
+[20,4,"GUIPUZCOA", "Hernani", "Lasarte", "San Sebastián", "Usurbil"],
+[21,9,"HUELVA", "Huelva", "Aljaraque", "Bea", "Gibrale?n", "Moguer", "Pozo del Camino", "San Juan del Puerto"],
+[22,4,"HUESCA", "Huesca"],
+[23,8,"JAEN", "Jaen", "Andujar", "Bailén", "Linares", "Torredelcampo", "Ubeda"],
+[24,4,"LEON", "Leon"],
+[25,4,"LERIDA", "Lérida"],
+[27,4,"LUGO", "Lugo"],
+[28,3,"MADRID", "Madrid", "Alcobendas", "Alcorcón", "Coslada", "Fuenlabrada", "Getafe", "Leganés", "Pinto", "San Fernando de Henares", "San Sebastián de los Reyes", "Torrejón de Ardoz"],
+[29,10,"MALAGA", "Málaga todas poblaciones"],
+[52,-1,"MELILLA", "Mellilla"],
+[30,6,"MURCIA", "Murcia", "Alcantarilla", "Algezares", "Aljucer", "Beniaján", "Cabezo de Torres", "Cabezo Cortado", "El Palmar", "El Puntal", "Espinardo", "La Albatalia", "La Azacaya", "Molina de Segura", "Nonduermas", "Puente Tocinos", "San Ginés"],
+[31,4,"NAVARRA", "Panplona", "Barrioplano", "Berriozar", "Burlada", "Huarte", "Mutilva Alta", "Mutilva Baja", "Noain", "Villava"],
+[32,4,"OURENSE", "Orense", "San Ciprián das Viñas"],
+[34,1,"PALENCIA", "Palencia", "Dueñas"],
+[35,-1,"PALMAS, LAS", "Las Palmas de Gran Canaria"],
+[36,4,"PONTEVEDRA", "Pontevedra", "Marín", "Mos", "Porriño", "Puixeros", "Redondela y Vigo"],
+[26,4,"RIOJA, LA", "Logroño"],
+[37,1,"SALAMANCA", "Salamanca", "Cabrerizos", "Carbajosa de la Sagrada", "Castellanos de Moriscos", "Villares de la Reina"],
+[38,-1,"SANTA CRUZ DE TENERIFE", "Santa Cruz de Tenerife"],
+[40,4,"SEGOVIA", "Segovia"],
+[41,8,"SEVILLA", "Sevilla", "Alcalá de Guadaira", "Bormujos", "Camas", "Castilleja de la Cuesta", "Dos Hermanas", "Gines", "La Rinconada", "Mairena de Aljarafe", "San Juan de Aznalfarache", "Santiponce", "Tomares", "Valencina de la Concepción"],
+[42,4,"SORIA", "Soria"],
+[43,4,"TARRAGONA", "Tarragona", "Reus"],
+[44,4,"TERUEL", "Teruel"],
+[45,4,"TOLEDO", "Toledo"],
+[46,3,"VALENCIA", "Valencia", "Alacuas", "Aldaya", "Burjasot", "Chirivella", "Mislata", "Nazaret", "Paiporta", "Paterna", "Pica?a", "Tabernes Blanques", "Torrente", "Vinalesa"],
+[47,1,"VALLADOLID", "Valladolid", "Cigales", "Fuensaldaña", "Laguna de Duero", "La Cisternita", "Tudela de Duero", "Villanuela"],
+[48,4,"VIZCAYA", "Arrigorriaga", "Astraduba", "Asua", "Baracaldo", "Basauri", "Bilbao", "Cruces", "Erandio", "Etxeberri", "Galdacano", "Guetxo", "Lejona", "Loiu", "Portugalete", "San Salvador del Valle", "Sondica", "Trápaga", "Zorroza"],
+[49,1,"ZAMORA", "Zamora"],
+[50,1,"ZARAGOZA", "Zaragoza", "Alfajarón", "Cadrete", "Casetas", "Cuarte de Huerva", "Burgo de Ebro", "Figueruelas", "La Cartuja", "La Puebla de Alfinden", "María de Huerva", "Monzalbarba", "Pastriz", "San Juan de Mozarrifar", "Utebo", "Villafranca de Ebro", "Villanueva de Gállego y Zuera"]
+],
+
+"peso_escala" : [
+10,
+20,
+30,
+40,
+50,
+60,
+70,
+80,
+90,
+100,
+120,
+140,
+160,
+180,
+200,
+250,
+300,
+350,
+400,
+450,
+500,
+600,
+700,
+800,
+900,
+1000,
+1001
+],
+
+"precio_baremo_descuento" : [
+0,
+0.2,
+0,
+0.2,
+0.2,
+0,
+0.2,
+0,
+0.2,
+0.2,
+0.2
+],
+
+"precio_baremo" : [
+[],
+[
+	9.92,
+	15.78,
+	20.82,
+	24.96,
+	29.31,
+	34.02,
+	37.35,
+	40.61,
+	44.17,
+	50.02,
+	56.12,
+	62.99,
+	69.76,
+	77.33,
+	85.13,
+	98.84,
+	110.31,
+	126.09,
+	139.18,
+	151.17,
+	162.06,
+	194.13,
+	217.55,
+	238.95,
+	251.33,
+	270.43,
+	249.84
+],
+[],
+[
+	8.66,
+	13.05,
+	16.83,
+	20.59,
+	24.03,
+	28.03,
+	31.35,
+	32.79,
+	37.13,
+	41.30,
+	46.25,
+	52.33,
+	57.95,
+	64.03,
+	69.76,
+	80.35,
+	90.42,
+	102.13,
+	112.26,
+	122.21,
+	127.94,
+	154.62,
+	171.66,
+	185.62,
+	209.25,
+	226.53,
+	205.71
+],
+[
+	10.69,
+	16.99,
+	22.42,
+	26.87,
+	31.57,
+	37.15,
+	42.57,
+	46.62,
+	51.34,
+	53.87,
+	62.68,
+	69.92,
+	75.13,
+	83.28,
+	91.68,
+	103.51,
+	118.80,
+	135.79,
+	150.10,
+	165.42,
+	170.92,
+	203.46,
+	228.00,
+	250.43,
+	262.01,
+	282.59,
+	260.34
+],
+[],
+[
+	8.20,
+	12.65,
+	16.71,
+	19.62,
+	23.39,
+	27.10,
+	29.95,
+	32.37,
+	35.12,
+	36.93,
+	42.34,
+	47.32,
+	52.36,
+	58.19,
+	63.41,
+	77.69,
+	89.77,
+	102.47,
+	110.61,
+	121.86,
+	127.50,
+	149.20,
+	166.13,
+	177.42,
+	189.34,
+	194.80,
+	175.06
+],
+[],
+[
+	7.07,
+	10.93,
+	13.15,
+	15.60,
+	18.06,
+	20.28,
+	22.50,
+	24.72,
+	26.60,
+	28.69,
+	32.38,
+	35.54,
+	38.46,
+	41.73,
+	44.89,
+	52.25,
+	59.34,
+	67.58,
+	74.58,
+	81.30,
+	87.50,
+	102.59,
+	115.85,
+	129.00,
+	142.15,
+	155.01,
+	147.99
+],
+[
+	7.78,
+	11.97,
+	14.76,
+	17.38,
+	19.99,
+	22.54,
+	24.96,
+	27.52,
+	29.58,
+	31.96,
+	35.90,
+	39.43,
+	42.70,
+	46.41,
+	49.94,
+	58.08,
+	65.96,
+	74.95,
+	82.66,
+	90.45,
+	97.37,
+	114.08,
+	128.78,
+	143.24,
+	157.81,
+	172.13,
+	161.95
+],
+[
+	4.45,
+	5.84,
+	6.85,
+	8.01,
+	9.13,
+	9.53,
+	10.64,
+	11.52,
+	12.92,
+	14.20,
+	16.08,
+	18.06,
+	20.41,
+	22.39,
+	24.26,
+	27.31,
+	29.75,
+	33.78,
+	36.82,
+	39.57,
+	42.38,
+	48.98,
+	54.78,
+	61.26,
+	67.58,
+	73.77,
+	66.52
+],
+[],
+[],
+[
+	16.98,
+	22.22,
+	28.43,
+	34.21,
+	40.16,
+	46.36,
+	51.48,
+	56.44,
+	61.15,
+	66.09,
+	74.66,
+	82.84,
+	90.64,
+	98.70,
+	107.74,
+	130.28,
+	151.50,
+	171.22,
+	189.82,
+	208.30,
+	220.92,
+	254.53,
+	283.62,
+	310.32,
+	329.62,
+	352.21,
+	323.77
+],
+[]
+],
+
+"baremoReexpedidion" : 10,
+
+"seguro" : 0.08,
+
+"descuento" : 0.2,
+
+"recargoCombustible" : 0.04
+}
+

+ 177 - 12
SquiLu-ourbiz/ourbiz-fltk.nut

@@ -2,6 +2,7 @@ local WIN32 = os.getenv("WINDIR") != null
 socket.open();
 
 dofile("ourbiz-client.nut");
+dofile("db-updater.nut");
 local appServer = AppServer.getAppServer();
 appServer.credentials("mingote", "tr14pink");
 appServer.connect("localhost", 8855);
@@ -251,6 +252,8 @@ class MyBaseWindow extends Fl_Window {
 		tbl_map[fldname] <- fld;
 	}
 
+	function get_input_fields(dbname){ return _db_map.get(dbname, null);}
+
 	function getChildWindow(winName, WindowClass){
 		local win = childWindows.get(winName, false);
 		if(!win){
@@ -341,11 +344,82 @@ class MyBaseWindow extends Fl_Window {
 	}
 }
 
+class DBUpdateByWidget extends DBTableUpdate
+{
+	constructor(){
+		base.constructor();
+	}
+
+	function get_widget_value(inputs){
+		foreach(fld_name, wdg in inputs){
+			//printf("%s : %s : %s\n", fld_name, wdg->classId(), Fl_Check_Button.className());
+			if(wdg instanceof Fl_Text_Editor){
+				get_widget_value(wdg, fld_name);
+				if((dbAction == e_insert) || wgt->changed2())
+				{
+					_field_changes.push([fld_name, wgt->buffer()->text()]);
+				}
+			}
+			else if(wdg instanceof Fl_Check_Button){
+				if((dbAction == e_insert) || wgt->changed2())
+				{
+					_field_changes.push([fld_name, wgt->value() ? "1" : "0"]);
+				}
+			}
+			else if(wdg instanceof Fl_Choice_Str){
+				if((dbAction == e_insert) || wgt->changed2())
+				{
+					_field_changes.push([fld_name, wgt->my_get_value()]);
+				}
+			}
+			else if(wdg instanceof Fl_Choice_Int){
+				if((dbAction == e_insert) || wgt->changed2())
+				{
+					_field_changes.push([fld_name, wgt->my_get_value_str()]);
+				}
+			}
+			else if(wdg instanceof Flu_Combo_Box){
+				if((dbAction == e_insert) || wgt->input.changed2())
+				{
+					_field_changes.push([fld_name, wgt->get_data_at().tostring()]);
+				}
+			}
+			else if(wdg instanceof Flu_Tree_Browser){
+				if((dbAction == e_insert) || wdg->changed2())
+				{
+					local tmp = "";
+					local node = wdg->get_hilighted();
+					if(node) {
+						local value = node->user_data();
+						if(value) tmp  = value.tostring();
+					}
+					_field_changes.push([fld_name, tmp]);
+				}
+			}
+			else if(wdg instanceof Fl_Input_){
+				if((dbAction == e_insert) || wgt->changed2())
+				{
+					_field_changes.push([fld_name, wgt->value()]);
+				}
+			}
+		}
+	}
+
+	function validate_regex(wdg,  re, emptyTrue=false)
+	{
+		local value = wdg->value();
+		if(emptyTrue && (!value || !value.len())) return true;
+		if(!re || !value) return false;
+		return value.find_lua(re);
+	}
+}
+
 class EditWindow extends MyBaseWindow {
 	_record = null;
 	_id = null;
 	_main_table = null;
 	_version_ = null;
+	_dbUpdater = null;
 
 	constructor(px, py, pw, ph, pl){
 		base.constructor(px, py, pw, ph, pl);
@@ -411,6 +485,104 @@ class EditWindow extends MyBaseWindow {
 			//choice->add(rec[1]);
 		}
 	}
+	
+	function on_Change_dbAction()
+	{
+		local colors = [255, 95, 79, 90, 238, 238, 238, 238];
+		local idx = dbAction->action();
+		btnDbAction->label(dbAction->text());
+		btnDbAction->color(colors[idx]);
+	}
+	function on_btnDbAction()
+	{
+		local cursor_wait = fl_cursor_wait();
+		switch(dbAction->action())
+		{
+		case DbAction_Enum.e_insert:
+		    do_insert();
+		    break;
+		case DbAction_Enum.e_update:
+		    do_update();
+		    break;
+		case DbAction_Enum.e_delete:
+		    do_delete();
+		    break;
+		case DbAction_Enum.e_export:
+		    do_export();
+		    break;
+		case DbAction_Enum.e_import:
+		    do_import();
+		    break;
+		case DbAction_Enum.e_refresh:
+		    do_refresh();
+		    break;
+		case DbAction_Enum.e_copy:
+		    do_copy();
+		    break;
+		}
+	}
+	function do_edit(aid){
+		local dbu = dbUpdater();
+		dbu->edit_id = aid;
+		dbu->version = 0;
+		dbAction->action(aid ? DbAction_Enum.e_update : Fl_Choice_dbAction::e_insert);
+		on_Change_dbAction();
+		delayed_method_call(this, this.do_edit_delayed, aid);
+	}
+	function do_edit_delayed(udata){}
+	function fill_edit_form(asBlank=false){
+		if(asBlank) _record.clear();
+		local  wfq = WidgetFillByMap(_record);
+		local input_fld_map = get_input_fields(dbUpdater()->get_fields_map_name());
+		wfq.set_widget_value(input_fld_map);
+		wfq.get("_version_", dbUpdater()->version);
+	}
+	function get_widget_changed(uw){
+		local input_fld_map = get_input_fields(dbUpdater()->get_fields_map_name());
+		uw.get_widget_value(input_fld_map);
+	}
+	function do_insert(){
+		//fl_alert("do_insert");
+		local dbu = dbUpdater();
+		dbu->dbAction = edbAction.e_insert;
+		dbu->clear();
+		get_widget_changed(dbu);
+		dbu->insert_table();
+		if(_formGroup) clear_changed_on_group(_formGroup);
+		dbAction->action(DbAction_Enum.e_update);
+		on_Change_dbAction();
+	}
+	function do_update(){
+		//fl_alert("do_update");
+		local dbu = dbUpdater();
+		dbu->dbAction = edbAction.e_update;
+		dbu->clear();
+		get_widget_changed(dbu);
+		dbu->update_table();
+		if(_formGroup) clear_changed_on_group(_formGroup);
+	}
+	function do_delete()	{
+		//fl_alert("do_delete");
+		local dbu = dbUpdater();
+		dbu->dbAction = edbAction.e_delete;
+		dbu->clear();
+		dbu->delete_record();
+		dbAction->action(DbAction_Enum.e_insert);
+		on_Change_dbAction();
+	}
+	function do_export(){/*fl_alert("do_delete");*/}
+	function do_import(){/*fl_alert("do_delete");*/}
+	function do_refresh(){/*fl_alert("do_delete");*/}
+	function do_copy(){/*fl_alert("do_delete");*/}
+	
+	function dbUpdater(dbu){
+		_dbUpdater = dbu;
+	}
+
+	function dbUpdater(){
+		if(!_dbUpdater) _dbUpdater = new DBUpdateByWidget();
+		return _dbUpdater;
+	}	
 }
 
 enum Fl_Data_Table_Events {e_none, e_event, e_select, e_insert, e_update, e_delete};
@@ -739,12 +911,10 @@ class MyListSearchWindow extends ListSearch {
 
 	function get_search_data(data){}
 	function fill_grid(){
-		//SafeCursorWait cursor_wait;
-		fl_cursor(FL_CURSOR_WAIT);
+		local cursor_wait = fl_cursor_wait();
 		grid->clear_data_rows();
 		get_search_data(grid->_data);
 		grid->recalc_data();
-		fl_cursor(FL_CURSOR_DEFAULT);
 	}
 	function cb_btnSearch(sender, udata){
 		this = sender.window();
@@ -830,7 +1000,7 @@ class OurSalesTax extends SalesTaxRatesEditWindow {
 		fill_grid();
 	}
 	function fill_grid(){
-		//SafeCursorWait cursor_wait;
+		local cursor_wait = fl_cursor_wait();
 		grid->clear_data_rows();
 		appServer.sales_tax_rates_get_list(grid->_data);
 		grid->recalc_data();
@@ -839,8 +1009,7 @@ class OurSalesTax extends SalesTaxRatesEditWindow {
 
 function print_entities_list_contact_report()
 {
-	//SafeCursorWait cursor_wait;
-	fl_cursor(FL_CURSOR_WAIT);
+	local cursor_wait = fl_cursor_wait();
 	local mydata = [];
 	appServer.entities_toprint_get_list(mydata);
 
@@ -897,7 +1066,6 @@ function print_entities_list_contact_report()
 	    printer.end_page();
 	}
 	printer.end_job();
-	fl_cursor(FL_CURSOR_DEFAULT);
 }
 
 class MyEditEntityWindow extends EditEntityWindow {
@@ -965,8 +1133,7 @@ class EntitiesListSearch extends MyListSearchWindow {
 
 function print_products_list()
 {
-	//SafeCursorWait cursor_wait;
-	fl_cursor(FL_CURSOR_WAIT);
+	local cursor_wait = fl_cursor_wait();
 	local mydata = [];
 	appServer.products_list_get_list(mydata);
 
@@ -1030,7 +1197,6 @@ function print_products_list()
             printer.set_current();
 	}
 	printer.end_job();
-	fl_cursor(FL_CURSOR_DEFAULT);
 }
 
 class MyEditProductWindow extends EditProductWindow {
@@ -1233,7 +1399,7 @@ class MyEditOrderWindow extends EditOrderWindow {
 		fill_choice_by_data(db_orders_payment_type_id, data);
 	}
 	function do_edit_delayed(udata){
-		fl_cursor(FL_CURSOR_WAIT);
+		local cursor_wait = fl_cursor_wait();
 		local lines = grid_lines->_data;
 		grid_lines->clear_data_rows();
 		_line_edit_id = 0;
@@ -1251,7 +1417,6 @@ class MyEditOrderWindow extends EditOrderWindow {
 		redraw_lines(false);
 		fill_edit_form(_id == 0);
 		delayed_focus(db_orders_entity_id);
-		fl_cursor(FL_CURSOR_DEFAULT);
 	}
 
 	function fill_edit_form(asBlank=false){

+ 1 - 0
SquiLu/squilu.cbp

@@ -107,6 +107,7 @@
 					<Add directory="../fltk" />
 					<Add directory="../third-party/flu" />
 					<Add directory="../libharu/include" />
+					<Add directory="../flu" />
 				</Compiler>
 				<Linker>
 					<Add option="-s" />