diff --git a/app/app.iml b/app/app.iml index 20413bf..219a04b 100644 --- a/app/app.iml +++ b/app/app.iml @@ -56,25 +56,7 @@ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" /> - <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" /> + <excludeFolder url="file://$MODULE_DIR$/build/intermediates" /> <excludeFolder url="file://$MODULE_DIR$/build/outputs" /> </content> <orderEntry type="jdk" jdkName="Android API 19 Platform" jdkType="Android SDK" /> diff --git a/app/build.gradle b/app/build.gradle index 06e72d4..6dce2b5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,11 +2,11 @@ apply plugin: 'com.android.application' android { compileSdkVersion 19 - buildToolsVersion '19.1.0' + buildToolsVersion '20.0.0' defaultConfig { applicationId "info.nerull7.mysqlbrowser" - minSdkVersion 14 + minSdkVersion 15 targetSdkVersion 19 versionCode 1 versionName "1.0" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b31c3ff..199b74d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,14 +3,13 @@ package="info.nerull7.mysqlbrowser" > <application - android:allowBackup="false" + android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" - android:label="@string/app_name" - android:theme="@style/LoginTheme" > + android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> @@ -18,30 +17,25 @@ </intent-filter> </activity> <activity - android:name=".ListActivity" - android:label="@string/title_activity_list" > + android:name=".DatabaseActivity" + android:label="@string/title_activity_database" > + </activity> + <activity + android:name=".TableActivity" + android:label="@string/title_activity_table" > </activity> <activity android:name=".EntriesActivity" - android:label="@string/title_activity_entries" > + android:label="@string/title_activity_entries" + android:theme="@style/EntriesTheme" > </activity> <activity android:name=".SettingsActivity" android:label="@string/title_activity_setting" - android:theme="@style/SettingsTheme" > - </activity> - <activity - android:name=".ElementActivity" - android:label="@string/title_activity_element" - android:windowSoftInputMode="adjustPan"> - </activity> - <activity - android:name=".SQLActivity" - android:label="@string/title_activity_sql" - android:windowSoftInputMode="adjustResize"> + android:icon="@drawable/ic_action_settings"> </activity> </application> <uses-permission android:name="android.permission.INTERNET" /> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + </manifest> diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/Crypto.java b/app/src/main/java/info/nerull7/mysqlbrowser/Crypto.java index 0ad320e..e22105a 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/Crypto.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/Crypto.java @@ -2,17 +2,21 @@ package info.nerull7.mysqlbrowser; import android.content.Context; import android.util.Base64; +import android.util.Log; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.nio.charset.Charset; import java.security.InvalidKeyException; +import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; +import java.security.spec.KeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; @@ -20,11 +24,10 @@ import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; +import javax.crypto.spec.PBEKeySpec; /** * Created by nerull7 on 28.07.14. - * - * Class delegated to encrypt data */ public class Crypto { private static final String KEY_FILE = "null_file"; // to trick h4x0r5 @@ -46,19 +49,23 @@ public class Crypto { } } - private void generateKey() throws NoSuchAlgorithmException { + private SecretKey generateKey() throws NoSuchAlgorithmException { SecureRandom secureRandom = new SecureRandom(); KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM); keyGenerator.init(OUTPUT_KEY_LENGTH, secureRandom); - secretKey = keyGenerator.generateKey(); + SecretKey secretKey = keyGenerator.generateKey(); + + return secretKey; } private void getSecretKey() throws NoSuchAlgorithmException, IOException, ClassNotFoundException { + String key; + // First try to open file File keyFile = new File(context.getFilesDir(), KEY_FILE); if(!keyFile.exists()) { // new key - generateKey(); + secretKey = generateKey(); FileOutputStream fileOutputStream = new FileOutputStream(keyFile); ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); objectOutputStream.writeObject(secretKey); @@ -93,6 +100,7 @@ public class Crypto { public String decryptBase64(String encodedString) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException { byte [] encryptedString = Base64.decode(encodedString, Base64.DEFAULT); - return decrypt(encryptedString); + String decrypted = decrypt(encryptedString); + return decrypted; } } diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/CustomScrollView.java b/app/src/main/java/info/nerull7/mysqlbrowser/CustomScrollView.java index 13ab2d4..e59685e 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/CustomScrollView.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/CustomScrollView.java @@ -2,7 +2,6 @@ package info.nerull7.mysqlbrowser; import android.content.Context; import android.util.AttributeSet; -import android.view.MotionEvent; import android.widget.ScrollView; /** @@ -10,18 +9,10 @@ import android.widget.ScrollView; */ public class CustomScrollView extends ScrollView { - private OnTouchEventListener onTouchEventListener; + private OnScrollChangedListener listener; - @Override - public boolean onTouchEvent(MotionEvent ev) { - if(onTouchEventListener != null){ - onTouchEventListener.onTouchEvent(ev); - } - return super.onTouchEvent(ev); - } - - public void setOnTouchEventListener(OnTouchEventListener onTouchEventListener){ - this.onTouchEventListener = onTouchEventListener; + public void setOnScrollChangedListener(OnScrollChangedListener listener){ + this.listener = listener; } public CustomScrollView(Context context) { @@ -32,7 +23,13 @@ public class CustomScrollView extends ScrollView { super(context,attributeSet); } - public interface OnTouchEventListener { - public boolean onTouchEvent(MotionEvent ev); + @Override + protected void onScrollChanged(int l, int t, int oldl, int oldt) { + if(listener!=null) + listener.onScrollChanged(l,t,oldl,oldt); + } + + public interface OnScrollChangedListener{ + public void onScrollChanged(int l, int t, int oldl, int oldt); } } diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseActivity.java similarity index 51% rename from app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java rename to app/src/main/java/info/nerull7/mysqlbrowser/DatabaseActivity.java index 3eeb667..0449410 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseActivity.java @@ -1,31 +1,19 @@ package info.nerull7.mysqlbrowser; import android.app.Activity; -import android.app.Fragment; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; -public class ListActivity extends Activity { +public class DatabaseActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_list); - Bundle extras = getIntent().getExtras(); - String fragmentName = extras.getString(Static.FRAGMENT_TO_START); - Fragment fragment = null; - if(fragmentName.compareTo(Static.FRAGMENT_DATABASE)==0){ - fragment = new DatabaseFragment(); - setTitle(R.string.title_fragment_database); - } else if (fragmentName.compareTo(Static.FRAGMENT_TABLE)==0) { - fragment = new TableFragment(); - setTitle(extras.getString(Static.DATABASE_NAME_ARG)); - } - fragment.setArguments(getIntent().getExtras()); + setContentView(R.layout.activity_database); if (savedInstanceState == null) { getFragmentManager().beginTransaction() - .add(R.id.container, fragment) + .add(R.id.container, new DatabaseFragment()) .commit(); } } @@ -33,7 +21,7 @@ public class ListActivity extends Activity { @Override public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.logged, menu); + getMenuInflater().inflate(R.menu.main, menu); return true; } @@ -47,8 +35,6 @@ public class ListActivity extends Activity { if (id == R.id.action_settings) { Static.startSettings(this); return true; - } else if (id == R.id.action_sql){ - Static.startSQL(this, getIntent().getExtras().getString(Static.DATABASE_NAME_ARG)); } return super.onOptionsItemSelected(item); } diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java index 428afa3..428cc0d 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java @@ -17,25 +17,20 @@ import android.widget.TextView; import java.util.List; -import info.nerull7.mysqlbrowser.db.DatabaseConnector; +import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector; /** * Created by nerull7 on 14.07.14. * * Fragment for showing list of Available Databases for user */ -public class DatabaseFragment extends Fragment implements AdapterView.OnItemClickListener, DatabaseConnector.ListReturnListener, DatabaseConnector.OnPostExecuteListener { +public class DatabaseFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener { private ListView databasesListView; private ListAdapter listAdapter; private RelativeLayout rootView; private ProgressBar progressBar; - private List<String> databases; - @Override - public void onResume() { - super.onResume(); - Static.databaseConnector.setDatabaseInUse(null); - } + private String chosenDatabase; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ @@ -45,46 +40,48 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic this.rootView = (RelativeLayout) rootView; progressBar = (ProgressBar) rootView.findViewById(R.id.loginProgressBar); - Static.databaseConnector.setListReturnListener(this); - Static.databaseConnector.setOnPostExecuteListener(this); - Static.databaseConnector.getDatabases(); +// Static.asyncDatabaseConnector.setListReturnListener(this); +// Static.asyncDatabaseConnector.getDatabases(); + + listAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, Static.databases); + databasesListView.setAdapter(listAdapter); + databasesListView.setOnItemClickListener(this); + progressBar.setVisibility(View.INVISIBLE); + return rootView; } @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { - if(Static.isNetworkConnected(getActivity())) { - String chosenDatabase = (String) listAdapter.getItem(position); - listAdapter.getItem(position); - Intent intent = new Intent(getActivity(), ListActivity.class); - intent.putExtra(Static.FRAGMENT_TO_START, Static.FRAGMENT_TABLE); - intent.putExtra(Static.DATABASE_NAME_ARG, chosenDatabase); - Static.databaseConnector.setDatabaseInUse(chosenDatabase); - startActivity(intent); - } else { - Static.showErrorAlert(getResources().getString(R.string.no_connection), getActivity()); - } + chosenDatabase = (String) listAdapter.getItem(position); + listAdapter.getItem(position); + + progressBar.setVisibility(View.VISIBLE); + Static.asyncDatabaseConnector.setDatabaseInUse(chosenDatabase); + Static.asyncDatabaseConnector.setListReturnListener(this); + Static.asyncDatabaseConnector.getTables(); } @Override - public void onListReturn(List<String> databases) { - this.databases = databases; - } - - @Override - public void onPostExecute() { - if(databases!= null) { - listAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, databases); - databasesListView.setAdapter(listAdapter); - databasesListView.setOnItemClickListener(this); - } else { - TextView errorMessage = new TextView(getActivity()); - errorMessage.setText(R.string.error_no_databases); - errorMessage.setTypeface(null, Typeface.ITALIC); - errorMessage.setClickable(false); - rootView.addView(errorMessage); - rootView.removeView(databasesListView); + public void onListReturn(List<String> tables) { +// if(databases!= null) { +// listAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, databases); +// databasesListView.setAdapter(listAdapter); +// databasesListView.setOnItemClickListener(this); +// } else { +// TextView errorMessage = new TextView(getActivity()); +// errorMessage.setText(R.string.error_no_databases); +// errorMessage.setTypeface(null, Typeface.ITALIC); +// errorMessage.setClickable(false); +// rootView.addView(errorMessage); +// rootView.removeView(databasesListView); +// } +// progressBar.setVisibility(View.INVISIBLE); + if(tables!=null) { + Static.tables = tables; } - progressBar.setVisibility(View.INVISIBLE); + Intent intent = new Intent(getActivity(), TableActivity.class); + intent.putExtra(Static.DATABASE_NAME_ARG, chosenDatabase); + startActivity(intent); } } diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java deleted file mode 100644 index 2034810..0000000 --- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java +++ /dev/null @@ -1,49 +0,0 @@ -package info.nerull7.mysqlbrowser; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.os.Bundle; - -public class ElementActivity extends Activity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_element); - Bundle bundle = getIntent().getExtras(); - String titleName = bundle.getString(Static.TABLE_NAME_ARG); - setTitle(titleName); - - ElementFragment elementFragment = new ElementFragment(); - elementFragment.setArguments(bundle); - - if (savedInstanceState == null) { - getFragmentManager().beginTransaction() - .add(R.id.container, elementFragment) - .commit(); - } - } - - @Override - public void onBackPressed() { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setMessage(getString(R.string.error_no_save)); - builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - - } - }); - builder.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - finish(); - } - }); - builder.setTitle(R.string.warning); - builder.setIcon(R.drawable.ic_action_warning); - builder.create(); - builder.show(); - } -} diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java deleted file mode 100644 index 32388b5..0000000 --- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java +++ /dev/null @@ -1,79 +0,0 @@ -package info.nerull7.mysqlbrowser; - -import android.content.Context; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.TextView; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by nerull7 on 2014-08-06. - */ -public class ElementArrayAdapter extends ArrayAdapter<String> { - private Context context; - private List<String> fields; - private List<String> values; - private int layout; - - public ElementArrayAdapter(Context context, int resource, List<String> fields) { - super(context, resource, fields); - init(context, resource, fields); - values = new ArrayList<String>(); - for(String field: fields){ - values.add(""); - } - } - - public ElementArrayAdapter(Context context, int resource, List<String> fields, List<String> values) { - super(context, resource, fields); - init(context, resource, fields); - this.values = new ArrayList<String>(); - if(values!=null) { - this.values.addAll(values); // Copy - } else { - for(int i=0;i<fields.size();i++){ - this.values.add(new String()); - } - } - } - - private void init(Context context, int resource, List<String> fields){ - this.context = context; - this.fields = fields; - layout = resource; - } - - @Override - public View getView(final int position, View convertView, ViewGroup parent) { - LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - final View rowView = layoutInflater.inflate(layout, parent, false); - - TextView textView = (TextView) rowView.findViewById(R.id.textFieldName); - textView.setText(fields.get(position)); - TextView textFieldName = (TextView) rowView.findViewById(R.id.editFieldValue); - textFieldName.setText(values.get(position)); - textFieldName.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (!hasFocus) { - String tmp = String.valueOf(((TextView) v).getText()); - values.set(position, tmp); - } - } - }); - return rowView; - } - - public List<String> getFieldArray(){ - return fields; - } - - public List<String> getValues() { - return values; - } -} diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java deleted file mode 100644 index 236c769..0000000 --- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java +++ /dev/null @@ -1,202 +0,0 @@ -package info.nerull7.mysqlbrowser; - -import android.app.AlertDialog; -import android.app.Fragment; -import android.content.Context; -import android.content.DialogInterface; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; -import android.widget.AbsListView; -import android.widget.ListView; -import android.widget.ProgressBar; - -import java.util.List; - -import info.nerull7.mysqlbrowser.db.DatabaseConnector; - -/** - * Created by nerull7 on 2014-08-06. - * - * Fragment for editing/adding elements - */ -public class ElementFragment extends Fragment implements DatabaseConnector.ListReturnListener, DatabaseConnector.StringReturnListener, DatabaseConnector.OnPostExecuteListener { - public static final String EDIT_ELEMENT = "edit_element"; - public static final String EDIT_LIST = "edit_element_list"; - - private static final int POST_EXECUTE_NONE = 0; - private static final int POST_EXECUTE_GET_FIELDS = 1; - private static final int POST_EXECUTE_UPDATE_ELEMENT = 2; - private static final int POST_EXECUTE_ADD_ELEMENT = 3; - - private String tableName; - private ElementArrayAdapter listAdapter; - - private ProgressBar progressBar; - private ListView listView; - - private List<String> values; - private String message; - private int postExecute; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - //Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_element, container, false); - progressBar = (ProgressBar) rootView.findViewById(R.id.progressBar); - listView = (ListView) rootView.findViewById(R.id.listView); - - listView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - if(scrollState==SCROLL_STATE_TOUCH_SCROLL) { - listView.requestFocus(); - InputMethodManager inputMethodManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); - inputMethodManager.hideSoftInputFromWindow(listView.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); - } - } - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - } - }); - listView.setItemsCanFocus(true); - initArguments(); - - postExecute = POST_EXECUTE_NONE; - Static.databaseConnector.setListReturnListener(this); - Static.databaseConnector.setOnPostExecuteListener(this); - Static.databaseConnector.getFields(tableName); - - return rootView; - } - - private void actionSave(){ - List<String> fields = listAdapter.getFieldArray(); - Static.databaseConnector.setStringReturnListener(this); - if(getArguments().getBoolean(EDIT_ELEMENT)) - Static.databaseConnector.updateElement(tableName, fields, values, listAdapter.getValues()); - else - Static.databaseConnector.addNewElement(tableName, fields, listAdapter.getValues()); - } - - private void actionRemove(){ - final List<String> fields = listAdapter.getFieldArray(); - Static.databaseConnector.setStringReturnListener(this); - - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setMessage(R.string.error_remove); - builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - Static.databaseConnector.removeElement(tableName, fields, values); -// getActivity().finish(); - } - }); - builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - // Nothing to do just get back - } - }); - builder.setTitle(R.string.warning); - builder.setIcon(R.drawable.ic_action_warning); - builder.setCancelable(false); // There is no exit - builder.create(); - builder.show(); - - - - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - listView.requestFocus(); - switch (item.getItemId()){ - case R.id.action_save: - actionSave(); - break; - case R.id.action_remove: - actionRemove(); - break; - default: - return super.onOptionsItemSelected(item); - } - return true; - } - - private void initArguments() { - tableName = getArguments().getString(Static.TABLE_NAME_ARG); - if(getArguments().getBoolean(EDIT_ELEMENT)) - values = getArguments().getStringArrayList(EDIT_LIST); - else - values = null; - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - inflater.inflate(R.menu.element, menu); - if(!getArguments().getBoolean(EDIT_ELEMENT)) { - menu.findItem(R.id.action_remove).setVisible(false); - } - super.onCreateOptionsMenu(menu, inflater); - } - - @Override - public void onListReturn(List<String> fields) { - listAdapter = new ElementArrayAdapter(getActivity(), R.layout.list_item_element_simple, fields, values); - postExecute = POST_EXECUTE_GET_FIELDS; - - } - - @Override - public void onStringReturn(String data) { - message = data; - postExecute = POST_EXECUTE_ADD_ELEMENT; - } - - @Override - public void onPostExecute() { - switch (postExecute){ - case POST_EXECUTE_GET_FIELDS: - listView.setAdapter(listAdapter); - progressBar.setVisibility(View.INVISIBLE); - setHasOptionsMenu(true); - break; - case POST_EXECUTE_ADD_ELEMENT: - case POST_EXECUTE_UPDATE_ELEMENT: - showInfo(message); - break; - } - // Clean after execute - postExecute = POST_EXECUTE_NONE; - } - - private void showInfo(String info){ - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setMessage(info); - builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - getActivity().finish(); - } - }); - /*builder.setNegativeButton(R.string.back, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - // Nothing to do just get back - } - });*/ - builder.setTitle(R.string.status); - builder.setIcon(R.drawable.ic_action_warning); - builder.setCancelable(false); // There is no exit - builder.create(); - builder.show(); - } - -} diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesActivity.java index c783710..db98696 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesActivity.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesActivity.java @@ -2,6 +2,11 @@ package info.nerull7.mysqlbrowser; import android.app.Activity; import android.os.Bundle; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; + +import java.util.zip.Inflater; public class EntriesActivity extends Activity { diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java index 3c8a5b9..ddc5daa 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java @@ -1,7 +1,6 @@ package info.nerull7.mysqlbrowser; import android.app.Fragment; -import android.content.Intent; import android.graphics.Typeface; import android.os.Bundle; import android.preference.PreferenceManager; @@ -9,11 +8,9 @@ import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; -import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; -import android.widget.HorizontalScrollView; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.ScrollView; @@ -21,17 +18,14 @@ import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; -import java.util.ArrayList; import java.util.List; -import info.nerull7.mysqlbrowser.db.DatabaseConnector; +import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector; /** * Created by nerull7 on 15.07.14. - * - * Fragment for showing elements */ -public class EntriesFragment extends Fragment implements DatabaseConnector.MatrixReturnListener, DatabaseConnector.ListReturnListener, DatabaseConnector.IntegerReturnListener, View.OnClickListener, DatabaseConnector.OnPostExecuteListener { +public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.MatrixReturnListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.IntegerReturnListener { private static final int HEADER_PADDING_TOP = 15; private static final int HEADER_PADDING_BOTTOM = 15; private static final int HEADER_PADDING_LEFT = 15; @@ -42,28 +36,23 @@ public class EntriesFragment extends Fragment implements DatabaseConnector.Matri private static final int ENTRIES_PADDING_RIGHT = 15; private TableLayout entriesTable; - private ScrollView entriesScrollView; + private CustomScrollView entriesScrollView; private FrameLayout headerFrame; - private HorizontalScrollView horizontalScrollView; + private RelativeLayout rootView; private TableRow.LayoutParams layoutParams; + private TableRow headerRow; private String databaseName; private String tableName; private int entriesLimit; private int page; private int pageCount; - private int rowCount; private ProgressBar progressBar; - private CustomScrollView fakeScrollView; + private ScrollView fakeScrollView; private View dummyView; - private int onPostExecuteListenerExecuted; - + private MenuInflater menuInflater; private Menu menu; - private TableRow headerRow; - private int[] maxWidth; - - private boolean isFirstCreate; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -72,11 +61,63 @@ public class EntriesFragment extends Fragment implements DatabaseConnector.Matri initArguments(); initViewItems(rootView); - initListeners(); - onPostExecuteListenerExecuted = 0; - Static.databaseConnector.getFields(tableName); - Static.databaseConnector.getEntriesCount(tableName); +// Static.asyncDatabaseConnector.setIntegerReturnListener(this); +// Static.asyncDatabaseConnector.setListReturnListener(this); +// Static.asyncDatabaseConnector.setMatrixReturnListener(this); +// Static.asyncDatabaseConnector.getFields(tableName); +// Static.asyncDatabaseConnector.getEntriesCount(tableName); + + pageCount = Static.pageCount/entriesLimit; + if( Static.pageCount%entriesLimit > 0) + pageCount++; + + if(pageCount>1) + setHasOptionsMenu(true); + + // First we need header + headerRow = new TableRow(getActivity()); + headerRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)); + for(int i =0;i<Static.header.size();i++){ + TextView textView = new TextView(getActivity()); + textView.setText(Static.header.get(i)); + textView.setTypeface(null, Typeface.BOLD); + textView.setLayoutParams(layoutParams); + textView.setBackgroundResource(R.drawable.background_header); + textView.setPadding(HEADER_PADDING_LEFT, HEADER_PADDING_TOP, HEADER_PADDING_RIGHT, HEADER_PADDING_BOTTOM); + headerRow.addView(textView); + } + headerFrame.addView(headerRow); + + // now data + if(Static.entries!=null) { + for (int i = 0; i < Static.entries.size(); i++) { + List<String> elements = Static.entries.get(i); + TableRow newRow = new TableRow(getActivity()); + for (int j = 0; j < elements.size(); j++) { // elements.size can be the same as in header so maybe some one number or not + TextView textView = new TextView(getActivity()); + textView.setText(elements.get(j)); + textView.setLayoutParams(layoutParams); + textView.setPadding(ENTRIES_PADDING_LEFT, ENTRIES_PADDING_TOP, ENTRIES_PADDING_RIGHT, ENTRIES_PADDING_BOTTOM); + textView.setBackgroundResource(R.drawable.background_element); + newRow.addView(textView); + } + entriesTable.addView(newRow); + + syncWidths(); + fakeScroll(); + } + } else { + TextView errorMessage = new TextView(getActivity()); + errorMessage.setText(R.string.error_no_entries); + errorMessage.setTypeface(null, Typeface.ITALIC); + errorMessage.setClickable(false); + entriesScrollView.removeView(entriesTable); + headerFrame.setVisibility(View.VISIBLE); + entriesScrollView.addView(errorMessage); + } + + setLoading(false); return rootView; } @@ -85,48 +126,39 @@ public class EntriesFragment extends Fragment implements DatabaseConnector.Matri databaseName = getArguments().getString(Static.DATABASE_NAME_ARG); tableName = getArguments().getString(Static.TABLE_NAME_ARG); page = 1; - isFirstCreate = true; entriesLimit = PreferenceManager.getDefaultSharedPreferences(getActivity()).getInt(SettingsFragment.ENTRIES_PAGE_LIMIT, SettingsFragment.ENTRIES_PAGE_LIMIT_DEF); } private void initViewItems(View rootView){ headerFrame = (FrameLayout) rootView.findViewById(R.id.headerFrame); - entriesScrollView = (ScrollView) rootView.findViewById(R.id.entriesScrollView); - fakeScrollView = (CustomScrollView) rootView.findViewById(R.id.fakeScroll); + entriesTable = (TableLayout) rootView.findViewById(R.id.entriesTable); + entriesScrollView = (CustomScrollView) rootView.findViewById(R.id.entriesScrollView); + fakeScrollView = (ScrollView) rootView.findViewById(R.id.fakeScroll); progressBar = (ProgressBar) rootView.findViewById(R.id.loginProgressBar); dummyView = rootView.findViewById(R.id.dummyView); - horizontalScrollView = (HorizontalScrollView) rootView.findViewById(R.id.horizontalScrollView); - entriesTable = new TableLayout(getActivity()); - fakeScrollView.setOnTouchEventListener(new CustomScrollView.OnTouchEventListener() { + this.rootView = (RelativeLayout) rootView; + + entriesScrollView.setOnScrollChangedListener(new CustomScrollView.OnScrollChangedListener() { @Override - public boolean onTouchEvent(MotionEvent ev) { - ev.offsetLocation(0, headerFrame.getHeight()); - horizontalScrollView.dispatchTouchEvent(ev); - return true; + public void onScrollChanged(int l, int t, int oldl, int oldt) { + fakeScrollView.scrollTo(0,t); } }); - layoutParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.MATCH_PARENT); - } - - private void initListeners(){ - Static.databaseConnector.setIntegerReturnListener(this); - Static.databaseConnector.setListReturnListener(this); - Static.databaseConnector.setMatrixReturnListener(this); - Static.databaseConnector.setOnPostExecuteListener(this); + layoutParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT); + headerFrame.setVisibility(View.INVISIBLE); + entriesTable.setVisibility(View.INVISIBLE); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.entries_activity_actions, menu); - + menuInflater = inflater; // I think we need it later menu.findItem(R.id.action_previous).setVisible(false); // hide previous - if(pageCount<=1) - menu.findItem(R.id.action_next).setVisible(false); // hide next if we don't have any more pages this.menu = menu; - super.onCreateOptionsMenu(menu, inflater); +// super.onCreateOptionsMenu(menu, inflater); } private void changeMenus(int page){ @@ -150,97 +182,76 @@ public class EntriesFragment extends Fragment implements DatabaseConnector.Matri progressBar.setVisibility(isLoading ? View.VISIBLE : View.INVISIBLE); } - private void loadAnotherPage(){ - changeMenus(page); - entriesScrollView.removeAllViews(); // clean table - entriesTable = new TableLayout(getActivity()); - onPostExecuteListenerExecuted--; - - setLoading(true); - Static.databaseConnector.getRows(tableName, entriesLimit, page); // get new entries - } - - private void addNewElement(){ - Intent intent = new Intent(getActivity(), ElementActivity.class); - intent.putExtra(Static.DATABASE_NAME_ARG,databaseName); - intent.putExtra(Static.TABLE_NAME_ARG,tableName); - startActivity(intent); - } - @Override public boolean onOptionsItemSelected(MenuItem item) { - if (Static.isNetworkConnected(getActivity())) { - switch (item.getItemId()) { - case R.id.action_previous: - page--; - loadAnotherPage(); - break; - case R.id.action_next: - page++; - loadAnotherPage(); - break; - case R.id.action_add: - addNewElement(); - break; - } - } else { - Static.showErrorAlert(getResources().getString(R.string.no_connection), getActivity()); + switch (item.getItemId()){ + case R.id.action_previous: + page--; + break; + case R.id.action_next: + page++; + break; } + changeMenus(page); + entriesTable.removeAllViews(); // clean table + + setLoading(true); + Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page); // get new entries + + return super.onOptionsItemSelected(item); } @Override public void onMatrixReturn(List<List<String>> rows) { - // Now we get Rows - if(rows!=null) { - int background; - for (int i = 0; i < rows.size(); i++) { - List<String> elements = rows.get(i); - TableRow newRow = new TableRow(getActivity()); - - if( i%2 == 0 ){ // Two backgrounds for lines for better visibility - background=R.drawable.entries_element_1; - } else { - background=R.drawable.entries_element_2; - } - - for (int j = 0; j < elements.size(); j++) { // elements.size can be the same as in header so maybe some one number or not - TextView textView = new TextView(getActivity()); - textView.setText(elements.get(j)); - textView.setLayoutParams(layoutParams); - textView.setPadding(ENTRIES_PADDING_LEFT, ENTRIES_PADDING_TOP, ENTRIES_PADDING_RIGHT, ENTRIES_PADDING_BOTTOM); - textView.setBackgroundResource(background); - textView.setId(j); - newRow.addView(textView); - } - newRow.setClickable(true); - newRow.setOnClickListener(this); - entriesTable.addView(newRow); - syncWidthsFirstStage(); - } - } else { - entriesTable = null; - } - +// // Now we get Rows +// if(rows!=null) { +// for (int i = 0; i < rows.size(); i++) { +// List<String> elements = rows.get(i); +// TableRow newRow = new TableRow(getActivity()); +// for (int j = 0; j < elements.size(); j++) { // elements.size can be the same as in header so maybe some one number or not +// TextView textView = new TextView(getActivity()); +// textView.setText(elements.get(j)); +// textView.setLayoutParams(layoutParams); +// textView.setPadding(ENTRIES_PADDING_LEFT, ENTRIES_PADDING_TOP, ENTRIES_PADDING_RIGHT, ENTRIES_PADDING_BOTTOM); +// textView.setBackgroundResource(R.drawable.background_element); +// newRow.addView(textView); +// } +// entriesTable.addView(newRow); +// +// syncWidths(); +// fakeScroll(); +// } +// } else { +// TextView errorMessage = new TextView(getActivity()); +// errorMessage.setText(R.string.error_no_entries); +// errorMessage.setTypeface(null, Typeface.ITALIC); +// errorMessage.setClickable(false); +// entriesScrollView.removeView(entriesTable); +// headerFrame.setVisibility(View.VISIBLE); +// entriesScrollView.addView(errorMessage); +// } +// +// setLoading(false); } @Override public void onListReturn(List<String> fieldList) { - // First we need header - headerRow = new TableRow(getActivity()); - headerRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)); - rowCount = fieldList.size(); - for (String aFieldList : fieldList) { - TextView textView = new TextView(getActivity()); - textView.setText(aFieldList); - textView.setTypeface(null, Typeface.BOLD); - textView.setLayoutParams(layoutParams); - textView.setBackgroundResource(R.drawable.background_header); - textView.setPadding(HEADER_PADDING_LEFT, HEADER_PADDING_TOP, HEADER_PADDING_RIGHT, HEADER_PADDING_BOTTOM); - headerRow.addView(textView); - } - - Static.databaseConnector.getRows(tableName, entriesLimit, page); +// // First we need header +// headerRow = new TableRow(getActivity()); +// headerRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)); +// for(int i =0;i<fieldList.size();i++){ +// TextView textView = new TextView(getActivity()); +// textView.setText(fieldList.get(i)); +// textView.setTypeface(null, Typeface.BOLD); +// textView.setLayoutParams(layoutParams); +// textView.setBackgroundResource(R.drawable.background_header); +// textView.setPadding(HEADER_PADDING_LEFT, HEADER_PADDING_TOP, HEADER_PADDING_RIGHT, HEADER_PADDING_BOTTOM); +// headerRow.addView(textView); +// } +// headerFrame.addView(headerRow); +// +// Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page); } @Override @@ -248,35 +259,31 @@ public class EntriesFragment extends Fragment implements DatabaseConnector.Matri pageCount = result/entriesLimit; if( result%entriesLimit > 0) pageCount++; - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - setHasOptionsMenu(true); - } - }); + + if(pageCount>1) + setHasOptionsMenu(true); } - private void syncWidthsFirstStage() { // TODO: Merge with adding columns maybe? Loops -= 3 should be quicker - maxWidth = new int[headerRow.getChildCount()]; - for (int i = 0; i < headerRow.getChildCount(); i++) { + private void syncWidths(){ // TODO: Merge with adding columns maybe? Loops -= 3 should be quicker + TableRow headerRow = (TableRow) headerFrame.getChildAt(0); + int maxWidth[]= new int[headerRow.getChildCount()]; + for(int i=0;i<headerRow.getChildCount();i++){ TextView textView = (TextView) headerRow.getChildAt(i); textView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); maxWidth[i] = textView.getMeasuredWidth(); } - for (int i = 0; i < entriesTable.getChildCount(); i++) { + for(int i=0;i<entriesTable.getChildCount();i++){ TableRow tableRow = (TableRow) entriesTable.getChildAt(i); - for (int j = 0; j < tableRow.getChildCount(); j++) { + for(int j=0;j<tableRow.getChildCount();j++){ TextView textView = (TextView) tableRow.getChildAt(j); textView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); int width = textView.getMeasuredWidth(); - if (width > maxWidth[j]) - maxWidth[j] = width; + if(width>maxWidth[j]) + maxWidth[j]=width; } } - } - private void syncWidthsSecondStage() { for(int i=0;i<headerRow.getChildCount();i++){ TableRow entriesRow = (TableRow) entriesTable.getChildAt(0); @@ -286,65 +293,16 @@ public class EntriesFragment extends Fragment implements DatabaseConnector.Matri tmpEntries.setWidth(maxWidth[i]); tmpHeader.setWidth(maxWidth[i]); } + + headerFrame.setVisibility(View.VISIBLE); + entriesTable.setVisibility(View.VISIBLE); } private void fakeScroll(){ entriesScrollView.measure(View.MeasureSpec.UNSPECIFIED,View.MeasureSpec.UNSPECIFIED); int height = entriesScrollView.getMeasuredHeight(); dummyView.setMinimumHeight(height); - - RelativeLayout.LayoutParams fakeScrollLayout = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - headerFrame.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - fakeScrollLayout.setMargins(0,headerFrame.getMeasuredHeight(),0,0); - - fakeScrollView.setLayoutParams(fakeScrollLayout); } - @Override - public void onClick(View view) { - ArrayList<String> values = new ArrayList<String>(); - for(int i=0;i<rowCount;i++){ - TextView element = (TextView)view.findViewById(i); - values.add(element.getText().toString()); -// element.setBackgroundResource(android.R.color.holo_blue_bright); - } - Intent intent = new Intent(getActivity(), ElementActivity.class); - intent.putExtra(Static.DATABASE_NAME_ARG,databaseName); - intent.putExtra(Static.TABLE_NAME_ARG,tableName); - intent.putExtra(ElementFragment.EDIT_ELEMENT, true); - intent.putStringArrayListExtra(ElementFragment.EDIT_LIST, values); - startActivity(intent); - } - - @Override - public void onResume() { - super.onResume(); - if(!isFirstCreate) { - initListeners(); // Could be overwritten - loadAnotherPage(); // This reloads entries - } else { - isFirstCreate = false; - } - } - - @Override - public void onPostExecute() { - if(++onPostExecuteListenerExecuted==3){ - if(headerFrame.getChildCount()==0) // You can have only one child - headerFrame.addView(headerRow); - if(entriesTable!=null) { - syncWidthsSecondStage(); - entriesScrollView.addView(entriesTable); - fakeScroll(); - } else { - TextView errorMessage = new TextView(getActivity()); - errorMessage.setText(R.string.error_no_entries); - errorMessage.setTypeface(null, Typeface.ITALIC); - errorMessage.setClickable(false); - entriesScrollView.addView(errorMessage); - } - setLoading(false); - } - } } diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java index 324c7e4..5946d31 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java @@ -1,34 +1,46 @@ package info.nerull7.mysqlbrowser; +import android.app.AlertDialog; import android.app.Fragment; +import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.graphics.Typeface; import android.os.Bundle; +import android.preference.Preference; import android.preference.PreferenceManager; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; +import android.widget.TextView; -import info.nerull7.mysqlbrowser.db.DatabaseConnector; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.List; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector; /** * Created by nerull7 on 07.07.14. - * - * Fragment for login */ -public class LoginFragment extends Fragment implements View.OnClickListener, DatabaseConnector.BooleanReturnListener, DatabaseConnector.OnPostExecuteListener { +public class LoginFragment extends Fragment implements View.OnClickListener, AsyncDatabaseConnector.BooleanReturnListener, AsyncDatabaseConnector.ListReturnListener { private EditText urlTextbox; private EditText loginTextbox; private EditText passwordTextbox; private ProgressBar progressBar; private Button loginButton; - DatabaseConnector databaseConnector; - - private boolean result; + AsyncDatabaseConnector asyncDatabaseConnector; public LoginFragment(){} @@ -49,13 +61,6 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Dat return rootView; } - @Override - public void onResume() { - super.onResume(); - - processCredentials(); - } - private void processCredentials() { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); @@ -84,38 +89,55 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Dat login = loginTextbox.getText().toString(); password = passwordTextbox.getText().toString(); url = urlTextbox.getText().toString(); - - if(Static.isNetworkConnected(getActivity())) { - databaseConnector = new DatabaseConnector(login, password, url, getActivity().getResources()); - databaseConnector.setBooleanReturnListener(this); - databaseConnector.setOnPostExecuteListener(this); - databaseConnector.checkLogin(); - } else { - Static.showErrorAlert(getResources().getString(R.string.no_connection), getActivity()); - loginButton.setEnabled(true); // Now we can click button again - progressBar.setVisibility(View.INVISIBLE); - } + asyncDatabaseConnector = new AsyncDatabaseConnector(login, password, url); + asyncDatabaseConnector.setBooleanReturnListener(this); + asyncDatabaseConnector.checkLogin(); } @Override public void onBooleanReturn(boolean result) { - this.result = result; - } - - - @Override - public void onPostExecute() { if(result) { - Static.databaseConnector = databaseConnector; - Intent intent = new Intent(getActivity(), ListActivity.class); - intent.putExtra(Static.FRAGMENT_TO_START, Static.FRAGMENT_DATABASE); - startActivity(intent); + Static.asyncDatabaseConnector = asyncDatabaseConnector; + Static.asyncDatabaseConnector.setListReturnListener(this); + Static.asyncDatabaseConnector.getDatabases(); } else { - Static.showErrorAlert(DatabaseConnector.errorMsg, getActivity()); + final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setMessage(Static.asyncDatabaseConnector.errorMsg); + builder.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + // Nothing to do here + // Cleaning inputs is stupid + } + }); + builder.setTitle(R.string.error); + builder.setIcon(R.drawable.ic_action_warning); + builder.create(); + builder.show(); } - loginButton.setEnabled(true); // Now we can click button again progressBar.setVisibility(View.INVISIBLE); } + + @Override + public void onListReturn(List<String> databases) { + if(databases!= null) { + Static.databases = databases; + + Intent intent = new Intent(getActivity(), DatabaseActivity.class); + startActivity(intent); + } +// listAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, databases); +// databasesListView.setAdapter(listAdapter); +// databasesListView.setOnItemClickListener(this); +// } else { +// TextView errorMessage = new TextView(getActivity()); +// errorMessage.setText(R.string.error_no_databases); +// errorMessage.setTypeface(null, Typeface.ITALIC); +// errorMessage.setClickable(false); +// rootView.addView(errorMessage); +// rootView.removeView(databasesListView); +// } + } } diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/MainActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/MainActivity.java index d70a46f..f5c394c 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/MainActivity.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/MainActivity.java @@ -1,6 +1,7 @@ package info.nerull7.mysqlbrowser; import android.app.Activity; +import android.content.Intent; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/NumberPickerDialog.java b/app/src/main/java/info/nerull7/mysqlbrowser/NumberPickerDialog.java new file mode 100644 index 0000000..c4778df --- /dev/null +++ b/app/src/main/java/info/nerull7/mysqlbrowser/NumberPickerDialog.java @@ -0,0 +1,108 @@ +package info.nerull7.mysqlbrowser; + +/** + * Created by nerull7 on 18.07.14. + */ + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.NumberPicker; + +/** + * A dialog that prompts the user for the message deletion limits. + */ +public class NumberPickerDialog extends AlertDialog implements DialogInterface.OnClickListener { + private static final String NUMBER = "number"; + + /** + * The callback interface used to indicate the user is done filling in + * the time (they clicked on the 'Set' button). + */ + public interface OnNumberSetListener { + + /** + * @param number The number that was set. + */ + void onNumberSet(int number); + } + + private final NumberPicker mNumberPicker; + private final OnNumberSetListener mCallback; + + /** + * @param context Parent. + * @param callBack How parent is notified. + * @param number The initial number. + */ + public NumberPickerDialog(Context context, + OnNumberSetListener callBack, + int number, + int rangeMin, + int rangeMax, + int title) { + this(context, AlertDialog.THEME_HOLO_LIGHT, callBack, number, rangeMin, rangeMax, title); + } + + /** + * @param context Parent. + * @param theme the theme to apply to this dialog + * @param callBack How parent is notified. + * @param number The initial number. + */ + public NumberPickerDialog(Context context, + int theme, + OnNumberSetListener callBack, + int number, + int rangeMin, + int rangeMax, + int title) { + super(context, theme); + mCallback = callBack; + + setTitle(title); + + setButton(DialogInterface.BUTTON_POSITIVE, context.getText(R.string.set), this); + setButton(DialogInterface.BUTTON_NEGATIVE, context.getText(R.string.cancel), + (OnClickListener) null); + + LayoutInflater inflater = + (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View view = inflater.inflate(R.layout.number_picker_dialog, null); + setView(view); + mNumberPicker = (NumberPicker) view.findViewById(R.id.number_picker); + + // initialize state + mNumberPicker.setMinValue(rangeMin); + mNumberPicker.setMaxValue(rangeMax); + mNumberPicker.setValue(number); + mNumberPicker.setOnLongPressUpdateInterval(100); // make the repeat rate three times as fast + // as normal since the range is so large. + mNumberPicker.setWrapSelectorWheel(false); // don't wrap from min->max + } + + public void onClick(DialogInterface dialog, int which) { + if (mCallback != null) { + mNumberPicker.clearFocus(); + mCallback.onNumberSet(mNumberPicker.getValue()); + dialog.dismiss(); + } + } + + @Override + public Bundle onSaveInstanceState() { + Bundle state = super.onSaveInstanceState(); + state.putInt(NUMBER, mNumberPicker.getValue()); + return state; + } + + @Override + public void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + int number = savedInstanceState.getInt(NUMBER); + mNumberPicker.setValue(number); + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/SQLActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/SQLActivity.java deleted file mode 100644 index 396ce94..0000000 --- a/app/src/main/java/info/nerull7/mysqlbrowser/SQLActivity.java +++ /dev/null @@ -1,22 +0,0 @@ -package info.nerull7.mysqlbrowser; - -import android.app.Activity; -import android.os.Bundle; - -/** - * Created by nerull7 on 30.09.14. - */ -public class SQLActivity extends Activity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_sql); - - if (savedInstanceState == null) { - getFragmentManager().beginTransaction() - .add(R.id.container, new SQLFragment()) - .commit(); - } - } - -} diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/SQLEntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/SQLEntriesFragment.java deleted file mode 100644 index 610a66a..0000000 --- a/app/src/main/java/info/nerull7/mysqlbrowser/SQLEntriesFragment.java +++ /dev/null @@ -1,240 +0,0 @@ -package info.nerull7.mysqlbrowser; - -import android.app.AlertDialog; -import android.app.Fragment; -import android.content.DialogInterface; -import android.graphics.Typeface; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; -import android.widget.HorizontalScrollView; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.ScrollView; -import android.widget.TableLayout; -import android.widget.TableRow; -import android.widget.TextView; - -import java.util.List; - -import info.nerull7.mysqlbrowser.db.DatabaseConnector; - -/** - * Created by nerull7 on 15.07.14. - * - * Fragment for showing elements - */ -public class SQLEntriesFragment extends Fragment implements DatabaseConnector.MatrixReturnListener, DatabaseConnector.ListReturnListener, DatabaseConnector.OnPostExecuteListener, DatabaseConnector.StringReturnListener { - private static final int HEADER_PADDING_TOP = 15; - private static final int HEADER_PADDING_BOTTOM = 15; - private static final int HEADER_PADDING_LEFT = 15; - private static final int HEADER_PADDING_RIGHT = 15; - private static final int ENTRIES_PADDING_TOP = 30; - private static final int ENTRIES_PADDING_BOTTOM = 30; - private static final int ENTRIES_PADDING_LEFT = 15; - private static final int ENTRIES_PADDING_RIGHT = 15; - - private TableLayout entriesTable; - private ScrollView entriesScrollView; - private FrameLayout headerFrame; - private HorizontalScrollView horizontalScrollView; - private TableRow.LayoutParams layoutParams; - - private ProgressBar progressBar; - private CustomScrollView fakeScrollView; - private View dummyView; - private boolean showError; - - private Menu menu; - private TableRow headerRow; - private int[] maxWidth; - - private boolean isFirstCreate; - private String errorMessage; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_entries, container, false); - initViewItems(rootView); - showError = false; - return rootView; - } - - private void initViewItems(View rootView){ - headerFrame = (FrameLayout) rootView.findViewById(R.id.headerFrame); - entriesScrollView = (ScrollView) rootView.findViewById(R.id.entriesScrollView); - fakeScrollView = (CustomScrollView) rootView.findViewById(R.id.fakeScroll); - progressBar = (ProgressBar) rootView.findViewById(R.id.loginProgressBar); - dummyView = rootView.findViewById(R.id.dummyView); - horizontalScrollView = (HorizontalScrollView) rootView.findViewById(R.id.horizontalScrollView); - entriesTable = new TableLayout(getActivity()); - - fakeScrollView.setOnTouchEventListener(new CustomScrollView.OnTouchEventListener() { - @Override - public boolean onTouchEvent(MotionEvent ev) { - ev.offsetLocation(0, headerFrame.getHeight()); - horizontalScrollView.dispatchTouchEvent(ev); - return true; - } - }); - - layoutParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.MATCH_PARENT); - } - - private void setLoading(boolean isLoading){ - if(menu != null) { - menu.findItem(R.id.action_next).setEnabled(!isLoading); - menu.findItem(R.id.action_previous).setEnabled(!isLoading); - } - progressBar.setVisibility(isLoading ? View.VISIBLE : View.INVISIBLE); - } - - @Override - public void onMatrixReturn(List<List<String>> rows) { - // Now we get Rows - if(rows!=null) { - int background; - for (int i = 0; i < rows.size(); i++) { - List<String> elements = rows.get(i); - TableRow newRow = new TableRow(getActivity()); - - if( i%2 == 0 ){ // Two backgrounds for lines for better visibility - background=R.drawable.entries_element_1; - } else { - background=R.drawable.entries_element_2; - } - - for (int j = 0; j < elements.size(); j++) { // elements.size can be the same as in header so maybe some one number or not - TextView textView = new TextView(getActivity()); - textView.setText(elements.get(j)); - textView.setLayoutParams(layoutParams); - textView.setPadding(ENTRIES_PADDING_LEFT, ENTRIES_PADDING_TOP, ENTRIES_PADDING_RIGHT, ENTRIES_PADDING_BOTTOM); - textView.setBackgroundResource(background); - textView.setId(j); - newRow.addView(textView); - } - newRow.setClickable(false); - entriesTable.addView(newRow); - syncWidthsFirstStage(); - } - } else { - entriesTable = null; - } - - } - - @Override - public void onListReturn(List<String> fieldList) { - // First we need header - headerRow = new TableRow(getActivity()); - headerRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)); - for (String aFieldList : fieldList) { - TextView textView = new TextView(getActivity()); - textView.setText(aFieldList); - textView.setTypeface(null, Typeface.BOLD); - textView.setLayoutParams(layoutParams); - textView.setBackgroundResource(R.drawable.background_header); - textView.setPadding(HEADER_PADDING_LEFT, HEADER_PADDING_TOP, HEADER_PADDING_RIGHT, HEADER_PADDING_BOTTOM); - headerRow.addView(textView); - } - } - - private void syncWidthsFirstStage() { // TODO: Merge with adding columns maybe? Loops -= 3 should be quicker - maxWidth = new int[headerRow.getChildCount()]; - for (int i = 0; i < headerRow.getChildCount(); i++) { - TextView textView = (TextView) headerRow.getChildAt(i); - textView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - maxWidth[i] = textView.getMeasuredWidth(); - } - - for (int i = 0; i < entriesTable.getChildCount(); i++) { - TableRow tableRow = (TableRow) entriesTable.getChildAt(i); - for (int j = 0; j < tableRow.getChildCount(); j++) { - TextView textView = (TextView) tableRow.getChildAt(j); - textView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - int width = textView.getMeasuredWidth(); - if (width > maxWidth[j]) - maxWidth[j] = width; - } - } - } - - private void syncWidthsSecondStage() { - for(int i=0;i<headerRow.getChildCount();i++){ - TableRow entriesRow = (TableRow) entriesTable.getChildAt(0); - - TextView tmpEntries = (TextView) entriesRow.getChildAt(i); - TextView tmpHeader = (TextView) headerRow.getChildAt(i); - - tmpEntries.setWidth(maxWidth[i]); - tmpHeader.setWidth(maxWidth[i]); - } - } - - private void fakeScroll(){ - entriesScrollView.measure(View.MeasureSpec.UNSPECIFIED,View.MeasureSpec.UNSPECIFIED); - int height = entriesScrollView.getMeasuredHeight(); - dummyView.setMinimumHeight(height); - - RelativeLayout.LayoutParams fakeScrollLayout = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - headerFrame.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - fakeScrollLayout.setMargins(0,headerFrame.getMeasuredHeight(),0,0); - - fakeScrollView.setLayoutParams(fakeScrollLayout); - } - -// @Override -// public void onResume() { -// super.onResume(); -// if(!isFirstCreate) { -// getActivity().finish(); -// } else { -// isFirstCreate = false; -// } -// } - - @Override - public void onPostExecute() { - if(!showError) { - if (headerFrame.getChildCount() == 0) // You can have only one child - headerFrame.addView(headerRow); - if (entriesTable != null) { - syncWidthsSecondStage(); - entriesScrollView.addView(entriesTable); - fakeScroll(); - } else { - TextView errorMessage = new TextView(getActivity()); - errorMessage.setText(R.string.error_no_entries); - errorMessage.setTypeface(null, Typeface.ITALIC); - errorMessage.setClickable(false); - entriesScrollView.addView(errorMessage); - } - setLoading(false); - } else { - setLoading(false); - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setMessage(errorMessage); - builder.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - getActivity().finish(); - } - }); - builder.setTitle(R.string.info); - builder.setIcon(R.drawable.ic_action_info); - builder.create(); - builder.show(); - } - } - - @Override - public void onStringReturn(String data) { - errorMessage = data; - showError = true; - } -} diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java deleted file mode 100644 index 0249a12..0000000 --- a/app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java +++ /dev/null @@ -1,89 +0,0 @@ -package info.nerull7.mysqlbrowser; - -import android.app.Fragment; -import android.app.FragmentTransaction; -import android.content.Context; -import android.os.Bundle; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; - -import info.nerull7.mysqlbrowser.db.DatabaseConnector; - -/** - * Created by nerull7 on 30.09.14. - */ -public class SQLFragment extends Fragment implements DatabaseConnector.OnPostExecuteListener { - private EditText sqlEditText; - private InputMethodManager inputMethodManager; - private SQLEntriesFragment sqlEntriesFragment; - private FragmentTransaction fragmentTransaction; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_sql, container, false); - sqlEditText = (EditText) rootView.findViewById(R.id.sqlQueryText); - setHasOptionsMenu(true); - return rootView; - } - - @Override - public void onStart() { - super.onStart(); - inputMethodManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); - inputMethodManager.showSoftInput(sqlEditText, InputMethodManager.SHOW_FORCED); - sqlEditText.requestFocus(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()){ - case R.id.action_execute: - actionExecute(); - break; - case R.id.action_cancel: - actionCancel(); - break; - } - return super.onOptionsItemSelected(item); - } - - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - inflater.inflate(R.menu.sql, menu); - super.onCreateOptionsMenu(menu, inflater); - } - - private void actionCancel(){ - inputMethodManager.hideSoftInputFromWindow(sqlEditText.getWindowToken(), 0); - getActivity().finish(); - } - - private void actionExecute(){ - String sqlQuery = String.valueOf(sqlEditText.getText()); - Log.d("SQLQUERY", sqlQuery); - - fragmentTransaction = getFragmentManager().beginTransaction(); - sqlEntriesFragment = new SQLEntriesFragment(); - fragmentTransaction.replace(R.id.container, sqlEntriesFragment); - fragmentTransaction.commit(); - - Static.databaseConnector.setStringReturnListener(sqlEntriesFragment); - Static.databaseConnector.setListReturnListener(sqlEntriesFragment); - Static.databaseConnector.setMatrixReturnListener(sqlEntriesFragment); - Static.databaseConnector.setOnPostExecuteListener(this); - Static.databaseConnector.executeSQL(getActivity().getIntent().getExtras().getString(Static.DATABASE_NAME_ARG), sqlQuery); - } - - @Override - public void onPostExecute() { - sqlEntriesFragment.onPostExecute(); - } -} diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/SettingsActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/SettingsActivity.java index d572c3f..3e84b0e 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/SettingsActivity.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/SettingsActivity.java @@ -1,5 +1,7 @@ package info.nerull7.mysqlbrowser; +import android.app.FragmentManager; +import android.app.FragmentTransaction; import android.os.Bundle; import android.preference.PreferenceActivity; diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java index dfff2bc..612337a 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java @@ -6,26 +6,32 @@ import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; import android.preference.Preference; import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; +import android.preference.PreferenceScreen; import android.util.Base64; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + /** * Created by nerull7 on 18.07.14. - * - * Fragment for Preferences/Settings */ -public class SettingsFragment extends PreferenceFragment implements Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener { +public class SettingsFragment extends PreferenceFragment implements NumberPickerDialog.OnNumberSetListener, Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener { public static final String ENTRIES_PAGE_LIMIT = "entries_limit"; - public static final String ENTRIES_PAGE_LIMIT_STRING = "entries_limit_string"; public static final String SAVE_SERVER_CREDENTIALS = "save_credentials_enabled"; public static final String URL_CREDENTIALS = "url"; public static final String LOGIN_CREDENTIALS = "login"; public static final String PASSWORD_CREDENTIALS = "password"; public static final int ENTRIES_PAGE_LIMIT_DEF = 20; + public static final int ENTRIES_MIN_PAGE = 20; + public static final int ENTRIES_MAX_PAGE = 100; private SharedPreferences preferences; - private EditTextPreference mEntriesLimit; + private Preference mEntriesLimit; private CheckBoxPreference saveCredentials; private EditTextPreference connectorUrlCredentials; private EditTextPreference loginCredentials; @@ -36,8 +42,7 @@ public class SettingsFragment extends PreferenceFragment implements Preference.O @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); - getPreferenceManager(); - preferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); + preferences = getPreferenceManager().getDefaultSharedPreferences(getActivity()); crypto = new Crypto(getActivity()); loadPrefs(); @@ -47,18 +52,17 @@ public class SettingsFragment extends PreferenceFragment implements Preference.O addPreferencesFromResource(R.xml.settings); // Getting fields - mEntriesLimit = (EditTextPreference) findPreference(ENTRIES_PAGE_LIMIT_STRING); + mEntriesLimit = findPreference(ENTRIES_PAGE_LIMIT); saveCredentials = (CheckBoxPreference) findPreference(SAVE_SERVER_CREDENTIALS); connectorUrlCredentials = (EditTextPreference) findPreference(URL_CREDENTIALS); loginCredentials = (EditTextPreference) findPreference(LOGIN_CREDENTIALS); passwordCredentials = (EditTextPreference) findPreference(PASSWORD_CREDENTIALS); // TODO: Some encryption // Settings fields - setEntriesPageLimit(); + setEntriesPageLimitSummary(); setPasswordCredentials(); // Settings Listener - mEntriesLimit.setOnPreferenceChangeListener(this); saveCredentials.setOnPreferenceClickListener(this); passwordCredentials.setOnPreferenceChangeListener(this); } @@ -73,6 +77,7 @@ public class SettingsFragment extends PreferenceFragment implements Preference.O } editor.putBoolean(SAVE_SERVER_CREDENTIALS, isEnabled); editor.apply(); + editor.commit(); if(!isEnabled) reloadLoginPrefsView(); @@ -82,7 +87,7 @@ public class SettingsFragment extends PreferenceFragment implements Preference.O saveCredentials.setChecked(preferences.getBoolean(SAVE_SERVER_CREDENTIALS, false)); connectorUrlCredentials.setText(preferences.getString(URL_CREDENTIALS, null)); loginCredentials.setText(preferences.getString(LOGIN_CREDENTIALS, null)); - passwordCredentials.setText(preferences.getString(PASSWORD_CREDENTIALS, null)); + passwordCredentials.setText(preferences.getString(PASSWORD_CREDENTIALS, null));; } private int getEntriesPageLimit(){ @@ -93,11 +98,6 @@ public class SettingsFragment extends PreferenceFragment implements Preference.O mEntriesLimit.setSummary(getString(R.string.entries_summary, getEntriesPageLimit())); } - private void setEntriesPageLimit(){ - mEntriesLimit.setText(String.valueOf(getEntriesPageLimit())); - setEntriesPageLimitSummary(); - } - private void setPasswordCredentials(){ String password; password = preferences.getString(PASSWORD_CREDENTIALS, null); @@ -118,6 +118,23 @@ public class SettingsFragment extends PreferenceFragment implements Preference.O } catch (Exception e) { e.printStackTrace(); } // TODO: Something useful } + @Override + public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { + if(preference == mEntriesLimit){ + new NumberPickerDialog(getActivity(), this, getEntriesPageLimit(), ENTRIES_MIN_PAGE, ENTRIES_MAX_PAGE, R.string.entries_limit).show(); + } + + return super.onPreferenceTreeClick(preferenceScreen, preference); + } + + @Override + public void onNumberSet(int number) { + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt(ENTRIES_PAGE_LIMIT, number); + editor.apply(); + setEntriesPageLimitSummary(); + } + @Override public boolean onPreferenceClick(Preference preference) { if(preference==saveCredentials){ @@ -133,16 +150,7 @@ public class SettingsFragment extends PreferenceFragment implements Preference.O public boolean onPreferenceChange(Preference preference, Object newValue) { if(preference == passwordCredentials){ savePassword((String) newValue); - } else if (preference == mEntriesLimit) { - saveEntriesLimit((String) newValue); } return false; } - - private void saveEntriesLimit(String newValue) { - SharedPreferences.Editor editor = preferences.edit(); - editor.putInt(ENTRIES_PAGE_LIMIT, Integer.parseInt(newValue)); - editor.apply(); - setEntriesPageLimit(); - } } diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java index abf0d41..d271055 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java @@ -1,13 +1,11 @@ package info.nerull7.mysqlbrowser; -import android.app.AlertDialog; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import info.nerull7.mysqlbrowser.db.DatabaseConnector; +import java.util.List; + +import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector; /** * Created by nerull7 on 14.07.14. @@ -16,45 +14,15 @@ public class Static { public static final String DATABASE_NAME_ARG = "DatabaseName"; public static final String TABLE_NAME_ARG = "TableName"; - public static final String FRAGMENT_TO_START = "FragmentStarter"; - public static final String FRAGMENT_DATABASE = "DatabaseFragment"; - public static final String FRAGMENT_TABLE = "TableFragment"; - - public static DatabaseConnector databaseConnector = null; + public static AsyncDatabaseConnector asyncDatabaseConnector = null; + static List<String> tables; + static List<String> databases; + static List<String> header; + static List<List<String>> entries; + static int pageCount; public static void startSettings(Context context){ Intent intent = new Intent(context, SettingsActivity.class); context.startActivity(intent); } - - public static boolean isNetworkConnected(Context context){ - ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); - if(networkInfo!=null && networkInfo.isConnected()){ - return true; - } else - return false; - } - - public static void showErrorAlert(String errorMessage, Context context){ - final AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setMessage(errorMessage); - builder.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - // Nothing to do here - // Cleaning inputs is stupid - } - }); - builder.setTitle(R.string.error); - builder.setIcon(R.drawable.ic_action_warning); - builder.create(); - builder.show(); - } - - public static void startSQL(Context context, String database) { - Intent intent = new Intent(context, SQLActivity.class); - intent.putExtra(Static.DATABASE_NAME_ARG, database); - context.startActivity(intent); - } } diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/TableActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/TableActivity.java new file mode 100644 index 0000000..e4c8256 --- /dev/null +++ b/app/src/main/java/info/nerull7/mysqlbrowser/TableActivity.java @@ -0,0 +1,46 @@ +package info.nerull7.mysqlbrowser; + +import android.app.Activity; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; + +public class TableActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_table); + setTitle(getIntent().getStringExtra(Static.DATABASE_NAME_ARG)); + + TableFragment tableFragment = new TableFragment(); + tableFragment.setArguments(getIntent().getExtras()); + if (savedInstanceState == null) { + getFragmentManager().beginTransaction() + .add(R.id.container, tableFragment) + .commit(); + } + } + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + + int id = item.getItemId(); + if (id == R.id.action_settings) { + Static.startSettings(this); + return true; + } + return super.onOptionsItemSelected(item); + } + +} diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java index 25dbedc..62af04b 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java @@ -4,9 +4,11 @@ import android.app.Fragment; import android.content.Intent; import android.graphics.Typeface; import android.os.Bundle; +import android.preference.PreferenceManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.ViewParent; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListAdapter; @@ -17,18 +19,20 @@ import android.widget.TextView; import java.util.List; -import info.nerull7.mysqlbrowser.db.DatabaseConnector; +import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector; /** * Created by nerull7 on 14.07.14. */ -public class TableFragment extends Fragment implements AdapterView.OnItemClickListener, DatabaseConnector.ListReturnListener, DatabaseConnector.OnPostExecuteListener { +public class TableFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.IntegerReturnListener, AsyncDatabaseConnector.MatrixReturnListener { private String databaseName; private ListView tablesList; private ListAdapter listAdapter; private RelativeLayout rootView; private ProgressBar progressBar; - private List<String> tables; + + private int listenerCalled; + private String chosenTable; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -38,36 +42,12 @@ public class TableFragment extends Fragment implements AdapterView.OnItemClickLi tablesList = (ListView) rootView.findViewById(R.id.tableList); this.rootView = (RelativeLayout) rootView; progressBar = (ProgressBar) rootView.findViewById(R.id.loginProgressBar); - Static.databaseConnector.setListReturnListener(this); - Static.databaseConnector.setOnPostExecuteListener(this); - Static.databaseConnector.getTables(); - return rootView; - } + listenerCalled = 0; +// Static.asyncDatabaseConnector.setListReturnListener(this); +// Static.asyncDatabaseConnector.getTables(); - @Override - public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { - if(Static.isNetworkConnected(getActivity())) { - String chosenTable = (String) listAdapter.getItem(position); - listAdapter.getItem(position); - Intent intent = new Intent(getActivity(), EntriesActivity.class); - intent.putExtra(Static.DATABASE_NAME_ARG,databaseName); - intent.putExtra(Static.TABLE_NAME_ARG,chosenTable); - startActivity(intent); - } else { - Static.showErrorAlert(getResources().getString(R.string.no_connection), getActivity()); - } - - } - - @Override - public void onListReturn(List<String> tables) { - this.tables = tables; - } - - @Override - public void onPostExecute() { - if(tables != null) { - listAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, tables); + if(Static.tables != null) { + listAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, Static.tables); tablesList.setAdapter(listAdapter); tablesList.setOnItemClickListener(this); } else { @@ -75,9 +55,73 @@ public class TableFragment extends Fragment implements AdapterView.OnItemClickLi errorMessage.setText(R.string.error_no_tables); errorMessage.setTypeface(null, Typeface.ITALIC); errorMessage.setClickable(false); - rootView.addView(errorMessage); - rootView.removeView(tablesList); + this.rootView.addView(errorMessage); + this.rootView.removeView(tablesList); } progressBar.setVisibility(View.INVISIBLE); + + return rootView; + } + + @Override + public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { + chosenTable = (String) listAdapter.getItem(position); + listAdapter.getItem(position); + + progressBar.setVisibility(View.VISIBLE); + Static.asyncDatabaseConnector.setIntegerReturnListener(this); + Static.asyncDatabaseConnector.setListReturnListener(this); + Static.asyncDatabaseConnector.setMatrixReturnListener(this); + + int entriesLimit = PreferenceManager.getDefaultSharedPreferences(getActivity()).getInt(SettingsFragment.ENTRIES_PAGE_LIMIT, SettingsFragment.ENTRIES_PAGE_LIMIT_DEF); + + Static.asyncDatabaseConnector.getRows(chosenTable, entriesLimit, 1); + Static.asyncDatabaseConnector.getFields(chosenTable); + Static.asyncDatabaseConnector.getEntriesCount(chosenTable); + } + + @Override + public void onListReturn(List<String> header) { +// if(tables != null) { +// listAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, tables); +// tablesList.setAdapter(listAdapter); +// tablesList.setOnItemClickListener(this); +// } else { +// TextView errorMessage = new TextView(getActivity()); +// errorMessage.setText(R.string.error_no_tables); +// errorMessage.setTypeface(null, Typeface.ITALIC); +// errorMessage.setClickable(false); +// rootView.addView(errorMessage); +// rootView.removeView(tablesList); +// } +// progressBar.setVisibility(View.INVISIBLE); + Static.header = header; + listenerCalled++; + if(listenerCalled==3) + startEntriesActivity(); + } + + @Override + public void onIntegerReturn(int result) { + Static.pageCount = result; + listenerCalled++; + if(listenerCalled==3) + startEntriesActivity(); + } + + @Override + public void onMatrixReturn(List<List<String>> data) { + Static.entries = data; + listenerCalled++; + if(listenerCalled==3) + startEntriesActivity(); + } + + + private void startEntriesActivity() { + Intent intent = new Intent(getActivity(), EntriesActivity.class); + intent.putExtra(Static.DATABASE_NAME_ARG,databaseName); + intent.putExtra(Static.TABLE_NAME_ARG,chosenTable); + startActivity(intent); } } diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java new file mode 100644 index 0000000..bab7b30 --- /dev/null +++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java @@ -0,0 +1,289 @@ +package info.nerull7.mysqlbrowser.db; + +import android.os.AsyncTask; +import android.util.Log; + +import org.json.JSONArray; +import org.json.JSONException; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by nerull7 on 07.07.14. + */ +public class AsyncDatabaseConnector { + public static final String ACTION_LOGIN = "login"; + public static final String ACTION_DATABASE_LIST = "dblist"; + public static final String ACTION_TABLE_LIST = "tablelist"; + public static final String ACTION_FIELD_LIST = "fieldlist"; + public static final String ACTION_ENTRIES_COUNT = "numrows"; + public static final String ACTION_DATA_MATRIX = "getrows"; + + private String login; + private String password; + private String url; + + private String database; + + private BooleanReturnListener booleanReturnListener; + private IntegerReturnListener integerReturnListener; + private StringReturnListener stringReturnListener; + private ListReturnListener listReturnListener; + private MatrixReturnListener matrixReturnListener; + + public static String errorMsg; + + public AsyncDatabaseConnector(String login, String password, String url){ + this.login = login; + this.password = password; + this.url = url; + + booleanReturnListener=null; + stringReturnListener=null; + listReturnListener=null; + matrixReturnListener=null; + } + + private String actionUrlBuilder(String action){ // TODO Better UrlBuilder this is shit only for use + String urlBuilder = url; + urlBuilder += "?u="+login; + urlBuilder += "&p="+password; + urlBuilder += "&a="+action; +// Log.d("URLBuilder", urlBuilder); + return urlBuilder; + } + + public void setDatabaseInUse(String database){ + this.database = database; + } + + private void getList(String urlQuery){ + Downloader downloader = new Downloader(new Downloader.OnFinishedListener() { + @Override + public void onFinished(String data, String error) { + List<String>list = null; + try { + list = parseListFromJSON(data); + } catch (JSONException e) { e.printStackTrace(); } + if(listReturnListener!=null) + listReturnListener.onListReturn(list); + } + }); + downloader.execute(urlQuery); + } + + private void getMatrix(String urlQuery){ + Downloader downloader = new Downloader(new Downloader.OnFinishedListener() { + @Override + public void onFinished(String data, String error) { + List<List<String>> list = null; + try { + list = parseMatrixFromJSON(data); + } catch (JSONException e) { e.printStackTrace(); } + if(matrixReturnListener!=null) + matrixReturnListener.onMatrixReturn(list); + } + }); + downloader.execute(urlQuery); + } + + private List<String> parseListFromJSON(String jsonListString) throws JSONException { + JSONArray jsonArray = new JSONArray(jsonListString); + List<String> databaseStringList = new ArrayList<String>(); + for(int i=0;i<jsonArray.length();i++){ + databaseStringList.add(jsonArray.getString(i)); + } + return databaseStringList; + } + + private List<List<String>> parseMatrixFromJSON(String jsonMatrixString) throws JSONException { + JSONArray jsonMatrix = new JSONArray(jsonMatrixString); + List<List<String>> matrix = new ArrayList<List<String>>(); + for(int i=0;i<jsonMatrix.length();i++){ + JSONArray jsonArray = jsonMatrix.getJSONArray(i); + List<String> list = new ArrayList<String>(); + for(int j=0;j<jsonArray.length();j++){ + list.add(jsonArray.getString(j)); + } + matrix.add(list); + } + return matrix; + } + + public boolean checkLogin(){ + Downloader downloader = new Downloader(new Downloader.OnFinishedListener() { + @Override + public void onFinished(String data, String error) { + List<String>list = null; + boolean listenerData; + if(data==null) { + listenerData = false; + errorMsg = error; + } + else if(booleanReturnListener!=null) + listenerData = (data.compareTo("OK")==0); + else { + errorMsg = data; + listenerData = false; + } + booleanReturnListener.onBooleanReturn(listenerData); + } + }); + downloader.execute(actionUrlBuilder(ACTION_LOGIN)); + return false; + } + + public void getDatabases(){ + getList(actionUrlBuilder(ACTION_DATABASE_LIST)); + } + + public void getTables(){ + getList(actionUrlBuilder(ACTION_TABLE_LIST)+"&d="+database); + } + + public void getFields(String table){ + getList(actionUrlBuilder(ACTION_FIELD_LIST)+"&d="+database+"&t="+table); + } + + public void getRows(String table, int count, int page){ + int limitStart = (page-1) * count; + getMatrix(actionUrlBuilder(ACTION_DATA_MATRIX)+"&d="+database+"&t="+table+"&s="+limitStart+"&l="+count); + } + + public void getEntriesCount(String table){ + String urlQuery = actionUrlBuilder(ACTION_ENTRIES_COUNT)+"&d="+database+"&t="+table; + Downloader downloader = new Downloader(new Downloader.OnFinishedListener() { + @Override + public void onFinished(String data, String error) { + if(integerReturnListener!=null) + integerReturnListener.onIntegerReturn(Integer.parseInt(data)); + } + }); + downloader.execute(urlQuery); + } + + public void setBooleanReturnListener(BooleanReturnListener booleanReturnListener){ + this.booleanReturnListener = booleanReturnListener; + } + + public void setStringReturnListener(StringReturnListener stringReturnListener) { + this.stringReturnListener = stringReturnListener; + } + + public void setIntegerReturnListener(IntegerReturnListener integerReturnListener){ + this.integerReturnListener = integerReturnListener; + } + + public void setListReturnListener(ListReturnListener listReturnListener) { + this.listReturnListener = listReturnListener; + } + + public void setMatrixReturnListener(MatrixReturnListener matrixReturnListener) { + this.matrixReturnListener = matrixReturnListener; + } + + public static interface BooleanReturnListener{ + public void onBooleanReturn(boolean result); + } + + public static interface IntegerReturnListener{ + public void onIntegerReturn(int result); + } + + public static interface StringReturnListener{ + public void onStringReturn(String data); + } + + public static interface ListReturnListener { + public void onListReturn(List<String> data); + } + + public static interface MatrixReturnListener{ + public void onMatrixReturn(List<List<String>> data); + } + + private static class Downloader extends AsyncTask<String, Void, String> { + private OnFinishedListener onFinishedListener; + private String errorString; + + public static final String CONNECTION_REQUEST_METHOD = "GET"; + public static final int CONNECTION_TIMEOUT = 15000; + public static final int READ_TIMEOUT = 10000; + + Downloader(OnFinishedListener onFinishedListener){ + this.onFinishedListener = onFinishedListener; + errorString = null; + } + + private String httpRequest(String urlRequest) throws IOException { + URL url = new URL(urlRequest); + InputStream inputStream = null; + String response; + + HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); // TODO Handling no connection + urlConnection.setReadTimeout(READ_TIMEOUT); + urlConnection.setConnectTimeout(CONNECTION_TIMEOUT); + urlConnection.setRequestMethod(CONNECTION_REQUEST_METHOD); + urlConnection.connect(); + + if(urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { + try { + inputStream = urlConnection.getInputStream(); + response = readStream(inputStream); + } finally { + if(inputStream!=null) + inputStream.close(); + urlConnection.disconnect(); + } + return response; + } + else { + errorString = "ERROR "+urlConnection.getResponseCode()+": "+urlConnection.getResponseMessage(); + return null; + } + } + + private String readStream(InputStream in) throws IOException { + String streamOutput = ""; + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(in)); + String line = ""; + while ((line = reader.readLine()) != null) { + streamOutput += line; + } + } finally { + if (reader != null) { + reader.close(); + } + } + return streamOutput; + } + + @Override + protected String doInBackground(String... strings) { + try { + return httpRequest(strings[0]); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(String data) { + onFinishedListener.onFinished(data, errorString); // Can't be null cos we demand listener in constructor + } + + private static interface OnFinishedListener { + void onFinished(String data, String error); + } + } +} diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/DatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/DatabaseConnector.java deleted file mode 100644 index c4f98ad..0000000 --- a/app/src/main/java/info/nerull7/mysqlbrowser/db/DatabaseConnector.java +++ /dev/null @@ -1,565 +0,0 @@ -package info.nerull7.mysqlbrowser.db; - -import android.content.res.Resources; -import android.os.AsyncTask; -import android.util.Log; - -import org.json.JSONArray; -import org.json.JSONException; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; -import java.net.HttpURLConnection; -import java.net.SocketException; -import java.net.SocketTimeoutException; -import java.net.URL; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.List; - -import info.nerull7.mysqlbrowser.R; - -/** - * Created by nerull7 on 07.07.14. - * Database connector using Async calls - */ -public class DatabaseConnector { - public static final String ACTION_LOGIN = "login"; - public static final String ACTION_DATABASE_LIST = "dblist"; - public static final String ACTION_TABLE_LIST = "tablelist"; - public static final String ACTION_FIELD_LIST = "fieldlist"; - public static final String ACTION_ENTRIES_COUNT = "numrows"; - public static final String ACTION_DATA_MATRIX = "getrows"; - public static final String ACTION_ADD_ELEMENT = "addelement"; - public static final String ACTION_UPDATE_ELEMENT = "updateelement"; - public static final String ACTION_REMOVE_ELEMENT = "removeelement"; - public static final String ACTION_SQL_QUERY = "query"; - - private String login; - private String password; - private String url; - - private String database; - - private final Resources resources; - - private BooleanReturnListener booleanReturnListener; - private IntegerReturnListener integerReturnListener; - private StringReturnListener stringReturnListener; - private ListReturnListener listReturnListener; - private MatrixReturnListener matrixReturnListener; - - public static String errorMsg; - private OnPostExecuteListener onPostExecuteListener; - - public DatabaseConnector(String login, String password, String url, Resources resources){ - this.login = login; - this.password = password; - this.url = url; - this.resources = resources; - - booleanReturnListener=null; - stringReturnListener=null; - listReturnListener=null; - matrixReturnListener=null; - } - - private Request requestBuilder(String action){ - Request request = new Request(url); - String urlData = "u="+login - + "&p="+password - + "&a="+action; - request.data = urlData; - - return request; - } - - private Request actionUrlBuilder(String action, String argument, String value){ - ArrayList<String> arguments = new ArrayList<String>(); - ArrayList<String> values = new ArrayList<String>(); - arguments.add(argument); - values.add(value); - return this.actionUrlBuilder(action, arguments, values); - } - - private Request actionUrlBuilder(String action, List<String> arguments, List<String> values){ // TODO Better UrlBuilder this is shit only for use - Request urlBuilder = requestBuilder(action); - for (int i = 0; i < arguments.size(); i++) { - try { - urlBuilder.data += "&" + arguments.get(i) + "=" + URLEncoder.encode(values.get(i), "UTF-8"); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - } -// Log.d("URLBuilder", urlBuilder); - return urlBuilder; - } - - public void setDatabaseInUse(String database){ - this.database = database; - } - - private void getList(Request urlQuery){ - Downloader downloader = new Downloader(new Downloader.OnFinishedListener() { - @Override - public void onFinished(String data, String error) { - List<String>list = null; - try { - list = parseListFromJSON(data); - } catch (JSONException e) { e.printStackTrace(); } - if(listReturnListener!=null) { - listReturnListener.onListReturn(list); - } - errorMsg = error; - } - }, onPostExecuteListener, resources); - downloader.execute(urlQuery); - } - - private void getMatrix(Request urlQuery){ - Downloader downloader = new Downloader(new Downloader.OnFinishedListener() { - @Override - public void onFinished(String data, String error) { - List<List<String>> list = null; - try { - list = parseMatrixFromJSON(data); - } catch (JSONException e) { e.printStackTrace(); } - if(matrixReturnListener!=null) - matrixReturnListener.onMatrixReturn(list); - errorMsg = error; - } - }, onPostExecuteListener, resources); - downloader.execute(urlQuery); - } - - private List<String> parseListFromJSON(String jsonListString) throws JSONException { - JSONArray jsonArray = new JSONArray(jsonListString); - List<String> databaseStringList = new ArrayList<String>(); - for(int i=0;i<jsonArray.length();i++){ - databaseStringList.add(jsonArray.getString(i)); - } - return databaseStringList; - } - - private List<List<String>> parseMatrixFromJSON(String jsonMatrixString) throws JSONException { - JSONArray jsonMatrix = new JSONArray(jsonMatrixString); - List<List<String>> matrix = new ArrayList<List<String>>(); - for(int i=0;i<jsonMatrix.length();i++){ - JSONArray jsonArray = jsonMatrix.getJSONArray(i); - List<String> list = new ArrayList<String>(); - for(int j=0;j<jsonArray.length();j++){ - list.add(jsonArray.getString(j)); - } - matrix.add(list); - } - return matrix; - } - - public boolean checkLogin(){ - Downloader downloader = new Downloader(new Downloader.OnFinishedListener() { - @Override - public void onFinished(String data, String error) { - boolean listenerData; - if(data == null) { - listenerData = false; - errorMsg = error; - } else if( data.compareTo("OK") == 0){ - listenerData = true; - } else { - errorMsg = data; - listenerData = false; - } - booleanReturnListener.onBooleanReturn(listenerData); - } - }, onPostExecuteListener, resources); - downloader.execute(requestBuilder(ACTION_LOGIN)); - return false; - } - - public void getDatabases(){ - getList(requestBuilder(ACTION_DATABASE_LIST)); - } - - public void getTables(){ - getList(actionUrlBuilder(ACTION_TABLE_LIST, "d", database)); - } - - public void getFields(String table){ - ArrayList<String> args = new ArrayList<String>(); - ArrayList<String> values = new ArrayList<String>(); - - args.add("d"); - values.add(database); - - args.add("t"); - values.add(table); - - getList(actionUrlBuilder(ACTION_FIELD_LIST, args, values)); - } - - public void getRows(String table, int count, int page){ - int limitStart = (page-1) * count; - ArrayList<String> args = new ArrayList<String>(); - ArrayList<String> values = new ArrayList<String>(); - - args.add("d"); - values.add(database); - - args.add("t"); - values.add(table); - - args.add("s"); - values.add(String.valueOf(limitStart)); - - args.add("l"); - values.add(String.valueOf(count)); - - getMatrix(actionUrlBuilder(ACTION_DATA_MATRIX, args, values)); - } - - public void getEntriesCount(String table){ - ArrayList<String> args = new ArrayList<String>(); - ArrayList<String> values = new ArrayList<String>(); - - args.add("d"); - values.add(database); - - args.add("t"); - values.add(table); - - Request urlQuery = actionUrlBuilder(ACTION_ENTRIES_COUNT, args, values); - Downloader downloader = new Downloader(new Downloader.OnFinishedListener() { - @Override - public void onFinished(String data, String error) { - if(integerReturnListener!=null) - integerReturnListener.onIntegerReturn(Integer.parseInt(data)); - errorMsg = error; - } - }, onPostExecuteListener, resources); - downloader.execute(urlQuery); - } - - public void addNewElement(String table, List<String> header, List<String> values) { - this.updateElement(table, header, null, values); - } - - public void updateElement(String table, List<String> header, List<String> oldValues, List<String> newValues){ - JSONArray headerJSON = new JSONArray(); - JSONArray newValuesJSON = new JSONArray(); - Request request; - - ArrayList<String> args = new ArrayList<String>(); - ArrayList<String> values = new ArrayList<String>(); - - args.add("d"); - values.add(database); - - args.add("t"); - values.add(table); - - for (String aHeader : header) { - headerJSON.put(aHeader); - } - - for (String newValue : newValues) { - newValuesJSON.put(newValue); - } - - args.add("h"); - values.add(headerJSON.toString()); - - args.add("v"); - values.add(newValuesJSON.toString()); - - if(oldValues!=null){ - JSONArray oldValuesJSON = new JSONArray(); - for(int i=0;i<newValues.size();i++){ - oldValuesJSON.put(oldValues.get(i)); - } - args.add("o"); - values.add(oldValuesJSON.toString()); - request = actionUrlBuilder(ACTION_UPDATE_ELEMENT, args, values); - } else - request = actionUrlBuilder(ACTION_ADD_ELEMENT, args, values); - - Downloader downloader = new Downloader(new Downloader.OnFinishedListener() { - @Override - public void onFinished(String data, String error) { - if(stringReturnListener!=null){ - stringReturnListener.onStringReturn(data); - } - errorMsg = error; - } - }, onPostExecuteListener, resources); - downloader.execute(request); - } - - public void removeElement(String table, List<String> header, List<String> values) { - JSONArray headerJSON = new JSONArray(); - JSONArray valuesJSON = new JSONArray(); - Request request; - - ArrayList<String> args = new ArrayList<String>(); - ArrayList<String> argValues = new ArrayList<String>(); - - args.add("d"); - argValues.add(database); - - args.add("t"); - argValues.add(table); - - for (String aHeader : header) { - headerJSON.put(aHeader); - } - - for (String value : values) { - valuesJSON.put(value); - } - - args.add("h"); - argValues.add(headerJSON.toString()); - - args.add("v"); - argValues.add(valuesJSON.toString()); - - request = actionUrlBuilder(ACTION_REMOVE_ELEMENT, args, argValues); - - Downloader downloader = new Downloader(new Downloader.OnFinishedListener() { - @Override - public void onFinished(String data, String error) { - if(stringReturnListener!=null){ - stringReturnListener.onStringReturn(data); - } - errorMsg = error; - } - }, onPostExecuteListener, resources); - downloader.execute(request); - } - - public void executeSQL(String database, String query){ - ArrayList<String> args = new ArrayList(); - ArrayList<String> values = new ArrayList(); - final Request request; - - if(database!=null){ - args.add("d"); - values.add(database); - } - args.add("q"); - values.add(query); - - request = actionUrlBuilder(ACTION_SQL_QUERY, args, values); - - Downloader downloader = new Downloader(new Downloader.OnFinishedListener() { - @Override - public void onFinished(String data, String error) { - String []response = data.split("\n"); - - if(response[0].equals("OK")) { - List<String> headerList = null; - try { - headerList = parseListFromJSON(response[1]); - } catch (JSONException e) { - e.printStackTrace(); - } - if (listReturnListener != null) { - listReturnListener.onListReturn(headerList); - } - - List<List<String>> dataMatrix = null; - try { - dataMatrix = parseMatrixFromJSON(response[2]); - } catch (JSONException e) { - e.printStackTrace(); - } - if (matrixReturnListener != null) - matrixReturnListener.onMatrixReturn(dataMatrix); - } else { - if(stringReturnListener!=null) - stringReturnListener.onStringReturn(data); - } - } - }, onPostExecuteListener, resources); - downloader.execute(request); - } - - public void setBooleanReturnListener(BooleanReturnListener booleanReturnListener){ - this.booleanReturnListener = booleanReturnListener; - } - - public void setStringReturnListener(StringReturnListener stringReturnListener) { - this.stringReturnListener = stringReturnListener; - } - - public void setIntegerReturnListener(IntegerReturnListener integerReturnListener){ - this.integerReturnListener = integerReturnListener; - } - - public void setListReturnListener(ListReturnListener listReturnListener) { - this.listReturnListener = listReturnListener; - } - - public void setMatrixReturnListener(MatrixReturnListener matrixReturnListener) { - this.matrixReturnListener = matrixReturnListener; - } - - public void setOnPostExecuteListener(OnPostExecuteListener onPostExecuteListener){ - this.onPostExecuteListener = onPostExecuteListener; - } - - public static interface BooleanReturnListener{ - public void onBooleanReturn(boolean result); - } - - public static interface IntegerReturnListener{ - public void onIntegerReturn(int result); - } - - public static interface StringReturnListener{ - public void onStringReturn(String data); - } - - public static interface ListReturnListener { - public void onListReturn(List<String> data); - } - - public static interface MatrixReturnListener{ - public void onMatrixReturn(List<List<String>> data); - } - - public static interface OnPostExecuteListener { - void onPostExecute(); - } - - private static class Downloader extends AsyncTask<Request, Void, String> { - private OnFinishedListener onFinishedListener; - private OnPostExecuteListener onPostExecuteListener; - private String errorString; - private Resources resources; - - public static final String CONNECTION_REQUEST_METHOD = "POST"; - public static final int CONNECTION_TIMEOUT = 15000; // ms - public static final int READ_TIMEOUT = 10000; // ms - - private Downloader(OnFinishedListener onFinishedListener, OnPostExecuteListener onPostExecuteListener, Resources resources){ - this.onFinishedListener = onFinishedListener; - this.onPostExecuteListener = onPostExecuteListener; - this.resources = resources; - errorString = null; - } - - private String httpRequest(Request urlRequest) throws IOException { - URL url = new URL(urlRequest.url); - InputStream inputStream = null; - String response; - -// Log.d("URL REQUEST", urlRequest); - - HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); // TODO Handling no connection - urlConnection.setReadTimeout(READ_TIMEOUT); - urlConnection.setConnectTimeout(CONNECTION_TIMEOUT); - urlConnection.setRequestMethod(CONNECTION_REQUEST_METHOD); - - OutputStream outputStream = urlConnection.getOutputStream(); - OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); - outputStreamWriter.write(urlRequest.data); - outputStreamWriter.flush(); - outputStreamWriter.close(); - outputStream.close(); - - try { - urlConnection.connect(); - - if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { - try { - inputStream = urlConnection.getInputStream(); - response = readStream(inputStream); - } finally { - if (inputStream != null) - inputStream.close(); - urlConnection.disconnect(); - } - return response; - } else { - errorString = "ERROR " + urlConnection.getResponseCode() + ": " + urlConnection.getResponseMessage(); - } - } catch (Exception e) { - parseException(e); - } - return null; - } - - private void parseException(Exception e){ - if(e instanceof SocketException){ - if(e.getMessage().contains("ECONNREFUSED")) { - errorString = resources.getString(R.string.error_connection_refused); - } else if(e.getMessage().contains("EHOSTUNREACH")) { - errorString = resources.getString(R.string.error_connection_unreachable); - } else { - errorString = "Exception: " + e.getClass(); - } - } else if (e instanceof SocketTimeoutException){ - errorString = resources.getString(R.string.error_connection_timeout); - } else { - errorString = "Exception: " + e.getClass(); - } - } - - private String readStream(InputStream in) throws IOException { - String streamOutput = ""; - BufferedReader reader = null; - try { - reader = new BufferedReader(new InputStreamReader(in)); - String line; - while ((line = reader.readLine()) != null) { - streamOutput += line + '\n'; - } - } finally { - if (reader != null) { - reader.close(); - } - } - return streamOutput.substring(0, streamOutput.length()-1); // Remove last \n - } - - @Override - protected String doInBackground(Request... requests) { - try { - String data = httpRequest(requests[0]); - onFinishedListener.onFinished(data, errorString); // Can't be null cos we demand listener in constructor - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } - - @Override - protected void onPostExecute(String data) { - if (onPostExecuteListener!=null) - onPostExecuteListener.onPostExecute(); - } - - public void setOnPostExecuteListener(OnPostExecuteListener onPostExecuteListener) { - this.onPostExecuteListener = onPostExecuteListener; - } - - private static interface OnFinishedListener { - void onFinished(String data, String error); - } - - } - - class Request{ - String url; - String data; - - Request(String url){ - this.url = url; - } - } -} diff --git a/app/src/main/res/drawable-hdpi/ic_action_add_circle.png b/app/src/main/res/drawable-hdpi/ic_action_add_circle.png deleted file mode 100644 index 5f68a01..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_action_add_circle.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_action_delete.png b/app/src/main/res/drawable-hdpi/ic_action_delete.png deleted file mode 100644 index 49e4513..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_action_delete.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_action_file_upload.png b/app/src/main/res/drawable-hdpi/ic_action_file_upload.png deleted file mode 100644 index 4910c3a..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_action_file_upload.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_action_info.png b/app/src/main/res/drawable-hdpi/ic_action_info.png deleted file mode 100644 index 75ecc18..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_action_info.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_action_save.png b/app/src/main/res/drawable-hdpi/ic_action_save.png deleted file mode 100644 index 107c11e..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_action_save.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_revert.png b/app/src/main/res/drawable-hdpi/ic_revert.png deleted file mode 100644 index f0f7b38..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_revert.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_add_circle.png b/app/src/main/res/drawable-mdpi/ic_action_add_circle.png deleted file mode 100644 index 649d671..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_action_add_circle.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_delete.png b/app/src/main/res/drawable-mdpi/ic_action_delete.png deleted file mode 100644 index 2706550..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_action_delete.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_file_upload.png b/app/src/main/res/drawable-mdpi/ic_action_file_upload.png deleted file mode 100644 index 8374b8d..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_action_file_upload.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_info.png b/app/src/main/res/drawable-mdpi/ic_action_info.png deleted file mode 100644 index 944ab3d..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_action_info.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_save.png b/app/src/main/res/drawable-mdpi/ic_action_save.png deleted file mode 100644 index 0235a4b..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_action_save.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_revert.png b/app/src/main/res/drawable-mdpi/ic_revert.png deleted file mode 100644 index a110afd..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_revert.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_action_add_circle.png b/app/src/main/res/drawable-xhdpi/ic_action_add_circle.png deleted file mode 100644 index adbda7f..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_action_add_circle.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_action_delete.png b/app/src/main/res/drawable-xhdpi/ic_action_delete.png deleted file mode 100644 index 1487306..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_action_delete.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_action_file_upload.png b/app/src/main/res/drawable-xhdpi/ic_action_file_upload.png deleted file mode 100644 index 702ea4e..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_action_file_upload.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_action_info.png b/app/src/main/res/drawable-xhdpi/ic_action_info.png deleted file mode 100644 index 6e10fde..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_action_info.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_action_save.png b/app/src/main/res/drawable-xhdpi/ic_action_save.png deleted file mode 100644 index 1692720..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_action_save.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_revert.png b/app/src/main/res/drawable-xhdpi/ic_revert.png deleted file mode 100644 index 67956bc..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_revert.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_add_circle.png b/app/src/main/res/drawable-xxhdpi/ic_action_add_circle.png deleted file mode 100644 index 73e6e67..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_action_add_circle.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_delete.png b/app/src/main/res/drawable-xxhdpi/ic_action_delete.png deleted file mode 100644 index 251f91d..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_action_delete.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_file_upload.png b/app/src/main/res/drawable-xxhdpi/ic_action_file_upload.png deleted file mode 100644 index 8e78556..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_action_file_upload.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_info.png b/app/src/main/res/drawable-xxhdpi/ic_action_info.png deleted file mode 100644 index 6835e8f..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_action_info.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_save.png b/app/src/main/res/drawable-xxhdpi/ic_action_save.png deleted file mode 100644 index 42bf596..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_action_save.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_revert.png b/app/src/main/res/drawable-xxhdpi/ic_revert.png deleted file mode 100644 index 8f0fbc0..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_revert.png and /dev/null differ diff --git a/app/src/main/res/drawable/entries_element_1.xml b/app/src/main/res/drawable/background_element.xml similarity index 69% rename from app/src/main/res/drawable/entries_element_1.xml rename to app/src/main/res/drawable/background_element.xml index 4149979..a682ad2 100644 --- a/app/src/main/res/drawable/entries_element_1.xml +++ b/app/src/main/res/drawable/background_element.xml @@ -1,6 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> -<shape xmlns:android="http://schemas.android.com/apk/res/android"> - <solid android:color="@color/entries_background_color_1"/> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <!--<solid android:color="#0fff"/>--> <stroke android:width="1dp" android:color="@color/border"/> + </shape> \ No newline at end of file diff --git a/app/src/main/res/drawable/entries_element_2.xml b/app/src/main/res/drawable/entries_element_2.xml deleted file mode 100644 index 0bd0f94..0000000 --- a/app/src/main/res/drawable/entries_element_2.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<shape xmlns:android="http://schemas.android.com/apk/res/android"> - <solid android:color="@color/entries_background_color_2"/> - <stroke android:width="1dp" android:color="@color/border"/> -</shape> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_element.xml b/app/src/main/res/layout/activity_database.xml similarity index 81% rename from app/src/main/res/layout/activity_element.xml rename to app/src/main/res/layout/activity_database.xml index 12fee7b..c4d324d 100644 --- a/app/src/main/res/layout/activity_element.xml +++ b/app/src/main/res/layout/activity_database.xml @@ -3,5 +3,5 @@ android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="info.nerull7.mysqlbrowser.ElementActivity" + tools:context="info.nerull7.mysqlbrowser.DatabaseActivity" tools:ignore="MergeRootFrame" /> diff --git a/app/src/main/res/layout/activity_sql.xml b/app/src/main/res/layout/activity_sql.xml deleted file mode 100644 index 43ab1db..0000000 --- a/app/src/main/res/layout/activity_sql.xml +++ /dev/null @@ -1,7 +0,0 @@ -<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/container" - android:layout_width="match_parent" - android:layout_height="match_parent" - tools:context="info.nerull7.mysqlbrowser.ListActivity" - tools:ignore="MergeRootFrame" /> diff --git a/app/src/main/res/layout/activity_list.xml b/app/src/main/res/layout/activity_table.xml similarity index 81% rename from app/src/main/res/layout/activity_list.xml rename to app/src/main/res/layout/activity_table.xml index 43ab1db..e80cef3 100644 --- a/app/src/main/res/layout/activity_list.xml +++ b/app/src/main/res/layout/activity_table.xml @@ -3,5 +3,5 @@ android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="info.nerull7.mysqlbrowser.ListActivity" + tools:context="info.nerull7.mysqlbrowser.TableActivity" tools:ignore="MergeRootFrame" /> diff --git a/app/src/main/res/layout/fragment_element.xml b/app/src/main/res/layout/fragment_element.xml deleted file mode 100644 index c57f312..0000000 --- a/app/src/main/res/layout/fragment_element.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" android:layout_height="match_parent"> - <ProgressBar - style="?android:attr/progressBarStyleHorizontal" - android:indeterminate="true" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:id="@+id/progressBar" - android:layout_centerHorizontal="true" - android:layout_alignParentTop="false" - android:layout_marginTop="-7dp" /> - - <ListView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:id="@+id/listView" - android:layout_below="@+id/progressBar" - android:layout_alignParentLeft="true" - android:layout_alignParentStart="true" - android:descendantFocusability="afterDescendants"/> - -</RelativeLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_entries.xml b/app/src/main/res/layout/fragment_entries.xml index 55f3cb8..a913904 100644 --- a/app/src/main/res/layout/fragment_entries.xml +++ b/app/src/main/res/layout/fragment_entries.xml @@ -4,9 +4,22 @@ android:layout_height="match_parent" tools:context="info.nerull7.mysqlbrowser.EntriesFragment"> - <HorizontalScrollView - android:layout_width="fill_parent" + <ScrollView + android:layout_width="wrap_content" android:layout_height="fill_parent" + android:layout_below="@+id/loginProgressBar" + android:layout_alignParentRight="true" + android:foregroundGravity="right" + android:id="@+id/fakeScroll"> + <View + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/dummyView"/> + </ScrollView> + + <HorizontalScrollView + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:id="@+id/horizontalScrollView" > <RelativeLayout @@ -20,18 +33,18 @@ android:id="@+id/headerFrame" ></FrameLayout> - <ScrollView + <info.nerull7.mysqlbrowser.CustomScrollView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/entriesScrollView" android:layout_below="@+id/headerFrame" android:scrollbars="none"> - <!--<TableLayout--> - <!--android:layout_width="wrap_content"--> - <!--android:layout_height="wrap_content"--> - <!--android:id="@+id/entriesTable">--> - <!--</TableLayout>--> - </ScrollView> + <TableLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/entriesTable"> + </TableLayout> + </info.nerull7.mysqlbrowser.CustomScrollView> </RelativeLayout> </HorizontalScrollView> @@ -45,17 +58,4 @@ android:layout_alignParentTop="false" android:layout_marginTop="-7dp" /> - <info.nerull7.mysqlbrowser.CustomScrollView - android:layout_width="wrap_content" - android:layout_height="fill_parent" - android:layout_alignParentRight="true" - android:foregroundGravity="right" - android:id="@+id/fakeScroll" - android:overScrollMode="never"> - <View - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:id="@+id/dummyView"/> - </info.nerull7.mysqlbrowser.CustomScrollView> - </RelativeLayout> diff --git a/app/src/main/res/layout/fragment_sql.xml b/app/src/main/res/layout/fragment_sql.xml deleted file mode 100644 index 1298338..0000000 --- a/app/src/main/res/layout/fragment_sql.xml +++ /dev/null @@ -1,24 +0,0 @@ -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="match_parent" - tools:context="info.nerull7.mysqlbrowser.DatabaseFragment"> - - - <EditText - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:inputType="textMultiLine" - android:ems="10" - android:id="@+id/sqlQueryText" - android:layout_alignParentTop="true" - android:layout_alignParentLeft="true" - android:layout_alignParentStart="true" - android:layout_alignParentBottom="true" - android:layout_alignParentRight="true" - android:layout_alignParentEnd="true" - android:gravity="left|top" - android:hint="@string/hint_sql_query" > - <requestFocus/> - </EditText> -</RelativeLayout> diff --git a/app/src/main/res/layout/list_item_element_simple.xml b/app/src/main/res/layout/list_item_element_simple.xml deleted file mode 100644 index 3e1dcc0..0000000 --- a/app/src/main/res/layout/list_item_element_simple.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" android:layout_height="match_parent"> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="New Text" - android:id="@+id/textFieldName" - android:layout_alignParentTop="true" - android:layout_alignParentLeft="true" - android:layout_alignParentStart="true" /> - - <EditText - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:id="@+id/editFieldValue" - android:layout_below="@+id/textFieldName" - android:layout_alignParentLeft="true" - android:layout_alignParentStart="true" /> - -</RelativeLayout> \ No newline at end of file diff --git a/app/src/main/res/menu/element.xml b/app/src/main/res/menu/element.xml deleted file mode 100644 index f3262ad..0000000 --- a/app/src/main/res/menu/element.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<menu xmlns:android="http://schemas.android.com/apk/res/android" > - - <item android:id="@+id/action_save" - android:title="@string/action_save" - android:showAsAction="always" - android:icon="@drawable/ic_action_save"/> - - <item android:id="@+id/action_remove" - android:title="@string/action_remove" - android:showAsAction="always" - android:icon="@drawable/ic_action_delete"/> - -</menu> diff --git a/app/src/main/res/menu/entries_activity_actions.xml b/app/src/main/res/menu/entries_activity_actions.xml index d4eca48..43bef46 100644 --- a/app/src/main/res/menu/entries_activity_actions.xml +++ b/app/src/main/res/menu/entries_activity_actions.xml @@ -1,12 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> - <item - android:id="@+id/action_add" - android:icon="@drawable/ic_action_add_circle" - android:title="@string/action_add" - android:showAsAction="ifRoom" /> - <item android:id="@+id/action_previous" android:icon="@drawable/ic_action_arrow_back" diff --git a/app/src/main/res/menu/logged.xml b/app/src/main/res/menu/logged.xml deleted file mode 100644 index 5d31f08..0000000 --- a/app/src/main/res/menu/logged.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<menu xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:id="@+id/action_settings" - android:title="@string/action_settings" - android:orderInCategory="100" - android:showAsAction="never" /> - <item android:id="@+id/action_sql" - android:title="@string/sql_query" - android:orderInCategory="200" - android:showAsAction="never" /> -</menu> \ No newline at end of file diff --git a/app/src/main/res/menu/sql.xml b/app/src/main/res/menu/sql.xml deleted file mode 100644 index 5bc3b39..0000000 --- a/app/src/main/res/menu/sql.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<menu xmlns:android="http://schemas.android.com/apk/res/android" > - - <item android:id="@+id/action_execute" - android:title="@string/action_execute" - android:showAsAction="always" - android:icon="@drawable/ic_action_file_upload"/> - - <item android:id="@+id/action_cancel" - android:title="@string/action_cancel" - android:showAsAction="always" - android:icon="@drawable/ic_action_delete"/> - -</menu> \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml deleted file mode 100644 index 44d7f9e..0000000 --- a/app/src/main/res/values-pl/strings.xml +++ /dev/null @@ -1,50 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="app_name">Przeglądarka Mysql</string> - - <string name="action_settings">Ustawienia</string> - <string name="action_add">Dodaj nowy</string> - <string name="action_remove">Usuń</string> - <string name="action_previous">Poprzedni</string> - <string name="action_next">Następny</string> - - <string name="title_fragment_database">Dostępne bazy</string> - - <string name="login">Zaloguj</string> - <string name="password">Hasło</string> - <string name="username">Użytkownik</string> - - <string name="yes">Tak</string> - <string name="no">Nie</string> - <string name="ok">OK</string> - <string name="cancel">Anuluj</string> - <string name="action_save">Zapisz</string> - <string name="set">Ustaw</string> - <string name="back">Cofnij</string> - - <string name="status">Info</string> - <string name="warning">Ostrzeżenie</string> - <string name="error">Błąd</string> - - <string name="login_error">Zły login/hasło</string> - - <string name="general_category">Ogólne</string> - <string name="entries_limit">Limit wpisów na stronę</string> - <string name="entries_summary">%s na stronę</string> <!-- <xliff:g id="count"></xliff:g> --> - - <string name="error_no_tables">Brak tabel w tej bazie</string> - <string name="error_no_entries">Brak wpisów w tej bazie</string> - <string name="error_no_databases">Brak dostępnych baz</string> - <string name="error_no_save">Twoje dane <b>NIE</b> zostaną zapisane! Czy chciałbyś kontynuować?</string> - <string name="error_remove">Ten wpis zostanie usunięty z bazy. Tej akcji <b>NIE MOŻNA</b> cofnąć! Czy chciałbyś kontynuować?</string> - <string name="error_connection_timeout">Przekroczono czas połączenia</string> - <string name="error_connection_reset">Połączenie zostało zrestartowane</string> - <string name="error_connection_unreachable">No route to host</string> - - <string name="pref_entries_per_page">Ustaw limit wpisów na stronę</string> - <string name="login_settings">Poświadczenia logowania</string> - <string name="save_credentials">Zapamiętaj poświadczenia</string> - <string name="connector_url">URL Wtyczki php</string> - <string name="no_connection">Brak połączenia internetowego</string> - -</resources> diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml new file mode 100644 index 0000000..65a325d --- /dev/null +++ b/app/src/main/res/values-v21/styles.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <style name="AppTheme" parent="android:Theme.Holo.Light"> + </style> +</resources> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index d9ecfa8..86784b1 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,8 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <resources> <color name="border">@android:color/tab_indicator_text</color> - <color name="header_background">#ffaa22</color> - <color name="header_login_background">@android:color/holo_blue_dark</color> - <color name="entries_background_color_1">@android:color/background_light</color> - <color name="entries_background_color_2">#ffcccccc</color> + <color name="header_background">@android:color/holo_orange_light</color> </resources> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e431c16..ff22c47 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,63 +1,34 @@ <?xml version="1.0" encoding="utf-8"?> <resources> + <string name="app_name">Mysql Browser</string> - <string name="action_settings">Settings</string> - <string name="action_add">Add new</string> - <string name="action_remove">Remove</string> - <string name="action_previous">Previous</string> - <string name="action_next">Next</string> - - <string name="title_activity_main">MainActivity</string> - <string name="title_activity_entries">EntriesActivity</string> - <string name="title_activity_setting">Settings</string> - <string name="title_activity_element">ElementActivity</string> - <string name="title_activity_list">ListActivity</string> - <string name="title_fragment_database">Available Databases</string> - <string name="login">Log in</string> <string name="password">Password</string> <string name="username">Username</string> <string name="hint_url">URL ex: https://example.com/c.php</string> - - <string name="yes">Yes</string> - <string name="no">No</string> - <string name="ok">OK</string> - <string name="cancel">Cancel</string> - <string name="action_save">Save</string> - <string name="set">Set</string> - <string name="back">Back</string> - - <string name="status">Status</string> - <string name="warning">Warning</string> - <string name="error">Error</string> - + <string name="title_activity_main">MainActivity</string> + <string name="title_activity_database">DatabaseActivity</string> + <string name="hello_world">Hello world!</string> <string name="login_error">Wrong login/password</string> - + <string name="ok">OK</string> + <string name="error">Error</string> + <string name="title_activity_table">TableActivity</string> + <string name="title_activity_entries">EntriesActivity</string> <string name="general_category">General</string> <string name="entries_limit">Entries per page limit</string> - <string name="entries_summary">%s entries per page</string> <!-- <xliff:g id="count"></xliff:g> --> - + <string name="entries_summary">%s entries per page</string><!--<xliff:g id="count"></xliff:g>--> + <string name="title_activity_setting">Settings</string> + <string name="cancel">Cancel</string> + <string name="set">Set</string> + <string name="pref_entries_per_page">Set number of entries per page</string> <string name="error_no_tables">No tables in this database</string> <string name="error_no_entries">No entries in this table</string> <string name="error_no_databases">No available databases</string> - <string name="error_no_save">Your data will <b>NOT</b> be saved! Would you like to continue?</string> - <string name="error_remove">This entry will be removed from database. This action <b>CAN NOT</b> be reversed! Would you like to continue?</string> - <string name="error_connection_timeout">Connection timeout</string> - <string name="error_connection_reset">Connection reset by peer</string> - <string name="error_connection_refused">Connection refused</string> - <string name="error_connection_unreachable">No route to host</string> - - <string name="pref_entries_per_page">Set number of entries per page</string> + <string name="action_previous">Previous</string> + <string name="action_next">Next</string> <string name="login_settings">Login credentials</string> <string name="save_credentials">Save credentials</string> <string name="connector_url">Connector URL</string> - <string name="no_connection">No Internet Connection</string> - <string name="sql_query">SQL Query</string> - <string name="title_activity_sql">SQL Query</string> - <string name="hint_sql_query">SQL Query</string> - <string name="action_cancel">Cancel</string> - <string name="action_execute">Execute</string> - <string name="info">Information</string> </resources> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 14ef368..292e457 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,20 +1,14 @@ -<?xml version="1.0" encoding="utf-8"?> <resources> - <!--Action Bar styles--> - <style name="DefaultActionBar" - parent="android:Widget.Holo.Light.ActionBar.Solid" > - <item name="android:background">@color/header_background</item> - <item name="android:icon">@drawable/ic_revert</item> + + <!-- Base application theme. --> + <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar"> + <!-- Customize your theme here. --> </style> - <style name="LoginActionBar" - parent="DefaultActionBar" > - <item name="android:background">@color/header_login_background</item> - <item name="android:icon">@drawable/ic_launcher</item> + <style name="TableTheme"> + <item name="android:layout_width">1dip</item> + <item name="android:layout_height">match_parent</item> + <item name="android:background">@android:color/white</item> </style> - <style name="SettingsActionBar" - parent="DefaultActionBar"> - <item name="android:icon">@drawable/ic_action_settings</item> - </style> </resources> diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 984a41c..c9512aa 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,19 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <!-- Base application theme. --> - <style name="AppTheme" + <!--Activites Themes--> + <style name="EntriesTheme" parent="android:Theme.Holo.Light"> - <item name="android:actionBarStyle">@style/DefaultActionBar</item> - </style> + <item name="android:actionBarStyle">@style/EntriesActionBar</item> + </style> - <style name="LoginTheme" - parent="AppTheme"> - <item name="android:actionBarStyle">@style/LoginActionBar</item> - </style> - - <style name="SettingsTheme" - parent="AppTheme"> - <item name="android:actionBarStyle">@style/SettingsActionBar</item> + <!--Action Bar styles--> + <style name="EntriesActionBar" + parent="android:Widget.Holo.Light.ActionBar.Solid" > + <item name="android:background">@color/header_background</item> </style> </resources> \ No newline at end of file diff --git a/app/src/main/res/xml/settings.xml b/app/src/main/res/xml/settings.xml index f310eb7..3cd5391 100644 --- a/app/src/main/res/xml/settings.xml +++ b/app/src/main/res/xml/settings.xml @@ -3,9 +3,8 @@ <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="@string/general_category"> - <EditTextPreference - android:key="entries_limit_string" - android:numeric="integer" + <Preference + android:key="entries_limit" android:title="@string/entries_limit" android:summary="@string/entries_summary" />