diff --git a/app/build.gradle b/app/build.gradle index 06e72d4..f0efe31 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,7 +6,7 @@ android { 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..792b2c8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,7 +3,7 @@ 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" > @@ -32,16 +32,11 @@ </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:label="@string/title_activity_element" > </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/DatabaseFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java index 428afa3..d02e088 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java @@ -17,25 +17,18 @@ 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); - } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ @@ -45,9 +38,8 @@ 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(); return rootView; } @@ -59,7 +51,7 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic 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); + Static.asyncDatabaseConnector.setDatabaseInUse(chosenDatabase); startActivity(intent); } else { Static.showErrorAlert(getResources().getString(R.string.no_connection), getActivity()); @@ -68,11 +60,6 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic @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); diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java index 32388b5..5f4c427 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java @@ -1,14 +1,13 @@ 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.EditText; import android.widget.TextView; -import java.util.ArrayList; import java.util.List; /** @@ -22,58 +21,33 @@ public class ElementArrayAdapter extends ArrayAdapter<String> { 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; + values = null; + } + + public ElementArrayAdapter(Context context, int resource, List<String> fields, List<String> values) { + this(context, resource, fields); + this.values = values; } @Override - public View getView(final int position, View convertView, ViewGroup parent) { + public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - final View rowView = layoutInflater.inflate(layout, parent, false); + 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); - } - } - }); + if(values != null){ + EditText textFieldName = (EditText) rowView.findViewById(R.id.editFieldValue); + textFieldName.setText(values.get(position)); + } + 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 index 236c769..898c6ba 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java @@ -2,7 +2,6 @@ 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; @@ -11,29 +10,24 @@ 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.EditText; import android.widget.ListView; import android.widget.ProgressBar; +import java.util.ArrayList; import java.util.List; -import info.nerull7.mysqlbrowser.db.DatabaseConnector; +import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector; /** * 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 class ElementFragment extends Fragment implements AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.StringReturnListener { 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; @@ -41,8 +35,6 @@ public class ElementFragment extends Fragment implements DatabaseConnector.ListR private ListView listView; private List<String> values; - private String message; - private int postExecute; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -51,83 +43,28 @@ public class ElementFragment extends Fragment implements DatabaseConnector.ListR 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); + Static.asyncDatabaseConnector.setListReturnListener(this); + Static.asyncDatabaseConnector.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); + if(item.getItemId() == R.id.action_save ){ + List<String> fields = listAdapter.getFieldArray(); + + Static.asyncDatabaseConnector.setStringReturnListener(this); + if(getArguments().getBoolean(EDIT_ELEMENT)) + Static.asyncDatabaseConnector.updateElement(tableName, fields, values, getNewValues()); + else + Static.asyncDatabaseConnector.addNewElement(tableName, fields, getNewValues()); + return true; + } else { + return super.onOptionsItemSelected(item); } - return true; } private void initArguments() { @@ -141,45 +78,34 @@ public class ElementFragment extends Fragment implements DatabaseConnector.ListR @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; + listView.setAdapter(listAdapter); +// databasesListView.setAdapter(listAdapter); +// databasesListView.setOnItemClickListener(this); + progressBar.setVisibility(View.INVISIBLE); + setHasOptionsMenu(true); + } + + private List<String> getNewValues(){ + List<String> newValues = new ArrayList<String>(); + + for(int i=0; i<listView.getChildCount();i++){ + EditText editText = (EditText) listView.getChildAt(i).findViewById(R.id.editFieldValue); + newValues.add(String.valueOf(editText.getText())); + } + return newValues; } @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.setMessage(data); builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { @@ -193,10 +119,8 @@ public class ElementFragment extends Fragment implements DatabaseConnector.ListR } });*/ builder.setTitle(R.string.status); - builder.setIcon(R.drawable.ic_action_warning); - builder.setCancelable(false); // There is no exit + builder.setIcon(R.drawable.ic_action_warning); //TODO Change Icon builder.create(); builder.show(); } - } diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java index 3c8a5b9..53f7e40 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java @@ -24,14 +24,14 @@ 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, View.OnClickListener { private static final int HEADER_PADDING_TOP = 15; private static final int HEADER_PADDING_BOTTOM = 15; private static final int HEADER_PADDING_LEFT = 15; @@ -57,13 +57,7 @@ public class EntriesFragment extends Fragment implements DatabaseConnector.Matri private CustomScrollView fakeScrollView; private View dummyView; - private int onPostExecuteListenerExecuted; - private Menu menu; - private TableRow headerRow; - private int[] maxWidth; - - private boolean isFirstCreate; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -72,11 +66,12 @@ 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); return rootView; } @@ -85,19 +80,18 @@ 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); + entriesTable = (TableLayout) rootView.findViewById(R.id.entriesTable); 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 @@ -108,14 +102,9 @@ public class EntriesFragment extends Fragment implements DatabaseConnector.Matri } }); - 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 @@ -152,12 +141,10 @@ public class EntriesFragment extends Fragment implements DatabaseConnector.Matri private void loadAnotherPage(){ changeMenus(page); - entriesScrollView.removeAllViews(); // clean table - entriesTable = new TableLayout(getActivity()); - onPostExecuteListenerExecuted--; + entriesTable.removeAllViews(); // clean table setLoading(true); - Static.databaseConnector.getRows(tableName, entriesLimit, page); // get new entries + Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page); // get new entries } private void addNewElement(){ @@ -216,17 +203,27 @@ public class EntriesFragment extends Fragment implements DatabaseConnector.Matri newRow.setClickable(true); newRow.setOnClickListener(this); entriesTable.addView(newRow); - syncWidthsFirstStage(); + + syncWidths(); + fakeScroll(); } } else { - entriesTable = null; + 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 + TableRow headerRow; headerRow = new TableRow(getActivity()); headerRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)); rowCount = fieldList.size(); @@ -239,8 +236,9 @@ public class EntriesFragment extends Fragment implements DatabaseConnector.Matri textView.setPadding(HEADER_PADDING_LEFT, HEADER_PADDING_TOP, HEADER_PADDING_RIGHT, HEADER_PADDING_BOTTOM); headerRow.addView(textView); } + headerFrame.addView(headerRow); - Static.databaseConnector.getRows(tableName, entriesLimit, page); + Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page); } @Override @@ -248,35 +246,30 @@ 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); - } - }); + + 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,6 +279,9 @@ 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(){ @@ -294,8 +290,7 @@ public class EntriesFragment extends Fragment implements DatabaseConnector.Matri 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); + fakeScrollLayout.setMargins(0,headerFrame.getHeight(),0,0); fakeScrollView.setLayoutParams(fakeScrollLayout); } @@ -316,35 +311,4 @@ public class EntriesFragment extends Fragment implements DatabaseConnector.Matri 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/ListActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java index 3eeb667..e2863fd 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java @@ -33,7 +33,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 +47,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/LoginFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java index 324c7e4..73e145d 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java @@ -12,23 +12,21 @@ import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; -import info.nerull7.mysqlbrowser.db.DatabaseConnector; +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 { private EditText urlTextbox; private EditText loginTextbox; private EditText passwordTextbox; private ProgressBar progressBar; private Button loginButton; - DatabaseConnector databaseConnector; - - private boolean result; + AsyncDatabaseConnector asyncDatabaseConnector; public LoginFragment(){} @@ -86,10 +84,9 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Dat url = urlTextbox.getText().toString(); if(Static.isNetworkConnected(getActivity())) { - databaseConnector = new DatabaseConnector(login, password, url, getActivity().getResources()); - databaseConnector.setBooleanReturnListener(this); - databaseConnector.setOnPostExecuteListener(this); - databaseConnector.checkLogin(); + asyncDatabaseConnector = new AsyncDatabaseConnector(login, password, url); + asyncDatabaseConnector.setBooleanReturnListener(this); + asyncDatabaseConnector.checkLogin(); } else { Static.showErrorAlert(getResources().getString(R.string.no_connection), getActivity()); loginButton.setEnabled(true); // Now we can click button again @@ -99,23 +96,18 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Dat @Override public void onBooleanReturn(boolean result) { - this.result = result; - } - - - @Override - public void onPostExecute() { if(result) { - Static.databaseConnector = databaseConnector; + Static.asyncDatabaseConnector = asyncDatabaseConnector; Intent intent = new Intent(getActivity(), ListActivity.class); intent.putExtra(Static.FRAGMENT_TO_START, Static.FRAGMENT_DATABASE); startActivity(intent); } else { - Static.showErrorAlert(DatabaseConnector.errorMsg, getActivity()); + Static.showErrorAlert(AsyncDatabaseConnector.errorMsg, getActivity()); } - loginButton.setEnabled(true); // Now we can click button again progressBar.setVisibility(View.INVISIBLE); } + + } 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/SettingsFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java index dfff2bc..b49d179 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java @@ -7,6 +7,7 @@ import android.preference.EditTextPreference; import android.preference.Preference; import android.preference.PreferenceFragment; import android.preference.PreferenceManager; +import android.preference.PreferenceScreen; import android.util.Base64; /** @@ -14,18 +15,19 @@ import android.util.Base64; * * 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; @@ -47,18 +49,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); } @@ -93,11 +94,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 +114,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 +146,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..6e59148 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java @@ -7,7 +7,7 @@ import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; -import info.nerull7.mysqlbrowser.db.DatabaseConnector; +import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector; /** * Created by nerull7 on 14.07.14. @@ -20,7 +20,7 @@ public class Static { public static final String FRAGMENT_DATABASE = "DatabaseFragment"; public static final String FRAGMENT_TABLE = "TableFragment"; - public static DatabaseConnector databaseConnector = null; + public static AsyncDatabaseConnector asyncDatabaseConnector = null; public static void startSettings(Context context){ Intent intent = new Intent(context, SettingsActivity.class); @@ -51,10 +51,4 @@ public class Static { 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/TableFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java index 25dbedc..8a63cd4 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java @@ -17,18 +17,17 @@ 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{ private String databaseName; private ListView tablesList; private ListAdapter listAdapter; private RelativeLayout rootView; private ProgressBar progressBar; - private List<String> tables; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -38,9 +37,8 @@ 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(); + Static.asyncDatabaseConnector.setListReturnListener(this); + Static.asyncDatabaseConnector.getTables(); return rootView; } @@ -61,11 +59,6 @@ public class TableFragment extends Fragment implements AdapterView.OnItemClickLi @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); tablesList.setAdapter(listAdapter); 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..d8a0261 --- /dev/null +++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java @@ -0,0 +1,330 @@ +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. + * Database connector using Async calls + */ +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"; + public static final String ACTION_ADD_ELEMENT = "addelement"; + public static final String ACTION_UPDATE_ELEMENT = "updateelement"; + + 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) { + 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); + } + }); + 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 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(); + String request; + + for (String aHeader : header) { + headerJSON.put(aHeader); + } + + for (String newValue : newValues) { + newValuesJSON.put(newValue); + } + + if(oldValues!=null){ + JSONArray oldValuesJSON = new JSONArray(); + for(int i=0;i<newValues.size();i++){ + oldValuesJSON.put(oldValues.get(i)); + } + request = actionUrlBuilder(ACTION_UPDATE_ELEMENT)+"&d="+database+"&t="+table+"&h="+headerJSON+"&v="+newValuesJSON+"&o="+oldValuesJSON; + } else + request = actionUrlBuilder(ACTION_ADD_ELEMENT)+"&d="+database+"&t="+table+"&h="+headerJSON+"&v="+newValuesJSON; + + Downloader downloader = new Downloader(new Downloader.OnFinishedListener() { + @Override + public void onFinished(String data, String error) { + if(stringReturnListener!=null){ + stringReturnListener.onStringReturn(data); + } + } + }); + 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 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; + + 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); + 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_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-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-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-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/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/fragment_element.xml b/app/src/main/res/layout/fragment_element.xml index c57f312..3e9e223 100644 --- a/app/src/main/res/layout/fragment_element.xml +++ b/app/src/main/res/layout/fragment_element.xml @@ -18,7 +18,6 @@ android:id="@+id/listView" android:layout_below="@+id/progressBar" android:layout_alignParentLeft="true" - android:layout_alignParentStart="true" - android:descendantFocusability="afterDescendants"/> + android:layout_alignParentStart="true" /> </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..3ed823a 100644 --- a/app/src/main/res/layout/fragment_entries.xml +++ b/app/src/main/res/layout/fragment_entries.xml @@ -26,11 +26,11 @@ 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>--> + <TableLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/entriesTable"> + </TableLayout> </ScrollView> </RelativeLayout> </HorizontalScrollView> 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/menu/element.xml b/app/src/main/res/menu/element.xml index f3262ad..8f2cd4b 100644 --- a/app/src/main/res/menu/element.xml +++ b/app/src/main/res/menu/element.xml @@ -7,9 +7,4 @@ 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/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/strings.xml b/app/src/main/res/values/strings.xml index e431c16..db2bbf2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,63 +1,43 @@ <?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="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_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="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> + <string name="action_add">Add new</string> + <string name="title_activity_element">ElementActivity</string> + <string name="action_save">Save</string> + <string name="title_fragment_database">Available Databases</string> + <string name="title_activity_list">ListActivity</string> + <string name="error_no_save">Your data will NOT be saved! Would you like to continue?</string> + <string name="yes">Yes</string> + <string name="warning">Warning</string> + <string name="status">Status</string> + <string name="back">Back</string> </resources> 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" />