Commit 889b9572 by Arturo Montejo Ráez

Merge branch 'master' of http://scm.ujaen.es/softuno/pictogram

parents 25c0f999 f4d53000
Showing with 404 additions and 275 deletions
...@@ -3,12 +3,6 @@ apply plugin: 'com.android.application' ...@@ -3,12 +3,6 @@ apply plugin: 'com.android.application'
android { android {
signingConfigs { signingConfigs {
release_config { release_config {
/*
storeFile file('F:/Users/Fernando/GoogleDrive/tmp/keystore.jks')
keyAlias 'default_key'
keyPassword 'danoia'
storePassword 'danoia'
*/
} }
} }
compileSdkVersion 21 compileSdkVersion 21
...@@ -32,17 +26,17 @@ android { ...@@ -32,17 +26,17 @@ android {
resValue "bool", "force_img_download", "false" resValue "bool", "force_img_download", "false"
resValue "integer", "netservice_timing", "20" resValue "integer", "netservice_timing", "20"
resValue "integer", "rows", "5" resValue "integer", "rows", "5"
resValue "integer", "columns", "8" resValue "integer", "columns", "10"
} }
debug { debug {
resValue "string", "db_name", "PCB.db" resValue "string", "db_name", "PCB.db"
resValue "bool", "force_db_create", "false" resValue "bool", "force_db_create", "true"
resValue "bool", "ssl_connect", "false" resValue "bool", "ssl_connect", "false"
resValue "bool", "force_img_download", "false" resValue "bool", "force_img_download", "false"
resValue "integer", "netservice_timing", "20" resValue "integer", "netservice_timing", "20"
resValue "integer", "rows", "5" resValue "integer", "rows", "5"
resValue "integer", "columns", "8" resValue "integer", "columns", "10"
} }
} }
productFlavors { productFlavors {
......
...@@ -83,7 +83,7 @@ public class Translate extends Activity implements iVocabularyListener, iImgDown ...@@ -83,7 +83,7 @@ public class Translate extends Activity implements iVocabularyListener, iImgDown
PCBcontext.init(this); PCBcontext.init(this);
PCBcontext.getDevice().setSerial("serial1"); PCBcontext.getDevice().setSerial("serial1");
PCBcontext.getDevice().setDeviceID("deviceID"); PCBcontext.getDevice().setDeviceID("deviceID");
PCBcontext.getDevice().deleteDeprecatedImgs();
PCBcontext.set_user(alumno_picto, TOKEN, this); PCBcontext.set_user(alumno_picto, TOKEN, this);
Log.i(LOG_TAG, "2) OnCreate - Serial:" + PCBcontext.getDevice().getSerial() + " dev. id:" + Log.i(LOG_TAG, "2) OnCreate - Serial:" + PCBcontext.getDevice().getSerial() + " dev. id:" +
PCBcontext.getDevice().getDeviceID() + " token:" + TOKEN); PCBcontext.getDevice().getDeviceID() + " token:" + TOKEN);
......
...@@ -17,6 +17,13 @@ ...@@ -17,6 +17,13 @@
<android:uses-permission android:name="android.permission.READ_PHONE_STATE" /> <android:uses-permission android:name="android.permission.READ_PHONE_STATE" />
<android:uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <android:uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- To auto-complete the email text field in the login form with the user's emails -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<android:uses-permission android:name="android.permission.READ_CALL_LOG" />
<application <application
android:name=".kiosk.AppContext" android:name=".kiosk.AppContext"
android:allowBackup="true" android:allowBackup="true"
...@@ -36,24 +43,22 @@ ...@@ -36,24 +43,22 @@
<activity <activity
android:name=".gui.MainActivity" android:name=".gui.MainActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:screenOrientation="landscape"> android:screenOrientation="landscape" />
</activity>
<activity <activity
android:name=".gui.SerialActivity" android:name=".gui.SerialActivity"
android:label="@string/title_activity_serial" android:label="@string/title_activity_serial"
android:screenOrientation="landscape"> android:screenOrientation="landscape" />
</activity>
<activity <activity
android:name=".gui.LoginActivity" android:name=".gui.LoginActivity"
android:exported="true" android:exported="true"
android:label="@string/title_activity_login_activity_fragments" android:label="@string/title_activity_login_activity_fragments"
android:screenOrientation="landscape"/> android:screenOrientation="landscape" />
<activity <activity
android:name=".gui.PictogramActivity" android:name=".gui.PictogramActivity"
android:exported="true" android:exported="true"
android:label="@string/app_name" android:label="@string/app_name"
android:launchMode="singleTop" android:launchMode="singleTop"
android:screenOrientation="landscape"/> android:screenOrientation="landscape" />
<!-- Intent Filter to run the app when the boot is completed --> <!-- Intent Filter to run the app when the boot is completed -->
<receiver android:name=".kiosk.BootReceiver"> <receiver android:name=".kiosk.BootReceiver">
<intent-filter> <intent-filter>
...@@ -66,7 +71,16 @@ ...@@ -66,7 +71,16 @@
android:exported="false" /> android:exported="false" />
<service <service
android:name=".net.NetService" android:name=".net.NetService"
android:exported="false"/> android:exported="false" />
<activity
android:name=".ImgLabelActivity"
android:label="@string/title_activity_img_label"
android:parentActivityName=".gui.PictogramActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.yottacode.pictogram.gui.PictogramActivity" />
</activity>
</application> </application>
</manifest> </manifest>
...@@ -116,48 +116,50 @@ public class RestapiWrapper { ...@@ -116,48 +116,50 @@ public class RestapiWrapper {
public static boolean ping(String server, String ping_op, iRestapiListener error_listener) { public static boolean ping(String server, String ping_op, iRestapiListener error_listener) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy); StrictMode.setThreadPolicy(policy);
boolean pingResult = GET(server + "/" + ping_op, null, error_listener)!=null; boolean pingResult = false;
try {
pingResult = GET(server + "/" + ping_op, null)!=null;
} catch (IOException e) {
e.printStackTrace();
Log.e(com.yottacode.net.RestapiWrapper.class.getName(), "ping failed at"+ping_op);
error_listener.error(e);
}
return pingResult; return pingResult;
} }
public static String GET(String surl, Hashtable<String, String> params, iRestapiListener listener) { public static String GET(String surl, Hashtable<String, String> params) throws IOException {
String result=null; String result=null;
InputStream inputStream = null; InputStream inputStream = null;
URL url = null; URL url = null;
try {
if (params!=null) { if (params!=null) {
surl += '?'; surl += '?';
for (String param : params.keySet()) { for (String param : params.keySet()) {
String value = params.get(param); String value = params.get(param);
surl += param + '=' + value + '&'; surl += param + '=' + value + '&';
} }
surl=surl.substring(0,surl.length()-1); surl=surl.substring(0,surl.length()-1);
} }
url = new URL(surl); url = new URL(surl);
HttpURLConnection urlConnection = null; HttpURLConnection urlConnection = null;
urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setReadTimeout(60000); urlConnection.setReadTimeout(60000);
urlConnection.setConnectTimeout(60000); urlConnection.setConnectTimeout(60000);
urlConnection.setRequestMethod("GET"); urlConnection.setRequestMethod("GET");
urlConnection.setDoInput(true); urlConnection.setDoInput(true);
urlConnection.connect(); urlConnection.connect();
inputStream = urlConnection.getInputStream(); inputStream = urlConnection.getInputStream();
// convert inputstream to string // convert inputstream to string
if (inputStream!=null) result = convertInputStreamToString(inputStream); if (inputStream!=null) result = convertInputStreamToString(inputStream);
} catch (IOException e) {
if (listener!=null) listener.error(e);
result=e.getMessage();
}
return result; return result;
} }
public String POST(String surl, String request_method, Hashtable<String, String> params, boolean json_params) { public String POST(String surl, String request_method, Hashtable<String, String> params, boolean json_params) throws IOException {
URL url = null; URL url = null;
String response = ""; String response = "";
try {
url = new URL(surl); url = new URL(surl);
HttpURLConnection urlConnection = null; HttpURLConnection urlConnection = null;
...@@ -206,10 +208,6 @@ public class RestapiWrapper { ...@@ -206,10 +208,6 @@ public class RestapiWrapper {
while ((line=br.readLine()) != null) { while ((line=br.readLine()) != null) {
response+=line; response+=line;
} }
} catch (IOException e) {
Log.e(com.yottacode.net.RestapiWrapper.class.getName(), "Error:" + e.getLocalizedMessage() + " when asking for " + surl);
response=e.getMessage();
}
return response; return response;
} }
...@@ -233,6 +231,7 @@ public class RestapiWrapper { ...@@ -233,6 +231,7 @@ public class RestapiWrapper {
protected boolean json_params; protected boolean json_params;
protected iRestapiListener listener; protected iRestapiListener listener;
protected String result; protected String result;
protected Exception error;
} }
private class HttpAsyncTask extends AsyncTask<HttpAsyncTaskParams, Void, HttpAsyncTaskParams> { private class HttpAsyncTask extends AsyncTask<HttpAsyncTaskParams, Void, HttpAsyncTaskParams> {
...@@ -240,9 +239,15 @@ public class RestapiWrapper { ...@@ -240,9 +239,15 @@ public class RestapiWrapper {
@Override @Override
protected HttpAsyncTaskParams doInBackground(HttpAsyncTaskParams... params) { protected HttpAsyncTaskParams doInBackground(HttpAsyncTaskParams... params) {
params[0].result = params[0].request_method.equalsIgnoreCase("GET") try {
? GET(params[0].url, params[0].url_params, null) params[0].result = params[0].request_method.equalsIgnoreCase("GET")
: POST(params[0].url, params[0].request_method, params[0].url_params, params[0].json_params); ? GET(params[0].url, params[0].url_params)
: POST(params[0].url, params[0].request_method, params[0].url_params, params[0].json_params);
} catch (IOException e) {
Log.e(com.yottacode.net.RestapiWrapper.class.getName(), "Error:" + e.getLocalizedMessage() + " when asking for " + params[0].url);
params[0].result=null;
params[0].error=e;
}
return params[0]; return params[0];
} }
...@@ -250,9 +255,10 @@ public class RestapiWrapper { ...@@ -250,9 +255,10 @@ public class RestapiWrapper {
@Override @Override
protected void onPostExecute(HttpAsyncTaskParams params) { protected void onPostExecute(HttpAsyncTaskParams params) {
try { try {
//if (params.e) if (params.error!=null) params.listener.error(params.error);
else
if(params.result!=null) { if(params.result!=null) {
Log.d(LOG_TAG, "JSON: " + params.result); Log.i(LOG_TAG, "Picto JSON Result: " + params.result);
Object jsonResult = new JSONTokener(params.result).nextValue(); Object jsonResult = new JSONTokener(params.result).nextValue();
if (jsonResult instanceof JSONObject) { if (jsonResult instanceof JSONObject) {
...@@ -269,7 +275,7 @@ public class RestapiWrapper { ...@@ -269,7 +275,7 @@ public class RestapiWrapper {
} catch (JSONException e) { } catch (JSONException e) {
params.listener.error(e); params.listener.error(e);
} }
params.url_params.clear(); if (params.url_params!=null) params.url_params.clear();
} }
} }
} }
\ No newline at end of file
...@@ -52,7 +52,7 @@ public abstract class Action { ...@@ -52,7 +52,7 @@ public abstract class Action {
jsonObject.put(param_id_sup,PCBcontext.getPcbdb().getCurrentUser().get_id_sup()); jsonObject.put(param_id_sup,PCBcontext.getPcbdb().getCurrentUser().get_id_sup());
//TODO Decidir qué almacenar con DEVICE //TODO Decidir qué almacenar con DEVICE
//if (PCBcontext.getDevice().getDeviceID()!=null) //if (PCBcontext.getDevice().getDeviceID()!=null)
// jsonObject.put(param_id_dev, PCBcontext.getDevice().getDeviceID()); //jsonObject.put(param_id_dev, PCBcontext.getDevice().getDeviceID());
return jsonObject; return jsonObject;
}catch(JSONException e) { }catch(JSONException e) {
......
...@@ -35,10 +35,10 @@ public class ActionLog implements iRestapiListener { ...@@ -35,10 +35,10 @@ public class ActionLog implements iRestapiListener {
*/ */
public void log(Action action) { public void log(Action action) {
if (PCBcontext.getRoom().inRoom()) if (PCBcontext.getRoom().inRoom())
PCBcontext.getRoom().emit(action.get_action(), action); PCBcontext.getRoom().emit(action);
else { else {
// If there is no room, the action is stored in local DB // If there is no room, the action is stored into the local DB
PCBcontext.getPcbdb().insertAction(action); PCBcontext.getPcbdb().insertAction(action);
actions_buffer.add(action.getDescription()); actions_buffer.add(action.getDescription());
Log.i(this.getClass().getCanonicalName(), " Batch action included: " + action.getDescription()); Log.i(this.getClass().getCanonicalName(), " Batch action included: " + action.getDescription());
...@@ -50,13 +50,19 @@ public class ActionLog implements iRestapiListener { ...@@ -50,13 +50,19 @@ public class ActionLog implements iRestapiListener {
if (!actions_buffer.isEmpty()) { if (!actions_buffer.isEmpty()) {
Hashtable<String, String> params=new Hashtable<>(1); Hashtable<String, String> params=new Hashtable<>(1);
String url="stu/actions_batch"; String url="stu/actions_batch";
String actions=""; JSONArray actions= new JSONArray();
for (JSONObject action: actions_buffer) for (JSONObject action: actions_buffer)
actions+=","+action.toString(); actions.put(action);
actions= "[" + actions.substring(1) + "]"; //actions= "{actions: [" + actions.substring(1) + "]}";
params.put("actions",actions); try {
params.put("json",new JSONObject().put("actions",actions).toString());
} catch (JSONException e) {
e.printStackTrace();
Log.e(this.getClass().getCanonicalName(), " Batch action error: " + e.getMessage());
}
Log.i(this.getClass().getCanonicalName()," Sending batch actions: "+url+": "+actions); Log.i(this.getClass().getCanonicalName()," Sending batch actions: "+url+": "+actions);
PCBcontext.getRestapiWrapper().ask(url, params, "post", this); PCBcontext.getRestapiWrapper().ask(url, params, "post", true, this);
} }
} }
......
...@@ -59,7 +59,7 @@ public class PictosAction extends Action { ...@@ -59,7 +59,7 @@ public class PictosAction extends Action {
return null; return null;
} }
} }
public JSONObject get_json_picto(Picto picto) throws JSONException { private JSONObject get_json_picto(Picto picto) throws JSONException {
final String param_id_json="id"; final String param_id_json="id";
final String param_picto="picto"; final String param_picto="picto";
final String param_attrs="attributes"; final String param_attrs="attributes";
......
...@@ -19,7 +19,9 @@ import com.yottacode.pictogram.tools.PCBcontext; ...@@ -19,7 +19,9 @@ import com.yottacode.pictogram.tools.PCBcontext;
import java.sql.SQLDataException; import java.sql.SQLDataException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedList; import java.util.LinkedList;
...@@ -36,8 +38,9 @@ public class Room { ...@@ -36,8 +38,9 @@ public class Room {
protected SailsSocketsIO socket=null; protected SailsSocketsIO socket=null;
protected boolean inRoom=false; protected boolean inRoom=false;
protected Hashtable<String, Emitter.Listener> listeners;
public Room( ) { public Room( ) {
listeners=new Hashtable<>();
reconnect(); reconnect();
} }
...@@ -46,22 +49,23 @@ public class Room { ...@@ -46,22 +49,23 @@ public class Room {
final String attributes_param="attributes"; final String attributes_param="attributes";
return new JSONObject().put(action_param, action).put(attributes_param, attributes); return new JSONObject().put(action_param, action).put(attributes_param, attributes);
} }
public void emit(String url, final Action action) { /* public void emit(String url, final Action action) {
Log.d(this.getClass().getName(), "Action: " + action.get_type() + " / Attributes emitted: " + action.get_json().toString()); Log.i(this.getClass().getName(), "Action: " + action.get_type() + " / Attributes emitted: " + action.get_json().toString());
try{ try{
this.socket.emit(url, this.common_data(action.get_type(), action.get_json()), new Ack() { this.socket.emit(url, this.common_data(action.get_type(), action.get_json()), new Ack() {
@Override @Override
public void call(Object... args) { public void call(Object... args) {
Log.i(this.getClass().getName(), "Ack");
for (Object arg : args) for (Object arg : args)
Log.d(this.getClass().getName(), "Ack messsage:" + arg); Log.i(this.getClass().getName(), "Ack messsage:" + arg);
} }
}); });
} catch (JSONException e) { } catch (JSONException e) {
Log.e(this.getClass().getCanonicalName(), e.getClass().getCanonicalName() + e.getMessage() + "--" + e.getLocalizedMessage()); Log.e(this.getClass().getCanonicalName(), e.getClass().getCanonicalName() + e.getMessage() + "--" + e.getLocalizedMessage());
} }
} }*/
public void emit(final Action action, String token) { public void emit(final Action action) {
String token=PCBcontext.getRestapiWrapper().getToken();
final String token_param="token"; final String token_param="token";
Log.d(this.getClass().getName(), "Action: " + action.get_type() + " / Attributes emitted: " + action.get_json().toString()); Log.d(this.getClass().getName(), "Action: " + action.get_type() + " / Attributes emitted: " + action.get_json().toString());
try{ try{
...@@ -82,31 +86,39 @@ public class Room { ...@@ -82,31 +86,39 @@ public class Room {
*/ */
public void reconnect() { public void reconnect() {
final String transport="polling"; final String transport="polling";
if (this.socket!=null) this.socket.destroy();
this.socket=new SailsSocketsIO(PCBcontext.getRestapiWrapper().getServer(), transport, new Emitter.Listener() { this.socket=new SailsSocketsIO(PCBcontext.getRestapiWrapper().getServer(), transport, new Emitter.Listener() {
@Override @Override
public void call(Object... args) { public void call(Object... args) {
Log.i(this.getClass().getName(), "Reconnect successful"); Log.i(this.getClass().getName(), "Reconnect successful");
subscribe(); subscribe();
listen_again();
inRoom=true; inRoom=true;
} }
}, new Emitter.Listener() { }, new Emitter.Listener() {
@Override @Override
public void call(Object... args) { public void call(Object... args) {
Log.i(this.getClass().getName(), "Room exit: "+args[0]); Log.i(this.getClass().getName(), "Reconnect unsuccesful: "+args[0]);
if (args.length>0 && args[0].toString().equals("transport error") ) { inRoom=false;
inRoom=false;
}
} }
}); });
} }
public boolean inRoom() {return this.inRoom;} public boolean inRoom() {return this.inRoom;}
public void listen(String msg, Emitter.Listener listener) { public void listen(String msg, Emitter.Listener listener) {
this.socket.registerMessage(msg, listener); this.socket.registerMessage(msg, listener);
this.listeners.put(msg, listener);
}
private void listen_again() {
for (String msg: this.listeners.keySet()) {
Log.i(this.getClass().getName(), "Listening to "+msg);
this.socket.registerMessage(msg, this.listeners.get(msg));
}
} }
void subscribe() { void subscribe() {
try { try {
SubscribeAction action = new SubscribeAction(); SubscribeAction action = new SubscribeAction();
this.emit(action, PCBcontext.getRestapiWrapper().getToken()); this.emit(action);
}catch (Exception e) { }catch (Exception e) {
Log.e(this.getClass().getCanonicalName(), e.getMessage()); Log.e(this.getClass().getCanonicalName(), e.getMessage());
} }
......
...@@ -38,7 +38,6 @@ public class Device extends SQLiteOpenHelper { ...@@ -38,7 +38,6 @@ public class Device extends SQLiteOpenHelper {
Context context; Context context;
final static class PARAMS { final static class PARAMS {
static String keyword="key"; static String keyword="key";
static String token="token";
static String deviceID="deviceID"; static String deviceID="deviceID";
static String serial="serial"; static String serial="serial";
static String stu_id="last__stu_id"; static String stu_id="last__stu_id";
...@@ -56,7 +55,7 @@ public class Device extends SQLiteOpenHelper { ...@@ -56,7 +55,7 @@ public class Device extends SQLiteOpenHelper {
super(context, DeviceHelper.getDBName(context), factory, version); super(context, DeviceHelper.getDBName(context), factory, version);
if (DeviceHelper.force_create(context)) { if (DeviceHelper.force_create(context)) {
Log.i(this.getClass().getCanonicalName(),"Forcing create new database"); Log.i(this.getClass().getCanonicalName(),"Forcing create new Database "+DeviceHelper.getDBName(context));
context.deleteDatabase(DeviceHelper.getDBName(context)); context.deleteDatabase(DeviceHelper.getDBName(context));
Log.i(this.getClass().getCanonicalName(), "Database dropped"); Log.i(this.getClass().getCanonicalName(), "Database dropped");
} }
...@@ -307,7 +306,7 @@ public class Device extends SQLiteOpenHelper { ...@@ -307,7 +306,7 @@ public class Device extends SQLiteOpenHelper {
for (User user : prev_users) for (User user : prev_users)
db.delete("users_detail","id_stu=? AND id_sup=?",new String[]{Integer.toString(user.get_id_stu()),Integer.toString(user.get_id_sup())}); db.delete("users_detail","id_stu=? AND id_sup=?",new String[]{Integer.toString(user.get_id_stu()),Integer.toString(user.get_id_sup())});
ImgDownloader downloader = new ImgDownloader(this.context, imgListener, ImgDownloader.source.remote ); ImgDownloader downloader = new ImgDownloader(this.context, imgListener, ImgDownloader.tsource.remote );
downloader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,imgs); downloader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,imgs);
...@@ -318,13 +317,17 @@ public class Device extends SQLiteOpenHelper { ...@@ -318,13 +317,17 @@ public class Device extends SQLiteOpenHelper {
/** /**
* delete the list of images (students, supervisors, pictograms) which are no longer used * delete the list of images (students, supervisors, pictograms) which are no longer used
*/ */
public void deleteDeprecatedImgs() throws IOException { public void deleteDeprecatedImgs() {
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.query("deprecated_images", null, null, null, null, null, null); Cursor cursor = db.query("deprecated_images", null, null, null, null, null, null);
while (cursor.moveToNext()) { while (cursor.moveToNext()) {
String type = cursor.getString(1); String type = cursor.getString(1);
String folder = type.equals("stu") ? Img.STUDENT : type.equals("sup") ? Img.SUPERVISOR : Img.VOCABULARY; String folder = type.equals("stu") ? Img.STUDENT : type.equals("sup") ? Img.SUPERVISOR : Img.VOCABULARY;
(new Img(cursor.getInt(0), null, folder)).delete_bitmap(this.context); try {
(new Img(cursor.getInt(0), null, folder)).delete_bitmap(this.context);
} catch (IOException e) {
e.printStackTrace();
}
Log.i(this.getClass().getCanonicalName(), "Image file " + cursor.getString(1) + "." + cursor.getInt(0) + " deleted"); Log.i(this.getClass().getCanonicalName(), "Image file " + cursor.getString(1) + "." + cursor.getInt(0) + " deleted");
} }
cursor.close(); cursor.close();
......
...@@ -11,6 +11,7 @@ import android.database.sqlite.SQLiteOpenHelper; ...@@ -11,6 +11,7 @@ import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log; import android.util.Log;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Vector; import java.util.Vector;
...@@ -201,20 +202,25 @@ public class PCBDBHelper extends SQLiteOpenHelper { ...@@ -201,20 +202,25 @@ public class PCBDBHelper extends SQLiteOpenHelper {
public void setStudentVocabulary(Vocabulary vocabulary) { public void setStudentVocabulary(Vocabulary vocabulary) {
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();
int id_stu = this.getCurrentUser().get_id_stu(); int id_stu = this.getCurrentUser().get_id_stu();
int seconds1 = Calendar.getInstance().get(Calendar.SECOND), inserts=0; int seconds1 = Calendar.getInstance().get(Calendar.SECOND);
int deleted=db.delete("collection", "id_stu=?", new String[] {String.valueOf(id_stu)});
db.delete("collection", "id_stu=" + id_stu, null);
int newsize=0;
ContentValues values=new ContentValues(5); ContentValues values=new ContentValues(5);
values.put("id_stu", id_stu); values.put("id_stu", id_stu);
for (Picto picto : vocabulary) { for (Picto picto : vocabulary) {
newsize++;
values.put("id_picto", picto.get_id()); values.put("id_picto", picto.get_id());
values.put("url", picto.get_url()); values.put("url", picto.get_url());
values.put("translation",picto.get_translation()); values.put("translation",picto.get_translation());
values.put("attributes",picto.get_json_attrs()); values.put("attributes",picto.get_json_attrs());
db.insert("collection_detail", null, values); db.insert("collection_detail", null, values);
} }
int seconds2 = Calendar.getInstance().get(Calendar.SECOND); int seconds2 = Calendar.getInstance().get(Calendar.SECOND);
Log.i(this.getClass().getName(), " Local student vocabulary updated, id:" + id_stu + ", cats: "+vocabulary.size() +" time:"+(seconds2-seconds1)); Log.i(this.getClass().getName(), " Local student vocabulary updated, id:" + id_stu + ", cats: " + vocabulary.size() + " time:" + (seconds2 - seconds1) + " secs. Size: " + newsize + " read only?" + db.isReadOnly());
db.close(); db.close();
} }
...@@ -247,11 +253,11 @@ public class PCBDBHelper extends SQLiteOpenHelper { ...@@ -247,11 +253,11 @@ public class PCBDBHelper extends SQLiteOpenHelper {
int id_stu = this.getCurrentUser().get_id_stu(); int id_stu = this.getCurrentUser().get_id_stu();
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();
db.delete("collection","id_stu=? AND id_sup=? AND id_picto=?", db.delete("collection","id_stu=? AND id_picto=?",
new String[]{ Integer.toString(this.currentUser.get_id_stu()), new String[]{ Integer.toString(this.currentUser.get_id_stu()),
Integer.toString(this.currentUser.get_id_sup()),
Integer.toString(picto_id)}); Integer.toString(picto_id)});
db.close(); db.close();
PCBcontext.getDevice().deleteDeprecatedImgs();
} }
/** /**
* Update a picto of the current collection's student. * Update a picto of the current collection's student.
...@@ -263,7 +269,10 @@ public class PCBDBHelper extends SQLiteOpenHelper { ...@@ -263,7 +269,10 @@ public class PCBDBHelper extends SQLiteOpenHelper {
public void modifyPicto(int picto_id, String attrs) { public void modifyPicto(int picto_id, String attrs) {
int id_stu = this.getCurrentUser().get_id_stu(); int id_stu = this.getCurrentUser().get_id_stu();
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("UPDATE collection SET attributes='" + attrs + "' WHERE id_stu=" + id_stu + " AND id_picto=" + picto_id); ContentValues values = new ContentValues(1);
values.put("attributes",attrs);
int updates=db.update("collection",values, "id_stu=? AND id_picto=?", new String[] {Integer.toString(id_stu), Integer.toString(picto_id)});
Log.i(this.getClass().getCanonicalName(),"Modify "+updates+" Picto, id. "+picto_id+" attributes="+attrs);//+ "::"+ Arrays.toString(Thread.currentThread().getStackTrace()));
db.close(); db.close();
} }
......
...@@ -11,8 +11,6 @@ import com.yottacode.pictogram.tools.PCBcontext; ...@@ -11,8 +11,6 @@ import com.yottacode.pictogram.tools.PCBcontext;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.HashMap;
/** /**
* A object which represents a pictogram * A object which represents a pictogram
* * * *
...@@ -25,14 +23,14 @@ public class Picto extends Img { ...@@ -25,14 +23,14 @@ public class Picto extends Img {
private final String LOG_TAG = this.getClass().getSimpleName(); // Or .getCanonicalName() private final String LOG_TAG = this.getClass().getSimpleName(); // Or .getCanonicalName()
public final static class JSON_ATTTRS { public final static class JSON_ATTTRS {
static String CATEGORY = "id_cat"; public static String CATEGORY = "id_cat";
static String ROW = "coord_x"; public static String COLUMN = "coord_x";
static String COLUMN = "coord_y"; public static String ROW = "coord_y";
static String MAGNIFY = "magnify"; public static String MAGNIFY = "magnify";
static String HIGHLIGHT = "highlight"; public static String HIGHLIGHT = "highlight";
static String STATUS = "status"; public static String STATUS = "status";
static String COLOR = "color"; public static String COLOR = "color";
static String PCB_STATUS_MODIFICATION="pcb_status_modification"; public static String PCB_STATUS_MODIFICATION="pcb_status_modification";
} }
public final static class JSON_ATTTR_STATUS_VALUES { public final static class JSON_ATTTR_STATUS_VALUES {
...@@ -48,7 +46,7 @@ public class Picto extends Img { ...@@ -48,7 +46,7 @@ public class Picto extends Img {
private JSONObject attributes; private JSONObject attributes;
private String translation; private String translation;
public Picto(int id, String url, String translation, int cat, int column, int row) throws JSONException { public Picto(int id, String url, String translation, int cat, int row, int column) throws JSONException {
this(id, url, translation, new JSONObject() this(id, url, translation, new JSONObject()
.put(JSON_ATTTRS.CATEGORY,cat) .put(JSON_ATTTRS.CATEGORY,cat)
.put(JSON_ATTTRS.COLUMN,column) .put(JSON_ATTTRS.COLUMN,column)
...@@ -102,15 +100,19 @@ public class Picto extends Img { ...@@ -102,15 +100,19 @@ public class Picto extends Img {
} }
/** /**
* JSON attribute of the picto * JSON attrs of the picto except the param regarding is locally modified since this is not saved into the server
*
* *
*/ */
public String get_json_attr(String attr) { public String get_json_server_attrs() {
JSONObject json = null;
try { try {
return this.attributes.getString(attr); json = new JSONObject(this.attributes.toString());
} catch (JSONException e) { } catch (JSONException e) {
return null; e.printStackTrace();
} }
json.remove(JSON_ATTTRS.PCB_STATUS_MODIFICATION);
return json.toString();
} }
/** /**
* Set JSON attribute of the picto * Set JSON attribute of the picto
...@@ -173,7 +175,8 @@ public class Picto extends Img { ...@@ -173,7 +175,8 @@ public class Picto extends Img {
*/ */
public boolean is_invisible() { public boolean is_invisible() {
try { try {
return this.attributes.getString(JSON_ATTTRS.STATUS).equals(JSON_ATTTR_STATUS_VALUES.INVISIBLE); return this.attributes.getString(JSON_ATTTRS.STATUS).equals(JSON_ATTTR_STATUS_VALUES.INVISIBLE) ||
(this.is_category() && !PCBcontext.getVocabulary().isVisibleCategory(this.get_id()));
} catch (JSONException e) { } catch (JSONException e) {
return false; return false;
} }
...@@ -318,14 +321,16 @@ public class Picto extends Img { ...@@ -318,14 +321,16 @@ public class Picto extends Img {
*/ */
public boolean alter_status() { public boolean alter_status() {
String status=is_enabled() ? JSON_ATTTR_STATUS_VALUES.DISABLED : JSON_ATTTR_STATUS_VALUES.ENABLED; String status=is_enabled() ? JSON_ATTTR_STATUS_VALUES.DISABLED : JSON_ATTTR_STATUS_VALUES.ENABLED;
Log.i(this.getClass().getCanonicalName(),"Picto id. "+get_id()+" status enabled/disabled modified to "+is_enabled());
try { try {
this.attributes.put(JSON_ATTTRS.STATUS, status); this.attributes.put(JSON_ATTTRS.STATUS, status);
status_modified(true); set_local_status(true);
new PictoUploader(this).uploadState(); new PictoUploader(this).uploadState();
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); e.printStackTrace();
Log.e(this.getClass().getCanonicalName(),e.getMessage()); Log.e(this.getClass().getCanonicalName(),e.getMessage());
} }
PCBcontext.getActionLog().log(new VocabularyAction(VocabularyAction.ALTERATTRS,this));
return is_enabled(); return is_enabled();
} }
...@@ -333,24 +338,26 @@ public class Picto extends Img { ...@@ -333,24 +338,26 @@ public class Picto extends Img {
* *
* @return true if the status of picto was modified from the PCB * @return true if the status of picto was modified from the PCB
*/ */
public boolean status_modified() { public boolean local_status() {
return !this.attributes.isNull(JSON_ATTTRS.PCB_STATUS_MODIFICATION); return !this.attributes.isNull(JSON_ATTTRS.PCB_STATUS_MODIFICATION);
} }
/** /**
* when the status is locally modified, it is required to remove when it is uploaded since it is no longer a local modification * when the status is locally modified, it is required to remove when it is uploaded since it is no longer a local modification
*/ */
public void status_modified(boolean modified) { public void set_local_status(boolean modified) {
if (modified) if (modified)
try { try {
this.attributes.put(JSON_ATTTRS.PCB_STATUS_MODIFICATION, true); this.attributes.put(JSON_ATTTRS.PCB_STATUS_MODIFICATION, true);
PCBcontext.getActionLog().log(new VocabularyAction(VocabularyAction.ALTERATTRS, this)); PCBcontext.getPcbdb().modifyPicto(this.get_id(), this.get_json_attrs());
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); e.printStackTrace();
Log.e(this.getClass().getCanonicalName(), e.getMessage()); Log.e(this.getClass().getCanonicalName(), e.getMessage());
} }
else else {
this.attributes.remove(JSON_ATTTRS.PCB_STATUS_MODIFICATION); this.attributes.remove(JSON_ATTTRS.PCB_STATUS_MODIFICATION);
PCBcontext.getPcbdb().modifyPicto(this.get_id(), this.get_json_attrs());
}
} }
} }
\ No newline at end of file
...@@ -246,16 +246,9 @@ public class User { ...@@ -246,16 +246,9 @@ public class User {
} }
} }
public boolean is_supervisor() {
/** return get_id_sup()!=User.NO_SUPERVISOR;
*
* @return the id of the real user: stu or sup
public int get_id() {
return this.get_name_sup() == null ? this.get_id_stu() : this.get_id_sup();
} }
*/
......
...@@ -47,11 +47,9 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -47,11 +47,9 @@ public class Vocabulary implements Iterable<Picto> {
this.pictos = new Hashtable<>(Vocabulary.DEFAULT_VOCABULARY_SIZE); this.pictos = new Hashtable<>(Vocabulary.DEFAULT_VOCABULARY_SIZE);
this.imgListener=listener; this.imgListener=listener;
if (PCBcontext.getNetService().online()) { if (PCBcontext.getNetService().online()) {
Log.i(this.getClass().getName(), "downloading vocabulary");
synchronize(); synchronize();
}else }else
try { try {
Log.i(this.getClass().getName(), "local vocabulary");
PCBcontext.getPcbdb().getStudentVocabulary(this); PCBcontext.getPcbdb().getStudentVocabulary(this);
listener.loadComplete(); listener.loadComplete();
} catch (JSONException e) { } catch (JSONException e) {
...@@ -69,6 +67,7 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -69,6 +67,7 @@ public class Vocabulary implements Iterable<Picto> {
break; break;
} }
case update:{ case update:{
Log.i(this.getClass().getCanonicalName(), "Picto update "+args.toString());
modifyAttsPicto(picto_cat, picto_id, args); modifyAttsPicto(picto_cat, picto_id, args);
break; break;
} }
...@@ -79,7 +78,7 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -79,7 +78,7 @@ public class Vocabulary implements Iterable<Picto> {
String uri=args.getJSONObject("picto").getString("uri"); String uri=args.getJSONObject("picto").getString("uri");
JSONObject attrs_picto = args.getJSONObject("attributes"); JSONObject attrs_picto = args.getJSONObject("attributes");
addPicto(new Picto(picto_id, uri, text, attrs_picto),ImgDownloader.source.remote); addPicto(new Picto(picto_id, uri, text, attrs_picto),ImgDownloader.tsource.remote);
} catch (JSONException e) { } catch (JSONException e) {
Log.e(this.getClass().getCanonicalName(), e.getClass().getCanonicalName() + "--" + e); Log.e(this.getClass().getCanonicalName(), e.getClass().getCanonicalName() + "--" + e);
...@@ -94,25 +93,45 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -94,25 +93,45 @@ public class Vocabulary implements Iterable<Picto> {
},listener}; },listener};
talk = new VocabularyTalk(room, listeners); talk = new VocabularyTalk(room, listeners);
} }
/** /**
* the vocabulary is (i) updated to and (ii) downloaded from the server. * UPload local status modifications and new pictos. Note that when
* a picto is uploaded is not required to delete from the local PCB
* because the PCB will get the remote vocabulary at the end of the process
* The only issue is: what happens whether the upload fails? --> The image will be lost.
* TODO: keep record of failed uploaded images to re-include as local pictos
*/ */
public void synchronize() { private void synchronize_upload() {
try { try {
PCBcontext.getPcbdb().getStudentVocabulary(this); PCBcontext.getPcbdb().getStudentVocabulary(this);
} catch (JSONException e) { } catch (JSONException e) {
Log.e(this.getClass().getName(), " Picto json error from local storage: " + e.getMessage()); Log.e(this.getClass().getName(), " Picto json error from local storage: " + e.getMessage());
} }
for (Picto picto: this) { for (Picto picto: this) {
if (picto.status_modified()) new PictoUploader(picto).uploadState(); if (picto.local_status()) {
if (picto.get_id() < 0) new PictoUploader(picto).uploadState();
try { Log.i(this.getClass().getCanonicalName(), "Picto status modified while offline. Picto translation: '" +
new PictoUploader(picto).upload(); //id<0 iif it is a local id picto.get_translation() + "', id:" + picto.get_id() + " Local status?" + picto.local_status());
} catch (IOException e) { }
e.printStackTrace(); if (picto.get_id() < 0) //id<0 iif it is a local id
Log.e(this.getClass().getName(), " Picto json error from server: " + picto.toString()); try {
} new PictoUploader(picto).upload();
} catch (IOException e) {
e.printStackTrace();
Log.e(this.getClass().getName(), " Picto json error from server: " + picto.toString());
}
} }
}
/**
* the vocabulary is (i) updated to and (ii) downloaded from the server.
*/
public void synchronize() {
synchronize_upload();
//download
final String picto_str="/pictos"; final String picto_str="/pictos";
String operation=PCBcontext.getPcbdb().getCurrentUser().get_restapi_operation_stu()+picto_str; String operation=PCBcontext.getPcbdb().getCurrentUser().get_restapi_operation_stu()+picto_str;
PCBcontext.getRestapiWrapper().ask(operation, new iRestapiListener() { PCBcontext.getRestapiWrapper().ask(operation, new iRestapiListener() {
...@@ -195,19 +214,19 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -195,19 +214,19 @@ public class Vocabulary implements Iterable<Picto> {
imgs.add(new Img(picto.get_id(), picto.get_url(), Img.VOCABULARY)); imgs.add(new Img(picto.get_id(), picto.get_url(), Img.VOCABULARY));
} }
Log.d(this.getClass().getName(), "Vocabulary size: " + updated_collection.length); Log.d(this.getClass().getName(), "Vocabulary size: " + updated_collection.length);
ImgDownloader downloader = new ImgDownloader(PCBcontext.getContext(), imgListener,ImgDownloader.source.remote); ImgDownloader downloader = new ImgDownloader(PCBcontext.getContext(), imgListener,ImgDownloader.tsource.remote);
downloader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, imgs); downloader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, imgs);
PCBcontext.getPcbdb().setStudentVocabulary(this); }
}
public int size() { return this.pictos.size();} public int size() { return this.pictos.size();}
/** /**
* It includes/updates a new picto to the user collection: download the image from remote or local storage, add the picto to the current vocabulary and update the database * It includes/updates a new picto to the user collection: download the image from remote or local storage, add the picto to the current vocabulary and update the database
* @param pic * @param pic
*/ */
public void addPicto(Picto pic, ImgDownloader.source source){ public void addPicto(Picto pic, ImgDownloader.tsource source){
addPicto(pic, source, this.imgListener);
}
public void addPicto(Picto pic, ImgDownloader.tsource source, iImgDownloaderListener imgListener){
Vector<Img> imgs=new Vector<Img>(1); Vector<Img> imgs=new Vector<Img>(1);
imgs.add(new Img(pic.get_id(), pic.get_url(), Img.VOCABULARY)); imgs.add(new Img(pic.get_id(), pic.get_url(), Img.VOCABULARY));
...@@ -291,14 +310,7 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -291,14 +310,7 @@ public class Vocabulary implements Iterable<Picto> {
* @return list of pictos which should be selectable at the beginning of a sentence. Empty categories are removed * @return list of pictos which should be selectable at the beginning of a sentence. Empty categories are removed
*/ */
public LinkedList<Picto> startSentence(){ public LinkedList<Picto> startSentence(){
Iterator<Picto> pictos=this.pictos.get(new Integer(Picto.NO_CATEGORY)).iterator(); return this.pictos.get(new Integer(Picto.NO_CATEGORY));
LinkedList<Picto> filteredPictos=new LinkedList<Picto>();
while (pictos.hasNext()) {
Picto picto = pictos.next();
if (!picto.is_category() || isVisibleCategory(picto.get_id()))
filteredPictos.add(picto);
}
return filteredPictos;
} }
/** /**
...@@ -306,13 +318,13 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -306,13 +318,13 @@ public class Vocabulary implements Iterable<Picto> {
* @param id * @param id
* @return * @return
*/ */
private boolean isVisibleCategory(int id) { public boolean isVisibleCategory(int id) {
if (empty_category(id)) return false; if (empty_category(id)) return false;
boolean visible=false; boolean visible=false;
for (Picto picto : this.pictos.get(id)) { for (Picto picto : this.pictos.get(id)) {
visible=picto.is_enabled(); visible=!picto.is_invisible();
if (visible) break; if (visible) break;
} }
return visible; return visible;
...@@ -322,18 +334,32 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -322,18 +334,32 @@ public class Vocabulary implements Iterable<Picto> {
*/ */
public Picto saveLocalPicto(String url, String exp, int cat, int coord_x, int coord_y) { public Picto saveLocalPicto(String url, String exp, int cat, int coord_x, int coord_y) {
int id= PCBcontext.getDevice().getNextLocalPictoID(); int id= PCBcontext.getDevice().getNextLocalPictoID();
Picto picto; final Picto picto[]=new Picto[1];
try { try {
picto = new Picto(id, url, exp, cat, coord_x, coord_y); picto[0] = new Picto(id, url, exp, cat, coord_x, coord_y);
addPicto(picto[0], ImgDownloader.tsource.local, new iImgDownloaderListener() {
@Override
public void loadComplete() {
try {
new PictoUploader(picto[0]).upload(); //id<0 iif it is a local id
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void loadImg(Img image) {
}
});
addPicto(picto, ImgDownloader.source.local);
new PictoUploader(picto).upload(); //id<0 iif it is a local id
} catch (Exception e) { } catch (Exception e) {
picto=null; picto[0]=null;
e.printStackTrace(); e.printStackTrace();
Log.e(Vocabulary.class.getCanonicalName(), e.getMessage()); Log.e(Vocabulary.class.getCanonicalName(), e.getMessage());
} }
return picto; PCBcontext.getActionLog().log(new VocabularyAction(VocabularyAction.ADD, picto[0]));
return picto[0];
} }
/** /**
......
...@@ -23,7 +23,7 @@ public class VocabularyIterator implements Iterator<Picto> { ...@@ -23,7 +23,7 @@ public class VocabularyIterator implements Iterator<Picto> {
this.keys = pictos.keys(); this.keys = pictos.keys();
if (pictos.size()>1) { if (pictos.size()>1) {
this.pictos=pictos; this.pictos=pictos;
this.category = pictos.keys().nextElement(); this.category = this.keys.nextElement();
} }
else { else {
......
package com.yottacode.pictogram.grammar; import android.util.Log; import com.github.nkzawa.emitter.Emitter; import org.json.JSONException;import org.json.JSONObject; import com.yottacode.pictogram.dao.Picto;import com.yottacode.pictogram.action.Room; /** * Websocket Vocabulary Room based on Room * @author Fernando Martinez Santiago * @version 1.0 */public class VocabularyTalk implements Emitter.Listener { private static final String URL ="vocabulary"; private Room room; iVocabularyListener listeners[]; public VocabularyTalk(Room room, iVocabularyListener listeners[]) { this.room = room; this.room.listen(URL, this); this.listeners=listeners; } @Override public void call(Object... args) { final String param_action="action"; final String param_attributes="attributes"; final String param_picto="picto"; final String param_picto_cat="id_cat"; final String action_update="update"; final String action_add="add"; final String action_delete="delete"; JSONObject msg = (JSONObject) args[0]; try { String action = msg.getString(param_action).toLowerCase(); JSONObject picto= msg.getJSONObject(param_attributes).getJSONObject(param_picto); JSONObject attrs_picto = picto.getJSONObject(param_attributes); int picto_id = picto.getInt(param_picto); int picto_cat = attrs_picto.optInt(param_picto_cat, Picto.NO_CATEGORY); Log.d(this.getClass().getName(), "Received message '" + action + "' for picto " + picto_id + " (cat " + picto_cat + ", attrs: "+attrs_picto); for (iVocabularyListener listener: this.listeners) listener.change(action.equals(action_update) ? iVocabularyListener.action.update : action.equals(action_add) ? iVocabularyListener.action.add : iVocabularyListener.action.delete , picto_cat, picto_id, attrs_picto); } catch (JSONException e) { Log.e(this.getClass().getCanonicalName(), e.getClass().getCanonicalName() + "--" + e); } }} package com.yottacode.pictogram.grammar; import android.util.Log; import com.github.nkzawa.emitter.Emitter; import org.json.JSONException;import org.json.JSONObject; import com.yottacode.pictogram.dao.Picto;import com.yottacode.pictogram.action.Room; /** * Websocket Vocabulary Room based on Room * @author Fernando Martinez Santiago * @version 1.0 */public class VocabularyTalk implements Emitter.Listener { private static final String URL ="vocabulary"; private Room room; iVocabularyListener listeners[]; public VocabularyTalk(Room room, iVocabularyListener listeners[]) { this.room = room; this.room.listen(URL, this); this.listeners=listeners; } @Override public void call(Object... args) { final String param_action="action"; final String param_attributes="attributes"; final String param_picto="picto"; final String param_picto_id="id"; final String param_picto_cat="id_cat"; final String action_update="update"; final String action_add="add"; final String action_delete="delete"; JSONObject msg = (JSONObject) args[0]; try { String action = msg.getString(param_action).toLowerCase(); JSONObject picto= msg.getJSONObject(param_attributes).getJSONObject(param_picto); JSONObject attrs_picto = picto.getJSONObject(param_attributes); int picto_id = picto.getInt(param_picto_id); int picto_cat = attrs_picto.optInt(param_picto_cat, Picto.NO_CATEGORY); Log.d(this.getClass().getName(), "Received message '" + action + "' for picto " + picto_id + " (cat " + picto_cat + ", attrs: "+attrs_picto); for (iVocabularyListener listener: this.listeners) listener.change(action.equals(action_update) ? iVocabularyListener.action.update : action.equals(action_add) ? iVocabularyListener.action.add : iVocabularyListener.action.delete , picto_cat, picto_id, attrs_picto); } catch (JSONException e) { Log.e(this.getClass().getCanonicalName(), e.getClass().getCanonicalName() + "--" + e); } }}
\ No newline at end of file \ No newline at end of file
......
...@@ -16,6 +16,5 @@ import java.util.LinkedList; ...@@ -16,6 +16,5 @@ import java.util.LinkedList;
*/ */
public interface iVocabularyListener { public interface iVocabularyListener {
public enum action {delete,add,update} public enum action {delete,add,update}
public enum arg {attributes, expression, url}
public void change(iVocabularyListener.action action, int picto_cat, int picto_id, JSONObject args); public void change(iVocabularyListener.action action, int picto_cat, int picto_id, JSONObject args);
} }
...@@ -261,7 +261,6 @@ public class LoginActivity extends FragmentActivity implements iRestapiListener{ ...@@ -261,7 +261,6 @@ public class LoginActivity extends FragmentActivity implements iRestapiListener{
} }
}); });
PCBcontext.getDevice().deleteDeprecatedImgs();
// Si sólo hay 1 estudiante paso a Pictogram // Si sólo hay 1 estudiante paso a Pictogram
if (users.size() == 1){ if (users.size() == 1){
//close the progress dialog //close the progress dialog
...@@ -289,8 +288,6 @@ public class LoginActivity extends FragmentActivity implements iRestapiListener{ ...@@ -289,8 +288,6 @@ public class LoginActivity extends FragmentActivity implements iRestapiListener{
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} }
} }
......
...@@ -2,6 +2,7 @@ package com.yottacode.pictogram.gui; ...@@ -2,6 +2,7 @@ package com.yottacode.pictogram.gui;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Canvas; import android.graphics.Canvas;
...@@ -23,7 +24,9 @@ import android.widget.GridView; ...@@ -23,7 +24,9 @@ import android.widget.GridView;
import android.widget.ImageView; import android.widget.ImageView;
import com.yottacode.pictogram.R; import com.yottacode.pictogram.R;
import com.yottacode.pictogram.dao.PCBDBHelper;
import com.yottacode.pictogram.dao.Picto; import com.yottacode.pictogram.dao.Picto;
import com.yottacode.pictogram.dao.User;
import com.yottacode.pictogram.grammar.iVocabularyListener; import com.yottacode.pictogram.grammar.iVocabularyListener;
import com.yottacode.pictogram.tools.PCBcontext; import com.yottacode.pictogram.tools.PCBcontext;
...@@ -146,7 +149,8 @@ public class PanelAdapter extends ArrayAdapter { ...@@ -146,7 +149,8 @@ public class PanelAdapter extends ArrayAdapter {
// Es un hueco en blanco // Es un hueco en blanco
imageView.setImageAlpha(0); imageView.setImageAlpha(0);
} else{ } else{
Bitmap bmp1 = lPictos.get(position).get_bitmap(PCBcontext.getContext()); Picto picto =lPictos.get(position);
Bitmap bmp1 = picto.get_bitmap(PCBcontext.getContext());
if (bmp1 != null){ if (bmp1 != null){
// Magnify // Magnify
if(lPictos.get(position).is_magnify()){ if(lPictos.get(position).is_magnify()){
...@@ -157,14 +161,14 @@ public class PanelAdapter extends ArrayAdapter { ...@@ -157,14 +161,14 @@ public class PanelAdapter extends ArrayAdapter {
imageView.setScaleY(1f); imageView.setScaleY(1f);
} }
// Estado de los pictos: enabled | disabled | invisible
String status = lPictos.get(position).get_status();
if(status.equalsIgnoreCase("invisible")){ if(picto.is_invisible()) {
imageView.setImageAlpha(0); imageView.setImageAlpha(PCBcontext.getPcbdb().getCurrentUser().is_supervisor() ? 50 : 0);
Log.d(LOG_TAG, "POSITION:" + position + " / STATUS: " + status); imageView.setImageBitmap(bmp1);
Log.d(LOG_TAG, "POSITION:" + position + " / STATUS: " + picto.get_status());
//imageView.setImageBitmap(bmp1); //imageView.setImageBitmap(bmp1);
} else if(status.equalsIgnoreCase("disabled")){ }
if(picto.is_disabled()){
imageView.setImageAlpha(100); // Entre 0 y 255 imageView.setImageAlpha(100); // Entre 0 y 255
Bitmap bmp2 = BitmapFactory.decodeResource(PCBcontext.getContext().getResources(), R.drawable.redcross3); Bitmap bmp2 = BitmapFactory.decodeResource(PCBcontext.getContext().getResources(), R.drawable.redcross3);
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig()); Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
...@@ -185,7 +189,7 @@ public class PanelAdapter extends ArrayAdapter { ...@@ -185,7 +189,7 @@ public class PanelAdapter extends ArrayAdapter {
canvas.drawBitmap(bmp2, boardPosX, boardPosY, null); canvas.drawBitmap(bmp2, boardPosX, boardPosY, null);
*/ */
} }
else{ if (picto.is_enabled()) {
/* AÑADO UN BORDE */ /* AÑADO UN BORDE */
/* /*
final int BORDER_WIDTH = 1; final int BORDER_WIDTH = 1;
......
...@@ -8,6 +8,7 @@ import android.util.Log; ...@@ -8,6 +8,7 @@ import android.util.Log;
import com.yottacode.pictogram.R; import com.yottacode.pictogram.R;
import com.yottacode.pictogram.tools.Img; import com.yottacode.pictogram.tools.Img;
import com.yottacode.pictogram.tools.PCBcontext;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
...@@ -29,16 +30,16 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> { ...@@ -29,16 +30,16 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> {
iImgDownloaderListener imgListener; iImgDownloaderListener imgListener;
public static enum status {downloading, downloaded_ok, downloaded_failed} public static enum status {downloading, downloaded_ok, downloaded_failed}
public static enum source{remote,local} public static enum tsource{remote,local}
public status current; public status current;
private boolean force_download; private boolean force_download;
Context context; Context context;
ActivityManager.MemoryInfo mi; ActivityManager.MemoryInfo mi;
ActivityManager activityManager; ActivityManager activityManager;
source source; tsource source;
public ImgDownloader(Context context, iImgDownloaderListener listener, source source) { public ImgDownloader(Context context, iImgDownloaderListener listener, tsource source) {
this.imgListener = listener; this.imgListener = listener;
this.context=context; this.context=context;
this.mi = new ActivityManager.MemoryInfo(); this.mi = new ActivityManager.MemoryInfo();
...@@ -68,7 +69,7 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> { ...@@ -68,7 +69,7 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> {
if (!img.exists_bitmap(this.context) || this.force_download) try { if (!img.exists_bitmap(this.context) || this.force_download) try {
this.activityManager.getMemoryInfo(mi); this.activityManager.getMemoryInfo(mi);
Log.i(this.getClass().getCanonicalName(), img.get_url() + " to be downloaded"); Log.i(this.getClass().getCanonicalName(), "Picto Img "+img.get_url() + " to be downloaded");
if (this.source==source.remote) { if (this.source==source.remote) {
String surl = context.getResources().getString(R.string.server) + "/" + img.get_url(); String surl = context.getResources().getString(R.string.server) + "/" + img.get_url();
URL url = new URL(surl); URL url = new URL(surl);
...@@ -113,8 +114,8 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> { ...@@ -113,8 +114,8 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> {
@Override @Override
protected void onPostExecute(Img img) { protected void onPostExecute(Img img) {
Log.d(this.getClass().getCanonicalName(), "Inside OnPostExecute()"+new SimpleDateFormat("HH:mm:ss")); PCBcontext.getDevice().deleteDeprecatedImgs();
if (imgListener!=null) if (imgListener!=null)
if(img == null) imgListener.loadComplete(); if(img == null) imgListener.loadComplete();
else imgListener.loadImg(img); else imgListener.loadImg(img);
} }
......
...@@ -55,14 +55,11 @@ public class NetService implements Runnable { ...@@ -55,14 +55,11 @@ public class NetService implements Runnable {
} }
}); });
Log.i(this.getClass().getName(), "Checking Pictogram server access..."); Log.i(this.getClass().getName(), "Checking Pictogram server access...");
Log.d(this.getClass().getName(), this.updated ? "Pictogram server access ok" : "Pictogram server access failed, Internet connection available?"); Log.i(this.getClass().getName(), this.updated ? "Pictogram server access ok" : "Pictogram server access failed, Internet connection available?");
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1); ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
exec.scheduleWithFixedDelay(this, 0, delay, TimeUnit.SECONDS); exec.scheduleWithFixedDelay(this, 0, delay, TimeUnit.SECONDS);
} }
public NetService(){
}
public boolean online() {return updated;} public boolean online() {return updated;}
...@@ -87,6 +84,7 @@ public class NetService implements Runnable { ...@@ -87,6 +84,7 @@ public class NetService implements Runnable {
if (result == null) { if (result == null) {
updated = false; updated = false;
} else if (!updated) { } else if (!updated) {
Log.i(this.getClass().getName(), "PCB reconnect");
PCBcontext.getRoom().reconnect(); PCBcontext.getRoom().reconnect();
PCBcontext.getVocabulary().synchronize(); PCBcontext.getVocabulary().synchronize();
PCBcontext.getActionLog().batch(); PCBcontext.getActionLog().batch();
......
package com.yottacode.pictogram.net; package com.yottacode.pictogram.net;
import android.content.Context;
import android.util.Log; import android.util.Log;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
...@@ -8,7 +7,6 @@ import com.koushikdutta.ion.Ion; ...@@ -8,7 +7,6 @@ import com.koushikdutta.ion.Ion;
import com.koushikdutta.ion.Response; import com.koushikdutta.ion.Response;
import com.yottacode.net.iRestapiListener; import com.yottacode.net.iRestapiListener;
import com.yottacode.pictogram.R; import com.yottacode.pictogram.R;
import com.yottacode.pictogram.action.PictoAction;
import com.yottacode.pictogram.action.VocabularyAction; import com.yottacode.pictogram.action.VocabularyAction;
import com.yottacode.pictogram.dao.Picto; import com.yottacode.pictogram.dao.Picto;
import com.yottacode.pictogram.tools.Img; import com.yottacode.pictogram.tools.Img;
...@@ -19,7 +17,6 @@ import org.json.JSONException; ...@@ -19,7 +17,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.Hashtable; import java.util.Hashtable;
...@@ -34,51 +31,17 @@ public class PictoUploader { ...@@ -34,51 +31,17 @@ public class PictoUploader {
this.picto=picto; this.picto=picto;
} }
/**
* if the status of a given picto was modifed from the PCB it is uploaded to the server
*
*/
public void uploadState( ){
Hashtable<String, String> params = new Hashtable<String, String>(1);
params.put("attributes", picto.get_json_attrs());
params.put("id_stu", Integer.toString(PCBcontext.getPcbdb().getCurrentUser().get_id_stu()));
params.put("id_pic", Integer.toString(this.picto.get_id()));
picto.status_modified(false);
Log.i(this.getClass().getCanonicalName(), "Uploading " + params.toString());
PCBcontext.getRestapiWrapper().ask(PCBcontext.getPcbdb().getCurrentUser().get_restapi_operation_stu()
+ "/picto"
, params, "put", new iRestapiListener() {
@Override
public void preExecute() {
}
@Override
public void result(JSONArray result) {
}
@Override
public void result(JSONObject result) {
Log.i(this.getClass().getCanonicalName(), "Uploaded state result: " + result.toString());
}
@Override
public void error(Exception e) {
Log.e(this.getClass().getCanonicalName(), "Error: " + e.getLocalizedMessage());
picto.status_modified(true);
}
}
);
PCBcontext.getActionLog().log(new VocabularyAction(VocabularyAction.ALTERATTRS,this.picto));
}
private int uploadImg( Img img) throws UnsupportedEncodingException { private int uploadImg( Img img) throws UnsupportedEncodingException {
int img_id; int img_id;
if (!img.get_filetype().equalsIgnoreCase("png")) if (!img.get_filetype().equalsIgnoreCase("png"))
throw new UnsupportedEncodingException("Extension "+img.get_filetype()+" is not supported. Only png files"); throw new UnsupportedEncodingException("Extension "+img.get_filetype()+" is not supported. Only png files");
Ion ion = Ion.getDefault(PCBcontext.getContext()); Ion ion = Ion.getDefault(PCBcontext.getContext());
Log.i(this.getClass().getCanonicalName(), "Uploading " + img.file_name() + " from " + img.get_type()); try {
Log.i(this.getClass().getCanonicalName(), "Uploading Picto img" + img.file_name() + " from " + img.get_type() + "size:" + img.get_bitmap(PCBcontext.getContext()).getWidth() + " " + img.get_bitmap(PCBcontext.getContext()).getHeight());
} catch (IOException e) {
Log.i(this.getClass().getCanonicalName(), "Uploading Picto img" + img.file_name() + " from " + img.get_type());
}
File file = img.file(PCBcontext.getContext()); File file = img.file(PCBcontext.getContext());
Response<JsonObject> response=null; Response<JsonObject> response=null;
...@@ -123,8 +86,7 @@ public class PictoUploader { ...@@ -123,8 +86,7 @@ public class PictoUploader {
/** /**
* if the a picto was included from the PCB, the translation is uploaded to the server * if the a picto was included from the PCB, the translation is uploaded to the server
*/ */
private int uploadAttributes(int id_picto) { private void uploadAttributes(int id_picto) {
final int id_stupicto[]=new int[1];
Hashtable<String, String> params = new Hashtable<String, String>(4); Hashtable<String, String> params = new Hashtable<String, String>(4);
try { try {
params.put("json", new JSONObject().put("attributes", params.put("json", new JSONObject().put("attributes",
...@@ -149,22 +111,14 @@ public class PictoUploader { ...@@ -149,22 +111,14 @@ public class PictoUploader {
@Override @Override
public void result(JSONObject result) { public void result(JSONObject result) {
Log.i(this.getClass().getCanonicalName(), " Attributes uploaded: " + result.toString()); Log.i(this.getClass().getCanonicalName(), " Attributes uploaded: " + result.toString());
/* try {
id_stupicto[0]=result.getJSONObject("picto").getInt("id");
} catch (JSONException e) {
e.printStackTrace();
Log.e(this.getClass().getCanonicalName(), "Error: " + e.getLocalizedMessage());
}*/
} }
@Override @Override
public void error(Exception e) { public void error(Exception e) {
Log.e(this.getClass().getCanonicalName(), " Error uploading attributes: " + e.getLocalizedMessage()); Log.e(this.getClass().getCanonicalName(), " Error uploading attributes: " + e.getLocalizedMessage());
id_stupicto[0]=-1; PCBcontext.getVocabulary().addPicto(picto, ImgDownloader.tsource.local);
} }
}); });
return id_stupicto[0];
} }
/** /**
...@@ -193,21 +147,66 @@ public class PictoUploader { ...@@ -193,21 +147,66 @@ public class PictoUploader {
@Override @Override
public void error(Exception e) { public void error(Exception e) {
Log.e(this.getClass().getCanonicalName(), "Error: " + e.getLocalizedMessage()); Log.e(this.getClass().getCanonicalName(), "Error: " + e.getLocalizedMessage());
PCBcontext.getVocabulary().addPicto(picto, ImgDownloader.tsource.local);
} }
}); });
} }
/** /**
*Upload local picto. It requires: i) to upload the image, ii) to upload the attributes and iii) to upload the expression *Try to Upload local picto. It requires:
**/ * i) to upload the image,
* ii) to upload the attributes
* iii) to upload the expression
* iv) delete the old local picto since it will be recovered from the server
**/
public void upload() throws IOException { public void upload() throws IOException {
int img_id=uploadImg(this.picto); int old_picto=this.picto.get_id();
if (img_id>0) { int img_id = uploadImg(this.picto);
uploadAttributes(img_id); if (img_id > 0) {
uploadTranslation(img_id); uploadAttributes(img_id);
PCBcontext.getActionLog().log(new VocabularyAction(VocabularyAction.ADD, this.picto)); uploadTranslation(img_id);
} PCBcontext.getRoom().emit(new VocabularyAction(VocabularyAction.ADD, PictoUploader.this.picto));
PCBcontext.getPcbdb().deletePicto(old_picto);
}
} }
/**
* if the status of a given picto was modifed from the PCB it is uploaded to the server
*
*/
public void uploadState( ){
Hashtable<String, String> params = new Hashtable<String, String>(1);
params.put("attributes", picto.get_json_server_attrs());
params.put("id_stu", Integer.toString(PCBcontext.getPcbdb().getCurrentUser().get_id_stu()));
params.put("id_pic", Integer.toString(this.picto.get_id()));
Log.i(this.getClass().getCanonicalName(), "Picto Uploading " + params.toString());
PCBcontext.getRestapiWrapper().ask(
PCBcontext.getPcbdb().getCurrentUser().get_restapi_operation_stu() + "/picto",
params, "put", new iRestapiListener() {
@Override
public void preExecute() {
}
@Override
public void result(JSONArray result) {
}
@Override
public void result(JSONObject result) {
Log.i(PictoUploader.this.getClass().getCanonicalName(), "Upload ok Picto " + PictoUploader.this.picto.get_id());
picto.set_local_status(false);
PCBcontext.getRoom().emit(new VocabularyAction(VocabularyAction.ALTERATTRS,PictoUploader.this.picto));
}
@Override
public void error(Exception e) {
Log.e(this.getClass().getCanonicalName(), "Picto Error: " + e.getLocalizedMessage());
}
}
);
}
} }
...@@ -4,8 +4,11 @@ package com.yottacode.pictogram.tools; ...@@ -4,8 +4,11 @@ package com.yottacode.pictogram.tools;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.util.Log; import android.util.Log;
import com.yottacode.tools.FileTools;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
...@@ -15,6 +18,7 @@ import java.io.IOException; ...@@ -15,6 +18,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Enumeration; import java.util.Enumeration;
/** /**
* Img * Img
* @author Fernando * @author Fernando
...@@ -26,11 +30,17 @@ public class Img { ...@@ -26,11 +30,17 @@ public class Img {
static public String SUPERVISOR="supervisor"; static public String SUPERVISOR="supervisor";
public static final void mkDirs(Context context) { public static final void mkDirs(Context context) {
new File(path(context, Img.VOCABULARY) ).mkdirs() ; File file;
new File(path(context, Img.STUDENT) ).mkdirs() ; file = new File(path(context, Img.VOCABULARY));
new File(path(context, Img.SUPERVISOR) ).mkdirs() ; FileTools.deleteDirectory(file);
file.mkdirs();
file = new File(path(context, Img.STUDENT));
FileTools.deleteDirectory(file);
file.mkdirs();
file = new File(path(context, Img.SUPERVISOR));
FileTools.deleteDirectory(file);
file.mkdirs();
} }
protected int id; protected int id;
protected String url; protected String url;
String type; String type;
...@@ -121,12 +131,13 @@ public class Img { ...@@ -121,12 +131,13 @@ public class Img {
File file = file(context); File file = file(context);
FileOutputStream os = new FileOutputStream(file); FileOutputStream os = new FileOutputStream(file);
try { try {
this.bitmap = BitmapFactory.decodeStream(is); this.bitmap = BitmapFactory.decodeStream(is, new Rect(0,0,78,66),null);
}catch(java.lang.OutOfMemoryError err) { }catch(java.lang.OutOfMemoryError err) {
Log.e(Img.class.getCanonicalName(), "Out of memory when decoding "+this.get_url()); Log.e(Img.class.getCanonicalName(), "Out of memory when decoding "+this.get_url());
} }
ByteArrayOutputStream outstream = new ByteArrayOutputStream(); ByteArrayOutputStream outstream = new ByteArrayOutputStream();
this.bitmap.setHasAlpha(true); this.bitmap.setHasAlpha(true);
Log.i(this.getClass().getCanonicalName(), "Img Uploading Picto img" + file_name() + " from " + get_type() + "size:" + get_bitmap(PCBcontext.getContext()).getWidth() + " " + get_bitmap(PCBcontext.getContext()).getHeight());
this.bitmap.compress(Bitmap.CompressFormat.PNG, 100, outstream); this.bitmap.compress(Bitmap.CompressFormat.PNG, 100, outstream);
byte[] byteArray = outstream.toByteArray(); byte[] byteArray = outstream.toByteArray();
os.write(byteArray); os.write(byteArray);
......
...@@ -28,7 +28,7 @@ public final class PCBcontext { ...@@ -28,7 +28,7 @@ public final class PCBcontext {
private static RestapiWrapper wrapper; private static RestapiWrapper wrapper;
private static Vocabulary vocabulary; private static Vocabulary vocabulary;
private static ActionLog actionLog; private static ActionLog actionLog;
private static boolean init=false;
protected PCBcontext() { protected PCBcontext() {
// Initialize internal objects. This initialization is run only the first time // Initialize internal objects. This initialization is run only the first time
...@@ -50,10 +50,15 @@ public final class PCBcontext { ...@@ -50,10 +50,15 @@ public final class PCBcontext {
// Init method for passing params to the singleton // Init method for passing params to the singleton
public static void init(Context c){ public static void init(Context c){
context=c; if (!init) {
device = new Device(c, null, 1); init=true;
wrapper = new RestapiWrapper(context.getResources().getString(R.string.server),null); context = c;
Log.i(PCBcontext.class.getCanonicalName(), "PCB context started, waiting. It's required set user "); device = new Device(c, null, 1);
wrapper = new RestapiWrapper(context.getResources().getString(R.string.server), null);
service = new NetService(context.getResources().getInteger(R.integer.netservice_timing));
Log.i(PCBcontext.class.getCanonicalName(), "PCB context started. It's required to be invoked set_user method");
}
else Log.e(PCBcontext.class.getClass().getCanonicalName(), "Init method was previously invoked! Please, revise your code");
} }
/** /**
...@@ -64,13 +69,14 @@ public final class PCBcontext { ...@@ -64,13 +69,14 @@ public final class PCBcontext {
* @param listener * @param listener
*/ */
public static void set_user(User student, String token, iImgDownloaderListener listener) { public static void set_user(User student, String token, iImgDownloaderListener listener) {
Log.i(PCBcontext.class.getCanonicalName(), "User set at student "+student.get_name_stu()); if (!init) throw new java.lang.AssertionError("init must be called once previously ");
Log.i(PCBcontext.class.getCanonicalName(), "User set at student " + student.get_name_stu());
wrapper.setToken(token); wrapper.setToken(token);
pcbdb = new PCBDBHelper(null, 1, student); pcbdb = new PCBDBHelper(null, 1, student);
service = new NetService(context.getResources().getInteger(R.integer.netservice_timing));
vocabulary= new Vocabulary(listener);
room = new Room(); room = new Room();
actionLog = new ActionLog(); actionLog = new ActionLog();
vocabulary = new Vocabulary(listener);
} }
// Return the context // Return the context
......
package com.yottacode.tools;
import java.io.File;
/**
* Created by Fernando on 14/03/2016.
*/
public class FileTools {
public static boolean deleteDirectory(File path) {
if( path.exists() ) {
File[] files = path.listFiles();
if (files == null) {
return true;
}
for(int i=0; i<files.length; i++) {
if(files[i].isDirectory()) {
deleteDirectory(files[i]);
}
else {
files[i].delete();
}
}
}
return( path.delete() );
}
}
...@@ -13,18 +13,12 @@ ...@@ -13,18 +13,12 @@
android:contentDescription="@string/app_name" android:contentDescription="@string/app_name"
android:orientation="vertical" android:orientation="vertical"
android:src="@drawable/yottalogo72p" android:src="@drawable/yottalogo72p"
android:layout_alignParentTop="true" android:scaleX="0.5"
android:layout_centerHorizontal="true" android:scaleY="0.5"
android:layout_marginTop="120dp" /> android:id="@+id/imageView2"
android:layout_alignParentBottom="true"
<TextView android:layout_alignParentEnd="true"
android:layout_width="wrap_content" android:layout_marginBottom="44dp" />
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="presenta..."
android:id="@+id/textView2"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<ImageView <ImageView
android:layout_width="200px" android:layout_width="200px"
...@@ -32,19 +26,10 @@ ...@@ -32,19 +26,10 @@
android:contentDescription="@string/app_name" android:contentDescription="@string/app_name"
android:orientation="vertical" android:orientation="vertical"
android:src="@drawable/logo_pictogram" android:src="@drawable/logo_pictogram"
android:layout_alignParentBottom="true" android:id="@+id/imageView"
android:layout_centerHorizontal="true" android:scaleX="1.5"
android:layout_marginBottom="120dp" android:scaleY="1.5"
android:id="@+id/imageView" /> android:layout_centerVertical="true"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Pictogram"
android:id="@+id/textView3"
android:paddingTop="70dp"
android:layout_alignBottom="@+id/imageView"
android:layout_centerHorizontal="true" /> android:layout_centerHorizontal="true" />
</RelativeLayout> </RelativeLayout>
...@@ -53,7 +53,8 @@ constraint ck_users UNIQUE(id_stu,id_sup) ...@@ -53,7 +53,8 @@ constraint ck_users UNIQUE(id_stu,id_sup)
CREATE TABLE collection ( CREATE TABLE collection (
id_stu INTEGER NOT NULL REFERENCES student ON DELETE CASCADE, id_stu INTEGER NOT NULL REFERENCES student ON DELETE CASCADE,
id_picto INTEGER NOT NULL REFERENCES picto ON DELETE CASCADE, id_picto INTEGER NOT NULL REFERENCES picto ON DELETE CASCADE,
attributes VARCHAR(1024) attributes VARCHAR(1024),
constraint ck_collection UNIQUE(id_stu,id_picto)
) )
;-- ;--
...@@ -202,7 +203,7 @@ CREATE TRIGGER trg_delete_collection_detail ...@@ -202,7 +203,7 @@ CREATE TRIGGER trg_delete_collection_detail
INSTEAD OF DELETE ON collection_detail INSTEAD OF DELETE ON collection_detail
FOR EACH ROW FOR EACH ROW
BEGIN BEGIN
DELETE FROM collection WHERE id_picto = OLD.id_picto ; DELETE FROM collection WHERE id_picto = OLD.id_picto AND id_stu = OLD.id_stu;
END END
;-- ;--
......
...@@ -47,4 +47,9 @@ ...@@ -47,4 +47,9 @@
<string name="naturalgrammar">SUpO_EN</string> <string name="naturalgrammar">SUpO_EN</string>
<string name="pictogrammar">SUpO_PICTOEN</string> <string name="pictogrammar">SUpO_PICTOEN</string>
<string name="nogrammar">Warning: unknown language</string> <string name="nogrammar">Warning: unknown language</string>
<!--Upload local img -->
<string name="enterImgLabel">Enter img label</string>
<string name="notNewCats">Including new categories is not allowed</string>
</resources> </resources>
...@@ -46,10 +46,14 @@ ...@@ -46,10 +46,14 @@
<!--Semantic grammar --> <!--Semantic grammar -->
<string name="loadingGrammar">Por favor espere, cargando gramática semántica</string> <string name="loadingGrammar">Por favor espere, cargando gramática semántica</string>
<string name="naturalgrammar">SUpO_ES</string> <string name="naturalgrammar">SUpO_ES</string>
<string name="pictogrammar">SUpO_PICTOES</string> <string name="grammar">SUpO_ES</string>
<string name="nogrammar">Advertencia: Lenguaje no soportado</string> <string name="nogrammar">Advertencia: Lenguaje no soportado</string>
<string name="pictogrammar">SUpO_PICTOES</string>
<item type="integer" name="maxInTape">8</item> <item type="integer" name="maxInTape">8</item>
<!--Upload local img -->
<string name="enterImgLabel">Introduzca etiqueta de la imagen</string>
<string name="notNewCats">No puede añadir nuevas categorias</string>
</resources> </resources>
...@@ -45,8 +45,28 @@ ...@@ -45,8 +45,28 @@
<!--Semantic grammar --> <!--Semantic grammar -->
<string name="loadingGrammar">Please wait, loading semmantic grammar</string> <string name="loadingGrammar">Please wait, loading semmantic grammar</string>
<string name="naturalgrammar">SUpO_EN</string>
<string name="grammar">SUpO_EN</string> <string name="grammar">SUpO_EN</string>
<string name="nogrammar">Warning: unknown language</string> <string name="nogrammar">Warning: unknown language</string>
<string name="pictogrammar">SUpO_PICTOEN</string>
<item type="integer" name="maxInTape">8</item> <!--Upload local img -->
<string name="enterImgLabel">Introduzca etiqueta de la imagen</string>
<string name="notNewCats">No puede añadir nuevas categorias</string>
<item name="maxInTape" type="integer">8</item>
<string name="title_activity_img_label">img_label</string>
<!-- Strings related to login -->
<string name="prompt_email">Email</string>
<string name="prompt_password">Password (optional)</string>
<string name="action_sign_in">Sign in or register</string>
<string name="action_sign_in_short">Sign in</string>
<string name="error_invalid_email">This email address is invalid</string>
<string name="error_invalid_password">This password is too short</string>
<string name="error_incorrect_password">This password is incorrect</string>
<string name="error_field_required">This field is required</string>
<string name="permission_rationale">"Contacts permissions are needed for providing email
completions."
</string>
</resources> </resources>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment