From 4398cce781b87b3081c719ac75a8c1d97d8bc28b Mon Sep 17 00:00:00 2001 From: Georg Reisinger <43533139+GeorgReisinger@users.noreply.github.com> Date: Mon, 28 Jan 2019 23:18:37 +0100 Subject: [PATCH] Group CRUD Funktionen und Item Add --- .../activitys/ShoppinglistDetails.java | 289 +++++++++++++++++- .../smartshopper/db/Database.java | 230 +++++++++++++- .../shoppinglist/details/DetailsAdapter.java | 103 ++++++- .../shoppinglist/details/group/Group.java | 8 +- .../layout/activity_shoppinglist_details.xml | 2 +- app/src/main/res/layout/add_group_dialog.xml | 123 ++++++++ app/src/main/res/layout/add_item_dialog.xml | 127 ++++++++ app/src/main/res/layout/cardviewgroup.xml | 23 ++ 8 files changed, 884 insertions(+), 21 deletions(-) create mode 100644 app/src/main/res/layout/add_group_dialog.xml create mode 100644 app/src/main/res/layout/add_item_dialog.xml diff --git a/app/src/main/java/at/smartshopper/smartshopper/activitys/ShoppinglistDetails.java b/app/src/main/java/at/smartshopper/smartshopper/activitys/ShoppinglistDetails.java index 0bfd429..076eab5 100644 --- a/app/src/main/java/at/smartshopper/smartshopper/activitys/ShoppinglistDetails.java +++ b/app/src/main/java/at/smartshopper/smartshopper/activitys/ShoppinglistDetails.java @@ -1,14 +1,27 @@ package at.smartshopper.smartshopper.activitys; +import android.content.Intent; +import android.graphics.Color; +import android.os.Build; import android.os.Bundle; import android.app.Activity; +import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.PopupWindow; import android.widget.Toast; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; +import com.squareup.picasso.Picasso; import org.json.JSONException; @@ -21,16 +34,25 @@ import at.smartshopper.smartshopper.shoppinglist.Shoppinglist; import at.smartshopper.smartshopper.shoppinglist.ShoppinglistAdapter; import at.smartshopper.smartshopper.shoppinglist.details.Details; import at.smartshopper.smartshopper.shoppinglist.details.DetailsAdapter; +import at.smartshopper.smartshopper.shoppinglist.details.group.Group; +import at.smartshopper.smartshopper.shoppinglist.details.item.Item; -public class ShoppinglistDetails extends Activity { +public class ShoppinglistDetails extends Activity implements DetailsAdapter.OnGroupEditClicked, DetailsAdapter.OnGroupDeleteClicked, DetailsAdapter.OnItemAddClicked { private Database db = new Database(); + private FloatingActionButton fab; + private String colorString; + private PopupWindow popupWindow; + private PopupWindow popupWindowItem; + private Button colorBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_shoppinglist_details); + fab = findViewById(R.id.addGroupFab); + colorBtn = (Button) findViewById(R.id.groupColor); Bundle bundle = getIntent().getExtras(); int position = -1; // or other values if (bundle != null) @@ -49,8 +71,22 @@ public class ShoppinglistDetails extends Activity { Shoppinglist aktuelleShopinglist = shoppinglists.get(position); + final String sl_id = aktuelleShopinglist.getSlId(); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + try { + showPupupGroupEdit(false, null, sl_id, v); + } catch (SQLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + } + }); + try { - showDetails(aktuelleShopinglist.getSlId()); + showDetails(sl_id); } catch (SQLException e) { e.printStackTrace(); } catch (JSONException e) { @@ -59,8 +95,142 @@ public class ShoppinglistDetails extends Activity { } + /** + * Zeigt ein Popup zum bearbeiten und erstellen von groups + * Wenn from db true ist wird die groupid benötigt + * + * @param fromDB Wenn true ist das popup im bearbeiten modus, wenn false wird die groupid nicht benötigt + * @param groupid Wenn fromDb true ist wird diese id benötigt um das richtige element zu bearbeiten + * @param v Der view auf dem das popup platziert werden soll + */ + private void showPupupGroupEdit(final boolean fromDB, final String groupid, final String sl_id, View v) throws SQLException, JSONException { + final LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE); + + final String username = FirebaseAuth.getInstance().getCurrentUser().getUid(); + + View customView = inflater.inflate(R.layout.add_group_dialog, null); + + ImageButton close = (ImageButton) customView.findViewById(R.id.groupClose); + final EditText name = (EditText) customView.findViewById(R.id.groupName); + Button color = (Button) customView.findViewById(R.id.groupColor); + Button finish = (Button) customView.findViewById(R.id.groupFinish); + + this.colorBtn = color; + + Picasso.get().load(R.drawable.close).into(close); + + if (fromDB) { + Group dbgroup = db.getGroup(groupid, sl_id); + String colorstring; + if(dbgroup.getColor().contains("#")){ + colorstring = dbgroup.getColor(); + }else{ + colorstring = "#" + dbgroup.getColor(); + } + color.setBackgroundColor(Color.parseColor(colorstring)); + name.setText(dbgroup.getName()); + } else { + colorString = "ffffff"; + } + + finish.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (fromDB) { + try { + db.editGroup(sl_id, groupid, name.getText().toString(), colorString, ""); + showDetails(sl_id); + popupWindow.dismiss(); + colorString = "ffffff"; + } catch (SQLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + } else { + try { + db.addGroup(sl_id, name.getText().toString(), colorString, ""); + showDetails(sl_id); + popupWindow.dismiss(); + colorString = "ffffff"; + } catch (SQLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + }); + + color.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(ShoppinglistDetails.this, Colorpicker.class); + startActivityForResult(intent, 1); + + } + }); + + close.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + popupWindow.dismiss(); + } + }); + + popupWindow = new PopupWindow(customView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + + // Set an elevation value for popup window + // Call requires API level 21 + if (Build.VERSION.SDK_INT >= 21) { + popupWindow.setElevation(5.0f); + } + + popupWindow.setOutsideTouchable(false); + popupWindow.setFocusable(true); + + + popupWindow.showAtLocation(v, Gravity.CENTER, 0, 0); + popupWindow.update(); + } + + /** + * Setzt das atribut color wenn die activity colorpicker beendet wird + * + * @param requestCode + * @param resultCode + * @param data + */ + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == 1) { + if (resultCode == RESULT_OK) { + int color = Integer.parseInt(data.getData().toString()); + this.colorString = colorToHexString(color); + String colorstring; + if(this.colorString.contains("#")){ + colorstring = this.colorString; + }else{ + colorstring = "#" + this.colorString; + } + int colorint = Color.parseColor(colorstring); + colorBtn.setBackgroundColor(colorint); + } + } + } + + /** + * Convertiert eine int farbe in eine hexa dezimale Farbe + * + * @param color Farbe zum umwandeln in int + * @return farbe als hex im string + */ + private static String colorToHexString(int color) { + return String.format("#%06X", 0xFFFFFFFF & color); + } + /** * Zeigt das Card View der Shoppinglist Details an + * * @param sl_id Shoppinglist welche angezeigt werden soll * @throws SQLException * @throws JSONException @@ -71,7 +241,122 @@ public class ShoppinglistDetails extends Activity { detailsRecycleView.setLayoutManager(new LinearLayoutManager(this)); List
detailsList = db.getListDetails(sl_id); DetailsAdapter detailsAdapter = new DetailsAdapter(detailsList); + detailsAdapter.setGroupEditClick(this); + detailsAdapter.setGroupDeleteClick(this); + detailsAdapter.setItemAddClick(this); detailsRecycleView.setAdapter(detailsAdapter); } + + + private void showPopupItemEdit(final boolean fromDB, final String sl_id, final String group_id, String item_id, View v) throws SQLException, JSONException { + final LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE); + + + View customView = inflater.inflate(R.layout.add_item_dialog, null); + + ImageButton close = (ImageButton) customView.findViewById(R.id.itemClose); + final EditText name = (EditText) customView.findViewById(R.id.itemName); + final EditText count = (EditText) customView.findViewById(R.id.itemAnzahl); + Button finish = (Button) customView.findViewById(R.id.itemFinish); + + + Picasso.get().load(R.drawable.close).into(close); + + if (fromDB) { + Item dbitem = db.getItem(item_id); + + + name.setText(dbitem.getName()); + } else { + colorString = "ffffff"; + } + + finish.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (fromDB) { + try { + + showDetails(sl_id); + popupWindow.dismiss(); + colorString = "ffffff"; + } catch (SQLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + } else { + try { + db.addItem(group_id, sl_id, name.getText().toString(), Integer.parseInt(count.getText().toString())); + showDetails(sl_id); + popupWindowItem.dismiss(); + colorString = "ffffff"; + } catch (SQLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + }); + + close.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + popupWindowItem.dismiss(); + } + }); + + popupWindowItem = new PopupWindow(customView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + + // Set an elevation value for popup window + // Call requires API level 21 + if (Build.VERSION.SDK_INT >= 21) { + popupWindowItem.setElevation(5.0f); + } + + popupWindowItem.setOutsideTouchable(false); + popupWindowItem.setFocusable(true); + + + popupWindowItem.showAtLocation(v, Gravity.CENTER, 0, 0); + popupWindowItem.update(); + } + + @Override + public void onGroupEditClick(String sl_id, String group_id, View v) { + try { + showPupupGroupEdit(true, group_id, sl_id, v); + } catch (SQLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + @Override + public void onGroupDeleteClick(String sl_id, String group_id, View v) { + try { + db.deleteGroup(group_id, sl_id); + showDetails(sl_id); + } catch (SQLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + @Override + public void onItemAddClick(String sl_id, String group_id, String item_id, View v) { + + try { + showPopupItemEdit(false, sl_id, group_id, item_id, v); + } catch (SQLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + + } } diff --git a/app/src/main/java/at/smartshopper/smartshopper/db/Database.java b/app/src/main/java/at/smartshopper/smartshopper/db/Database.java index d3b0599..7b5009a 100644 --- a/app/src/main/java/at/smartshopper/smartshopper/db/Database.java +++ b/app/src/main/java/at/smartshopper/smartshopper/db/Database.java @@ -50,6 +50,116 @@ public class Database { System.out.println("Database connected!"); } + /** + * Löscht eine Gruppe von der Tabelle Group und alle items dieser group, desswegen wird aucj die tabelle item geleert + * @param group_id Die group id welche gelöscht werden soll + * @param sl_id Die Shoppingliste auf der sich die group befindet + * @throws SQLException + */ + public void deleteGroup(String group_id, String sl_id) throws SQLException { + sqlUpdate2Param("DELETE FROM \"Item\" WHERE group_id = ? AND sl_id = ?", group_id, sl_id); + sqlUpdate2Param("DELETE FROM \"Group\" WHERE group_id = ? AND sl_id = ?", group_id, sl_id); + } + + /** + * Fügt ein neues Item der Datenbank hinzu + * @param group_id Die group id in der das neue item angezeigt werden soll + * @param sl_id Die Shoppingliste in der das neue item nagezeigt werden soll + * @param name Der name des Items + * @param count Die anzahl des Items + * @throws SQLException + */ + public void addItem(String group_id, String sl_id, String name, int count) throws SQLException { + sqlUpdate5Param("INSERT INTO \"Item\" VALUES (?,?,?,?,?)", generateItemId(), group_id, sl_id, name, count); + } + + /** + * Erstellt eine neue Gruppe + * + * @param sl_id Shoppinglist id in welcher die Gruppe ist + * @param name + * @param color + * @param hidden + */ + public void addGroup(String sl_id, String name, String color, String hidden) throws SQLException { + sqlUpdate4Param("INSERT INTO \"Group\" (group_id, sl_id, name, color, hidden) VALUES (?, ?,?,?, false)", generateGroupId(), sl_id, name, color); + } + + /** + * Bearbeitet eine Gruppe + * + * @param sl_id Die Shoppinglist oid in welcher die gruppe ist + * @param group_id Die Group id der gruppe + * @param newname Der neue Name + * @param newcolor Die neue Farbe + * @param newhidden Der neue hidden boolean + * @throws SQLException + * @throws JSONException + */ + public void editGroup(String sl_id, String group_id, String newname, String newcolor, String newhidden) throws SQLException, JSONException { + Group oldgroup = getGroup(group_id, sl_id); + + if (!oldgroup.getName().equals(newname) && newname != null) { + sqlUpdate3Param("UPDATE \"Group\" SET name = ? WHERE group_id = ? AND sl_id = ?", newname, group_id, sl_id); + } + + /* + if (!oldgroup.getHidden().equals(newhidden) && newhidden != null) { + sqlUpdate3Param("UPDATE \"Group\" SET hidden = ? WHERE group_id = ? AND sl_id = ?", newhidden, group_id, sl_id); + } +*/ + if (!oldgroup.getColor().equals(newcolor) && newcolor != null) { + sqlUpdate3Param("UPDATE \"Group\" SET color = ? WHERE group_id = ? AND sl_id = ?", newcolor, group_id, sl_id); + } + + } + + /** + * Hollt ein bestimtes item + * @param item_id Die sl_id in der das item ist + * @return + * @throws SQLException + * @throws JSONException + */ + public Item getItem(String item_id) throws SQLException, JSONException { + String SQL = "SELECT row_to_json(\"Item\") AS obj FROM \"Item\" JOIN \"Group\" USING (group_id) WHERE item_id = ?"; + + connectDatabase(); + + PreparedStatement pstmt = conect.prepareStatement(SQL); + pstmt.setString(1, item_id); + ResultSet rs = pstmt.executeQuery(); + rs.next(); + String resultString = rs.getString(1); + JSONObject jsonObject = new JSONObject(resultString); + + return new Item(generateItemId(), jsonObject.getString("group_id"), jsonObject.getString("sl_id"), jsonObject.getString("name"), jsonObject.getString("count")); + } + + /** + * Hollt alle daten einer Bestimmten group und erstellt damit ein Group object + * + * @param group_id Group id die zu holen ist + * @param sl_id Shoppingliste der group + * @throws SQLException + * @throws JSONException + */ + public Group getGroup(String group_id, String sl_id) throws SQLException, JSONException { + String SQL = "SELECT row_to_json(\"Group\") AS obj FROM \"Group\" WHERE group_id = ? AND sl_id = ?"; + connectDatabase(); + + PreparedStatement pstmt = conect.prepareStatement(SQL); + System.out.println(sl_id); + pstmt.setString(1, group_id); + pstmt.setString(2, sl_id); + ResultSet rs = pstmt.executeQuery(); + rs.next(); + String resultString = rs.getString(1); + JSONObject jsonObject = new JSONObject(resultString); + + return new Group(jsonObject.getString("group_id"), jsonObject.getString("sl_id"), jsonObject.getString("name"), jsonObject.getString("color"), jsonObject.getString("hidden")); + } + /** * Löscht eine Shoppingliste aus der Tabelle: * Shoppinglist / - member / -admin @@ -250,6 +360,24 @@ public class Database { return output; } + /** + * Generiert eine neue 8 stellige group_id + * + * @return Neue group_id + */ + private String generateGroupId() { + return generateSL_Id(); + } + /** + * Generiert eine neue 8 stellige item_id + * + * @return Neue item_id + */ + public String generateItemId() { + return generateSL_Id(); + } + + /** * Holt alle Items einer bestimmten shoppingliste, angegeben durch die shoppinglist id * @@ -322,35 +450,119 @@ public class Database { /** * Bearbeitet die Eigenschaften einer Shoppingliste - * @param sl_id Shoppinglist Id welche zu bearbeiten ist - * @param newname Neuer Shoppinglistname + * + * @param sl_id Shoppinglist Id welche zu bearbeiten ist + * @param newname Neuer Shoppinglistname * @param newdescription Neue Shoppinglist Beschreibung - * @param newColor Neue Shoppinglist Farbe + * @param newColor Neue Shoppinglist Farbe * @throws SQLException * @throws JSONException */ public void editShoppinglist(String sl_id, String newname, String newdescription, String newColor) throws SQLException, JSONException { Shoppinglist oldShoppinglist = getShoppinglist(sl_id); - if(!oldShoppinglist.getname().equals(newname) && newname != null){ + if (!oldShoppinglist.getname().equals(newname) && newname != null) { sqlUpdate2Param("UPDATE \"Shoppinglist\" SET name = ? WHERE sl_id = ?", newname, sl_id); } - if(!oldShoppinglist.getdescription().equals(newdescription) && newdescription != null){ + if (!oldShoppinglist.getdescription().equals(newdescription) && newdescription != null) { sqlUpdate2Param("UPDATE \"Shoppinglist\" SET description = ? WHERE sl_id = ?", newdescription, sl_id); } - if(!oldShoppinglist.getcolor().equals(newColor) && newColor != null){ + if (!oldShoppinglist.getcolor().equals(newColor) && newColor != null) { sqlUpdate2Param("UPDATE \"Shoppinglist\" SET color = ? WHERE sl_id = ?", newColor, sl_id); } } + /** + * Führt einen SQL Befehl durch der keine rückgabe hat. + * + * @param SQL Der SQL befehl + * @param param ein Parameter + * @param param2 ein 2. Parameter + * @param param3 ein 3. parameter + * @param param4 ein 4. Parameter + * @param param5 ein 5. Parameter + * @throws SQLException + */ + private void sqlUpdate5Param(String SQL, String param, String param2, String param3, String param4, String param5) throws SQLException { + connectDatabase(); + PreparedStatement pstmt = conect.prepareStatement(SQL); + pstmt.setString(1, param); + pstmt.setString(2, param2); + pstmt.setString(3, param3); + pstmt.setString(4, param4); + pstmt.setString(5, param5); + pstmt.executeUpdate(); + } + + /** + * Führt einen SQL Befehl durch der keine rückgabe hat. + * + * @param SQL Der SQL befehl + * @param param ein Parameter + * @param param2 ein 2. Parameter + * @param param3 ein 3. parameter + * @param param4 ein 4. Parameter + * @param param5 ein 5. Parameter + * @throws SQLException + */ + private void sqlUpdate5Param(String SQL, String param, String param2, String param3, String param4, int param5) throws SQLException { + connectDatabase(); + PreparedStatement pstmt = conect.prepareStatement(SQL); + pstmt.setString(1, param); + pstmt.setString(2, param2); + pstmt.setString(3, param3); + pstmt.setString(4, param4); + pstmt.setInt(5, param5); + pstmt.executeUpdate(); + } + + /** + * Führt einen SQL Befehl durch der keine rückgabe hat. + * + * @param SQL Der SQL befehl + * @param param ein Parameter + * @param param2 ein 2. Parameter + * @param param3 ein 3. parameter + * @param param4 ein 4. Parameter + * @throws SQLException + */ + private void sqlUpdate4Param(String SQL, String param, String param2, String param3, String param4) throws SQLException { + connectDatabase(); + PreparedStatement pstmt = conect.prepareStatement(SQL); + pstmt.setString(1, param); + pstmt.setString(2, param2); + pstmt.setString(3, param3); + pstmt.setString(4, param4); + pstmt.executeUpdate(); + } + + /** + * Führt einen SQL Befehl durch der keine rückgabe hat. + * + * @param SQL Der SQL befehl + * @param param ein Parameter + * @param param2 ein 2. Parameter + * @param param3 ein 3. parameter + * @throws SQLException + */ + private void sqlUpdate3Param(String SQL, String param, String param2, String param3) throws SQLException { + connectDatabase(); + PreparedStatement pstmt = conect.prepareStatement(SQL); + pstmt.setString(1, param); + pstmt.setString(2, param2); + pstmt.setString(3, param3); + + pstmt.executeUpdate(); + } + /** * Führt einen SQL Befehl durch der keine rückgabe hat. * - * @param SQL Der SQL befehl - * @param param ein Parameter + * @param SQL Der SQL befehl + * @param param ein Parameter * @param param2 ein 2. Parameter * @throws SQLException */ @@ -361,6 +573,7 @@ public class Database { pstmt.setString(2, param2); pstmt.executeUpdate(); } + /** * Führt einen SQL Befehl durch der keine rückgabe hat. * @@ -377,6 +590,7 @@ public class Database { /** * Hollt eine Shoppingliste vom server + * * @param sl_id Shoppingliste welche heruntergelanden werden soll * @return Ein Shoppinglist Objekt * @throws SQLException diff --git a/app/src/main/java/at/smartshopper/smartshopper/shoppinglist/details/DetailsAdapter.java b/app/src/main/java/at/smartshopper/smartshopper/shoppinglist/details/DetailsAdapter.java index 11fe511..12a0c52 100644 --- a/app/src/main/java/at/smartshopper/smartshopper/shoppinglist/details/DetailsAdapter.java +++ b/app/src/main/java/at/smartshopper/smartshopper/shoppinglist/details/DetailsAdapter.java @@ -2,6 +2,7 @@ package at.smartshopper.smartshopper.shoppinglist.details; import android.app.Activity; import android.graphics.Color; +import android.media.Image; import android.support.annotation.NonNull; import android.support.v7.widget.CardView; import android.support.v7.widget.LinearLayoutManager; @@ -12,16 +13,23 @@ import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TextView; + import com.squareup.picasso.Picasso; + import java.util.List; + import at.smartshopper.smartshopper.R; import at.smartshopper.smartshopper.customViews.RoundCornersTransformation; import at.smartshopper.smartshopper.db.Database; +import at.smartshopper.smartshopper.shoppinglist.ShoppinglistAdapter; import at.smartshopper.smartshopper.shoppinglist.details.item.ItemAdapter; public class DetailsAdapter extends RecyclerView.Adapter { private List
details; + private OnGroupEditClicked onGroupEditClicked; + private OnItemAddClicked onItemAddClicked; + private OnGroupDeleteClicked onGroupDeleteClicked; public DetailsAdapter(List
details) { this.details = details; @@ -29,6 +37,7 @@ public class DetailsAdapter extends RecyclerView.Adapter + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +