From 1d3b04af9287b92b16693a9967abdd61886b0aa8 Mon Sep 17 00:00:00 2001
From: "@potel5u" <guillaume.potel!@etu.univ-lorrain.fr>
Date: Fri, 28 Mar 2025 09:10:42 +0100
Subject: [PATCH] =?UTF-8?q?Enregistrement=20d'un=20mod=C3=A8le=20et=20ouvr?=
 =?UTF-8?q?ir=20=C3=A0=20partir=20d'un=20autre=20modele=20enregistr=C3=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/build.gradle                              |  1 +
 app/src/main/AndroidManifest.xml              |  2 +-
 .../main/java/fr/ul/projet/MainActivity.java  | 40 +++++++--------
 ...reateActivity.java => ModeleActivity.java} | 47 +++++++++++++++--
 .../main/java/fr/ul/projet/PieceActivity.java |  2 +-
 .../main/java/fr/ul/projet/modele/Modele.java | 51 +++++++++++--------
 app/src/main/res/layout/activity_create.xml   | 13 +++++
 app/src/main/res/values/strings.xml           |  1 +
 8 files changed, 110 insertions(+), 47 deletions(-)
 rename app/src/main/java/fr/ul/projet/{CreateActivity.java => ModeleActivity.java} (62%)

diff --git a/app/build.gradle b/app/build.gradle
index 014e853..ae6bebb 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,6 +30,7 @@ android {
 
 dependencies {
 
+    implementation 'com.google.code.gson:gson:2.10.1'
     implementation libs.appcompat
     implementation libs.material
     implementation libs.activity
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 11b90b2..9f95c9a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -22,7 +22,7 @@
             </intent-filter>
         </activity>
         <activity
-            android:name=".CreateActivity"
+            android:name=".ModeleActivity"
             android:exported="false"/>
         <activity
             android:name=".OpenActivity"
diff --git a/app/src/main/java/fr/ul/projet/MainActivity.java b/app/src/main/java/fr/ul/projet/MainActivity.java
index 572c8d4..1f09ad5 100644
--- a/app/src/main/java/fr/ul/projet/MainActivity.java
+++ b/app/src/main/java/fr/ul/projet/MainActivity.java
@@ -7,7 +7,6 @@ import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.OpenableColumns;
-import android.util.Log;
 import android.view.View;
 import android.widget.EditText;
 import android.widget.Toast;
@@ -23,14 +22,12 @@ import androidx.appcompat.app.AppCompatActivity;
 import androidx.core.graphics.Insets;
 import androidx.core.view.ViewCompat;
 import androidx.core.view.WindowInsetsCompat;
-import androidx.lifecycle.ViewModelProvider;
 
 import fr.ul.projet.modele.Modele;
 
 public class MainActivity extends AppCompatActivity implements View.OnClickListener{
 
     private ActivityResultLauncher<Intent> launcher;
-    private static final int PICK_FILE_REQUEST = 1;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -51,7 +48,21 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
                 new ActivityResultCallback<ActivityResult>() {
                     @Override
                     public void onActivityResult(ActivityResult result){
-                        int resCode = result.getResultCode(); // Code retourné par l'activité
+                        if (result.getResultCode() == MainActivity.RESULT_OK && result.getData() != null){
+                            Uri fileUri = result.getData().getData();
+                            if (fileUri != null){
+                                Modele modele = new Modele().chargerModele(MainActivity.this, fileUri);
+
+                                if (modele != null){
+                                    Intent intent = new Intent(MainActivity.this, ModeleActivity.class);
+                                    intent.putExtra("modele", modele);
+                                    launcher.launch(intent);
+                                } else{
+                                    Toast.makeText(MainActivity.this, "Impossible de charger le modèle", Toast.LENGTH_LONG).show();
+                                }
+                            }
+                        }
+
 
                 }
     }
@@ -79,7 +90,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
             public void onClick(DialogInterface dialog, int which){
                 String userInput = input.getText().toString();
                 Modele modele = new Modele(userInput);
-                Intent intent = new Intent(MainActivity.this, CreateActivity.class);
+                Intent intent = new Intent(MainActivity.this, ModeleActivity.class);
                 intent.putExtra("modele", modele);
                 launcher.launch(intent);
             }
@@ -119,25 +130,14 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
     }
 
     private void openFileChooser(){
-        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
         intent.setType("*/*");
         intent.addCategory(Intent.CATEGORY_OPENABLE);
-        startActivityForResult(Intent.createChooser(intent, "Sélectionner un fichier"), PICK_FILE_REQUEST);
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data){
-        super.onActivityResult(requestCode, resultCode, data);
 
-        if (requestCode == PICK_FILE_REQUEST && resultCode == RESULT_OK && data != null){
-            Uri fileUri = data.getData();
+        intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{"application/json"});
+        intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
 
-            if (fileUri != null){
-                Intent intent = new Intent(MainActivity.this, OpenActivity.class);
-                intent.putExtra("fichier", getFileName(fileUri));
-                launcher.launch(intent);
-            }
-        }
+        launcher.launch(Intent.createChooser(intent, "Sélectionner un fichier"));
     }
 
     public String getFileName(Uri uri){
diff --git a/app/src/main/java/fr/ul/projet/CreateActivity.java b/app/src/main/java/fr/ul/projet/ModeleActivity.java
similarity index 62%
rename from app/src/main/java/fr/ul/projet/CreateActivity.java
rename to app/src/main/java/fr/ul/projet/ModeleActivity.java
index fc84cff..b52c0ea 100644
--- a/app/src/main/java/fr/ul/projet/CreateActivity.java
+++ b/app/src/main/java/fr/ul/projet/ModeleActivity.java
@@ -1,11 +1,17 @@
 package fr.ul.projet;
 
+import android.content.ContentValues;
+import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.net.Uri;
 import android.os.Bundle;
+import android.os.Environment;
+import android.provider.MediaStore;
 import android.view.View;
 import android.widget.EditText;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import androidx.activity.EdgeToEdge;
 import androidx.activity.result.ActivityResult;
@@ -17,12 +23,15 @@ import androidx.appcompat.app.AppCompatActivity;
 import androidx.core.graphics.Insets;
 import androidx.core.view.ViewCompat;
 import androidx.core.view.WindowInsetsCompat;
-import androidx.lifecycle.ViewModelProvider;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
 
 import fr.ul.projet.modele.Modele;
-import fr.ul.projet.modele.Piece;
 
-public class CreateActivity extends AppCompatActivity {
+public class ModeleActivity extends AppCompatActivity {
 
     private ActivityResultLauncher<Intent> launcher;
     private Modele modele;
@@ -70,7 +79,7 @@ public class CreateActivity extends AppCompatActivity {
             public void onClick(DialogInterface dialog, int which){
                 String userInput = input.getText().toString();
                 modele.ajouterPiece(userInput, "", "", "", "");
-                Intent intent = new Intent(CreateActivity.this, PieceActivity.class);
+                Intent intent = new Intent(ModeleActivity.this, PieceActivity.class);
                 intent.putExtra("modele", modele);
                 launcher.launch(intent);
             }
@@ -87,7 +96,35 @@ public class CreateActivity extends AppCompatActivity {
     }
 
     public void quit(View v){
-        Intent res = new Intent(CreateActivity.this, MainActivity.class);
+        Intent res = new Intent(ModeleActivity.this, MainActivity.class);
         launcher.launch(res);
     }
+
+    public void save(View v){
+        this.enregistrerModele(this);
+    }
+
+    public void enregistrerModele(Context context)  {
+        ContentValues values = new ContentValues();
+        values.put(MediaStore.MediaColumns.DISPLAY_NAME, this.modele.getFichierJson());
+        values.put(MediaStore.MediaColumns.MIME_TYPE, "application/json");
+        values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOCUMENTS + "/Modeles");
+
+        Uri uri = context.getContentResolver().insert(MediaStore.Files.getContentUri("external"), values);
+
+        if (uri != null) {
+            try (OutputStream outputStream = context.getContentResolver().openOutputStream(uri)) {
+                if (outputStream != null) {
+                    outputStream.write(this.modele.toJson().getBytes());
+                    outputStream.flush();
+                    outputStream.close();
+                    Toast.makeText(context, "Fichier enregistré avec succès : " + this.modele.getFichierJson(), Toast.LENGTH_LONG).show();
+                }
+            } catch (IOException e) {
+                Toast.makeText(context, "Erreur d'écriture du fichier", Toast.LENGTH_SHORT).show();
+            }
+        } else {
+            Toast.makeText(context, "Impossible de créer le fichier", Toast.LENGTH_SHORT).show();
+        }
+    }
 }
diff --git a/app/src/main/java/fr/ul/projet/PieceActivity.java b/app/src/main/java/fr/ul/projet/PieceActivity.java
index 49cc97a..9aee075 100644
--- a/app/src/main/java/fr/ul/projet/PieceActivity.java
+++ b/app/src/main/java/fr/ul/projet/PieceActivity.java
@@ -92,7 +92,7 @@ public class PieceActivity extends AppCompatActivity {
     }
 
     public void backToModele(View v){
-        Intent res = new Intent(PieceActivity.this, CreateActivity.class);
+        Intent res = new Intent(PieceActivity.this, ModeleActivity.class);
         res.putExtra("modele", this.modele);
         launcher.launch(res);
     }
diff --git a/app/src/main/java/fr/ul/projet/modele/Modele.java b/app/src/main/java/fr/ul/projet/modele/Modele.java
index 4973e2a..7442bb0 100644
--- a/app/src/main/java/fr/ul/projet/modele/Modele.java
+++ b/app/src/main/java/fr/ul/projet/modele/Modele.java
@@ -1,14 +1,21 @@
 package fr.ul.projet.modele;
 
+import android.content.Context;
+import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.google.gson.Gson;
+
 import org.json.JSONObject;
 
+import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -38,6 +45,14 @@ public class Modele implements Parcelable{
         this.fichierJson = new File("").getAbsolutePath() + "/" + this.getNom() + FabriqueIdentifiant.getInstance().getCptJson() + ".json";
     }
 
+    public Modele(){
+        this.pieceAffichee = false;
+        this.pieceCourante = null;
+        this.nom = "";
+        this.pieces = new HashMap<Integer, Piece>();
+        this.fichierJson = new File("").getAbsolutePath() + "/" + this.getNom() + FabriqueIdentifiant.getInstance().getCptJson() + ".json";
+    }
+
     protected Modele(Parcel in){
         this.pieceAffichee = in.readByte() != 0;
         this.fichierJson = in.readString();
@@ -244,6 +259,7 @@ public class Modele implements Parcelable{
         }
 
         try{
+            modeleJson.put("nom", this.nom);
             modeleJson.put("pièces", pieces);
         } catch (Exception e){
             e.printStackTrace();
@@ -252,31 +268,26 @@ public class Modele implements Parcelable{
         return modeleJson.toString();
     }
 
-    public void enregistrerModele() throws Exception {
-        PrintWriter flotFiltre;
-        FileWriter flot;
 
-        try {
-            File file = new File(this.fichierJson);
+    public Modele chargerModele(Context context, Uri fichier){
+        try (InputStream inputStream = context.getContentResolver().openInputStream(fichier);
+             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
 
-            if (file.exists()){
-                file.delete();
+            StringBuilder jsonBuilder = new StringBuilder();
+            String line;
+            while ((line = reader.readLine()) != null) {
+                jsonBuilder.append(line);
             }
 
-            flot = new FileWriter(file.getAbsoluteFile());
-            flotFiltre = new PrintWriter(new BufferedWriter(flot));
-            flotFiltre.print(this.toJson());
-            flotFiltre.close();
-        } catch (IOException e){
-            throw new Exception("Impossble d'écrire (" + e + ")");
-        }
-    }
+            String jsonString = jsonBuilder.toString();
 
-    public void chargerModele() throws Exception{
-        try{
-            // Charger via json
-        } catch (Exception e) {
-            throw new Exception("Impossible de charger le modèle (" + e + ")");
+            // Désérialiser le JSON en un objet Modele avec Gson
+            Gson gson = new Gson();
+            return gson.fromJson(jsonString, Modele.class);
+
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
         }
     }
 
diff --git a/app/src/main/res/layout/activity_create.xml b/app/src/main/res/layout/activity_create.xml
index be5a14c..0175487 100644
--- a/app/src/main/res/layout/activity_create.xml
+++ b/app/src/main/res/layout/activity_create.xml
@@ -44,4 +44,17 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintVertical_bias="0.836" />
+
+    <Button
+        android:id="@+id/boutonSave"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:onClick="save"
+        android:text="@string/sauvegarder"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.497"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.005" />
 </androidx.constraintlayout.widget.ConstraintLayout>
\ 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 cbc4a84..e7234d1 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -7,4 +7,5 @@
     <string name="quitter">Retour à l\'accueil</string>
     <string name="accueil">Retour au modèle</string>
     <string name="creer_piece">Ajouter un pièce</string>
+    <string name="sauvegarder">Sauvegarder le modèle</string>
 </resources>
\ No newline at end of file
-- 
GitLab