From 0304cc25908752f952bdebf5ac596ea0e90b8497 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Thu, 31 Jul 2014 15:23:52 +0200
Subject: [PATCH 01/59] Try to make UI not stuck - DO NOT MERGE

It doesn't work SHIT
---
 .../mysqlbrowser/DatabaseFragment.java        |  53 ++++---
 .../nerull7/mysqlbrowser/EntriesFragment.java | 149 ++++++++++++------
 .../nerull7/mysqlbrowser/LoginFragment.java   |  31 +++-
 .../info/nerull7/mysqlbrowser/Static.java     |   7 +
 .../nerull7/mysqlbrowser/TableFragment.java   |  97 +++++++++---
 5 files changed, 245 insertions(+), 92 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
index d1648d0..428cc0d 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
@@ -30,6 +30,8 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic
     private RelativeLayout rootView;
     private ProgressBar progressBar;
 
+    private String chosenDatabase;
+
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
         //Inflate the layout for this fragment
@@ -38,35 +40,48 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic
         this.rootView = (RelativeLayout) rootView;
         progressBar = (ProgressBar) rootView.findViewById(R.id.loginProgressBar);
 
-        Static.asyncDatabaseConnector.setListReturnListener(this);
-        Static.asyncDatabaseConnector.getDatabases();
+//        Static.asyncDatabaseConnector.setListReturnListener(this);
+//        Static.asyncDatabaseConnector.getDatabases();
+
+        listAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, Static.databases);
+        databasesListView.setAdapter(listAdapter);
+        databasesListView.setOnItemClickListener(this);
+        progressBar.setVisibility(View.INVISIBLE);
+
         return rootView;
     }
 
     @Override
     public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
-        String chosenDatabase =  (String) listAdapter.getItem(position);
+        chosenDatabase =  (String) listAdapter.getItem(position);
         listAdapter.getItem(position);
-        Intent intent = new Intent(getActivity(), TableActivity.class);
-        intent.putExtra(Static.DATABASE_NAME_ARG,chosenDatabase);
+
+        progressBar.setVisibility(View.VISIBLE);
         Static.asyncDatabaseConnector.setDatabaseInUse(chosenDatabase);
-        startActivity(intent);
+        Static.asyncDatabaseConnector.setListReturnListener(this);
+        Static.asyncDatabaseConnector.getTables();
     }
 
     @Override
-    public void onListReturn(List<String> databases) {
-        if(databases!= null) {
-            listAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, databases);
-            databasesListView.setAdapter(listAdapter);
-            databasesListView.setOnItemClickListener(this);
-        } else {
-            TextView errorMessage = new TextView(getActivity());
-            errorMessage.setText(R.string.error_no_databases);
-            errorMessage.setTypeface(null, Typeface.ITALIC);
-            errorMessage.setClickable(false);
-            rootView.addView(errorMessage);
-            rootView.removeView(databasesListView);
+    public void onListReturn(List<String> tables) {
+//        if(databases!= null) {
+//            listAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, databases);
+//            databasesListView.setAdapter(listAdapter);
+//            databasesListView.setOnItemClickListener(this);
+//        } else {
+//            TextView errorMessage = new TextView(getActivity());
+//            errorMessage.setText(R.string.error_no_databases);
+//            errorMessage.setTypeface(null, Typeface.ITALIC);
+//            errorMessage.setClickable(false);
+//            rootView.addView(errorMessage);
+//            rootView.removeView(databasesListView);
+//        }
+//        progressBar.setVisibility(View.INVISIBLE);
+        if(tables!=null) {
+            Static.tables = tables;
         }
-        progressBar.setVisibility(View.INVISIBLE);
+        Intent intent = new Intent(getActivity(), TableActivity.class);
+        intent.putExtra(Static.DATABASE_NAME_ARG, chosenDatabase);
+        startActivity(intent);
     }
 }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index 6d10075..ddc5daa 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -62,11 +62,62 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         initArguments();
         initViewItems(rootView);
 
-        Static.asyncDatabaseConnector.setIntegerReturnListener(this);
-        Static.asyncDatabaseConnector.setListReturnListener(this);
-        Static.asyncDatabaseConnector.setMatrixReturnListener(this);
-        Static.asyncDatabaseConnector.getFields(tableName);
-        Static.asyncDatabaseConnector.getEntriesCount(tableName);
+//        Static.asyncDatabaseConnector.setIntegerReturnListener(this);
+//        Static.asyncDatabaseConnector.setListReturnListener(this);
+//        Static.asyncDatabaseConnector.setMatrixReturnListener(this);
+//        Static.asyncDatabaseConnector.getFields(tableName);
+//        Static.asyncDatabaseConnector.getEntriesCount(tableName);
+
+        pageCount = Static.pageCount/entriesLimit;
+        if( Static.pageCount%entriesLimit > 0)
+            pageCount++;
+
+        if(pageCount>1)
+            setHasOptionsMenu(true);
+
+        // First we need header
+        headerRow = new TableRow(getActivity());
+        headerRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
+        for(int i =0;i<Static.header.size();i++){
+            TextView textView = new TextView(getActivity());
+            textView.setText(Static.header.get(i));
+            textView.setTypeface(null, Typeface.BOLD);
+            textView.setLayoutParams(layoutParams);
+            textView.setBackgroundResource(R.drawable.background_header);
+            textView.setPadding(HEADER_PADDING_LEFT, HEADER_PADDING_TOP, HEADER_PADDING_RIGHT, HEADER_PADDING_BOTTOM);
+            headerRow.addView(textView);
+        }
+        headerFrame.addView(headerRow);
+
+        // now data
+        if(Static.entries!=null) {
+            for (int i = 0; i < Static.entries.size(); i++) {
+                List<String> elements = Static.entries.get(i);
+                TableRow newRow = new TableRow(getActivity());
+                for (int j = 0; j < elements.size(); j++) { // elements.size can be the same as in header so maybe some one number or not
+                    TextView textView = new TextView(getActivity());
+                    textView.setText(elements.get(j));
+                    textView.setLayoutParams(layoutParams);
+                    textView.setPadding(ENTRIES_PADDING_LEFT, ENTRIES_PADDING_TOP, ENTRIES_PADDING_RIGHT, ENTRIES_PADDING_BOTTOM);
+                    textView.setBackgroundResource(R.drawable.background_element);
+                    newRow.addView(textView);
+                }
+                entriesTable.addView(newRow);
+
+                syncWidths();
+                fakeScroll();
+            }
+        } else {
+            TextView errorMessage = new TextView(getActivity());
+            errorMessage.setText(R.string.error_no_entries);
+            errorMessage.setTypeface(null, Typeface.ITALIC);
+            errorMessage.setClickable(false);
+            entriesScrollView.removeView(entriesTable);
+            headerFrame.setVisibility(View.VISIBLE);
+            entriesScrollView.addView(errorMessage);
+        }
+
+        setLoading(false);
 
         return rootView;
     }
@@ -153,54 +204,54 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
 
     @Override
     public void onMatrixReturn(List<List<String>> rows) {
-        // Now we get Rows
-        if(rows!=null) {
-            for (int i = 0; i < rows.size(); i++) {
-                List<String> elements = rows.get(i);
-                TableRow newRow = new TableRow(getActivity());
-                for (int j = 0; j < elements.size(); j++) { // elements.size can be the same as in header so maybe some one number or not
-                    TextView textView = new TextView(getActivity());
-                    textView.setText(elements.get(j));
-                    textView.setLayoutParams(layoutParams);
-                    textView.setPadding(ENTRIES_PADDING_LEFT, ENTRIES_PADDING_TOP, ENTRIES_PADDING_RIGHT, ENTRIES_PADDING_BOTTOM);
-                    textView.setBackgroundResource(R.drawable.background_element);
-                    newRow.addView(textView);
-                }
-                entriesTable.addView(newRow);
-
-                syncWidths();
-                fakeScroll();
-            }
-        } else {
-            TextView errorMessage = new TextView(getActivity());
-            errorMessage.setText(R.string.error_no_entries);
-            errorMessage.setTypeface(null, Typeface.ITALIC);
-            errorMessage.setClickable(false);
-            entriesScrollView.removeView(entriesTable);
-            headerFrame.setVisibility(View.VISIBLE);
-            entriesScrollView.addView(errorMessage);
-        }
-
-        setLoading(false);
+//        // Now we get Rows
+//        if(rows!=null) {
+//            for (int i = 0; i < rows.size(); i++) {
+//                List<String> elements = rows.get(i);
+//                TableRow newRow = new TableRow(getActivity());
+//                for (int j = 0; j < elements.size(); j++) { // elements.size can be the same as in header so maybe some one number or not
+//                    TextView textView = new TextView(getActivity());
+//                    textView.setText(elements.get(j));
+//                    textView.setLayoutParams(layoutParams);
+//                    textView.setPadding(ENTRIES_PADDING_LEFT, ENTRIES_PADDING_TOP, ENTRIES_PADDING_RIGHT, ENTRIES_PADDING_BOTTOM);
+//                    textView.setBackgroundResource(R.drawable.background_element);
+//                    newRow.addView(textView);
+//                }
+//                entriesTable.addView(newRow);
+//
+//                syncWidths();
+//                fakeScroll();
+//            }
+//        } else {
+//            TextView errorMessage = new TextView(getActivity());
+//            errorMessage.setText(R.string.error_no_entries);
+//            errorMessage.setTypeface(null, Typeface.ITALIC);
+//            errorMessage.setClickable(false);
+//            entriesScrollView.removeView(entriesTable);
+//            headerFrame.setVisibility(View.VISIBLE);
+//            entriesScrollView.addView(errorMessage);
+//        }
+//
+//        setLoading(false);
     }
 
     @Override
     public void onListReturn(List<String> fieldList) {
-        // First we need header
-        headerRow = new TableRow(getActivity());
-        headerRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
-        for(int i =0;i<fieldList.size();i++){
-            TextView textView = new TextView(getActivity());
-            textView.setText(fieldList.get(i));
-            textView.setTypeface(null, Typeface.BOLD);
-            textView.setLayoutParams(layoutParams);
-            textView.setBackgroundResource(R.drawable.background_header);
-            textView.setPadding(HEADER_PADDING_LEFT, HEADER_PADDING_TOP, HEADER_PADDING_RIGHT, HEADER_PADDING_BOTTOM);
-            headerRow.addView(textView);
-        }
-        headerFrame.addView(headerRow);
-
-        Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page);
+//        // First we need header
+//        headerRow = new TableRow(getActivity());
+//        headerRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
+//        for(int i =0;i<fieldList.size();i++){
+//            TextView textView = new TextView(getActivity());
+//            textView.setText(fieldList.get(i));
+//            textView.setTypeface(null, Typeface.BOLD);
+//            textView.setLayoutParams(layoutParams);
+//            textView.setBackgroundResource(R.drawable.background_header);
+//            textView.setPadding(HEADER_PADDING_LEFT, HEADER_PADDING_TOP, HEADER_PADDING_RIGHT, HEADER_PADDING_BOTTOM);
+//            headerRow.addView(textView);
+//        }
+//        headerFrame.addView(headerRow);
+//
+//        Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page);
     }
 
     @Override
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
index c17bddf..5946d31 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
@@ -6,6 +6,7 @@ import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.graphics.Typeface;
 import android.os.Bundle;
 import android.preference.Preference;
 import android.preference.PreferenceManager;
@@ -13,12 +14,15 @@ import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ProgressBar;
+import android.widget.TextView;
 
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
+import java.util.List;
 
 import javax.crypto.BadPaddingException;
 import javax.crypto.IllegalBlockSizeException;
@@ -29,7 +33,7 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
 /**
  * Created by nerull7 on 07.07.14.
  */
-public class LoginFragment extends Fragment implements View.OnClickListener, AsyncDatabaseConnector.BooleanReturnListener {
+public class LoginFragment extends Fragment implements View.OnClickListener, AsyncDatabaseConnector.BooleanReturnListener, AsyncDatabaseConnector.ListReturnListener {
     private EditText urlTextbox;
     private EditText loginTextbox;
     private EditText passwordTextbox;
@@ -94,8 +98,8 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
     public void onBooleanReturn(boolean result) {
         if(result) {
             Static.asyncDatabaseConnector = asyncDatabaseConnector;
-            Intent intent = new Intent(getActivity(), DatabaseActivity.class);
-            startActivity(intent);
+            Static.asyncDatabaseConnector.setListReturnListener(this);
+            Static.asyncDatabaseConnector.getDatabases();
         }
         else {
             final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
@@ -115,4 +119,25 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
         loginButton.setEnabled(true); // Now we can click button again
         progressBar.setVisibility(View.INVISIBLE);
     }
+
+    @Override
+    public void onListReturn(List<String> databases) {
+        if(databases!= null) {
+            Static.databases = databases;
+
+            Intent intent = new Intent(getActivity(), DatabaseActivity.class);
+            startActivity(intent);
+        }
+//            listAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, databases);
+//            databasesListView.setAdapter(listAdapter);
+//            databasesListView.setOnItemClickListener(this);
+//        } else {
+//            TextView errorMessage = new TextView(getActivity());
+//            errorMessage.setText(R.string.error_no_databases);
+//            errorMessage.setTypeface(null, Typeface.ITALIC);
+//            errorMessage.setClickable(false);
+//            rootView.addView(errorMessage);
+//            rootView.removeView(databasesListView);
+//        }
+    }
 }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
index 055f1f7..d271055 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
@@ -3,6 +3,8 @@ package info.nerull7.mysqlbrowser;
 import android.content.Context;
 import android.content.Intent;
 
+import java.util.List;
+
 import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
 
 /**
@@ -13,6 +15,11 @@ public class Static {
     public static final String TABLE_NAME_ARG = "TableName";
 
     public static AsyncDatabaseConnector asyncDatabaseConnector = null;
+    static List<String> tables;
+    static List<String> databases;
+    static List<String> header;
+    static List<List<String>> entries;
+    static int pageCount;
 
     public static void startSettings(Context context){
         Intent intent = new Intent(context, SettingsActivity.class);
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
index 812f260..62af04b 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
@@ -4,6 +4,7 @@ import android.app.Fragment;
 import android.content.Intent;
 import android.graphics.Typeface;
 import android.os.Bundle;
+import android.preference.PreferenceManager;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -23,13 +24,16 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
 /**
  * Created by nerull7 on 14.07.14.
  */
-public class TableFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener{
+public class TableFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.IntegerReturnListener, AsyncDatabaseConnector.MatrixReturnListener {
     private String databaseName;
     private ListView tablesList;
     private ListAdapter listAdapter;
     private RelativeLayout rootView;
     private ProgressBar progressBar;
 
+    private int listenerCalled;
+    private String chosenTable;
+
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                              Bundle savedInstanceState) {
@@ -38,25 +42,12 @@ public class TableFragment extends Fragment implements AdapterView.OnItemClickLi
         tablesList = (ListView) rootView.findViewById(R.id.tableList);
         this.rootView = (RelativeLayout) rootView;
         progressBar = (ProgressBar) rootView.findViewById(R.id.loginProgressBar);
-        Static.asyncDatabaseConnector.setListReturnListener(this);
-        Static.asyncDatabaseConnector.getTables();
-        return rootView;
-    }
+        listenerCalled = 0;
+//        Static.asyncDatabaseConnector.setListReturnListener(this);
+//        Static.asyncDatabaseConnector.getTables();
 
-    @Override
-    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
-        String chosenTable =  (String) listAdapter.getItem(position);
-        listAdapter.getItem(position);
-        Intent intent = new Intent(getActivity(), EntriesActivity.class);
-        intent.putExtra(Static.DATABASE_NAME_ARG,databaseName);
-        intent.putExtra(Static.TABLE_NAME_ARG,chosenTable);
-        startActivity(intent);
-    }
-
-    @Override
-    public void onListReturn(List<String> tables) {
-        if(tables != null) {
-            listAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, tables);
+        if(Static.tables != null) {
+            listAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, Static.tables);
             tablesList.setAdapter(listAdapter);
             tablesList.setOnItemClickListener(this);
         } else {
@@ -64,9 +55,73 @@ public class TableFragment extends Fragment implements AdapterView.OnItemClickLi
             errorMessage.setText(R.string.error_no_tables);
             errorMessage.setTypeface(null, Typeface.ITALIC);
             errorMessage.setClickable(false);
-            rootView.addView(errorMessage);
-            rootView.removeView(tablesList);
+            this.rootView.addView(errorMessage);
+            this.rootView.removeView(tablesList);
         }
         progressBar.setVisibility(View.INVISIBLE);
+
+        return rootView;
+    }
+
+    @Override
+    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
+        chosenTable =  (String) listAdapter.getItem(position);
+        listAdapter.getItem(position);
+
+        progressBar.setVisibility(View.VISIBLE);
+        Static.asyncDatabaseConnector.setIntegerReturnListener(this);
+        Static.asyncDatabaseConnector.setListReturnListener(this);
+        Static.asyncDatabaseConnector.setMatrixReturnListener(this);
+
+        int entriesLimit = PreferenceManager.getDefaultSharedPreferences(getActivity()).getInt(SettingsFragment.ENTRIES_PAGE_LIMIT, SettingsFragment.ENTRIES_PAGE_LIMIT_DEF);
+
+        Static.asyncDatabaseConnector.getRows(chosenTable, entriesLimit, 1);
+        Static.asyncDatabaseConnector.getFields(chosenTable);
+        Static.asyncDatabaseConnector.getEntriesCount(chosenTable);
+    }
+
+    @Override
+    public void onListReturn(List<String> header) {
+//        if(tables != null) {
+//            listAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, tables);
+//            tablesList.setAdapter(listAdapter);
+//            tablesList.setOnItemClickListener(this);
+//        } else {
+//            TextView errorMessage = new TextView(getActivity());
+//            errorMessage.setText(R.string.error_no_tables);
+//            errorMessage.setTypeface(null, Typeface.ITALIC);
+//            errorMessage.setClickable(false);
+//            rootView.addView(errorMessage);
+//            rootView.removeView(tablesList);
+//        }
+//        progressBar.setVisibility(View.INVISIBLE);
+        Static.header = header;
+        listenerCalled++;
+        if(listenerCalled==3)
+            startEntriesActivity();
+    }
+
+    @Override
+    public void onIntegerReturn(int result) {
+        Static.pageCount = result;
+        listenerCalled++;
+        if(listenerCalled==3)
+            startEntriesActivity();
+    }
+
+    @Override
+    public void onMatrixReturn(List<List<String>> data) {
+        Static.entries = data;
+        listenerCalled++;
+        if(listenerCalled==3)
+            startEntriesActivity();
+    }
+
+
+    private void startEntriesActivity() {
+        Intent intent = new Intent(getActivity(), EntriesActivity.class);
+        intent.putExtra(Static.DATABASE_NAME_ARG,databaseName);
+        intent.putExtra(Static.TABLE_NAME_ARG,chosenTable);
+        startActivity(intent);
     }
 }

From bcf550f6679c50823c4db095b5a3e6c052243c61 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Fri, 1 Aug 2014 09:12:38 +0200
Subject: [PATCH 02/59] Styles fix

 Removed 'L' style
 Changed Theme to Holo.Light without DarkActionBar
---
 app/src/main/res/values-v21/styles.xml | 5 -----
 app/src/main/res/values/styles.xml     | 2 +-
 2 files changed, 1 insertion(+), 6 deletions(-)
 delete mode 100644 app/src/main/res/values-v21/styles.xml

diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml
deleted file mode 100644
index 65a325d..0000000
--- a/app/src/main/res/values-v21/styles.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <style name="AppTheme" parent="android:Theme.Holo.Light">
-    </style>
-</resources>
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 292e457..29f1aa9 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -1,7 +1,7 @@
 <resources>
 
     <!-- Base application theme. -->
-    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+    <style name="AppTheme" parent="android:Theme.Holo.Light">
         <!-- Customize your theme here. -->
     </style>
 

From 5ea924f149773594addabaa5a5c721750985c8dd Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Fri, 1 Aug 2014 09:32:38 +0200
Subject: [PATCH 03/59] Better tables visibility

 Plural and not plural entries lines have different background.
---
 .../info/nerull7/mysqlbrowser/EntriesFragment.java     | 10 +++++++++-
 .../{background_element.xml => entries_element_1.xml}  |  6 ++----
 app/src/main/res/drawable/entries_element_2.xml        |  6 ++++++
 app/src/main/res/values/colors.xml                     |  2 ++
 4 files changed, 19 insertions(+), 5 deletions(-)
 rename app/src/main/res/drawable/{background_element.xml => entries_element_1.xml} (69%)
 create mode 100644 app/src/main/res/drawable/entries_element_2.xml

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index 6d10075..e262af7 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -155,15 +155,23 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     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(R.drawable.background_element);
+                    textView.setBackgroundResource(background);
                     newRow.addView(textView);
                 }
                 entriesTable.addView(newRow);
diff --git a/app/src/main/res/drawable/background_element.xml b/app/src/main/res/drawable/entries_element_1.xml
similarity index 69%
rename from app/src/main/res/drawable/background_element.xml
rename to app/src/main/res/drawable/entries_element_1.xml
index a682ad2..4149979 100644
--- a/app/src/main/res/drawable/background_element.xml
+++ b/app/src/main/res/drawable/entries_element_1.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <!--<solid android:color="#0fff"/>-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/entries_background_color_1"/>
     <stroke android:width="1dp" android:color="@color/border"/>
-
 </shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/entries_element_2.xml b/app/src/main/res/drawable/entries_element_2.xml
new file mode 100644
index 0000000..0bd0f94
--- /dev/null
+++ b/app/src/main/res/drawable/entries_element_2.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/entries_background_color_2"/>
+    <stroke android:width="1dp" android:color="@color/border"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 86784b1..bf9163e 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -2,4 +2,6 @@
 <resources>
     <color name="border">@android:color/tab_indicator_text</color>
     <color name="header_background">@android:color/holo_orange_light</color>
+    <color name="entries_background_color_1">@android:color/background_light</color>
+    <color name="entries_background_color_2">#ffcccccc</color>
 </resources>
\ No newline at end of file

From 8f69536a70b796f3acc8ab492986ba1b3524b338 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Fri, 1 Aug 2014 11:28:49 +0200
Subject: [PATCH 04/59] Fix hidden Scrollbar

---
 .../mysqlbrowser/CustomScrollView.java        | 25 ++++++++-------
 .../nerull7/mysqlbrowser/EntriesFragment.java | 25 ++++++++++-----
 app/src/main/res/layout/fragment_entries.xml  | 31 ++++++++++---------
 3 files changed, 48 insertions(+), 33 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/CustomScrollView.java b/app/src/main/java/info/nerull7/mysqlbrowser/CustomScrollView.java
index e59685e..13ab2d4 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/CustomScrollView.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/CustomScrollView.java
@@ -2,6 +2,7 @@ package info.nerull7.mysqlbrowser;
 
 import android.content.Context;
 import android.util.AttributeSet;
+import android.view.MotionEvent;
 import android.widget.ScrollView;
 
 /**
@@ -9,10 +10,18 @@ import android.widget.ScrollView;
  */
 public class CustomScrollView extends ScrollView {
 
-    private OnScrollChangedListener listener;
+    private OnTouchEventListener onTouchEventListener;
 
-    public void setOnScrollChangedListener(OnScrollChangedListener listener){
-        this.listener = listener;
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if(onTouchEventListener != null){
+            onTouchEventListener.onTouchEvent(ev);
+        }
+        return super.onTouchEvent(ev);
+    }
+
+    public void setOnTouchEventListener(OnTouchEventListener onTouchEventListener){
+        this.onTouchEventListener = onTouchEventListener;
     }
 
     public CustomScrollView(Context context) {
@@ -23,13 +32,7 @@ public class CustomScrollView extends ScrollView {
         super(context,attributeSet);
     }
 
-    @Override
-    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
-        if(listener!=null)
-            listener.onScrollChanged(l,t,oldl,oldt);
-    }
-
-    public interface OnScrollChangedListener{
-        public void onScrollChanged(int l, int t, int oldl, int oldt);
+    public interface OnTouchEventListener {
+        public boolean onTouchEvent(MotionEvent ev);
     }
 }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index e262af7..fc90c18 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -8,9 +8,11 @@ import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
+import android.widget.HorizontalScrollView;
 import android.widget.ProgressBar;
 import android.widget.RelativeLayout;
 import android.widget.ScrollView;
@@ -36,9 +38,10 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     private static final int ENTRIES_PADDING_RIGHT = 15;
 
     private TableLayout entriesTable;
-    private CustomScrollView entriesScrollView;
+    private ScrollView entriesScrollView;
     private FrameLayout headerFrame;
     private RelativeLayout rootView;
+    private HorizontalScrollView horizontalScrollView;
     private TableRow.LayoutParams layoutParams;
     private TableRow headerRow;
 
@@ -48,7 +51,7 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     private int page;
     private int pageCount;
     private ProgressBar progressBar;
-    private ScrollView fakeScrollView;
+    private CustomScrollView fakeScrollView;
     private View dummyView;
 
     private MenuInflater menuInflater;
@@ -82,17 +85,20 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     private void initViewItems(View rootView){
         headerFrame = (FrameLayout) rootView.findViewById(R.id.headerFrame);
         entriesTable = (TableLayout) rootView.findViewById(R.id.entriesTable);
-        entriesScrollView = (CustomScrollView) rootView.findViewById(R.id.entriesScrollView);
-        fakeScrollView = (ScrollView) rootView.findViewById(R.id.fakeScroll);
+        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);
 
         this.rootView = (RelativeLayout) rootView;
 
-        entriesScrollView.setOnScrollChangedListener(new CustomScrollView.OnScrollChangedListener() {
+        fakeScrollView.setOnTouchEventListener(new CustomScrollView.OnTouchEventListener() {
             @Override
-            public void onScrollChanged(int l, int t, int oldl, int oldt) {
-                fakeScrollView.scrollTo(0,t);
+            public boolean onTouchEvent(MotionEvent ev) {
+                entriesScrollView.onTouchEvent(ev);
+                horizontalScrollView.onTouchEvent(ev);
+                return true;
             }
         });
 
@@ -259,6 +265,11 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         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);
+        fakeScrollLayout.setMargins(0,headerFrame.getHeight(),0,0);
+
+        fakeScrollView.setLayoutParams(fakeScrollLayout);
     }
 
 
diff --git a/app/src/main/res/layout/fragment_entries.xml b/app/src/main/res/layout/fragment_entries.xml
index a913904..b573ad0 100644
--- a/app/src/main/res/layout/fragment_entries.xml
+++ b/app/src/main/res/layout/fragment_entries.xml
@@ -4,19 +4,6 @@
     android:layout_height="match_parent"
     tools:context="info.nerull7.mysqlbrowser.EntriesFragment">
 
-    <ScrollView
-        android:layout_width="wrap_content"
-        android:layout_height="fill_parent"
-        android:layout_below="@+id/loginProgressBar"
-        android:layout_alignParentRight="true"
-        android:foregroundGravity="right"
-        android:id="@+id/fakeScroll">
-        <View
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:id="@+id/dummyView"/>
-    </ScrollView>
-
     <HorizontalScrollView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
@@ -33,7 +20,7 @@
                 android:id="@+id/headerFrame"
                 ></FrameLayout>
 
-            <info.nerull7.mysqlbrowser.CustomScrollView
+            <ScrollView
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:id="@+id/entriesScrollView"
@@ -44,7 +31,7 @@
                     android:layout_height="wrap_content"
                     android:id="@+id/entriesTable">
                 </TableLayout>
-            </info.nerull7.mysqlbrowser.CustomScrollView>
+            </ScrollView>
         </RelativeLayout>
     </HorizontalScrollView>
 
@@ -58,4 +45,18 @@
         android:layout_alignParentTop="false"
         android:layout_marginTop="-7dp" />
 
+    <info.nerull7.mysqlbrowser.CustomScrollView
+        android:layout_width="wrap_content"
+        android:layout_height="fill_parent"
+        android:layout_below="@+id/loginProgressBar"
+        android:layout_alignParentRight="true"
+        android:foregroundGravity="right"
+        android:id="@+id/fakeScroll"
+        android:overScrollMode="never">
+        <View
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/dummyView"/>
+    </info.nerull7.mysqlbrowser.CustomScrollView>
+
 </RelativeLayout>

From ad9cdc6e3a3488096a86388a26e8616dbf048237 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Fri, 1 Aug 2014 13:10:35 +0200
Subject: [PATCH 05/59] Build for KitKat not 4.4W (android wear)

---
 app/build.gradle | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/build.gradle b/app/build.gradle
index 6dce2b5..f0efe31 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
 
 android {
     compileSdkVersion 19
-    buildToolsVersion '20.0.0'
+    buildToolsVersion '19.1.0'
 
     defaultConfig {
         applicationId "info.nerull7.mysqlbrowser"

From 739ad4a104823c54432bce9cdb36433043ca5603 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Fri, 1 Aug 2014 14:04:18 +0200
Subject: [PATCH 06/59] A little bit theming

---
 app/src/main/AndroidManifest.xml              |   8 +++----
 app/src/main/res/drawable-hdpi/ic_revert.png  | Bin 0 -> 1026 bytes
 app/src/main/res/drawable-mdpi/ic_revert.png  | Bin 0 -> 666 bytes
 app/src/main/res/drawable-xhdpi/ic_revert.png | Bin 0 -> 1408 bytes
 .../main/res/drawable-xxhdpi/ic_revert.png    | Bin 0 -> 2081 bytes
 app/src/main/res/values/colors.xml            |   3 ++-
 app/src/main/res/values/styles.xml            |  22 +++++++++++-------
 app/src/main/res/values/themes.xml            |  20 +++++++++-------
 8 files changed, 32 insertions(+), 21 deletions(-)
 create mode 100644 app/src/main/res/drawable-hdpi/ic_revert.png
 create mode 100644 app/src/main/res/drawable-mdpi/ic_revert.png
 create mode 100644 app/src/main/res/drawable-xhdpi/ic_revert.png
 create mode 100644 app/src/main/res/drawable-xxhdpi/ic_revert.png

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 199b74d..09f4cb8 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -9,7 +9,8 @@
         android:theme="@style/AppTheme" >
         <activity
             android:name=".MainActivity"
-            android:label="@string/app_name" >
+            android:label="@string/app_name"
+            android:theme="@style/LoginTheme" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
 
@@ -26,13 +27,12 @@
         </activity>
         <activity
             android:name=".EntriesActivity"
-            android:label="@string/title_activity_entries"
-            android:theme="@style/EntriesTheme" >
+            android:label="@string/title_activity_entries" >
         </activity>
         <activity
             android:name=".SettingsActivity"
             android:label="@string/title_activity_setting"
-            android:icon="@drawable/ic_action_settings">
+            android:theme="@style/SettingsTheme">
         </activity>
     </application>
 
diff --git a/app/src/main/res/drawable-hdpi/ic_revert.png b/app/src/main/res/drawable-hdpi/ic_revert.png
new file mode 100644
index 0000000000000000000000000000000000000000..f0f7b382e89379eb78d4f7537b2bf2d858af27f8
GIT binary patch
literal 1026
zcmV+d1pWJoP)<h;3K|Lk000e1NJLTq002Ay002A)1^@s6I{evk000BYNkl<ZXhZFp
zO>9h26vxlGZ)U1y#^<7l2qnU%k@(tJsE7nXM9fS@NR*X@NLWxTd@k5nSSbrp?K}}d
zkXT@iSag9%d_<&aBfi?1mQLS2&KoM7er4Xg^O~3Gd#n3q?m74WyXV~d-aQXtoLxB1
zcp(5T_lO4(4kBD;GZ3V7nFVwRP7vWB!eurCK}wfdK*wg&Qt8YgMD@-}OuSvn1csZt
zS8CJ?tW>P26#LO^<Wu@arphqjJrAk?)efi7d03_I17L-Px*8JkFOtymz^u+Nvzvja
z*=_>TZYvQ_!xIXH+q;)&1vP{)(}qAzZ3^IJE*WhFL<*UmtBBMc{%Zo?*I9|^T}jyd
zn9>gW{TVIU^$dHH?;}9a#3QZc_Uz%tV-c@3pou^S`Tr0QZnsj=hhAv&4A>T%U&{dJ
zod_p@!#Wwe;KasBU(bLIvwJJ2^)&#BIT6H3m*I5Y<#g>AJBBB~p>$U*0Y1pD#nP@{
zoZcJylJO^{nU8EG4}AUWBqLn$nuna_Qf!-*`@I-;PVaQ-r@&ksnAhzQc6zpd6yA|r
zm8N@I;U*-g8BY92eRw?|<@J2dzrZFLhR(d@HCX*mBw1+8heYKEFni`1WW5{a$uM#s
zqW6}HErbMGQqZCi4x8Dfn&`y<ab#(u8tN)PLUYetLs|9<$>1?Z?V|{n=2Fp@z63VX
z**&}~Ul}MapRNS=HNwVGQ+mWcSZ^hxSA7Yr(%GZDyPlB}XZzvZzCkCW|Mvv9zC}}-
zfsZrrNw=a3G6e7h1D}%eDGD5F?pn=9hBZ>+@_sZt?yHMGmGUVHEG5cIKcc|nE~Nut
zf!yR>+P|At5aA%g&S${qDP4F{a*j9DLi)rc`dH%PT|HMh8YMvg`#{{w#k_*|b2t7)
zfx|7?<r?Xk8$p9@`LwixPfO3Ge2N0Y(DSf6oqj(L+jPpzHXzYyccg!<3GtXtL`6?u
zvJtjbn%^cH6nVp~87`sQE$m$ciD^Gw`YAA%2WIzNgx|tN_*-_fM6ni!cN-Vu?XM7`
zmnXosLau)7<D|UA&9FnoIj#cj=PJi#hjvAE_YBw`J=Bs}$0Z(H_?)8D0DR&y(7wJ@
z>`{^Z9e48-IIrgR_bIA3a)2u#d--nIZ%h39XMUq<)REqcuyyJW#}p0>ya(<VV}CvD
z=vk%})eu3I{WBtTD2=VTs>&Boi+v7sm)v#ifJ>GrYZw5_&Zqyp1rhdNOk@=W5tf}#
w|9J}{?7x`EDheVjJD>jZ7DU*8F_BgD2aJhUOk1k0G5`Po07*qoM6N<$g8T69YXATM

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-mdpi/ic_revert.png b/app/src/main/res/drawable-mdpi/ic_revert.png
new file mode 100644
index 0000000000000000000000000000000000000000..a110afdc240a4df6b43e49d54660d346e1a34b9f
GIT binary patch
literal 666
zcmV;L0%iS)P)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T70007ENkl<ZSV!%a
zF^dyH6vyA2Sr2Y^;}=jt5g{t5mDq@lg%&mnn~2(pm0qvaRob6diIoZ_3tCxN*w~3S
zo}i`?3-t?_-90#W=J{sN!@XdVomuY)$4--E^5*@2^MAveL74G@GtLJMVBHEe4mJ+f
zb)fG0oqGmlZ+KCO@C8J;HqoU;65f&IbRM-{ySVA*;3Ep;T>23Z-zoI3jD=)4+0K>$
z>AdoTqi_K;TSzxRqY|$kkUD<_0zV<aKm(lPWQWXO1TbLu=SZ|4h|VbCorP%rt1X;~
zcL(IfqBp#Sh)a`%iD*H0TlZbyY60>Y?6ONwIEkDhuGqz^s@v+hK)N{?XL}^kfQuQf
zSF{+Txk~exD8x2I{tsJ7CqS>C+-3FKMoegN%6w{}-;~8i=UM1p-U;t)3!vyH?^*D8
z0Z4eV07QDb32<bdH?*QV;fbvWBtjXdLlz1w#ZnaoEk3s!rLVNyzQm@t9ZpR@+f_;7
zZ_qFGIq+c-xg%8{_JAgLOmo#GN|DoUoqr^?2V8e>m2=rbuCasjTkl{4xVg?du*AGU
z*-sLuHq!~s&0{s}9W>23PFA>^9kWp)gbz9ji{@@KoB+#LT~)Ddz3SjuwpZqw9}AUl
zlT>-44VV1yRX4N|=j5PSEPLs7ekniTuhVi65Z+MT;Gr#?iJz8yVon(+*Z8ru%t5=y
z1pZ`&n<@$)yTH{3EJUAX`#hl+{yg~)nkjw_d=UUIb1jzOvj5E$?*9Om)%lhwep)^V
zCT*ZriR(C1b!`J!)v0lDjf0JYbsea?e&)~MZ+E22Dd%1f9{>OV07*qoM6N<$f+5s2
AivR!s

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xhdpi/ic_revert.png b/app/src/main/res/drawable-xhdpi/ic_revert.png
new file mode 100644
index 0000000000000000000000000000000000000000..67956bc699320eceaa326bc746607c9268d64938
GIT binary patch
literal 1408
zcmb7^`9ISQ0LQ<ZD?E;JFK2q@-lIIFIWn0sY38V$Ya&rzLrg2RSSd;?IX3rwy%=82
za>kPEA>?Yv5h50HYb-qV{0Gku@6Y?U&yVkTEXGbs0wMtbfE3yu>GI3i-y9JAwbX-a
z3;+<ZLnE!-NVuhpa}{#u<vGh)y!C<s3HvtWyI7Pq`DnW^F;AC3qSKYv=cAmo+heP>
z$c=rarF{x~6{X2mO$bhGFgAX=U1u7F#^zJR#U*nf*7A3<${ftYe>w%p#hk7)xq4eb
zf-{56E%#0K*B8=ymd3mo{(c904Oww1fd9!DKt9?L>{uU>3-}+xcNPhWXeI%!Fg0Bu
zO_+XzhXDO^l%0H5OacJ~6?>auf#c%Fv;8q8e<E^vE-37p4hU+Vdo3eMAQqHP8pqS<
zd`f>vJ(f@JiO_i~<<KYSv%eJ%gG(h1i_~3NlQ6x}e7_c~$1<P}9wOchYRMb=?knEp
zX<VG#EC<?05h9*K(pj_=lh|Px`++xW>xka2|MWrGo8alCG%e@~Wd~(jW7tum@On@c
zW|fjpjw~fc$NO<)a{7=TSX$p(c^0KT>(Yv38O1VpnHL2F;qmvYdt;HYV%BqZfv*;Z
zx2unRyIVkAvat2EI()HdZUpH9otH#JBt)JZ%K46X5N|o(Y0{fSgYch$!d1iUfLlQe
zHujT72F<xODA&>P9ieI;zdT6O!^avk$q8Uwh%`-odS)_EAX+`?G=ZE6j@e#^iy#^=
zEs#n*;B#jKvK`l&0py&~8$C&qTj$J<aH4c5Nac(UIo;{>y5SaRhh^Z?KkB>c9iD+o
zyoX9BTu50X6wGH*7Qw0|lyJ?lnESYlq<z2sNx{Y_DZ3VH#O=n-ET<0WBWfY1qX#1I
zDrq}M<y?2?qo+3?2M$NQH<mH)QfCwY#?lq`5S~7fnF~LTFw~v4>I=D(Q`xR=o3QB|
zy1u$l+UxF?rt(3Das0qBd%P6>jf`mgpbqC&zAjg(%z1f;yLWC%q|(Of%ZOWZ!t@F9
zRa1i^hUg~KW)Y++$;}t2TY_>Uzm_|!(zxUna^Bh1HZ%y*Rv>waKuuQn`|mT?OX~Ea
z9Ipn_Ct0aB#^v#cOhuU=S*^9`pRWSzBFe3I7iBYmdz8`bU`~KI6j-^;#Nv|GqRTtN
zlpZ|tWpy#HS5(?YHH}<jQJ*TP2rU6^{12AB;Q1>XX%`ex>p*WSsTaz&Lgdj?k?njl
zpeG9s$Vq58JFC5{fksIaBF6I;RHjN^jPTfQshBFfIWTMfd_)0^1u(V<jBh~50R(6`
zg`J>k|NgJUu5sAKsjhjd#B2aqPIIPCL${WBN*NS-c;m?_xJzIQdzVcx4RI|rmSmYE
z#3(ryw@`vOkGg|b^Ra{FbblwV*47=SShb+g#YrMFG0A~38<_NlP?6hEs55AWj^DDy
z1c6dzHF&(RPaO;*{)PpoiqT*AdH#xTVc>ZSZ!(j{;ol>a0}9ZgtdS{<>c%&meBAQz
z@|U+0#8=RdNsvWw8%V6ZHP$_G$AfIZG}DNcR&}X8fof8F%?~Z^3{t~i7Pd)uwrEQ7
z&J5Q->ET$TYC}5*pEbb@C`B8^`LP;9tw-WY#^Q_3Qvdk;q{Z|O-kV5`xhq5;G@cx)
zdZvq`5$nBPW_Ew<=|mOriBw0IqHhN5)PY)_VTp1@uY-<3jpId_<K(qQXeEtXF4(jx
z)9-=T?E~f_+cS!~-U+n(?t4)}u;U%1FpOZyrfy>C?eU4KmD|@{qrNE55xEDxCLHx?
z;0aY{gygIYi3O*MzT@?(J<Xl~m~Q?a+CUmx<bOp7{2U#vN0ask|CABhXu&sNS-)Eg
Mplvb8$}@P%ziqCaEC2ui

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xxhdpi/ic_revert.png b/app/src/main/res/drawable-xxhdpi/ic_revert.png
new file mode 100644
index 0000000000000000000000000000000000000000..8f0fbc05970655e5fa06f03b4d2048b2c2c00039
GIT binary patch
literal 2081
zcmcJQ`#%#31ID*wbJ^UM&2?@$TE|?bPTR2DQZ7jn<=!evnJgu@t(@g_V<fSPrEtic
zX6_rBxsHwqxr{8A%q66(6pOd>dH;p?{o#3@&-3|we}10Z-d?UM5M2lW08nvvbMg6^
z@&8Iu{-@i7Vfz69g*kT@C*SzcC1wx_?x!v6eJJ|t^>|JyE#_e3-6uD+;Tq}%@^WoE
z+d*OVDxt4IR)^Oo(2AcIu19Y-hL}}{(3Ehel`|a+3ScWhLrlRAIL63(bo^fB?n|<s
zE2$0rSK=&_5_^O=rLO+Hvm27Ftyj3S?6Wq7;2Jq(jqNs}BIYwa8K6OYuWH0_MR+D>
z+9d}Y_+fwtmH{ydzRe(Qo?Pe55%B*4pdvYyyt=54ba<ZBs<85y2tA!89#Mcq(H+t~
zHr3tfrNoBaP3hJZ;NKtD;UkZz>P(E1Jad$=`A`Y>p%iB<J0@;d6x{B4yq^|uQ^2e+
zy;*<Xc~fn<(q}U=r<VaA^>IL>G%-(M$pK$S&4Wg6I*q06qMkQ;2RY7mW(Z%jck65=
zIW}eEaB`TDd)*SrI&JAVBte_&v1S0nDV+vr#X6g!QmBp?Y=h@ocu$*0UCsR5t0s5M
z)mDwXjSOgyp~ODd6yKo7kG8Ct2Tp2%w3?dPTPf`_6U&2J0_4@{Gif2bhDFdATKKlP
z$ti!paxEv<n-~58c~RrYI5obr>`#tQTB`Ej{Z%W`r#ODoXYs3XJVFJX7wRC-^=S$~
z5Zp)+onRhHO+L1BsItDdIdsY?3qAZ6VxSYFOhNB^zzwoIPCNtF5>AV|u+#YhZ64tY
zD_d26<v~2%<`84yQHfVG9YiQDj7#rLKrJ3HWMx?)PEG=rhEuF|;dUJ=@qM4V`{u>u
zERl?G;ue+IQjMoSGu8}tnnpvs7UET+YR;X~oFMg*g5c#5*(X-K&q)F@HV!@<pah2Z
z@8op@W$iO(>_jUTx0qV{$;#A>q(3)HM5%GoHubV)<1`>CPEvbaul&t;=IFM?mB4|>
z$Vl7z=V^dEQm=y~$XQ%abzqpCE245mnEVUaHka1r#c}9x*fC!vT>Qg}o^928I$#@(
zL&dWu5>`^&5*jZO;|yQUY`|D+kUVJ9hwuDGSTpIL^M8D}WGE221IMAd!YXbJXX5uw
zI3}ZCGAegt;fEq??bXQ;7=_7jk3w(prDVa7qt}f)Cbf=;CdAH+sg6WBv6b!;U#7F-
zB39Bp|7mZ2Z&+06D&j=#Y>6lbuSe`w)tikjw~lp)oTT324d!`83T~4wl&X`8Tu)Q1
zn$L3lN}-55Ywt@&*>eyOJ`9N=mySKknUw@u2Fle|epd;;b;!h4C@OoLB@V4f?U4+%
zaAoI=g!?*RY0)b|M|0(7d`A2u1(=-W8wyLI&!&W?_-Bd2NUlBk?w|u3JaJXg5Tzis
z4o3FGC3(G6dT=n{(sN)Clb6MzUCQRcw!_}u!q3~yyY9Q}*S|kfK>p&9UO14AhuL@8
za9Mi-hdavHHT-0?)D)`qH5eR3kruNgT)p5g#YM%O_P2C9GV+rYEUR!E)wq+4YBR1*
zx2}J20U(oSWGJ7jQ=gb~QzY+HQ!x9MXN({)&G5?M@%)FTJbsc+X(@nlD$jkmrSoW?
zYxJrwKAE5Z+#x7@576H)Jk`kmIU-7Ab5$2L=Mwj)gd&J)_}G?RpQUX*-M9I_UC)nf
zUh4;X3Q?W;&5yiu>>2HJ1>Fq)FVMF)Me#CRfBb;%^?eC$2;@ubr4C|Zn1T)Qu7cWl
zSDi*R^~rOWCs2d>TpcLg7StD~EMI|XSX6rOZ8g(&F5TkSy;!|w54+rVtttLG#x6e^
zVm3_)-}tP}+b!X*>uDPLFLH@yEh>{mrSstOp~jDA9*K`;S;T8T2ey`>F{V%P+QB(5
z4P-Xud%k49Omm7kr}99h(cY|Nk*Vu)zok}d;!9tEbUgwjEaL+VjIT)9(qH1k)Ux!c
zP|ET(lp4!KAr%MchMu-C3)9VL*Tae<5<eCk44kBV15hZIq4SxA`YEgL)_bya5)iR`
z&5#{z-}ad8nju&>;9!II+CsMG!YTj3C<KeEuiMqdkM*~Gk~ntRKlA(tqB0SSsknno
z{aCt#)$?u(tkGm%A3nvfMXBhCk%A|f%q1$Mc<JUR|Dsk%`cTH~M4VAhgV#W2#KkvX
zun<l)*ejQ4ue_;4A$gxYYJJp!<Zsp5=pWFYVDi^)RgQ1&T&KnLRGHo6G&A$fu=u+n
zcfO+I{s}uYBm7t5Z;qSk_fR9VMntcrJX&2!z|3J$-isnxiIi5paCdJSIM}zUDye|!
z)`Ik#itQroI4s{PxUWnpo7Ehu+M~hlKn4ZitAGrWNA;RHJg3HBbHmfKhx&?ot!iw@
zy!Qn?)Ei*AO`V3iGRqKbe2wWRCk&$J-dl{no;B)5aau!|wr%*ddPPk_@;@g#L+Y56
zZC5{E_=7WoG>WyFxVQVA%Hz<P38STLx3)B{eqDxpy2f{}LR=4t5o&c7Qy{|qQF`*a
zJ(m4#&~VXqOfe$*`pj1#MNfeA*bY3P`uP8UfIpya{CvjxI8ylY`T_3yy<FJNMB0A<
DXe!ZC

literal 0
HcmV?d00001

diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index bf9163e..d9ecfa8 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
     <color name="border">@android:color/tab_indicator_text</color>
-    <color name="header_background">@android:color/holo_orange_light</color>
+    <color name="header_background">#ffaa22</color>
+    <color name="header_login_background">@android:color/holo_blue_dark</color>
     <color name="entries_background_color_1">@android:color/background_light</color>
     <color name="entries_background_color_2">#ffcccccc</color>
 </resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 29f1aa9..14ef368 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -1,14 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
 <resources>
-
-    <!-- Base application theme. -->
-    <style name="AppTheme" parent="android:Theme.Holo.Light">
-        <!-- Customize your theme here. -->
+    <!--Action Bar styles-->
+    <style name="DefaultActionBar"
+        parent="android:Widget.Holo.Light.ActionBar.Solid" >
+        <item name="android:background">@color/header_background</item>
+        <item name="android:icon">@drawable/ic_revert</item>
     </style>
 
-    <style name="TableTheme">
-        <item name="android:layout_width">1dip</item>
-        <item name="android:layout_height">match_parent</item>
-        <item name="android:background">@android:color/white</item>
+    <style name="LoginActionBar"
+        parent="DefaultActionBar" >
+        <item name="android:background">@color/header_login_background</item>
+        <item name="android:icon">@drawable/ic_launcher</item>
     </style>
 
+    <style name="SettingsActionBar"
+        parent="DefaultActionBar">
+        <item name="android:icon">@drawable/ic_action_settings</item>
+        </style>
 </resources>
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index c9512aa..984a41c 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -1,15 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <!--Activites Themes-->
-    <style name="EntriesTheme"
+    <!-- Base application theme. -->
+    <style name="AppTheme"
         parent="android:Theme.Holo.Light">
-        <item name="android:actionBarStyle">@style/EntriesActionBar</item>
-        </style>
+        <item name="android:actionBarStyle">@style/DefaultActionBar</item>
+    </style>
 
-    <!--Action Bar styles-->
-    <style name="EntriesActionBar"
-        parent="android:Widget.Holo.Light.ActionBar.Solid" >
-        <item name="android:background">@color/header_background</item>
+    <style name="LoginTheme"
+        parent="AppTheme">
+        <item name="android:actionBarStyle">@style/LoginActionBar</item>
+    </style>
+
+    <style name="SettingsTheme"
+        parent="AppTheme">
+        <item name="android:actionBarStyle">@style/SettingsActionBar</item>
     </style>
 
 </resources>
\ No newline at end of file

From 5f87f442c6bc66b893265a8ea3140f9a3c9ee6e6 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Fri, 1 Aug 2014 14:23:36 +0200
Subject: [PATCH 07/59] Fix not showing mysql/php errors

---
 .../mysqlbrowser/db/AsyncDatabaseConnector.java        | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index bab7b30..2065aea 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -123,16 +123,16 @@ public class AsyncDatabaseConnector {
             public void onFinished(String data, String error) {
                 List<String>list = null;
                 boolean listenerData;
-                if(data==null) {
+                if(data == null) {
                     listenerData = false;
                     errorMsg = error;
-                }
-                else if(booleanReturnListener!=null)
-                    listenerData = (data.compareTo("OK")==0);
-                else {
+                } else if( data.compareTo("OK") == 0){
+                    listenerData = true;
+                } else {
                     errorMsg = data;
                     listenerData = false;
                 }
+
                 booleanReturnListener.onBooleanReturn(listenerData);
             }
         });

From 9ea0c789bb5361b0f93fd4f03763d23e386eafca Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Fri, 1 Aug 2014 14:30:45 +0200
Subject: [PATCH 08/59] Checking network status before requests

---
 app/src/main/AndroidManifest.xml              |  1 +
 .../mysqlbrowser/DatabaseFragment.java        | 16 ++++++----
 .../nerull7/mysqlbrowser/EntriesFragment.java | 30 +++++++++---------
 .../nerull7/mysqlbrowser/LoginFragment.java   | 29 ++++++++---------
 .../info/nerull7/mysqlbrowser/Static.java     | 31 +++++++++++++++++++
 .../nerull7/mysqlbrowser/TableFragment.java   | 17 ++++++----
 app/src/main/res/values/strings.xml           |  1 +
 7 files changed, 83 insertions(+), 42 deletions(-)

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 09f4cb8..5829f73 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -37,5 +37,6 @@
     </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 d1648d0..21d4671 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
@@ -45,12 +45,16 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic
 
     @Override
     public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
-        String chosenDatabase =  (String) listAdapter.getItem(position);
-        listAdapter.getItem(position);
-        Intent intent = new Intent(getActivity(), TableActivity.class);
-        intent.putExtra(Static.DATABASE_NAME_ARG,chosenDatabase);
-        Static.asyncDatabaseConnector.setDatabaseInUse(chosenDatabase);
-        startActivity(intent);
+        if(Static.isNetworkConnected(getActivity())) {
+            String chosenDatabase = (String) listAdapter.getItem(position);
+            listAdapter.getItem(position);
+            Intent intent = new Intent(getActivity(), TableActivity.class);
+            intent.putExtra(Static.DATABASE_NAME_ARG, chosenDatabase);
+            Static.asyncDatabaseConnector.setDatabaseInUse(chosenDatabase);
+            startActivity(intent);
+        } else {
+            Static.showErrorAlert(getResources().getString(R.string.no_connection), getActivity());
+        }
     }
 
     @Override
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index fc90c18..005821c 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -139,21 +139,23 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()){
-            case R.id.action_previous:
-                page--;
-                break;
-            case R.id.action_next:
-                page++;
-                break;
+        if(Static.isNetworkConnected(getActivity())) {
+            switch (item.getItemId()) {
+                case R.id.action_previous:
+                    page--;
+                    break;
+                case R.id.action_next:
+                    page++;
+                    break;
+            }
+            changeMenus(page);
+            entriesTable.removeAllViews(); // clean table
+
+            setLoading(true);
+            Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page); // get new entries
+        } else {
+            Static.showErrorAlert(getResources().getString(R.string.no_connection), getActivity());
         }
-        changeMenus(page);
-        entriesTable.removeAllViews(); // clean table
-
-        setLoading(true);
-        Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page); // get new entries
-
-
         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 c17bddf..41cb054 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
@@ -85,9 +85,16 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
         login = loginTextbox.getText().toString();
         password = passwordTextbox.getText().toString();
         url = urlTextbox.getText().toString();
-        asyncDatabaseConnector = new AsyncDatabaseConnector(login, password, url);
-        asyncDatabaseConnector.setBooleanReturnListener(this);
-        asyncDatabaseConnector.checkLogin();
+
+        if(Static.isNetworkConnected(getActivity())) {
+            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
+            progressBar.setVisibility(View.INVISIBLE);
+        }
     }
 
     @Override
@@ -98,21 +105,11 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
             startActivity(intent);
         }
         else {
-            final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-            builder.setMessage(Static.asyncDatabaseConnector.errorMsg);
-            builder.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialogInterface, int i) {
-                    // Nothing to do here
-                    // Cleaning inputs is stupid
-                }
-            });
-            builder.setTitle(R.string.error);
-            builder.setIcon(R.drawable.ic_action_warning);
-            builder.create();
-            builder.show();
+            Static.showErrorAlert(Static.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/Static.java b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
index 055f1f7..1013bec 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
@@ -1,7 +1,13 @@
 package info.nerull7.mysqlbrowser;
 
+import android.app.AlertDialog;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+
+import java.net.NetworkInterface;
 
 import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
 
@@ -18,4 +24,29 @@ public class Static {
         Intent intent = new Intent(context, SettingsActivity.class);
         context.startActivity(intent);
     }
+
+    public static boolean isNetworkConnected(Context context){
+        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
+        if(networkInfo!=null && networkInfo.isConnected()){
+            return true;
+        } else
+            return false;
+    }
+
+    public static void showErrorAlert(String errorMessage, Context context){
+        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        builder.setMessage(errorMessage);
+        builder.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialogInterface, int i) {
+                // Nothing to do here
+                // Cleaning inputs is stupid
+            }
+        });
+        builder.setTitle(R.string.error);
+        builder.setIcon(R.drawable.ic_action_warning);
+        builder.create();
+        builder.show();
+    }
 }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
index 812f260..91d63f7 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
@@ -45,12 +45,17 @@ public class TableFragment extends Fragment implements AdapterView.OnItemClickLi
 
     @Override
     public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
-        String chosenTable =  (String) listAdapter.getItem(position);
-        listAdapter.getItem(position);
-        Intent intent = new Intent(getActivity(), EntriesActivity.class);
-        intent.putExtra(Static.DATABASE_NAME_ARG,databaseName);
-        intent.putExtra(Static.TABLE_NAME_ARG,chosenTable);
-        startActivity(intent);
+        if(Static.isNetworkConnected(getActivity())) {
+            String chosenTable =  (String) listAdapter.getItem(position);
+            listAdapter.getItem(position);
+            Intent intent = new Intent(getActivity(), EntriesActivity.class);
+            intent.putExtra(Static.DATABASE_NAME_ARG,databaseName);
+            intent.putExtra(Static.TABLE_NAME_ARG,chosenTable);
+            startActivity(intent);
+        } else {
+            Static.showErrorAlert(getResources().getString(R.string.no_connection), getActivity());
+        }
+
     }
 
     @Override
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ff22c47..6d1f5be 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -30,5 +30,6 @@
     <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>
 
 </resources>

From 677df2941c173767c93611e1839d2a2e4e5d2c7f Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 6 Aug 2014 12:20:47 +0200
Subject: [PATCH 09/59] New menu

 Better menu pages handling
 New action - add (to be implemented)
---
 .../nerull7/mysqlbrowser/EntriesFragment.java |  34 ++++++++++++------
 .../drawable-hdpi/ic_action_add_circle.png    | Bin 0 -> 711 bytes
 .../drawable-mdpi/ic_action_add_circle.png    | Bin 0 -> 497 bytes
 .../drawable-xhdpi/ic_action_add_circle.png   | Bin 0 -> 885 bytes
 .../drawable-xxhdpi/ic_action_add_circle.png  | Bin 0 -> 1605 bytes
 .../res/menu/entries_activity_actions.xml     |   6 ++++
 app/src/main/res/values/strings.xml           |   1 +
 7 files changed, 30 insertions(+), 11 deletions(-)
 create mode 100644 app/src/main/res/drawable-hdpi/ic_action_add_circle.png
 create mode 100644 app/src/main/res/drawable-mdpi/ic_action_add_circle.png
 create mode 100644 app/src/main/res/drawable-xhdpi/ic_action_add_circle.png
 create mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_add_circle.png

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index 005821c..e6d6bc5 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -54,7 +54,6 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     private CustomScrollView fakeScrollView;
     private View dummyView;
 
-    private MenuInflater menuInflater;
     private Menu menu;
 
     @Override
@@ -110,10 +109,12 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         inflater.inflate(R.menu.entries_activity_actions, menu);
-        menuInflater = inflater; // I think we need it later
+
         menu.findItem(R.id.action_previous).setVisible(false); // hide previous
+        if(pageCount<=1)
+            menu.findItem(R.id.action_next).setVisible(false); // hide next if we don't have any more pages
         this.menu = menu;
-//        super.onCreateOptionsMenu(menu, inflater);
+        super.onCreateOptionsMenu(menu, inflater);
     }
 
     private void changeMenus(int page){
@@ -137,22 +138,34 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         progressBar.setVisibility(isLoading ? View.VISIBLE : View.INVISIBLE);
     }
 
+    private void loadAnotherPage(){
+        changeMenus(page);
+        entriesTable.removeAllViews(); // clean table
+
+        setLoading(true);
+        Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page); // get new entries
+    }
+
+    private void addNewElement(){
+        //TODO Implement this method
+    }
+
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        if(Static.isNetworkConnected(getActivity())) {
+        if (Static.isNetworkConnected(getActivity())) {
             switch (item.getItemId()) {
                 case R.id.action_previous:
                     page--;
+                    loadAnotherPage();
                     break;
                 case R.id.action_next:
                     page++;
+                    loadAnotherPage();
+                    break;
+                case R.id.action_add:
+                    addNewElement();
                     break;
             }
-            changeMenus(page);
-            entriesTable.removeAllViews(); // clean table
-
-            setLoading(true);
-            Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page); // get new entries
         } else {
             Static.showErrorAlert(getResources().getString(R.string.no_connection), getActivity());
         }
@@ -225,8 +238,7 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         if( result%entriesLimit > 0)
             pageCount++;
 
-        if(pageCount>1)
-            setHasOptionsMenu(true);
+        setHasOptionsMenu(true);
     }
 
     private void syncWidths(){ // TODO: Merge with adding columns maybe? Loops -= 3 should be quicker
diff --git a/app/src/main/res/drawable-hdpi/ic_action_add_circle.png b/app/src/main/res/drawable-hdpi/ic_action_add_circle.png
new file mode 100644
index 0000000000000000000000000000000000000000..5f68a011878f3bfe1092a7b9e9aecce5684d72c8
GIT binary patch
literal 711
zcmV;&0yzDNP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm0007xNkl<ZXhZE;
zO(<qj82-?(F-F<3k)6eqvLH1Z6vfo6MYglFv_aUgvz)ESTA?Uxl*VGDEbOM)u+#Y4
zpc$U0&i%Tsd(Yqfj?XK%p6=qD_q^|O&iiwIDhk5C3gPw_-U%31Fq)u;P%B-k6{v)P
z%?eHUHvk`jYGwEx{@1`ca0>iU_@9?pUIL$BKqt@+)H@n;f&RaMpTMP~Y_Yp9fm)2v
z3v>WgzRH!{Kl~4XZQ#arEFS`GP%;SAxhgaCze4*uaO5(s3jzB10Pw{{fk)px$ZP;s
z@nK8g0|p!hT0IQ%5jla-GH`DawjscoAALdNBb!NL(X<ja1irq2+hk2N-Dyp?3MK*!
z*dfz025w)`1-6a=Q{@=on{DX7Q3a+R#*xp*?6d%+rdS<;ZxHJ8(Wv}(Di(w^ei~pr
z`F#5jT1^woBESke4)_)+rof2=f!Q1cSnTG2XB9h(Kp#5y_)L|ODK!BOy8~<`ZAv4+
zW#;U=?rq{@ham753g(r27Imc&XhG}u9J5c+5Ck~x58!v)wlo5C9lB7SFBE}I7`1C6
zFoF)B^H?8n1&%THl8FFwf1?Ef-DZnzu4&XJ#hzhY)&y+~F#Yi~rTbW<X4Fh)^-FHV
zbcKw@PXeZ5$5S2CaV7!A1P!Y(5a1D!3az%h7OP1D)EgZ^vqWx{-r^ZM8N}iVkhy3V
zA_4J1EIy5PV-@->0#Dbatc6VcR^qj8=6DgtE%lSs{U*25^lkA68j=uwq$C0HhkB9_
zeXSDZdC?bJBq9E4kt9T4?nbU8`g%RS?-BdJ5ho$~i78Gb&m$i%st$p&Jn|*C(qf-k
tO~(c?58Wmr!P-qPG{F>?YGCmM9svbSxH0M#(4_zX002ovPDHLkV1j#nKC%D+

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-mdpi/ic_action_add_circle.png b/app/src/main/res/drawable-mdpi/ic_action_add_circle.png
new file mode 100644
index 0000000000000000000000000000000000000000..649d671c25f55b04cdf73baf01e0ae357bfbab11
GIT binary patch
literal 497
zcmV<N0S^9&P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80005FNkl<ZSVzT|
zJ1j&&6oz*xk!+zR5hXSe(RtMLBEmKrJ<+LjLaovuB6{jYCnE7EB|@!`pd|i(%_P@k
zj(cWE&Ln^4?(CU4-#PQRbE_5OQZ@Ep$pz>FcsJDH0(eLL485iXlmbA9qtJkJ9`i+r
zJLtjzmGWo+809oH47HVx_-*hBT|vhXvm=%=fPVCxgF2OtL$fzD96<L{|K9-W=rjwp
zXFB)YKJah|UB||e02uk=KR7Q!?8Gt=1K^x5{~_&C!Z;mU;hKm6%)n?wk@hFpoI1M+
z)IEwmm#{f1+JykzYAcXtwco&Q-wig8dPo7l-LVOAyS7RQ!0pCpG$jXs<2Ioa31Ag}
zFbkTJ3&7|%VgNi|*EF7;O)dbtuS2b4yEp}X_`M_maKXI<|FP}NwT+_=7hx^Z=7-qE
z!$SzbGrl1J?4kWOAv-i3gcgK8yJ+V-<3|R}0aB;n5doaL2**(O2GJ%@f%zh20H)iJ
z08`MUa<S!Z!zRWT4<hrUn8BOAj0j-<Iwpkag~YEx(<_;WFujy|2-9nM@klWHFo~T@
nCZA@?12WC5?8_)^v<&Mn3o~pXvH|R|00000NkvXXu0mjf%rx5A

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xhdpi/ic_action_add_circle.png b/app/src/main/res/drawable-xhdpi/ic_action_add_circle.png
new file mode 100644
index 0000000000000000000000000000000000000000..adbda7f3a06b1f84421e52277e67c45d28ecf871
GIT binary patch
literal 885
zcmV-*1B(2KP)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF0009#Nkl<ZcwX(B
zO{fl07{~7o3m;Lwl7()e6e|j`@Ug;%QYb|%SlHOGu&}VOU~@MX6rvPLvBAp6f>5kj
z2z9fNd=>dvp#1)IN7H!copa86=FI4Mr~ci0yU+8SbAEHa=9x2t1IDjG<Lw{l1L*ev
z;{;L;fl08Qg=V73Xd)Ur%KsNXzo9Sa9eRttrnonC0vJOB=A(sZE}HJypbyx;LeJ0(
z^xM<l$-E8#y0c5sGBnkx7S%?dFnNd`jrNpk4@Zlb0MzhRXeAowSiY~>PaN){yRksT
z0<ee*ZA4RiTNG&j8NX}jX`ugKw_X8^C(;(Aao)tG`QbA95n6aJ0A^6=b~HP*@JN1d
zh;sqG4~Z8FU=D@tMiW8`t-<FzG0&jazOh39sPVgyCcQRY+DDxAh2RT7-F{z-?tJkE
zs3)B884f-GG~w-S!I-b=b(#}SBBzPb2f$8(HZ|K<HM;nJtq$j0oLm8Do!{XSuthfK
zsY~TP!3BUOyZtEUCTE0r9}BRi@%K<ffZ8k#BTbH_mkWRmc(0CFF@?H_o)ls(=I?Eh
z%eh0m>%9Qb-9Ln4@9k3o(6htQZoQzY2du$)edN26vInTF8|Zdf8@d6|^ZWr6>yb8J
zhg3a4W$ID-IO>>B=muZ`PTKC)ais*H`kzM6J2j*mfXz54sZqz38i0~1S9}2+#KAX>
z<q9h`0HxQC`2bJ?^RR1c0_;))P!*4$e-f=_Ltq}pdjcBf>e2*&Q&jF{v4Uj)R$#cv
zwKV~DO#rw`J@2~$Scl<S&xVa)|G?2lwpyO@mzLWhNB`v>wpqwq{BqM3K*$R4nBbQj
z8_=uSRst;X4AOBWC>sJH1+*PN$NKdFlyoEWL%{qbXnq+qzY#LO71rEn`e8@_LRJFT
zy-Dh=aM0th`Gko1l$g4+>7=Ltm`{rfg6S6{SuZgCYD^GJzZ}ihcGIuN1;P9Q2|+M@
zL?#;wrVmNwA(%ZTmq9RnP%?vH`lxLF(bw!@={y9}$K{J4Onxv?%myi+pyaBCM=zhu
z=&YaK>i##M%#@|Y%zZTFnjdV`uIiXvqm@fhcppFt%55&gd=K~osTR^f{Vxn}00000
LNkvXXu0mjfX_=)~

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_add_circle.png b/app/src/main/res/drawable-xxhdpi/ic_action_add_circle.png
new file mode 100644
index 0000000000000000000000000000000000000000..73e6e6750f353db3f11f53a05b3204a853ce5f7a
GIT binary patch
literal 1605
zcmV-L2D<r)P)<h;3K|Lk000e1NJLTq003YB003YJ1^@s6;+S_h000IINkl<ZcwX&Y
zU8q$>6!tH}tS~68mlP6AgbMNJK?tuHMhHEa5*iAEK2$zPsGxxaiI_+aC4z#XM2Oi#
z5K;sdK@a{QDToRN*C*2gCAG*j{k}Y#PM34`UVCQE%${@Bz{lm@JA18J>zn^Id-m{Q
zmXdm4cv9`Ae3%iCxDprvMnGZ@Bvx-Nzz9g}fyC-_ZUHR&h?f8U!Oy#ied(mW=>&|0
zRZjsEfX9Jxz{3FlJ{lO=vic5w-U4m{H-KxvZ@^{XQtR(d4hsEH(+C&?gQo(|0F!_x
zlpOFY<O~8o180FhmE?MhX#xQ(!xZ4Tmh)M=LngKol5iS04<zlnQWEe0jDG=`1xyU-
z@e<h=@xNohPr%<P%8-J92Vv-JU;qeR+oe9`xbZ!36!=T}kVd}P1U!#IzXXieD0~1J
zS0M9S;8XzF9Yw|>;1OtF0L%np>2&oW$Asg+H^6mQA=2k!ID>usE5Jk2LNz4cA1KFR
zfMZ0k6q0~ZDD`}ReSJth!JGrZYz^PFx+ShP)Ke(OaBzJMn5JIhGy=~+?dJeng=z{x
zz+))kDu653UP@e9?*XoA8l_DDoxTF#)<G|(UtrXJfMlp7O#)c+SN5>;3x|`0PqbQs
z76I(@-|E3`r&}#&3-}oD9uqVO;B03Z&?^J3v}@tO{3+lyJJKNFWfWqbwA4M8?+EPq
z+Q%ke0=URp1o+DFu_5KNTqk@1I4{<G9LMd2cYxehxY~qq9M}OkZCm&dz=alDfTjB_
z;E;<WTnXT==F$XR51TxrS>1vtw1-hOSG!z%$Y)rd&w$#ys4fNNe*PLD#g_7I=-mcz
z|GraVym$k^nOW?_t?ZA0TJZ!I0$zlYg|V$`=_3JK0EQJiC9X#{B_e?3`3m@<j&JG`
zz%b%QAXOx*=>)K4ZUw~Q&AJ3Ipt86Q!^(M^P5{m2t|<dLqEv?f=6w@L6+ov!IS??2
za_#~|r!DFb@GOLKvn^%HfdKkvFK|xcs5%5JfxsCOp#k&cLcj_5;Go10QUW-)UJs-i
zd<$E0A%L^A4}i)Ocv1qUL)hyQMg!-`g#fzY0C2L(A5sE1^Wh9Ab;^kV&V)E4Dos)X
z*!?si#+wrXJP^EHg8=sXo2vvx`hQLY&?WBy-B#`Yx=hjnCL`bKNDi)2lN$lMVbFy#
zqa*~(fq+-5JQL~vxe@Rs{PLqO0dzh|XhO=306L!}bWM^Lz;ixY0e3FXeS+A<c68Zp
zsPA?(Uwe}HMN%OdxZmeXz}pb;v_zXA55spK0(7KnqKvYDj8BM^afG#ikBoM^F5;J+
zz65AaL0NO(_iP2O#7UlG?SB{0TJiJz5Ld*`T@afh100V^N-xOMZv^}fpD=*bb!W7y
zuhXs({YF5gy+*+Qn{D(8S4DtzL4tm@B#U<!MA<e7yOZEO2vfC9L){5bnTFaz%$)$0
zg_vzcxD%kV6=9ok?gXf8#@TkXI{_-&(H4+#CqN}2L-p$bt-E{N&B^0nR$-r7NRk3A
zC||$Ys0QWjSW0~YRF9?D!K``&s2|LtdOMmZCqeyaB30YrTsZ+j4(HnObQuAI$QI;y
zI@Q|?8r3B5R5ZIFQL2gu3>9LpD3!Z4_$x|OZ!hU}Cn5MtdQ@$%sdgqH+H0y*pYlcR
zsw-l6rl)S#D(bIGGDUq+yC{cURq!7p(XT3?YP+oCJ^{%t>!5PGt|sAiHAMro3!6Mf
z5RJi#hne00v`$cam=pEU##~uOtNZcNKAw6mef>yM9W+`%p~tSRlz4nd9!&x$nr~7r
z2cC2&OAe1T`r_91mS9&G3#*fM3n<j~;^p1E6VAKOAIeK80;q?xBYrJo00^l^Sl67g
zWqW;nyS4TKhZ62%)lB<@Nf#1g5m2bNkN5<hhDtix;xkrrk(t*_HX-%RXRO+tU3|!m
zapp;hSQvy}o?z>%54m-kiP@(N6V<?>YVBj54I!c^hJDVqVT807hch_)pmT!>%A#no
z*8y2LC1xRwfSBIypvwp_0up;5v3hF(MnGZ@BvyY9w~}>m3c$is00000NkvXXu0mjf
DjDp@=

literal 0
HcmV?d00001

diff --git a/app/src/main/res/menu/entries_activity_actions.xml b/app/src/main/res/menu/entries_activity_actions.xml
index 43bef46..d4eca48 100644
--- a/app/src/main/res/menu/entries_activity_actions.xml
+++ b/app/src/main/res/menu/entries_activity_actions.xml
@@ -1,6 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:id="@+id/action_add"
+        android:icon="@drawable/ic_action_add_circle"
+        android:title="@string/action_add"
+        android:showAsAction="ifRoom" />
+
     <item
         android:id="@+id/action_previous"
         android:icon="@drawable/ic_action_arrow_back"
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 6d1f5be..f8d2e52 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -31,5 +31,6 @@
     <string name="save_credentials">Save credentials</string>
     <string name="connector_url">Connector URL</string>
     <string name="no_connection">No Internet Connection</string>
+    <string name="action_add">Add new</string>
 
 </resources>

From f4382ca24918bc654260cba43d276fa720579d4a Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 6 Aug 2014 12:25:14 +0200
Subject: [PATCH 10/59] Welcome Element UI

 Element Activity
 Element Fragment
---
 app/src/main/AndroidManifest.xml              |  6 +++++-
 .../nerull7/mysqlbrowser/ElementActivity.java | 21 +++++++++++++++++++
 .../nerull7/mysqlbrowser/ElementFragment.java |  9 ++++++++
 app/src/main/res/layout/activity_element.xml  |  7 +++++++
 app/src/main/res/layout/fragment_element.xml  |  6 ++++++
 app/src/main/res/menu/element.xml             |  8 +++++++
 app/src/main/res/values/strings.xml           |  3 ++-
 7 files changed, 58 insertions(+), 2 deletions(-)
 create mode 100644 app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java
 create mode 100644 app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
 create mode 100644 app/src/main/res/layout/activity_element.xml
 create mode 100644 app/src/main/res/layout/fragment_element.xml
 create mode 100644 app/src/main/res/menu/element.xml

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5829f73..ba08ea4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -32,7 +32,11 @@
         <activity
             android:name=".SettingsActivity"
             android:label="@string/title_activity_setting"
-            android:theme="@style/SettingsTheme">
+            android:theme="@style/SettingsTheme" >
+        </activity>
+        <activity
+            android:name=".ElementActivity"
+            android:label="@string/title_activity_element" >
         </activity>
     </application>
 
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java
new file mode 100644
index 0000000..38680c8
--- /dev/null
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java
@@ -0,0 +1,21 @@
+package info.nerull7.mysqlbrowser;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import info.nerull7.mysqlbrowser.R;
+
+public class ElementActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_database);
+        if (savedInstanceState == null) {
+            getFragmentManager().beginTransaction()
+                    .add(R.id.container, new ElementFragment())
+                    .commit();
+        }
+    }
+}
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
new file mode 100644
index 0000000..c69d447
--- /dev/null
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
@@ -0,0 +1,9 @@
+package info.nerull7.mysqlbrowser;
+
+import android.app.Fragment;
+
+/**
+ * Created by nerull7 on 2014-08-06.
+ */
+public class ElementFragment extends Fragment {
+}
diff --git a/app/src/main/res/layout/activity_element.xml b/app/src/main/res/layout/activity_element.xml
new file mode 100644
index 0000000..12fee7b
--- /dev/null
+++ b/app/src/main/res/layout/activity_element.xml
@@ -0,0 +1,7 @@
+<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.ElementActivity"
+    tools:ignore="MergeRootFrame" />
diff --git a/app/src/main/res/layout/fragment_element.xml b/app/src/main/res/layout/fragment_element.xml
new file mode 100644
index 0000000..987aad8
--- /dev/null
+++ b/app/src/main/res/layout/fragment_element.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/app/src/main/res/menu/element.xml b/app/src/main/res/menu/element.xml
new file mode 100644
index 0000000..7109817
--- /dev/null
+++ b/app/src/main/res/menu/element.xml
@@ -0,0 +1,8 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context="info.nerull7.mysqlbrowser.ElementActivity" >
+    <item android:id="@+id/action_settings"
+        android:title="@string/action_settings"
+        android:orderInCategory="100"
+        android:showAsAction="never" />
+</menu>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index f8d2e52..3e85dfd 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -17,7 +17,7 @@
     <string name="title_activity_entries">EntriesActivity</string>
     <string name="general_category">General</string>
     <string name="entries_limit">Entries per page limit</string>
-    <string name="entries_summary">%s entries per page</string><!--<xliff:g id="count"></xliff:g>-->
+    <string name="entries_summary">%s entries per page</string> <!-- <xliff:g id="count"></xliff:g> -->
     <string name="title_activity_setting">Settings</string>
     <string name="cancel">Cancel</string>
     <string name="set">Set</string>
@@ -32,5 +32,6 @@
     <string name="connector_url">Connector URL</string>
     <string name="no_connection">No Internet Connection</string>
     <string name="action_add">Add new</string>
+    <string name="title_activity_element">ElementActivity</string>
 
 </resources>

From 78d840db2913c35a31a3758a733e54cddc6d5f90 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 6 Aug 2014 13:50:15 +0200
Subject: [PATCH 11/59] Add element implementation-ish

---
 .../nerull7/mysqlbrowser/ElementActivity.java | 11 +++-
 .../mysqlbrowser/ElementArrayAdapter.java     | 37 +++++++++++
 .../nerull7/mysqlbrowser/ElementFragment.java | 63 ++++++++++++++++++-
 .../nerull7/mysqlbrowser/EntriesFragment.java |  6 +-
 app/src/main/res/layout/fragment_element.xml  | 17 +++++
 .../res/layout/list_item_element_simple.xml   | 23 +++++++
 app/src/main/res/menu/element.xml             | 16 ++---
 app/src/main/res/values/strings.xml           |  1 +
 8 files changed, 163 insertions(+), 11 deletions(-)
 create mode 100644 app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
 create mode 100644 app/src/main/res/layout/list_item_element_simple.xml

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java
index 38680c8..28c0fe8 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java
@@ -11,10 +11,17 @@ public class ElementActivity extends Activity {
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_database);
+        setContentView(R.layout.activity_element);
+        Bundle bundle = getIntent().getExtras();
+        String titleName = bundle.getString(Static.TABLE_NAME_ARG);
+        setTitle(titleName);
+
+        ElementFragment elementFragment = new ElementFragment();
+        elementFragment.setArguments(bundle);
+
         if (savedInstanceState == null) {
             getFragmentManager().beginTransaction()
-                    .add(R.id.container, new ElementFragment())
+                    .add(R.id.container, elementFragment)
                     .commit();
         }
     }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
new file mode 100644
index 0000000..2579937
--- /dev/null
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
@@ -0,0 +1,37 @@
+package info.nerull7.mysqlbrowser;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import java.util.List;
+
+/**
+ * Created by nerull7 on 2014-08-06.
+ */
+public class ElementArrayAdapter extends ArrayAdapter<String> {
+    private Context context;
+    private List<String> values;
+    private int layout;
+
+    public ElementArrayAdapter(Context context, int resource, List<String> objects) {
+        super(context, resource, objects);
+        this.context = context;
+        values = objects;
+        layout = resource;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        View rowView = layoutInflater.inflate(layout, parent, false);
+
+        TextView textView = (TextView) rowView.findViewById(R.id.textFieldName);
+        textView.setText(values.get(position));
+
+        return rowView;
+    }
+}
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
index c69d447..ed62562 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
@@ -1,9 +1,70 @@
 package info.nerull7.mysqlbrowser;
 
 import android.app.Fragment;
+import android.content.Context;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import java.util.List;
+
+import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
 
 /**
  * Created by nerull7 on 2014-08-06.
  */
-public class ElementFragment extends Fragment {
+public class ElementFragment extends Fragment implements AsyncDatabaseConnector.ListReturnListener {
+    private String databaseName;
+    private String tableName;
+    private ListAdapter listAdapter;
+
+    private ProgressBar progressBar;
+    private ListView listView;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        //Inflate the layout for this fragment
+        View rootView = inflater.inflate(R.layout.fragment_element, container, false);
+        progressBar = (ProgressBar) rootView.findViewById(R.id.progressBar);
+        listView = (ListView) rootView.findViewById(R.id.listView);
+
+        initArguments();
+
+        Static.asyncDatabaseConnector.setListReturnListener(this);
+        Static.asyncDatabaseConnector.getFields(tableName);
+
+        return rootView;
+    }
+
+    private void initArguments() {
+        databaseName = getArguments().getString(Static.DATABASE_NAME_ARG);
+        tableName = getArguments().getString(Static.TABLE_NAME_ARG);
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        inflater.inflate(R.menu.element, menu);
+        super.onCreateOptionsMenu(menu, inflater);
+    }
+
+    @Override
+    public void onListReturn(List<String> fields) {
+        listAdapter = new ElementArrayAdapter(getActivity(), R.layout.list_item_element_simple, fields);
+        listView.setAdapter(listAdapter);
+//        databasesListView.setAdapter(listAdapter);
+//        databasesListView.setOnItemClickListener(this);
+        progressBar.setVisibility(View.INVISIBLE);
+
+        setHasOptionsMenu(true);
+    }
+
 }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index e6d6bc5..ad186ab 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -1,6 +1,7 @@
 package info.nerull7.mysqlbrowser;
 
 import android.app.Fragment;
+import android.content.Intent;
 import android.graphics.Typeface;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
@@ -147,7 +148,10 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     }
 
     private void addNewElement(){
-        //TODO Implement this method
+        Intent intent = new Intent(getActivity(), ElementActivity.class);
+        intent.putExtra(Static.DATABASE_NAME_ARG,databaseName);
+        intent.putExtra(Static.TABLE_NAME_ARG,tableName);
+        startActivity(intent);
     }
 
     @Override
diff --git a/app/src/main/res/layout/fragment_element.xml b/app/src/main/res/layout/fragment_element.xml
index 987aad8..3e9e223 100644
--- a/app/src/main/res/layout/fragment_element.xml
+++ b/app/src/main/res/layout/fragment_element.xml
@@ -2,5 +2,22 @@
 
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent" android:layout_height="match_parent">
+    <ProgressBar
+        style="?android:attr/progressBarStyleHorizontal"
+        android:indeterminate="true"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:id="@+id/progressBar"
+        android:layout_centerHorizontal="true"
+        android:layout_alignParentTop="false"
+        android:layout_marginTop="-7dp" />
+
+    <ListView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/listView"
+        android:layout_below="@+id/progressBar"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentStart="true" />
 
 </RelativeLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/list_item_element_simple.xml b/app/src/main/res/layout/list_item_element_simple.xml
new file mode 100644
index 0000000..3e1dcc0
--- /dev/null
+++ b/app/src/main/res/layout/list_item_element_simple.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="New Text"
+        android:id="@+id/textFieldName"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentStart="true" />
+
+    <EditText
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:id="@+id/editFieldValue"
+        android:layout_below="@+id/textFieldName"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentStart="true" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/app/src/main/res/menu/element.xml b/app/src/main/res/menu/element.xml
index 7109817..8f2cd4b 100644
--- a/app/src/main/res/menu/element.xml
+++ b/app/src/main/res/menu/element.xml
@@ -1,8 +1,10 @@
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    tools:context="info.nerull7.mysqlbrowser.ElementActivity" >
-    <item android:id="@+id/action_settings"
-        android:title="@string/action_settings"
-        android:orderInCategory="100"
-        android:showAsAction="never" />
+<?xml version="1.0" encoding="utf-8"?>
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item android:id="@+id/action_save"
+        android:title="@string/action_save"
+        android:showAsAction="always"
+        android:icon="@drawable/ic_action_save"/>
+
 </menu>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 3e85dfd..06015be 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -33,5 +33,6 @@
     <string name="no_connection">No Internet Connection</string>
     <string name="action_add">Add new</string>
     <string name="title_activity_element">ElementActivity</string>
+    <string name="action_save">Save</string>
 
 </resources>

From 6ca1cacda5ead4dc233dcb3a86e2d3de503f1007 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 6 Aug 2014 15:20:59 +0200
Subject: [PATCH 12/59] Merge two activities into one

DatabaseActivity and TableActivity is now ListActivity!
---
 app/src/main/AndroidManifest.xml              |  8 +---
 .../mysqlbrowser/DatabaseFragment.java        |  3 +-
 ...atabaseActivity.java => ListActivity.java} | 18 ++++++--
 .../nerull7/mysqlbrowser/LoginFragment.java   | 15 +-----
 .../info/nerull7/mysqlbrowser/Static.java     |  4 ++
 .../nerull7/mysqlbrowser/TableActivity.java   | 46 -------------------
 app/src/main/res/layout/activity_database.xml |  7 ---
 .../{activity_table.xml => activity_list.xml} |  2 +-
 app/src/main/res/values/strings.xml           |  4 +-
 9 files changed, 28 insertions(+), 79 deletions(-)
 rename app/src/main/java/info/nerull7/mysqlbrowser/{DatabaseActivity.java => ListActivity.java} (58%)
 delete mode 100644 app/src/main/java/info/nerull7/mysqlbrowser/TableActivity.java
 delete mode 100644 app/src/main/res/layout/activity_database.xml
 rename app/src/main/res/layout/{activity_table.xml => activity_list.xml} (81%)

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ba08ea4..792b2c8 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -18,12 +18,8 @@
             </intent-filter>
         </activity>
         <activity
-            android:name=".DatabaseActivity"
-            android:label="@string/title_activity_database" >
-        </activity>
-        <activity
-            android:name=".TableActivity"
-            android:label="@string/title_activity_table" >
+            android:name=".ListActivity"
+            android:label="@string/title_activity_list" >
         </activity>
         <activity
             android:name=".EntriesActivity"
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
index 21d4671..d02e088 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
@@ -48,7 +48,8 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic
         if(Static.isNetworkConnected(getActivity())) {
             String chosenDatabase = (String) listAdapter.getItem(position);
             listAdapter.getItem(position);
-            Intent intent = new Intent(getActivity(), TableActivity.class);
+            Intent intent = new Intent(getActivity(), ListActivity.class);
+            intent.putExtra(Static.FRAGMENT_TO_START, Static.FRAGMENT_TABLE);
             intent.putExtra(Static.DATABASE_NAME_ARG, chosenDatabase);
             Static.asyncDatabaseConnector.setDatabaseInUse(chosenDatabase);
             startActivity(intent);
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java
similarity index 58%
rename from app/src/main/java/info/nerull7/mysqlbrowser/DatabaseActivity.java
rename to app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java
index 0449410..e2863fd 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseActivity.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java
@@ -1,19 +1,31 @@
 package info.nerull7.mysqlbrowser;
 
 import android.app.Activity;
+import android.app.Fragment;
 import android.os.Bundle;
 import android.view.Menu;
 import android.view.MenuItem;
 
-public class DatabaseActivity extends Activity {
+public class ListActivity extends Activity {
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_database);
+        setContentView(R.layout.activity_list);
+        Bundle extras = getIntent().getExtras();
+        String fragmentName = extras.getString(Static.FRAGMENT_TO_START);
+        Fragment fragment = null;
+        if(fragmentName.compareTo(Static.FRAGMENT_DATABASE)==0){
+            fragment = new DatabaseFragment();
+            setTitle(R.string.title_fragment_database);
+        } else if (fragmentName.compareTo(Static.FRAGMENT_TABLE)==0) {
+            fragment = new TableFragment();
+            setTitle(extras.getString(Static.DATABASE_NAME_ARG));
+        }
+        fragment.setArguments(getIntent().getExtras());
         if (savedInstanceState == null) {
             getFragmentManager().beginTransaction()
-                    .add(R.id.container, new DatabaseFragment())
+                    .add(R.id.container, fragment)
                     .commit();
         }
     }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
index 41cb054..d296709 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
@@ -1,15 +1,10 @@
 package info.nerull7.mysqlbrowser;
 
-import android.app.AlertDialog;
 import android.app.Fragment;
-import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
-import android.preference.Preference;
 import android.preference.PreferenceManager;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -17,13 +12,6 @@ import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ProgressBar;
 
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-
 import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
 
 /**
@@ -101,7 +89,8 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
     public void onBooleanReturn(boolean result) {
         if(result) {
             Static.asyncDatabaseConnector = asyncDatabaseConnector;
-            Intent intent = new Intent(getActivity(), DatabaseActivity.class);
+            Intent intent = new Intent(getActivity(), ListActivity.class);
+            intent.putExtra(Static.FRAGMENT_TO_START, Static.FRAGMENT_DATABASE);
             startActivity(intent);
         }
         else {
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
index 1013bec..4517e51 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
@@ -18,6 +18,10 @@ public class Static {
     public static final String DATABASE_NAME_ARG = "DatabaseName";
     public static final String TABLE_NAME_ARG = "TableName";
 
+    public static final String FRAGMENT_TO_START = "FragmentStarter";
+    public static final String FRAGMENT_DATABASE = "DatabaseFragment";
+    public static final String FRAGMENT_TABLE = "TableFragment";
+
     public static AsyncDatabaseConnector asyncDatabaseConnector = null;
 
     public static void startSettings(Context context){
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/TableActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/TableActivity.java
deleted file mode 100644
index e4c8256..0000000
--- a/app/src/main/java/info/nerull7/mysqlbrowser/TableActivity.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package info.nerull7.mysqlbrowser;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
-
-public class TableActivity extends Activity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_table);
-        setTitle(getIntent().getStringExtra(Static.DATABASE_NAME_ARG));
-
-        TableFragment tableFragment = new TableFragment();
-        tableFragment.setArguments(getIntent().getExtras());
-        if (savedInstanceState == null) {
-            getFragmentManager().beginTransaction()
-                    .add(R.id.container, tableFragment)
-                    .commit();
-        }
-    }
-
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.main, menu);
-        return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        // Handle action bar item clicks here. The action bar will
-        // automatically handle clicks on the Home/Up button, so long
-        // as you specify a parent activity in AndroidManifest.xml.
-
-        int id = item.getItemId();
-        if (id == R.id.action_settings) {
-            Static.startSettings(this);
-            return true;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
-}
diff --git a/app/src/main/res/layout/activity_database.xml b/app/src/main/res/layout/activity_database.xml
deleted file mode 100644
index c4d324d..0000000
--- a/app/src/main/res/layout/activity_database.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.DatabaseActivity"
-    tools:ignore="MergeRootFrame" />
diff --git a/app/src/main/res/layout/activity_table.xml b/app/src/main/res/layout/activity_list.xml
similarity index 81%
rename from app/src/main/res/layout/activity_table.xml
rename to app/src/main/res/layout/activity_list.xml
index e80cef3..43ab1db 100644
--- a/app/src/main/res/layout/activity_table.xml
+++ b/app/src/main/res/layout/activity_list.xml
@@ -3,5 +3,5 @@
     android:id="@+id/container"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    tools:context="info.nerull7.mysqlbrowser.TableActivity"
+    tools:context="info.nerull7.mysqlbrowser.ListActivity"
     tools:ignore="MergeRootFrame" />
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 06015be..dc7ea10 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -8,12 +8,10 @@
     <string name="username">Username</string>
     <string name="hint_url">URL ex: https://example.com/c.php</string>
     <string name="title_activity_main">MainActivity</string>
-    <string name="title_activity_database">DatabaseActivity</string>
     <string name="hello_world">Hello world!</string>
     <string name="login_error">Wrong login/password</string>
     <string name="ok">OK</string>
     <string name="error">Error</string>
-    <string name="title_activity_table">TableActivity</string>
     <string name="title_activity_entries">EntriesActivity</string>
     <string name="general_category">General</string>
     <string name="entries_limit">Entries per page limit</string>
@@ -34,5 +32,7 @@
     <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>
 
 </resources>

From f5b99dbc71fa79c64a002750b2c6ce296cba17dc Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 6 Aug 2014 18:27:03 +0200
Subject: [PATCH 13/59] Warning message on not saving

 Warning message when you cancel saving new entry into database
---
 .../nerull7/mysqlbrowser/ElementActivity.java | 26 +++++++++++++++++++
 app/src/main/res/values/strings.xml           |  3 +++
 2 files changed, 29 insertions(+)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java
index 28c0fe8..e78073f 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java
@@ -1,6 +1,10 @@
 package info.nerull7.mysqlbrowser;
 
 import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
 import android.os.Bundle;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -25,4 +29,26 @@ public class ElementActivity extends Activity {
                     .commit();
         }
     }
+
+    @Override
+    public void onBackPressed() {
+        AlertDialog.Builder builder = new AlertDialog.Builder(this);
+        builder.setMessage(getString(R.string.error_no_save));
+        builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+
+            }
+        });
+        builder.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                finish();
+            }
+        });
+        builder.setTitle(R.string.warning);
+        builder.setIcon(R.drawable.ic_action_warning);
+        builder.create();
+        builder.show();
+    }
 }
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index dc7ea10..7cf7543 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -34,5 +34,8 @@
     <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>
 
 </resources>

From bfc1203e44d1c85182d819b0a33c3b538a9ea446 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 13 Aug 2014 00:17:03 +0200
Subject: [PATCH 14/59] Editing entries

---
 .../mysqlbrowser/ElementArrayAdapter.java     | 20 ++++++++---
 .../nerull7/mysqlbrowser/ElementFragment.java | 11 +++++-
 .../nerull7/mysqlbrowser/EntriesFragment.java | 36 +++++++++++++++++--
 app/src/main/res/layout/fragment_entries.xml  |  5 ++-
 4 files changed, 61 insertions(+), 11 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
index 2579937..95bcd35 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
@@ -5,6 +5,7 @@ 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.List;
@@ -14,14 +15,21 @@ import java.util.List;
  */
 public class ElementArrayAdapter extends ArrayAdapter<String> {
     private Context context;
+    private List<String> fields;
     private List<String> values;
     private int layout;
 
-    public ElementArrayAdapter(Context context, int resource, List<String> objects) {
-        super(context, resource, objects);
+    public ElementArrayAdapter(Context context, int resource, List<String> fields) {
+        super(context, resource, fields);
         this.context = context;
-        values = objects;
+        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
@@ -30,7 +38,11 @@ public class ElementArrayAdapter extends ArrayAdapter<String> {
         View rowView = layoutInflater.inflate(layout, parent, false);
 
         TextView textView = (TextView) rowView.findViewById(R.id.textFieldName);
-        textView.setText(values.get(position));
+        textView.setText(fields.get(position));
+        if(values != null){
+            EditText textFieldName = (EditText) rowView.findViewById(R.id.editFieldValue);
+            textFieldName.setText(values.get(position));
+        }
 
         return rowView;
     }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
index ed62562..886ae34 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
@@ -23,6 +23,9 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
  * Created by nerull7 on 2014-08-06.
  */
 public class ElementFragment extends Fragment implements AsyncDatabaseConnector.ListReturnListener {
+    public static final String EDIT_ELEMENT = "edit_element";
+    public static final String EDIT_LIST = "edit_element_list";
+
     private String databaseName;
     private String tableName;
     private ListAdapter listAdapter;
@@ -30,6 +33,8 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
     private ProgressBar progressBar;
     private ListView listView;
 
+    private List<String> values;
+
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         //Inflate the layout for this fragment
@@ -48,6 +53,10 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
     private void initArguments() {
         databaseName = getArguments().getString(Static.DATABASE_NAME_ARG);
         tableName = getArguments().getString(Static.TABLE_NAME_ARG);
+        if(getArguments().getBoolean(EDIT_ELEMENT))
+            values = getArguments().getStringArrayList(EDIT_LIST);
+        else
+            values = null;
     }
 
     @Override
@@ -58,7 +67,7 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
 
     @Override
     public void onListReturn(List<String> fields) {
-        listAdapter = new ElementArrayAdapter(getActivity(), R.layout.list_item_element_simple, fields);
+        listAdapter = new ElementArrayAdapter(getActivity(), R.layout.list_item_element_simple, fields, values);
         listView.setAdapter(listAdapter);
 //        databasesListView.setAdapter(listAdapter);
 //        databasesListView.setOnItemClickListener(this);
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index ad186ab..d746a5b 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -1,10 +1,17 @@
 package info.nerull7.mysqlbrowser;
 
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
 import android.app.Fragment;
 import android.content.Intent;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
 import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -12,6 +19,7 @@ import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
 import android.widget.FrameLayout;
 import android.widget.HorizontalScrollView;
 import android.widget.ProgressBar;
@@ -21,6 +29,9 @@ import android.widget.TableLayout;
 import android.widget.TableRow;
 import android.widget.TextView;
 
+import org.w3c.dom.Text;
+
+import java.util.ArrayList;
 import java.util.List;
 
 import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
@@ -28,7 +39,7 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
 /**
  * Created by nerull7 on 15.07.14.
  */
-public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.MatrixReturnListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.IntegerReturnListener {
+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;
@@ -51,6 +62,7 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     private int entriesLimit;
     private int page;
     private int pageCount;
+    private int rowCount;
     private ProgressBar progressBar;
     private CustomScrollView fakeScrollView;
     private View dummyView;
@@ -96,8 +108,7 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         fakeScrollView.setOnTouchEventListener(new CustomScrollView.OnTouchEventListener() {
             @Override
             public boolean onTouchEvent(MotionEvent ev) {
-                entriesScrollView.onTouchEvent(ev);
-                horizontalScrollView.onTouchEvent(ev);
+                entriesScrollView.dispatchTouchEvent(ev);
                 return true;
             }
         });
@@ -197,8 +208,11 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
                     textView.setLayoutParams(layoutParams);
                     textView.setPadding(ENTRIES_PADDING_LEFT, ENTRIES_PADDING_TOP, ENTRIES_PADDING_RIGHT, ENTRIES_PADDING_BOTTOM);
                     textView.setBackgroundResource(background);
+                    textView.setId(j);
                     newRow.addView(textView);
                 }
+                newRow.setClickable(true);
+                newRow.setOnClickListener(this);
                 entriesTable.addView(newRow);
 
                 syncWidths();
@@ -222,6 +236,7 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         // First we need header
         headerRow = new TableRow(getActivity());
         headerRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
+        rowCount = fieldList.size();
         for(int i =0;i<fieldList.size();i++){
             TextView textView = new TextView(getActivity());
             textView.setText(fieldList.get(i));
@@ -290,5 +305,20 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         fakeScrollView.setLayoutParams(fakeScrollLayout);
     }
 
+    @Override
+    public void onClick(View view) {
+        ArrayList<String> values = new ArrayList<String>();
+        for(int i=0;i<rowCount;i++){
+            TextView element =  (TextView)view.findViewById(i);
+            values.add(element.getText().toString());
+//            element.setBackgroundResource(android.R.color.holo_blue_bright);
+        }
 
+        Intent intent = new Intent(getActivity(), ElementActivity.class);
+        intent.putExtra(Static.DATABASE_NAME_ARG,databaseName);
+        intent.putExtra(Static.TABLE_NAME_ARG,tableName);
+        intent.putExtra(ElementFragment.EDIT_ELEMENT, true);
+        intent.putStringArrayListExtra(ElementFragment.EDIT_LIST, values);
+        startActivity(intent);
+    }
 }
diff --git a/app/src/main/res/layout/fragment_entries.xml b/app/src/main/res/layout/fragment_entries.xml
index b573ad0..3ed823a 100644
--- a/app/src/main/res/layout/fragment_entries.xml
+++ b/app/src/main/res/layout/fragment_entries.xml
@@ -5,8 +5,8 @@
     tools:context="info.nerull7.mysqlbrowser.EntriesFragment">
 
     <HorizontalScrollView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
         android:id="@+id/horizontalScrollView" >
 
         <RelativeLayout
@@ -48,7 +48,6 @@
     <info.nerull7.mysqlbrowser.CustomScrollView
         android:layout_width="wrap_content"
         android:layout_height="fill_parent"
-        android:layout_below="@+id/loginProgressBar"
         android:layout_alignParentRight="true"
         android:foregroundGravity="right"
         android:id="@+id/fakeScroll"

From d4a1de33820be0fcb53d0ecf242cbab386e18120 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 13 Aug 2014 00:27:16 +0200
Subject: [PATCH 15/59] Refresh credentials

after changes done in settings
---
 .../main/java/info/nerull7/mysqlbrowser/LoginFragment.java | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
index d296709..15edaa4 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
@@ -45,6 +45,13 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
         return rootView;
     }
 
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        processCredentials();
+    }
+
     private void processCredentials() {
         SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
 

From 7f08209668508944b12a6223ae068c34f4369628 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 13 Aug 2014 01:20:18 +0200
Subject: [PATCH 16/59] Fix not scrolling horizontally

---
 app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index d746a5b..dab215e 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -109,6 +109,7 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
             @Override
             public boolean onTouchEvent(MotionEvent ev) {
                 entriesScrollView.dispatchTouchEvent(ev);
+                horizontalScrollView.onTouchEvent(ev);
                 return true;
             }
         });

From da9a01ce2493021575812a3ead5e185e3a4ec5da Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 13 Aug 2014 01:34:06 +0200
Subject: [PATCH 17/59] Fix scrolling and pressing

---
 .../main/java/info/nerull7/mysqlbrowser/EntriesFragment.java  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index dab215e..361f34f 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -108,8 +108,8 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         fakeScrollView.setOnTouchEventListener(new CustomScrollView.OnTouchEventListener() {
             @Override
             public boolean onTouchEvent(MotionEvent ev) {
-                entriesScrollView.dispatchTouchEvent(ev);
-                horizontalScrollView.onTouchEvent(ev);
+                ev.offsetLocation(0, headerFrame.getHeight());
+                horizontalScrollView.dispatchTouchEvent(ev);
                 return true;
             }
         });

From 43f1acb73682e2c663710f1871f44870e17c368d Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Sat, 16 Aug 2014 18:37:55 +0200
Subject: [PATCH 18/59] Add and update entries!

---
 .../mysqlbrowser/ElementArrayAdapter.java     |  9 ++++
 .../nerull7/mysqlbrowser/ElementFragment.java | 38 ++++++++++++++++-
 .../db/AsyncDatabaseConnector.java            | 42 +++++++++++++++++++
 3 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
index 95bcd35..f532ff5 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
@@ -8,6 +8,7 @@ import android.widget.ArrayAdapter;
 import android.widget.EditText;
 import android.widget.TextView;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -46,4 +47,12 @@ public class ElementArrayAdapter extends ArrayAdapter<String> {
 
         return rowView;
     }
+
+    public List<String> getFieldArray(){
+        return fields;
+    }
+
+    public List<String> getValueArray(){
+        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 886ae34..b9cb5c3 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
@@ -7,14 +7,17 @@ import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
+import android.widget.EditText;
 import android.widget.ListAdapter;
 import android.widget.ListView;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
@@ -22,13 +25,13 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
 /**
  * Created by nerull7 on 2014-08-06.
  */
-public class ElementFragment extends Fragment implements AsyncDatabaseConnector.ListReturnListener {
+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 String databaseName;
     private String tableName;
-    private ListAdapter listAdapter;
+    private ElementArrayAdapter listAdapter;
 
     private ProgressBar progressBar;
     private ListView listView;
@@ -50,6 +53,22 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
         return rootView;
     }
 
+    @Override
+    public boolean onOptionsItemSelected(MenuItem 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);
+        }
+    }
+
     private void initArguments() {
         databaseName = getArguments().getString(Static.DATABASE_NAME_ARG);
         tableName = getArguments().getString(Static.TABLE_NAME_ARG);
@@ -76,4 +95,19 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
         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) { //TODO Better UI handling
+        Static.showErrorAlert(data,getActivity());
+        getActivity().finish();
+    }
 }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index 2065aea..8ed0c03 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -5,6 +5,7 @@ import android.util.Log;
 
 import org.json.JSONArray;
 import org.json.JSONException;
+import org.json.JSONObject;
 
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -25,6 +26,8 @@ public class AsyncDatabaseConnector {
     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;
@@ -169,6 +172,43 @@ public class AsyncDatabaseConnector {
         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(int i=0;i<header.size();i++){
+            headerJSON.put(header.get(i));
+        }
+
+        for(int i=0;i<newValues.size();i++){
+            newValuesJSON.put(newValues.get(i));
+        }
+
+        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;
     }
@@ -227,6 +267,8 @@ public class AsyncDatabaseConnector {
             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);

From ebdc1bc86d3b6b28b4f94fde70616da82df6f683 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Sun, 17 Aug 2014 12:52:59 +0200
Subject: [PATCH 19/59] New AlertDialog for Update/Add element

---
 .../nerull7/mysqlbrowser/ElementFragment.java | 24 ++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
index b9cb5c3..39cb4a5 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
@@ -1,7 +1,9 @@
 package info.nerull7.mysqlbrowser;
 
+import android.app.AlertDialog;
 import android.app.Fragment;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.graphics.Typeface;
 import android.os.Bundle;
 import android.view.LayoutInflater;
@@ -106,8 +108,24 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
     }
 
     @Override
-    public void onStringReturn(String data) { //TODO Better UI handling
-        Static.showErrorAlert(data,getActivity());
-        getActivity().finish();
+    public void onStringReturn(String data) {
+        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+        builder.setMessage(data);
+        builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialogInterface, int i) {
+                getActivity().finish();
+            }
+        });
+        /*builder.setNegativeButton(R.string.back, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialogInterface, int i) {
+                // Nothing to do just get back
+            }
+        });*/
+        builder.setTitle(R.string.status);
+        builder.setIcon(R.drawable.ic_action_warning); //TODO Change Icon
+        builder.create();
+        builder.show();
     }
 }

From f050abc968574ac18d1372b01bce1412e6f8efbd Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Sun, 17 Aug 2014 13:00:12 +0200
Subject: [PATCH 20/59] Add missing strings

---
 app/src/main/res/values/strings.xml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7cf7543..db2bbf2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -37,5 +37,7 @@
     <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>

From b52e80f7767d338a8f48b032115a23190ad1c33e Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Sun, 17 Aug 2014 13:00:47 +0200
Subject: [PATCH 21/59] Remove unused imports

---
 .../main/java/info/nerull7/mysqlbrowser/Crypto.java    |  5 -----
 .../info/nerull7/mysqlbrowser/ElementActivity.java     |  5 -----
 .../info/nerull7/mysqlbrowser/ElementArrayAdapter.java |  1 -
 .../info/nerull7/mysqlbrowser/ElementFragment.java     |  5 -----
 .../info/nerull7/mysqlbrowser/EntriesActivity.java     |  5 -----
 .../info/nerull7/mysqlbrowser/EntriesFragment.java     | 10 ----------
 .../java/info/nerull7/mysqlbrowser/MainActivity.java   |  1 -
 .../info/nerull7/mysqlbrowser/SettingsActivity.java    |  2 --
 .../info/nerull7/mysqlbrowser/SettingsFragment.java    |  7 -------
 .../main/java/info/nerull7/mysqlbrowser/Static.java    |  2 --
 .../java/info/nerull7/mysqlbrowser/TableFragment.java  |  1 -
 .../mysqlbrowser/db/AsyncDatabaseConnector.java        |  1 -
 12 files changed, 45 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/Crypto.java b/app/src/main/java/info/nerull7/mysqlbrowser/Crypto.java
index e22105a..7f93f0d 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/Crypto.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/Crypto.java
@@ -2,21 +2,17 @@ package info.nerull7.mysqlbrowser;
 
 import android.content.Context;
 import android.util.Base64;
-import android.util.Log;
 
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.nio.charset.Charset;
 import java.security.InvalidKeyException;
-import java.security.Key;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
-import java.security.spec.KeySpec;
 
 import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
@@ -24,7 +20,6 @@ import javax.crypto.IllegalBlockSizeException;
 import javax.crypto.KeyGenerator;
 import javax.crypto.NoSuchPaddingException;
 import javax.crypto.SecretKey;
-import javax.crypto.spec.PBEKeySpec;
 
 /**
  * Created by nerull7 on 28.07.14.
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java
index e78073f..2034810 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementActivity.java
@@ -2,13 +2,8 @@ package info.nerull7.mysqlbrowser;
 
 import android.app.Activity;
 import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
-import info.nerull7.mysqlbrowser.R;
 
 public class ElementActivity extends Activity {
 
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
index f532ff5..1793468 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
@@ -8,7 +8,6 @@ import android.widget.ArrayAdapter;
 import android.widget.EditText;
 import android.widget.TextView;
 
-import java.util.ArrayList;
 import java.util.List;
 
 /**
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
index 39cb4a5..a151fdd 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
@@ -2,9 +2,7 @@ package info.nerull7.mysqlbrowser;
 
 import android.app.AlertDialog;
 import android.app.Fragment;
-import android.content.Context;
 import android.content.DialogInterface;
-import android.graphics.Typeface;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -12,12 +10,9 @@ import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
 import android.widget.EditText;
-import android.widget.ListAdapter;
 import android.widget.ListView;
 import android.widget.ProgressBar;
-import android.widget.TextView;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesActivity.java
index db98696..c783710 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesActivity.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesActivity.java
@@ -2,11 +2,6 @@ package info.nerull7.mysqlbrowser;
 
 import android.app.Activity;
 import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-
-import java.util.zip.Inflater;
 
 public class EntriesActivity extends Activity {
 
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index 361f34f..fa41427 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -1,17 +1,10 @@
 package info.nerull7.mysqlbrowser;
 
-import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
 import android.app.Fragment;
 import android.content.Intent;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
 import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -19,7 +12,6 @@ import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
 import android.widget.FrameLayout;
 import android.widget.HorizontalScrollView;
 import android.widget.ProgressBar;
@@ -29,8 +21,6 @@ import android.widget.TableLayout;
 import android.widget.TableRow;
 import android.widget.TextView;
 
-import org.w3c.dom.Text;
-
 import java.util.ArrayList;
 import java.util.List;
 
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/MainActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/MainActivity.java
index f5c394c..d70a46f 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/MainActivity.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/MainActivity.java
@@ -1,7 +1,6 @@
 package info.nerull7.mysqlbrowser;
 
 import android.app.Activity;
-import android.content.Intent;
 import android.os.Bundle;
 import android.view.Menu;
 import android.view.MenuItem;
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/SettingsActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/SettingsActivity.java
index 3e84b0e..d572c3f 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/SettingsActivity.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/SettingsActivity.java
@@ -1,7 +1,5 @@
 package info.nerull7.mysqlbrowser;
 
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
 import android.os.Bundle;
 import android.preference.PreferenceActivity;
 
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java
index 612337a..ba386a4 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java
@@ -9,13 +9,6 @@ import android.preference.PreferenceFragment;
 import android.preference.PreferenceScreen;
 import android.util.Base64;
 
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-
 /**
  * Created by nerull7 on 18.07.14.
  */
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
index 4517e51..6e59148 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
@@ -7,8 +7,6 @@ import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 
-import java.net.NetworkInterface;
-
 import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
 
 /**
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
index 91d63f7..8a63cd4 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
@@ -7,7 +7,6 @@ import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewParent;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
 import android.widget.ListAdapter;
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index 8ed0c03..2827020 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -5,7 +5,6 @@ import android.util.Log;
 
 import org.json.JSONArray;
 import org.json.JSONException;
-import org.json.JSONObject;
 
 import java.io.BufferedReader;
 import java.io.IOException;

From db3361b390befd49f7db0441e4f9b457861e3b7b Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Sun, 17 Aug 2014 13:10:01 +0200
Subject: [PATCH 22/59] Fix AsyncDatabaseConnector warnings

---
 .../mysqlbrowser/db/AsyncDatabaseConnector.java      | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index 2827020..d8a0261 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -17,6 +17,7 @@ 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";
@@ -123,7 +124,6 @@ public class AsyncDatabaseConnector {
         Downloader downloader = new Downloader(new Downloader.OnFinishedListener() {
             @Override
             public void onFinished(String data, String error) {
-                List<String>list = null;
                 boolean listenerData;
                 if(data == null) {
                     listenerData = false;
@@ -180,12 +180,12 @@ public class AsyncDatabaseConnector {
         JSONArray newValuesJSON = new JSONArray();
         String request;
 
-        for(int i=0;i<header.size();i++){
-            headerJSON.put(header.get(i));
+        for (String aHeader : header) {
+            headerJSON.put(aHeader);
         }
 
-        for(int i=0;i<newValues.size();i++){
-            newValuesJSON.put(newValues.get(i));
+        for (String newValue : newValues) {
+            newValuesJSON.put(newValue);
         }
 
         if(oldValues!=null){
@@ -296,7 +296,7 @@ public class AsyncDatabaseConnector {
             BufferedReader reader = null;
             try {
                 reader = new BufferedReader(new InputStreamReader(in));
-                String line = "";
+                String line;
                 while ((line = reader.readLine()) != null) {
                     streamOutput += line;
                 }

From 2c42713d2b7ad4350d53d6493bfa612f1317bd29 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Sun, 17 Aug 2014 13:26:44 +0200
Subject: [PATCH 23/59] Fix ElementFragment warnings

---
 .../main/java/info/nerull7/mysqlbrowser/ElementFragment.java  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
index a151fdd..898c6ba 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
@@ -21,12 +21,13 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
 
 /**
  * Created by nerull7 on 2014-08-06.
+ *
+ * Fragment for editing/adding elements
  */
 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 String databaseName;
     private String tableName;
     private ElementArrayAdapter listAdapter;
 
@@ -67,7 +68,6 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
     }
 
     private void initArguments() {
-        databaseName = getArguments().getString(Static.DATABASE_NAME_ARG);
         tableName = getArguments().getString(Static.TABLE_NAME_ARG);
         if(getArguments().getBoolean(EDIT_ELEMENT))
             values = getArguments().getStringArrayList(EDIT_LIST);

From 3bc4da929732cfcd6ac7fad6d2e04079f1f6be8f Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Sun, 17 Aug 2014 13:29:26 +0200
Subject: [PATCH 24/59] Fix EntriesFragment warnings

---
 .../info/nerull7/mysqlbrowser/EntriesFragment.java    | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index fa41427..53f7e40 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -28,6 +28,8 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
 
 /**
  * Created by nerull7 on 15.07.14.
+ *
+ * Fragment for showing elements
  */
 public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.MatrixReturnListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.IntegerReturnListener, View.OnClickListener {
     private static final int HEADER_PADDING_TOP = 15;
@@ -42,10 +44,8 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     private TableLayout entriesTable;
     private ScrollView entriesScrollView;
     private FrameLayout headerFrame;
-    private RelativeLayout rootView;
     private HorizontalScrollView horizontalScrollView;
     private TableRow.LayoutParams layoutParams;
-    private TableRow headerRow;
 
     private String databaseName;
     private String tableName;
@@ -93,8 +93,6 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         dummyView = rootView.findViewById(R.id.dummyView);
         horizontalScrollView = (HorizontalScrollView) rootView.findViewById(R.id.horizontalScrollView);
 
-        this.rootView = (RelativeLayout) rootView;
-
         fakeScrollView.setOnTouchEventListener(new CustomScrollView.OnTouchEventListener() {
             @Override
             public boolean onTouchEvent(MotionEvent ev) {
@@ -225,12 +223,13 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     @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();
-        for(int i =0;i<fieldList.size();i++){
+        for (String aFieldList : fieldList) {
             TextView textView = new TextView(getActivity());
-            textView.setText(fieldList.get(i));
+            textView.setText(aFieldList);
             textView.setTypeface(null, Typeface.BOLD);
             textView.setLayoutParams(layoutParams);
             textView.setBackgroundResource(R.drawable.background_header);

From 1623340a77ec5b28041deb174ccaf678e9da88a5 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Sun, 17 Aug 2014 13:51:16 +0200
Subject: [PATCH 25/59] Fix LoginFragment warnings

---
 .../main/java/info/nerull7/mysqlbrowser/LoginFragment.java    | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
index 15edaa4..73e145d 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
@@ -16,6 +16,8 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
 
 /**
  * Created by nerull7 on 07.07.14.
+ *
+ * Fragment for login
  */
 public class LoginFragment extends Fragment implements View.OnClickListener, AsyncDatabaseConnector.BooleanReturnListener {
     private EditText urlTextbox;
@@ -101,7 +103,7 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
             startActivity(intent);
         }
         else {
-            Static.showErrorAlert(Static.asyncDatabaseConnector.errorMsg, getActivity());
+            Static.showErrorAlert(AsyncDatabaseConnector.errorMsg, getActivity());
         }
         loginButton.setEnabled(true); // Now we can click button again
         progressBar.setVisibility(View.INVISIBLE);

From 68dc0893ca5823186cbc08e0d92d0f3803cb0500 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Sun, 17 Aug 2014 16:06:12 +0200
Subject: [PATCH 26/59] Some fixes

---
 app/app.iml                                   | 20 ++++++++++++++++++-
 .../info/nerull7/mysqlbrowser/Crypto.java     | 15 ++++++--------
 .../mysqlbrowser/ElementArrayAdapter.java     |  4 ----
 .../mysqlbrowser/SettingsFragment.java        |  9 ++++++---
 4 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/app/app.iml b/app/app.iml
index 219a04b..20413bf 100644
--- a/app/app.iml
+++ b/app/app.iml
@@ -56,7 +56,25 @@
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
-      <excludeFolder url="file://$MODULE_DIR$/build/intermediates" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
       <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
     </content>
     <orderEntry type="jdk" jdkName="Android API 19 Platform" jdkType="Android SDK" />
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/Crypto.java b/app/src/main/java/info/nerull7/mysqlbrowser/Crypto.java
index 7f93f0d..0ad320e 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/Crypto.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/Crypto.java
@@ -23,6 +23,8 @@ import javax.crypto.SecretKey;
 
 /**
  * Created by nerull7 on 28.07.14.
+ *
+ * Class delegated to encrypt data
  */
 public class Crypto {
     private static final String KEY_FILE = "null_file"; // to trick h4x0r5
@@ -44,23 +46,19 @@ public class Crypto {
         }
     }
 
-    private SecretKey generateKey() throws NoSuchAlgorithmException {
+    private void generateKey() throws NoSuchAlgorithmException {
         SecureRandom secureRandom = new SecureRandom();
 
         KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
         keyGenerator.init(OUTPUT_KEY_LENGTH, secureRandom);
-        SecretKey secretKey = keyGenerator.generateKey();
-
-        return secretKey;
+        secretKey = keyGenerator.generateKey();
     }
 
     private void getSecretKey() throws NoSuchAlgorithmException, IOException, ClassNotFoundException {
-        String key;
-
         // First try to open file
         File keyFile = new File(context.getFilesDir(), KEY_FILE);
         if(!keyFile.exists()) { // new key
-            secretKey = generateKey();
+            generateKey();
             FileOutputStream fileOutputStream =  new FileOutputStream(keyFile);
             ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
             objectOutputStream.writeObject(secretKey);
@@ -95,7 +93,6 @@ public class Crypto {
 
     public String decryptBase64(String encodedString) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
         byte [] encryptedString = Base64.decode(encodedString, Base64.DEFAULT);
-        String decrypted = decrypt(encryptedString);
-        return decrypted;
+        return decrypt(encryptedString);
     }
 }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
index 1793468..5f4c427 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
@@ -50,8 +50,4 @@ public class ElementArrayAdapter extends ArrayAdapter<String> {
     public List<String> getFieldArray(){
         return fields;
     }
-
-    public List<String> getValueArray(){
-        return values;
-    }
 }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java
index ba386a4..b49d179 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java
@@ -6,11 +6,14 @@ import android.preference.CheckBoxPreference;
 import android.preference.EditTextPreference;
 import android.preference.Preference;
 import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
 import android.preference.PreferenceScreen;
 import android.util.Base64;
 
 /**
  * Created by nerull7 on 18.07.14.
+ *
+ * Fragment for Preferences/Settings
  */
 public class SettingsFragment extends PreferenceFragment implements NumberPickerDialog.OnNumberSetListener, Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
     public static final String ENTRIES_PAGE_LIMIT = "entries_limit";
@@ -35,7 +38,8 @@ public class SettingsFragment extends PreferenceFragment implements NumberPicker
     @Override
     public void onCreate(Bundle savedInstanceState){
         super.onCreate(savedInstanceState);
-        preferences = getPreferenceManager().getDefaultSharedPreferences(getActivity());
+        getPreferenceManager();
+        preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
         crypto = new Crypto(getActivity());
 
         loadPrefs();
@@ -70,7 +74,6 @@ public class SettingsFragment extends PreferenceFragment implements NumberPicker
         }
         editor.putBoolean(SAVE_SERVER_CREDENTIALS, isEnabled);
         editor.apply();
-        editor.commit();
 
         if(!isEnabled)
             reloadLoginPrefsView();
@@ -80,7 +83,7 @@ public class SettingsFragment extends PreferenceFragment implements NumberPicker
         saveCredentials.setChecked(preferences.getBoolean(SAVE_SERVER_CREDENTIALS, false));
         connectorUrlCredentials.setText(preferences.getString(URL_CREDENTIALS, null));
         loginCredentials.setText(preferences.getString(LOGIN_CREDENTIALS, null));
-        passwordCredentials.setText(preferences.getString(PASSWORD_CREDENTIALS, null));;
+        passwordCredentials.setText(preferences.getString(PASSWORD_CREDENTIALS, null));
     }
 
     private int getEntriesPageLimit(){

From f40ed114618e3ff27ee5a91733487f27a897be74 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Sun, 17 Aug 2014 22:17:54 +0200
Subject: [PATCH 27/59] Fix URL Encoding

---
 .../db/AsyncDatabaseConnector.java            | 88 +++++++++++++++++--
 1 file changed, 81 insertions(+), 7 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index d8a0261..8aeef5c 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -2,6 +2,7 @@ package info.nerull7.mysqlbrowser.db;
 
 import android.os.AsyncTask;
 import android.util.Log;
+import android.widget.ArrayAdapter;
 
 import org.json.JSONArray;
 import org.json.JSONException;
@@ -10,8 +11,10 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -54,11 +57,32 @@ public class AsyncDatabaseConnector {
         matrixReturnListener=null;
     }
 
-    private String actionUrlBuilder(String action){ // TODO Better UrlBuilder this is shit only for use
+    private String actionUrlBuilder(String action){
         String urlBuilder = url;
         urlBuilder += "?u="+login;
         urlBuilder += "&p="+password;
         urlBuilder += "&a="+action;
+
+        return urlBuilder;
+    }
+
+    private String 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 String actionUrlBuilder(String action, List<String> arguments, List<String> values){ // TODO Better UrlBuilder this is shit only for use
+        String urlBuilder = actionUrlBuilder(action);
+        for (int i = 0; i < arguments.size(); i++) {
+            try {
+                urlBuilder += "&" + arguments.get(i) + "=" + URLEncoder.encode(values.get(i), "UTF-8");
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace();
+            }
+        }
 //        Log.d("URLBuilder", urlBuilder);
         return urlBuilder;
     }
@@ -147,20 +171,53 @@ public class AsyncDatabaseConnector {
     }
 
     public void getTables(){
-        getList(actionUrlBuilder(ACTION_TABLE_LIST)+"&d="+database);
+        getList(actionUrlBuilder(ACTION_TABLE_LIST, "d", database));
     }
 
     public void getFields(String table){
-        getList(actionUrlBuilder(ACTION_FIELD_LIST)+"&d="+database+"&t="+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;
-        getMatrix(actionUrlBuilder(ACTION_DATA_MATRIX)+"&d="+database+"&t="+table+"&s="+limitStart+"&l="+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){
-        String urlQuery = actionUrlBuilder(ACTION_ENTRIES_COUNT)+"&d="+database+"&t="+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);
+
+        String urlQuery = actionUrlBuilder(ACTION_ENTRIES_COUNT, args, values);
         Downloader downloader = new Downloader(new Downloader.OnFinishedListener() {
             @Override
             public void onFinished(String data, String error) {
@@ -180,6 +237,15 @@ public class AsyncDatabaseConnector {
         JSONArray newValuesJSON = new JSONArray();
         String 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);
         }
@@ -188,14 +254,22 @@ public class AsyncDatabaseConnector {
             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));
             }
-            request = actionUrlBuilder(ACTION_UPDATE_ELEMENT)+"&d="+database+"&t="+table+"&h="+headerJSON+"&v="+newValuesJSON+"&o="+oldValuesJSON;
+            args.add("o");
+            values.add(oldValuesJSON.toString());
+            request = actionUrlBuilder(ACTION_UPDATE_ELEMENT, args, values);
         } else
-            request = actionUrlBuilder(ACTION_ADD_ELEMENT)+"&d="+database+"&t="+table+"&h="+headerJSON+"&v="+newValuesJSON;
+            request = actionUrlBuilder(ACTION_ADD_ELEMENT, args, values);
 
         Downloader downloader = new Downloader(new Downloader.OnFinishedListener() {
             @Override

From f691d83fab6edf947ce08efd915b81e63aa269a7 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Tue, 19 Aug 2014 23:06:07 +0200
Subject: [PATCH 28/59] Fix different fields height

---
 .../main/java/info/nerull7/mysqlbrowser/EntriesFragment.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index 53f7e40..670324e 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -102,7 +102,7 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
             }
         });
 
-        layoutParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT);
+        layoutParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.MATCH_PARENT);
         headerFrame.setVisibility(View.INVISIBLE);
         entriesTable.setVisibility(View.INVISIBLE);
     }

From 697c2e845a95e52b2047dceaf76b7840cf329285 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 01:30:50 +0200
Subject: [PATCH 29/59] More jobs on AsyncTask DO NOT MERGE

not finished yet.
---
 app/src/main/AndroidManifest.xml              |  3 ++
 .../mysqlbrowser/DatabaseFragment.java        |  9 +++-
 .../nerull7/mysqlbrowser/EntriesFragment.java | 34 +++++++++-----
 .../nerull7/mysqlbrowser/LoginFragment.java   | 10 ++--
 .../nerull7/mysqlbrowser/TableFragment.java   |  9 +++-
 .../db/AsyncDatabaseConnector.java            | 46 +++++++++++++++----
 6 files changed, 85 insertions(+), 26 deletions(-)

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 792b2c8..39f66fe 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -39,4 +39,7 @@
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+
 </manifest>
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
index d02e088..c70f172 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
@@ -24,11 +24,12 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
  *
  * Fragment for showing list of Available Databases for user
  */
-public class DatabaseFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener {
+public class DatabaseFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.OnPostExecuteListener {
     private ListView databasesListView;
     private ListAdapter listAdapter;
     private RelativeLayout rootView;
     private ProgressBar progressBar;
+    private List<String> databases;
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
@@ -39,6 +40,7 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic
         progressBar = (ProgressBar) rootView.findViewById(R.id.loginProgressBar);
 
         Static.asyncDatabaseConnector.setListReturnListener(this);
+        Static.asyncDatabaseConnector.setOnPostExecuteListener(this);
         Static.asyncDatabaseConnector.getDatabases();
         return rootView;
     }
@@ -60,6 +62,11 @@ 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/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index 670324e..f46b353 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -31,7 +31,7 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
  *
  * Fragment for showing elements
  */
-public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.MatrixReturnListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.IntegerReturnListener, View.OnClickListener {
+public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.MatrixReturnListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.IntegerReturnListener, View.OnClickListener, AsyncDatabaseConnector.OnPostExecuteListener {
     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,7 +57,10 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     private CustomScrollView fakeScrollView;
     private View dummyView;
 
+    private int onPostExecuteListenerExecuted;
+
     private Menu menu;
+    private TableRow headerRow;
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -70,6 +73,8 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         Static.asyncDatabaseConnector.setIntegerReturnListener(this);
         Static.asyncDatabaseConnector.setListReturnListener(this);
         Static.asyncDatabaseConnector.setMatrixReturnListener(this);
+        Static.asyncDatabaseConnector.setOnPostExecuteListener(this);
+        onPostExecuteListenerExecuted = 0;
         Static.asyncDatabaseConnector.getFields(tableName);
         Static.asyncDatabaseConnector.getEntriesCount(tableName);
 
@@ -203,9 +208,6 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
                 newRow.setClickable(true);
                 newRow.setOnClickListener(this);
                 entriesTable.addView(newRow);
-
-                syncWidths();
-                fakeScroll();
             }
         } else {
             TextView errorMessage = new TextView(getActivity());
@@ -223,7 +225,6 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     @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();
@@ -236,7 +237,6 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
             textView.setPadding(HEADER_PADDING_LEFT, HEADER_PADDING_TOP, HEADER_PADDING_RIGHT, HEADER_PADDING_BOTTOM);
             headerRow.addView(textView);
         }
-        headerFrame.addView(headerRow);
 
         Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page);
     }
@@ -246,12 +246,15 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         pageCount = result/entriesLimit;
         if( result%entriesLimit > 0)
             pageCount++;
-
-        setHasOptionsMenu(true);
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                setHasOptionsMenu(true);
+            }
+        });
     }
 
     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);
@@ -280,8 +283,8 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
             tmpHeader.setWidth(maxWidth[i]);
         }
 
-        headerFrame.setVisibility(View.VISIBLE);
-        entriesTable.setVisibility(View.VISIBLE);
+//        headerFrame.setVisibility(View.VISIBLE);
+//        entriesTable.setVisibility(View.VISIBLE);
     }
 
     private void fakeScroll(){
@@ -311,4 +314,13 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         intent.putStringArrayListExtra(ElementFragment.EDIT_LIST, values);
         startActivity(intent);
     }
+
+    @Override
+    public void onPostExecute() {
+        if(++onPostExecuteListenerExecuted==3){
+            headerFrame.addView(headerRow);
+            syncWidths();
+            fakeScroll();
+        }
+    }
 }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
index 73e145d..726d080 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
@@ -19,7 +19,7 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
  *
  * Fragment for login
  */
-public class LoginFragment extends Fragment implements View.OnClickListener, AsyncDatabaseConnector.BooleanReturnListener {
+public class LoginFragment extends Fragment implements View.OnClickListener, AsyncDatabaseConnector.BooleanReturnListener, AsyncDatabaseConnector.OnPostExecuteListener {
     private EditText urlTextbox;
     private EditText loginTextbox;
     private EditText passwordTextbox;
@@ -86,6 +86,7 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
         if(Static.isNetworkConnected(getActivity())) {
             asyncDatabaseConnector = new AsyncDatabaseConnector(login, password, url);
             asyncDatabaseConnector.setBooleanReturnListener(this);
+            asyncDatabaseConnector.setOnPostExecuteListener(this);
             asyncDatabaseConnector.checkLogin();
         } else {
             Static.showErrorAlert(getResources().getString(R.string.no_connection), getActivity());
@@ -105,9 +106,12 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
         else {
             Static.showErrorAlert(AsyncDatabaseConnector.errorMsg, getActivity());
         }
-        loginButton.setEnabled(true); // Now we can click button again
-        progressBar.setVisibility(View.INVISIBLE);
     }
 
 
+    @Override
+    public void onPostExecute() {
+        loginButton.setEnabled(true); // Now we can click button again
+        progressBar.setVisibility(View.INVISIBLE);
+    }
 }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
index 8a63cd4..1007f2c 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
@@ -22,12 +22,13 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
 /**
  * Created by nerull7 on 14.07.14.
  */
-public class TableFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener{
+public class TableFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.OnPostExecuteListener {
     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,6 +39,7 @@ public class TableFragment extends Fragment implements AdapterView.OnItemClickLi
         this.rootView = (RelativeLayout) rootView;
         progressBar = (ProgressBar) rootView.findViewById(R.id.loginProgressBar);
         Static.asyncDatabaseConnector.setListReturnListener(this);
+        Static.asyncDatabaseConnector.setOnPostExecuteListener(this);
         Static.asyncDatabaseConnector.getTables();
         return rootView;
     }
@@ -59,6 +61,11 @@ 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
index 8aeef5c..0f01403 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -45,6 +45,7 @@ public class AsyncDatabaseConnector {
     private MatrixReturnListener matrixReturnListener;
 
     public static String errorMsg;
+    private OnPostExecuteListener onPostExecuteListener;
 
     public AsyncDatabaseConnector(String login, String password, String url){
         this.login = login;
@@ -99,10 +100,18 @@ public class AsyncDatabaseConnector {
                 try {
                     list = parseListFromJSON(data);
                 } catch (JSONException e) { e.printStackTrace(); }
-                if(listReturnListener!=null)
-                    listReturnListener.onListReturn(list);
+                if(listReturnListener!=null) {
+                    final List<String> finalList = list;
+//                    new Thread(new Runnable() {
+//                        @Override
+//                        public void run() {
+                            listReturnListener.onListReturn(finalList);
+//
+//                        }
+//                    }).run();
+                }
             }
-        });
+        }, onPostExecuteListener);
         downloader.execute(urlQuery);
     }
 
@@ -117,7 +126,7 @@ public class AsyncDatabaseConnector {
                 if(matrixReturnListener!=null)
                     matrixReturnListener.onMatrixReturn(list);
             }
-        });
+        }, onPostExecuteListener);
         downloader.execute(urlQuery);
     }
 
@@ -161,7 +170,7 @@ public class AsyncDatabaseConnector {
 
                 booleanReturnListener.onBooleanReturn(listenerData);
             }
-        });
+        }, onPostExecuteListener);
         downloader.execute(actionUrlBuilder(ACTION_LOGIN));
         return false;
     }
@@ -224,7 +233,7 @@ public class AsyncDatabaseConnector {
                 if(integerReturnListener!=null)
                     integerReturnListener.onIntegerReturn(Integer.parseInt(data));
             }
-        });
+        }, onPostExecuteListener);
         downloader.execute(urlQuery);
     }
 
@@ -278,7 +287,7 @@ public class AsyncDatabaseConnector {
                     stringReturnListener.onStringReturn(data);
                 }
             }
-        });
+        }, onPostExecuteListener);
         downloader.execute(request);
     }
 
@@ -302,6 +311,10 @@ public class AsyncDatabaseConnector {
         this.matrixReturnListener = matrixReturnListener;
     }
 
+    public void setOnPostExecuteListener(OnPostExecuteListener onPostExecuteListener){
+        this.onPostExecuteListener = onPostExecuteListener;
+    }
+
     public static interface BooleanReturnListener{
         public void onBooleanReturn(boolean result);
     }
@@ -322,16 +335,22 @@ public class AsyncDatabaseConnector {
         public void onMatrixReturn(List<List<String>> data);
     }
 
+    public static interface OnPostExecuteListener {
+        void onPostExecute();
+    }
+
     private static class Downloader extends AsyncTask<String, Void, String> {
         private OnFinishedListener onFinishedListener;
+        private OnPostExecuteListener onPostExecuteListener;
         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){
+        Downloader(OnFinishedListener onFinishedListener, OnPostExecuteListener onPostExecuteListener){
             this.onFinishedListener = onFinishedListener;
+            this.onPostExecuteListener = onPostExecuteListener;
             errorString = null;
         }
 
@@ -385,7 +404,8 @@ public class AsyncDatabaseConnector {
         @Override
         protected String doInBackground(String... strings) {
             try {
-                return httpRequest(strings[0]);
+                String data = httpRequest(strings[0]);
+                onFinishedListener.onFinished(data, errorMsg); // Can't be null cos we demand listener in constructor
             } catch (IOException e) {
                 e.printStackTrace();
             }
@@ -394,11 +414,17 @@ public class AsyncDatabaseConnector {
 
         @Override
         protected void onPostExecute(String data) {
-            onFinishedListener.onFinished(data, errorString); // Can't be null cos we demand listener in constructor
+            if (onPostExecuteListener!=null)
+                onPostExecuteListener.onPostExecute();
+        }
+
+        public void setOnPostExecuteListener(OnPostExecuteListener onPostExecuteListener) {
+            this.onPostExecuteListener = onPostExecuteListener;
         }
 
         private static interface OnFinishedListener {
             void onFinished(String data, String error);
         }
+
     }
 }

From e48b75863e1389992b673bb530adec9855c02bd7 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 11:24:55 +0200
Subject: [PATCH 30/59] Better UI

 Less actions on main thread.
---
 .../nerull7/mysqlbrowser/ElementFragment.java | 41 +++++++++++---
 .../nerull7/mysqlbrowser/EntriesFragment.java | 55 ++++++++++---------
 app/src/main/res/layout/fragment_entries.xml  | 10 ++--
 3 files changed, 69 insertions(+), 37 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
index 898c6ba..65e7685 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
@@ -24,10 +24,15 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
  *
  * Fragment for editing/adding elements
  */
-public class ElementFragment extends Fragment implements AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.StringReturnListener {
+public class ElementFragment extends Fragment implements AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.StringReturnListener, AsyncDatabaseConnector.OnPostExecuteListener {
     public static final String EDIT_ELEMENT = "edit_element";
     public static final String EDIT_LIST = "edit_element_list";
 
+    private static final int POST_EXECUTE_NONE = 0;
+    private static final int POST_EXECUTE_GET_FIELDS = 1;
+    private static final int POST_EXECUTE_UPDATE_ELEMENT = 2;
+    private static final int POST_EXECUTE_ADD_ELEMENT = 3;
+
     private String tableName;
     private ElementArrayAdapter listAdapter;
 
@@ -35,6 +40,8 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
     private ListView listView;
 
     private List<String> values;
+    private String message;
+    private int postExecute;
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -45,7 +52,9 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
 
         initArguments();
 
+        postExecute = POST_EXECUTE_NONE;
         Static.asyncDatabaseConnector.setListReturnListener(this);
+        Static.asyncDatabaseConnector.setOnPostExecuteListener(this);
         Static.asyncDatabaseConnector.getFields(tableName);
 
         return rootView;
@@ -84,12 +93,8 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
     @Override
     public void onListReturn(List<String> fields) {
         listAdapter = new ElementArrayAdapter(getActivity(), R.layout.list_item_element_simple, fields, values);
-        listView.setAdapter(listAdapter);
-//        databasesListView.setAdapter(listAdapter);
-//        databasesListView.setOnItemClickListener(this);
-        progressBar.setVisibility(View.INVISIBLE);
+        postExecute = POST_EXECUTE_GET_FIELDS;
 
-        setHasOptionsMenu(true);
     }
 
     private List<String> getNewValues(){
@@ -104,8 +109,30 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
 
     @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(data);
+        builder.setMessage(info);
         builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
             @Override
             public void onClick(DialogInterface dialogInterface, int i) {
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index f46b353..f0a6583 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -61,6 +61,7 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
 
     private Menu menu;
     private TableRow headerRow;
+    private int[] maxWidth;
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -91,12 +92,12 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
 
     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,8 +109,6 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         });
 
         layoutParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.MATCH_PARENT);
-        headerFrame.setVisibility(View.INVISIBLE);
-        entriesTable.setVisibility(View.INVISIBLE);
     }
 
     @Override
@@ -146,7 +145,9 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
 
     private void loadAnotherPage(){
         changeMenus(page);
-        entriesTable.removeAllViews(); // clean table
+        entriesScrollView.removeAllViews(); // clean table
+        entriesTable = new TableLayout(getActivity());
+        onPostExecuteListenerExecuted--;
 
         setLoading(true);
         Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page); // get new entries
@@ -208,18 +209,12 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
                 newRow.setClickable(true);
                 newRow.setOnClickListener(this);
                 entriesTable.addView(newRow);
+                syncWidthsFirstStage();
             }
         } else {
-            TextView errorMessage = new TextView(getActivity());
-            errorMessage.setText(R.string.error_no_entries);
-            errorMessage.setTypeface(null, Typeface.ITALIC);
-            errorMessage.setClickable(false);
-            entriesScrollView.removeView(entriesTable);
-            headerFrame.setVisibility(View.VISIBLE);
-            entriesScrollView.addView(errorMessage);
+            entriesTable = null;
         }
 
-        setLoading(false);
     }
 
     @Override
@@ -254,25 +249,27 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         });
     }
 
-    private void syncWidths(){ // TODO: Merge with adding columns maybe? Loops -= 3 should be quicker
-        int maxWidth[]= new int[headerRow.getChildCount()];
-        for(int i=0;i<headerRow.getChildCount();i++){
+    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++){
+        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);
 
@@ -282,9 +279,6 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
             tmpEntries.setWidth(maxWidth[i]);
             tmpHeader.setWidth(maxWidth[i]);
         }
-
-//        headerFrame.setVisibility(View.VISIBLE);
-//        entriesTable.setVisibility(View.VISIBLE);
     }
 
     private void fakeScroll(){
@@ -318,9 +312,20 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     @Override
     public void onPostExecute() {
         if(++onPostExecuteListenerExecuted==3){
-            headerFrame.addView(headerRow);
-            syncWidths();
-            fakeScroll();
+            if(entriesTable!=null) {
+                syncWidthsSecondStage();
+                fakeScroll();
+                entriesScrollView.addView(entriesTable);
+            } else {
+                TextView errorMessage = new TextView(getActivity());
+                errorMessage.setText(R.string.error_no_entries);
+                errorMessage.setTypeface(null, Typeface.ITALIC);
+                errorMessage.setClickable(false);
+                entriesScrollView.addView(errorMessage);
+            }
+            if(headerFrame.getChildCount()==0) // You can have only one child
+                headerFrame.addView(headerRow);
+            setLoading(false);
         }
     }
 }
diff --git a/app/src/main/res/layout/fragment_entries.xml b/app/src/main/res/layout/fragment_entries.xml
index 3ed823a..55f3cb8 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>

From 475a7b4c6184e6fcee99a10b894ddb22407d5dfe Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 11:25:55 +0200
Subject: [PATCH 31/59] Fix for info box

---
 app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
index 65e7685..bfa7c97 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
@@ -147,6 +147,7 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
         });*/
         builder.setTitle(R.string.status);
         builder.setIcon(R.drawable.ic_action_warning); //TODO Change Icon
+        builder.setCancelable(false); // There is no exit
         builder.create();
         builder.show();
     }

From 87c276dfc4dd613e4de899134ccd4745704ddea1 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 11:37:02 +0200
Subject: [PATCH 32/59] Reload table after changes

---
 .../nerull7/mysqlbrowser/EntriesFragment.java | 26 ++++++++++++++++---
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index f0a6583..e9f09f6 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -63,6 +63,8 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     private TableRow headerRow;
     private int[] maxWidth;
 
+    private boolean isFirstCreate;
+
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                              Bundle savedInstanceState) {
@@ -70,11 +72,8 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
 
         initArguments();
         initViewItems(rootView);
+        initListeners();
 
-        Static.asyncDatabaseConnector.setIntegerReturnListener(this);
-        Static.asyncDatabaseConnector.setListReturnListener(this);
-        Static.asyncDatabaseConnector.setMatrixReturnListener(this);
-        Static.asyncDatabaseConnector.setOnPostExecuteListener(this);
         onPostExecuteListenerExecuted = 0;
         Static.asyncDatabaseConnector.getFields(tableName);
         Static.asyncDatabaseConnector.getEntriesCount(tableName);
@@ -86,6 +85,7 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         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);
     }
@@ -111,6 +111,13 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         layoutParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.MATCH_PARENT);
     }
 
+    private void initListeners(){
+        Static.asyncDatabaseConnector.setIntegerReturnListener(this);
+        Static.asyncDatabaseConnector.setListReturnListener(this);
+        Static.asyncDatabaseConnector.setMatrixReturnListener(this);
+        Static.asyncDatabaseConnector.setOnPostExecuteListener(this);
+    }
+
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         inflater.inflate(R.menu.entries_activity_actions, menu);
@@ -309,6 +316,17 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         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){

From 298fab290a3473cd6933b8052252af7742414a74 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 11:38:53 +0200
Subject: [PATCH 33/59] Don't need URL log now.

---
 .../info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index 0f01403..01f8911 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -359,7 +359,7 @@ public class AsyncDatabaseConnector {
             InputStream inputStream = null;
             String response;
 
-            Log.d("URL REQUEST", urlRequest);
+//            Log.d("URL REQUEST", urlRequest);
 
             HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();  // TODO Handling no connection
             urlConnection.setReadTimeout(READ_TIMEOUT);

From 2b661013bdd3ee3ce96b67cd4e4adf8918d4d167 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 11:39:39 +0200
Subject: [PATCH 34/59] Remove unused commented code.

---
 .../nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java  | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index 01f8911..f02a60a 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -101,14 +101,7 @@ public class AsyncDatabaseConnector {
                     list = parseListFromJSON(data);
                 } catch (JSONException e) { e.printStackTrace(); }
                 if(listReturnListener!=null) {
-                    final List<String> finalList = list;
-//                    new Thread(new Runnable() {
-//                        @Override
-//                        public void run() {
-                            listReturnListener.onListReturn(finalList);
-//
-//                        }
-//                    }).run();
+                    listReturnListener.onListReturn(list);
                 }
             }
         }, onPostExecuteListener);

From ba87ba1291c6bf04bce06e1ff52b4a183c54f561 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 11:47:01 +0200
Subject: [PATCH 35/59] Set more generic Type

---
 .../java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
index 5f4c427..9004c95 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
@@ -40,7 +40,7 @@ public class ElementArrayAdapter extends ArrayAdapter<String> {
         TextView textView = (TextView) rowView.findViewById(R.id.textFieldName);
         textView.setText(fields.get(position));
         if(values != null){
-            EditText textFieldName = (EditText) rowView.findViewById(R.id.editFieldValue);
+            TextView textFieldName = (TextView) rowView.findViewById(R.id.editFieldValue);
             textFieldName.setText(values.get(position));
         }
 

From 555a428af40ea08a5880efbbf89a37651be87c1d Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 12:16:05 +0200
Subject: [PATCH 36/59] Fix not showing scroll

---
 .../java/info/nerull7/mysqlbrowser/EntriesFragment.java  | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index e9f09f6..9bf12ef 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
@@ -294,7 +294,8 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         dummyView.setMinimumHeight(height);
 
         RelativeLayout.LayoutParams fakeScrollLayout = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-        fakeScrollLayout.setMargins(0,headerFrame.getHeight(),0,0);
+        headerFrame.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+        fakeScrollLayout.setMargins(0,headerFrame.getMeasuredHeight(),0,0);
 
         fakeScrollView.setLayoutParams(fakeScrollLayout);
     }
@@ -330,10 +331,12 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     @Override
     public void onPostExecute() {
         if(++onPostExecuteListenerExecuted==3){
+            if(headerFrame.getChildCount()==0) // You can have only one child
+                headerFrame.addView(headerRow);
             if(entriesTable!=null) {
                 syncWidthsSecondStage();
-                fakeScroll();
                 entriesScrollView.addView(entriesTable);
+                fakeScroll();
             } else {
                 TextView errorMessage = new TextView(getActivity());
                 errorMessage.setText(R.string.error_no_entries);
@@ -341,8 +344,6 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
                 errorMessage.setClickable(false);
                 entriesScrollView.addView(errorMessage);
             }
-            if(headerFrame.getChildCount()==0) // You can have only one child
-                headerFrame.addView(headerRow);
             setLoading(false);
         }
     }

From 7bcbe46d91954d9ab37e549eff4dcfb76e9c1707 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 15:07:12 +0200
Subject: [PATCH 37/59] Added remove element

---
 .../nerull7/mysqlbrowser/ElementFragment.java |  10 +++-
 .../nerull7/mysqlbrowser/LoginFragment.java   |  12 +++--
 .../db/AsyncDatabaseConnector.java            |  44 +++++++++++++++++-
 .../res/drawable-hdpi/ic_action_delete.png    | Bin 0 -> 764 bytes
 .../res/drawable-mdpi/ic_action_delete.png    | Bin 0 -> 507 bytes
 .../res/drawable-xhdpi/ic_action_delete.png   | Bin 0 -> 990 bytes
 .../res/drawable-xxhdpi/ic_action_delete.png  | Bin 0 -> 1721 bytes
 app/src/main/res/menu/element.xml             |   5 ++
 app/src/main/res/values/strings.xml           |   2 +
 9 files changed, 66 insertions(+), 7 deletions(-)
 create mode 100644 app/src/main/res/drawable-hdpi/ic_action_delete.png
 create mode 100644 app/src/main/res/drawable-mdpi/ic_action_delete.png
 create mode 100644 app/src/main/res/drawable-xhdpi/ic_action_delete.png
 create mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_delete.png

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
index bfa7c97..42eba73 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
@@ -62,15 +62,18 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
+        List<String> fields = listAdapter.getFieldArray();
         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 if(item.getItemId() == R.id.action_remove) {
+            Static.asyncDatabaseConnector.setStringReturnListener(this);
+            Static.asyncDatabaseConnector.removeElement(tableName, fields, values);
+            return true;
         } else {
             return super.onOptionsItemSelected(item);
         }
@@ -87,6 +90,9 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
     @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);
     }
 
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
index 726d080..b3b048c 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
@@ -28,6 +28,8 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
 
     AsyncDatabaseConnector asyncDatabaseConnector;
 
+    private boolean result;
+
     public LoginFragment(){}
 
     @Override
@@ -97,6 +99,12 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
 
     @Override
     public void onBooleanReturn(boolean result) {
+        this.result = result;
+    }
+
+
+    @Override
+    public void onPostExecute() {
         if(result) {
             Static.asyncDatabaseConnector = asyncDatabaseConnector;
             Intent intent = new Intent(getActivity(), ListActivity.class);
@@ -106,11 +114,7 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
         else {
             Static.showErrorAlert(AsyncDatabaseConnector.errorMsg, getActivity());
         }
-    }
 
-
-    @Override
-    public void onPostExecute() {
         loginButton.setEnabled(true); // Now we can click button again
         progressBar.setVisibility(View.INVISIBLE);
     }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index f02a60a..8a8872f 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -31,6 +31,7 @@ public class AsyncDatabaseConnector {
     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";
 
     private String login;
     private String password;
@@ -206,7 +207,7 @@ public class AsyncDatabaseConnector {
         args.add("l");
         values.add(String.valueOf(count));
 
-        getMatrix(actionUrlBuilder(ACTION_DATA_MATRIX, args, values) );
+        getMatrix(actionUrlBuilder(ACTION_DATA_MATRIX, args, values));
     }
 
     public void getEntriesCount(String table){
@@ -284,6 +285,47 @@ public class AsyncDatabaseConnector {
         downloader.execute(request);
     }
 
+    public void removeElement(String table, List<String> header, List<String> values) {
+        JSONArray headerJSON = new JSONArray();
+        JSONArray valuesJSON = new JSONArray();
+        String 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);
+                }
+            }
+        }, onPostExecuteListener);
+        downloader.execute(request);
+    }
+
     public void setBooleanReturnListener(BooleanReturnListener booleanReturnListener){
         this.booleanReturnListener = booleanReturnListener;
     }
diff --git a/app/src/main/res/drawable-hdpi/ic_action_delete.png b/app/src/main/res/drawable-hdpi/ic_action_delete.png
new file mode 100644
index 0000000000000000000000000000000000000000..49e4513d88cf182c6efcb7c684f85fc1456f70be
GIT binary patch
literal 764
zcmV<Y0t5YtP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm0008RNkl<ZXhZE;
zOGs8h6!y2$O;+GeH`1;^30f3^8x0ava3SQAwk=(@(S>bl*V3){$e=|~f`YmUL>ECQ
z<SyFiPVBX@hx&bR@6R;dJ7;G82Ojal$JKw%nRC9Gb7s!WEz~G~3d;SjIVT{@U^+m@
zm73{t%|I<2Y)R0JcO%dM)FqDp!utoX59|V85*(FEtW*M5;lN$sHgGM_nXi!l0Biu?
z0(Fbxu>>xohx@=C;6kkNMDH)&o4^Y2GqkT50=HnK2e=YyOpyPM_IJR?kbXl5FwVPy
z_7DRRvhSg@2zcd(FM&(wa0Iv!;ZTgq4wPnr-;%Nq0gn8mDmtI~OcK-5O!yG!twPx3
z4K%~)t!ow}0!-K;X&NisKJQ9w7XdDnV?eoAn^3-7on8Q$ORS4PAC&G1*0_eh25tha
zfu3zc{u9s-NPEdTWZq=;pGSZ@>=U75IzN**!9*VpAVKHnk_09BQ4d?sAoJgjok!pS
zggb>1eT8<G0_k%Re+&R^g5DO|7l1#897~ahg5E0Hmu;CW0vt__zEs<oqiB*Cbj$>G
zURuuk&fWp^o+q<b<dH?-I$9qKqmed;I21$Jc4G=Zd^Uf~BEZmL2>Cu)Az_D;kBpDK
zB?zra1ej1UD@vM_b~y3>*s!rlaTd97I75hQf0NH}STcFxL@~24<LtQd#ASL9jocHQ
z1jf<I(^Slp6)I*wzAIIpZJz3$x(F~QCV~1G?-QM@WMz}@YU46}h{g$^c*eGqSUmx<
zR~<qmpgxJ!FQXlpg|2`k_SvL-WPD6|ZDi_8iPKul@gj^R^*^^2XR@4TEUG`ykc8?Z
zB?+iM)RTnjYn60eR(-LRR*|Z&7D+<&<!%~Es;}40Iz{aV4wHoHPfR8ewIBKH(pT+g
uR;h+p^PyWJQn7aF3r)ogm#bs-1Wo|IXw)%-dy;hk0000<MNUMnLSTZmt6qBm

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-mdpi/ic_action_delete.png b/app/src/main/res/drawable-mdpi/ic_action_delete.png
new file mode 100644
index 0000000000000000000000000000000000000000..2706550e95d428313d6e9d999f57faf06cc66b33
GIT binary patch
literal 507
zcmV<X0R;YuP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80005PNkl<ZSVzT|
zPbft}6vp3UiC$r^WGSyCYirgd%ErRmlbw~FSYu(MNUT{~ONuO&>`}tfpYMBSYMjp8
zxpS#=>&tWI%sIa~^Y7kz&G@Ms=dV=-=mB^?)a3^7j=zu4Ywmz@0GMzb8g|LGT!grV
zE*wyjrwjl`IR%YE9m$A44xi8!bPBOL(I*8kgr0Lycge)k?G1)Q=q}d32%w2hvruQn
z<i6VnejGv9TAUaFN51$E$wP=etr8jl=Y07OWsen%)3GJjga$AJr!ghU3v3V2NMcHE
z&^`b)6u(Q@jzhZy;8t6K<Z5T~UFZp#jsP+)6P!SO(2@ed-LVOAyS5(*FbUg)Le5bg
zKwqwp2H}%?pLzId)jEg$EC#TO23A3PWP%W)s7=P==r=R~9<OVW<ld|$VjIg|R2><1
z9ftO?9Zta@{%<7!*eoGv%SlfEZRlPC@Qhz50U#lKoT9}k!|ubtJL6Xc%mK`&z<d#M
zN=&yQ0n87gqN8{RfX`5wqqx^?X?Y(ck78EA^fDrV`E^VP(-#tdYMH*0c?i>&QV(JJ
xS{_~^W*;Wn1!?kWR`RCKb4z_0<wdLD{S5+*j3Jmsy~O|k002ovPDHLkV1m;y-kJaa

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xhdpi/ic_action_delete.png b/app/src/main/res/drawable-xhdpi/ic_action_delete.png
new file mode 100644
index 0000000000000000000000000000000000000000..1487306f124b1ba77501573e78888f41bb0b96fe
GIT binary patch
literal 990
zcmV<410np0P)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF000A}Nkl<ZcwX&W
zIjl}W6n-y=HH09d&{!g&laNqYDoa5kp|C3`G!zsHg+f6=qaeYv6(kZ0OJylYNOTmo
zMj?U_Vhs}CC;!OJm^*XM+<V`<FXv72<^S)!=gge*&6)Mi?d~$3x{dqaH9){X1Q=(a
zH=DpHa6Ji_2#f|s0)spJ|HAJV;1lo$cny5+jk;-)fI)CzIxq{E3XE4e^bYbbfXBcy
z;I~p=B;Eu8tl7E1JYby2inP#sh};JrbRs3KA(W_-06M-9SO5$Wmai5235C1Bow|sq
zi-6fMXeBU4>rtlsN9bJv9%btPQ>#kAaOAWGU_0-N#QxzT@GZCSDg;bGq3eLjxrNuH
z_X_!(2j1r7mrKAD6t)!@kyB^`I$x3JN#Lb6?;HZ?{1$+nUYio<5vQ~yXbE80?`ToY
z`xU@QII3w58UoniZEr!FPemR3gkylHW7H6^37Pg)Z=Z77f6me2v_wft0LS@_k_=lU
za|X5~=Lr%5*xBs_w3D0<&>343Avt+*vUCJs=UAE~1T2U4BBdjow_gR;12dGmzW7tz
zI0vi%xW3S&+Yr81g#gz6UO+RqzXkd0okF?X-CThLI^P3uxy-Z-Sgc@xYlj0sX%wU)
zfQ7M8X=2S^@`Q)tdP4>Ybp9;x!^>|qt~HUs%3!4gQ;Yzv=XV3rB`w?OVc>h9ByA-4
zHDAnf7%p}J(*A`@=|ezpKOsiIOek@>t4T4#rIAop^Rz=tq_h15{yYge5+gtxYA*jO
z4%9(l$j?yI{3{nDU=N;ax3P*O^x(pEUPYtIBB2U#sVL?4+CfbOa07E+D%ZqwjYCb<
ze9^@HxcG0QwJZXrL3mq50;n!=jB=sgzDk=9nSLBMpZgEW2$&DSRW%UcNQgN|8BJ5k
zHS01I?@0+*3c)40B?a_ikq{~-x3`a(d=n3END0Ut0b&Nk`h=pMbhy;kPjDnCYXWPL
z`y6cv0{K)VG*R=;tcUn>K^g((2{7LT%y)w3he7ibA@fsVjuxgDLnI(~B+x8^{9#$L
zcF5Ud%vuhc-w-jsCC2bHy(vlp%x{a61k*1@TojmoHAWIlzZ`XAwdvR6B*FXv36fy?
zh>U9rrVmLKNicg%&XHjHprj+g^ikR3Qr7HY=^_cHkIVZ+nEYVE-`(MU0ykILJgR&$
z!?S*TtJ`lrnemBm*XBN&DkGv*_fyB@T4ih##tab91grfiPxBG*2MGKYP<l%#F#rGn
M07*qoM6N<$f;$_*VgLXD

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_delete.png b/app/src/main/res/drawable-xxhdpi/ic_action_delete.png
new file mode 100644
index 0000000000000000000000000000000000000000..251f91da422b503afb01693827c75e4be9d4915e
GIT binary patch
literal 1721
zcmV;q21fabP)<h;3K|Lk000e1NJLTq003YB003YJ1^@s6;+S_h000JnNkl<ZcwX&Y
zU8q$>6!r%d&7{z@2uw665i~^YArKA1kiZAEB>F)?1+}M0NCgoLLGh_XR8T4jD}4w;
z6rn`$!HTFLR7kl#h?<5{YFMOwpPpUY!`Wxg&ssC*p1TG<^xiu&Yu5T^*8I=z-_Jr;
z3-r$_-Guiu0y0+uBftpAY=O+;tpykXnJti6d~a?6Ec<|l{chvmJDF`6B)-!LcmP^G
z28;nl0S^Jg0sek4FtDNZKlt}A;0ACVxCUGSE&&%BzYj8ycA`!rU?>!x2uuLR0gnh7
z;4<>*0nPv?fj@=vjn1YM2w)kW0wy<%&)TgS*h)ykPrzv)tLw^1z#u693@`(DLet`H
z@;-;ZeFOXe{GFo=IS3d6MV|#`0rcmc5ZG@V1x^6BQWhvR0aKvd3&7}<N_xop6>*OM
zKYFBzikgam2T{s7z;qy$%uvIyPxux%4EzzAiEFwP#-NX%3k-8DRENa7iE<nS*hi=Z
zO#(PZr@NWm3u=9pf!P|qZn!1RHN=A!0j%u{fl1;e&XeKK5c@g6Rv{WR2zVGJTncdJ
z+D(Bo>s`QANu{I-pwZt1xOC8s;Ubj!2p}0EL6QL0{3Ts%{KDWQVUJWxkRpISe^nQ{
zovK>S7VrTO-6u#8z|qcYK(}<buC9e0^IjlobR<E*izvkNuBGm>cwa%ELoqtV62M8;
zd>}TT7#(t^<vig45Ik9nF&vi{-UfQx3|E>k_5)jipk<2~0v13hTY!aoEnt6$Awmh@
zs^+VLu7^!Iv@9WdGmWH7=Jg5Sy^0#5G}rUr0;HCdxkL3Sz}3>nL#^qV?mXgiweuA~
zY6p%>+3y2h`w1Zg%!H7aJQc2rPUC+JoCUby&RMiJ2{itP05|T(1Fs8`@Fns(=3^UQ
z0=SL%E+Da!^;^RboLLruoAS#PNucp}0_9ElM;pYC^f6pTT<)xG0-U!ueF@-(3RgK}
z18e>cpltjiPpy_vuKCU7Cke}iS^`&1xuN3}d<bCN6+r9;dfDw%6;hgncE&HtAmxsF
zkl}W~>9mCp0Z$`SF1E!47K#g5ryMeoa!0M)PL+7-xES!UORKzgJL>2q=w)O&&B1VW
zQCw=Hlsif(tE~5T_~ElUL-6meOtUtw2Bd~;KD9E`9r+kvs<jn1r<>gj)Skd|C15Ht
zTjav1M;uK9r69OY)qRNYeO)A10yy&F2uM2kkl@-9H1Z75n<F8Ph}s5M0_c9U_IM?0
ztB>)e-A=Qic_4U;1OfE>>+3R#{JVtVB#Dev=fC6|@IUqkmBFP2Jc-ntooWXk5}Msn
zOj=F7IP3l;mVoDw!92}Umhuj%#Y|qT?bH=h+wC;V{{p`_9!mg?PZClEpV~}=GSm+D
z5XZF>m(-KSCkd6o#RYMNGWCYL4+$;?%VB($iyQZBolykvxXD--ErsLwxTAKWQ@fpV
zS<c~yZLtJs4ngZUi){(HYJQ;?&ku1%9NYrvqSgW<>MW)B_fQgY8=ofm9e59@Tp6wF
z19<3a9U!#^6v~sYJId*H$~tlmuo0*{yk!K0RtdLs(FB+aax-*QtY{a+jI9$6Cn35M
zrf3_6h7%w%47G_^H~}IPF<XiVCqQH=!WQGg2@qL~v*qY;0z{UhZ9^uU0FezDihl=?
zdb_7t9iLfl-SUFZvW50+S!_#^2D43h|5hNnDR0M8{0R^}mSP99{0I;~m__k+G|`;|
z@uP_pZHIH+2~atlYsb^w2<SmHmE-9YZx=M`Nl?3>LD9UTv<8saA+sw=Fl611SS!Bm
zl3sNyP`{){(RNL>H37-4sZzXM)V`mDq!+ad(e_lq|0E=Ts(_;Hv5tELWP7ZG!tJ@5
zjL+2+4bUEJs-GKF#t0dPHfLr}mSrY@;yE!}325CTi%?M|DbM@x)N|YGM=p{jT0kMk
zo~?ATcvBon0+=;hz#9M`zv#x$(GRzlTf)*VbVt47>EeO}_6eM*rM}vv)#`Y{jc>w5
z`~2ntO1q$P{`P#mLv_$3pb&2#aA-qB3IZtJK4DTpLMj3Z@%9lP<zc9U*Sou)V4tyS
zSSoc3C=<l(O@7FY`^@89m{W+;gFJbHtxtW(t<^}(K4qv-yF#+Gk9mezO)-sq&Q{U5
zv01bKvJX1PTCuOE&p8U}>$bnEzY&nR8W;gaKxPYM7H=)U2*_-K%;NtATo1f(VxgWZ
P00000NkvXXu0mjfj7Sv9

literal 0
HcmV?d00001

diff --git a/app/src/main/res/menu/element.xml b/app/src/main/res/menu/element.xml
index 8f2cd4b..f3262ad 100644
--- a/app/src/main/res/menu/element.xml
+++ b/app/src/main/res/menu/element.xml
@@ -7,4 +7,9 @@
         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/values/strings.xml b/app/src/main/res/values/strings.xml
index db2bbf2..5cea4e6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -39,5 +39,7 @@
     <string name="warning">Warning</string>
     <string name="status">Status</string>
     <string name="back">Back</string>
+    <string name="action_remove">Remove</string>
+
 
 </resources>

From 93c8d65cfa76e759d8943c07ac3ce9bcdf29afb8 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 15:20:12 +0200
Subject: [PATCH 38/59] Added warning before remove entry

---
 .../nerull7/mysqlbrowser/ElementFragment.java | 65 ++++++++++++++-----
 app/src/main/res/values/strings.xml           |  2 +
 2 files changed, 52 insertions(+), 15 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
index 42eba73..a26c459 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
@@ -60,23 +60,57 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
         return rootView;
     }
 
+    private void actionSave(){
+        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());
+    }
+
+    private void actionRemove(){
+        final List<String> fields = listAdapter.getFieldArray();
+        Static.asyncDatabaseConnector.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.asyncDatabaseConnector.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) {
-        List<String> fields = listAdapter.getFieldArray();
-        if(item.getItemId() == R.id.action_save ){
-            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 if(item.getItemId() == R.id.action_remove) {
-            Static.asyncDatabaseConnector.setStringReturnListener(this);
-            Static.asyncDatabaseConnector.removeElement(tableName, fields, values);
-            return true;
-        } else {
-            return super.onOptionsItemSelected(item);
+        switch (item.getItemId()){
+            case R.id.action_save:
+                actionSave();
+                break;
+            case R.id.action_remove:
+                actionRemove();
+                break;
+            default:
+                return super.onOptionsItemSelected(item);
         }
+        return true;
     }
 
     private void initArguments() {
@@ -152,9 +186,10 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
             }
         });*/
         builder.setTitle(R.string.status);
-        builder.setIcon(R.drawable.ic_action_warning); //TODO Change Icon
+        builder.setIcon(R.drawable.ic_action_warning);
         builder.setCancelable(false); // There is no exit
         builder.create();
         builder.show();
     }
+
 }
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5cea4e6..2700a04 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -40,6 +40,8 @@
     <string name="status">Status</string>
     <string name="back">Back</string>
     <string name="action_remove">Remove</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="no">No</string>
 
 
 </resources>

From 9bebe4407c696a00c062784a8880d7120066d80e Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 15:26:29 +0200
Subject: [PATCH 39/59] Some String cleanup

---
 app/src/main/res/values/strings.xml | 55 ++++++++++++++++-------------
 1 file changed, 30 insertions(+), 25 deletions(-)

diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2700a04..5bbac4d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,47 +1,52 @@
 <?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="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="title_activity_main">MainActivity</string>
-    <string name="hello_world">Hello world!</string>
-    <string name="login_error">Wrong login/password</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_entries">EntriesActivity</string>
+
+    <string name="login_error">Wrong login/password</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="action_previous">Previous</string>
-    <string name="action_next">Next</string>
+    <string name="error_no_save">Your data will NOT 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="pref_entries_per_page">Set number of entries per page</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="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>
-    <string name="action_remove">Remove</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="no">No</string>
-
 
 </resources>

From 2dd63650de756ba62150b5017b4cd1b49c65262f Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 15:31:44 +0200
Subject: [PATCH 40/59] Some Bolding

---
 app/src/main/res/values/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5bbac4d..b3a32f1 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -40,7 +40,7 @@
     <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 NOT be saved! Would you like to continue?</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="pref_entries_per_page">Set number of entries per page</string>

From 23e1078c7d7135d1b18521b20c92e1bed34ca94b Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 15:35:58 +0200
Subject: [PATCH 41/59] Turns out we need it

 Re added title_fragment_database string.
---
 app/src/main/res/values/strings.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index b3a32f1..d7b1d0e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -13,6 +13,7 @@
     <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>

From dfb3374d59653b8d8f96074d9457488d129bf49b Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 15:38:50 +0200
Subject: [PATCH 42/59] =?UTF-8?q?Polskie=20t=C5=82umaczenie?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/src/main/res/values-pl/strings.xml | 47 ++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 app/src/main/res/values-pl/strings.xml

diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
new file mode 100644
index 0000000..35ba264
--- /dev/null
+++ b/app/src/main/res/values-pl/strings.xml
@@ -0,0 +1,47 @@
+<?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="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>

From 5d635e4408cd71c4589dae91753410a1b9320aa6 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 15:52:45 +0200
Subject: [PATCH 43/59] Showing connection error DO NOT MERGE

 FIXME
---
 .../mysqlbrowser/db/AsyncDatabaseConnector.java      | 12 +++++++++++-
 app/src/main/res/values/strings.xml                  |  1 +
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index 8a8872f..3aceda8 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -12,12 +12,15 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.UnsupportedEncodingException;
+import java.net.ConnectException;
 import java.net.HttpURLConnection;
 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
@@ -400,7 +403,14 @@ public class AsyncDatabaseConnector {
             urlConnection.setReadTimeout(READ_TIMEOUT);
             urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
             urlConnection.setRequestMethod(CONNECTION_REQUEST_METHOD);
-            urlConnection.connect();
+            try {
+                urlConnection.connect();
+            } catch (ConnectException e) {
+//                errorMsg = e.getMessage();
+                if (e.getCause().equals(CONNECTION_REQUEST_METHOD)) {
+                    errorMsg == R.string.error_connection_timeout; // FIXME
+                }
+            }
 
             if(urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                 try {
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d7b1d0e..c1647e7 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -49,5 +49,6 @@
     <string name="save_credentials">Save credentials</string>
     <string name="connector_url">Connector URL</string>
     <string name="no_connection">No Internet Connection</string>
+    <string name="error_connection_timeout">Connection timeout</string>
 
 </resources>

From f223b58e21bd86cd9deeda160977440525edf37c Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 20:14:04 +0200
Subject: [PATCH 44/59] Add missing image

---
 .../main/res/drawable-hdpi/ic_action_save.png    | Bin 0 -> 575 bytes
 .../main/res/drawable-mdpi/ic_action_save.png    | Bin 0 -> 387 bytes
 .../main/res/drawable-xhdpi/ic_action_save.png   | Bin 0 -> 807 bytes
 .../main/res/drawable-xxhdpi/ic_action_save.png  | Bin 0 -> 1274 bytes
 4 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 app/src/main/res/drawable-hdpi/ic_action_save.png
 create mode 100644 app/src/main/res/drawable-mdpi/ic_action_save.png
 create mode 100644 app/src/main/res/drawable-xhdpi/ic_action_save.png
 create mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_save.png

diff --git a/app/src/main/res/drawable-hdpi/ic_action_save.png b/app/src/main/res/drawable-hdpi/ic_action_save.png
new file mode 100644
index 0000000000000000000000000000000000000000..107c11e10943aadbcb217dcbfb14e593c546090c
GIT binary patch
literal 575
zcmV-F0>J%=P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00068Nkl<ZXhZE;
zxk>~<5Zzrtgblqvz(ny23=Q-z+|Wcp13}P8MKDm%#Blu!6*bcz5Ka65?@;i-;}z_{
zF!uCR_2mq9LoqP(s`|aE>N$GqwTh2=#rfBwfWNL_tU%c-FbIOvun}0dXR;@Ve=MCt
z*Fr>o7S@yoHN=0z?^G&6CtwD_#tg~WxE;dzj2l2FU_H||U)-QfTtkCnx06o5R%!ww
zzXp3}lH<TOG$3|6Nd&B7!VeBJCMKPrJeR_DD!Tv@rfsJx2++1u6$B*hwWR8^D1f<O
zRWQyXPW%1u3RooCnX6R=oUyP76a`o$&xvcSfRi*@1c?<eNnY{|p?mk|#tl}1H!!+@
zUBVtZ>;`ZghfTmtzpaA^xCg;D>^Uc`y*S^3(f77=co*;rMtiWw0%rZVJ_qX&D)26V
zb`*}7q^5wIWMUJTcLCd&>5fTi2)IQiHkg2A%=F15)dk!p6B`9^6SV{2EfYKp+yWCD
ztOAu^#B>|og*_Eywh!0m%Xk|l-t-J;caAC@^bBah=qMfDZ=(qzs>C_$Iwgb%kHY9x
zLizwRUIW?9U1`P$Pn%LSZ2tt&p6rT>KpD5!RXne7@<1ve^bd}_3cujOK8#)ze~qHj
zhWy2pB}Z*@1EU>kC3zRUX|gVy`V>{b>0~~FMFBptDv22@Ajy^w><<lKaWTN=iY@>E
N002ovPDHLkV1jPw_B#Lo

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-mdpi/ic_action_save.png b/app/src/main/res/drawable-mdpi/ic_action_save.png
new file mode 100644
index 0000000000000000000000000000000000000000..0235a4bc83af005a013905c5933184d4da8e4aa3
GIT binary patch
literal 387
zcmV-}0et?6P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80003>Nkl<ZSVv=I
z7+}CS!1gnYIsjV;@BpJF6o}P;n3;ko`T^8C2Z$fxGXt9g5`h{tDX<t>D?vwKb3i-P
z=O2OeLoytqho%RwBd|H33u?e6AiabP2f*|b6%zDv0LU>|LxP?TfH|TLIcVtZ0Fd2f
zL&gDQq(7px5FG+UnMQ`9Q3ni<5cms>`*T2i51Iy)fwUo!l^4Y!@Dpg!EFgZ2mH=ge
z{4^kDCy+2HcEBc}1xIjLVgnTSqqPH?ffjtmVF@o#yq4AuC<j{bABQENqP>&W4(J71
z@Dhh55<u}HT07tj(1KMsEC~aOo6y<;AoKSF@opgg1GS6=NV@{DBLT}n(gbq>tVu@5
ztZzUCuqK;4kj+I%15h4RepDi>qjjSc-A&hl0`mzufLhIRWP3n9zXimrf%pp{2M`gG
h)KfCrH5>2{0039UNg=?aI*kAT002ovPDHLkV1hFxkPH9-

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xhdpi/ic_action_save.png b/app/src/main/res/drawable-xhdpi/ic_action_save.png
new file mode 100644
index 0000000000000000000000000000000000000000..16927204caae70368849ffce621fce712d86756c
GIT binary patch
literal 807
zcmV+?1K9kDP)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF0008+Nkl<ZcwX&V
zJ4hZu5LTig@j<N8L>ocud^BkSV#;WdMo_S}u(7bv!a`G6Xd##sDbfjo0V_dUO|Xy@
zzB*AvP#Y`7CmPXjzytZ+yPJLd+}zzR4Eo>A%+B}iw|lQGEy;N+%{l%OPk>iI&KdAi
zAm;+`i=fUFsDoPCU=6UhFr8S}LOVplU$7h7#9R<f=%@!)X4|2|_&wyBu_b{+0F8XV
zFz^A7)=J<I(2L%h9gdvqR8~sh5HN;{D_mFYIG?c+I0Q^67Q8haJ8%plEFG;qoMxm1
z4gr&j-sf;^ol}(qA65ThX|<J*H3EnjEhS`;03v~{gsc+4Rzj8u2$b+6Y8}ct0fc?X
z6A;0GR{-NWou>N$6&ybWim?VTgd@hKC<+jRj!}pwz)yi9Tm~7+6XW8ifS&?>3WPIY
zdMhkuf-?&7Yk<Tx;6I8wf}K4T_YQw+Va53HB1!?50J#j?fSnhNOf`PD!al<)8Pevu
zh#_DH75|1^#8h5|^WCsUF2Wc;5d<8g$e*xVCaBl&qt9_4nEp|2i4#Dezr#*6!Mun6
z0F216X^9i?57o~bBIrWgN5j}4EO7$pJN~XA2-=I#XBaDnfN!XTR)3R5SA$WLz-KXu
zD<HA}1~{E>gQ|3i6EK3R?ifH-F6B5lZWt?O3QVICx(u2$x;vyRflW(X0ZXWU#Sj7A
z6@D>{6{CPtR5AtA-O=?1F@vz0v=cz}ufi5IfqaGkC(Rg@d*V|dC~6V^{9yuWhhGQN
zH_lBA0aWNFjED#xgA0qN$Kp;{OB^bV^VS5YHc4sp|HAbiNA{oW`TKx+93y*Wle{4I
z0l$Z%@^M~?jUj>bZE|54uW*9u4{aO*q;Hgr!ncK!v$h0C-YOe~jb6LaI|$k^Wu*WL
zmbh6u4m|B;+>TpMI8z|VA!)n33KuPS*D!kY{u?*)K>{5D;>b+pc~3wphs|NpUI7lt
lOl2ysfK(2f!=iJqfJX!{kwN&_59<H`002ovPDHLkV1fhCTwnkI

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_save.png b/app/src/main/res/drawable-xxhdpi/ic_action_save.png
new file mode 100644
index 0000000000000000000000000000000000000000..42bf5966dc034829cc3a357a071573164cd22ff7
GIT binary patch
literal 1274
zcmV<W1O@wvP)<h;3K|Lk000e1NJLTq003YB003YJ1^@s6;+S_h000ERNkl<ZcwX(D
zIfxWN6oz*_5RX7mOcWhO@CZyi5ky5J4-_>p6cevpF;P|!(Zt9D1HsHd#oI*jL_8A%
z4-g#`6HzemKs^5+reV?D?pM|Ix~6Mh!((QdSMOE*U)SrNp6=T2F599i&>c0qCGRo-
zk#_<EU;rX35IMcg00R(Nfyn7?1{i?I3PetCGr#~uRv>bEn*j*`XkZL8VUuAaVFM$N
zsciZ?2ynh^5NZ1|Ghh&stb)yk4Ui_RiQgsk^JW!&^#wrj*TZI1(a8uoek13VDj@g*
zSc}fhjUY_bDb>r74*=Hu%?XyB{@|*XBOd^rviD~|RLhYMfF0=BsH$s08{|_dM?L`d
z6`X4R!smb5K(PM0z!M1HEqFQd0dOFv_Z0si?2GRRD`>a7M2_I)C^Ued7~I}A2avY|
zN!bJ|M+QJD`Tu@F%8>!^2N0wj832C(S<6!8$N-cFzzE*u$N+=^;9ZUkKo|ht<;Vbp
z1;A+AT|ycF7qw)*2B1Kv5MRXdQWyXO(B9XAYzD|mshXDoP?J^`*Z|0MQu9h0fSPJG
z3LNz;s75-eb=3f<Nh=F%0AxC;c^LpTX=Q;8fJ`SfF9V<^tt_wskm;o6WdPKql?65c
zGM&`C41k)nvcLvFrjweN0Z@}x7T5sDbW-y&0BX|80(T4mK7;VRrO6Py`rP3mlhn;C
zX#nq_#WUC|*az6RmNrB2IvO?!HVrn`O|zihNdkBei7vyQ!+0BD-o|H^r^1%O#srmC
z7Az?MeB$OB>^h9^T{b?kzZkXzR^`+C$pB!DKLvZ}qIw^`e3E}1tg2%~G63#Dv@<2e
z&zi5nn|Xm^6@^IxKog@p2IDhlAvQi4xd}EQM6iMwwFkh`a~$>}uvk+NZ({|esP+Kf
zK%_&k(9at47_bdCJ}}sS!_^+Z1&rvnl1K{>ccoJ7ENtxo9L7j^4A9sb2)b1xaIcuP
z2e1c&`K%<;2*ll`6g!z2z{Nm9*Z)i$9tZXtfP4iEK*1iOeRpvW@@p;jF&weWEY=~J
zJheXt9Kk4GOGfJ9GZAgJc(ikAQhNXwG1^-$BX;mz2;b!n{ywg?2f%CnM}0;vXv4Mc
z_?v;|R(k+E13CeF8d#<2h_@kd%)Y|a9smdRwlxcW1QKj;tM-oz6fZAK5&$^B8!-L~
z7GmSCV~aur62wRb087z1*j>S(^IYcRLoTswKgf6p$=`puhVxaJYdK=sSqkHsPnBz1
zCo=<j^Wr6Ho}M;^5F7AY0n@(p+*fy!1dt7scSrE-h+ot`!oIdX7=~9aCd)5cJllzJ
zH$>J)bpS;Rw+eUCAa2>65>?*ykk@hcXQ#`^d=5;Vx^%HbSI$bOtF1l&I&JZ8iSU`v
zeY`pC(!d7*4{)8de7#gpp0V)~N>kc^em(%$jyF2ZaY@txz7H@)-bm)O`2tA&Uzj+F
z2<IoTlQ8G|n0x`SgM_deHVane7adn|H2qn29>LD~h+n1z^&V6Mf28zptcrl~RPz(;
zCG0V*S=1o!^D;A_OkQi-QosO2-W3dh0f?+X<n%TJ3_xTBBB!?*U;rX35IMcg00R(N
kfyn7?1{i?I3Peu-7sTY{VYt|_;s5{u07*qoM6N<$f`dpaivR!s

literal 0
HcmV?d00001


From ba8b96c22ed0f269a89bf602bafc2bd24880601e Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 20 Aug 2014 23:38:44 +0200
Subject: [PATCH 45/59] Revert "Showing connection error DO NOT MERGE"

It doesn't work right now. Work moved into error branch.

This reverts commit 5d635e4408cd71c4589dae91753410a1b9320aa6.
---
 .../mysqlbrowser/db/AsyncDatabaseConnector.java      | 12 +-----------
 app/src/main/res/values/strings.xml                  |  1 -
 2 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index 3aceda8..8a8872f 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -12,15 +12,12 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.UnsupportedEncodingException;
-import java.net.ConnectException;
 import java.net.HttpURLConnection;
 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
@@ -403,14 +400,7 @@ public class AsyncDatabaseConnector {
             urlConnection.setReadTimeout(READ_TIMEOUT);
             urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
             urlConnection.setRequestMethod(CONNECTION_REQUEST_METHOD);
-            try {
-                urlConnection.connect();
-            } catch (ConnectException e) {
-//                errorMsg = e.getMessage();
-                if (e.getCause().equals(CONNECTION_REQUEST_METHOD)) {
-                    errorMsg == R.string.error_connection_timeout; // FIXME
-                }
-            }
+            urlConnection.connect();
 
             if(urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                 try {
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c1647e7..d7b1d0e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -49,6 +49,5 @@
     <string name="save_credentials">Save credentials</string>
     <string name="connector_url">Connector URL</string>
     <string name="no_connection">No Internet Connection</string>
-    <string name="error_connection_timeout">Connection timeout</string>
 
 </resources>

From d478b474fb3e1a143d9ad25ddd3464b42a0a8c54 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Thu, 21 Aug 2014 15:17:36 +0200
Subject: [PATCH 46/59] Connection error handling

---
 .../nerull7/mysqlbrowser/LoginFragment.java   |  2 +-
 .../db/AsyncDatabaseConnector.java            | 81 +++++++++++++------
 app/src/main/res/values-pl/strings.xml        |  3 +
 app/src/main/res/values/strings.xml           |  4 +
 4 files changed, 66 insertions(+), 24 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
index b3b048c..d0a1eee 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
@@ -86,7 +86,7 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
         url = urlTextbox.getText().toString();
 
         if(Static.isNetworkConnected(getActivity())) {
-            asyncDatabaseConnector = new AsyncDatabaseConnector(login, password, url);
+            asyncDatabaseConnector = new AsyncDatabaseConnector(login, password, url, getActivity().getResources());
             asyncDatabaseConnector.setBooleanReturnListener(this);
             asyncDatabaseConnector.setOnPostExecuteListener(this);
             asyncDatabaseConnector.checkLogin();
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index 8a8872f..5c0bac3 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -1,5 +1,6 @@
 package info.nerull7.mysqlbrowser.db;
 
+import android.content.res.Resources;
 import android.os.AsyncTask;
 import android.util.Log;
 import android.widget.ArrayAdapter;
@@ -12,12 +13,17 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.UnsupportedEncodingException;
+import java.net.ConnectException;
 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
@@ -39,6 +45,8 @@ public class AsyncDatabaseConnector {
 
     private String database;
 
+    private final Resources resources;
+
     private BooleanReturnListener booleanReturnListener;
     private IntegerReturnListener integerReturnListener;
     private StringReturnListener stringReturnListener;
@@ -48,10 +56,11 @@ public class AsyncDatabaseConnector {
     public static String errorMsg;
     private OnPostExecuteListener onPostExecuteListener;
 
-    public AsyncDatabaseConnector(String login, String password, String url){
+    public AsyncDatabaseConnector(String login, String password, String url, Resources resources){
         this.login = login;
         this.password = password;
         this.url = url;
+        this.resources = resources;
 
         booleanReturnListener=null;
         stringReturnListener=null;
@@ -104,8 +113,9 @@ public class AsyncDatabaseConnector {
                 if(listReturnListener!=null) {
                     listReturnListener.onListReturn(list);
                 }
+                errorMsg = error;
             }
-        }, onPostExecuteListener);
+        }, onPostExecuteListener, resources);
         downloader.execute(urlQuery);
     }
 
@@ -119,8 +129,9 @@ public class AsyncDatabaseConnector {
                 } catch (JSONException e) { e.printStackTrace(); }
                 if(matrixReturnListener!=null)
                     matrixReturnListener.onMatrixReturn(list);
+                errorMsg = error;
             }
-        }, onPostExecuteListener);
+        }, onPostExecuteListener, resources);
         downloader.execute(urlQuery);
     }
 
@@ -161,10 +172,9 @@ public class AsyncDatabaseConnector {
                     errorMsg = data;
                     listenerData = false;
                 }
-
                 booleanReturnListener.onBooleanReturn(listenerData);
             }
-        }, onPostExecuteListener);
+        }, onPostExecuteListener, resources);
         downloader.execute(actionUrlBuilder(ACTION_LOGIN));
         return false;
     }
@@ -226,8 +236,9 @@ public class AsyncDatabaseConnector {
             public void onFinished(String data, String error) {
                 if(integerReturnListener!=null)
                     integerReturnListener.onIntegerReturn(Integer.parseInt(data));
+                errorMsg = error;
             }
-        }, onPostExecuteListener);
+        }, onPostExecuteListener, resources);
         downloader.execute(urlQuery);
     }
 
@@ -280,8 +291,9 @@ public class AsyncDatabaseConnector {
                 if(stringReturnListener!=null){
                     stringReturnListener.onStringReturn(data);
                 }
+                errorMsg = error;
             }
-        }, onPostExecuteListener);
+        }, onPostExecuteListener, resources);
         downloader.execute(request);
     }
 
@@ -321,8 +333,9 @@ public class AsyncDatabaseConnector {
                 if(stringReturnListener!=null){
                     stringReturnListener.onStringReturn(data);
                 }
+                errorMsg = error;
             }
-        }, onPostExecuteListener);
+        }, onPostExecuteListener, resources);
         downloader.execute(request);
     }
 
@@ -378,14 +391,16 @@ public class AsyncDatabaseConnector {
         private OnFinishedListener onFinishedListener;
         private OnPostExecuteListener onPostExecuteListener;
         private String errorString;
+        private Resources resources;
 
         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, OnPostExecuteListener onPostExecuteListener){
+        Downloader(OnFinishedListener onFinishedListener, OnPostExecuteListener onPostExecuteListener, Resources resources){
             this.onFinishedListener = onFinishedListener;
             this.onPostExecuteListener = onPostExecuteListener;
+            this.resources = resources;
             errorString = null;
         }
 
@@ -400,22 +415,42 @@ public class AsyncDatabaseConnector {
             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();
+            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();
                 }
-                return response;
+            } catch (Exception e) {
+                parseException(e);
             }
-            else {
-                errorString = "ERROR "+urlConnection.getResponseCode()+": "+urlConnection.getResponseMessage();
-                return null;
+            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();
             }
         }
 
@@ -440,7 +475,7 @@ public class AsyncDatabaseConnector {
         protected String doInBackground(String... strings) {
             try {
                 String data = httpRequest(strings[0]);
-                onFinishedListener.onFinished(data, errorMsg); // Can't be null cos we demand listener in constructor
+                onFinishedListener.onFinished(data, errorString); // Can't be null cos we demand listener in constructor
             } catch (IOException e) {
                 e.printStackTrace();
             }
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 35ba264..44d7f9e 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -37,6 +37,9 @@
     <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>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d7b1d0e..ec32bc1 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -43,6 +43,10 @@
     <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="login_settings">Login credentials</string>

From fae910fc8c3df91de1a8fa0773a16193b85740e1 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Tue, 16 Sep 2014 11:25:54 +0200
Subject: [PATCH 47/59] Time to POST it

Moved away from sending data in GET request and now using POST requests.
---
 .../db/AsyncDatabaseConnector.java            | 68 ++++++++++++-------
 1 file changed, 42 insertions(+), 26 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index 5c0bac3..277dbb7 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -2,8 +2,6 @@ package info.nerull7.mysqlbrowser.db;
 
 import android.content.res.Resources;
 import android.os.AsyncTask;
-import android.util.Log;
-import android.widget.ArrayAdapter;
 
 import org.json.JSONArray;
 import org.json.JSONException;
@@ -12,8 +10,9 @@ 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.ConnectException;
 import java.net.HttpURLConnection;
 import java.net.SocketException;
 import java.net.SocketTimeoutException;
@@ -68,16 +67,17 @@ public class AsyncDatabaseConnector {
         matrixReturnListener=null;
     }
 
-    private String actionUrlBuilder(String action){
-        String urlBuilder = url;
-        urlBuilder += "?u="+login;
-        urlBuilder += "&p="+password;
-        urlBuilder += "&a="+action;
+    private Request requestBuilder(String action){
+        Request request = new Request(url);
+        String urlData   = "u="+login
+                         + "&p="+password
+                         + "&a="+action;
+        request.data = urlData;
 
-        return urlBuilder;
+        return request;
     }
 
-    private String actionUrlBuilder(String action, String argument, String value){
+    private Request actionUrlBuilder(String action, String argument, String value){
         ArrayList<String> arguments = new ArrayList<String>();
         ArrayList<String> values = new ArrayList<String>();
         arguments.add(argument);
@@ -85,11 +85,11 @@ public class AsyncDatabaseConnector {
         return this.actionUrlBuilder(action, arguments, values);
     }
 
-    private String actionUrlBuilder(String action, List<String> arguments, List<String> values){ // TODO Better UrlBuilder this is shit only for use
-        String urlBuilder = actionUrlBuilder(action);
+    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 += "&" + arguments.get(i) + "=" + URLEncoder.encode(values.get(i), "UTF-8");
+                urlBuilder.data += "&" + arguments.get(i) + "=" + URLEncoder.encode(values.get(i), "UTF-8");
             } catch (UnsupportedEncodingException e) {
                 e.printStackTrace();
             }
@@ -102,7 +102,7 @@ public class AsyncDatabaseConnector {
         this.database = database;
     }
 
-    private void getList(String urlQuery){
+    private void getList(Request urlQuery){
         Downloader downloader = new Downloader(new Downloader.OnFinishedListener() {
             @Override
             public void onFinished(String data, String error) {
@@ -119,7 +119,7 @@ public class AsyncDatabaseConnector {
         downloader.execute(urlQuery);
     }
 
-    private void getMatrix(String urlQuery){
+    private void getMatrix(Request urlQuery){
         Downloader downloader = new Downloader(new Downloader.OnFinishedListener() {
             @Override
             public void onFinished(String data, String error) {
@@ -175,12 +175,12 @@ public class AsyncDatabaseConnector {
                 booleanReturnListener.onBooleanReturn(listenerData);
             }
         }, onPostExecuteListener, resources);
-        downloader.execute(actionUrlBuilder(ACTION_LOGIN));
+        downloader.execute(requestBuilder(ACTION_LOGIN));
         return false;
     }
 
     public void getDatabases(){
-        getList(actionUrlBuilder(ACTION_DATABASE_LIST));
+        getList(requestBuilder(ACTION_DATABASE_LIST));
     }
 
     public void getTables(){
@@ -230,7 +230,7 @@ public class AsyncDatabaseConnector {
         args.add("t");
         values.add(table);
 
-        String urlQuery = actionUrlBuilder(ACTION_ENTRIES_COUNT, args, values);
+        Request urlQuery = actionUrlBuilder(ACTION_ENTRIES_COUNT, args, values);
         Downloader downloader = new Downloader(new Downloader.OnFinishedListener() {
             @Override
             public void onFinished(String data, String error) {
@@ -249,7 +249,7 @@ public class AsyncDatabaseConnector {
     public void updateElement(String table, List<String> header, List<String> oldValues, List<String> newValues){
         JSONArray headerJSON = new JSONArray();
         JSONArray newValuesJSON = new JSONArray();
-        String request;
+        Request request;
 
         ArrayList<String> args = new ArrayList<String>();
         ArrayList<String> values = new ArrayList<String>();
@@ -300,7 +300,7 @@ public class AsyncDatabaseConnector {
     public void removeElement(String table, List<String> header, List<String> values) {
         JSONArray headerJSON = new JSONArray();
         JSONArray valuesJSON = new JSONArray();
-        String request;
+        Request request;
 
         ArrayList<String> args = new ArrayList<String>();
         ArrayList<String> argValues = new ArrayList<String>();
@@ -387,13 +387,13 @@ public class AsyncDatabaseConnector {
         void onPostExecute();
     }
 
-    private static class Downloader extends AsyncTask<String, Void, String> {
+    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 = "GET";
+        public static final String CONNECTION_REQUEST_METHOD = "POST";
         public static final int CONNECTION_TIMEOUT = 15000;
         public static final int READ_TIMEOUT = 10000;
 
@@ -404,8 +404,8 @@ public class AsyncDatabaseConnector {
             errorString = null;
         }
 
-        private String httpRequest(String urlRequest) throws IOException {
-            URL url = new URL(urlRequest);
+        private String httpRequest(Request urlRequest) throws IOException {
+            URL url = new URL(urlRequest.url);
             InputStream inputStream = null;
             String response;
 
@@ -416,6 +416,13 @@ public class AsyncDatabaseConnector {
             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();
 
@@ -472,9 +479,9 @@ public class AsyncDatabaseConnector {
         }
 
         @Override
-        protected String doInBackground(String... strings) {
+        protected String doInBackground(Request... requests) {
             try {
-                String data = httpRequest(strings[0]);
+                String data = httpRequest(requests[0]);
                 onFinishedListener.onFinished(data, errorString); // Can't be null cos we demand listener in constructor
             } catch (IOException e) {
                 e.printStackTrace();
@@ -497,4 +504,13 @@ public class AsyncDatabaseConnector {
         }
 
     }
+
+    class Request{
+        String url;
+        String data;
+
+        Request(String url){
+            this.url = url;
+        }
+    }
 }

From 7b5e2ddd6dd064c5821923eb55b6b81134959083 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 17 Sep 2014 13:43:35 +0200
Subject: [PATCH 48/59] Support for ICS (API 14)

---
 app/build.gradle | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/build.gradle b/app/build.gradle
index f0efe31..06e72d4 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -6,7 +6,7 @@ android {
 
     defaultConfig {
         applicationId "info.nerull7.mysqlbrowser"
-        minSdkVersion 15
+        minSdkVersion 14
         targetSdkVersion 19
         versionCode 1
         versionName "1.0"

From 6c842541c3bd579d43572027277c7b416bc85186 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Tue, 30 Sep 2014 15:41:43 +0200
Subject: [PATCH 49/59] Half implementation of SQL Query

 Need to finish it.
---
 app/src/main/AndroidManifest.xml              |   4 +
 .../nerull7/mysqlbrowser/ListActivity.java    |   4 +-
 .../nerull7/mysqlbrowser/SQLActivity.java     |  22 ++++++
 .../nerull7/mysqlbrowser/SQLFragment.java     |  72 ++++++++++++++++++
 .../info/nerull7/mysqlbrowser/Static.java     |   5 ++
 .../db/AsyncDatabaseConnector.java            |  44 ++++++++++-
 .../drawable-hdpi/ic_action_file_upload.png   | Bin 0 -> 380 bytes
 .../drawable-mdpi/ic_action_file_upload.png   | Bin 0 -> 271 bytes
 .../drawable-xhdpi/ic_action_file_upload.png  | Bin 0 -> 466 bytes
 .../drawable-xxhdpi/ic_action_file_upload.png | Bin 0 -> 832 bytes
 app/src/main/res/layout/activity_sql.xml      |   7 ++
 app/src/main/res/layout/fragment_sql.xml      |  24 ++++++
 app/src/main/res/menu/logged.xml              |  12 +++
 app/src/main/res/menu/sql.xml                 |  15 ++++
 app/src/main/res/values/strings.xml           |   5 ++
 15 files changed, 211 insertions(+), 3 deletions(-)
 create mode 100644 app/src/main/java/info/nerull7/mysqlbrowser/SQLActivity.java
 create mode 100644 app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java
 create mode 100644 app/src/main/res/drawable-hdpi/ic_action_file_upload.png
 create mode 100644 app/src/main/res/drawable-mdpi/ic_action_file_upload.png
 create mode 100644 app/src/main/res/drawable-xhdpi/ic_action_file_upload.png
 create mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_file_upload.png
 create mode 100644 app/src/main/res/layout/activity_sql.xml
 create mode 100644 app/src/main/res/layout/fragment_sql.xml
 create mode 100644 app/src/main/res/menu/logged.xml
 create mode 100644 app/src/main/res/menu/sql.xml

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 39f66fe..f6b00ce 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -34,6 +34,10 @@
             android:name=".ElementActivity"
             android:label="@string/title_activity_element" >
         </activity>
+        <activity
+            android:name=".SQLActivity"
+            android:label="@string/title_activity_sql">
+        </activity>
     </application>
 
     <uses-permission android:name="android.permission.INTERNET" />
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java
index e2863fd..c88c75f 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.main, menu);
+        getMenuInflater().inflate(R.menu.logged, menu);
         return true;
     }
 
@@ -47,6 +47,8 @@ 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);
         }
         return super.onOptionsItemSelected(item);
     }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/SQLActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/SQLActivity.java
new file mode 100644
index 0000000..396ce94
--- /dev/null
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/SQLActivity.java
@@ -0,0 +1,22 @@
+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/SQLFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java
new file mode 100644
index 0000000..0ba7079
--- /dev/null
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java
@@ -0,0 +1,72 @@
+package info.nerull7.mysqlbrowser;
+
+import android.app.Activity;
+import android.app.Fragment;
+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;
+
+/**
+ * Created by nerull7 on 30.09.14.
+ */
+public class SQLFragment extends Fragment{
+    private EditText sqlEditText;
+    private InputMethodManager inputMethodManager;
+
+    @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);
+
+        Static.asyncDatabaseConnector.setOnPostExecuteListener(null);
+        Static.asyncDatabaseConnector.executeSQL(null /*FIXME*/, sqlQuery);
+    }
+}
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
index 6e59148..01d7d35 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
@@ -51,4 +51,9 @@ public class Static {
         builder.create();
         builder.show();
     }
+
+    public static void startSQL(Context context) {
+        Intent intent = new Intent(context, SQLActivity.class);
+        context.startActivity(intent);
+    }
 }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index 277dbb7..42a8e04 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -2,6 +2,7 @@ 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;
@@ -37,6 +38,7 @@ public class AsyncDatabaseConnector {
     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;
@@ -339,6 +341,44 @@ public class AsyncDatabaseConnector {
         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");
+
+                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);
+            }
+        }, onPostExecuteListener, resources);
+        downloader.execute(request);
+    }
+
     public void setBooleanReturnListener(BooleanReturnListener booleanReturnListener){
         this.booleanReturnListener = booleanReturnListener;
     }
@@ -468,14 +508,14 @@ public class AsyncDatabaseConnector {
                 reader = new BufferedReader(new InputStreamReader(in));
                 String line;
                 while ((line = reader.readLine()) != null) {
-                    streamOutput += line;
+                    streamOutput += line + '\n';
                 }
             } finally {
                 if (reader != null) {
                     reader.close();
                 }
             }
-            return streamOutput;
+            return streamOutput.substring(0, streamOutput.length()-1); // Remove last \n
         }
 
         @Override
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
new file mode 100644
index 0000000000000000000000000000000000000000..4910c3a51ea2c2c6cacf5c1bf24b4022ae8d48bf
GIT binary patch
literal 380
zcmV-?0fYXDP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm0003)Nkl<ZXhZFn
zO$x$5424@k&*efqlDH5NaUmW_TzD=8aRw@krEPvD&#@(i(nZtE`;s>_Q&%Iu>XGZO
z9H4Xuy#rJ4z`6mvqCk-risDy|@LPC7AW#6Q_)qa65D0)S@h}K$fFbb^2ulEtcykCV
z0Eu{02nzs>cr%DxfE@8A5IF!A;<F*N0G8sjAT$67@oESu08+dPLISW%W}B|rY#|)j
z9s}`l?6`CCNdRU<!ZT;VBxXy*zc~3M093vU70`OW5yp3hJ3vwv?|{ZqZXvgj#y80~
zZXvhOA6e)m)Up%C!~ew8tkf33nsq2h%S}wJ1$plPkg^Jrayt<HeGIqs&?1oX6&epa
z`*4%{!~wJ=CccAo;P7J$#r4cA6bm*7Rl6_kld~Ro4{&l7iE)4;We1%Him<qaij;jy
a7J35@$Tu-sra*rH0000<MNUMnLSTX+yOps3

literal 0
HcmV?d00001

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
new file mode 100644
index 0000000000000000000000000000000000000000..8374b8d217e64cd212b5d2498b40d8e3cb36fe8f
GIT binary patch
literal 271
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJYo0ESArbD$DG~_>EDn4#?y+jP
zBv8=o_E4{A@gyPk2A%T8s6Ff+lb>=F$u{Izp81?&*(AfBuz607`-E2vHPe6+K{5_K
zPgSg&BG@M+S$g&<9AkVE;kQMZ!?Ho>bY~HZ9s34m-+;qG2aX77l!zry+|MfVyVF;G
zp}>J<%exzxPkCsHy2~0!F)dbf@Z)$PbRunf=3HJ+!}$xMikuo2EL@^-;5kD;fUs6s
z=T`0zo8;bEj&B((7p#8U@l}bjw7ua||B6t_z>~fL$!w)cOIG<8N}5SAG3@@Nq?nw$
Rc@@xy44$rjF6*2UngADGVh8{L

literal 0
HcmV?d00001

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
new file mode 100644
index 0000000000000000000000000000000000000000..702ea4ef6c6b2c1202ca33a99c04527077a7bfc2
GIT binary patch
literal 466
zcmV;@0WJQCP)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF0004*Nkl<ZcwX(8
zy$!-J5QSj{Y6^Csqy(`7n=k~MumXaTk{u|hSpggoD54~?eRuDS{Ag&-f8YCjmNK1G
z{+m{Q{s{rlfXWH*3RErto1pg<*tQ0qyiD{2&>Vi<9{dviT_AV?Xb!*Wq<;2*-~r&9
ze0S|v001`u4WKXi?)8V7fCMm<d=~)J1QdXn<Xuca0EkWA#RO{rImts!umq5sJk$g$
z02;|dOt1i;l{~}*Z2%U@o0^~rz$$rD6SM#zk~c9y0{|*{6BDEWJd#&6K?1-lc~ui~
z0nEcLR*_$EmXUQsWw*%j*HHI}to@bc0!UfskW$=JyBCfh9Zmq2blbUUfDkgTfDj;i
zz!(8GK})^Z1V04$3J5LZD<A~OSAeg;2mwBWmiLR#;D^9Y2>B=+@7@G0_b;9s(F4Sr
zw48tdEb0Ek+%zCFrKYn>zxHM>JvglSdYt@X<QhN#G=Nv2?jEoRS74^y#f0-c!}xpZ
z9Jx&}b)91C382_$KpUe0Akf7wLj#J92DC9600Ld?GSwUK1{&5%L0@*GGXMYp07*qo
IM6N<$f@6WctN;K2

literal 0
HcmV?d00001

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
new file mode 100644
index 0000000000000000000000000000000000000000..8e78556a3584fd8d4870943c6a7e872c4dd5ad21
GIT binary patch
literal 832
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>U}pDpaSW-5dppO`i`h}YRrt=!
ziFa1M=yh=va17WpanU=QN$*_J4Hy^m*qi=cy;`eAk;SL<>yy3f&U190Zmo0T)NwAq
z{*0TG!;VErf$<<q)As8u9u5YL58j$G3JLfqR8;#mu&@Yo+=~-dVBE~v)Be0<>#xj;
zf3xmt79?Kfj5ur`wXs@up10Qutp_;_c8B8Q|5yBS=j?B6ue^5cD$5%Ge;<$Ru3c%y
zIhEy4-`th2<NTdwTC7rekpIS~w`QfqDg}n4=caTB6;6pgV79SYO|euaReVG48wJkH
z_kEkVW=LB<eWbCtVcHGH$rJSYjJPs-WmObIWm1I>^vwloa&2&bv%u3s&^?l+;waxF
z0Xg@JOjSqyZdr7RTre)Xpwe<Qa7n|xjm;`8M*>?KUfl2$b>GXH(jjZY8T)v}_68lG
zOiB0RIHpa<{3>L=3QVvB>e+ETke~5pGP`F%ud+Ym)g*P5zCA1<JwQErg-=u$WC7jw
z#p07dfyJKg$&vGeenpmC*ibfm>HFIvzE^Dc_t$4f{Lf$6-mv!=_nz#S{%P@xm_GbU
zfBdWWsT@<(`u7XBGDg(DyL10a9FxzEA4i1_q-VX-U{s6wlf?PJ*tB#CgRoxRMwSmV
zXIXhQaEkAbVEW<XE30~-r8{1Sv1Zw_KB0s|NA;&M*aZi>a~eE+B<{^Hf91->EHer|
zcB?j=zj7rIx3Pt8jMx8c-+A%lv7P%@*19pSov-c0uwwpe$Jq<78*@2a-xIvv+hKzr
z=Y)m?rh~V$nN$>JIDGgvt3g)S;NIbQUjFy`kuHhS`|lK5+ho*xZ%}t&>T!2w$~j=d
zXcqS+i*teUR?{gA()v|fSuRYxB{fZ;VB_QM3%}3IcRv1ki@nW_^6+iNuflErW&hz%
z`yI=AH08-HZ>E@!kDduNNbU^tXwZ(k6T@Vne4UH4;Ar=3Z-%rdQHqS~Dhi7^5A?)n
zs~iy3&(mX^F)_Q9WyhnVXH^-Di`GtH2;Z|~Crg6cI??<2W&Mdkc8ZgMIfKE|)z4*}
HQ$iB}zV&4+

literal 0
HcmV?d00001

diff --git a/app/src/main/res/layout/activity_sql.xml b/app/src/main/res/layout/activity_sql.xml
new file mode 100644
index 0000000..43ab1db
--- /dev/null
+++ b/app/src/main/res/layout/activity_sql.xml
@@ -0,0 +1,7 @@
+<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_sql.xml b/app/src/main/res/layout/fragment_sql.xml
new file mode 100644
index 0000000..1298338
--- /dev/null
+++ b/app/src/main/res/layout/fragment_sql.xml
@@ -0,0 +1,24 @@
+<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/logged.xml b/app/src/main/res/menu/logged.xml
new file mode 100644
index 0000000..5d31f08
--- /dev/null
+++ b/app/src/main/res/menu/logged.xml
@@ -0,0 +1,12 @@
+<?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
new file mode 100644
index 0000000..5bc3b39
--- /dev/null
+++ b/app/src/main/res/menu/sql.xml
@@ -0,0 +1,15 @@
+<?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/strings.xml b/app/src/main/res/values/strings.xml
index ec32bc1..d4c83cb 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -53,5 +53,10 @@
     <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>
 
 </resources>

From b5615d75917fbf055837db1b902f6d157402e661 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 1 Oct 2014 11:40:22 +0200
Subject: [PATCH 50/59] SQL queries

 Full support
---
 .../mysqlbrowser/DatabaseFragment.java        |   6 +
 .../nerull7/mysqlbrowser/ListActivity.java    |   2 +-
 .../mysqlbrowser/SQLEntriesFragment.java      | 245 ++++++++++++++++++
 .../nerull7/mysqlbrowser/SQLFragment.java     |  24 +-
 .../info/nerull7/mysqlbrowser/Static.java     |   3 +-
 .../db/AsyncDatabaseConnector.java            |  35 ++-
 .../main/res/drawable-hdpi/ic_action_info.png | Bin 0 -> 696 bytes
 .../main/res/drawable-mdpi/ic_action_info.png | Bin 0 -> 469 bytes
 .../res/drawable-xhdpi/ic_action_info.png     | Bin 0 -> 891 bytes
 .../res/drawable-xxhdpi/ic_action_info.png    | Bin 0 -> 1577 bytes
 app/src/main/res/values/strings.xml           |   1 +
 11 files changed, 298 insertions(+), 18 deletions(-)
 create mode 100644 app/src/main/java/info/nerull7/mysqlbrowser/SQLEntriesFragment.java
 create mode 100644 app/src/main/res/drawable-hdpi/ic_action_info.png
 create mode 100644 app/src/main/res/drawable-mdpi/ic_action_info.png
 create mode 100644 app/src/main/res/drawable-xhdpi/ic_action_info.png
 create mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_info.png

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
index c70f172..91a6ff4 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
@@ -31,6 +31,12 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic
     private ProgressBar progressBar;
     private List<String> databases;
 
+    @Override
+    public void onResume() {
+        super.onResume();
+        Static.asyncDatabaseConnector.setDatabaseInUse(null);
+    }
+
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
         //Inflate the layout for this fragment
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java
index c88c75f..3eeb667 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java
@@ -48,7 +48,7 @@ public class ListActivity extends Activity {
             Static.startSettings(this);
             return true;
         } else if (id == R.id.action_sql){
-            Static.startSQL(this);
+            Static.startSQL(this, getIntent().getExtras().getString(Static.DATABASE_NAME_ARG));
         }
         return super.onOptionsItemSelected(item);
     }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/SQLEntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/SQLEntriesFragment.java
new file mode 100644
index 0000000..4c1af95
--- /dev/null
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/SQLEntriesFragment.java
@@ -0,0 +1,245 @@
+package info.nerull7.mysqlbrowser;
+
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.HorizontalScrollView;
+import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
+import android.widget.ScrollView;
+import android.widget.TableLayout;
+import android.widget.TableRow;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
+
+/**
+ * Created by nerull7 on 15.07.14.
+ *
+ * Fragment for showing elements
+ */
+public class SQLEntriesFragment extends Fragment implements AsyncDatabaseConnector.MatrixReturnListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.OnPostExecuteListener, AsyncDatabaseConnector.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
index 0ba7079..c67bc2e 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java
@@ -2,6 +2,7 @@ package info.nerull7.mysqlbrowser;
 
 import android.app.Activity;
 import android.app.Fragment;
+import android.app.FragmentTransaction;
 import android.content.Context;
 import android.os.Bundle;
 import android.util.Log;
@@ -14,12 +15,16 @@ import android.view.ViewGroup;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
 
+import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
+
 /**
  * Created by nerull7 on 30.09.14.
  */
-public class SQLFragment extends Fragment{
+public class SQLFragment extends Fragment implements AsyncDatabaseConnector.OnPostExecuteListener {
     private EditText sqlEditText;
     private InputMethodManager inputMethodManager;
+    private SQLEntriesFragment sqlEntriesFragment;
+    private FragmentTransaction fragmentTransaction;
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -66,7 +71,20 @@ public class SQLFragment extends Fragment{
         String sqlQuery = String.valueOf(sqlEditText.getText());
         Log.d("SQLQUERY", sqlQuery);
 
-        Static.asyncDatabaseConnector.setOnPostExecuteListener(null);
-        Static.asyncDatabaseConnector.executeSQL(null /*FIXME*/, sqlQuery);
+        fragmentTransaction = getFragmentManager().beginTransaction();
+        sqlEntriesFragment = new SQLEntriesFragment();
+        fragmentTransaction.replace(R.id.container, sqlEntriesFragment);
+        fragmentTransaction.commit();
+
+        Static.asyncDatabaseConnector.setStringReturnListener(sqlEntriesFragment);
+        Static.asyncDatabaseConnector.setListReturnListener(sqlEntriesFragment);
+        Static.asyncDatabaseConnector.setMatrixReturnListener(sqlEntriesFragment);
+        Static.asyncDatabaseConnector.setOnPostExecuteListener(this);
+        Static.asyncDatabaseConnector.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/Static.java b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
index 01d7d35..ca0281e 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
@@ -52,8 +52,9 @@ public class Static {
         builder.show();
     }
 
-    public static void startSQL(Context context) {
+    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/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index 42a8e04..0162ca8 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -360,20 +360,29 @@ public class AsyncDatabaseConnector {
             public void onFinished(String data, String error) {
                 String []response = data.split("\n");
 
-                List<String>headerList = null;
-                try {
-                    headerList = parseListFromJSON(response[1]);
-                } catch (JSONException e) { e.printStackTrace(); }
-                if(listReturnListener!=null) {
-                    listReturnListener.onListReturn(headerList);
-                }
+                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);
+                    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);
diff --git a/app/src/main/res/drawable-hdpi/ic_action_info.png b/app/src/main/res/drawable-hdpi/ic_action_info.png
new file mode 100644
index 0000000000000000000000000000000000000000..75ecc1834177da3ec2c3baae4ede59d3bb423cbc
GIT binary patch
literal 696
zcmV;p0!RIcP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm0007iNkl<ZXhZE;
zJt#&|82&!O;;(EhvKf>zkg}jClv!jo8Z8J5o6#yVD-?xAi9soYO%^u!U67yWse8Y!
z>)w0rJ@=fi`^u@OudjRFpXZ$Sea~M$C%ol_`=9$KpqN2-fWB<aw5b^=frE_>8t_{O
zQ~~9V<8SzV2JV0x;M&1wT4HGl)WCrbpbe-^=*$E9p8+SpV?x<NcU=ON(9jFC1Espg
z9k~zuo&x*8OHy4r1X^Ka5U5USOws=d-?xGDBzlt&V4M#CT}cdR^gV*i4iGCp;u0u>
z!cm}E!yz4!O9-t4?<(Oq1UT~JMReZvnIu+KGZBZtP!Yl=Y@iuVTT!#1BEW<lQB9-e
z?;BBx9YuhpauU$3HjH0)1*RS5kxpZES_T43Y!rcE2zBaMbmDf_lZ14B4q!g%v||Wu
z1__1{;0ikh=q^$$fzv($3n>V2v0DUwt=M4%`p~&YXQ&(*(*&sY0NC^U6hwg2%+XJ}
zxAE$>LEs(+mYnb`*a{-hgs&4RM&G9B3Y1@Y4FnNj=rDw`*mmL6p^Cs5I<#cbd-!w#
ztf>gF_SYLA;NOhtmQb%NxA?;~Au<P8{&<>7)95_QCQo8)Jeg5%S`s|fQEw;#=EOWu
zk;Z$-+NeTw=@pm(3TJG85{oB5mZn0;<Vx%YgffKK(L@s43ZYm@Y@&?XA`q*Lc4HR$
zGn&M)7BUlC30pG|Yb%k}%^WYnxTXHFK>o??G{ax~frcbRA1O&d{GpyCL|?18OM&Q%
zEs_v_wMY`8FL&Kg5`Dey-5QB~;P8?V{lw%YBKDEbzuOl3%&Iyzh<WH%5wZ4N^+IFK
euqnmj348<P?Wr+h%~m%60000<MNUMnLSTaSOF9z(

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-mdpi/ic_action_info.png b/app/src/main/res/drawable-mdpi/ic_action_info.png
new file mode 100644
index 0000000000000000000000000000000000000000..944ab3d239f33c5ab2439a170e146d29744b8c10
GIT binary patch
literal 469
zcmV;`0V@89P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80004;Nkl<ZSVzT|
zKP*H+5XSFZiCl9vi718SBG*#Wi->46dKaBaC)8JIL`3w|v?3CslnAv(P!ivF_9bgG
z>&@<SnN7azyLYoQzn%U2>NVq1H;!M+1sDZ*3mSGE_(1&vy`^?21%LrN(3A@<#UjK#
zbmf3bc{Bj*<s#IEhDtsD7<@rD&>6(+L`xaKBwDUOBg(*`**jhwLl3d`e*w&((K6J?
z3|=(*#KQ@6EBT25u;=Ul5Zs42kTM|waLhL=q&=1}4#$2tCnSI+7|klu{tTN-XE%p>
zOwr~VHmAN_2*9P*g*3DM4t7V**(&O31prsa9>nF^FCoAJ-pwl<(If|e?Jl767{C_(
zU={{h*!x`xfZOZ#AR~LecktZbw*4WP!0(L&fLGW)Is0+c&4ji+*gl2;+~e00oaD{{
zhB$<HX8g*4IY8<VRLOui1gVp-3V=8XIV35|Fc%=Y3<+Sq5t(nr%!27*L;&;Sm=LBH
zl43J7y^<9WrkBzJ!t`41pG{^TCei_E@@bZEQtM62zKryqGA+LW6Sia_0)jgh00000
LNkvXXu0mjf`4r7(

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xhdpi/ic_action_info.png b/app/src/main/res/drawable-xhdpi/ic_action_info.png
new file mode 100644
index 0000000000000000000000000000000000000000..6e10fde30dd53259f71fc77743b17ffa6e375b8a
GIT binary patch
literal 891
zcmV->1BCpEP)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF0009*Nkl<ZcwX(B
zOQ=mz7{~7o1CJ<=n+$Xdr5I7j9e9i|p%h9H0|q803=9km44B-B0fi`qQcN)N7!ZmP
z1EFpPl2?((0Oj|uyLH;mK6|Zo*4let-`Vx=w$J^(_4w`e{Px=Yea5eT<Mr?B0qC^=
z;{>Yg0#jf;8x5eTXfhf<%KsOCzo9Sa9eRttR`G070vJaH7NA9F9-8S{p%2)<LeJ0(
z^xM<l$vg!BJ=tYwIhyWNigKe*m^?&}Mq5g`hoePI0IK*ZG=wHN=I?9v6Nh`~ZY&V7
z04%0J8__i18U@;a#_t+>8tDJmty=&SNofmGKd<A`_;4Bh2+h130JF$+JDL-kc_hC#
zq;mni4@oZ+z+5uhjV6U;n!x8fX`Vr^ebWvBpvvz;8uXfUX&rIa7lJPUHT!)Hdh+=P
zpq6mLr#tun(15qM0e!x#)oDyPiJS&T9{@W^w64*<tkU`aYj!y2;^YcI^ZX8%1RG>?
zp0bp#6I=jju-lJfE^<al?_&<u4DJUb0@Pw@7-?`Uyj%cmz<YJXf+?ws=t(ZkCERa|
zoX;K7yWR}|J^e!{_S(KG0NOho?bHg&TEH5d*GGOTRki@-bpzclszWCL+Rq<Av9`3W
zWvHqJC{JyrkE6EngiZh!;-uwnimOThD*tKpyj?{)0oaU#f*SwBrC`bxUjPSj@C{=%
z6_&zl$9w=NfO)v7wFxZO5&ZrMv=()N`55mB%&4hurzqIVeBp`!ti*6rQ)?1fuB-Un
zcLlHx!?l4Kxwt*RXe4Ji$o&cz=RliV_}z2`ka`BFdKy%{+s*_<U0^E?O9M%}xYYsR
zF$KHi+5*f2Fy94I4}x`c0k1(Y^)y%q0Iz8<^+Ko)0A35B)Jx$y0C+8hHCv?I3{?%l
zdov^eDQAMJ0R(M_%?Cuxhs4wkOb0~;z<gL-5KO-q$y$NwS7U-;`sHZ0g*N?qToBA3
zkPrmZM`W_DVET|$D+II0<T41R4@zbbOdpkPjWC-%EZqvh^l|w-2$LU7<X^fdo}l2W
zx<@yk%;>D2-s+B-PiFEUvU_tMO%;J?)bC}-<Qi4j6ou&lNI`WhrD?te`~g~!#6e&I
RlA-_r002ovPDHLkV1ke}kFx*(

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_info.png b/app/src/main/res/drawable-xxhdpi/ic_action_info.png
new file mode 100644
index 0000000000000000000000000000000000000000..6835e8f56a38d6298b74ec0316501d58e9c8af15
GIT binary patch
literal 1577
zcmV+^2G;qBP)<h;3K|Lk000e1NJLTq003YB003YJ1^@s6;+S_h000H>Nkl<ZcwX&Y
zU5Hji7<T;&Gb15?x~YYPia<p&F9cCRk`TJ+2Z<;U>LT?*M5PiWP(($%&=3?7MIzKL
zf`~$>5WMIIF(FbY*u7FqNHmp7)92a!4(=}B`Och~cg{QW?K|)w?ssP1nddq4`_9bi
z8Dl|}fgV-sW_*kZp!^b;049Jk1Ip&D2ABZK3@Dq=xdt%rV_W?FkALqfbLnM1bpa-$
zRF45OfJcExfQJD7eIhWfRq8wV_g~-!@HcQ3xB^@TF1G&eMNsTWsR=L%1%3v266gh{
z2@&uo(&+<!2Yv-^38fpHObP-p4^IKJTjcZYju}`>D8f150-)M-X$mj_g`W#N4?Gc*
z@eXPC<F_Axv%r5EdC(Bx0Tgrruoz%_o<d;1@g49z@K2K&YFdCfDBLn&dXt5$Ve1b(
zdlLA$Mx3BWn-X9Oa`^%<A85*^FEQ*BegwV-uKOn98m|d5*v7vIJm{LKM4r2ee0&M8
zkBAmx3cxWso0}yWy!B-Svo?I&YL+<H5D&2g;M@Kx@T_=_brSpqW{(4`6`~=A08^2}
zw*k&vyD4yHeGvFdvQW|jko30zE**4ZxP(F-0Vsw@kQ9J#{;Dn}zaX3<9FnRDQUb8e
zU(<!nPT5<|8n6!t?h_;g;ArO!pj$dz*QSLX^HCsZbR;3ba%5tuYp%QOxo=ROuR_Wc
zDgY;0F9V_Jgp@%uF6RlK0p63f5aPJJupY>5hAS-?`+?nn*Rn;30I$F(Yk-Bp8gRmg
z2wwrXs`<J?)59uHZ&sNTh2^1F&9_`W95N2`^9fLU71bxBT+d$%Xe=q;hTR<i*YDc}
z`WH3<<9(S7h{vVuy+AF0f{y@;U}Qx=Mnj@ffNcQXitPg3nI9+#!2EmxoT^j6x&qLR
z_#U9;$x2-S*39jIvwO3y0CcEul~XIEE&zGqswo{hPN9wfeD+;H%Yn`U<sd*G^0^;y
z+HFxsfTxit7uz&L4g!#$kAd?pMAZ@CH6-|)OQI2<$wh#lz`-#W9$W?B*m@%nd(%`^
zo^ug^qqLns<qkYo0p=mGl~wH6@531Q6#qL@#fhr`9QkkrWWk*Qj)XWO>KI%FVDr;$
zKHe&BLVxFm;9XUTxCp>@e@j(D_Iq0fKEz+kX6*wJTm+bf=iV`by%;!vSig0O=_0^F
zB=C}#d5iQpC^#J|0LiBa7V0xV@+m@TaH#>@=aZ7dolfvh{($1xQhmDQW6*JbI8*>`
zH+ft>Z(b>q{5?RY<>+<zJrxo9k(ZA`1xRTKn#)YM;GFx1I3xCMg4jgS!SS%y`zjwP
zHvz7J0y>aNS4OM)09NJAfc6?tA!Tj?u&LY%ly2TK0px4x&=i9OuqG%>px`Em=B*R<
z7a_P4rs<T1p}F+|BE!&>CSth>ATkk4X(=K%0YsJ}Qd*45O#qR_xRjQoa}z*hIXWeW
zOl|^*IAk~y+5kx1-Qz!~%VT3!Q9d!3Boj=<DW6jf5OvC@vMnVi0YtZ@*v71S4X60V
zESk5iiS8nZZ%w3W+nnnzK$Ok7wmscVfId7HWqUf!+X0Pg5uzQ?plKdadLPj8kflBf
zihe|iBG@6l@>&r6kRDCjG1c}0G<Hmt<~0v$S6vaqs}rhx-PJ95y(bzys9j{ut}3`M
zQsY+@(6n9FF(`oAWgRqb*VQOqS5s6#yRfNVe=+Q7iO$NdEK?SM<~cE24UCp^WZdt=
zUC$klAGzovQ3DD)c5S5#<0GDt6o5&y2D}N(^vFvNQIfv6b!bhntBW09C+Qkcm}Q^9
ziCRiWn;a==`xtk)@lLqlHh*O5u>_zUyT0B*@|Xe?=IsLx9fW8?0GhW?n3RanlmLZ!
z`-o5EVW>l^H{egO&sepXYPtpt6{z@-8~x0^F3LrCrVnXy2ivInkXyTvn0?AH!rSGO
zq<zfOhqZ`t>~ppe$qh}K{g-{vIh4iG9$#}5G}^fzD8C7y{2G`5CV(;n%I2*Gm;lNQ
bD4V|rgY8#vZc9{$00000NkvXXu0mjfjmpNB

literal 0
HcmV?d00001

diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d4c83cb..e431c16 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -58,5 +58,6 @@
     <string name="hint_sql_query">SQL Query</string>
     <string name="action_cancel">Cancel</string>
     <string name="action_execute">Execute</string>
+    <string name="info">Information</string>
 
 </resources>

From 7b3b06db5e05b27b200f280d18c4aeacb9fbf9d5 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Thu, 2 Oct 2014 15:31:13 +0200
Subject: [PATCH 51/59] Don't need this permissions.

---
 app/src/main/AndroidManifest.xml | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f6b00ce..2969942 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -42,8 +42,4 @@
 
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-
 </manifest>

From 4fbbabbf81fb372059e0125b1531b6939c7ac8b3 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Mon, 6 Oct 2014 13:04:08 +0200
Subject: [PATCH 52/59] Backup disallowed.

---
 app/src/main/AndroidManifest.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 2969942..5876902 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,7 +3,7 @@
     package="info.nerull7.mysqlbrowser" >
 
     <application
-        android:allowBackup="true"
+        android:allowBackup="false"
         android:icon="@drawable/ic_launcher"
         android:label="@string/app_name"
         android:theme="@style/AppTheme" >

From 283af19d923fea15a53bd35c02dfc28c9e4a4784 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Tue, 7 Oct 2014 00:19:52 +0200
Subject: [PATCH 53/59] Bug fix  Missing new values in edit when they out of
 view  SQL Query better view with IME

---
 app/src/main/AndroidManifest.xml              |  6 ++-
 .../mysqlbrowser/ElementArrayAdapter.java     | 48 +++++++++++++------
 .../nerull7/mysqlbrowser/ElementFragment.java | 34 ++++++++-----
 app/src/main/res/layout/fragment_element.xml  |  3 +-
 4 files changed, 62 insertions(+), 29 deletions(-)

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5876902..b31c3ff 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -32,11 +32,13 @@
         </activity>
         <activity
             android:name=".ElementActivity"
-            android:label="@string/title_activity_element" >
+            android:label="@string/title_activity_element"
+            android:windowSoftInputMode="adjustPan">
         </activity>
         <activity
             android:name=".SQLActivity"
-            android:label="@string/title_activity_sql">
+            android:label="@string/title_activity_sql"
+            android:windowSoftInputMode="adjustResize">
         </activity>
     </application>
 
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
index 9004c95..adc23ba 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
@@ -1,13 +1,14 @@
 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;
 
 /**
@@ -21,33 +22,52 @@ public class ElementArrayAdapter extends ArrayAdapter<String> {
 
     public ElementArrayAdapter(Context context, int resource, List<String> fields) {
         super(context, resource, fields);
-        this.context = context;
-        this.fields = fields;
-        layout = resource;
-        values = null;
+        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) {
-        this(context, resource, fields);
-        this.values = values;
+        super(context, resource, fields);
+        init(context, resource, fields);
+        this.values = new ArrayList<String>();
+        this.values.addAll(values); // Copy
+    }
+
+    private void init(Context context, int resource, List<String> fields){
+        this.context = context;
+        this.fields = fields;
+        layout = resource;
     }
 
     @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
+    public View getView(final int position, View convertView, ViewGroup parent) {
         LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        View rowView = layoutInflater.inflate(layout, parent, false);
+        final View rowView = layoutInflater.inflate(layout, parent, false);
 
         TextView textView = (TextView) rowView.findViewById(R.id.textFieldName);
         textView.setText(fields.get(position));
-        if(values != null){
-            TextView textFieldName = (TextView) rowView.findViewById(R.id.editFieldValue);
-            textFieldName.setText(values.get(position));
-        }
-
+        TextView textFieldName = (TextView) rowView.findViewById(R.id.editFieldValue);
+        textFieldName.setText(values.get(position));
+        textFieldName.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+            @Override
+            public void onFocusChange(View v, boolean hasFocus) {
+                if (!hasFocus) {
+                    String tmp = String.valueOf(((TextView) v).getText());
+                    values.set(position, tmp);
+                }
+            }
+        });
         return rowView;
     }
 
     public List<String> getFieldArray(){
         return fields;
     }
+
+    public List<String> getValues() {
+        return values;
+    }
 }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
index a26c459..6b84366 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
@@ -2,17 +2,22 @@ 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.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.AbsListView;
 import android.widget.EditText;
 import android.widget.ListView;
 import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -50,6 +55,21 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
         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;
@@ -64,9 +84,9 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
         List<String> fields = listAdapter.getFieldArray();
         Static.asyncDatabaseConnector.setStringReturnListener(this);
         if(getArguments().getBoolean(EDIT_ELEMENT))
-            Static.asyncDatabaseConnector.updateElement(tableName, fields, values, getNewValues());
+            Static.asyncDatabaseConnector.updateElement(tableName, fields, values, listAdapter.getValues());
         else
-            Static.asyncDatabaseConnector.addNewElement(tableName, fields, getNewValues());
+            Static.asyncDatabaseConnector.addNewElement(tableName, fields, listAdapter.getValues());
     }
 
     private void actionRemove(){
@@ -137,16 +157,6 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
 
     }
 
-    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;
diff --git a/app/src/main/res/layout/fragment_element.xml b/app/src/main/res/layout/fragment_element.xml
index 3e9e223..c57f312 100644
--- a/app/src/main/res/layout/fragment_element.xml
+++ b/app/src/main/res/layout/fragment_element.xml
@@ -18,6 +18,7 @@
         android:id="@+id/listView"
         android:layout_below="@+id/progressBar"
         android:layout_alignParentLeft="true"
-        android:layout_alignParentStart="true" />
+        android:layout_alignParentStart="true"
+        android:descendantFocusability="afterDescendants"/>
 
 </RelativeLayout>
\ No newline at end of file

From 58fc51b6bd2ff91fe3bde058f1de93051e2e615c Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Tue, 7 Oct 2014 00:33:46 +0200
Subject: [PATCH 54/59] Fix for not updating current field on save

---
 app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
index 6b84366..a9f2953 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
@@ -120,6 +120,7 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
+        listView.requestFocus();
         switch (item.getItemId()){
             case R.id.action_save:
                 actionSave();

From 99f56acb4b726a51f2dfa4d7547ada35b001ba2d Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 8 Oct 2014 20:14:23 +0200
Subject: [PATCH 55/59] Rename DatabaseConnector

---
 .../mysqlbrowser/DatabaseFragment.java        | 14 +++++------
 .../nerull7/mysqlbrowser/ElementFragment.java | 24 ++++++++-----------
 .../nerull7/mysqlbrowser/EntriesFragment.java | 20 ++++++++--------
 .../nerull7/mysqlbrowser/LoginFragment.java   | 18 +++++++-------
 .../mysqlbrowser/SQLEntriesFragment.java      |  9 ++-----
 .../nerull7/mysqlbrowser/SQLFragment.java     | 15 ++++++------
 .../info/nerull7/mysqlbrowser/Static.java     |  4 ++--
 .../nerull7/mysqlbrowser/TableFragment.java   | 10 ++++----
 ...eConnector.java => DatabaseConnector.java} | 10 ++++----
 9 files changed, 57 insertions(+), 67 deletions(-)
 rename app/src/main/java/info/nerull7/mysqlbrowser/db/{AsyncDatabaseConnector.java => DatabaseConnector.java} (98%)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
index 91a6ff4..428afa3 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java
@@ -17,14 +17,14 @@ import android.widget.TextView;
 
 import java.util.List;
 
-import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
+import info.nerull7.mysqlbrowser.db.DatabaseConnector;
 
 /**
  * Created by nerull7 on 14.07.14.
  *
  * Fragment for showing list of Available Databases for user
  */
-public class DatabaseFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.OnPostExecuteListener {
+public class DatabaseFragment extends Fragment implements AdapterView.OnItemClickListener, DatabaseConnector.ListReturnListener, DatabaseConnector.OnPostExecuteListener {
     private ListView databasesListView;
     private ListAdapter listAdapter;
     private RelativeLayout rootView;
@@ -34,7 +34,7 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic
     @Override
     public void onResume() {
         super.onResume();
-        Static.asyncDatabaseConnector.setDatabaseInUse(null);
+        Static.databaseConnector.setDatabaseInUse(null);
     }
 
     @Override
@@ -45,9 +45,9 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic
         this.rootView = (RelativeLayout) rootView;
         progressBar = (ProgressBar) rootView.findViewById(R.id.loginProgressBar);
 
-        Static.asyncDatabaseConnector.setListReturnListener(this);
-        Static.asyncDatabaseConnector.setOnPostExecuteListener(this);
-        Static.asyncDatabaseConnector.getDatabases();
+        Static.databaseConnector.setListReturnListener(this);
+        Static.databaseConnector.setOnPostExecuteListener(this);
+        Static.databaseConnector.getDatabases();
         return rootView;
     }
 
@@ -59,7 +59,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.asyncDatabaseConnector.setDatabaseInUse(chosenDatabase);
+            Static.databaseConnector.setDatabaseInUse(chosenDatabase);
             startActivity(intent);
         } else {
             Static.showErrorAlert(getResources().getString(R.string.no_connection), getActivity());
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
index a9f2953..236c769 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementFragment.java
@@ -5,7 +5,6 @@ import android.app.Fragment;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -14,22 +13,19 @@ 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 android.widget.RelativeLayout;
 
-import java.util.ArrayList;
 import java.util.List;
 
-import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
+import info.nerull7.mysqlbrowser.db.DatabaseConnector;
 
 /**
  * Created by nerull7 on 2014-08-06.
  *
  * Fragment for editing/adding elements
  */
-public class ElementFragment extends Fragment implements AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.StringReturnListener, AsyncDatabaseConnector.OnPostExecuteListener {
+public class ElementFragment extends Fragment implements DatabaseConnector.ListReturnListener, DatabaseConnector.StringReturnListener, DatabaseConnector.OnPostExecuteListener {
     public static final String EDIT_ELEMENT = "edit_element";
     public static final String EDIT_LIST = "edit_element_list";
 
@@ -73,32 +69,32 @@ public class ElementFragment extends Fragment implements AsyncDatabaseConnector.
         initArguments();
 
         postExecute = POST_EXECUTE_NONE;
-        Static.asyncDatabaseConnector.setListReturnListener(this);
-        Static.asyncDatabaseConnector.setOnPostExecuteListener(this);
-        Static.asyncDatabaseConnector.getFields(tableName);
+        Static.databaseConnector.setListReturnListener(this);
+        Static.databaseConnector.setOnPostExecuteListener(this);
+        Static.databaseConnector.getFields(tableName);
 
         return rootView;
     }
 
     private void actionSave(){
         List<String> fields = listAdapter.getFieldArray();
-        Static.asyncDatabaseConnector.setStringReturnListener(this);
+        Static.databaseConnector.setStringReturnListener(this);
         if(getArguments().getBoolean(EDIT_ELEMENT))
-            Static.asyncDatabaseConnector.updateElement(tableName, fields, values, listAdapter.getValues());
+            Static.databaseConnector.updateElement(tableName, fields, values, listAdapter.getValues());
         else
-            Static.asyncDatabaseConnector.addNewElement(tableName, fields, listAdapter.getValues());
+            Static.databaseConnector.addNewElement(tableName, fields, listAdapter.getValues());
     }
 
     private void actionRemove(){
         final List<String> fields = listAdapter.getFieldArray();
-        Static.asyncDatabaseConnector.setStringReturnListener(this);
+        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.asyncDatabaseConnector.removeElement(tableName, fields, values);
+                Static.databaseConnector.removeElement(tableName, fields, values);
 //                getActivity().finish();
             }
         });
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java
index 9bf12ef..3c8a5b9 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.AsyncDatabaseConnector;
+import info.nerull7.mysqlbrowser.db.DatabaseConnector;
 
 /**
  * Created by nerull7 on 15.07.14.
  *
  * Fragment for showing elements
  */
-public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.MatrixReturnListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.IntegerReturnListener, View.OnClickListener, AsyncDatabaseConnector.OnPostExecuteListener {
+public class EntriesFragment extends Fragment implements DatabaseConnector.MatrixReturnListener, DatabaseConnector.ListReturnListener, DatabaseConnector.IntegerReturnListener, View.OnClickListener, DatabaseConnector.OnPostExecuteListener {
     private static final int HEADER_PADDING_TOP = 15;
     private static final int HEADER_PADDING_BOTTOM = 15;
     private static final int HEADER_PADDING_LEFT = 15;
@@ -75,8 +75,8 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         initListeners();
 
         onPostExecuteListenerExecuted = 0;
-        Static.asyncDatabaseConnector.getFields(tableName);
-        Static.asyncDatabaseConnector.getEntriesCount(tableName);
+        Static.databaseConnector.getFields(tableName);
+        Static.databaseConnector.getEntriesCount(tableName);
 
         return rootView;
     }
@@ -112,10 +112,10 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
     }
 
     private void initListeners(){
-        Static.asyncDatabaseConnector.setIntegerReturnListener(this);
-        Static.asyncDatabaseConnector.setListReturnListener(this);
-        Static.asyncDatabaseConnector.setMatrixReturnListener(this);
-        Static.asyncDatabaseConnector.setOnPostExecuteListener(this);
+        Static.databaseConnector.setIntegerReturnListener(this);
+        Static.databaseConnector.setListReturnListener(this);
+        Static.databaseConnector.setMatrixReturnListener(this);
+        Static.databaseConnector.setOnPostExecuteListener(this);
     }
 
     @Override
@@ -157,7 +157,7 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
         onPostExecuteListenerExecuted--;
 
         setLoading(true);
-        Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page); // get new entries
+        Static.databaseConnector.getRows(tableName, entriesLimit, page); // get new entries
     }
 
     private void addNewElement(){
@@ -240,7 +240,7 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.
             headerRow.addView(textView);
         }
 
-        Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page);
+        Static.databaseConnector.getRows(tableName, entriesLimit, page);
     }
 
     @Override
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
index d0a1eee..324c7e4 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java
@@ -12,21 +12,21 @@ import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ProgressBar;
 
-import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
+import info.nerull7.mysqlbrowser.db.DatabaseConnector;
 
 /**
  * Created by nerull7 on 07.07.14.
  *
  * Fragment for login
  */
-public class LoginFragment extends Fragment implements View.OnClickListener, AsyncDatabaseConnector.BooleanReturnListener, AsyncDatabaseConnector.OnPostExecuteListener {
+public class LoginFragment extends Fragment implements View.OnClickListener, DatabaseConnector.BooleanReturnListener, DatabaseConnector.OnPostExecuteListener {
     private EditText urlTextbox;
     private EditText loginTextbox;
     private EditText passwordTextbox;
     private ProgressBar progressBar;
     private Button loginButton;
 
-    AsyncDatabaseConnector asyncDatabaseConnector;
+    DatabaseConnector databaseConnector;
 
     private boolean result;
 
@@ -86,10 +86,10 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
         url = urlTextbox.getText().toString();
 
         if(Static.isNetworkConnected(getActivity())) {
-            asyncDatabaseConnector = new AsyncDatabaseConnector(login, password, url, getActivity().getResources());
-            asyncDatabaseConnector.setBooleanReturnListener(this);
-            asyncDatabaseConnector.setOnPostExecuteListener(this);
-            asyncDatabaseConnector.checkLogin();
+            databaseConnector = new DatabaseConnector(login, password, url, getActivity().getResources());
+            databaseConnector.setBooleanReturnListener(this);
+            databaseConnector.setOnPostExecuteListener(this);
+            databaseConnector.checkLogin();
         } else {
             Static.showErrorAlert(getResources().getString(R.string.no_connection), getActivity());
             loginButton.setEnabled(true); // Now we can click button again
@@ -106,13 +106,13 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy
     @Override
     public void onPostExecute() {
         if(result) {
-            Static.asyncDatabaseConnector = asyncDatabaseConnector;
+            Static.databaseConnector = databaseConnector;
             Intent intent = new Intent(getActivity(), ListActivity.class);
             intent.putExtra(Static.FRAGMENT_TO_START, Static.FRAGMENT_DATABASE);
             startActivity(intent);
         }
         else {
-            Static.showErrorAlert(AsyncDatabaseConnector.errorMsg, getActivity());
+            Static.showErrorAlert(DatabaseConnector.errorMsg, getActivity());
         }
 
         loginButton.setEnabled(true); // Now we can click button again
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/SQLEntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/SQLEntriesFragment.java
index 4c1af95..610a66a 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/SQLEntriesFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/SQLEntriesFragment.java
@@ -3,14 +3,10 @@ package info.nerull7.mysqlbrowser;
 import android.app.AlertDialog;
 import android.app.Fragment;
 import android.content.DialogInterface;
-import android.content.Intent;
 import android.graphics.Typeface;
 import android.os.Bundle;
-import android.preference.PreferenceManager;
 import android.view.LayoutInflater;
 import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -23,17 +19,16 @@ import android.widget.TableLayout;
 import android.widget.TableRow;
 import android.widget.TextView;
 
-import java.util.ArrayList;
 import java.util.List;
 
-import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
+import info.nerull7.mysqlbrowser.db.DatabaseConnector;
 
 /**
  * Created by nerull7 on 15.07.14.
  *
  * Fragment for showing elements
  */
-public class SQLEntriesFragment extends Fragment implements AsyncDatabaseConnector.MatrixReturnListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.OnPostExecuteListener, AsyncDatabaseConnector.StringReturnListener {
+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;
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java
index c67bc2e..0249a12 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java
@@ -1,6 +1,5 @@
 package info.nerull7.mysqlbrowser;
 
-import android.app.Activity;
 import android.app.Fragment;
 import android.app.FragmentTransaction;
 import android.content.Context;
@@ -15,12 +14,12 @@ import android.view.ViewGroup;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
 
-import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
+import info.nerull7.mysqlbrowser.db.DatabaseConnector;
 
 /**
  * Created by nerull7 on 30.09.14.
  */
-public class SQLFragment extends Fragment implements AsyncDatabaseConnector.OnPostExecuteListener {
+public class SQLFragment extends Fragment implements DatabaseConnector.OnPostExecuteListener {
     private EditText sqlEditText;
     private InputMethodManager inputMethodManager;
     private SQLEntriesFragment sqlEntriesFragment;
@@ -76,11 +75,11 @@ public class SQLFragment extends Fragment implements AsyncDatabaseConnector.OnPo
         fragmentTransaction.replace(R.id.container, sqlEntriesFragment);
         fragmentTransaction.commit();
 
-        Static.asyncDatabaseConnector.setStringReturnListener(sqlEntriesFragment);
-        Static.asyncDatabaseConnector.setListReturnListener(sqlEntriesFragment);
-        Static.asyncDatabaseConnector.setMatrixReturnListener(sqlEntriesFragment);
-        Static.asyncDatabaseConnector.setOnPostExecuteListener(this);
-        Static.asyncDatabaseConnector.executeSQL(getActivity().getIntent().getExtras().getString(Static.DATABASE_NAME_ARG), sqlQuery);
+        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
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
index ca0281e..abf0d41 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.AsyncDatabaseConnector;
+import info.nerull7.mysqlbrowser.db.DatabaseConnector;
 
 /**
  * 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 AsyncDatabaseConnector asyncDatabaseConnector = null;
+    public static DatabaseConnector databaseConnector = null;
 
     public static void startSettings(Context context){
         Intent intent = new Intent(context, SettingsActivity.class);
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
index 1007f2c..25dbedc 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java
@@ -17,12 +17,12 @@ import android.widget.TextView;
 
 import java.util.List;
 
-import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
+import info.nerull7.mysqlbrowser.db.DatabaseConnector;
 
 /**
  * Created by nerull7 on 14.07.14.
  */
-public class TableFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.OnPostExecuteListener {
+public class TableFragment extends Fragment implements AdapterView.OnItemClickListener, DatabaseConnector.ListReturnListener, DatabaseConnector.OnPostExecuteListener {
     private String databaseName;
     private ListView tablesList;
     private ListAdapter listAdapter;
@@ -38,9 +38,9 @@ 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.asyncDatabaseConnector.setListReturnListener(this);
-        Static.asyncDatabaseConnector.setOnPostExecuteListener(this);
-        Static.asyncDatabaseConnector.getTables();
+        Static.databaseConnector.setListReturnListener(this);
+        Static.databaseConnector.setOnPostExecuteListener(this);
+        Static.databaseConnector.getTables();
         return rootView;
     }
 
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/DatabaseConnector.java
similarity index 98%
rename from app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
rename to app/src/main/java/info/nerull7/mysqlbrowser/db/DatabaseConnector.java
index 0162ca8..c4f98ad 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/DatabaseConnector.java
@@ -28,7 +28,7 @@ import info.nerull7.mysqlbrowser.R;
  * Created by nerull7 on 07.07.14.
  * Database connector using Async calls
  */
-public class AsyncDatabaseConnector {
+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";
@@ -57,7 +57,7 @@ public class AsyncDatabaseConnector {
     public static String errorMsg;
     private OnPostExecuteListener onPostExecuteListener;
 
-    public AsyncDatabaseConnector(String login, String password, String url, Resources resources){
+    public DatabaseConnector(String login, String password, String url, Resources resources){
         this.login = login;
         this.password = password;
         this.url = url;
@@ -443,10 +443,10 @@ public class AsyncDatabaseConnector {
         private Resources resources;
 
         public static final String CONNECTION_REQUEST_METHOD = "POST";
-        public static final int CONNECTION_TIMEOUT = 15000;
-        public static final int READ_TIMEOUT = 10000;
+        public static final int CONNECTION_TIMEOUT = 15000; // ms
+        public static final int READ_TIMEOUT = 10000; // ms
 
-        Downloader(OnFinishedListener onFinishedListener, OnPostExecuteListener onPostExecuteListener, Resources resources){
+        private Downloader(OnFinishedListener onFinishedListener, OnPostExecuteListener onPostExecuteListener, Resources resources){
             this.onFinishedListener = onFinishedListener;
             this.onPostExecuteListener = onPostExecuteListener;
             this.resources = resources;

From 038a86e35cf55371c43f724359348e79e4e22cef Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 8 Oct 2014 20:39:13 +0200
Subject: [PATCH 56/59] Moved OnPostExecuteListener to Download class

---
 .../nerull7/mysqlbrowser/db/DatabaseConnector.java    | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/DatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/DatabaseConnector.java
index c4f98ad..9fbbd6f 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/DatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/DatabaseConnector.java
@@ -55,7 +55,7 @@ public class DatabaseConnector {
     private MatrixReturnListener matrixReturnListener;
 
     public static String errorMsg;
-    private OnPostExecuteListener onPostExecuteListener;
+    private Downloader.OnPostExecuteListener onPostExecuteListener;
 
     public DatabaseConnector(String login, String password, String url, Resources resources){
         this.login = login;
@@ -408,7 +408,7 @@ public class DatabaseConnector {
         this.matrixReturnListener = matrixReturnListener;
     }
 
-    public void setOnPostExecuteListener(OnPostExecuteListener onPostExecuteListener){
+    public void setOnPostExecuteListener(Downloader.OnPostExecuteListener onPostExecuteListener){
         this.onPostExecuteListener = onPostExecuteListener;
     }
 
@@ -432,9 +432,7 @@ public class DatabaseConnector {
         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;
@@ -552,6 +550,9 @@ public class DatabaseConnector {
             void onFinished(String data, String error);
         }
 
+        public static interface OnPostExecuteListener {
+            void onPostExecute();
+        }
     }
 
     class Request{

From a6c7b27e2f027b2e5fa1992b10e0678831464f0e Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Wed, 8 Oct 2014 20:44:01 +0200
Subject: [PATCH 57/59] Revert "Moved OnPostExecuteListener to Download class"

This was a mistake

This reverts commit 038a86e35cf55371c43f724359348e79e4e22cef.
---
 .../nerull7/mysqlbrowser/db/DatabaseConnector.java    | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/DatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/DatabaseConnector.java
index 9fbbd6f..c4f98ad 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/DatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/DatabaseConnector.java
@@ -55,7 +55,7 @@ public class DatabaseConnector {
     private MatrixReturnListener matrixReturnListener;
 
     public static String errorMsg;
-    private Downloader.OnPostExecuteListener onPostExecuteListener;
+    private OnPostExecuteListener onPostExecuteListener;
 
     public DatabaseConnector(String login, String password, String url, Resources resources){
         this.login = login;
@@ -408,7 +408,7 @@ public class DatabaseConnector {
         this.matrixReturnListener = matrixReturnListener;
     }
 
-    public void setOnPostExecuteListener(Downloader.OnPostExecuteListener onPostExecuteListener){
+    public void setOnPostExecuteListener(OnPostExecuteListener onPostExecuteListener){
         this.onPostExecuteListener = onPostExecuteListener;
     }
 
@@ -432,7 +432,9 @@ public class DatabaseConnector {
         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;
@@ -550,9 +552,6 @@ public class DatabaseConnector {
             void onFinished(String data, String error);
         }
 
-        public static interface OnPostExecuteListener {
-            void onPostExecute();
-        }
     }
 
     class Request{

From 534824c1c91dee4d8f8019018c6ba20bb2f0d5b2 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Mon, 13 Oct 2014 15:39:41 +0200
Subject: [PATCH 58/59] Can't use that

---
 .../mysqlbrowser/NumberPickerDialog.java      | 108 ------------------
 .../mysqlbrowser/SettingsFragment.java        |  44 ++++---
 app/src/main/res/xml/settings.xml             |   5 +-
 3 files changed, 23 insertions(+), 134 deletions(-)
 delete mode 100644 app/src/main/java/info/nerull7/mysqlbrowser/NumberPickerDialog.java

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/NumberPickerDialog.java b/app/src/main/java/info/nerull7/mysqlbrowser/NumberPickerDialog.java
deleted file mode 100644
index c4778df..0000000
--- a/app/src/main/java/info/nerull7/mysqlbrowser/NumberPickerDialog.java
+++ /dev/null
@@ -1,108 +0,0 @@
-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/SettingsFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java
index b49d179..dfff2bc 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/SettingsFragment.java
@@ -7,7 +7,6 @@ import android.preference.EditTextPreference;
 import android.preference.Preference;
 import android.preference.PreferenceFragment;
 import android.preference.PreferenceManager;
-import android.preference.PreferenceScreen;
 import android.util.Base64;
 
 /**
@@ -15,19 +14,18 @@ import android.util.Base64;
  *
  * Fragment for Preferences/Settings
  */
-public class SettingsFragment extends PreferenceFragment implements NumberPickerDialog.OnNumberSetListener, Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
+public class SettingsFragment extends PreferenceFragment implements 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 Preference mEntriesLimit;
+    private EditTextPreference mEntriesLimit;
     private CheckBoxPreference saveCredentials;
     private EditTextPreference connectorUrlCredentials;
     private EditTextPreference loginCredentials;
@@ -49,17 +47,18 @@ public class SettingsFragment extends PreferenceFragment implements NumberPicker
         addPreferencesFromResource(R.xml.settings);
 
         // Getting fields
-        mEntriesLimit = findPreference(ENTRIES_PAGE_LIMIT);
+        mEntriesLimit = (EditTextPreference) findPreference(ENTRIES_PAGE_LIMIT_STRING);
         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
-        setEntriesPageLimitSummary();
+        setEntriesPageLimit();
         setPasswordCredentials();
 
         // Settings Listener
+        mEntriesLimit.setOnPreferenceChangeListener(this);
         saveCredentials.setOnPreferenceClickListener(this);
         passwordCredentials.setOnPreferenceChangeListener(this);
     }
@@ -94,6 +93,11 @@ public class SettingsFragment extends PreferenceFragment implements NumberPicker
         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);
@@ -114,23 +118,6 @@ public class SettingsFragment extends PreferenceFragment implements NumberPicker
         } 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){
@@ -146,7 +133,16 @@ public class SettingsFragment extends PreferenceFragment implements NumberPicker
     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/res/xml/settings.xml b/app/src/main/res/xml/settings.xml
index 3cd5391..f310eb7 100644
--- a/app/src/main/res/xml/settings.xml
+++ b/app/src/main/res/xml/settings.xml
@@ -3,8 +3,9 @@
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
     <PreferenceCategory
         android:title="@string/general_category">
-        <Preference
-            android:key="entries_limit"
+        <EditTextPreference
+            android:key="entries_limit_string"
+            android:numeric="integer"
             android:title="@string/entries_limit"
             android:summary="@string/entries_summary"
             />

From 0a37de8e2b9b4e3af19b70daf39aa9545612888b Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Tue, 14 Oct 2014 09:39:26 +0200
Subject: [PATCH 59/59] Fix NullPointerException

---
 .../info/nerull7/mysqlbrowser/ElementArrayAdapter.java    | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
index adc23ba..32388b5 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ElementArrayAdapter.java
@@ -33,7 +33,13 @@ public class ElementArrayAdapter extends ArrayAdapter<String> {
         super(context, resource, fields);
         init(context, resource, fields);
         this.values = new ArrayList<String>();
-        this.values.addAll(values); // Copy
+        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){