diff --git a/README.md b/README.md index d76d3a67..0f746762 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,6 @@ For questions, bugs, suggestions you can: This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. ## About -Family Gem is written in Java within Eclipse and Android Studio. -Project started on beginning of 2018. -Author is Michele Salvador, an Italian self-taught programmer and genealogy enthusiast. +Family Gem is written in Java within Eclipse and Android Studio. +Project started on beginning of 2018. +Author is Michele Salvador, an Italian programmer and genealogy enthusiast. diff --git a/app/build.gradle b/app/build.gradle index d60f90ec..4df8c44b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -22,7 +22,7 @@ android { minSdkVersion 19 targetSdkVersion 33 versionCode 22 - versionName '0.9.1' + versionName '0.9.1.4' vectorDrawables.useSupportLibrary = true resConfigs 'cs', 'de', 'en', 'eo', 'es', 'fa', 'fr', 'hr', 'hu', 'in', 'it', 'iw', 'kn', 'mr', 'nb', 'nl', 'pl', 'pt', 'ru', 'sk', 'sr', 'tr', 'uk' def utenteAruba = "" @@ -69,8 +69,8 @@ android { dependencies { implementation 'androidx.multidex:multidex:2.0.1' implementation 'commons-io:commons-io:2.8.0' // Versions from 2.9.0 to 2.11.0 give NoClassDefFoundError on old devices - implementation 'com.google.code.gson:gson:2.8.7' - implementation 'commons-net:commons-net:3.6' + implementation 'com.google.code.gson:gson:2.10' + implementation 'commons-net:commons-net:3.8.0' implementation 'androidx.lifecycle:lifecycle-process:2.5.1' //implementation 'org.familysearch.gedcom:gedcom:1.13.0' implementation files('libs/gedcom-1.14.0-SNAPSHOT.jar') @@ -78,16 +78,17 @@ dependencies { implementation 'androidx.work:work-runtime:2.7.1' implementation 'androidx.appcompat:appcompat:1.7.0-alpha01' implementation 'com.android.installreferrer:installreferrer:2.2' - implementation 'com.google.android.material:material:1.6.1' + implementation 'com.google.android.material:material:1.7.0' implementation 'com.google.android.flexbox:flexbox:3.0.0' implementation files('libs/gedcomgraph-3.2.jar') - implementation 'joda-time:joda-time:2.10.10' + implementation 'joda-time:joda-time:2.12.1' implementation 'com.theartofdev.edmodo:android-image-cropper:2.8.0' - implementation 'com.otaliastudios:zoomlayout:1.3.0' - implementation 'com.github.AndroidDeveloperLB:FastScrollerAndRecyclerViewFixes:5' - implementation 'org.jsoup:jsoup:1.14.1' + implementation 'com.otaliastudios:zoomlayout:1.9.0' + implementation 'com.github.AndroidDeveloperLB:FastScrollerAndRecyclerViewFixes:9' + implementation 'org.jsoup:jsoup:1.15.3' implementation files('libs/geonames-1.1.14.jar') implementation 'com.squareup.picasso:picasso:2.71828' + implementation 'jp.wasabeef:picasso-transformations:2.2.1' implementation 'org.jdom:jdom:1.1.3' // Don't update to version 2.x for compatibility with GeoNames //androidTestImplementation 'androidx.test:runner:1.4.0' } diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index fe915179..2ad0ef4c 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,4 +1,4 @@ --keep class app.familygem.Settings, app.familygem.Chiesa, app.familygem.Podio # for R8.fullMode +-keep class app.familygem.Settings, app.familygem.list.FamiliesFragment, app.familygem.Podio # for R8.fullMode -keepclassmembernames class app.familygem.Settings, app.familygem.Settings$Tree, app.familygem.Settings$Diagram, app.familygem.Settings$ZippedTree, app.familygem.Settings$Share { *; } -keepclassmembers class org.folg.gedcom.model.* { *; } #-keeppackagenames org.folg.gedcom.model # Gedcom parser lo chiama come stringa eppure funziona anche senza diff --git a/app/src/androidTest/java/app/familygem/ExportTest.java b/app/src/androidTest/java/app/familygem/ExportTest.java index 77e26f8a..e4e03f47 100644 --- a/app/src/androidTest/java/app/familygem/ExportTest.java +++ b/app/src/androidTest/java/app/familygem/ExportTest.java @@ -130,24 +130,24 @@ void esportaGedcom() { if( !documentsDir.exists() ) documentsDir.mkdir(); File fileGedcom = new File( documentsDir, "Küçük ağaç.ged" ); - Esportatore esp = new Esportatore( appContext ); - assertTrue( esp.apriAlbero( idAlbero ) ); - assertNull( esp.messaggioSuccesso ); - assertNull( esp.messaggioErrore ); - assertTrue( esp.esportaGedcom(Uri.fromFile(fileGedcom)) ); + Exporter esp = new Exporter( appContext ); + assertTrue( esp.openTree( idAlbero ) ); + assertNull( esp.successMessage); + assertNull( esp.errorMessage); + assertTrue( esp.exportGedcom(Uri.fromFile(fileGedcom)) ); assertTrue( fileGedcom.isFile() ); - assertEquals( esp.messaggioSuccesso, appContext.getString(R.string.gedcom_exported_ok) ); - s.l( esp.messaggioSuccesso ); + assertEquals( esp.successMessage, appContext.getString(R.string.gedcom_exported_ok) ); + s.l( esp.successMessage); File fileGedcomZip = new File( documentsDir, "ਸੰਕੁਚਿਤ.zip" ); - Esportatore esp2 = new Esportatore( appContext ); - assertTrue( esp2.apriAlbero( idAlbero ) ); - boolean result = esp2.esportaGedcomZippato(Uri.fromFile(fileGedcomZip)); - s.l( esp2.messaggioErrore ); + Exporter esp2 = new Exporter( appContext ); + assertTrue( esp2.openTree( idAlbero ) ); + boolean result = esp2.exportZippedGedcom(Uri.fromFile(fileGedcomZip)); + s.l( esp2.errorMessage); assertTrue( result ); - assertEquals( esp2.messaggioSuccesso, appContext.getString(R.string.zip_exported_ok) ); + assertEquals( esp2.successMessage, appContext.getString(R.string.zip_exported_ok) ); assertTrue( fileGedcomZip.isFile() ); - s.l( esp2.messaggioSuccesso ); + s.l( esp2.successMessage); } // Esporta in /Documents l'ultimo albero come backup ZIP @@ -155,14 +155,14 @@ void esportaBackup() { File documentsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS); if( !documentsDir.exists() ) documentsDir.mkdir(); File fileBackup = new File( documentsDir, "Becàp olè.zip" ); - Esportatore esp = new Esportatore( appContext ); + Exporter esp = new Exporter( appContext ); Settings.Tree ultimoAlb = Global.settings.trees.get(Global.settings.trees.size()-1); - assertTrue( esp.apriAlbero( ultimoAlb.id ) ); - boolean result = esp.esportaBackupZip( null, -1, Uri.fromFile(fileBackup) ); - s.l( esp.messaggioErrore ); + assertTrue( esp.openTree( ultimoAlb.id ) ); + boolean result = esp.exportZipBackup( null, -1, Uri.fromFile(fileBackup) ); + s.l( esp.errorMessage); assertTrue( result ); - assertEquals( esp.messaggioSuccesso, appContext.getString(R.string.zip_exported_ok) ); + assertEquals( esp.successMessage, appContext.getString(R.string.zip_exported_ok) ); assertTrue( fileBackup.isFile() ); - s.l( esp.messaggioSuccesso ); + s.l( esp.successMessage); } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ccfccb50..e6f02cb5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -56,19 +56,19 @@ + android:parentActivityName=".TreesActivity" /> + android:parentActivityName=".TreesActivity"/> + android:parentActivityName=".TreesActivity" /> + android:parentActivityName=".TreesActivity" /> + android:parentActivityName=".TreesActivity" /> diff --git a/app/src/main/java/app/familygem/AdattatoreGalleriaMedia.java b/app/src/main/java/app/familygem/AdattatoreGalleriaMedia.java deleted file mode 100644 index b43b0c3c..00000000 --- a/app/src/main/java/app/familygem/AdattatoreGalleriaMedia.java +++ /dev/null @@ -1,170 +0,0 @@ -// Adattatore per RecyclerView con lista dei media - -package app.familygem; - -import android.app.Activity; -import android.content.Context; -import androidx.appcompat.app.AppCompatActivity; -import androidx.recyclerview.widget.RecyclerView; -import android.content.Intent; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; -import org.folg.gedcom.model.Media; -import org.folg.gedcom.model.Person; -import java.util.List; -import app.familygem.detail.Immagine; -import app.familygem.visitor.ListaMediaContenitore; -import app.familygem.visitor.TrovaPila; - -class AdattatoreGalleriaMedia extends RecyclerView.Adapter { - - private List listaMedia; - private boolean dettagli; - - AdattatoreGalleriaMedia( List listaMedia, boolean dettagli ) { - this.listaMedia = listaMedia; - this.dettagli = dettagli; - } - - @Override - public gestoreVistaMedia onCreateViewHolder( ViewGroup parent, int tipo ) { - View vista = LayoutInflater.from(parent.getContext()).inflate( R.layout.pezzo_media, parent, false ); - return new gestoreVistaMedia( vista, dettagli ); - } - @Override - public void onBindViewHolder( final gestoreVistaMedia gestore, int posizione ) { - gestore.setta( posizione ); - } - @Override - public int getItemCount() { - return listaMedia.size(); - } - @Override - public long getItemId(int position) { - return position; - } - @Override - public int getItemViewType(int position) { - return position; - } - - class gestoreVistaMedia extends RecyclerView.ViewHolder implements View.OnClickListener { - View vista; - boolean dettagli; - Media media; - Object contenitore; - ImageView vistaImmagine; - TextView vistaTesto; - TextView vistaNumero; - gestoreVistaMedia( View vista, boolean dettagli ) { - super(vista); - this.vista = vista; - this.dettagli = dettagli; - vistaImmagine = vista.findViewById( R.id.media_img ); - vistaTesto = vista.findViewById( R.id.media_testo ); - vistaNumero = vista.findViewById( R.id.media_num ); - } - void setta( int posizione ) { - media = listaMedia.get( posizione ).media; - contenitore = listaMedia.get( posizione ).contenitore; - if( dettagli ) { - arredaMedia( media, vistaTesto, vistaNumero ); - vista.setOnClickListener( this ); - ((Activity)vista.getContext()).registerForContextMenu( vista ); - vista.setTag( R.id.tag_oggetto, media ); - vista.setTag( R.id.tag_contenitore, contenitore ); - // Registra menu contestuale - final AppCompatActivity attiva = (AppCompatActivity) vista.getContext(); - if( vista.getContext() instanceof Individuo ) { // Fragment individuoMedia - attiva.getSupportFragmentManager() - .findFragmentByTag( "android:switcher:" + R.id.schede_persona + ":0" ) // non garantito in futuro - .registerForContextMenu( vista ); - } else if( vista.getContext() instanceof Principal ) // Fragment Galleria - attiva.getSupportFragmentManager().findFragmentById( R.id.contenitore_fragment ).registerForContextMenu( vista ); - else // nelle AppCompatActivity - attiva.registerForContextMenu( vista ); - } else { - RecyclerView.LayoutParams parami = new RecyclerView.LayoutParams( RecyclerView.LayoutParams.WRAP_CONTENT, U.dpToPx(110) ); - int margin = U.dpToPx(5); - parami.setMargins( margin, margin, margin, margin ); - vista.setLayoutParams( parami ); - vistaTesto.setVisibility( View.GONE ); - vistaNumero.setVisibility( View.GONE ); - } - F.dipingiMedia( media, vistaImmagine, vista.findViewById(R.id.media_circolo) ); - } - @Override - public void onClick( View v ) { - AppCompatActivity attiva = (AppCompatActivity) v.getContext(); - // Galleria in modalità scelta dell'oggetto media - // Restituisce l'id di un oggetto media a IndividuoMedia - if( attiva.getIntent().getBooleanExtra( "galleriaScegliMedia", false ) ) { - Intent intent = new Intent(); - intent.putExtra( "idMedia", media.getId() ); - attiva.setResult( Activity.RESULT_OK, intent ); - attiva.finish(); - // Galleria in modalità normale apre Immagine - } else { - Intent intento = new Intent( v.getContext(), Immagine.class ); - if( media.getId() != null ) { // tutti i Media record - Memoria.setPrimo( media ); - } else if( (attiva instanceof Individuo && contenitore instanceof Person) // media di primo livello nell'Indi - || attiva instanceof Dettaglio ) { // normale apertura nei Dettagli - Memoria.aggiungi( media ); - } else { // da Galleria tutti i media semplici, o da IndividuoMedia i media sotto molteplici livelli - new TrovaPila( Global.gc, media ); - if( attiva instanceof Principal ) // Solo in Galleria - intento.putExtra( "daSolo", true ); // così poi Immagine mostra la dispensa - } - v.getContext().startActivity( intento ); - } - } - } - - static void arredaMedia( Media media, TextView vistaTesto, TextView vistaNumero ) { - String testo = ""; - if( media.getTitle() != null ) - testo = media.getTitle() + "\n"; - if( Global.settings.expert && media.getFile() != null ) { - String file = media.getFile(); - file = file.replace( '\\', '/' ); - if( file.lastIndexOf('/') > -1 ) { - if( file.length() > 1 && file.endsWith("/") ) // rimuove l'ultima barra - file = file.substring( 0, file.length()-1 ); - file = file.substring( file.lastIndexOf('/') + 1 ); - } - testo += file; - } - if( testo.isEmpty() ) - vistaTesto.setVisibility( View.GONE ); - else { - if( testo.endsWith("\n") ) - testo = testo.substring( 0, testo.length()-1 ); - vistaTesto.setText( testo ); - } - if( media.getId() != null ) { - vistaNumero.setText( String.valueOf(Galleria.popolarita(media)) ); - vistaNumero.setVisibility( View.VISIBLE ); - } else - vistaNumero.setVisibility( View.GONE ); - } - - // Questa serve solo per creare una RecyclerView con le iconcine dei media che risulti trasparente ai click - // todo però impedisce lo scroll in Dettaglio - static class RiciclaVista extends RecyclerView { - boolean dettagli; - public RiciclaVista( Context context, boolean dettagli) { - super(context); - this.dettagli = dettagli; - } - @Override - public boolean onTouchEvent( MotionEvent e ) { - super.onTouchEvent( e ); - return dettagli; // quando è false la griglia non intercetta il click - } - } -} \ No newline at end of file diff --git a/app/src/main/java/app/familygem/Anagrafe.java b/app/src/main/java/app/familygem/Anagrafe.java index c3eec2d6..e8544b8e 100644 --- a/app/src/main/java/app/familygem/Anagrafe.java +++ b/app/src/main/java/app/familygem/Anagrafe.java @@ -5,6 +5,7 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.StateListDrawable; import android.os.Bundle; +import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.appcompat.app.AlertDialog; @@ -35,6 +36,9 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; +import app.familygem.constant.Choice; import app.familygem.constant.Format; import app.familygem.constant.Gender; import static app.familygem.Global.gc; @@ -42,10 +46,12 @@ public class Anagrafe extends Fragment { - List people; - AdattatoreAnagrafe adapter; - private Order order; - private boolean gliIdsonoNumerici; + private List allPeople = new ArrayList<>(); // The immutable complete list of people + private List selectedPeople = new ArrayList<>(); // Some persons selected by the search feature + private PersonsAdapter adapter = new PersonsAdapter(); + private @NonNull Order order = Order.NONE; + private SearchView searchView; + private boolean idsAreNumeric; private enum Order { NONE, @@ -64,15 +70,13 @@ public Order prev() { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { - View view = inflater.inflate(R.layout.ricicla_vista, container, false); + View view = inflater.inflate(R.layout.recycler_view, container, false); if( gc != null ) { - people = gc.getPeople(); - arredaBarra(); - RecyclerView vistaLista = view.findViewById(R.id.riciclatore); - vistaLista.setPadding(12, 12, 12, vistaLista.getPaddingBottom()); - adapter = new AdattatoreAnagrafe(); - vistaLista.setAdapter(adapter); - gliIdsonoNumerici = verificaIdNumerici(); + establishPeople(); + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); + recyclerView.setPadding(12, 12, 12, recyclerView.getPaddingBottom()); + recyclerView.setAdapter(adapter); + idsAreNumeric = verifyNumericIds(); view.findViewById(R.id.fab).setOnClickListener(v -> { Intent intent = new Intent(getContext(), EditaIndividuo.class); intent.putExtra("idIndividuo", "TIZIO_NUOVO"); @@ -82,30 +86,70 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bu // Fast scroller StateListDrawable thumbDrawable = (StateListDrawable)ContextCompat.getDrawable(getContext(), R.drawable.scroll_thumb); Drawable lineDrawable = ContextCompat.getDrawable(getContext(), R.drawable.empty); - new FastScrollerEx(vistaLista, thumbDrawable, lineDrawable, thumbDrawable, lineDrawable, + new FastScrollerEx(recyclerView, thumbDrawable, lineDrawable, thumbDrawable, lineDrawable, U.dpToPx(40), U.dpToPx(100), 0, true, U.dpToPx(80)); } return view; } - void arredaBarra() { - ((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(people.size() + " " - + getString(people.size() == 1 ? R.string.person : R.string.persons).toLowerCase()); - setHasOptionsMenu(people.size() > 1); + // Put all the people inside the lists + private void establishPeople() { + allPeople.clear(); + for( Person person : gc.getPeople()) { + allPeople.add(new PersonWrapper(person)); + // On version 0.9.2 all person's extensions was removed, replaced by PersonWrapper fields + person.setExtensions(null); // todo remove on a future release + } + selectedPeople.clear(); + selectedPeople.addAll(allPeople); + // Display search results every second + Timer timer = new Timer(); + TimerTask task = new TimerTask() { + @Override + public void run() { + if( getActivity() != null && searchView != null ) { + getActivity().runOnUiThread(() -> adapter.getFilter().filter(searchView.getQuery())); + } + } + }; + timer.scheduleAtFixedRate(task, 500, 1000); + new Thread() { + @Override + public void run() { + for( PersonWrapper wrapper : allPeople ) { + wrapper.completeFields(); // This task could take long time on a big tree + } + timer.cancel(); + // Display final rusults + if( getActivity() != null && searchView != null ) { + getActivity().runOnUiThread(() -> adapter.getFilter().filter(searchView.getQuery())); + } + } + }.start(); + furnishToolbar(); } - public class AdattatoreAnagrafe extends RecyclerView.Adapter implements Filterable { + // Title and options in toolbar + private void furnishToolbar() { + ((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(allPeople.size() + " " + + getString(allPeople.size() == 1 ? R.string.person : R.string.persons).toLowerCase()); + setHasOptionsMenu(allPeople.size() > 1); + } + + private class PersonsAdapter extends RecyclerView.Adapter implements Filterable { @Override - public GestoreIndividuo onCreateViewHolder(ViewGroup parent, int tipo) { - View vistaIndividuo = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.pezzo_individuo, parent, false); - registerForContextMenu(vistaIndividuo); - return new GestoreIndividuo(vistaIndividuo); + public IndiHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View indiView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.piece_person, parent, false); + registerForContextMenu(indiView); + return new IndiHolder(indiView); } @Override - public void onBindViewHolder(GestoreIndividuo gestore, int posizione) { - Person person = people.get(posizione); - View vistaIndi = gestore.vista; + public void onBindViewHolder(IndiHolder indiHolder, int position) { + Person person = selectedPeople.get(position).person; + View indiView = indiHolder.view; + indiView.setTag(R.id.tag_id, person.getId()); + indiView.setTag(R.id.tag_position, position); String label = null; if( order == Order.ID_ASC || order == Order.ID_DESC ) @@ -113,8 +157,8 @@ public void onBindViewHolder(GestoreIndividuo gestore, int posizione) { else if( order == Order.SURNAME_ASC || order == Order.SURNAME_DESC ) label = U.surname(person); else if( order == Order.KIN_ASC || order == Order.KIN_DESC ) - label = String.valueOf(person.getExtension("kin")); - TextView infoView = vistaIndi.findViewById(R.id.indi_ruolo); + label = String.valueOf(selectedPeople.get(position).relatives); + TextView infoView = indiView.findViewById(R.id.person_info); if( label == null ) infoView.setVisibility(View.GONE); else { @@ -123,53 +167,59 @@ else if( order == Order.KIN_ASC || order == Order.KIN_DESC ) infoView.setVisibility(View.VISIBLE); } - TextView vistaNome = vistaIndi.findViewById(R.id.indi_nome); - String nome = U.epiteto(person); - vistaNome.setText(nome); - vistaNome.setVisibility((nome.isEmpty() && label != null) ? View.GONE : View.VISIBLE); + TextView nameView = indiView.findViewById(R.id.person_name); + String name = U.epiteto(person); + nameView.setText(name); + nameView.setVisibility((name.isEmpty() && label != null) ? View.GONE : View.VISIBLE); - TextView vistaTitolo = vistaIndi.findViewById(R.id.indi_titolo); - String titolo = U.titolo(person); - if( titolo.isEmpty() ) - vistaTitolo.setVisibility(View.GONE); + TextView titleView = indiView.findViewById(R.id.person_title); + String title = U.titolo(person); + if( title.isEmpty() ) + titleView.setVisibility(View.GONE); else { - vistaTitolo.setText(titolo); - vistaTitolo.setVisibility(View.VISIBLE); + titleView.setText(title); + titleView.setVisibility(View.VISIBLE); } - int bordo; + int border; switch( Gender.getGender(person) ) { - case MALE: bordo = R.drawable.casella_bordo_maschio; break; - case FEMALE: bordo = R.drawable.casella_bordo_femmina; break; - default: bordo = R.drawable.casella_bordo_neutro; + case MALE: border = R.drawable.casella_bordo_maschio; break; + case FEMALE: border = R.drawable.casella_bordo_femmina; break; + default: border = R.drawable.casella_bordo_neutro; } - vistaIndi.findViewById(R.id.indi_bordo).setBackgroundResource(bordo); + indiView.findViewById(R.id.person_border).setBackgroundResource(border); - U.details(person, vistaIndi.findViewById(R.id.indi_dettagli)); - F.unaFoto(Global.gc, person, vistaIndi.findViewById(R.id.indi_foto)); - vistaIndi.findViewById(R.id.indi_lutto).setVisibility(U.isDead(person) ? View.VISIBLE : View.GONE); - vistaIndi.setTag(person.getId()); + U.details(person, indiView.findViewById(R.id.person_details)); + F.oneImage(Global.gc, person, indiView.findViewById(R.id.person_image)); + indiView.findViewById(R.id.person_mourning).setVisibility(U.isDead(person) ? View.VISIBLE : View.GONE); } @Override public Filter getFilter() { return new Filter() { @Override protected FilterResults performFiltering(CharSequence charSequence) { - String query = charSequence.toString(); - if( query.isEmpty() ) { - people = gc.getPeople(); + // Split query by spaces and search all the words + String[] query = charSequence.toString().trim().toLowerCase().split("\\s+"); + selectedPeople.clear(); + if( query.length == 0 ) { + selectedPeople.addAll(allPeople); } else { - List filteredList = new ArrayList<>(); - for( Person pers : gc.getPeople() ) { - if( U.epiteto(pers).toLowerCase().contains(query.toLowerCase()) ) { - filteredList.add(pers); + outer: + for( PersonWrapper wrapper : allPeople ) { + if( wrapper.text != null ) { + for( String word : query ) { + if( !wrapper.text.contains(word) ) { + continue outer; + } + } + selectedPeople.add(wrapper); } } - people = filteredList; } - sortPeople(); + if( order != Order.NONE ) + sortPeople(); FilterResults filterResults = new FilterResults(); - filterResults.values = people; + filterResults.values = selectedPeople; return filterResults; } @Override @@ -180,39 +230,39 @@ protected void publishResults(CharSequence cs, FilterResults fr) { } @Override public int getItemCount() { - return people.size(); + return selectedPeople.size(); } } - class GestoreIndividuo extends RecyclerView.ViewHolder implements View.OnClickListener { - View vista; - GestoreIndividuo( View vista ) { - super( vista ); - this.vista = vista; - vista.setOnClickListener(this); + private class IndiHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + View view; + IndiHolder(View view) { + super(view); + this.view = view; + view.setOnClickListener(this); } @Override - public void onClick( View vista ) { - // Anagrafe per scegliere il parente e restituire i valori a Diagramma, Individuo, Famiglia o Condivisione - Person parente = gc.getPerson((String)vista.getTag()); + public void onClick(View view) { + // Choose the relative and return the values to Diagram, ProfileActivity, Famiglia or Condivisione + Person relative = gc.getPerson((String)view.getTag(R.id.tag_id)); Intent intent = getActivity().getIntent(); - if( intent.getBooleanExtra("anagrafeScegliParente", false) ) { - intent.putExtra( "idParente", parente.getId() ); + if( intent.getBooleanExtra(Choice.PERSON, false) ) { + intent.putExtra("idParente", relative.getId()); // Cerca una eventuale famiglia esistente che possa ospitare perno String collocazione = intent.getStringExtra("collocazione"); if( collocazione != null && collocazione.equals("FAMIGLIA_ESISTENTE") ) { String idFamiglia = null; switch( intent.getIntExtra("relazione",0) ) { case 1: // Genitore - if( parente.getSpouseFamilyRefs().size() > 0 ) - idFamiglia = parente.getSpouseFamilyRefs().get(0).getRef(); + if( relative.getSpouseFamilyRefs().size() > 0 ) + idFamiglia = relative.getSpouseFamilyRefs().get(0).getRef(); break; case 2: - if( parente.getParentFamilyRefs().size() > 0 ) - idFamiglia = parente.getParentFamilyRefs().get(0).getRef(); + if( relative.getParentFamilyRefs().size() > 0 ) + idFamiglia = relative.getParentFamilyRefs().get(0).getRef(); break; case 3: - for( Family fam : parente.getSpouseFamilies(gc) ) { + for( Family fam : relative.getSpouseFamilies(gc) ) { if( fam.getHusbandRefs().isEmpty() || fam.getWifeRefs().isEmpty() ) { idFamiglia = fam.getId(); break; @@ -220,7 +270,7 @@ public void onClick( View vista ) { } break; case 4: - for( Family fam : parente.getParentFamilies(gc) ) { + for( Family fam : relative.getParentFamilies(gc) ) { if( fam.getHusbandRefs().isEmpty() || fam.getWifeRefs().isEmpty() ) { idFamiglia = fam.getId(); break; @@ -235,30 +285,36 @@ public void onClick( View vista ) { } getActivity().setResult( AppCompatActivity.RESULT_OK, intent ); getActivity().finish(); - } else { // Normale collegamento alla scheda individuo - // todo Click sulla foto apre la scheda media.. - // intento.putExtra( "scheda", 0 ); - Memoria.setPrimo( parente ); - startActivity( new Intent(getContext(), Individuo.class) ); + } else { // Normal link to the profile + Memory.setPrimo(relative); + startActivity(new Intent(getContext(), ProfileActivity.class)); } } } - // Andandosene dall'attività senza aver scelto un parente resetta l'extra + // Update all the contents onBackPressed() + public void restart() { + // Recreate the lists for some person added or removed + establishPeople(); + // Update content of existing views + adapter.notifyDataSetChanged(); + } + + // Reset the extra if leaving this fragment without choosing a person @Override public void onPause() { super.onPause(); - getActivity().getIntent().removeExtra("anagrafeScegliParente"); + getActivity().getIntent().removeExtra(Choice.PERSON); } // Verifica se tutti gli id delle persone contengono numeri - // Appena un id contiene solo lettere restituisce falso - boolean verificaIdNumerici() { - esterno: - for( Person p : gc.getPeople() ) { - for( char c : p.getId().toCharArray() ) { - if (Character.isDigit(c)) - continue esterno; + // Appena un id contiene solo lettere restituisce false + private boolean verifyNumericIds() { + out: + for( Person person : gc.getPeople() ) { + for( char character : person.getId().toCharArray() ) { + if( Character.isDigit(character) ) + continue out; } return false; } @@ -266,161 +322,99 @@ boolean verificaIdNumerici() { } private void sortPeople() { - Collections.sort(people, (p1, p2) -> { + Collections.sort(selectedPeople, (wrapper1, wrapper2) -> { + Person p1 = wrapper1.person; + Person p2 = wrapper2.person; switch( order ) { case ID_ASC: // Sort for GEDCOM ID - if( gliIdsonoNumerici ) - return U.soloNumeri(p1.getId()) - U.soloNumeri(p2.getId()); + if( idsAreNumeric ) + return U.getNumberOnly(p1.getId()) - U.getNumberOnly(p2.getId()); else return p1.getId().compareToIgnoreCase(p2.getId()); case ID_DESC: - if( gliIdsonoNumerici ) - return U.soloNumeri(p2.getId()) - U.soloNumeri(p1.getId()); + if( idsAreNumeric ) + return U.getNumberOnly(p2.getId()) - U.getNumberOnly(p1.getId()); else return p2.getId().compareToIgnoreCase(p1.getId()); case SURNAME_ASC: // Sort for surname - if (p1.getNames().size() == 0) // i nomi null vanno in fondo - return (p2.getNames().size() == 0) ? 0 : 1; - if (p2.getNames().size() == 0) - return -1; - Name n1 = p1.getNames().get(0); - Name n2 = p2.getNames().get(0); - // anche i nomi con value, given e surname null vanno in fondo - if (n1.getValue() == null && n1.getGiven() == null && n1.getSurname() == null) - return (n2.getValue() == null) ? 0 : 1; - if (n2.getValue() == null && n2.getGiven() == null && n2.getSurname() == null) + if( wrapper1.surname == null ) // Null surnames go to the end + return wrapper2.surname == null ? 0 : 1; + if( wrapper2.surname == null ) return -1; - return cognomeNome(p1).compareToIgnoreCase(cognomeNome(p2)); + return wrapper1.surname.compareTo(wrapper2.surname); case SURNAME_DESC: - if (p1.getNames().size() == 0) - return p2.getNames().size() == 0 ? 0 : 1; - if (p2.getNames().size() == 0) + if( wrapper1.surname == null ) + return wrapper2.surname == null ? 0 : 1; + if( wrapper2.surname == null ) return -1; - n1 = p1.getNames().get(0); - n2 = p2.getNames().get(0); - if (n1.getValue() == null && n1.getGiven() == null && n1.getSurname() == null) - return (n2.getValue() == null) ? 0 : 1; - if (n2.getValue() == null && n2.getGiven() == null && n2.getSurname() == null) - return -1; - return cognomeNome(p2).compareToIgnoreCase(cognomeNome(p1)); + return wrapper2.surname.compareTo(wrapper1.surname); case DATE_ASC: // Sort for person's main year - return getDate(p1) - getDate(p2); + return wrapper1.date - wrapper2.date; case DATE_DESC: - int date1 = getDate(p1); - int date2 = getDate(p2); - if( date2 == Integer.MAX_VALUE ) // Those without year go to the bottom + if( wrapper2.date == Integer.MAX_VALUE ) // Those without year go to the bottom return -1; - if( date1 == Integer.MAX_VALUE ) - return date2 == Integer.MAX_VALUE ? 0 : 1; - return date2 - date1; + if( wrapper1.date == Integer.MAX_VALUE ) + return 1; + return wrapper2.date - wrapper1.date; case AGE_ASC: // Sort for main person's year - return getAge(p1) - getAge(p2); + return wrapper1.age - wrapper2.age; case AGE_DESC: - int age1 = getAge(p1); - int age2 = getAge(p2); - if( age2 == Integer.MAX_VALUE ) // Those without age go to the bottom + if( wrapper2.age == Integer.MAX_VALUE ) // Those without age go to the bottom return -1; - if( age1 == Integer.MAX_VALUE ) - return age2 == Integer.MAX_VALUE ? 0 : 1; - return age2 - age1; + if( wrapper1.age == Integer.MAX_VALUE ) + return 1; + return wrapper2.age - wrapper1.age; case KIN_ASC: // Sort for number of relatives - return countRelatives(p1) - countRelatives(p2); + return wrapper1.relatives - wrapper2.relatives; case KIN_DESC: - return countRelatives(p2) - countRelatives(p1); + return wrapper2.relatives - wrapper1.relatives; } return 0; }); } - // Restituisce una stringa con cognome e nome attaccati: - // 'SalvadorMichele ' oppure 'ValleFrancesco Maria ' oppure ' Donatella ' - private static String cognomeNome(Person person) { - Name name = person.getNames().get(0); - String epiteto = name.getValue(); - String nomeDato = ""; - String cognome = " "; // deve esserci uno spazio per ordinare i nomi senza cognome - if( epiteto != null ) { - if( epiteto.indexOf('/') > 0 ) - nomeDato = epiteto.substring( 0, epiteto.indexOf('/') ); // prende il nome prima di '/' - if( epiteto.lastIndexOf('/') - epiteto.indexOf('/') > 1 ) // se c'è un cognome tra i due '/' - cognome = epiteto.substring( epiteto.indexOf('/')+1, epiteto.lastIndexOf("/") ); - String prefix = name.getPrefix(); // Solo il nomeDato proveniente dal value potrebbe avere un prefisso, dal given no perché già di suo è solo il nomeDato - if( prefix != null && nomeDato.startsWith(prefix) ) - nomeDato = nomeDato.substring( prefix.length() ).trim(); - } else { - if( name.getGiven() != null ) - nomeDato = name.getGiven(); - if( name.getSurname() != null ) - cognome = name.getSurname(); - } - String surPrefix = name.getSurnamePrefix(); - if( surPrefix != null && cognome.startsWith(surPrefix) ) - cognome = cognome.substring( surPrefix.length() ).trim(); - return cognome.concat( nomeDato ); - } - - // riceve una Person e restituisce il primo anno della sua esistenza - Datatore datatore = new Datatore(""); - private int findDate(Person person) { - for( EventFact event : person.getEventsFacts() ) { - if( event.getDate() != null ) { - datatore.analizza(event.getDate()); - return datatore.getDateNumber(); - } - } - return Integer.MAX_VALUE; - } - - int getDate(Person person) { - Object date = person.getExtension("date"); - return date == null ? Integer.MAX_VALUE : (int)date; - } - - // Calculate the age of a person in days or MAX_VALUE - private int calcAge(Person person) { - int days = Integer.MAX_VALUE; - Datatore start = null, end = null; - for( EventFact event : person.getEventsFacts() ) { - if( event.getTag() != null && event.getTag().equals("BIRT") && event.getDate() != null ) { - start = new Datatore(event.getDate()); - break; - } - } - for( EventFact event : person.getEventsFacts() ) { - if( event.getTag() != null && event.getTag().equals("DEAT") && event.getDate() != null ) { - end = new Datatore(event.getDate()); - break; - } - } - if( start != null && start.isSingleKind() && !start.data1.isFormat(Format.D_M) ) { - LocalDate startDate = new LocalDate(start.data1.date); - // If the person is still alive the end is now - LocalDate now = LocalDate.now(); - if( end == null && startDate.isBefore(now) - && Years.yearsBetween(startDate, now).getYears() <= 120 && !U.isDead(person) ) { - end = new Datatore(now.toDate()); - } - if( end != null && end.isSingleKind() && !end.data1.isFormat(Format.D_M) ) { - LocalDate endDate = new LocalDate(end.data1.date); - if( startDate.isBefore(endDate) || startDate.isEqual(endDate) ) { - days = Days.daysBetween(startDate, endDate).getDays(); + // Write a string with surname and first name concatenated: + // 'salvadormichele ' or 'vallefrancesco maria ' or ' donatella ' + private String getSurnameFirstname(Person person) { + List names = person.getNames(); + if( !names.isEmpty() ){ + Name name = names.get(0); + String value = name.getValue(); + if (value != null || name.getGiven() != null || name.getSurname() != null) { + String given = ""; + String surname = " "; // There must be a space to sort names without surname + if( value != null ) { + if( value.replace('/', ' ').trim().isEmpty() ) // Empty value + return null; + if( value.indexOf('/') > 0 ) + given = value.substring(0, value.indexOf('/')); // Take the given name before '/' + if( value.lastIndexOf('/') - value.indexOf('/') > 1 ) // If there is a surname between two '/' + surname = value.substring(value.indexOf('/') + 1, value.lastIndexOf("/")); + // Only the given name coming from the value could have a prefix, + // from getGiven() no, because it is already only the given name. + String prefix = name.getPrefix(); + if( prefix != null && given.startsWith(prefix) ) + given = given.substring(prefix.length()).trim(); + } else { + if( name.getGiven() != null ) + given = name.getGiven(); + if( name.getSurname() != null ) + surname = name.getSurname(); } + String surPrefix = name.getSurnamePrefix(); + if( surPrefix != null && surname.startsWith(surPrefix) ) + surname = surname.substring(surPrefix.length()).trim(); + return surname.concat(given).toLowerCase(); } } - return days; + return null; } - int getAge(Person person) { - Object age = person.getExtension("age"); - return age == null ? Integer.MAX_VALUE : (int)age; - } - - /** Count how many near relatives a person has: parents, siblings, step-siblings, spouses and children. - * Save also the result in the 'kin' extension. + /** Count how many near relatives one person has: parents, siblings, step-siblings, spouses and children. * @param person The person to start from * @return Number of near relatives (person excluded) */ - static int countRelatives(Person person) { + public static int countRelatives(Person person) { int count = 0; if( person != null ) { // Famiglie di origine: genitori e fratelli @@ -454,12 +448,86 @@ static int countRelatives(Person person) { count--; // Minus their self count += famiglia.getChildRefs().size(); } - person.putExtension("kin", count); } return count; } - // menu opzioni nella toolbar + // Class to wrap a person of the list and all their relevant fields + Datatore datator = new Datatore(""); // Here outside to initialize only once + private class PersonWrapper { + + final Person person; + String text; // Single string with all names and events for search + String surname; // Surname and name of the person + int date; // Date in the format YYYYMMDD + int age; // Age in days + int relatives; // Number of near relatives + + PersonWrapper(Person person) { + this.person = person; + } + + void completeFields() { + // Write one string concatenating all names and personal events + text = ""; + for( Name name : person.getNames() ) { + text += U.writeFullName(name, " ") + " "; + } + for( EventFact event : person.getEventsFacts() ) { + if( !("SEX".equals(event.getTag()) || "Y".equals(event.getValue())) ) // Sex and 'Yes' excluded + text += ProfileFactsFragment.writeEventText(event) + " "; + } + text = text.toLowerCase(); + + // Surname and first name concatenated + surname = getSurnameFirstname(person); + + // Find the first date of a person's life or MAX_VALUE + date = Integer.MAX_VALUE; + for( EventFact event : person.getEventsFacts() ) { + if( event.getDate() != null ) { + datator.analizza(event.getDate()); + date = datator.getDateNumber(); + } + } + + // Calculate the age of a person in days or MAX_VALUE + age = Integer.MAX_VALUE; + Datatore start = null, end = null; + for( EventFact event : person.getEventsFacts() ) { + if( event.getTag() != null && event.getTag().equals("BIRT") && event.getDate() != null ) { + start = new Datatore(event.getDate()); + break; + } + } + for( EventFact event : person.getEventsFacts() ) { + if( event.getTag() != null && event.getTag().equals("DEAT") && event.getDate() != null ) { + end = new Datatore(event.getDate()); + break; + } + } + if( start != null && start.isSingleKind() && !start.data1.isFormat(Format.D_M) ) { + LocalDate startDate = new LocalDate(start.data1.date); + // If the person is still alive the end is now + LocalDate now = LocalDate.now(); + if( end == null && startDate.isBefore(now) + && Years.yearsBetween(startDate, now).getYears() <= 120 && !U.isDead(person) ) { + end = new Datatore(now.toDate()); + } + if( end != null && end.isSingleKind() && !end.data1.isFormat(Format.D_M) ) { + LocalDate endDate = new LocalDate(end.data1.date); + if( startDate.isBefore(endDate) || startDate.isEqual(endDate) ) { + age = Days.daysBetween(startDate, endDate).getDays(); + } + } + } + + // Relatives + relatives = countRelatives(person); + } + } + + // Options menu in toolbar @Override public void onCreateOptionsMenu( Menu menu, MenuInflater inflater ) { @@ -471,18 +539,18 @@ public void onCreateOptionsMenu( Menu menu, MenuInflater inflater ) { subMenu.add(0, 4, 0, R.string.age); subMenu.add(0, 5, 0, R.string.number_relatives); - // Ricerca nell'Anagrafe - inflater.inflate( R.menu.cerca, menu ); // già questo basta a far comparire la lente con il campo di ricerca - final SearchView vistaCerca = (SearchView) menu.findItem(R.id.ricerca).getActionView(); - vistaCerca.setOnQueryTextListener( new SearchView.OnQueryTextListener() { + // Search in Anagrafe + inflater.inflate(R.menu.search, menu); // già questo basta a far comparire la lente con il campo di ricerca + searchView = (SearchView)menu.findItem(R.id.search_item).getActionView(); + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override - public boolean onQueryTextChange( String query ) { + public boolean onQueryTextChange(String query) { adapter.getFilter().filter(query); return true; } @Override - public boolean onQueryTextSubmit( String q ) { - vistaCerca.clearFocus(); + public boolean onQueryTextSubmit(String q) { + searchView.clearFocus(); return false; } }); @@ -491,46 +559,30 @@ public boolean onQueryTextSubmit( String q ) { public boolean onOptionsItemSelected( MenuItem item ) { int id = item.getItemId(); if( id > 0 && id <= 5 ) { - // Clicking twice the same menu item switchs sorting ASC and DESC + // Clicking twice the same menu item switches sorting ASC and DESC if( order == Order.values()[id * 2 - 1] ) order = order.next(); else if( order == Order.values()[id * 2] ) order = order.prev(); else order = Order.values()[id * 2 - 1]; - - if( order == Order.DATE_ASC ) { - for( Person p : gc.getPeople() ) { - int date = findDate(p); - if( date < Integer.MAX_VALUE ) - p.putExtension("date", date); - else - p.getExtensions().remove("date"); - } - } else if( order == Order.AGE_ASC ) { - for( Person p : gc.getPeople() ) { - int age = calcAge(p); - if( age < Integer.MAX_VALUE ) - p.putExtension("age", age); - else - p.getExtensions().remove("age"); - } - } sortPeople(); adapter.notifyDataSetChanged(); - //U.salvaJson( false ); // dubbio se metterlo per salvare subito il riordino delle persone... + //U.salvaJson(false); // dubbio se metterlo per salvare subito il riordino delle persone... return true; } return false; } - // Menu contestuale - private String idIndi; + // Context menu + private int position; + private String indiId; @Override - public void onCreateContextMenu( ContextMenu menu, View vista, ContextMenu.ContextMenuInfo info) { - idIndi = (String)vista.getTag(); + public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { + indiId = (String)view.getTag(R.id.tag_id); + position = (int)view.getTag(R.id.tag_position); menu.add(0, 0, 0, R.string.diagram); - String[] familyLabels = Diagram.getFamilyLabels(getContext(), gc.getPerson(idIndi), null); + String[] familyLabels = Diagram.getFamilyLabels(getContext(), gc.getPerson(indiId), null); if( familyLabels[0] != null ) menu.add(0, 1, 0, familyLabels[0]); if( familyLabels[1] != null ) @@ -541,28 +593,31 @@ public void onCreateContextMenu( ContextMenu menu, View vista, ContextMenu.Conte menu.add(0, 5, 0, R.string.delete); } @Override - public boolean onContextItemSelected( MenuItem item ) { + public boolean onContextItemSelected(MenuItem item) { int id = item.getItemId(); if( id == 0 ) { // Apri Diagramma - U.qualiGenitoriMostrare(getContext(), gc.getPerson(idIndi), 1); + U.qualiGenitoriMostrare(getContext(), gc.getPerson(indiId), 1); } else if( id == 1 ) { // Famiglia come figlio - U.qualiGenitoriMostrare(getContext(), gc.getPerson(idIndi), 2); + U.qualiGenitoriMostrare(getContext(), gc.getPerson(indiId), 2); } else if( id == 2 ) { // Famiglia come coniuge - U.qualiConiugiMostrare(getContext(), gc.getPerson(idIndi), null); + U.qualiConiugiMostrare(getContext(), gc.getPerson(indiId), null); } else if( id == 3 ) { // Modifica - Intent intento = new Intent(getContext(), EditaIndividuo.class); - intento.putExtra("idIndividuo", idIndi); - startActivity(intento); + Intent intent = new Intent(getContext(), EditaIndividuo.class); + intent.putExtra("idIndividuo", indiId); + startActivity(intent); } else if( id == 4 ) { // Edit ID - U.editId(getContext(), gc.getPerson(idIndi), adapter::notifyDataSetChanged); + U.editId(getContext(), gc.getPerson(indiId), adapter::notifyDataSetChanged); } else if( id == 5 ) { // Elimina - new AlertDialog.Builder(getContext()).setMessage( R.string.really_delete_person ) - .setPositiveButton( R.string.delete, (dialog, i) -> { - Family[] famiglie = deletePerson(getContext(), idIndi); - adapter.notifyDataSetChanged(); - arredaBarra(); + new AlertDialog.Builder(getContext()).setMessage(R.string.really_delete_person) + .setPositiveButton(R.string.delete, (dialog, i) -> { + Family[] famiglie = deletePerson(getContext(), indiId); + selectedPeople.remove(position); + allPeople.remove(position); + adapter.notifyItemRemoved(position); + adapter.notifyItemRangeChanged(position, selectedPeople.size() - position); + furnishToolbar(); U.controllaFamiglieVuote(getContext(), null, false, famiglie); - }).setNeutralButton( R.string.cancel, null ).show(); + }).setNeutralButton(R.string.cancel, null).show(); } else { return false; } @@ -571,26 +626,25 @@ public boolean onContextItemSelected( MenuItem item ) { // Cancella tutti i ref nelle famiglie della tal persona // Restituisce l'elenco delle famiglie affette - static Family[] scollega( String idScollegando ) { - Person egli = gc.getPerson( idScollegando ); - Set famiglie = new HashSet<>(); - for( Family f : egli.getParentFamilies(gc) ) { // scollega i suoi ref nelle famiglie - f.getChildRefs().remove( f.getChildren(gc).indexOf(egli) ); - famiglie.add( f ); + static Family[] unlinkPerson(Person person) { + Set families = new HashSet<>(); + for( Family f : person.getParentFamilies(gc) ) { // scollega i suoi ref nelle famiglie + f.getChildRefs().remove(f.getChildren(gc).indexOf(person)); + families.add(f); } - for( Family f : egli.getSpouseFamilies(gc) ) { - if( f.getHusbands(gc).contains(egli) ) { - f.getHusbandRefs().remove( f.getHusbands(gc).indexOf(egli) ); - famiglie.add( f ); + for( Family f : person.getSpouseFamilies(gc) ) { + if( f.getHusbands(gc).contains(person) ) { + f.getHusbandRefs().remove(f.getHusbands(gc).indexOf(person)); + families.add(f); } - if( f.getWives(gc).contains(egli) ) { - f.getWifeRefs().remove( f.getWives(gc).indexOf(egli) ); - famiglie.add( f ); + if( f.getWives(gc).contains(person) ) { + f.getWifeRefs().remove(f.getWives(gc).indexOf(person)); + families.add(f); } } - egli.setParentFamilyRefs( null ); // nell'indi scollega i ref delle famiglie a cui appartiene - egli.setSpouseFamilyRefs( null ); - return famiglie.toArray( new Family[0] ); + person.setParentFamilyRefs(null); // nell'indi scollega i ref delle famiglie a cui appartiene + person.setSpouseFamilyRefs(null); + return families.toArray(new Family[0]); } /** Delete a person from the tree, possibly find the new root. @@ -598,10 +652,10 @@ static Family[] scollega( String idScollegando ) { * @param personId Id of the person to be deleted * @return Array of modified families */ - static Family[] deletePerson(Context context, String personId) { - Family[] families = scollega(personId); + public static Family[] deletePerson(Context context, String personId) { Person person = gc.getPerson(personId); - Memoria.annullaIstanze(person); + Family[] families = unlinkPerson(person); + Memory.annullaIstanze(person); gc.getPeople().remove(person); gc.createIndexes(); // Necessary String newRootId = U.trovaRadice(gc); // Todo dovrebbe essere: trovaParentePiuProssimo diff --git a/app/src/main/java/app/familygem/CartelleMedia.java b/app/src/main/java/app/familygem/CartelleMedia.java index 1b5f1c24..433421de 100644 --- a/app/src/main/java/app/familygem/CartelleMedia.java +++ b/app/src/main/java/app/familygem/CartelleMedia.java @@ -1,5 +1,3 @@ -// Activity in cui è possibile vedere la lista delle cartelle, aggiungerne, eliminarne - package app.familygem; import android.Manifest; @@ -22,130 +20,132 @@ import java.util.ArrayList; import java.util.List; +// Activity where you can see the list of media folders, add them, delete them public class CartelleMedia extends BaseActivity { - int idAlbero; - List cartelle; + int treeId; + List dirs; List uris; @Override - protected void onCreate( Bundle bandolo ) { - super.onCreate( bandolo ); - setContentView( R.layout.cartelle_media ); - idAlbero = getIntent().getIntExtra( "idAlbero", 0 ); - cartelle = new ArrayList<>( Global.settings.getTree(idAlbero).dirs); - uris = new ArrayList<>( Global.settings.getTree(idAlbero).uris ); - aggiornaLista(); - getSupportActionBar().setDisplayHomeAsUpEnabled( true ); - findViewById( R.id.fab ).setOnClickListener( v -> { + protected void onCreate(Bundle bundle) { + super.onCreate(bundle); + setContentView(R.layout.cartelle_media); + treeId = getIntent().getIntExtra("idAlbero", 0); + dirs = new ArrayList<>(Global.settings.getTree(treeId).dirs); + uris = new ArrayList<>(Global.settings.getTree(treeId).uris); + updateList(); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + findViewById(R.id.fab).setOnClickListener(v -> { int perm = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE); if( perm == PackageManager.PERMISSION_DENIED ) - ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.READ_EXTERNAL_STORAGE }, 3517); + ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 3517); else if( perm == PackageManager.PERMISSION_GRANTED ) - faiScegliereCartella(); + chooseFolder(); }); - if( Global.settings.getTree(idAlbero).dirs.isEmpty() && Global.settings.getTree(idAlbero).uris.isEmpty() ) - new Fabuloso( this, R.string.add_device_folder ).show(); + if( Global.settings.getTree(treeId).dirs.isEmpty() && Global.settings.getTree(treeId).uris.isEmpty() ) + new Fabuloso(this, R.string.add_device_folder).show(); } - void faiScegliereCartella() { + void chooseFolder() { if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivityForResult( intent, 123 ); } else { - // KitKat utilizza la selezione di un file per risalire alla cartella + // KitKat uses the selection of a file to locate the container folder Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType( "*/*"); startActivityForResult( intent, 456 ); } } - void aggiornaLista() { - LinearLayout scatola = findViewById( R.id.cartelle_scatola ); - scatola.removeAllViews(); - for( String cart : cartelle ) { - View vistaCartella = getLayoutInflater().inflate( R.layout.pezzo_cartella, scatola, false ); - scatola.addView( vistaCartella ); - TextView vistaNome = vistaCartella.findViewById( R.id.cartella_nome ); - TextView vistaUrl = vistaCartella.findViewById( R.id.cartella_url ); - vistaUrl.setText( cart ); + void updateList() { + LinearLayout layout = findViewById(R.id.cartelle_scatola); + layout.removeAllViews(); + for( String dir : dirs ) { + View folderView = getLayoutInflater().inflate(R.layout.pezzo_cartella, layout, false); + layout.addView(folderView); + TextView nameView = folderView.findViewById(R.id.cartella_nome); + TextView urlView = folderView.findViewById(R.id.cartella_url); + urlView.setText(dir); if( Global.settings.expert ) - vistaUrl.setSingleLine( false ); - View bottoneElimina = vistaCartella.findViewById( R.id.cartella_elimina ); + urlView.setSingleLine(false); + View deleteButton = folderView.findViewById(R.id.cartella_elimina); // La cartella '/storage/.../Android/data/app.familygem/files/X' va preservata inquanto è quella di default dei media copiati // Oltretutto in Android 11 non è più raggiungibile dall'utente con SAF - if( cart.equals(getExternalFilesDir(null) + "/" + idAlbero) ) { - vistaNome.setText( R.string.app_storage ); - bottoneElimina.setVisibility( View.GONE ); + if( dir.equals(getExternalFilesDir(null) + "/" + treeId) ) { + nameView.setText(R.string.app_storage); + deleteButton.setVisibility(View.GONE); } else { - vistaNome.setText( nomeCartella(cart) ); - bottoneElimina.setOnClickListener( v -> { - new AlertDialog.Builder(this).setMessage( R.string.sure_delete ) - .setPositiveButton( R.string.yes, (di,id) -> { - cartelle.remove( cart ); - salva(); - }).setNeutralButton( R.string.cancel, null ).show(); + nameView.setText(folderName(dir)); + deleteButton.setOnClickListener(v -> { + new AlertDialog.Builder(this).setMessage(R.string.sure_delete) + .setPositiveButton(R.string.yes, (di, id) -> { + dirs.remove(dir); + save(); + }).setNeutralButton(R.string.cancel, null).show(); }); } - registerForContextMenu( vistaCartella ); + registerForContextMenu(folderView); } - for( String stringUri : uris ) { - View vistaUri = getLayoutInflater().inflate( R.layout.pezzo_cartella, scatola, false ); - scatola.addView( vistaUri ); - DocumentFile documentDir = DocumentFile.fromTreeUri( this, Uri.parse(stringUri) ); - String nome = null; + for( String uriString : uris ) { + View uriView = getLayoutInflater().inflate(R.layout.pezzo_cartella, layout, false); + layout.addView(uriView); + DocumentFile documentDir = DocumentFile.fromTreeUri(this, Uri.parse(uriString)); + String name = null; if( documentDir != null ) - nome = documentDir.getName(); - ((TextView)vistaUri.findViewById(R.id.cartella_nome)).setText( nome ); - TextView vistaUrl = vistaUri.findViewById( R.id.cartella_url ); + name = documentDir.getName(); + ((TextView)uriView.findViewById(R.id.cartella_nome)).setText(name); + TextView urlView = uriView.findViewById(R.id.cartella_url); if( Global.settings.expert ) { - vistaUrl.setSingleLine( false ); - vistaUrl.setText( stringUri ); + urlView.setSingleLine(false); + urlView.setText(uriString); } else - vistaUrl.setText( Uri.decode(stringUri) ); // lo mostra decodificato cioè un po' più leggibile - vistaUri.findViewById( R.id.cartella_elimina ).setOnClickListener( v -> { - new AlertDialog.Builder(this).setMessage( R.string.sure_delete ) - .setPositiveButton( R.string.yes, (di,id) -> { + urlView.setText(Uri.decode(uriString)); // lo mostra decodificato cioè un po' più leggibile + uriView.findViewById(R.id.cartella_elimina).setOnClickListener(v -> { + new AlertDialog.Builder(this).setMessage(R.string.sure_delete) + .setPositiveButton(R.string.yes, (di, id) -> { // Revoca il permesso per questo uri, se l'uri non è usato in nessun altro albero boolean uriEsisteAltrove = false; for( Settings.Tree albero : Global.settings.trees ) { for( String uri : albero.uris ) - if( uri.equals(stringUri) && albero.id != idAlbero ) { + if( uri.equals(uriString) && albero.id != treeId ) { uriEsisteAltrove = true; break; } } if( !uriEsisteAltrove ) - revokeUriPermission( Uri.parse(stringUri), Intent.FLAG_GRANT_READ_URI_PERMISSION ); - uris.remove( stringUri ); - salva(); - }).setNeutralButton( R.string.cancel, null ).show(); + revokeUriPermission(Uri.parse(uriString), Intent.FLAG_GRANT_READ_URI_PERMISSION); + uris.remove(uriString); + save(); + }).setNeutralButton(R.string.cancel, null).show(); }); - registerForContextMenu( vistaUri ); + registerForContextMenu(uriView); } } - String nomeCartella( String url ) { + String folderName(String url) { if( url.lastIndexOf('/') > 0 ) - return url.substring( url.lastIndexOf('/') + 1 ); + return url.substring(url.lastIndexOf('/') + 1); return url; } - void salva() { - Global.settings.getTree(idAlbero).dirs.clear(); - for( String path : cartelle ) - Global.settings.getTree(idAlbero).dirs.add( path ); - Global.settings.getTree(idAlbero).uris.clear(); + void save() { + Global.settings.getTree(treeId).dirs.clear(); + for( String path : dirs ) + Global.settings.getTree(treeId).dirs.add(path); + Global.settings.getTree(treeId).uris.clear(); for( String uri : uris ) - Global.settings.getTree(idAlbero).uris.add( uri ); + Global.settings.getTree(treeId).uris.add(uri); Global.settings.save(); - aggiornaLista(); + updateList(); + Global.edited = true; } @Override - public boolean onOptionsItemSelected( MenuItem item ) { + public boolean onOptionsItemSelected(MenuItem item) { onBackPressed(); return true; } @@ -156,51 +156,52 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { if( resultCode == Activity.RESULT_OK ) { Uri uri = data.getData(); if( uri != null ) { - // in KitKat è stato selezionato un file e ne ricaviamo il percorso della cartella + // In KitKat a file has been selected and we get the path of the folder if( requestCode == 456 ) { - String percorso = F.uriPercorsoCartellaKitKat( this, uri ); - if( percorso != null ) { - cartelle.add( percorso ); - salva(); + String path = F.uriPercorsoCartellaKitKat(this, uri); + if( path != null ) { + dirs.add(path); + save(); } } else if( requestCode == 123 ) { - String percorso = F.uriPercorsoCartella( uri ); - if( percorso != null ) { - cartelle.add( percorso ); - salva(); + String path = F.uriPercorsoCartella(uri); + if( path != null ) { + dirs.add(path); + save(); } else { getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); - DocumentFile docDir = DocumentFile.fromTreeUri( this, uri ); + DocumentFile docDir = DocumentFile.fromTreeUri(this, uri); if( docDir != null && docDir.canRead() ) { - uris.add( uri.toString() ); - salva(); + uris.add(uri.toString()); + save(); } else - Toast.makeText( this, "Could not read this position.", Toast.LENGTH_SHORT ).show(); + Toast.makeText(this, "Could not read this position.", Toast.LENGTH_SHORT).show(); } } } else - Toast.makeText( this, R.string.something_wrong, Toast.LENGTH_SHORT ).show(); + Toast.makeText(this, R.string.something_wrong, Toast.LENGTH_SHORT).show(); } } - View vistaScelta; + View selectedView; @Override - public void onCreateContextMenu( ContextMenu menu, View vista, ContextMenu.ContextMenuInfo info ) { - vistaScelta = vista; - menu.add(0, 0, 0, R.string.copy ); + public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { + selectedView = view; + menu.add(0, 0, 0, R.string.copy); } @Override public boolean onContextItemSelected( MenuItem item ) { if( item.getItemId() == 0 ) { // Copia - U.copiaNegliAppunti( getText(android.R.string.copyUrl), ((TextView)vistaScelta.findViewById(R.id.cartella_url)).getText() ); + U.copiaNegliAppunti( getText(android.R.string.copyUrl), ((TextView)selectedView.findViewById(R.id.cartella_url)).getText() ); return true; } return false; } @Override - public void onRequestPermissionsResult( int codice, String[] permessi, int[] accordi ) { - if( accordi.length > 0 && accordi[0] == PackageManager.PERMISSION_GRANTED && codice == 3517 ) - faiScegliereCartella(); + public void onRequestPermissionsResult(int code, String[] permissions, int[] results) { + super.onRequestPermissionsResult(code, permissions, results); + if( results.length > 0 && results[0] == PackageManager.PERMISSION_GRANTED && code == 3517 ) + chooseFolder(); } } \ No newline at end of file diff --git a/app/src/main/java/app/familygem/Compara.java b/app/src/main/java/app/familygem/Compara.java index 932c7f37..c2c592d7 100644 --- a/app/src/main/java/app/familygem/Compara.java +++ b/app/src/main/java/app/familygem/Compara.java @@ -32,21 +32,21 @@ public class Compara extends BaseActivity { SimpleDateFormat changeDateFormat; @Override - protected void onCreate( Bundle bandolo ) { - super.onCreate( bandolo ); - setContentView( R.layout.compara ); - int idAlbero = getIntent().getIntExtra("idAlbero",1); // Albero vecchio - int idAlbero2 = getIntent().getIntExtra("idAlbero2",1); // Albero nuovo ricevuto in condivisione + protected void onCreate(Bundle bundle) { + super.onCreate(bundle); + setContentView(R.layout.compara); + int idAlbero = getIntent().getIntExtra("idAlbero", 1); // Albero vecchio + int idAlbero2 = getIntent().getIntExtra("idAlbero2", 1); // Albero nuovo ricevuto in condivisione Global.treeId2 = idAlbero2; // servirà alle immagini di Confrontatore e a Conferma - Global.gc = Alberi.apriGedcomTemporaneo( idAlbero, true ); - Global.gc2 = Alberi.apriGedcomTemporaneo( idAlbero2, false ); + Global.gc = TreesActivity.openTemporaryGedcom(idAlbero, true); + Global.gc2 = TreesActivity.openTemporaryGedcom(idAlbero2, false); if( Global.gc == null || Global.gc2 == null ) { - Toast.makeText( this, R.string.no_useful_data, Toast.LENGTH_LONG ).show(); + Toast.makeText(this, R.string.no_useful_data, Toast.LENGTH_LONG).show(); onBackPressed(); return; } - TimeZone.setDefault( TimeZone.getTimeZone("Europe/Rome") ); // riconduce tutte le date al fuso orario di Aruba + TimeZone.setDefault(TimeZone.getTimeZone("Europe/Rome")); // riconduce tutte le date al fuso orario di Aruba try { SimpleDateFormat formatoDataId = new SimpleDateFormat("yyyyMMddHHmmss", Locale.ENGLISH); sharingDate = formatoDataId.parse(getIntent().getStringExtra("idData")); @@ -54,44 +54,44 @@ protected void onCreate( Bundle bandolo ) { e.printStackTrace(); } - changeDateFormat = new SimpleDateFormat( "d MMM yyyyHH:mm:ss", Locale.ENGLISH ); + changeDateFormat = new SimpleDateFormat("d MMM yyyyHH:mm:ss", Locale.ENGLISH); Confronto.reset(); // Necessario svuotarlo, ad esempio dopo un cambio di configurazione // Confronta tutti i record dei due Gedcom for( Family o2 : Global.gc2.getFamilies() ) - confronta( Global.gc.getFamily(o2.getId()), o2, 7 ); + confronta(Global.gc.getFamily(o2.getId()), o2, 7); for( Family o : Global.gc.getFamilies() ) - riconfronta( o, Global.gc2.getFamily(o.getId()), 7 ); + riconfronta(o, Global.gc2.getFamily(o.getId()), 7); for( Person o2 : Global.gc2.getPeople() ) - confronta( Global.gc.getPerson(o2.getId()), o2, 6 ); + confronta(Global.gc.getPerson(o2.getId()), o2, 6); for( Person o : Global.gc.getPeople() ) - riconfronta( o, Global.gc2.getPerson(o.getId()), 6 ); + riconfronta(o, Global.gc2.getPerson(o.getId()), 6); for( Source o2 : Global.gc2.getSources() ) - confronta( Global.gc.getSource(o2.getId()), o2, 5 ); + confronta(Global.gc.getSource(o2.getId()), o2, 5); for( Source o : Global.gc.getSources() ) - riconfronta( o, Global.gc2.getSource(o.getId()), 5 ); + riconfronta(o, Global.gc2.getSource(o.getId()), 5); for( Media o2 : Global.gc2.getMedia() ) - confronta( Global.gc.getMedia(o2.getId()), o2, 4 ); + confronta(Global.gc.getMedia(o2.getId()), o2, 4); for( Media o : Global.gc.getMedia() ) - riconfronta( o, Global.gc2.getMedia(o.getId()), 4 ); + riconfronta(o, Global.gc2.getMedia(o.getId()), 4); for( Repository o2 : Global.gc2.getRepositories() ) - confronta( Global.gc.getRepository(o2.getId()), o2, 3 ); + confronta(Global.gc.getRepository(o2.getId()), o2, 3); for( Repository o : Global.gc.getRepositories() ) - riconfronta( o, Global.gc2.getRepository(o.getId()), 3 ); + riconfronta(o, Global.gc2.getRepository(o.getId()), 3); for( Submitter o2 : Global.gc2.getSubmitters() ) - confronta( Global.gc.getSubmitter(o2.getId()), o2, 2 ); + confronta(Global.gc.getSubmitter(o2.getId()), o2, 2); for( Submitter o : Global.gc.getSubmitters() ) - riconfronta( o, Global.gc2.getSubmitter(o.getId()), 2 ); + riconfronta(o, Global.gc2.getSubmitter(o.getId()), 2); for( Note o2 : Global.gc2.getNotes() ) - confronta( Global.gc.getNote(o2.getId()), o2, 1 ); + confronta(Global.gc.getNote(o2.getId()), o2, 1); for( Note o : Global.gc.getNotes() ) - riconfronta( o, Global.gc2.getNote(o.getId()), 1 ); + riconfronta(o, Global.gc2.getNote(o.getId()), 1); Settings.Tree tree2 = Global.settings.getTree(idAlbero2); if( Confronto.getLista().isEmpty() ) { @@ -129,24 +129,24 @@ protected void onCreate( Bundle bandolo ) { intent.putExtra("posizione", 1); if( Confronto.get().quanteScelte > 0 ) { // Dialogo di richiesta revisione new AlertDialog.Builder(this) - .setTitle( Confronto.get().quanteScelte == 1 ? getString(R.string.one_update_choice) - : getString(R.string.many_updates_choice, Confronto.get().quanteScelte) ) + .setTitle(Confronto.get().quanteScelte == 1 ? getString(R.string.one_update_choice) + : getString(R.string.many_updates_choice, Confronto.get().quanteScelte)) .setMessage(R.string.updates_replace_add) - .setPositiveButton( android.R.string.ok, (dialog,id) -> { + .setPositiveButton(android.R.string.ok, (dialog, id) -> { Confronto.get().autoProsegui = true; Confronto.get().scelteFatte = 1; - startActivity( intent ); - }).setNeutralButton( android.R.string.cancel, (dialog,id) -> botton2.setEnabled(true) ) - .setOnCancelListener( dialog -> botton2.setEnabled(true) ).show(); + startActivity(intent); + }).setNeutralButton(android.R.string.cancel, (dialog, id) -> botton2.setEnabled(true)) + .setOnCancelListener(dialog -> botton2.setEnabled(true)).show(); } else { // Avvio in automatico Confronto.get().autoProsegui = true; - startActivity( intent ); + startActivity(intent); } }); } else { botton1.setText(R.string.delete_imported_tree); botton1.setOnClickListener(v -> { - Alberi.deleteTree(Compara.this, idAlbero2); + TreesActivity.deleteTree(Compara.this, idAlbero2); onBackPressed(); }); botton2.setVisibility(View.GONE); @@ -228,14 +228,14 @@ void arredaScheda( Gedcom gc, int idAlbero, int idScheda ) { TextView title = carta.findViewById(R.id.confronto_titolo); TextView data = carta.findViewById(R.id.confronto_testo); title.setText(tree.title); - data.setText(Alberi.scriviDati(this, tree)); + data.setText(TreesActivity.scriviDati(this, tree)); if( idScheda == R.id.compara_nuovo ) { if( tree.grade == 30 ) { carta.setCardBackgroundColor(getResources().getColor(R.color.consumed)); - title.setTextColor(getResources().getColor(R.color.grayText)); - data.setTextColor(getResources().getColor(R.color.grayText)); + title.setTextColor(getResources().getColor(R.color.gray_text)); + data.setTextColor(getResources().getColor(R.color.gray_text)); } else - carta.setCardBackgroundColor(getResources().getColor(R.color.evidenziaMedio)); + carta.setCardBackgroundColor(getResources().getColor(R.color.accent_medium)); Submitter autore = gc.getSubmitter(tree.shares.get(tree.shares.size() - 1).submitter); String txt = ""; if( autore != null ) { diff --git a/app/src/main/java/app/familygem/Condivisione.java b/app/src/main/java/app/familygem/Condivisione.java index 46d9dbae..f8b67fb0 100644 --- a/app/src/main/java/app/familygem/Condivisione.java +++ b/app/src/main/java/app/familygem/Condivisione.java @@ -33,12 +33,13 @@ import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; +import app.familygem.constant.Choice; public class Condivisione extends BaseActivity { Gedcom gc; Settings.Tree tree; - Esportatore esporter; + Exporter exporter; String nomeAutore; int accessible; // 0 = false, 1 = true String dataId; @@ -58,10 +59,10 @@ protected void onCreate(Bundle bundle) { editaTitolo.setText(tree.title); if( tree.grade == 10 ) - ((TextView)findViewById( R.id.condividi_tit_autore )).setText( R.string.changes_submitter ); + ((TextView)findViewById(R.id.condividi_tit_autore)).setText(R.string.changes_submitter); - esporter = new Esportatore( this ); - esporter.apriAlbero( treeId ); + exporter = new Exporter(this); + exporter.openTree(treeId); gc = Global.gc; if( gc != null ) { displayShareRoot(); @@ -69,16 +70,16 @@ protected void onCreate(Bundle bundle) { final Submitter[] autore = new Submitter[1]; // albero in Italia con submitter referenziato if( tree.grade == 0 && gc.getHeader() != null && gc.getHeader().getSubmitter(gc) != null ) - autore[0] = gc.getHeader().getSubmitter( gc ); + autore[0] = gc.getHeader().getSubmitter(gc); // in Italia ci sono autori ma nessuno referenziato, prende l'ultimo else if( tree.grade == 0 && !gc.getSubmitters().isEmpty() ) - autore[0] = gc.getSubmitters().get(gc.getSubmitters().size()-1); + autore[0] = gc.getSubmitters().get(gc.getSubmitters().size() - 1); // in Australia ci sono autori freschi, ne prende uno else if( tree.grade == 10 && U.autoreFresco(gc) != null ) autore[0] = U.autoreFresco(gc); final EditText editaAutore = findViewById(R.id.condividi_autore); nomeAutore = autore[0] == null ? "" : autore[0].getName(); - editaAutore.setText( nomeAutore ); + editaAutore.setText(nomeAutore); // Display an alert for the acknowledgment of sharing if( !Global.settings.shareAgreement ) { @@ -91,7 +92,7 @@ else if( tree.grade == 10 && U.autoreFresco(gc) != null ) } // Raccoglie i dati della condivisione e posta al database - findViewById( R.id.bottone_condividi ).setOnClickListener( v -> { + findViewById(R.id.bottone_condividi).setOnClickListener(v -> { if( uploadSuccesso ) concludi(); else { @@ -111,12 +112,12 @@ else if( tree.grade == 10 && U.autoreFresco(gc) != null ) // Aggiornamento del submitter Header header = gc.getHeader(); if( header == null ) { - header = AlberoNuovo.creaTestata(tree.id + ".json"); + header = NewTreeActivity.creaTestata(tree.id + ".json"); gc.setHeader(header); } else header.setDateTime(U.actualDateTime()); if( autore[0] == null ) { - autore[0] = Podio.nuovoAutore(null); + autore[0] = Podio.createSubmitter(null); } if( header.getSubmitterRef() == null ) { header.setSubmitterRef(autore[0].getId()); @@ -164,7 +165,7 @@ else if( tree.root != null && gc.getPerson(tree.root) != null ) { rootView = U.linkaPersona(rootLayout, person, 1); rootView.setOnClickListener(v -> { Intent intent = new Intent(this, Principal.class); - intent.putExtra("anagrafeScegliParente", true); + intent.putExtra(Choice.PERSON, true); startActivityForResult(intent, 5007); }); } @@ -191,32 +192,32 @@ protected Condivisione doInBackground(Condivisione... contesti) { Condivisione questo = contesti[0]; try { URL url = new URL("https://www.familygem.app/inserisci.php"); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setRequestMethod("POST"); - OutputStream out = new BufferedOutputStream( conn.getOutputStream() ); + OutputStream out = new BufferedOutputStream(conn.getOutputStream()); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8")); - String dati = "password=" + URLEncoder.encode( BuildConfig.passwordAruba, "UTF-8") + - "&titoloAlbero=" + URLEncoder.encode( questo.tree.title, "UTF-8") + - "&nomeAutore=" + URLEncoder.encode( questo.nomeAutore, "UTF-8") + + String dati = "password=" + URLEncoder.encode(BuildConfig.passwordAruba, "UTF-8") + + "&titoloAlbero=" + URLEncoder.encode(questo.tree.title, "UTF-8") + + "&nomeAutore=" + URLEncoder.encode(questo.nomeAutore, "UTF-8") + "&accessibile=" + questo.accessible; - writer.write( dati ); + writer.write(dati); writer.flush(); writer.close(); out.close(); // Risposta - BufferedReader lettore = new BufferedReader( new InputStreamReader(conn.getInputStream()) ); + BufferedReader lettore = new BufferedReader(new InputStreamReader(conn.getInputStream())); String linea1 = lettore.readLine(); lettore.close(); conn.disconnect(); if( linea1.startsWith("20") ) { - questo.dataId = linea1.replaceAll( "[-: ]", "" ); - Settings.Share share = new Settings.Share( questo.dataId, questo.idAutore ); + questo.dataId = linea1.replaceAll("[-: ]", ""); + Settings.Share share = new Settings.Share(questo.dataId, questo.idAutore); questo.tree.aggiungiCondivisione(share); Global.settings.save(); } } catch( Exception e ) { - U.toast( questo, e.getLocalizedMessage() ); + U.toast(questo, e.getLocalizedMessage()); } return questo; } @@ -225,11 +226,11 @@ protected Condivisione doInBackground(Condivisione... contesti) { protected void onPostExecute(Condivisione questo) { if( questo.dataId != null && questo.dataId.startsWith("20") ) { File fileTree = new File( questo.getCacheDir(), questo.dataId + ".zip" ); - if( questo.esporter.esportaBackupZip(questo.tree.shareRoot, 9, Uri.fromFile(fileTree)) ) { + if( questo.exporter.exportZipBackup(questo.tree.shareRoot, 9, Uri.fromFile(fileTree)) ) { new InvioFTP().execute( questo ); return; } else - Toast.makeText( questo, questo.esporter.messaggioErrore, Toast.LENGTH_LONG ).show(); + Toast.makeText( questo, questo.exporter.errorMessage, Toast.LENGTH_LONG ).show(); } // Un Toast di errore qui sostituirebbe il messaggio di tosta() in catch() questo.findViewById( R.id.bottone_condividi ).setEnabled(true); @@ -243,41 +244,41 @@ protected Condivisione doInBackground(Condivisione... contesti) { Condivisione questo = contesti[0]; try { FTPClient ftpClient = new FTPClient(); - ftpClient.connect( "89.46.104.211", 21 ); + ftpClient.connect("89.46.104.211", 21); ftpClient.enterLocalPassiveMode(); - ftpClient.login( BuildConfig.utenteAruba, BuildConfig.passwordAruba ); + ftpClient.login(BuildConfig.utenteAruba, BuildConfig.passwordAruba); ftpClient.changeWorkingDirectory("/www.familygem.app/condivisi"); - ftpClient.setFileType( FTP.BINARY_FILE_TYPE ); + ftpClient.setFileType(FTP.BINARY_FILE_TYPE); BufferedInputStream buffIn; String nomeZip = questo.dataId + ".zip"; - buffIn = new BufferedInputStream( new FileInputStream( questo.getCacheDir() + "/" + nomeZip ) ); - questo.uploadSuccesso = ftpClient.storeFile( nomeZip, buffIn ); + buffIn = new BufferedInputStream(new FileInputStream(questo.getCacheDir() + "/" + nomeZip)); + questo.uploadSuccesso = ftpClient.storeFile(nomeZip, buffIn); buffIn.close(); ftpClient.logout(); ftpClient.disconnect(); } catch( Exception e ) { - U.toast( questo, e.getLocalizedMessage() ); + U.toast(questo, e.getLocalizedMessage()); } return questo; } protected void onPostExecute(Condivisione questo) { if( questo.uploadSuccesso ) { - Toast.makeText( questo, R.string.correctly_uploaded, Toast.LENGTH_SHORT ).show(); + Toast.makeText(questo, R.string.correctly_uploaded, Toast.LENGTH_SHORT).show(); questo.concludi(); } else { - questo.findViewById( R.id.bottone_condividi ).setEnabled(true); - questo.findViewById( R.id.condividi_circolo ).setVisibility( View.INVISIBLE ); + questo.findViewById(R.id.bottone_condividi).setEnabled(true); + questo.findViewById(R.id.condividi_circolo).setVisibility(View.INVISIBLE); } } } // Mostra le app per condividere il link void concludi() { - Intent intento = new Intent( Intent.ACTION_SEND ); - intento.setType( "text/plain" ); - intento.putExtra( Intent.EXTRA_SUBJECT, getString( R.string.sharing_tree ) ); - intento.putExtra( Intent.EXTRA_TEXT, getString( R.string.click_this_link, - "https://www.familygem.app/share.php?tree=" + dataId ) ); + Intent intento = new Intent(Intent.ACTION_SEND); + intento.setType("text/plain"); + intento.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.sharing_tree)); + intento.putExtra(Intent.EXTRA_TEXT, getString(R.string.click_this_link, + "https://www.familygem.app/share.php?tree=" + dataId)); //startActivity( Intent.createChooser( intento, "Condividi con" ) ); /* Tornando indietro da una app di messaggistica il requestCode 35417 arriva sempre corretto Invece il resultCode può essere RESULT_OK o RESULT_CANCELED a capocchia @@ -285,9 +286,9 @@ void concludi() { anche inviando un Sms ritorna RESULT_CANCELED anche se l'sms è stato inviato oppure da Whatsapp è RESULT_OK sia che il messaggio è stato inviato o no In pratica non c'è modo di sapere se nella app di messaggistica il messaggio è stato inviato */ - startActivityForResult( Intent.createChooser(intento,getText(R.string.share_with)),35417 ); - findViewById( R.id.bottone_condividi ).setEnabled(true); - findViewById( R.id.condividi_circolo ).setVisibility( View.INVISIBLE ); + startActivityForResult(Intent.createChooser(intento, getText(R.string.share_with)), 35417); + findViewById(R.id.bottone_condividi).setEnabled(true); + findViewById(R.id.condividi_circolo).setVisibility(View.INVISIBLE); } // Aggiorna le preferenze così da mostrare la nuova radice scelta in Anagrafe @@ -309,7 +310,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { } @Override - public boolean onOptionsItemSelected( MenuItem i ) { + public boolean onOptionsItemSelected(MenuItem i) { onBackPressed(); return true; } diff --git a/app/src/main/java/app/familygem/Conferma.java b/app/src/main/java/app/familygem/Conferma.java index 04bac512..f02d6365 100644 --- a/app/src/main/java/app/familygem/Conferma.java +++ b/app/src/main/java/app/familygem/Conferma.java @@ -41,7 +41,7 @@ protected void onCreate( Bundle bandolo ) { CardView carta = findViewById( R.id.conferma_vecchio ); Settings.Tree tree = Global.settings.getTree( Global.settings.openTree); ((TextView)carta.findViewById(R.id.confronto_titolo )).setText( tree.title); - String txt = Alberi.scriviDati( this, tree); + String txt = TreesActivity.scriviDati( this, tree); ((TextView)carta.findViewById(R.id.confronto_testo )).setText( txt ); carta.findViewById( R.id.confronto_data ).setVisibility( View.GONE ); @@ -62,7 +62,7 @@ protected void onCreate( Bundle bandolo ) { findViewById(R.id.conferma_annulla ).setOnClickListener( v -> { Confronto.reset(); - startActivity( new Intent( Conferma.this, Alberi.class ) ); + startActivity( new Intent( Conferma.this, TreesActivity.class ) ); }); findViewById(R.id.conferma_ok ).setOnClickListener( v -> { @@ -212,7 +212,7 @@ protected void onCreate( Bundle bandolo ) { new AlertDialog.Builder( Conferma.this ) .setMessage( R.string.all_imported_delete ) .setPositiveButton( android.R.string.ok, (d, i) -> { - Alberi.deleteTree( this, Global.treeId2); + TreesActivity.deleteTree( this, Global.treeId2); concludi(); }).setNegativeButton( R.string.no, (d, i) -> concludi() ) .setOnCancelListener( dialog -> concludi() ).show(); @@ -225,7 +225,7 @@ protected void onCreate( Bundle bandolo ) { // Apre l'elenco degli alberi void concludi() { Confronto.reset(); - startActivity( new Intent( this, Alberi.class ) ); + startActivity( new Intent( this, TreesActivity.class ) ); } // Calcola l'id più alto per una certa classe confrontando albero nuovo e vecchio diff --git a/app/src/main/java/app/familygem/Confrontatore.java b/app/src/main/java/app/familygem/Confrontatore.java index 908e7a36..92f9b65a 100644 --- a/app/src/main/java/app/familygem/Confrontatore.java +++ b/app/src/main/java/app/familygem/Confrontatore.java @@ -109,81 +109,81 @@ protected void onCreate( Bundle bandolo ) { onBackPressed(); // Ritorna a Compara } - void arredaScheda( Gedcom gc, int idScheda, Object o ) { + void arredaScheda(Gedcom gc, int idScheda, Object o) { String tit = ""; String txt = ""; String data = ""; CardView carta = findViewById(idScheda); - ImageView vistaFoto = carta.findViewById( R.id.confronto_foto ); + ImageView vistaFoto = carta.findViewById(R.id.confronto_foto); if( o instanceof Note ) { - tipoRecord( R.string.shared_note ); - Note n = (Note) o; + tipoRecord(R.string.shared_note); + Note n = (Note)o; txt = n.getValue(); - data = dataOra( n.getChange() ); + data = dataOra(n.getChange()); } else if( o instanceof Submitter ) { - tipoRecord( R.string.submitter ); - Submitter s = (Submitter) o; + tipoRecord(R.string.submitter); + Submitter s = (Submitter)o; tit = s.getName(); if( s.getEmail() != null ) txt += s.getEmail() + "\n"; if( s.getAddress() != null ) txt += Dettaglio.writeAddress(s.getAddress(), true); data = dataOra(s.getChange()); } else if( o instanceof Repository ) { - tipoRecord( R.string.repository ); - Repository r = (Repository) o; + tipoRecord(R.string.repository); + Repository r = (Repository)o; tit = r.getName(); if( r.getAddress() != null ) txt += Dettaglio.writeAddress(r.getAddress(), true) + "\n"; if( r.getEmail() != null ) txt += r.getEmail(); data = dataOra(r.getChange()); } else if( o instanceof Media ) { - tipoRecord( R.string.shared_media ); - Media m = (Media) o; - if(m.getTitle()!=null) tit = m.getTitle(); + tipoRecord(R.string.shared_media); + Media m = (Media)o; + if( m.getTitle() != null ) tit = m.getTitle(); txt = m.getFile(); - data = dataOra( m.getChange() ); - vistaFoto.setVisibility( View.VISIBLE ); - F.dipingiMedia( m, vistaFoto, null ); + data = dataOra(m.getChange()); + vistaFoto.setVisibility(View.VISIBLE); + F.paintMedia(m, vistaFoto, null); } else if( o instanceof Source ) { - tipoRecord( R.string.source ); - Source f = (Source) o; - if(f.getTitle()!=null) tit = f.getTitle(); - else if(f.getAbbreviation()!=null) tit = f.getAbbreviation(); - if(f.getAuthor()!=null) txt = f.getAuthor()+"\n"; - if(f.getPublicationFacts()!=null) txt += f.getPublicationFacts()+"\n"; - if(f.getText()!=null) txt += f.getText(); - data = dataOra( f.getChange() ); + tipoRecord(R.string.source); + Source s = (Source)o; + if( s.getTitle() != null ) tit = s.getTitle(); + else if( s.getAbbreviation() != null ) tit = s.getAbbreviation(); + if( s.getAuthor() != null ) txt = s.getAuthor() + "\n"; + if( s.getPublicationFacts() != null ) txt += s.getPublicationFacts() + "\n"; + if( s.getText() != null ) txt += s.getText(); + data = dataOra(s.getChange()); } else if( o instanceof Person ) { - tipoRecord( R.string.person ); - Person p = (Person) o; - tit = U.epiteto( p ); - txt = U.details( p, null ); - data = dataOra( p.getChange() ); - vistaFoto.setVisibility( View.VISIBLE ); - F.unaFoto( gc, p, vistaFoto ); + tipoRecord(R.string.person); + Person p = (Person)o; + tit = U.epiteto(p); + txt = U.details(p, null); + data = dataOra(p.getChange()); + vistaFoto.setVisibility(View.VISIBLE); + F.oneImage(gc, p, vistaFoto); } else if( o instanceof Family ) { - tipoRecord( R.string.family ); - Family f = (Family) o; - txt = U.testoFamiglia( this, gc, f, false ); - data = dataOra( f.getChange() ); + tipoRecord(R.string.family); + Family f = (Family)o; + txt = U.testoFamiglia(this, gc, f, false); + data = dataOra(f.getChange()); } - TextView testoTitolo = carta.findViewById( R.id.confronto_titolo ); + TextView testoTitolo = carta.findViewById(R.id.confronto_titolo); if( tit == null || tit.isEmpty() ) - testoTitolo.setVisibility( View.GONE ); + testoTitolo.setVisibility(View.GONE); else - testoTitolo.setText( tit ); + testoTitolo.setText(tit); - TextView testoTesto = carta.findViewById( R.id.confronto_testo ); + TextView testoTesto = carta.findViewById(R.id.confronto_testo); if( txt.isEmpty() ) - testoTesto.setVisibility( View.GONE ); + testoTesto.setVisibility(View.GONE); else { - if( txt.endsWith( "\n" ) ) - txt = txt.substring( 0, txt.length() - 1 ); - testoTesto.setText( txt ); + if( txt.endsWith("\n") ) + txt = txt.substring(0, txt.length() - 1); + testoTesto.setText(txt); } View vistaCambi = carta.findViewById(R.id.confronto_data); @@ -193,20 +193,20 @@ else if( o instanceof Family ) { ((TextView)vistaCambi.findViewById(R.id.cambi_testo)).setText(data); if( idScheda == R.id.confronto_nuovo ) { - carta.setCardBackgroundColor(getResources().getColor(R.color.evidenziaMedio)); + carta.setCardBackgroundColor(getResources().getColor(R.color.accent_medium)); } if( tit.isEmpty() && txt.isEmpty() && data.isEmpty() ) // todo intendi oggetto null? - carta.setVisibility( View.GONE ); + carta.setVisibility(View.GONE); } // Titolo della pagina - void tipoRecord( int string ) { - TextView testoTipo = findViewById( R.id.confronto_tipo ); - testoTipo.setText( getString(string) ); + void tipoRecord(int string) { + TextView testoTipo = findViewById(R.id.confronto_tipo); + testoTipo.setText(getString(string)); } - String dataOra( Change cambi ) { + String dataOra(Change cambi) { String dataOra = ""; if( cambi != null ) dataOra = cambi.getDateTime().getValue() + " - " + cambi.getDateTime().getTime(); @@ -215,13 +215,13 @@ String dataOra( Change cambi ) { void vaiAvanti() { Intent intent = new Intent(); - if( getIntent().getIntExtra("posizione",0) == Confronto.getLista().size() ) { + if( getIntent().getIntExtra("posizione", 0) == Confronto.getLista().size() ) { // Terminati i confronti - intent.setClass( this, Conferma.class ); + intent.setClass(this, Conferma.class); } else { // Prossimo confronto - intent.setClass( this, Confrontatore.class ); - intent.putExtra( "posizione", getIntent().getIntExtra("posizione",0) + 1 ); + intent.setClass(this, Confrontatore.class); + intent.putExtra("posizione", getIntent().getIntExtra("posizione", 0) + 1); } if( Confronto.get().autoProsegui ) { if( Confronto.getFronte(this).doppiaOpzione ) @@ -229,11 +229,11 @@ void vaiAvanti() { else finish(); // rimuove il fronte attuale dallo stack } - startActivity( intent ); + startActivity(intent); } @Override - public boolean onOptionsItemSelected( MenuItem i ) { + public boolean onOptionsItemSelected(MenuItem i) { onBackPressed(); return true; } diff --git a/app/src/main/java/app/familygem/Datatore.java b/app/src/main/java/app/familygem/Datatore.java index 0bdfa6b1..264cd55c 100644 --- a/app/src/main/java/app/familygem/Datatore.java +++ b/app/src/main/java/app/familygem/Datatore.java @@ -11,9 +11,9 @@ import app.familygem.constant.Format; import app.familygem.constant.Kind; -class Datatore { +public class Datatore { - Data data1; + public Data data1; Data data2; String frase; // Quella che andrà tra parentesi Kind kind; @@ -21,22 +21,22 @@ class Datatore { static final String[] suffissi = { "B.C.", "BC", "BCE" }; // With a string date in GEDCOM style - Datatore(String gedcomDate) { + public Datatore(String gedcomDate) { data1 = new Data(); data2 = new Data(); analizza(gedcomDate); } // With one single complete Date - Datatore(Date date) { + public Datatore(Date date) { data1 = new Data(); data1.date = date; data1.format.applyPattern(Format.D_M_Y); kind = Kind.EXACT; } - class Data { - Date date; + public class Data { + public Date date; SimpleDateFormat format; boolean negativa; boolean doppia; @@ -66,8 +66,8 @@ void scanna( String dataGc ) { doppia = false; // reset if( dataGc.indexOf('/') > 0 ) { String[] tata = dataGc.split("[/ ]"); - if( tata.length > 1 && tata[tata.length-2].length() < 3 && U.soloNumeri( tata[tata.length-2] ) <= 12 ) - dataGc = dataGc.replace( '/', ' ' ); + if( tata.length > 1 && tata[tata.length - 2].length() < 3 && U.getNumberOnly(tata[tata.length - 2]) <= 12 ) + dataGc = dataGc.replace('/', ' '); else doppia = true; } @@ -103,7 +103,7 @@ void cambiaEra() { } } - boolean isFormat(String format) { + public boolean isFormat(String format) { return this.format.toPattern().equals(format); } @@ -115,7 +115,7 @@ public String toString() { } // Riconosce il tipo di data e crea la classe Data - void analizza(String dataGc) { + public void analizza(String dataGc) { // Reset the important values kind = null; @@ -278,7 +278,7 @@ public int getDateNumber() { } // Kinds of date that represent a single event in time - boolean isSingleKind() { + public boolean isSingleKind() { return kind == Kind.EXACT || kind == Kind.APPROXIMATE || kind == Kind.CALCULATED || kind == Kind.ESTIMATED; } } diff --git a/app/src/main/java/app/familygem/Dettaglio.java b/app/src/main/java/app/familygem/Dettaglio.java index 773d5f9c..752f1f20 100644 --- a/app/src/main/java/app/familygem/Dettaglio.java +++ b/app/src/main/java/app/familygem/Dettaglio.java @@ -56,6 +56,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import app.familygem.constant.Choice; import app.familygem.detail.CitazioneFonte; import app.familygem.detail.Estensione; import app.familygem.detail.Evento; @@ -63,6 +64,11 @@ import app.familygem.detail.Immagine; import app.familygem.detail.Indirizzo; import app.familygem.detail.Nota; +import app.familygem.list.FamiliesFragment; +import app.familygem.list.GalleryFragment; +import app.familygem.list.NotesFragment; +import app.familygem.list.RepositoriesFragment; +import app.familygem.list.SourcesFragment; import app.familygem.visitor.TrovaPila; import static app.familygem.Global.gc; @@ -87,7 +93,7 @@ protected void onCreate(Bundle bundle) { actionBar = getSupportActionBar(); U.gedcomSicuro(gc); - object = Memoria.getOggetto(); + object = Memory.getOggetto(); if( object == null ) { onBackPressed(); // salta tutti gli altri dettagli senza oggetto } else @@ -108,7 +114,7 @@ protected void onCreate(Bundle bundle) { FloatingActionButton fab = findViewById(R.id.fab); fab.setOnClickListener(view -> { - PopupMenu popup = menuFAB(view); + PopupMenu popup = fabMenu(view); popup.show(); popup.setOnMenuItemClickListener(item -> { // FAB + mette un nuovo uovo e lo rende subito editabile @@ -143,45 +149,45 @@ else if( object instanceof Repository ) edit(pezzo); // todo : aprire Address nuovo per editarlo } else if( id == 101 ) { - Magazzino.newRepository(this, (Source)object); + RepositoriesFragment.newRepository(this, (Source)object); } else if( id == 102 ) { Intent intento = new Intent(this, Principal.class); - intento.putExtra("magazzinoScegliArchivio", true); + intento.putExtra(Choice.REPOSITORY, true); startActivityForResult(intento, 4562); } else if( id == 103 ) { // Nuova nota Note note = new Note(); note.setValue(""); ((NoteContainer)object).addNote(note); - Memoria.aggiungi(note); + Memory.aggiungi(note); startActivity(new Intent(this, Nota.class)); toBeSaved = true; } else if( id == 104 ) { // Nuova nota condivisa - Quaderno.newNote(this, object); + NotesFragment.newNote(this, object); } else if( id == 105 ) { // Collega nota condivisa Intent intento = new Intent(this, Principal.class); - intento.putExtra("quadernoScegliNota", true); + intento.putExtra(Choice.NOTE, true); startActivityForResult(intento, 7074); } else if( id == 106 ) { // Cerca media locale - F.appAcquisizioneImmagine(this, null, 4173, (MediaContainer)object); + F.mediaAppList(this, null, 4173, (MediaContainer)object); } else if( id == 107 ) { // Cerca media condiviso - F.appAcquisizioneImmagine(this, null, 4174, (MediaContainer)object); + F.mediaAppList(this, null, 4174, (MediaContainer)object); } else if( id == 108 ) { // Collega media condiviso Intent inten = new Intent(this, Principal.class); - inten.putExtra("galleriaScegliMedia", true); + inten.putExtra(Choice.MEDIA, true); startActivityForResult(inten, 43616); } else if( id == 109 ) { // Nuova fonte-nota SourceCitation citaz = new SourceCitation(); citaz.setValue(""); if( object instanceof Note ) ((Note)object).addSourceCitation(citaz); else ((SourceCitationContainer)object).addSourceCitation(citaz); - Memoria.aggiungi(citaz); + Memory.aggiungi(citaz); startActivity(new Intent(this, CitazioneFonte.class)); toBeSaved = true; } else if( id == 110 ) { // Nuova fonte - Biblioteca.nuovaFonte(this, object); + SourcesFragment.createNewSource(this, object); } else if( id == 111 ) { // Collega fonte Intent intent = new Intent(this, Principal.class); - intent.putExtra("bibliotecaScegliFonte", true); + intent.putExtra(Choice.SOURCE, true); startActivityForResult(intent, 5065); } else if( id == 120 || id == 121 ) { // Crea nuovo familiare Intent intent = new Intent(this, EditaIndividuo.class); @@ -191,7 +197,7 @@ else if( object instanceof Repository ) startActivity(intent); } else if( id == 122 || id == 123 ) { // Collega persona esistente Intent intent = new Intent(this, Principal.class); - intent.putExtra("anagrafeScegliParente", true); + intent.putExtra(Choice.PERSON, true); intent.putExtra("relazione", id - 117); startActivityForResult(intent, 34417); } else if( id == 124 ) { // Metti matrimonio @@ -201,7 +207,7 @@ else if( object instanceof Repository ) marriage.setPlace(""); marriage.setType(""); ((Family)object).addEventFact(marriage); - Memoria.aggiungi(marriage); + Memory.aggiungi(marriage); startActivity(new Intent(this, Evento.class)); toBeSaved = true; } else if( id == 125 ) { // Metti divorzio @@ -209,7 +215,7 @@ else if( object instanceof Repository ) divorce.setTag("DIV"); divorce.setDate(""); ((Family)object).addEventFact(divorce); - Memoria.aggiungi(divorce); + Memory.aggiungi(divorce); startActivity(new Intent(this, Evento.class)); toBeSaved = true; } else if( id >= 200 ) { // Metti altro evento @@ -225,13 +231,14 @@ else if( object instanceof Repository ) }); }); // Prova del menu: se è vuoto nasconde il fab - if( !menuFAB(null).getMenu().hasVisibleItems() ) // todo ok? + // Todo If the FAB is hidden, deleting one piece the FAB should reappear + if( !fabMenu(null).getMenu().hasVisibleItems() ) fab.hide(); } // Menu del FAB: solo coi metodi che non sono già presenti in box - PopupMenu menuFAB(View vista) { - PopupMenu popup = new PopupMenu(this, vista); + PopupMenu fabMenu(View fabView) { + PopupMenu popup = new PopupMenu(this, fabView); Menu menu = popup.getMenu(); String[] conIndirizzo = {"Www", "Email", "Phone", "Fax"}; // questi oggetti compaiono nel FAB di Evento se esiste un Indirizzo int u = 0; @@ -318,58 +325,58 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if( resultCode == RESULT_OK ) { // Dal submenu 'Collega...' in FAB - if( requestCode == 34417 ) { // Familiare scelto in Anagrafe + if( requestCode == 34417 ) { // Relative chosen from Anagrafe Person aggiungendo = gc.getPerson(data.getStringExtra("idParente")); Famiglia.aggrega(aggiungendo, (Family)object, data.getIntExtra("relazione", 0)); - U.save(true, Memoria.oggettoCapo()); + U.save(true, Memory.oggettoCapo()); return; - } else if( requestCode == 5065 ) { // Fonte scelta in Biblioteca + } else if( requestCode == 5065 ) { // Source selected in SourcesFragment SourceCitation citaFonte = new SourceCitation(); - citaFonte.setRef(data.getStringExtra("idFonte")); + citaFonte.setRef(data.getStringExtra("sourceId")); if( object instanceof Note ) ((Note)object).addSourceCitation(citaFonte); else ((SourceCitationContainer)object).addSourceCitation(citaFonte); } else if( requestCode == 7074 ) { // Nota condivisa NoteRef rifNota = new NoteRef(); - rifNota.setRef(data.getStringExtra("idNota")); + rifNota.setRef(data.getStringExtra("noteId")); ((NoteContainer)object).addNoteRef(rifNota); } else if( requestCode == 4173 ) { // File preso dal file manager o altra app diventa media locale Media media = new Media(); media.setFileTag("FILE"); ((MediaContainer)object).addMedia(media); if( F.proponiRitaglio(this, null, data, media) ) { - U.save(false, Memoria.oggettoCapo()); + U.save(false, Memory.oggettoCapo()); return; } } else if( requestCode == 4174 ) { // File preso dal file manager diventa media condiviso - Media media = Galleria.nuovoMedia(object); + Media media = GalleryFragment.nuovoMedia(object); if( F.proponiRitaglio(this, null, data, media) ) { - U.save(false, media, Memoria.oggettoCapo()); + U.save(false, media, Memory.oggettoCapo()); return; } - } else if( requestCode == 43616 ) { // Media da Galleria + } else if( requestCode == 43616 ) { // Media from GalleryFragment MediaRef rifMedia = new MediaRef(); - rifMedia.setRef(data.getStringExtra("idMedia")); + rifMedia.setRef(data.getStringExtra("mediaId")); ((MediaContainer)object).addMediaRef(rifMedia); - } else if( requestCode == 4562 ) { // Archivio scelto in Magazzino da Fonte + } else if( requestCode == 4562 ) { // Archivio scelto in RepositoriesFragment da Fonte RepositoryRef archRef = new RepositoryRef(); - archRef.setRef(data.getStringExtra("idArchivio")); + archRef.setRef(data.getStringExtra("repoId")); ((Source)object).setRepositoryRef(archRef); } else if( requestCode == 5173 ) { // Salva in Media un file scelto con le app da Immagine if( F.proponiRitaglio(this, null, data, (Media)object) ) { - U.save(false, Memoria.oggettoCapo()); + U.save(false, Memory.oggettoCapo()); return; } } else if( requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE ) { F.fineRitaglioImmagine(data); } // da menu contestuale 'Scegli...' - if( requestCode == 5390 ) { // Imposta l'archivio che è stato scelto in Magazzino da ArchivioRef - ((RepositoryRef)object).setRef(data.getStringExtra("idArchivio")); - } else if( requestCode == 7047 ) { // Imposta la fonte che è stata scelta in Biblioteca da CitazioneFonte - ((SourceCitation)object).setRef(data.getStringExtra("idFonte")); + if( requestCode == 5390 ) { // Imposta l'archivio che è stato scelto in RepositoriesFragment da ArchivioRef + ((RepositoryRef)object).setRef(data.getStringExtra("repoId")); + } else if( requestCode == 7047 ) { // Set the source that has been chosen in SourcesFragment by CitazioneFonte + ((SourceCitation)object).setRef(data.getStringExtra("sourceId")); } - U.save(true, Memoria.oggettoCapo()); - // 'true' indica di ricaricare sia questo Dettaglio grazie al seguente onRestart(), sia Individuo o Famiglia + U.save(true, Memory.oggettoCapo()); + // 'true' indica di ricaricare sia questo Dettaglio grazie al seguente onRestart(), sia ProfileActivity o Famiglia } else if( requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE ) Global.edited = true; } @@ -401,14 +408,14 @@ public void placeSlug(String tag, String id) { FlexboxLayout slugLayout = findViewById(R.id.dettaglio_bava); if( Global.settings.expert ) { slugLayout.removeAllViews(); - for( final Memoria.Passo step : Memoria.getPila() ) { + for( final Memory.Passo step : Memory.getPila() ) { View stepView = LayoutInflater.from(this).inflate(R.layout.pezzo_bava, box, false); TextView stepText = stepView.findViewById(R.id.bava_goccia); - if( Memoria.getPila().indexOf(step) < Memoria.getPila().size() - 1 ) { + if( Memory.getPila().indexOf(step) < Memory.getPila().size() - 1 ) { if( step.oggetto instanceof Visitable ) // le estensioni GedcomTag non sono Visitable ed è impossibile trovargli la pila stepView.setOnClickListener(v -> { new TrovaPila(gc, step.oggetto); - startActivity(new Intent(this, Memoria.classi.get(step.oggetto.getClass()))); + startActivity(new Intent(this, Memory.classes.get(step.oggetto.getClass()))); }); } else { step.tag = tag; @@ -533,16 +540,16 @@ public View placePiece(String title, String text, Object object, boolean multiLi // Se si tratta di una data if( object.equals("Date") ) { editoreData = pieceView.findViewById(R.id.fatto_data); - editoreData.inizia(editText); + editoreData.initialize(editText); } } else if( object instanceof Address ) { // Indirizzo click = v -> { - Memoria.aggiungi(object); + Memory.aggiungi(object); startActivity(new Intent(this, Indirizzo.class)); }; } else if( object instanceof EventFact ) { // Evento click = v -> { - Memoria.aggiungi(object); + Memory.aggiungi(object); startActivity(new Intent(this, Evento.class)); }; // Gli EventFact della famiglia possono avere delle note e dei media @@ -551,7 +558,7 @@ public View placePiece(String title, String text, Object object, boolean multiLi U.placeMedia(scatolaNote, object, false); } else if( object instanceof GedcomTag ) { // Estensione click = v -> { - Memoria.aggiungi(object); + Memory.aggiungi(object); startActivity(new Intent(this, Estensione.class)); }; } @@ -753,8 +760,8 @@ void save(View pieceView) { } ((TextView)pieceView.findViewById(R.id.fatto_testo)).setText(text); restore(pieceView); - U.save(true, Memoria.oggettoCapo()); - /*if( Memoria.getPila().size() == 1 ) { + U.save(true, Memory.oggettoCapo()); + /*if( Memory.getPila().size() == 1 ) { ricrea(); // Todo Bisognerebbe aggiornare la data Cambiamento del record, però magari senza ricaricare tutto. }*/ // In immagine modificato il percorso aggiorna l'immagine @@ -791,13 +798,13 @@ public boolean onCreateOptionsMenu( Menu menu ) { gc.getHeader().getSubmitter(gc) == null || !gc.getHeader().getSubmitter(gc).equals(object)) ) menu.add(0, 1, 0, R.string.make_default); if( object instanceof Media ) { - if( box.findViewById(R.id.immagine_foto).getTag(R.id.tag_tipo_file).equals(1) ) + if( box.findViewById(R.id.immagine_foto).getTag(R.id.tag_file_type).equals(1) ) menu.add(0, 2, 0, R.string.crop); menu.add(0, 3, 0, R.string.choose_file); } if( object instanceof Family ) menu.add(0, 4, 0, R.string.delete); - else if( !(object instanceof Submitter && U.autoreHaCondiviso((Submitter)object)) ) // autore che ha condiviso non può essere eliminato + else if( !(object instanceof Submitter && U.submitterHasShared((Submitter)object)) ) // autore che ha condiviso non può essere eliminato menu.add(0, 5, 0, R.string.delete); } return true; @@ -806,21 +813,21 @@ else if( !(object instanceof Submitter && U.autoreHaCondiviso((Submitter)object) public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if( id == 1 ) { // Autore principale - Podio.autorePrincipale((Submitter)object); + Podio.setMainSubmitter((Submitter)object); } else if( id == 2 ) { // Immagine: ritaglia croppaImmagine(box); } else if( id == 3 ) { // Immagine: scegli - F.appAcquisizioneImmagine(this, null, 5173, null); + F.mediaAppList(this, null, 5173, null); } else if( id == 4 ) { // Famiglia Family fam = (Family)object; if( fam.getHusbandRefs().size() + fam.getWifeRefs().size() + fam.getChildRefs().size() > 0 ) { new AlertDialog.Builder(this).setMessage(R.string.really_delete_family) .setPositiveButton(android.R.string.yes, (dialog, i) -> { - Chiesa.deleteFamily(fam); + FamiliesFragment.deleteFamily(fam); onBackPressed(); }).setNeutralButton(android.R.string.cancel, null).show(); } else { - Chiesa.deleteFamily(fam); + FamiliesFragment.deleteFamily(fam); onBackPressed(); } } else if( id == 5 ) { // Tutti gli altri @@ -839,7 +846,7 @@ public void onBackPressed() { super.onBackPressed(); if( object instanceof EventFact ) Evento.ripulisciTag((EventFact)object); - Memoria.arretra(); + Memory.arretra(); } public void elimina() {} @@ -917,7 +924,7 @@ public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.Context } else if( pieceObject instanceof Integer ) { if( pieceObject.equals(43614) ) { // Immaginona // è un'immagine ritagliabile - if( pieceView.findViewById(R.id.immagine_foto).getTag(R.id.tag_tipo_file).equals(1) ) + if( pieceView.findViewById(R.id.immagine_foto).getTag(R.id.tag_file_type).equals(1) ) menu.add(0, 100, 0, R.string.crop); menu.add(0, 101, 0, R.string.choose_file); } else if( pieceObject.equals(4043) || pieceObject.equals(6064) ) // Nome e cognome per inesperti @@ -953,8 +960,8 @@ public boolean onContextItemSelected( MenuItem item ) { U.qualiGenitoriMostrare(this, person, 1); return true; case 11: // Scheda persona - Memoria.setPrimo(person); - startActivity(new Intent(this, Individuo.class)); + Memory.setPrimo(person); + startActivity(new Intent(this, ProfileActivity.class)); return true; case 12: // Famiglia come figlio U.qualiGenitoriMostrare(this, person, 2); @@ -997,7 +1004,7 @@ public boolean onContextItemSelected( MenuItem item ) { }).setNeutralButton(R.string.cancel, null).show(); return true; case 20: // Nota - U.copiaNegliAppunti(getText(R.string.note), ((TextView)pieceView.findViewById(R.id.nota_testo)).getText()); + U.copiaNegliAppunti(getText(R.string.note), ((TextView)pieceView.findViewById(R.id.note_text)).getText()); return true; case 21: U.scollegaNota((Note)pieceObject, object, null); @@ -1016,13 +1023,13 @@ public boolean onContextItemSelected( MenuItem item ) { ((Note)object).getSourceCitations().remove(pieceObject); else ((SourceCitationContainer)object).getSourceCitations().remove(pieceObject); - Memoria.annullaIstanze(pieceObject); + Memory.annullaIstanze(pieceObject); break; case 40: // Media - Galleria.scollegaMedia(((Media)pieceObject).getId(), (MediaContainer)object); + GalleryFragment.scollegaMedia(((Media)pieceObject).getId(), (MediaContainer)object); break; case 41: - Object[] capiMedia = Galleria.eliminaMedia((Media)pieceObject, null); + Object[] capiMedia = GalleryFragment.eliminaMedia((Media)pieceObject, null); U.save(true, capiMedia); // un media condiviso può dover aggiornare le date di più capi refresh(); return true; @@ -1039,18 +1046,18 @@ public boolean onContextItemSelected( MenuItem item ) { break; case 58: ((Family)object).getEventsFacts().remove(pieceObject); - Memoria.annullaIstanze(pieceObject); + Memory.annullaIstanze(pieceObject); break; case 61: // Estensione U.eliminaEstensione((GedcomTag)pieceObject, object, null); break; // Fonte - case 70: // Copia + case 70: // Copy text U.copiaNegliAppunti(getText(R.string.source), ((TextView)pieceView.findViewById(R.id.fonte_testo)).getText()); return true; - case 71: // Scegli in Biblioteca + case 71: // Chose in SourcesFragment Intent inte = new Intent(this, Principal.class); - inte.putExtra("bibliotecaScegliFonte", true); + inte.putExtra(Choice.SOURCE, true); startActivityForResult(inte, 7047); return true; // Citazione archivio @@ -1061,22 +1068,22 @@ public boolean onContextItemSelected( MenuItem item ) { return true; case 81: // Elimina ((Source)object).setRepositoryRef(null); - Memoria.annullaIstanze(pieceObject); + Memory.annullaIstanze(pieceObject); break; // Archivio case 90: // Copia U.copiaNegliAppunti(getText(R.string.repository), ((TextView)pieceView.findViewById(R.id.fonte_testo)).getText()); return true; - case 91: // Scegli in Magazzino + case 91: // Scegli in RepositoriesFragment Intent intn = new Intent(this, Principal.class); - intn.putExtra("magazzinoScegliArchivio", true); + intn.putExtra(Choice.REPOSITORY, true); startActivityForResult(intn, 5390); return true; case 100: // Immaginona ritaglia croppaImmagine(pieceView); return true; case 101: // scegli immagine - F.appAcquisizioneImmagine(this, null, 5173, null); + F.mediaAppList(this, null, 5173, null); return true; default: return false; @@ -1084,7 +1091,7 @@ public boolean onContextItemSelected( MenuItem item ) { // Prima ricrea la pagina e poi salva, che per alberi grossi può metterci alcuni secondi //closeContextMenu(); // Inutile. La chiusura del menu aspetta la fine del salvataggio, // a meno di mettere salvaJson() dentro un postDelayed() di almeno 500 ms - U.updateChangeDate(Memoria.oggettoCapo()); + U.updateChangeDate(Memory.oggettoCapo()); refresh(); U.save(true, (Object[])null); return true; diff --git a/app/src/main/java/app/familygem/Diagram.java b/app/src/main/java/app/familygem/Diagram.java index 867f1466..d7ab2b49 100644 --- a/app/src/main/java/app/familygem/Diagram.java +++ b/app/src/main/java/app/familygem/Diagram.java @@ -42,6 +42,7 @@ import java.util.List; import java.util.Locale; import java.util.Set; +import app.familygem.constant.Choice; import app.familygem.constant.Gender; import app.familygem.constant.Relation; import app.familygem.detail.Famiglia; @@ -341,7 +342,7 @@ class FulcrumGlow extends View { } @Override protected void onDraw(Canvas canvas) { - paint.setColor(getResources().getColor(R.color.evidenzia)); + paint.setColor(getResources().getColor(R.color.accent)); paint.setMaskFilter(bmf); setLayerType(View.LAYER_TYPE_SOFTWARE, paint); canvas.drawRect(GLOW_SPACE - extend, GLOW_SPACE - extend, @@ -385,7 +386,7 @@ else if( Gender.isFemale(person) ) } else if( personNode.acquired ) { background.setBackgroundResource(R.drawable.casella_sfondo_sposo); } - F.unaFoto(Global.gc, person, view.findViewById(R.id.card_photo)); + F.oneImage(Global.gc, person, view.findViewById(R.id.card_photo)); TextView vistaNome = view.findViewById(R.id.card_name); String nome = U.epiteto(person, true); if( nome.isEmpty() && view.findViewById(R.id.card_photo).getVisibility()==View.VISIBLE ) @@ -402,12 +403,12 @@ else if( Gender.isFemale(person) ) if( !U.isDead(person) ) view.findViewById(R.id.card_mourn).setVisibility(View.GONE); registerForContextMenu(this); - setOnClickListener( v -> { + setOnClickListener(v -> { if( person.getId().equals(Global.indi) ) { - Memoria.setPrimo( person ); - startActivity( new Intent(getContext(), Individuo.class) ); + Memory.setPrimo(person); + startActivity(new Intent(getContext(), ProfileActivity.class)); } else { - clickCard( person ); + clickCard(person); } }); } @@ -448,7 +449,7 @@ class GraphicBond extends GraphicMetric { bondLayout.addView(year, yearParams); } setOnClickListener( view -> { - Memoria.setPrimo( familyNode.spouseFamily ); + Memory.setPrimo( familyNode.spouseFamily ); startActivity( new Intent( context, Famiglia.class ) ); }); } @@ -494,8 +495,8 @@ class Asterisk extends GraphicMetric { getLayoutInflater().inflate(R.layout.diagram_asterisk, this, true); registerForContextMenu(this); setOnClickListener( v -> { - Memoria.setPrimo(personNode.person); - startActivity(new Intent(getContext(), Individuo.class)); + Memory.setPrimo(personNode.person); + startActivity(new Intent(getContext(), ProfileActivity.class)); }); } } @@ -519,7 +520,7 @@ public Lines(Context context, List> lineGroups, boolean dashed) { } @Override public void invalidate() { - paint.setColor(getResources().getColor(printPDF ? R.color.lineeDiagrammaStampa : R.color.lineeDiagrammaSchermo)); + paint.setColor(getResources().getColor(printPDF ? R.color.diagram_lines_print : R.color.diagram_lines_screen)); paths.clear(); // In case of PDF print float width = toPx(graph.getWidth()); int pathNum = 0; // index of paths @@ -620,7 +621,7 @@ private int toPx(float dips) { } // Generate the 2 family (as child and as partner) labels for contextual menu - static String[] getFamilyLabels(Context context, Person person, Family family) { + public static String[] getFamilyLabels(Context context, Person person, Family family) { String[] labels = { null, null }; List parentFams = person.getParentFamilies(gc); List spouseFams = person.getSpouseFamilies(gc); @@ -683,11 +684,11 @@ public boolean onContextItemSelected(MenuItem item) { else // Due famiglie completeSelect(pers, Global.familyNum == 0 ? 1 : 0); } else if( id == 0 ) { // Apri scheda individuo - Memoria.setPrimo(pers); - startActivity(new Intent(getContext(), Individuo.class)); + Memory.setPrimo(pers); + startActivity(new Intent(getContext(), ProfileActivity.class)); } else if( id == 1 ) { // Famiglia come figlio if( idPersona.equals(Global.indi) ) { // Se è fulcro apre direttamente la famiglia - Memoria.setPrimo(parentFam); + Memory.setPrimo(parentFam); startActivity(new Intent(getContext(), Famiglia.class)); } else U.qualiGenitoriMostrare(getContext(), pers, 2); @@ -715,7 +716,7 @@ public boolean onContextItemSelected(MenuItem item) { new AlertDialog.Builder(getContext()).setItems(parenti, (dialog, quale) -> { Intent intento = new Intent(getContext(), Principal.class); intento.putExtra("idIndividuo", idPersona); - intento.putExtra("anagrafeScegliParente", true); + intento.putExtra(Choice.PERSON, true); intento.putExtra("relazione", quale + 1); if( U.controllaMultiMatrimoni(intento, getContext(), Diagram.this) ) return; @@ -764,7 +765,7 @@ private void ripristina() { @Override public void onActivityResult( int requestCode, int resultCode, Intent data ) { if( resultCode == AppCompatActivity.RESULT_OK ) { - // Aggiunge il parente che è stata scelto in Anagrafe + // Add the relative who has been chosen in Anagrafe if( requestCode == 1401 ) { Object[] modificati = EditaIndividuo.aggiungiParente( data.getStringExtra("idIndividuo"), // corrisponde a 'idPersona', il quale però si annulla in caso di cambio di configurazione diff --git a/app/src/main/java/app/familygem/EditaIndividuo.java b/app/src/main/java/app/familygem/EditaIndividuo.java index 13fad117..a8d4ad02 100644 --- a/app/src/main/java/app/familygem/EditaIndividuo.java +++ b/app/src/main/java/app/familygem/EditaIndividuo.java @@ -26,6 +26,8 @@ import app.familygem.constant.Gender; import app.familygem.detail.Evento; import app.familygem.detail.Famiglia; +import app.familygem.list.FamiliesFragment; + import static app.familygem.Global.gc; public class EditaIndividuo extends AppCompatActivity { @@ -92,10 +94,10 @@ protected void onCreate(Bundle bandolo) { Person pivot = gc.getPerson(idIndi); String surname = null; // Cognome del fratello - if( relazione == 2 ) { // = fratello + if( relazione == 2 ) { // Sibling surname = U.surname(pivot); // Cognome del padre - } else if( relazione == 4 ) { // = figlio da Diagramma o Individuo + } else if( relazione == 4 ) { // Child from Diagram or ProfileActivity if( Gender.isMale(pivot) ) surname = U.surname(pivot); else if( idFamiglia != null ) { @@ -103,7 +105,7 @@ else if( idFamiglia != null ) { if( fam != null && !fam.getHusbands(gc).isEmpty() ) surname = U.surname(fam.getHusbands(gc).get(0)); } - } else if( relazione == 6 ) { // = figlio da Famiglia + } else if( relazione == 6 ) { // Child from Famiglia Family fam = gc.getFamily(idFamiglia); if( !fam.getHusbands(gc).isEmpty() ) surname = U.surname(fam.getHusbands(gc).get(0)); @@ -124,9 +126,9 @@ else if( !fam.getChildren(gc).isEmpty() ) Name n = p.getNames().get(0); String epiteto = n.getValue(); if( epiteto != null ) { - nome = epiteto.replaceAll( "/.*?/", "" ).trim(); // rimuove il cognome '/.../' + nome = epiteto.replaceAll("/.*?/", "").trim(); // rimuove il cognome '/.../' if( epiteto.indexOf('/') < epiteto.lastIndexOf('/') ) - cognome = epiteto.substring( epiteto.indexOf('/') + 1, epiteto.lastIndexOf('/') ).trim(); + cognome = epiteto.substring(epiteto.indexOf('/') + 1, epiteto.lastIndexOf('/')).trim(); } else { if( n.getGiven() != null ) { nome = n.getGiven(); @@ -137,8 +139,8 @@ else if( !fam.getChildren(gc).isEmpty() ) nomeDaPieces = true; } } - ((EditText)findViewById( R.id.nome )).setText( nome ); - ((EditText)findViewById( R.id.cognome )).setText( cognome ); + ((EditText)findViewById(R.id.nome)).setText(nome); + ((EditText)findViewById(R.id.cognome)).setText(cognome); } // Sex switch( Gender.getGender(p) ) { @@ -156,7 +158,7 @@ else if( !fam.getChildren(gc).isEmpty() ) for( EventFact fatto : p.getEventsFacts() ) { if( fatto.getTag().equals("BIRT") ) { if( fatto.getDate() != null ) - dataNascita.setText( fatto.getDate().trim() ); + dataNascita.setText(fatto.getDate().trim()); if( fatto.getPlace() != null ) luogoNascita.setText(fatto.getPlace().trim()); } @@ -164,21 +166,21 @@ else if( !fam.getChildren(gc).isEmpty() ) bottonMorte.setChecked(true); attivaMorte(); if( fatto.getDate() != null ) - dataMorte.setText( fatto.getDate().trim() ); + dataMorte.setText(fatto.getDate().trim()); if( fatto.getPlace() != null ) luogoMorte.setText(fatto.getPlace().trim()); } } } - editoreDataNascita.inizia( dataNascita ); - bottonMorte.setOnCheckedChangeListener( (coso, attivo) -> { - if (attivo) + editoreDataNascita.initialize(dataNascita); + bottonMorte.setOnCheckedChangeListener((coso, attivo) -> { + if( attivo ) attivaMorte(); else disattivaMorte(); }); - editoreDataMorte.inizia( dataMorte ); - luogoMorte.setOnEditorActionListener( (vista, actionId, keyEvent) -> { + editoreDataMorte.initialize(dataMorte); + luogoMorte.setOnEditorActionListener((vista, actionId, keyEvent) -> { if( actionId == EditorInfo.IME_ACTION_DONE ) salva(); return false; @@ -256,7 +258,7 @@ else if( sexUnknown.isChecked() ) sesso.setValue(sessoScelto); p.addEventFact(sesso); } - IndividuoEventi.aggiornaRuoliConiugali(p); + ProfileFactsFragment.aggiornaRuoliConiugali(p); } else { // Remove existing sex tag for( EventFact fact : p.getEventsFacts() ) { if( fact.getTag().equals("SEX") ) { @@ -331,7 +333,7 @@ else if( sexUnknown.isChecked() ) if( relazione >= 5 ) { // viene da Famiglia Famiglia.aggrega( p, gc.getFamily(idFamiglia), relazione ); modificati[1] = gc.getFamily(idFamiglia); - } else if( relazione > 0 ) // viene da Diagramma o IndividuoFamiliari + } else if( relazione > 0 ) // viene da Diagram o ProfileRelativesFragment modificati = aggiungiParente( idIndi, nuovoId, idFamiglia, relazione, getIntent().getStringExtra("collocazione") ); } else Global.indi = p.getId(); // per mostrarlo orgogliosi in Diagramma @@ -351,7 +353,7 @@ static Object[] aggiungiParente(String idPerno, String nuovoId, String idFamigli idPerno = collocazione.substring(17); // il genitore diventa effettivamente il perno relazione = relazione == 2 ? 4 : relazione; // anziché un fratello a perno, è come se mettessimo un figlio al genitore } - // In Anagrafe è stata individuata la famiglia in cui finirà perno + // In Anagrafe has been identified the family in which will end the pivot else if( collocazione != null && collocazione.equals("FAMIGLIA_ESISTENTE") ) { nuovoId = null; nuovo = null; @@ -360,7 +362,7 @@ else if( collocazione != null && collocazione.equals("FAMIGLIA_ESISTENTE") ) { else if( idFamiglia != null ) { idPerno = null; // perno è già presente nella sua famiglia e non va riaggiunto } - Family famiglia = idFamiglia != null ? gc.getFamily(idFamiglia) : Chiesa.nuovaFamiglia(true);; + Family famiglia = idFamiglia != null ? gc.getFamily(idFamiglia) : FamiliesFragment.newFamily(true); Person perno = gc.getPerson( idPerno ); SpouseRef refSposo1 = new SpouseRef(), refSposo2 = new SpouseRef(); ChildRef refFiglio1 = new ChildRef(), refFiglio2 = new ChildRef(); diff --git a/app/src/main/java/app/familygem/EditoreData.java b/app/src/main/java/app/familygem/EditoreData.java index 48cdd936..3a27483c 100644 --- a/app/src/main/java/app/familygem/EditoreData.java +++ b/app/src/main/java/app/familygem/EditoreData.java @@ -1,6 +1,7 @@ package app.familygem; import android.content.Context; +import android.os.Build; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; @@ -15,6 +16,7 @@ import android.widget.LinearLayout; import android.widget.NumberPicker; import android.widget.TextView; +import android.widget.Toast; import androidx.appcompat.widget.PopupMenu; import java.lang.reflect.Field; import java.util.Calendar; @@ -47,17 +49,17 @@ public EditoreData( Context contesto, AttributeSet as ) { super( contesto, as ); } - // Azioni da fare una sola volta all'inizio - void inizia( final EditText editaTesto ) { + // Actions to be done only once at the beginning + void initialize(final EditText editaTesto) { - addView( inflate( getContext(), R.layout.editore_data, null ), this.getLayoutParams() ); + addView(inflate(getContext(), R.layout.editore_data, null), this.getLayoutParams()); this.editaTesto = editaTesto; for( int i = 0; i < anniRuota.length - 1; i++ ) anniRuota[i] = i < 10 ? "0" + i : "" + i; anniRuota[100] = "-"; - datatore = new Datatore( editaTesto.getText().toString() ); + datatore = new Datatore(editaTesto.getText().toString()); data1 = datatore.data1; data2 = datatore.data2; @@ -177,45 +179,47 @@ public void afterTextChanged(Editable testo) { } // Prepara le quattro ruote di un carro con le impostazioni iniziali - void arredaCarro( final int quale, final NumberPicker ruotaGiorno, final NumberPicker ruotaMese, final NumberPicker ruotaSecolo, final NumberPicker ruotaAnno ) { + void arredaCarro(final int quale, final NumberPicker ruotaGiorno, final NumberPicker ruotaMese, final NumberPicker ruotaSecolo, final NumberPicker ruotaAnno) { ruotaGiorno.setMinValue(0); ruotaGiorno.setMaxValue(31); - ruotaGiorno.setDisplayedValues( giorniRuota ); - stilizza(ruotaGiorno); - ruotaGiorno.setOnValueChangedListener( (picker, vecchio, nuovo) -> - aggiorna( quale == 1 ? data1 : data2, ruotaGiorno, ruotaMese, ruotaSecolo, ruotaAnno ) + ruotaGiorno.setDisplayedValues(giorniRuota); + prepare(ruotaGiorno); + ruotaGiorno.setOnValueChangedListener((picker, vecchio, nuovo) -> + aggiorna(quale == 1 ? data1 : data2, ruotaGiorno, ruotaMese, ruotaSecolo, ruotaAnno) ); ruotaMese.setMinValue(0); ruotaMese.setMaxValue(12); - ruotaMese.setDisplayedValues( mesiRuota ); - stilizza(ruotaMese); - ruotaMese.setOnValueChangedListener( (picker, vecchio, nuovo) -> - aggiorna( quale == 1 ? data1 : data2, ruotaGiorno, ruotaMese, ruotaSecolo, ruotaAnno ) + ruotaMese.setDisplayedValues(mesiRuota); + prepare(ruotaMese); + ruotaMese.setOnValueChangedListener((picker, vecchio, nuovo) -> + aggiorna(quale == 1 ? data1 : data2, ruotaGiorno, ruotaMese, ruotaSecolo, ruotaAnno) ); ruotaSecolo.setMinValue(0); ruotaSecolo.setMaxValue(20); - stilizza(ruotaSecolo); - ruotaSecolo.setOnValueChangedListener( (picker, vecchio, nuovo) -> - aggiorna( quale == 1 ? data1 : data2, ruotaGiorno, ruotaMese, ruotaSecolo, ruotaAnno ) + prepare(ruotaSecolo); + ruotaSecolo.setOnValueChangedListener((picker, vecchio, nuovo) -> + aggiorna(quale == 1 ? data1 : data2, ruotaGiorno, ruotaMese, ruotaSecolo, ruotaAnno) ); ruotaAnno.setMinValue(0); ruotaAnno.setMaxValue(100); - ruotaAnno.setDisplayedValues( anniRuota ); - stilizza(ruotaAnno); - ruotaAnno.setOnValueChangedListener( ( picker, vecchio, nuovo ) -> - aggiorna( quale == 1 ? data1 : data2, ruotaGiorno, ruotaMese, ruotaSecolo, ruotaAnno ) + ruotaAnno.setDisplayedValues(anniRuota); + prepare(ruotaAnno); + ruotaAnno.setOnValueChangedListener((picker, vecchio, nuovo) -> + aggiorna(quale == 1 ? data1 : data2, ruotaGiorno, ruotaMese, ruotaSecolo, ruotaAnno) ); } - void stilizza( NumberPicker ruota ) { - // Toglie le famigerate linee divisorie azzurre - try { - Field campo = NumberPicker.class.getDeclaredField( "mSelectionDivider" ); - campo.setAccessible( true ); - campo.set( ruota, null ); - } catch( Exception e ) {} - // Risolve il bug https://issuetracker.google.com/issues/37055335 - ruota.setSaveFromParentEnabled(false); + void prepare(NumberPicker wheel) { + // Remove the dividing blue lines on API <= 22 + if( Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1 ) { + try { + Field field = NumberPicker.class.getDeclaredField("mSelectionDivider"); + field.setAccessible(true); + field.set(wheel, null); + } catch( Exception e ) {} + } + // Fix the bug https://issuetracker.google.com/issues/37055335 + wheel.setSaveFromParentEnabled(false); } // Prende la stringa data, aggiorna le Date e ci modifica tutto l'editore data diff --git a/app/src/main/java/app/familygem/Esportatore.java b/app/src/main/java/app/familygem/Exporter.java similarity index 58% rename from app/src/main/java/app/familygem/Esportatore.java rename to app/src/main/java/app/familygem/Exporter.java index bd3e993d..541b2d17 100644 --- a/app/src/main/java/app/familygem/Esportatore.java +++ b/app/src/main/java/app/familygem/Exporter.java @@ -25,66 +25,67 @@ import java.util.zip.ZipOutputStream; import app.familygem.visitor.ListaMedia; -public class Esportatore { +// Utility class to export a tree as GEDCOM or ZIP backup +public class Exporter { - private final Context contesto; - private int idAlbero; - private Gedcom gc; + private final Context context; + private int treeId; + private Gedcom gedcom; private Uri targetUri; - public String messaggioErrore; // Messaggio di eventuale errore - public String messaggioSuccesso; // Messaggio del risultato ottenuto + public String errorMessage; // Message of possible error + public String successMessage; // Message of the obtained result - Esportatore(Context context) { - this.contesto = context; + Exporter(Context context) { + this.context = context; } - // Apre l'albero Json e restituisce true se c'è riuscito - public boolean apriAlbero(int idAlbero) { - this.idAlbero = idAlbero; - gc = Alberi.apriGedcomTemporaneo(idAlbero, true); - if( gc == null ) { - return errore(R.string.no_useful_data); + // Open the Json tree and return true if successful + public boolean openTree(int treeId) { + this.treeId = treeId; + gedcom = TreesActivity.openTemporaryGedcom(treeId, true); + if( gedcom == null ) { + return error(R.string.no_useful_data); } return true; } - // Scrive il solo GEDCOM nell'URI - public boolean esportaGedcom(Uri targetUri) { + // Write only the GEDCOM in the URI + public boolean exportGedcom(Uri targetUri) { this.targetUri = targetUri; aggiornaTestata(estraiNome(targetUri)); ottimizzaGedcom(); - GedcomWriter scrittore = new GedcomWriter(); - File fileGc = new File(contesto.getCacheDir(), "temp.ged"); + GedcomWriter writer = new GedcomWriter(); + File gedcomFile = new File(context.getCacheDir(), "temp.ged"); try { - scrittore.write(gc, fileGc); - OutputStream out = contesto.getContentResolver().openOutputStream(targetUri); - FileUtils.copyFile(fileGc, out); + writer.write(gedcom, gedcomFile); + OutputStream out = context.getContentResolver().openOutputStream(targetUri); + FileUtils.copyFile(gedcomFile, out); out.flush(); out.close(); } catch( Exception e ) { - return errore(e.getLocalizedMessage()); + return error(e.getLocalizedMessage()); } - // Rende il file visibile da Windows - // Ma pare inefficace in KitKat in cui il file rimane invisibile - contesto.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, targetUri)); - Global.gc = Alberi.readJson(idAlbero); // Resetta le modifiche - return successo(R.string.gedcom_exported_ok); + // Make the file visible from Windows + // But it seems ineffective in KitKat where the file remains invisible + context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, targetUri)); + Global.gc = TreesActivity.readJson(treeId); // Reset changes + return success(R.string.gedcom_exported_ok); } - // Scrive il GEDCOM con i media in un file ZIP - public boolean esportaGedcomZippato(Uri targetUri) { + // Write the GEDCOM with the media in a ZIP file + public boolean exportZippedGedcom(Uri targetUri) { this.targetUri = targetUri; - // Crea il file GEDCOM - String titolo = Global.settings.getTree(idAlbero).title; - String nomeFileGedcom = titolo.replaceAll("[\\\\/:*?\"<>|'$]", "_") + ".ged"; - aggiornaTestata(nomeFileGedcom); + // Create the GEDCOM file + String title = Global.settings.getTree(treeId).title; + String gedcomFileName = title.replaceAll("[\\\\/:*?\"<>|'$]", "_") + ".ged"; + aggiornaTestata(gedcomFileName); ottimizzaGedcom(); GedcomWriter scrittore = new GedcomWriter(); - File fileGc = new File(contesto.getCacheDir(), nomeFileGedcom); + File fileGc = new File(context.getCacheDir(), gedcomFileName); try { - scrittore.write(gc, fileGc); + scrittore.write(gedcom, fileGc); } catch( Exception e ) { - return errore(e.getLocalizedMessage()); + return error(e.getLocalizedMessage()); } DocumentFile gedcomDocument = DocumentFile.fromFile(fileGc); // Aggiunge il GEDCOM alla raccolta di file media @@ -92,41 +93,41 @@ public boolean esportaGedcomZippato(Uri targetUri) { raccolta.put(gedcomDocument, 0); if( !creaFileZip(raccolta) ) return false; - contesto.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, targetUri)); - Global.gc = Alberi.readJson(idAlbero); - return successo(R.string.zip_exported_ok); + context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, targetUri)); + Global.gc = TreesActivity.readJson(treeId); + return success(R.string.zip_exported_ok); } - // Crea un file zippato con l'albero, i settaggi e i media - public boolean esportaBackupZip(String radice, int grado, Uri targetUri) { + // Create a zipped file with the tree, settings and media + public boolean exportZipBackup(String root, int grade, Uri targetUri) { this.targetUri = targetUri; // Media Map files = raccogliMedia(); - // Json dell'albero - File fileTree = new File(contesto.getFilesDir(), idAlbero + ".json"); + // Tree Json + File fileTree = new File(context.getFilesDir(), treeId + ".json"); files.put(DocumentFile.fromFile(fileTree), 1); // Json delle preferenze - Settings.Tree tree = Global.settings.getTree(idAlbero); - if( radice == null ) radice = tree.root; - if( grado < 0 ) grado = tree.grade; - // String titoloAlbero, String radice, int grado possono arrivare diversi da Condividi - Settings.ZippedTree settaggi = new Settings.ZippedTree( - tree.title, tree.persons, tree.generations, radice, tree.shares, grado); - File fileSettings = settaggi.salva(); + Settings.Tree tree = Global.settings.getTree(treeId); + if( root == null ) root = tree.root; + if( grade < 0 ) grade = tree.grade; + // String titoloAlbero, String root, int grade possono arrivare diversi da Condividi + Settings.ZippedTree settings = new Settings.ZippedTree( + tree.title, tree.persons, tree.generations, root, tree.shares, grade); + File fileSettings = settings.salva(); files.put(DocumentFile.fromFile(fileSettings), 0); if( !creaFileZip(files) ) return false; - contesto.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, targetUri)); - return successo(R.string.zip_exported_ok); + context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, targetUri)); + return success(R.string.zip_exported_ok); } // Restituisce il numero di file media da allegare public int quantiFileMedia() { - ListaMedia visitaMedia = new ListaMedia( gc, 0 ); - gc.accept( visitaMedia ); + ListaMedia visitaMedia = new ListaMedia(gedcom, 0 ); + gedcom.accept( visitaMedia ); int quantiFile = 0; for( Media med : visitaMedia.lista ) { - if( F.percorsoMedia(idAlbero, med) != null || F.uriMedia( idAlbero, med ) != null ) + if( F.percorsoMedia(treeId, med) != null || F.uriMedia(treeId, med ) != null ) quantiFile++; } return quantiFile; @@ -134,8 +135,8 @@ public int quantiFileMedia() { // Riceve l'id di un albero e restituisce una Map di DocumentFile dei media che riesce a rastrellare private Map raccogliMedia() { - ListaMedia visitaMedia = new ListaMedia( gc, 0 ); - gc.accept( visitaMedia ); + ListaMedia visitaMedia = new ListaMedia(gedcom, 0 ); + gedcom.accept( visitaMedia ); /* Capita che diversi Media puntino allo stesso file. * E potrebbe anche capitare che diversi percorsi finiscano con nomi di file uguali, * ad es. 'percorsoA/img.jpg' 'percorsoB/img.jpg' @@ -159,22 +160,22 @@ private Map raccogliMedia() { Media med = new Media(); med.setFile(path); // Paths - String percorsoMedia = F.percorsoMedia(idAlbero, med); + String percorsoMedia = F.percorsoMedia(treeId, med); if( percorsoMedia != null ) collezione.put(DocumentFile.fromFile(new File(percorsoMedia)), 2); // todo canRead() ? else { // URIs - Uri uriMedia = F.uriMedia(idAlbero, med); + Uri uriMedia = F.uriMedia(treeId, med); if( uriMedia != null ) - collezione.put(DocumentFile.fromSingleUri(contesto, uriMedia), 2); + collezione.put(DocumentFile.fromSingleUri(context, uriMedia), 2); } } return collezione; } private void aggiornaTestata(String nomeFileGedcom) { - Header testa = gc.getHeader(); + Header testa = gedcom.getHeader(); if( testa == null ) - gc.setHeader(AlberoNuovo.creaTestata(nomeFileGedcom)); + gedcom.setHeader(NewTreeActivity.creaTestata(nomeFileGedcom)); else { testa.setFile(nomeFileGedcom); testa.setDateTime(U.actualDateTime()); @@ -184,8 +185,8 @@ private void aggiornaTestata(String nomeFileGedcom) { // Migliora il GEDCOM per l'esportazione void ottimizzaGedcom() { // Value dei nomi da given e surname - for( Person pers : gc.getPeople() ) { - for( Name n : pers.getNames() ) + for( Person person : gedcom.getPeople() ) { + for( Name n : person.getNames() ) if( n.getValue() == null && (n.getPrefix() != null || n.getGiven() != null || n.getSurname() != null || n.getSuffix() != null) ) { String epiteto = ""; @@ -197,7 +198,7 @@ void ottimizzaGedcom() { epiteto += " /" + n.getSurname() + "/"; if( n.getSuffix() != null ) epiteto += " " + n.getSuffix(); - n.setValue( epiteto.trim() ); + n.setValue(epiteto.trim()); } } } @@ -209,7 +210,7 @@ private String estraiNome( Uri uri ) { return uri.getLastPathSegment(); } // Cursore (di solito funziona questo) - Cursor cursore = contesto.getContentResolver().query( uri, null, null, null, null); + Cursor cursore = context.getContentResolver().query( uri, null, null, null, null); if( cursore != null && cursore.moveToFirst() ) { int indice = cursore.getColumnIndex( OpenableColumns.DISPLAY_NAME ); String nomeFile = cursore.getString( indice ); @@ -217,7 +218,7 @@ private String estraiNome( Uri uri ) { if( nomeFile != null ) return nomeFile; } // DocumentFile - DocumentFile document = DocumentFile.fromSingleUri( contesto, targetUri ); + DocumentFile document = DocumentFile.fromSingleUri(context, targetUri ); String nomeFile = document.getName(); if( nomeFile != null ) return nomeFile; // Alla frutta @@ -229,10 +230,10 @@ private String estraiNome( Uri uri ) { boolean creaFileZip(Map files) { byte[] buffer = new byte[128]; try { - ZipOutputStream zos = new ZipOutputStream(contesto.getContentResolver().openOutputStream(targetUri)); + ZipOutputStream zos = new ZipOutputStream(context.getContentResolver().openOutputStream(targetUri)); for( Map.Entry fileTipo : files.entrySet() ) { DocumentFile file = fileTipo.getKey(); - InputStream input = contesto.getContentResolver().openInputStream(file.getUri()); + InputStream input = context.getContentResolver().openInputStream(file.getUri()); String nomeFile = file.getName(); // File che non vengono rinominati ('settings.json', 'famiglia.ged') if( fileTipo.getValue() == 1 ) nomeFile = "tree.json"; @@ -248,21 +249,21 @@ else if( fileTipo.getValue() == 2 ) } zos.close(); } catch( IOException e ) { - return errore(e.getLocalizedMessage()); + return error(e.getLocalizedMessage()); } return true; } - public boolean successo( int messaggio ) { - messaggioSuccesso = contesto.getString( messaggio ); + public boolean success(int message) { + successMessage = context.getString(message); return true; } - public boolean errore(int error) { - return errore(contesto.getString(error)); + public boolean error(int error) { + return error(context.getString(error)); } - public boolean errore(String error) { - messaggioErrore = error; + public boolean error(String error) { + errorMessage = error; return false; } } diff --git a/app/src/main/java/app/familygem/F.java b/app/src/main/java/app/familygem/F.java index 910bcbd8..741f2b45 100644 --- a/app/src/main/java/app/familygem/F.java +++ b/app/src/main/java/app/familygem/F.java @@ -63,15 +63,16 @@ import java.util.ArrayList; import java.util.List; import app.familygem.detail.Immagine; +import app.familygem.list.GalleryFragment; import app.familygem.visitor.ListaMedia; public class F { // Impacchettamento per ricavare una cartella in KitKat - static String uriPercorsoCartellaKitKat( Context contesto, Uri uri ) { - String percorso = uriPercorsoFile( uri ); + static String uriPercorsoCartellaKitKat(Context contesto, Uri uri) { + String percorso = uriPercorsoFile(uri); if( percorso != null && percorso.lastIndexOf('/') > 0 ) { - return percorso.substring( 0, percorso.lastIndexOf('/') ); + return percorso.substring(0, percorso.lastIndexOf('/')); } else { Toast.makeText(contesto, "Could not get this position.", Toast.LENGTH_SHORT).show(); return null; @@ -149,10 +150,10 @@ private static String trovaNomeFile( Uri uri ) { // Riceve un tree Uri ricavato con ACTION_OPEN_DOCUMENT_TREE e cerca di restituire il percorso della cartella // altrimenti tranquillamente restituisce null - public static String uriPercorsoCartella( Uri uri ) { + public static String uriPercorsoCartella(Uri uri) { if( uri == null ) return null; if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) { - String treeDocId = DocumentsContract.getTreeDocumentId( uri ); + String treeDocId = DocumentsContract.getTreeDocumentId(uri); switch( uri.getAuthority() ) { case "com.android.externalstorage.documents": // memoria interna e scheda SD String[] split = treeDocId.split(":"); @@ -170,8 +171,8 @@ else if( split[0].equalsIgnoreCase("home") ) { File[] filesDirs = Global.context.getExternalFilesDirs(null); for( File dir : filesDirs ) { String altro = dir.getAbsolutePath(); - if( altro.contains(split[0])) { - percorso = altro.substring( 0, altro.indexOf("/Android") ); + if( altro.contains(split[0]) ) { + percorso = altro.substring(0, altro.indexOf("/Android")); break; } } @@ -211,59 +212,58 @@ static void salvaDocumento( Activity attivita, Fragment frammento, int idAlbero, // Metodi per mostrare immagini: - // Riceve una Person e sceglie il Media principale da cui ricavare l'immagine - static void unaFoto( Gedcom gc, Person p, ImageView img ) { - ListaMedia visita = new ListaMedia( gc, 0 ); - p.accept( visita ); - boolean trovatoQualcosa = false; - for( Media med : visita.lista ) { // Cerca un media contrassegnato Primario Y + // Receive a Person and choose the main Media from which to obtain the image + public static Media oneImage(Gedcom gedcom, Person person, ImageView imageView) { + ListaMedia visitor = new ListaMedia(gedcom, 0); + person.accept(visitor); + Media media = null; + for( Media med : visitor.lista ) { // Look for a media with Primary 'Y' if( med.getPrimary() != null && med.getPrimary().equals("Y") ) { - dipingiMedia( med, img, null ); - trovatoQualcosa = true; + paintMedia(med, imageView, null); + media = med; break; } } - if( !trovatoQualcosa ) { // In alternativa restituisce il primo che trova - for( Media med : visita.lista ) { - dipingiMedia( med, img, null ); - trovatoQualcosa = true; + if( media == null ) { // Alternatively return the first one available + for( Media med : visitor.lista ) { + paintMedia(med, imageView, null); + media = med; break; } } - img.setVisibility( trovatoQualcosa ? View.VISIBLE : View.GONE ); + imageView.setVisibility(media != null ? View.VISIBLE : View.GONE); + return media; } - // Mostra le immagini con Picasso - public static void dipingiMedia( Media media, ImageView imageView, ProgressBar circo ) { - int idAlbero; - // Confrontatore ha bisogno dell'id dell'albero nuovo per cercare nella sua cartella + // Display an image with Picasso + public static void paintMedia(Media media, ImageView imageView, ProgressBar progress) { + int treeId; + // Confrontatore needs the new tree id to search inside its folder View probabile = null; if( imageView.getParent() != null && imageView.getParent().getParent() != null ) - probabile = (View) imageView.getParent().getParent().getParent(); + probabile = (View)imageView.getParent().getParent().getParent(); if( probabile != null && probabile.getId() == R.id.confronto_nuovo ) - idAlbero = Global.treeId2; - else idAlbero = Global.settings.openTree; - String percorso = percorsoMedia(idAlbero, media); + treeId = Global.treeId2; + else treeId = Global.settings.openTree; + String path = percorsoMedia(treeId, media); Uri[] uri = new Uri[1]; - if( percorso == null ) - uri[0] = uriMedia(idAlbero, media); - if( circo != null ) circo.setVisibility(View.VISIBLE); - imageView.setTag(R.id.tag_tipo_file, 0); - if( percorso != null || uri[0] != null ) { + if( path == null ) + uri[0] = uriMedia(treeId, media); + if( progress != null ) progress.setVisibility(View.VISIBLE); + imageView.setTag(R.id.tag_file_type, 0); + if( path != null || uri[0] != null ) { RequestCreator creator; - if( percorso != null ) - creator = Picasso.get().load("file://" + percorso); + if( path != null ) + creator = Picasso.get().load("file://" + path); else creator = Picasso.get().load(uri[0]); - creator.placeholder(R.drawable.image) - .fit() - .centerInside() + creator.placeholder(R.drawable.image).fit().centerInside() .into(imageView, new Callback() { @Override public void onSuccess() { - if( circo != null ) circo.setVisibility(View.GONE); - imageView.setTag(R.id.tag_tipo_file, 1); - imageView.setTag(R.id.tag_percorso, percorso); // 'percorso' o 'uri' uno dei 2 è valido, l'altro è null + if( progress != null ) progress.setVisibility(View.GONE); + imageView.setTag(R.id.tag_file_type, 1); + imageView.setTag(R.id.tag_percorso, path); // 'percorso' o 'uri' uno dei 2 è valido, l'altro è null imageView.setTag(R.id.tag_uri, uri[0]); // Nella pagina Dettaglio Immagine ricarica il menu opzioni per mostrare il comando Crop if( imageView.getId() == R.id.immagine_foto ) { @@ -272,78 +272,78 @@ public void onSuccess() { } } @Override - public void onError( Exception e ) { - // Magari è un video da cui ricavare una thumbnail + public void onError(Exception e) { + // Maybe it's a video to make a thumbnail from Bitmap bitmap = null; try { // Ultimamente questi generatori di thumbnail inchiodano, quindi meglio pararsi il culo - bitmap = ThumbnailUtils.createVideoThumbnail( percorso, MediaStore.Video.Thumbnails.MINI_KIND ); - // Tramite l'URI + bitmap = ThumbnailUtils.createVideoThumbnail(path, MediaStore.Video.Thumbnails.MINI_KIND); + // Via the URI if( bitmap == null && uri[0] != null ) { - MediaMetadataRetriever mMR = new MediaMetadataRetriever(); - mMR.setDataSource( Global.context, uri[0] ); - bitmap = mMR.getFrameAtTime(); + MediaMetadataRetriever retriever = new MediaMetadataRetriever(); + retriever.setDataSource(Global.context, uri[0]); + bitmap = retriever.getFrameAtTime(); } - } catch( Exception excpt ) {} - imageView.setTag(R.id.tag_tipo_file, 2); + } catch( Exception exception ) {} + imageView.setTag(R.id.tag_file_type, 2); if( bitmap == null ) { - // un File locale senza anteprima - String formato = media.getFormat(); - if( formato == null ) - formato = percorso != null ? MimeTypeMap.getFileExtensionFromUrl(percorso.replaceAll("[^a-zA-Z0-9./]", "_")) : ""; - // Rimuove gli spazi bianchi che non fanno trovare l'estensione - if( formato.isEmpty() && uri[0] != null ) - formato = MimeTypeMap.getFileExtensionFromUrl( uri[0].getLastPathSegment() ); - bitmap = generaIcona( imageView, R.layout.media_file, formato ); - imageView.setScaleType( ImageView.ScaleType.FIT_CENTER ); - if( imageView.getParent() instanceof RelativeLayout && // brutto ma efficace + // A local file with no preview + String format = media.getFormat(); + if( format == null ) + format = path != null ? MimeTypeMap.getFileExtensionFromUrl(path.replaceAll("[^a-zA-Z0-9./]", "_")) : ""; + // Rimuove gli spazi bianchi che non fanno trovare l'estensione + if( format.isEmpty() && uri[0] != null ) + format = MimeTypeMap.getFileExtensionFromUrl(uri[0].getLastPathSegment()); + bitmap = generaIcona(imageView, R.layout.media_file, format); + imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); + if( imageView.getParent() instanceof RelativeLayout && // Ugly but effective ((RelativeLayout)imageView.getParent()).findViewById(R.id.media_testo) != null ) { - RelativeLayout.LayoutParams parami = new RelativeLayout.LayoutParams( - RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT ); - parami.addRule( RelativeLayout.ABOVE, R.id.media_testo ); - imageView.setLayoutParams( parami ); + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT); + params.addRule(RelativeLayout.ABOVE, R.id.media_testo); + imageView.setLayoutParams(params); } - imageView.setTag( R.id.tag_tipo_file, 3 ); + imageView.setTag(R.id.tag_file_type, 3); } imageView.setImageBitmap(bitmap); - imageView.setTag( R.id.tag_percorso, percorso ); - imageView.setTag( R.id.tag_uri, uri[0] ); - if( circo!=null ) circo.setVisibility( View.GONE ); + imageView.setTag(R.id.tag_percorso, path); + imageView.setTag(R.id.tag_uri, uri[0]); + if( progress != null ) progress.setVisibility(View.GONE); } }); - } else if( media.getFile() != null && !media.getFile().isEmpty() ) { // magari è un'immagine in internet - String percorsoFile = media.getFile(); - Picasso.get().load(percorsoFile).fit() + } else if( media.getFile() != null && !media.getFile().isEmpty() ) { // Maybe it's an image on the internet + String filePath = media.getFile(); + Picasso.get().load(filePath).fit() .placeholder(R.drawable.image).centerInside() .into(imageView, new Callback() { @Override public void onSuccess() { - if( circo != null ) circo.setVisibility(View.GONE); - imageView.setTag(R.id.tag_tipo_file, 1); + if( progress != null ) progress.setVisibility(View.GONE); + imageView.setTag(R.id.tag_file_type, 1); try { - new ImboscaImmagine(media).execute(new URL(percorsoFile)); + new ImboscaImmagine(media).execute(new URL(filePath)); } catch( Exception e ) {} } @Override - public void onError( Exception e ) { + public void onError(Exception e) { // Proviamo con una pagina web - new ZuppaMedia(imageView, circo, media).execute(percorsoFile); + new ZuppaMedia(imageView, progress, media).execute(filePath); } }); } else { // Media privo di collegamento a un file - if( circo != null ) circo.setVisibility(View.GONE); + if( progress != null ) progress.setVisibility(View.GONE); imageView.setImageResource(R.drawable.image); } } // Riceve un Media, cerca il file in locale con diverse combinazioni di percorso e restituisce l'indirizzo - public static String percorsoMedia( int idAlbero, Media m ) { + public static String percorsoMedia(int idAlbero, Media m) { String file = m.getFile(); if( file != null && !file.isEmpty() ) { String nome = file.replace("\\", "/"); // Percorso FILE (quello nel gedcom) if( new File(nome).canRead() ) return nome; - for( String dir : Global.settings.getTree( idAlbero ).dirs ) { + for( String dir : Global.settings.getTree(idAlbero).dirs ) { // Cartella media + percorso FILE String percorso = dir + '/' + nome; File prova = new File(percorso); @@ -364,7 +364,7 @@ public static String percorsoMedia( int idAlbero, Media m ) { if( stringa != null ) { String percorsoCache; if( stringa instanceof String ) - percorsoCache = (String) stringa; + percorsoCache = (String)stringa; else percorsoCache = ((JsonPrimitive)stringa).getAsString(); if( new File(percorsoCache).isFile() ) @@ -410,21 +410,22 @@ static class ImboscaImmagine extends AsyncTask { ImboscaImmagine( Media media ) { this.media = media; } - protected String doInBackground( URL... url ) { + @Override + protected String doInBackground(URL... url) { try { - File cartellaCache = new File( Global.context.getCacheDir().getPath() + "/" + Global.settings.openTree); - if( !cartellaCache.exists() ) { + File cacheDir = new File(Global.context.getCacheDir().getPath() + "/" + Global.settings.openTree); + if( !cacheDir.exists() ) { // Elimina extension "cache" da tutti i Media - ListaMedia visitaMedia = new ListaMedia( Global.gc, 0 ); - Global.gc.accept( visitaMedia ); + ListaMedia visitaMedia = new ListaMedia(Global.gc, 0); + Global.gc.accept(visitaMedia); for( Media media : visitaMedia.lista ) if( media.getExtension("cache") != null ) - media.putExtension( "cache", null ); - cartellaCache.mkdir(); + media.putExtension("cache", null); + cacheDir.mkdir(); } - String estensione = FilenameUtils.getName( url[0].getPath() ); + String estensione = FilenameUtils.getName(url[0].getPath()); if( estensione.lastIndexOf('.') > 0 ) - estensione = estensione.substring( estensione.lastIndexOf('.')+1 ); + estensione = estensione.substring(estensione.lastIndexOf('.') + 1); String ext; switch( estensione ) { case "png": @@ -441,14 +442,15 @@ protected String doInBackground( URL... url ) { default: ext = "jpg"; } - File cache = fileNomeProgressivo( cartellaCache.getPath(), "img." + ext ); - FileUtils.copyURLToFile( url[0], cache ); + File cache = fileNomeProgressivo(cacheDir.getPath(), "img." + ext); + FileUtils.copyURLToFile(url[0], cache); return cache.getPath(); } catch( Exception e ) { e.printStackTrace(); } return null; } + @Override protected void onPostExecute( String percorso) { if( percorso != null ) media.putExtension( "cache", percorso ); @@ -457,30 +459,30 @@ protected void onPostExecute( String percorso) { // Scarica asincronicamente un'immagine da una pagina internet static class ZuppaMedia extends AsyncTask { - ImageView vistaImmagine; - ProgressBar circo; + ImageView imageView; + ProgressBar progress; Media media; URL url; - int tagTipoFile = 0; // setTag deve stare nel thread principale, non nel doInBackground - int vistaImmagineWidth; // idem - ZuppaMedia( ImageView vistaImmagine, ProgressBar circo, Media media ) { - this.vistaImmagine = vistaImmagine; - this.circo = circo; + int tagFileType = 0; // setTag deve stare nel thread principale, non nel doInBackground + int imageViewWidth; // idem + ZuppaMedia(ImageView imageView, ProgressBar progress, Media media ) { + this.imageView = imageView; + this.progress = progress; this.media = media; - vistaImmagineWidth = vistaImmagine.getWidth(); + imageViewWidth = imageView.getWidth(); } @Override - protected Bitmap doInBackground(String... parametri) { + protected Bitmap doInBackground(String... params) { Bitmap bitmap; try { - Connection connessione = Jsoup.connect(parametri[0]); + Connection connessione = Jsoup.connect(params[0]); //if (connessione.equals(bitmap)) { // TODO: verifica che un address sia associato all'hostname Document doc = connessione.get(); List lista = doc.select("img"); if( lista.isEmpty() ) { // Pagina web trovata ma senza immagini - tagTipoFile = 3; - url = new URL( parametri[0] ); - return generaIcona( vistaImmagine, R.layout.media_mondo, url.getProtocol() ); // ritorna una bitmap + tagFileType = 3; + url = new URL( params[0] ); + return generaIcona(imageView, R.layout.media_mondo, url.getProtocol() ); // ritorna una bitmap } int maxDimensioniConAlt = 1; int maxDimensioni = 1; @@ -528,12 +530,12 @@ else if( imgSrcLungo != null ) opzioni.inJustDecodeBounds = true; // prende solo le info dell'immagine senza scaricarla BitmapFactory.decodeStream(inputStream, null, opzioni); // Infine cerca di caricare l'immagine vera e propria ridimensionandola - if( opzioni.outWidth > vistaImmagineWidth ) - opzioni.inSampleSize = opzioni.outWidth / (vistaImmagineWidth+1); + if( opzioni.outWidth > imageViewWidth ) + opzioni.inSampleSize = opzioni.outWidth / (imageViewWidth +1); inputStream = url.openConnection().getInputStream(); opzioni.inJustDecodeBounds = false; // Scarica l'immagine bitmap = BitmapFactory.decodeStream( inputStream, null, opzioni ); - tagTipoFile = 1; + tagFileType = 1; } catch( Exception e ) { return null; } @@ -541,126 +543,126 @@ else if( imgSrcLungo != null ) } @Override protected void onPostExecute(Bitmap bitmap) { - vistaImmagine.setTag(R.id.tag_tipo_file, tagTipoFile); + imageView.setTag(R.id.tag_file_type, tagFileType); if( bitmap != null ) { - vistaImmagine.setImageBitmap(bitmap); - vistaImmagine.setTag(R.id.tag_percorso, url.toString()); // usato da Immagine - if( tagTipoFile == 1 ) + imageView.setImageBitmap(bitmap); + imageView.setTag(R.id.tag_percorso, url.toString()); // usato da Immagine + if( tagFileType == 1 ) new ImboscaImmagine(media).execute(url); } - if( circo != null ) // può arrivare molto in ritardo quando la pagina non esiste più - circo.setVisibility(View.GONE); + if( progress != null ) // può arrivare molto in ritardo quando la pagina non esiste più + progress.setVisibility(View.GONE); } } - // Metodi per acquisizione immagini: + // Methods to get images: - // Propone una bella lista di app per acquisire immagini - public static void appAcquisizioneImmagine(Context contesto, Fragment frammento, int codice, MediaContainer contenitore) { - // Richiesta permesso accesso memoria device - int perm = ContextCompat.checkSelfPermission(contesto, Manifest.permission.READ_EXTERNAL_STORAGE); + // Display a list of apps to get images + public static void mediaAppList(Context context, Fragment fragment, int code, MediaContainer container) { + // Request permission to access device memory + int perm = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE); if( perm == PackageManager.PERMISSION_DENIED ) { - if( frammento != null ) { // Galleria - frammento.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, codice); + if( fragment != null ) { // GalleryFragment + fragment.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, code); } else - ActivityCompat.requestPermissions((AppCompatActivity)contesto, - new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, codice); + ActivityCompat.requestPermissions((AppCompatActivity)context, + new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, code); return; } // Colleziona gli intenti utili per acquisire immagini - List listaRisolvi = new ArrayList<>(); - final List listaIntenti = new ArrayList<>(); - // Camere - Intent intentoCamera = new Intent( MediaStore.ACTION_IMAGE_CAPTURE ); - for( ResolveInfo info : contesto.getPackageManager().queryIntentActivities(intentoCamera,0) ) { - Intent finalIntent = new Intent( intentoCamera ); - finalIntent.setComponent( new ComponentName(info.activityInfo.packageName, info.activityInfo.name) ); - listaIntenti.add(finalIntent); - listaRisolvi.add( info ); + List resolveList = new ArrayList<>(); + final List intentList = new ArrayList<>(); + // Cameras + Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + for( ResolveInfo info : context.getPackageManager().queryIntentActivities(cameraIntent, 0) ) { + Intent finalIntent = new Intent(cameraIntent); + finalIntent.setComponent(new ComponentName(info.activityInfo.packageName, info.activityInfo.name)); + intentList.add(finalIntent); + resolveList.add(info); } - // Gallerie - Intent intentoGalleria = new Intent( Intent.ACTION_GET_CONTENT ); - intentoGalleria.setType("image/*"); - String[] mimeTypes = { "image/*", "audio/*", "video/*", "application/*", "text/*" }; + // Galleries + Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT); + galleryIntent.setType("image/*"); + String[] mimeTypes = {"image/*", "audio/*", "video/*", "application/*", "text/*"}; if( Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT ) - mimeTypes[0] = "*/*"; // Altrimenti KitKat non vede gli 'application/*' in Downloads - intentoGalleria.putExtra( Intent.EXTRA_MIME_TYPES, mimeTypes ); - for( ResolveInfo info : contesto.getPackageManager().queryIntentActivities(intentoGalleria,0) ) { - Intent finalIntent = new Intent( intentoGalleria ); + mimeTypes[0] = "*/*"; // Otherwise KitKat does not see the 'application/*' in Downloads + galleryIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes); + for( ResolveInfo info : context.getPackageManager().queryIntentActivities(galleryIntent, 0) ) { + Intent finalIntent = new Intent(galleryIntent); finalIntent.setComponent(new ComponentName(info.activityInfo.packageName, info.activityInfo.name)); - listaIntenti.add( finalIntent ); - listaRisolvi.add( info ); + intentList.add(finalIntent); + resolveList.add(info); } - // Media vuoto - if( Global.settings.expert && codice != 5173 ) { // tranne che per la scelta di file in Immagine - Intent intento = new Intent( contesto, Immagine.class ); - ResolveInfo info = contesto.getPackageManager().resolveActivity( intento, 0 ); - intento.setComponent(new ComponentName(info.activityInfo.packageName,info.activityInfo.name)); - listaIntenti.add( intento ); - listaRisolvi.add( info ); + // Empty media + if( Global.settings.expert && code != 5173 ) { // tranne che per la scelta di file in Immagine + Intent intento = new Intent(context, Immagine.class); + ResolveInfo info = context.getPackageManager().resolveActivity(intento, 0); + intento.setComponent(new ComponentName(info.activityInfo.packageName, info.activityInfo.name)); + intentList.add(intento); + resolveList.add(info); } - new AlertDialog.Builder( contesto ).setAdapter( faiAdattatore( contesto, listaRisolvi ), + new AlertDialog.Builder(context).setAdapter(faiAdattatore(context, resolveList), (dialog, id) -> { - Intent intento = listaIntenti.get(id); + Intent intento = intentList.get(id); // Predispone un Uri in cui mettere la foto scattata dall'app fotocamera if( intento.getAction() != null && intento.getAction().equals(MediaStore.ACTION_IMAGE_CAPTURE) ) { - File dir = contesto.getExternalFilesDir( String.valueOf(Global.settings.openTree) ); + File dir = context.getExternalFilesDir(String.valueOf(Global.settings.openTree)); if( !dir.exists() ) dir.mkdir(); - File fotoFile = fileNomeProgressivo( dir.getAbsolutePath(), "image.jpg" ); + File fotoFile = fileNomeProgressivo(dir.getAbsolutePath(), "image.jpg"); Global.fotoCamera = fotoFile.getAbsolutePath(); // Lo salva per riprenderlo dopo che la foto è stata scattata Uri fotoUri; if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) - fotoUri = FileProvider.getUriForFile( contesto, BuildConfig.APPLICATION_ID + ".provider", fotoFile ); + fotoUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", fotoFile); else // KitKat - fotoUri = Uri.fromFile( fotoFile ); - intento.putExtra( MediaStore.EXTRA_OUTPUT, fotoUri ); + fotoUri = Uri.fromFile(fotoFile); + intento.putExtra(MediaStore.EXTRA_OUTPUT, fotoUri); } if( intento.getComponent().getPackageName().equals("app.familygem") ) { - // Crea un Media vuoto - Media med; - if( codice==4173 || codice==2173 ) { // Media semplice - med = new Media(); - med.setFileTag( "FILE" ); - contenitore.addMedia( med ); - Memoria.aggiungi( med ); + // Create an empty Media + Media media; + if( code == 4173 || code == 2173 ) { // Media semplice + media = new Media(); + media.setFileTag("FILE"); + container.addMedia(media); + Memory.aggiungi(media); } else { // Media condiviso - med = Galleria.nuovoMedia( contenitore ); - Memoria.setPrimo( med ); + media = GalleryFragment.nuovoMedia(container); + Memory.setPrimo(media); } - med.setFile( "" ); - contesto.startActivity( intento ); - U.save( true, Memoria.oggettoCapo() ); - } else if( frammento != null ) - frammento.startActivityForResult( intento, codice ); // Così il risultato ritorna al frammento + media.setFile(""); + context.startActivity(intento); + U.save(true, Memory.oggettoCapo()); + } else if( fragment != null ) + fragment.startActivityForResult( intento, code ); // Così il risultato ritorna al frammento else - ((AppCompatActivity)contesto).startActivityForResult( intento, codice ); + ((AppCompatActivity)context).startActivityForResult( intento, code ); }).show(); } - // Strettamente legato a quello qui sopra - private static ArrayAdapter faiAdattatore(final Context contesto, final List listaRisolvi) { - return new ArrayAdapter(contesto, R.layout.pezzo_app, R.id.intento_titolo, listaRisolvi) { + // Closely related to the method above + private static ArrayAdapter faiAdattatore(final Context context, final List resolveList) { + return new ArrayAdapter(context, R.layout.piece_app, R.id.app_title, resolveList) { @Override - public View getView(int posizione, View vista, ViewGroup genitore) { - View view = super.getView(posizione, vista, genitore); - ResolveInfo info = listaRisolvi.get(posizione); - ImageView image = view.findViewById(R.id.intento_icona); - TextView textview = view.findViewById(R.id.intento_titolo); + public View getView(int position, View view, ViewGroup parent) { + View appView = super.getView(position, view, parent); + ResolveInfo info = resolveList.get(position); + ImageView imageView = appView.findViewById(R.id.app_icon); + TextView textview = appView.findViewById(R.id.app_title); if( info.activityInfo.packageName.equals("app.familygem") ) { - image.setImageResource(R.drawable.image); + imageView.setImageResource(R.drawable.image); textview.setText(R.string.empty_media); } else { - image.setImageDrawable(info.loadIcon(contesto.getPackageManager())); - textview.setText(info.loadLabel(contesto.getPackageManager()).toString()); + imageView.setImageDrawable(info.loadIcon(context.getPackageManager())); + textview.setText(info.loadLabel(context.getPackageManager()).toString()); } - return view; + return appView; } }; } // Salva il file acquisito e propone di ritagliarlo se è un'immagine // ritorna true se apre il dialogo e quindi bisogna bloccare l'aggiornamento dell'attività - static boolean proponiRitaglio( Context contesto, Fragment frammento, Intent data, Media media ) { + public static boolean proponiRitaglio( Context contesto, Fragment frammento, Intent data, Media media ) { // Trova il percorso dell'immagine Uri uri = null; String percorso; @@ -702,45 +704,42 @@ else if( Global.fotoCamera != null ) { } } // Aggiunge il percorso della cartella nel Tree in preferenze - if( Global.settings.getCurrentTree().dirs.add( fileMedia[0].getParent() ) ) // true se ha aggiunto la cartella + if( Global.settings.getCurrentTree().dirs.add(fileMedia[0].getParent()) ) // true se ha aggiunto la cartella Global.settings.save(); // Imposta nel Media il percorso trovato - media.setFile( fileMedia[0].getAbsolutePath() ); + media.setFile(fileMedia[0].getAbsolutePath()); // Se si tratta di un'immagine apre il diaogo di proposta ritaglio - String tipoMime = URLConnection.guessContentTypeFromName( fileMedia[0].getName() ); + String tipoMime = URLConnection.guessContentTypeFromName(fileMedia[0].getName()); if( tipoMime != null && tipoMime.startsWith("image/") ) { - ImageView vistaImmagine = new ImageView( contesto ); - dipingiMedia( media, vistaImmagine, null ); + ImageView vistaImmagine = new ImageView(contesto); + paintMedia(media, vistaImmagine, null); Global.mediaCroppato = media; // Media parcheggiato in attesa di essere aggiornato col nuovo percorso file Global.edited = false; // per non innescare il recreate() che negli Android nuovi non fa comparire l'AlertDialog - new AlertDialog.Builder( contesto ) + new AlertDialog.Builder(contesto) .setView(vistaImmagine) - .setMessage( R.string.want_crop_image ) - .setPositiveButton( R.string.yes, (dialog, id) -> tagliaImmagine( contesto, fileMedia[0], null, frammento ) ) - .setNeutralButton( R.string.no, (dialog, which) -> { - concludiProponiRitaglio( contesto, frammento ); - }).setOnCancelListener( dialog -> { // click fuori dal dialogo - concludiProponiRitaglio( contesto, frammento ); + .setMessage(R.string.want_crop_image) + .setPositiveButton(R.string.yes, (dialog, id) -> tagliaImmagine(contesto, fileMedia[0], null, frammento)) + .setNeutralButton(R.string.no, (dialog, which) -> { + concludiProponiRitaglio(contesto, frammento); + }).setOnCancelListener(dialog -> { // click fuori dal dialogo + concludiProponiRitaglio(contesto, frammento); }).show(); - FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, U.dpToPx(320) ); - vistaImmagine.setLayoutParams( params ); // l'assegnazione delle dimensioni deve venire DOPO la creazione del dialogo + FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, U.dpToPx(320)); + vistaImmagine.setLayoutParams(params); // l'assegnazione delle dimensioni deve venire DOPO la creazione del dialogo return true; } return false; } - // Conclusione negativa della proposta di ritaglio dell'immagine: aggiorna semplicemente la pagina per mostrare l'immagine - static void concludiProponiRitaglio( Context contesto, Fragment frammento ) { - if( frammento instanceof Galleria ) - ((Galleria)frammento).ricrea(); - else if( contesto instanceof Dettaglio ) - ((Dettaglio)contesto).refresh(); - else if( contesto instanceof Individuo ) { - IndividuoMedia indiMedia = (IndividuoMedia) ((AppCompatActivity)contesto).getSupportFragmentManager() - .findFragmentByTag( "android:switcher:" + R.id.schede_persona + ":0" ); - indiMedia.refresh(); - } - Global.edited = true; // per rinfrescare le pagine precedenti + // Negative conclusion of the image cropping proposal: simply refresh the view to show the image + static void concludiProponiRitaglio(Context context, Fragment fragment) { + if( fragment instanceof GalleryFragment ) + ((GalleryFragment)fragment).ricrea(); + else if( context instanceof Dettaglio ) + ((Dettaglio)context).refresh(); + else if( context instanceof ProfileActivity ) + ((ProfileActivity)context).refresh(); + Global.edited = true; // To update previous pages } // Avvia il ritaglio di un'immagine con CropImage @@ -791,18 +790,18 @@ static File fileNomeProgressivo( String dir, String nome ) { } // Conclude la procedura di ritaglio di un'immagine - static void fineRitaglioImmagine( Intent data ) { + public static void fineRitaglioImmagine(Intent data) { CropImage.ActivityResult risultato = CropImage.getActivityResult(data); - Uri uri = risultato.getUri(); // ad es. 'file:///storage/emulated/0/Android/data/app.familygem/files/5/anna.webp' - Picasso.get().invalidate( uri ); // cancella dalla cache l'eventuale immagine prima del ritaglio che ha lo stesso percorso - String percorso = uriPercorsoFile( uri ); - Global.mediaCroppato.setFile( percorso ); + Uri uri = risultato.getUri(); // E.g. 'file:///storage/emulated/0/Android/data/app.familygem/files/5/anna.webp' + Picasso.get().invalidate(uri); // cancella dalla cache l'eventuale immagine prima del ritaglio che ha lo stesso percorso + String percorso = uriPercorsoFile(uri); + Global.mediaCroppato.setFile(percorso); } // Risposta a tutte le richieste di permessi per Android 6+ - static void risultatoPermessi( Context contesto, Fragment frammento, int codice, String[] permessi, int[] accordi, MediaContainer contenitore ) { + public static void risultatoPermessi(Context contesto, Fragment frammento, int codice, String[] permessi, int[] accordi, MediaContainer contenitore) { if( accordi.length > 0 && accordi[0] == PackageManager.PERMISSION_GRANTED ) { - appAcquisizioneImmagine( contesto, frammento, codice, contenitore ); + mediaAppList( contesto, frammento, codice, contenitore ); } else { String permesso = permessi[0].substring(permessi[0].lastIndexOf('.') + 1); Toast.makeText( contesto, contesto.getString(R.string.not_granted,permesso), Toast.LENGTH_LONG ).show(); diff --git a/app/src/main/java/app/familygem/Facciata.java b/app/src/main/java/app/familygem/Facciata.java index 4f0a8b61..fcffd4bb 100644 --- a/app/src/main/java/app/familygem/Facciata.java +++ b/app/src/main/java/app/familygem/Facciata.java @@ -60,7 +60,7 @@ else if( uri.getLastPathSegment().endsWith( ".zip" ) ) // click sulla pagina di scaricaCondiviso( this, dataId, null ); } } else { - Intent treesIntent = new Intent(this, Alberi.class); + Intent treesIntent = new Intent(this, TreesActivity.class); // Open last tree at startup if( Global.settings.loadTree ) { treesIntent.putExtra("apriAlberoAutomaticamente", true); @@ -93,7 +93,7 @@ static void scaricaCondiviso( Context contesto, String idData, View rotella ) { fos.write(data, 0, count); } fos.close(); - if( client.completePendingCommand() && AlberoNuovo.unZip(contesto, percorsoZip, null) ) { + if( client.completePendingCommand() && NewTreeActivity.unZip(contesto, percorsoZip, null) ) { // Se l'albero è stato scaricato con l'install referrer if( Global.settings.referrer != null && Global.settings.referrer.equals(idData) ) { Global.settings.referrer = null; @@ -118,6 +118,6 @@ static void scaricamentoFallito( Context contesto, String messaggio, View rotell if( rotella != null ) ((Activity)contesto).runOnUiThread( () -> rotella.setVisibility( View.GONE ) ); else - contesto.startActivity( new Intent(contesto, Alberi.class) ); + contesto.startActivity( new Intent(contesto, TreesActivity.class) ); } } diff --git a/app/src/main/java/app/familygem/Global.java b/app/src/main/java/app/familygem/Global.java index 257af77f..b23f3a42 100644 --- a/app/src/main/java/app/familygem/Global.java +++ b/app/src/main/java/app/familygem/Global.java @@ -21,7 +21,6 @@ public class Global extends MultiDexApplication { public static String indi; // Id of the selected person displayed across the app public static int familyNum; // Quale famiglia dei genitori mostrare in diagramma, normalmente la 0 static View principalView; - static int ordineMagazzino; public static boolean edited; // C'è stata un'editazione in EditaIndividuo o in Dettaglio e quindi il contenuto delle attività precedenti va aggiornato static boolean daSalvare; // Il contenuto del Gedcom è stato modificato e deve essere salvato public static String fotoCamera; // percorso in cui l'app fotocamera mette la foto scattata @@ -38,6 +37,15 @@ public void onCreate() { } public static void start(Context context) { + // Handle all uncaught exceptions + Thread.setDefaultUncaughtExceptionHandler((thread, e) -> { + if( settings.loadTree ) { + settings.loadTree = false; + settings.save(); + } + Toast.makeText(context, e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); + }); + // Settings File settingsFile = new File(context.getFilesDir(), "settings.json"); // Rename "preferenze.json" to "settings.json" (introduced in version 0.8) File preferenzeFile = new File(context.getFilesDir(), "preferenze.json"); diff --git a/app/src/main/java/app/familygem/InfoAlbero.java b/app/src/main/java/app/familygem/InfoAlbero.java index 3e870b34..d6d4a7b8 100644 --- a/app/src/main/java/app/familygem/InfoAlbero.java +++ b/app/src/main/java/app/familygem/InfoAlbero.java @@ -40,7 +40,7 @@ protected void onCreate(Bundle bundle) { i += "\n\n" + getText(R.string.item_exists_but_file) + "\n" + file.getAbsolutePath(); } else { i += "\n" + getText(R.string.file) + ": " + file.getAbsolutePath(); - gc = Alberi.apriGedcomTemporaneo(treeId, false); + gc = TreesActivity.openTemporaryGedcom(treeId, false); if( gc == null ) i += "\n\n" + getString(R.string.no_useful_data); else { @@ -69,109 +69,109 @@ protected void onCreate(Bundle bundle) { for( Settings.Share share : tree.shares ) { i += "\n" + dataIdVersoData(share.dateId); if( gc.getSubmitter(share.submitter) != null ) - i += " - " + nomeAutore( gc.getSubmitter(share.submitter) ); + i += " - " + submitterName( gc.getSubmitter(share.submitter) ); } } } } - ((TextView)findViewById(R.id.info_statistiche)).setText( i ); + ((TextView)findViewById(R.id.info_statistiche)).setText(i); - Button bottoneHeader = scatola.findViewById( R.id.info_gestisci_testata ); + Button bottoneHeader = scatola.findViewById(R.id.info_gestisci_testata); if( gc != null ) { Header h = gc.getHeader(); - if( h == null) { - bottoneHeader.setText( R.string.create_header ); - bottoneHeader.setOnClickListener( view -> { - gc.setHeader( AlberoNuovo.creaTestata( file.getName() ) ); + if( h == null ) { + bottoneHeader.setText(R.string.create_header); + bottoneHeader.setOnClickListener(view -> { + gc.setHeader(NewTreeActivity.creaTestata(file.getName())); U.saveJson(gc, treeId); recreate(); }); } else { - scatola.findViewById( R.id.info_testata ).setVisibility( View.VISIBLE ); + scatola.findViewById(R.id.info_testata).setVisibility(View.VISIBLE); if( h.getFile() != null ) - poni( getText(R.string.file), h.getFile() ); + poni(getText(R.string.file), h.getFile()); if( h.getCharacterSet() != null ) { - poni( getText(R.string.characrter_set), h.getCharacterSet().getValue() ); - poni( getText(R.string.version), h.getCharacterSet().getVersion() ); + poni(getText(R.string.characrter_set), h.getCharacterSet().getValue()); + poni(getText(R.string.version), h.getCharacterSet().getVersion()); } - spazio(); // uno spazietto - poni( getText(R.string.language), h.getLanguage() ); + spazio(); // uno spazietto + poni(getText(R.string.language), h.getLanguage()); spazio(); - poni( getText(R.string.copyright), h.getCopyright() ); + poni(getText(R.string.copyright), h.getCopyright()); spazio(); - if (h.getGenerator() != null) { - poni( getText(R.string.software), h.getGenerator().getName() != null ? h.getGenerator().getName() : h.getGenerator().getValue() ); - poni( getText(R.string.version), h.getGenerator().getVersion() ); + if( h.getGenerator() != null ) { + poni(getText(R.string.software), h.getGenerator().getName() != null ? h.getGenerator().getName() : h.getGenerator().getValue()); + poni(getText(R.string.version), h.getGenerator().getVersion()); if( h.getGenerator().getGeneratorCorporation() != null ) { - poni( getText(R.string.corporation), h.getGenerator().getGeneratorCorporation().getValue() ); + poni(getText(R.string.corporation), h.getGenerator().getGeneratorCorporation().getValue()); if( h.getGenerator().getGeneratorCorporation().getAddress() != null ) - poni( getText(R.string.address), h.getGenerator().getGeneratorCorporation().getAddress().getDisplayValue() ); // non è male - poni( getText(R.string.telephone), h.getGenerator().getGeneratorCorporation().getPhone() ); - poni( getText(R.string.fax), h.getGenerator().getGeneratorCorporation().getFax() ); + poni(getText(R.string.address), h.getGenerator().getGeneratorCorporation().getAddress().getDisplayValue()); // non è male + poni(getText(R.string.telephone), h.getGenerator().getGeneratorCorporation().getPhone()); + poni(getText(R.string.fax), h.getGenerator().getGeneratorCorporation().getFax()); } spazio(); if( h.getGenerator().getGeneratorData() != null ) { - poni( getText(R.string.source), h.getGenerator().getGeneratorData().getValue() ); - poni( getText(R.string.date), h.getGenerator().getGeneratorData().getDate() ); - poni( getText(R.string.copyright), h.getGenerator().getGeneratorData().getCopyright() ); + poni(getText(R.string.source), h.getGenerator().getGeneratorData().getValue()); + poni(getText(R.string.date), h.getGenerator().getGeneratorData().getDate()); + poni(getText(R.string.copyright), h.getGenerator().getGeneratorData().getCopyright()); } } spazio(); if( h.getSubmitter(gc) != null ) - poni( getText( R.string.submitter ), nomeAutore(h.getSubmitter(gc)) ); // todo: renderlo cliccabile? + poni(getText(R.string.submitter), submitterName(h.getSubmitter(gc))); // todo: renderlo cliccabile? if( gc.getSubmission() != null ) - poni( getText(R.string.submission), gc.getSubmission().getDescription() ); // todo: cliccabile + poni(getText(R.string.submission), gc.getSubmission().getDescription()); // todo: cliccabile spazio(); if( h.getGedcomVersion() != null ) { - poni( getText(R.string.gedcom), h.getGedcomVersion().getVersion() ); - poni( getText(R.string.form), h.getGedcomVersion().getForm() ); + poni(getText(R.string.gedcom), h.getGedcomVersion().getVersion()); + poni(getText(R.string.form), h.getGedcomVersion().getForm()); } - poni( getText(R.string.destination), h.getDestination() ); + poni(getText(R.string.destination), h.getDestination()); spazio(); if( h.getDateTime() != null ) { - poni( getText(R.string.date), h.getDateTime().getValue() ); - poni( getText(R.string.time), h.getDateTime().getTime() ); + poni(getText(R.string.date), h.getDateTime().getValue()); + poni(getText(R.string.time), h.getDateTime().getTime()); } spazio(); - for( Estensione est : U.trovaEstensioni(h) ) { // ogni estensione nella sua riga + for( Estensione est : U.trovaEstensioni(h) ) { // ogni estensione nella sua riga poni( est.nome, est.testo ); } spazio(); - if( righetta != null ) - ((TableLayout)findViewById( R.id.info_tabella ) ).removeView( righetta ); + if( row != null ) + ((TableLayout)findViewById(R.id.info_tabella)).removeView(row); // Bottone per aggiorna l'header GEDCOM coi parametri di Family Gem - bottoneHeader.setOnClickListener( view -> { + bottoneHeader.setOnClickListener(view -> { h.setFile(treeId + ".json"); CharacterSet caratteri = h.getCharacterSet(); if( caratteri == null ) { caratteri = new CharacterSet(); - h.setCharacterSet( caratteri ); + h.setCharacterSet(caratteri); } - caratteri.setValue( "UTF-8" ); - caratteri.setVersion( null ); + caratteri.setValue("UTF-8"); + caratteri.setVersion(null); - Locale loc = new Locale( Locale.getDefault().getLanguage() ); - h.setLanguage( loc.getDisplayLanguage(Locale.ENGLISH) ); + Locale loc = new Locale(Locale.getDefault().getLanguage()); + h.setLanguage(loc.getDisplayLanguage(Locale.ENGLISH)); Generator programma = h.getGenerator(); if( programma == null ) { programma = new Generator(); - h.setGenerator( programma ); + h.setGenerator(programma); } - programma.setValue( "FAMILY_GEM" ); - programma.setName( getString(R.string.app_name) ); + programma.setValue("FAMILY_GEM"); + programma.setName(getString(R.string.app_name)); //programma.setVersion( BuildConfig.VERSION_NAME ); // lo farà salvaJson() - programma.setGeneratorCorporation( null ); + programma.setGeneratorCorporation(null); GedcomVersion versioneGc = h.getGedcomVersion(); if( versioneGc == null ) { versioneGc = new GedcomVersion(); - h.setGedcomVersion( versioneGc ); + h.setGedcomVersion(versioneGc); } - versioneGc.setVersion( "5.5.1" ); - versioneGc.setForm( "LINEAGE-LINKED" ); - h.setDestination( null ); + versioneGc.setVersion("5.5.1"); + versioneGc.setForm("LINEAGE-LINKED"); + h.setDestination(null); U.saveJson(gc, treeId); recreate(); @@ -181,7 +181,7 @@ protected void onCreate(Bundle bundle) { } // Estensioni del Gedcom, ovvero tag non standard di livello 0 zero for( Estensione est : U.trovaEstensioni(gc) ) { - U.metti( scatola, est.nome, est.testo ); + U.metti(scatola, est.nome, est.testo); } } else bottoneHeader.setVisibility(View.GONE); @@ -193,8 +193,8 @@ String dataIdVersoData(String id) { + id.substring(8, 10) + ":" + id.substring(10, 12) + ":" + id.substring(12); } - static String nomeAutore( Submitter autor ) { - String nome = autor.getName(); + public static String submitterName(Submitter submitter) { + String nome = submitter.getName(); if( nome == null ) nome = "[" + Global.context.getString(R.string.no_name) + "]"; else if( nome.isEmpty() ) @@ -202,7 +202,7 @@ else if( nome.isEmpty() ) return nome; } - // Refresh the data displayed below the tree title in Alberi list + // Refresh the data displayed below the tree title in TreesActivity list static void refreshData(Gedcom gedcom, Settings.Tree treeItem) { treeItem.persons = gedcom.getPeople().size(); treeItem.generations = quanteGenerazioni(gedcom, U.getRootId(gedcom, treeItem)); @@ -234,13 +234,13 @@ void poni(CharSequence title, String text) { } } - TableRow righetta; + TableRow row; void spazio() { if( testoMesso ) { - righetta = new TableRow(getApplicationContext()); - View cella = new View(getApplicationContext()); - cella.setBackgroundResource(R.color.primario); - righetta.addView(cella); + row = new TableRow(this); + View cella = new View(this); + cella.setBackgroundResource(R.color.primary); + row.addView(cella); TableRow.LayoutParams param = (TableRow.LayoutParams)cella.getLayoutParams(); param.weight = 1; param.span = 2; @@ -248,7 +248,7 @@ void spazio() { param.topMargin = 5; param.bottomMargin = 5; cella.setLayoutParams(param); - ((TableLayout)findViewById(R.id.info_tabella)).addView(righetta); + ((TableLayout)findViewById(R.id.info_tabella)).addView(row); testoMesso = false; } } diff --git a/app/src/main/java/app/familygem/Memoria.java b/app/src/main/java/app/familygem/Memory.java similarity index 78% rename from app/src/main/java/app/familygem/Memoria.java rename to app/src/main/java/app/familygem/Memory.java index 929c9618..8e3bf64c 100644 --- a/app/src/main/java/app/familygem/Memoria.java +++ b/app/src/main/java/app/familygem/Memory.java @@ -1,5 +1,3 @@ -// Gestisce le pile di oggetti gerarchici per scrivere la bava in Dettaglio - package app.familygem; import org.folg.gedcom.model.Address; @@ -35,41 +33,42 @@ import app.familygem.detail.Nome; import app.familygem.detail.Nota; -public class Memoria { - - static Map classi = new HashMap<>(); - private static final Memoria memoria = new Memoria(); - List lista = new ArrayList<>(); - - Memoria() { - classi.put( Person.class, Individuo.class ); - classi.put( Repository.class, Archivio.class ); - classi.put( RepositoryRef.class, ArchivioRef.class ); - classi.put( Submitter.class, Autore.class ); - classi.put( Change.class, Cambiamenti.class ); - classi.put( SourceCitation.class, CitazioneFonte.class ); - classi.put( GedcomTag.class, Estensione.class ); - classi.put( EventFact.class, Evento.class ); - classi.put( Family.class, Famiglia.class ); - classi.put( Source.class, Fonte.class ); - classi.put( Media.class, Immagine.class ); - classi.put( Address.class, Indirizzo.class ); - classi.put( Name.class, Nome.class ); - classi.put( Note.class, Nota.class ); +// Manager of stacks of hierarchical objects to write breadcrumbs in Detail +public class Memory { + + static Map classes = new HashMap<>(); + private static final Memory memory = new Memory(); + List list = new ArrayList<>(); + + Memory() { + classes.put(Person.class, ProfileActivity.class); + classes.put(Repository.class, Archivio.class); + classes.put(RepositoryRef.class, ArchivioRef.class); + classes.put(Submitter.class, Autore.class); + classes.put(Change.class, Cambiamenti.class); + classes.put(SourceCitation.class, CitazioneFonte.class); + classes.put(GedcomTag.class, Estensione.class); + classes.put(EventFact.class, Evento.class); + classes.put(Family.class, Famiglia.class); + classes.put(Source.class, Fonte.class); + classes.put(Media.class, Immagine.class); + classes.put(Address.class, Indirizzo.class); + classes.put(Name.class, Nome.class); + classes.put(Note.class, Nota.class); } // Restituisce l'ultima pila creata se ce n'è almeno una // oppure ne restituisce una vuota giusto per non restituire null static Pila getPila() { - if( memoria.lista.size() > 0 ) - return memoria.lista.get( memoria.lista.size() - 1 ); + if( memory.list.size() > 0 ) + return memory.list.get( memory.list.size() - 1 ); else return new Pila(); // una pila vuota che non viene aggiunta alla lista } public static Pila addPila() { Pila pila = new Pila(); - memoria.lista.add( pila ); + memory.list.add( pila ); return pila; } @@ -101,7 +100,7 @@ public static Passo aggiungi( Object oggetto ) { // In altre parole mette il primo oggetto senza aggiungere ulteriori pile public static void replacePrimo( Object oggetto ) { String tag = oggetto instanceof Family ? "FAM" : "INDI"; - if( memoria.lista.size() == 0 ) { + if( memory.list.size() == 0 ) { setPrimo( oggetto, tag ); } else { getPila().clear(); @@ -135,20 +134,20 @@ public static Object getOggetto() { return getPila().peek().oggetto; } - static void arretra() { + public static void arretra() { while( getPila().size() > 0 && getPila().lastElement().filotto ) getPila().pop(); if( getPila().size() > 0 ) getPila().pop(); if( getPila().isEmpty() ) - memoria.lista.remove( getPila() ); + memory.list.remove( getPila() ); //stampa("arretra"); } // Quando un oggetto viene eliminato, lo rende null in tutti i passi, // e anche gli oggetti negli eventuali passi seguenti vengono annullati. public static void annullaIstanze( Object oggio ) { - for( Pila pila : memoria.lista ) { + for( Pila pila : memory.list ) { boolean seguente = false; for( Passo passo : pila ) { if( passo.oggetto != null && (passo.oggetto.equals(oggio) || seguente) ) { @@ -162,7 +161,7 @@ public static void annullaIstanze( Object oggio ) { public static void stampa( String intro ) { if( intro != null ) s.l( intro ); - for( Pila pila : memoria.lista ) { + for( Pila pila : memory.list ) { for( Passo passo : pila ) { String filotto = passo.filotto ? "< " : ""; if( passo.tag != null ) diff --git a/app/src/main/java/app/familygem/AlberoNuovo.java b/app/src/main/java/app/familygem/NewTreeActivity.java similarity index 64% rename from app/src/main/java/app/familygem/AlberoNuovo.java rename to app/src/main/java/app/familygem/NewTreeActivity.java index 5e952760..acc9d860 100644 --- a/app/src/main/java/app/familygem/AlberoNuovo.java +++ b/app/src/main/java/app/familygem/NewTreeActivity.java @@ -1,6 +1,5 @@ package app.familygem; -import android.Manifest; import android.app.Activity; import android.app.DownloadManager; import android.content.BroadcastReceiver; @@ -13,10 +12,7 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; @@ -24,13 +20,13 @@ import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.EditText; +import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.google.gson.Gson; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.Locale; @@ -45,88 +41,79 @@ import org.folg.gedcom.parser.JsonParser; import org.folg.gedcom.parser.ModelParser; -public class AlberoNuovo extends BaseActivity { +public class NewTreeActivity extends BaseActivity { - View rotella; + ProgressBar progress; @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); - setContentView(R.layout.albero_nuovo); - rotella = findViewById(R.id.nuovo_circolo); + setContentView(R.layout.new_tree); + progress = findViewById(R.id.new_progress); String referrer = Global.settings.referrer; // Dataid proveniente da una condivisione boolean esisteDataId = referrer != null && referrer.matches("[0-9]{14}"); // Scarica l'albero condiviso - Button scaricaCondiviso = findViewById( R.id.bottone_scarica_condiviso ); + Button scaricaCondiviso = findViewById(R.id.new_download_shared); if( esisteDataId ) // Non ha bisogno di permessi perché scarica e decomprime solo nello storage esterno dell'app - scaricaCondiviso.setOnClickListener( v -> Facciata.scaricaCondiviso(this, referrer, rotella) ); + scaricaCondiviso.setOnClickListener(v -> Facciata.scaricaCondiviso(this, referrer, progress)); else - scaricaCondiviso.setVisibility( View.GONE ); + scaricaCondiviso.setVisibility(View.GONE); - // Crea un albero vuoto - Button alberoVuoto = findViewById( R.id.bottone_albero_vuoto ); + // Create an empty tree + Button emptyTree = findViewById(R.id.new_empty_tree); if( esisteDataId ) { if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) - alberoVuoto.setBackgroundTintList( ColorStateList.valueOf(getResources().getColor(R.color.primarioChiaro)) ); + emptyTree.setBackgroundTintList(ColorStateList.valueOf(getResources().getColor(R.color.primary_light))); } - alberoVuoto.setOnClickListener( v -> { - View vistaMessaggio = LayoutInflater.from(this).inflate(R.layout.albero_nomina, null); + emptyTree.setOnClickListener(v -> { + View dialogView = LayoutInflater.from(this).inflate(R.layout.albero_nomina, null); AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setView( vistaMessaggio ).setTitle( R.string.title ); - TextView vistaTesto = vistaMessaggio.findViewById( R.id.nuovo_nome_testo ); - vistaTesto.setText( R.string.modify_later ); - vistaTesto.setVisibility( View.VISIBLE ); - EditText nuovoNome = vistaMessaggio.findViewById( R.id.nuovo_nome_albero ); - builder.setPositiveButton( R.string.create, (dialog, id) -> newTree(nuovoNome.getText().toString()) ) - .setNeutralButton( R.string.cancel, null ).create().show(); - nuovoNome.setOnEditorActionListener( (view, action, event) -> { + builder.setView(dialogView).setTitle(R.string.title); + TextView textView = dialogView.findViewById(R.id.nuovo_nome_testo); + textView.setText(R.string.modify_later); + textView.setVisibility(View.VISIBLE); + EditText nuovoNome = dialogView.findViewById(R.id.nuovo_nome_albero); + builder.setPositiveButton(R.string.create, (dialog, id) -> newTree(nuovoNome.getText().toString())) + .setNeutralButton(R.string.cancel, null).create().show(); + nuovoNome.setOnEditorActionListener((view, action, event) -> { if( action == EditorInfo.IME_ACTION_DONE ) { - newTree( nuovoNome.getText().toString() ); + newTree(nuovoNome.getText().toString()); return true; // completa le azioni di salva() } return false; // Eventuali altri action che non esistono }); - vistaMessaggio.postDelayed( () -> { + dialogView.postDelayed(() -> { nuovoNome.requestFocus(); - InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); inputMethodManager.showSoftInput(nuovoNome, InputMethodManager.SHOW_IMPLICIT); }, 300); }); - Button scaricaEsempio = findViewById(R.id.bottone_scarica_esempio); - // Non ha bisogno di permessi - scaricaEsempio.setOnClickListener( v -> scaricaEsempio() ); + Button downloadExample = findViewById(R.id.new_download_example); + downloadExample.setOnClickListener(v -> downloadExample()); // It doesn't need permission - Button importaGedcom = findViewById(R.id.bottone_importa_gedcom); - importaGedcom.setOnClickListener( v -> { - int perm = ContextCompat.checkSelfPermission(v.getContext(),Manifest.permission.READ_EXTERNAL_STORAGE); - if( perm == PackageManager.PERMISSION_DENIED ) - ActivityCompat.requestPermissions( (AppCompatActivity)v.getContext(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1390 ); - else if( perm == PackageManager.PERMISSION_GRANTED ) - importaGedcom(); + // Let you choose a GEDCOM file to import + Button importGedcom = findViewById(R.id.new_import_gedcom); + importGedcom.setOnClickListener(v -> { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + // KitKat disables .ged files in the Download folder if the type is 'application/*' + if( Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT ) + intent.setType("*/*"); + else + intent.setType("application/*"); + startActivityForResult(intent, 630); }); - Button recuperaBackup = findViewById(R.id.bottone_recupera_backup); - recuperaBackup.setOnClickListener( v -> { - Intent intent = new Intent( Intent.ACTION_GET_CONTENT ); - intent.setType( "application/zip" ); - startActivityForResult( intent, 219 ); + Button recoverBackup = findViewById(R.id.new_recover_backup); + recoverBackup.setOnClickListener(v -> { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.setType("application/zip"); + startActivityForResult(intent, 219); }); } - // Elabora la risposta alle richieste di permesso - @Override - public void onRequestPermissionsResult( int codice, String[] permessi, int[] accordi ) { // If request is cancelled, the result arrays are empty - super.onRequestPermissionsResult(codice, permessi, accordi); - if( accordi.length > 0 && accordi[0] == PackageManager.PERMISSION_GRANTED ) { - if( codice == 1390 ) { - importaGedcom(); - } - } - } - // Create a brand new tree void newTree(String title) { int num = Global.settings.max() + 1; @@ -148,15 +135,15 @@ void newTree(String title) { Toast.makeText(this, R.string.tree_created, Toast.LENGTH_SHORT).show(); } - // Scarica da Google Drive il file zip dei Simpson nella cache esterna dell'app, quindi senza bisogno di permessi - void scaricaEsempio() { - rotella.setVisibility( View.VISIBLE ); - DownloadManager gestoreScarico = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); - // Evita download multipli - Cursor curso = gestoreScarico.query( new DownloadManager.Query().setFilterByStatus(DownloadManager.STATUS_RUNNING) ); - if( curso.moveToFirst() ) { - curso.close(); - findViewById(R.id.bottone_scarica_esempio).setEnabled(false); + // Download the Simpsons zip file from Google Drive into the app's external cache, so without permissions needed + void downloadExample() { + progress.setVisibility(View.VISIBLE); + DownloadManager downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE); + // Avoid multiple downloads + Cursor cursor = downloadManager.query(new DownloadManager.Query().setFilterByStatus(DownloadManager.STATUS_RUNNING)); + if( cursor.moveToFirst() ) { + cursor.close(); + findViewById(R.id.new_download_example).setEnabled(false); return; } String url = "https://drive.google.com/uc?export=download&id=1FT-60avkxrHv6G62pxXs9S6Liv5WkkKf"; @@ -164,21 +151,21 @@ void scaricaEsempio() { File fileZip = new File(percorsoZip); if( fileZip.exists() ) fileZip.delete(); - DownloadManager.Request richiesta = new DownloadManager.Request( Uri.parse( url ) ) - .setTitle( getString(R.string.simpsons_tree) ) - .setDescription( getString(R.string.family_gem_example) ) - .setMimeType( "application/zip" ) - .setNotificationVisibility( DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) - .setDestinationUri( Uri.parse( "file://" + percorsoZip ) ); - gestoreScarico.enqueue( richiesta ); + DownloadManager.Request richiesta = new DownloadManager.Request(Uri.parse(url)) + .setTitle(getString(R.string.simpsons_tree)) + .setDescription(getString(R.string.family_gem_example)) + .setMimeType("application/zip") + .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) + .setDestinationUri(Uri.parse("file://" + percorsoZip)); + downloadManager.enqueue(richiesta); BroadcastReceiver alCompletamento = new BroadcastReceiver() { @Override - public void onReceive( Context contesto, Intent intento ) { - unZip( contesto, percorsoZip, null ); - unregisterReceiver( this ); + public void onReceive(Context contesto, Intent intento) { + unZip(contesto, percorsoZip, null); + unregisterReceiver(this); } }; - registerReceiver( alCompletamento, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE) ); + registerReceiver(alCompletamento, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); // ACTION_DOWNLOAD_COMPLETE intende il completamento di QUALSIASI download che è in corso, non solo questo. } @@ -234,15 +221,15 @@ else if( zipEntry.getName().equals("settings.json") ) if( zipped.grade == 9 && confronta(context, tree, false) ) { tree.grade = 20; // lo marchia come derivato } - // Il download è avvenuto dal dialogo del referrer in Alberi - if( context instanceof Alberi ) { - Alberi treesPage = (Alberi)context; - treesPage.runOnUiThread( () -> { - treesPage.rotella.setVisibility(View.GONE); - treesPage.aggiornaLista(); + // Il download è avvenuto dal dialogo del referrer in TreesActivity + if( context instanceof TreesActivity ) { + TreesActivity treesActivity = (TreesActivity)context; + treesActivity.runOnUiThread( () -> { + treesActivity.progress.setVisibility(View.GONE); + treesActivity.aggiornaLista(); }); - } else // Albero di esempio (Simpson) o di backup (da Facciata o da AlberoNuovo) - context.startActivity(new Intent(context, Alberi.class)); + } else // Example tree (Simpson) or backup tree (from Facciata or from NewTreeActivity) + context.startActivity(new Intent(context, TreesActivity.class)); Global.settings.save(); U.toast((Activity)context, R.string.tree_imported_ok); return true; @@ -265,24 +252,13 @@ static String updateLanguage(String json) { return json; } - // Fa scegliere un file Gedcom da importare - void importaGedcom() { - Intent intent = new Intent(Intent.ACTION_GET_CONTENT); - // KitKat disabilita i file .ged nella cartella Download se il type è 'application/*' - if( Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT ) - intent.setType("*/*"); - else - intent.setType("application/*"); - startActivityForResult(intent, 630); - } - @Override - protected void onActivityResult( int requestCode, int resultCode, final Intent data ) { - super.onActivityResult( requestCode, resultCode, data ); - // Importa un file Gedcom scelto con SAF + protected void onActivityResult(int requestCode, int resultCode, final Intent data) { + super.onActivityResult(requestCode, resultCode, data); + // Import a Gedcom file chosen with SAF if( resultCode == RESULT_OK && requestCode == 630 ){ try { - // Legge l'input + // Read the input Uri uri = data.getData(); InputStream input = getContentResolver().openInputStream(uri); Gedcom gedcom = new ModelParser().parseGedcom(input); @@ -290,33 +266,33 @@ protected void onActivityResult( int requestCode, int resultCode, final Intent d Toast.makeText(this, R.string.invalid_gedcom, Toast.LENGTH_LONG).show(); return; } - gedcom.createIndexes(); // necessario per poi calcolare le generazioni - // Salva il file Json + gedcom.createIndexes(); // Necessary to calculate the generations + // Save the JSON file int newNumber = Global.settings.max() + 1; PrintWriter printWriter = new PrintWriter(getFilesDir() + "/" + newNumber + ".json"); JsonParser jsonParser = new JsonParser(); printWriter.print(jsonParser.toJson(gedcom)); printWriter.close(); - // Nome albero e percorso della cartella - String percorso = F.uriPercorsoFile(uri); - String nomeAlbero; - String percorsoCartella = null; - if( percorso != null && percorso.lastIndexOf('/') > 0 ) { // è un percorso completo del file gedcom - File fileGedcom = new File(percorso); - percorsoCartella = fileGedcom.getParent(); - nomeAlbero = fileGedcom.getName(); - } else if( percorso != null ) { // È solo il nome del file 'famiglia.ged' - nomeAlbero = percorso; - } else // percorso null - nomeAlbero = getString(R.string.tree) + " " + newNumber; - if( nomeAlbero.lastIndexOf('.') > 0 ) // Toglie l'estensione - nomeAlbero = nomeAlbero.substring(0, nomeAlbero.lastIndexOf('.')); - // Salva le impostazioni in preferenze - String idRadice = U.trovaRadice(gedcom); - Global.settings.aggiungi(new Settings.Tree(newNumber, nomeAlbero, percorsoCartella, - gedcom.getPeople().size(), InfoAlbero.quanteGenerazioni(gedcom, idRadice), idRadice, null, 0)); + // Tree name and folder path + String path = F.uriPercorsoFile(uri); + String treeName; + String folderPath = null; + if( path != null && path.lastIndexOf('/') > 0 ) { // It's a full path to the gedcom file + File fileGedcom = new File(path); + folderPath = fileGedcom.getParent(); + treeName = fileGedcom.getName(); + } else if( path != null ) { // It's just a file name, e.g. 'family.ged' + treeName = path; + } else // Null path + treeName = getString(R.string.tree) + " " + newNumber; + if( treeName.lastIndexOf('.') > 0 ) // Remove the extension + treeName = treeName.substring(0, treeName.lastIndexOf('.')); + // Save the settings + String rootId = U.trovaRadice(gedcom); + Global.settings.aggiungi(new Settings.Tree(newNumber, treeName, folderPath, + gedcom.getPeople().size(), InfoAlbero.quanteGenerazioni(gedcom, rootId), rootId, null, 0)); new Notifier(this, gedcom, newNumber, Notifier.What.CREATE); - // Se necessario propone di mostrare le funzioni avanzate + // If necessary propose to show advanced tools if( !gedcom.getSources().isEmpty() && !Global.settings.expert ) { new AlertDialog.Builder(this).setMessage(R.string.complex_tree_advanced_tools) .setPositiveButton(android.R.string.ok, (dialog, i) -> { @@ -359,9 +335,9 @@ protected void onActivityResult( int requestCode, int resultCode, final Intent d }} */ } else - Toast.makeText(AlberoNuovo.this, R.string.backup_invalid, Toast.LENGTH_LONG).show(); + Toast.makeText(NewTreeActivity.this, R.string.backup_invalid, Toast.LENGTH_LONG).show(); } catch( Exception e ) { - Toast.makeText(AlberoNuovo.this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); + Toast.makeText(NewTreeActivity.this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); } } } diff --git a/app/src/main/java/app/familygem/NotifyReceiver.java b/app/src/main/java/app/familygem/NotifyReceiver.java index 217cbcc2..9b35cb23 100644 --- a/app/src/main/java/app/familygem/NotifyReceiver.java +++ b/app/src/main/java/app/familygem/NotifyReceiver.java @@ -23,7 +23,7 @@ public void onReceive(Context context, Intent intent) { } else { // Create notification - Intent notifyIntent = new Intent(context, Alberi.class) + Intent notifyIntent = new Intent(context, TreesActivity.class) .putExtra(Notifier.TREE_ID_KEY, intent.getIntExtra("treeId", 0)) .putExtra(Notifier.INDI_ID_KEY, intent.getStringExtra("indiId")) .putExtra(Notifier.NOTIFY_ID_KEY, intent.getIntExtra("id", 1)); diff --git a/app/src/main/java/app/familygem/NuovoParente.java b/app/src/main/java/app/familygem/NuovoParente.java index 597ec52c..12094cd8 100644 --- a/app/src/main/java/app/familygem/NuovoParente.java +++ b/app/src/main/java/app/familygem/NuovoParente.java @@ -18,6 +18,7 @@ import org.folg.gedcom.model.Person; import java.util.ArrayList; import java.util.List; +import app.familygem.constant.Choice; public class NuovoParente extends DialogFragment { @@ -96,7 +97,7 @@ else if( voceFamiglia.esistente ) // veicola ad Anagrafe l'intenzione di congiun intento.setClass(getContext(), EditaIndividuo.class); startActivity(intento); } else { // Collega persona esistente - intento.putExtra("anagrafeScegliParente", true); + intento.putExtra(Choice.PERSON, true); intento.setClass(getContext(), Principal.class); if( frammento != null ) frammento.startActivityForResult(intento, 1401); diff --git a/app/src/main/java/app/familygem/Podio.java b/app/src/main/java/app/familygem/Podio.java index f0c9f77a..3fa26b4d 100644 --- a/app/src/main/java/app/familygem/Podio.java +++ b/app/src/main/java/app/familygem/Podio.java @@ -1,4 +1,4 @@ -// Lista dei Submitter (autori) +// List of submitters package app.familygem; @@ -24,77 +24,76 @@ public class Podio extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle stato) { - List listAutori = gc.getSubmitters(); - ((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(listAutori.size() + " " + - getString(listAutori.size() == 1 ? R.string.submitter : R.string.submitters).toLowerCase()); + List submitterList = gc.getSubmitters(); + ((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(submitterList.size() + " " + + getString(submitterList.size() == 1 ? R.string.submitter : R.string.submitters).toLowerCase()); setHasOptionsMenu(true); - View vista = inflater.inflate(R.layout.magazzino, container, false); - LinearLayout scatola = vista.findViewById(R.id.magazzino_scatola); - for( final Submitter autor : listAutori ) { - View vistaPezzo = inflater.inflate(R.layout.magazzino_pezzo, scatola, false); - scatola.addView(vistaPezzo); - ((TextView)vistaPezzo.findViewById(R.id.magazzino_nome)).setText(InfoAlbero.nomeAutore(autor)); - vistaPezzo.findViewById(R.id.magazzino_archivi).setVisibility(View.GONE); + View vista = inflater.inflate(R.layout.scrollview, container, false); + LinearLayout layout = vista.findViewById(R.id.scrollview_layout); + for( final Submitter autor : submitterList ) { + View vistaPezzo = inflater.inflate(R.layout.scrollview_item, layout, false); + layout.addView(vistaPezzo); + ((TextView)vistaPezzo.findViewById(R.id.item_name)).setText(InfoAlbero.submitterName(autor)); + vistaPezzo.findViewById(R.id.item_num).setVisibility(View.GONE); vistaPezzo.setOnClickListener(v -> { - Memoria.setPrimo(autor); + Memory.setPrimo(autor); startActivity(new Intent(getContext(), Autore.class)); }); registerForContextMenu(vistaPezzo); vistaPezzo.setTag(autor); } vista.findViewById(R.id.fab).setOnClickListener(v -> { - nuovoAutore(getContext()); + createSubmitter(getContext()); U.save(true); }); return vista; } - // Elimina un autore + // Delete one submitter // Todo mi sa che andrebbe cercato eventuale SubmitterRef in tutti i record - public static void eliminaAutore(Submitter aut) { - Header testa = gc.getHeader(); - if( testa != null && testa.getSubmitterRef() != null - && testa.getSubmitterRef().equals(aut.getId()) ) { - testa.setSubmitterRef(null); + public static void deleteSubmitter(Submitter submitter) { + Header header = gc.getHeader(); + if( header != null && header.getSubmitterRef() != null + && header.getSubmitterRef().equals(submitter.getId()) ) { + header.setSubmitterRef(null); } - gc.getSubmitters().remove(aut); + gc.getSubmitters().remove(submitter); if( gc.getSubmitters().isEmpty() ) gc.setSubmitters(null); - Memoria.annullaIstanze(aut); + Memory.annullaIstanze(submitter); } - // Crea un Autore nuovo, se riceve un contesto lo apre in modalità editore - static Submitter nuovoAutore(Context contesto) { + // Create a new submitter. Receiving a context open it for editing. + public static Submitter createSubmitter(Context context) { Submitter subm = new Submitter(); subm.setId(U.nuovoId(gc, Submitter.class)); subm.setName(""); U.updateChangeDate(subm); gc.addSubmitter(subm); - if( contesto != null ) { - Memoria.setPrimo(subm); - contesto.startActivity(new Intent(contesto, Autore.class)); + if( context != null ) { + Memory.setPrimo(subm); + context.startActivity(new Intent(context, Autore.class)); } return subm; } - static void autorePrincipale(Submitter subm) { - Header testa = gc.getHeader(); - if( testa == null ) { - testa = AlberoNuovo.creaTestata(Global.settings.openTree + ".json"); - gc.setHeader(testa); + public static void setMainSubmitter(Submitter submitter) { + Header header = gc.getHeader(); + if( header == null ) { + header = NewTreeActivity.creaTestata(Global.settings.openTree + ".json"); + gc.setHeader(header); } - testa.setSubmitterRef(subm.getId()); - U.save(false, subm); + header.setSubmitterRef(submitter.getId()); + U.save(false, submitter); } - // Menu contestuale - Submitter subm; + Submitter submitter; @Override public void onCreateContextMenu(ContextMenu menu, View vista, ContextMenu.ContextMenuInfo info ) { - subm = (Submitter)vista.getTag(); - if( gc.getHeader() == null || gc.getHeader().getSubmitter(gc) == null || !gc.getHeader().getSubmitter(gc).equals(subm) ) + submitter = (Submitter)vista.getTag(); + if( gc.getHeader() == null || gc.getHeader().getSubmitter(gc) == null || !gc.getHeader().getSubmitter(gc).equals(submitter) ) menu.add(0, 0, 0, R.string.make_default); - if( !U.autoreHaCondiviso(subm) ) // può essere eliminato solo se non ha mai condiviso + if( !U.submitterHasShared(submitter) ) // Can be deleted only if he has never shared menu.add(0, 1, 0, R.string.delete); // todo spiegare perché non può essere eliminato? } @@ -102,11 +101,11 @@ public void onCreateContextMenu(ContextMenu menu, View vista, ContextMenu.Contex public boolean onContextItemSelected( MenuItem item ) { switch( item.getItemId() ) { case 0: - autorePrincipale(subm); + setMainSubmitter(submitter); return true; case 1: // Todo conferma elimina - eliminaAutore(subm); + deleteSubmitter(submitter); U.save(false); getActivity().recreate(); return true; diff --git a/app/src/main/java/app/familygem/Principal.java b/app/src/main/java/app/familygem/Principal.java index 25b1f2d1..30968245 100644 --- a/app/src/main/java/app/familygem/Principal.java +++ b/app/src/main/java/app/familygem/Principal.java @@ -24,6 +24,12 @@ import java.util.Arrays; import java.util.List; import java.util.Random; +import app.familygem.constant.Choice; +import app.familygem.list.FamiliesFragment; +import app.familygem.list.GalleryFragment; +import app.familygem.list.NotesFragment; +import app.familygem.list.RepositoriesFragment; +import app.familygem.list.SourcesFragment; import app.familygem.visitor.ListaMedia; import app.familygem.visitor.ListaNote; import static app.familygem.Global.gc; @@ -35,8 +41,8 @@ public class Principal extends AppCompatActivity implements NavigationView.OnNav NavigationView menuPrincipe; List idMenu = Arrays.asList( R.id.nav_diagramma, R.id.nav_persone, R.id.nav_famiglie, R.id.nav_media, R.id.nav_note, R.id.nav_fonti, R.id.nav_archivi, R.id.nav_autore ); - List frammenti = Arrays.asList( Diagram.class, Anagrafe.class, Chiesa.class, - Galleria.class, Quaderno.class, Biblioteca.class, Magazzino.class, Podio.class ); + List frammenti = Arrays.asList( Diagram.class, Anagrafe.class, FamiliesFragment.class, + GalleryFragment.class, NotesFragment.class, SourcesFragment.class, RepositoriesFragment.class, Podio.class ); @Override protected void onCreate(Bundle savedInstanceState) { @@ -48,29 +54,29 @@ protected void onCreate(Bundle savedInstanceState) { scatolissima = findViewById(R.id.scatolissima); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( - this, scatolissima, toolbar, R.string.drawer_open, R.string.drawer_close ); + this, scatolissima, toolbar, R.string.drawer_open, R.string.drawer_close); scatolissima.addDrawerListener(toggle); toggle.syncState(); menuPrincipe = findViewById(R.id.menu); menuPrincipe.setNavigationItemSelectedListener(this); Global.principalView = scatolissima; - U.gedcomSicuro( gc ); + U.gedcomSicuro(gc); furnishMenu(); if( savedInstanceState == null ) { // carica la home solo la prima volta, non ruotando lo schermo Fragment fragment; String backName = null; // Etichetta per individuare diagramma nel backstack dei frammenti - if( getIntent().getBooleanExtra("anagrafeScegliParente",false) ) + if( getIntent().getBooleanExtra(Choice.PERSON, false) ) fragment = new Anagrafe(); - else if( getIntent().getBooleanExtra("galleriaScegliMedia",false) ) - fragment = new Galleria(); - else if( getIntent().getBooleanExtra("bibliotecaScegliFonte",false) ) - fragment = new Biblioteca(); - else if( getIntent().getBooleanExtra("quadernoScegliNota",false) ) - fragment = new Quaderno(); - else if( getIntent().getBooleanExtra("magazzinoScegliArchivio",false) ) - fragment = new Magazzino(); + else if( getIntent().getBooleanExtra(Choice.MEDIA, false) ) + fragment = new GalleryFragment(); + else if( getIntent().getBooleanExtra(Choice.SOURCE, false) ) + fragment = new SourcesFragment(); + else if( getIntent().getBooleanExtra(Choice.NOTE, false) ) + fragment = new NotesFragment(); + else if( getIntent().getBooleanExtra(Choice.REPOSITORY, false) ) + fragment = new RepositoriesFragment(); else { // la normale apertura fragment = new Diagram(); backName = "diagram"; @@ -81,7 +87,7 @@ else if( getIntent().getBooleanExtra("magazzinoScegliArchivio",false) ) menuPrincipe.getHeaderView(0).findViewById(R.id.menu_alberi).setOnClickListener(v -> { scatolissima.closeDrawer(GravityCompat.START); - startActivity(new Intent(Principal.this, Alberi.class)); + startActivity(new Intent(Principal.this, TreesActivity.class)); }); // Nasconde le voci del menu più ostiche @@ -110,24 +116,19 @@ public void onRestart() { if( fragment instanceof Diagram ) { ((Diagram)fragment).forceDraw = true; // Così ridisegna il diagramma } else if( fragment instanceof Anagrafe ) { - // Update persons list - Anagrafe anagrafe = (Anagrafe)fragment; - if( anagrafe.people.size() == 0 ) // Probably it's a Collections.EmptyList - anagrafe.people = gc.getPeople(); // replace it with the real ArrayList - anagrafe.adapter.notifyDataSetChanged(); - anagrafe.arredaBarra(); - } else if( fragment instanceof Chiesa ) { - ((Chiesa)fragment).refresh(Chiesa.What.RELOAD); - } else if( fragment instanceof Galleria ) { - ((Galleria)fragment).ricrea(); - /*} else if( fragment instanceof Quaderno ) { - // Doesn't work to update Quaderno when a note is deleted - ((Quaderno)fragment).adapter.notifyDataSetChanged();*/ + ((Anagrafe)fragment).restart(); + } else if( fragment instanceof FamiliesFragment ) { + ((FamiliesFragment)fragment).refresh(FamiliesFragment.What.RELOAD); + } else if( fragment instanceof GalleryFragment ) { + ((GalleryFragment)fragment).ricrea(); + /*} else if( fragment instanceof NotesFragment ) { + // Doesn't work to update NotesFragment when a note is deleted + ((NotesFragment)fragment).adapter.notifyDataSetChanged();*/ } else { recreate(); // questo dovrebbe andare a scomparire man mano } + furnishMenu(); // To display the Save button and update items count Global.edited = false; - furnishMenu(); // praticamente solo per mostrare il bottone Salva } } @@ -152,7 +153,7 @@ void furnishMenu() { int caso = new Random().nextInt( cercaMedia.lista.size() ); for( Media med : cercaMedia.lista ) if( --caso < 0 ) { // arriva a -1 - F.dipingiMedia( med, imageView, null ); + F.paintMedia( med, imageView, null ); imageView.setVisibility( ImageView.VISIBLE ); break; } @@ -200,24 +201,25 @@ void furnishMenu() { Global.daSalvare = false; Toast.makeText(this, R.string.saved, Toast.LENGTH_SHORT).show(); }); - saveButton.setOnLongClickListener( vista -> { - PopupMenu popup = new PopupMenu(this, vista); + saveButton.setOnLongClickListener(view -> { + PopupMenu popup = new PopupMenu(this, view); popup.getMenu().add(0, 0, 0, R.string.revert); popup.show(); - popup.setOnMenuItemClickListener( item -> { + popup.setOnMenuItemClickListener(item -> { if( item.getItemId() == 0 ) { - Alberi.openGedcom(Global.settings.openTree, false); + TreesActivity.openGedcom(Global.settings.openTree, false); U.qualiGenitoriMostrare(this, null, 0); // Semplicemente ricarica il diagramma scatolissima.closeDrawer(GravityCompat.START); - saveButton.setVisibility(View.GONE); + //saveButton.setVisibility(View.GONE); + Global.edited = false; Global.daSalvare = false; + furnishMenu(); } return true; }); return true; }); - if( Global.daSalvare ) - saveButton.setVisibility( View.VISIBLE ); + saveButton.setVisibility(Global.daSalvare ? View.VISIBLE : View.GONE); } // Evidenzia voce del menu e mostra/nasconde toolbar @@ -242,7 +244,7 @@ public void onBackPressed() { } else { super.onBackPressed(); if( getSupportFragmentManager().getBackStackEntryCount() == 0 ) { - // Fa tornare ad Alberi invece di rivedere il primo diagramma del backstack + // Fa tornare a TreesActivity invece di rivedere il primo diagramma del backstack super.onBackPressed(); } else aggiornaInterfaccia(null); diff --git a/app/src/main/java/app/familygem/Individuo.java b/app/src/main/java/app/familygem/ProfileActivity.java similarity index 73% rename from app/src/main/java/app/familygem/Individuo.java rename to app/src/main/java/app/familygem/ProfileActivity.java index 2c579762..801631f5 100644 --- a/app/src/main/java/app/familygem/Individuo.java +++ b/app/src/main/java/app/familygem/ProfileActivity.java @@ -1,13 +1,17 @@ package app.familygem; import android.content.Intent; +import android.graphics.PorterDuff; +import android.net.Uri; import android.os.Bundle; import com.google.android.material.appbar.CollapsingToolbarLayout; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.tabs.TabLayout; +import androidx.core.content.ContextCompat; import androidx.core.util.Pair; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentPagerAdapter; import androidx.viewpager.widget.ViewPager; import androidx.appcompat.app.AlertDialog; @@ -18,8 +22,11 @@ import android.view.MenuItem; import android.view.SubMenu; import android.view.View; +import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; +import com.squareup.picasso.Picasso; +import com.squareup.picasso.RequestCreator; import com.theartofdev.edmodo.cropper.CropImage; import org.folg.gedcom.model.EventFact; import org.folg.gedcom.model.Family; @@ -33,17 +40,23 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import app.familygem.constant.Choice; import app.familygem.constant.Gender; import app.familygem.detail.CitazioneFonte; import app.familygem.detail.Evento; import app.familygem.detail.Nome; import app.familygem.detail.Nota; +import app.familygem.list.GalleryFragment; +import app.familygem.list.NotesFragment; +import app.familygem.list.SourcesFragment; +import jp.wasabeef.picasso.transformations.BlurTransformation; import static app.familygem.Global.gc; -public class Individuo extends AppCompatActivity { +public class ProfileActivity extends AppCompatActivity { Person one; TabLayout tabLayout; + Fragment[] tabs = new Fragment[3]; String[] mainEventTags = {"BIRT", "BAPM", "RESI", "OCCU", "DEAT", "BURI"}; List> otherEvents; // List of tag + label @@ -51,28 +64,28 @@ public class Individuo extends AppCompatActivity { protected void onCreate(Bundle bundle) { super.onCreate(bundle); U.gedcomSicuro(gc); - one = (Person)Memoria.getOggetto(); - // Se l'app va in background e viene stoppata, 'Memoria' è resettata e quindi 'uno' sarà null + one = (Person)Memory.getOggetto(); + // Se l'app va in background e viene stoppata, 'Memory' è resettata e quindi 'one' sarà null if( one == null && bundle != null ) { one = gc.getPerson(bundle.getString("idUno")); // In bundle è salvato l'id dell'individuo - Memoria.setPrimo(one); // Altrimenti la memoria è senza una pila + Memory.setPrimo(one); // Altrimenti la memoria è senza una pila } if( one == null ) return; // Capita raramente che il bundle non faccia il suo lavoro Global.indi = one.getId(); setContentView(R.layout.individuo); // Barra - Toolbar toolbar = findViewById(R.id.toolbar); + Toolbar toolbar = findViewById(R.id.profile_toolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); // fa comparire la freccia indietro e il menu // Assegna alla vista pagina un adapter che gestisce le tre schede - ViewPager viewPager = findViewById(R.id.schede_persona); + ViewPager viewPager = findViewById(R.id.profile_pager); ImpaginatoreSezioni impaginatoreSezioni = new ImpaginatoreSezioni(); viewPager.setAdapter(impaginatoreSezioni); // arricchisce il tablayout - tabLayout = findViewById(R.id.tabs); + tabLayout = findViewById(R.id.profile_tabs); tabLayout.setupWithViewPager(viewPager); // altrimenti il testo nei TabItem scompare (?!) tabLayout.getTabAt(0).setText(R.string.media); tabLayout.getTabAt(1).setText(R.string.events); @@ -84,7 +97,7 @@ protected void onCreate(Bundle bundle) { viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled( int posizione, // 0 tra la prima e la seconda, 1 tra la seconda e la terza... - float scostamento, // 1->0 a destra, 0->1 a sinistra + float scostamento, // 1 -> 0 a destra, 0 -> 1 a sinistra int positionOffsetPixels ) { if( scostamento > 0 ) fab.hide(); @@ -123,19 +136,18 @@ class ImpaginatoreSezioni extends FragmentPagerAdapter { super( getSupportFragmentManager() ); } - @Override // in realtà non seleziona ma CREA le tre schede - public Fragment getItem( int position ) { - Fragment scheda = new Fragment(); + @Override // in realtà non seleziona ma CREA le tre schede + public Fragment getItem(int position) { if( position == 0 ) - scheda = new IndividuoMedia(); + tabs[0] = new ProfileMediaFragment(); else if( position == 1 ) - scheda = new IndividuoEventi(); + tabs[1] = new ProfileFactsFragment(); else if( position == 2 ) - scheda = new IndividuoFamiliari(); - return scheda; + tabs[2] = new ProfileRelativesFragment(); + return tabs[position]; } - @Override // necessario + @Override public int getCount() { return 3; } @@ -152,34 +164,34 @@ protected void onStart() { return; } - // Tutto ciò che nella pagina può cambiare - TextView idView = findViewById(R.id.persona_id); + // Person ID in the header + TextView idView = findViewById(R.id.profile_id); if( Global.settings.expert ) { idView.setText("INDI " + one.getId()); idView.setOnClickListener(v -> { - U.editId(this, one, ((IndividuoEventi)getTab(1))::refreshId); + U.editId(this, one, this::refresh); }); } else idView.setVisibility(View.GONE); - CollapsingToolbarLayout barraCollasso = findViewById(R.id.toolbar_layout); - barraCollasso.setTitle(U.epiteto(one)); // aggiorna il titolo se il nome viene modificato, ma non lo setta se è una stringa vuota - F.unaFoto(Global.gc, one, findViewById(R.id.persona_foto)); - F.unaFoto(Global.gc, one, findViewById(R.id.persona_sfondo)); + // Person name in the header + CollapsingToolbarLayout toolbarLayout = findViewById(R.id.profile_toolbar_layout); + toolbarLayout.setTitle(U.epiteto(one)); + toolbarLayout.setExpandedTitleTextAppearance(R.style.AppTheme_ExpandedAppBar); + toolbarLayout.setCollapsedTitleTextAppearance(R.style.AppTheme_CollapsedAppBar); + setImages(); if( Global.edited ) { - // Ricostruisce le tre schede ritornando alla pagina - for( int i = 0; i < 3; i++ ) { - Fragment scheda = getTab(i); - if( scheda != null ) { // alla prima creazione dell'activity sono null - getSupportFragmentManager().beginTransaction().detach(scheda).commit(); - getSupportFragmentManager().beginTransaction().attach(scheda).commit(); + // Reload the 3 tabs coming back to the profile + for( Fragment tab : tabs ) { + if( tab != null ) { // At the first activity creation they are null + getSupportFragmentManager().beginTransaction().detach(tab).commit(); + getSupportFragmentManager().beginTransaction().attach(tab).commit(); } - // ToDo tornando indietro dopo una editazione non aggiorna la scheda 0 coi media... } invalidateOptionsMenu(); } // Menu FAB findViewById(R.id.fab).setOnClickListener(vista -> { - PopupMenu popup = new PopupMenu(Individuo.this, vista); + PopupMenu popup = new PopupMenu(this, vista); Menu menu = popup.getMenu(); switch( tabLayout.getSelectedTabPosition() ) { case 0: // Individuo Media @@ -231,29 +243,29 @@ protected void onStart() { popup.show(); popup.setOnMenuItemClickListener(item -> { CharSequence[] familiari = {getText(R.string.parent), getText(R.string.sibling), getText(R.string.partner), getText(R.string.child)}; - AlertDialog.Builder builder = new AlertDialog.Builder(Individuo.this); + AlertDialog.Builder builder = new AlertDialog.Builder(this); switch( item.getItemId() ) { // Scheda Eventi case 0: break; // Media case 10: // Cerca media locale - F.appAcquisizioneImmagine(Individuo.this, null, 2173, one); + F.mediaAppList(this, null, 2173, one); break; case 11: // Cerca oggetto media - F.appAcquisizioneImmagine(Individuo.this, null, 2174, one); + F.mediaAppList(this, null, 2174, one); break; - case 12: // Collega media in Galleria - Intent inten = new Intent(Individuo.this, Principal.class); - inten.putExtra("galleriaScegliMedia", true); + case 12: // Link media in GalleryFragment + Intent inten = new Intent(this, Principal.class); + inten.putExtra(Choice.MEDIA, true); startActivityForResult(inten, 43614); break; case 20: // Create name Name name = new Name(); name.setValue("//"); one.addName(name); - Memoria.aggiungi(name); - startActivity(new Intent(Individuo.this, Nome.class)); + Memory.aggiungi(name); + startActivity(new Intent(this, Nome.class)); U.save(true, one); break; case 21: // Create sex @@ -266,9 +278,8 @@ protected void onStart() { gender.setValue(sexValues[i]); one.addEventFact(gender); dialog.dismiss(); - IndividuoEventi.aggiornaRuoliConiugali(one); - IndividuoEventi factsTab = (IndividuoEventi)getTab(1); - factsTab.refresh(1); + ProfileFactsFragment.aggiornaRuoliConiugali(one); + refresh(); U.save(true, one); }).show(); break; @@ -276,33 +287,33 @@ protected void onStart() { Note note = new Note(); note.setValue(""); one.addNote(note); - Memoria.aggiungi(note); - startActivity(new Intent(Individuo.this, Nota.class)); + Memory.aggiungi(note); + startActivity(new Intent(this, Nota.class)); // todo? Dettaglio.edita(View vistaValore); U.save(true, one); break; case 23: // Create shared note - Quaderno.newNote(Individuo.this, one); + NotesFragment.newNote(this, one); break; case 24: // Link shared note - Intent intent = new Intent(Individuo.this, Principal.class); - intent.putExtra("quadernoScegliNota", true); + Intent intent = new Intent(this, Principal.class); + intent.putExtra(Choice.NOTE, true); startActivityForResult(intent, 4074); break; case 25: // Nuova fonte-nota SourceCitation citaz = new SourceCitation(); citaz.setValue(""); one.addSourceCitation(citaz); - Memoria.aggiungi(citaz); - startActivity(new Intent(Individuo.this, CitazioneFonte.class)); + Memory.aggiungi(citaz); + startActivity(new Intent(this, CitazioneFonte.class)); U.save(true, one); break; case 26: // Nuova fonte - Biblioteca.nuovaFonte(Individuo.this, one); + SourcesFragment.createNewSource(this, one); break; case 27: // Collega fonte - Intent intento = new Intent(Individuo.this, Principal.class); - intento.putExtra("bibliotecaScegliFonte", true); + Intent intento = new Intent(this, Principal.class); + intento.putExtra(Choice.SOURCE, true); startActivityForResult(intento, 50473); break; // Scheda Familiari @@ -315,7 +326,7 @@ protected void onStart() { Intent intento1 = new Intent(getApplicationContext(), EditaIndividuo.class); intento1.putExtra("idIndividuo", one.getId()); intento1.putExtra("relazione", quale + 1); - if( U.controllaMultiMatrimoni(intento1, Individuo.this, null) ) + if( U.controllaMultiMatrimoni(intento1, this, null) ) return; startActivity(intento1); }).show(); @@ -329,9 +340,9 @@ protected void onStart() { builder.setItems(familiari, (dialog, quale) -> { Intent intento2 = new Intent(getApplication(), Principal.class); intento2.putExtra("idIndividuo", one.getId()); - intento2.putExtra("anagrafeScegliParente", true); + intento2.putExtra(Choice.PERSON, true); intento2.putExtra("relazione", quale + 1); - if( U.controllaMultiMatrimoni(intento2, Individuo.this, null) ) + if( U.controllaMultiMatrimoni(intento2, this, null) ) return; startActivityForResult(intento2, 1401); }).show(); @@ -363,8 +374,8 @@ protected void onStart() { nuovoEvento.setDate(""); } one.addEventFact(nuovoEvento); - Memoria.aggiungi(nuovoEvento); - startActivity(new Intent(Individuo.this, Evento.class)); + Memory.aggiungi(nuovoEvento); + startActivity(new Intent(this, Evento.class)); U.save(true, one); } return true; @@ -372,9 +383,54 @@ protected void onStart() { }); } - // 0:Media, 1:Facts, 2:Relatives - private Fragment getTab(int num) { - return getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.schede_persona + ":" + num); + /* Display an image in the profile header + The blurred background image is displayed in most cases (jpg, png, gif...) + ToDo but not in case of a video preview, or image downloaded from the web with ZuppaMedia */ + void setImages() { + ImageView imageView = findViewById(R.id.profile_image); + Media media = F.oneImage(Global.gc, one, imageView); + // Same image blurred on background + if( media != null ) { + String path = F.percorsoMedia(Global.settings.openTree, media); + Uri uri = null; + if( path == null ) + uri = F.uriMedia(Global.settings.openTree, media); + if( path != null || uri != null ) { + RequestCreator creator; + ImageView backImageView = findViewById(R.id.profile_background); + backImageView.setColorFilter(ContextCompat.getColor( + this, R.color.primary_grayed), PorterDuff.Mode.MULTIPLY); + if( path != null ) + creator = Picasso.get().load("file://" + path); + else + creator = Picasso.get().load(uri); + creator.resize(200, 200).centerCrop() + .transform(new BlurTransformation(Global.context, 5, 1)) + .into(backImageView); + } + } + } + + // Refresh everyting without recreating the activity + public void refresh() { + // Name in the header + CollapsingToolbarLayout toolbarLayout = findViewById(R.id.profile_toolbar_layout); + toolbarLayout.setTitle(U.epiteto(one)); + // Header images + setImages(); + // ID in the header + if( Global.settings.expert ) { + TextView idView = findViewById(R.id.profile_id); + idView.setText("INDI " + one.getId()); + } + // 3 tabs + for( Fragment tab : tabs ) { + if( tab != null ) { + FragmentManager manager = getSupportFragmentManager(); + manager.beginTransaction().detach(tab).commit(); + manager.beginTransaction().attach(tab).commit(); + } + } } @Override @@ -396,7 +452,7 @@ public void onActivityResult( int requestCode, int resultCode, Intent data ) { return; } } else if( requestCode == 2174 ) { // File dalle app in nuovo Media condiviso, con proposta di ritagliarlo - Media media = Galleria.nuovoMedia(one); + Media media = GalleryFragment.nuovoMedia(one); if( F.proponiRitaglio(this, null, data, media) ) { U.save(true, media, one); return; @@ -407,17 +463,17 @@ public void onActivityResult( int requestCode, int resultCode, Intent data ) { U.save(true); // la data di cambio per i Media condivisi viene già salvata nel passaggio precedente // todo passargli Global.mediaCroppato ? return; - } else if( requestCode == 43614 ) { // Media da Galleria + } else if( requestCode == 43614 ) { // Media from GalleryFragment MediaRef rifMedia = new MediaRef(); - rifMedia.setRef( data.getStringExtra("idMedia") ); + rifMedia.setRef( data.getStringExtra("mediaId") ); one.addMediaRef( rifMedia ); } else if( requestCode == 4074 ) { // Nota NoteRef rifNota = new NoteRef(); - rifNota.setRef( data.getStringExtra("idNota") ); + rifNota.setRef( data.getStringExtra("noteId") ); one.addNoteRef( rifNota ); } else if( requestCode == 50473 ) { // Fonte SourceCitation citaz = new SourceCitation(); - citaz.setRef( data.getStringExtra("idFonte") ); + citaz.setRef( data.getStringExtra("sourceId") ); one.addSourceCitation( citaz ); } else if( requestCode == 1401 ) { // Parente Object[] modificati = EditaIndividuo.aggiungiParente( @@ -436,11 +492,10 @@ public void onActivityResult( int requestCode, int resultCode, Intent data ) { @Override public void onBackPressed() { - Memoria.arretra(); + Memory.arretra(); super.onBackPressed(); } - // Menu Opzioni @Override public boolean onCreateOptionsMenu(Menu menu) { menu.add(0, 0, 0, R.string.diagram); diff --git a/app/src/main/java/app/familygem/IndividuoEventi.java b/app/src/main/java/app/familygem/ProfileFactsFragment.java similarity index 80% rename from app/src/main/java/app/familygem/IndividuoEventi.java rename to app/src/main/java/app/familygem/ProfileFactsFragment.java index 763c1a3a..cb2201e8 100644 --- a/app/src/main/java/app/familygem/IndividuoEventi.java +++ b/app/src/main/java/app/familygem/ProfileFactsFragment.java @@ -4,7 +4,6 @@ import android.os.Bundle; import androidx.fragment.app.Fragment; import androidx.appcompat.app.AlertDialog; -import androidx.fragment.app.FragmentManager; import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.MenuItem; @@ -12,7 +11,6 @@ import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; -import com.google.android.material.appbar.CollapsingToolbarLayout; import org.folg.gedcom.model.Address; import org.folg.gedcom.model.EventFact; import org.folg.gedcom.model.Family; @@ -34,10 +32,9 @@ import app.familygem.detail.Nome; import static app.familygem.Global.gc; -public class IndividuoEventi extends Fragment { +public class ProfileFactsFragment extends Fragment { Person one; - private View changeView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -46,37 +43,22 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa LinearLayout layout = vistaEventi.findViewById(R.id.contenuto_scheda); one = gc.getPerson(Global.indi); if( one != null ) { - for( Name nome : one.getNames()) { + for( Name nome : one.getNames() ) { String tit = getString(R.string.name); if( nome.getType() != null && !nome.getType().isEmpty() ) { tit += " (" + TypeView.getTranslatedType(nome.getType(), TypeView.Combo.NAME) + ")"; } - placeEvent(layout, tit, U.nomeCognome(nome, " "), nome); + placeEvent(layout, tit, U.writeFullName(nome, " "), nome); } - for (EventFact fatto : one.getEventsFacts() ) { - String txt = ""; - if( fatto.getValue() != null ) { - if( fatto.getValue().equals("Y") && fatto.getTag()!=null && - ( fatto.getTag().equals("BIRT") || fatto.getTag().equals("CHR") || fatto.getTag().equals("DEAT") ) ) - txt = getString(R.string.yes); - else txt = fatto.getValue(); - txt += "\n"; - } - //if( fatto.getType() != null ) txt += fatto.getType() + "\n"; // Included in event title - if( fatto.getDate() != null ) txt += new Datatore(fatto.getDate()).writeDateLong() + "\n"; - if( fatto.getPlace() != null ) txt += fatto.getPlace() + "\n"; - Address indirizzo = fatto.getAddress(); - if( indirizzo != null ) txt += Dettaglio.writeAddress(indirizzo, true) + "\n"; - if( fatto.getCause() != null ) txt += fatto.getCause(); - if( txt.endsWith("\n") ) txt = txt.substring(0, txt.length() - 1); // Rimuove l'ultimo acapo - placeEvent(layout, writeEventTitle(fatto), txt, fatto); + for( EventFact fact : one.getEventsFacts() ) { + placeEvent(layout, writeEventTitle(fact), writeEventText(fact), fact); } for( Estensione est : U.trovaEstensioni(one) ) { placeEvent(layout, est.nome, est.testo, est.gedcomTag); } U.placeNotes(layout, one, true); U.placeSourceCitations(layout, one); - changeView = U.placeChangeDate(layout, one.getChange()); + U.placeChangeDate(layout, one.getChange()); } } return vistaEventi; @@ -122,6 +104,24 @@ public static String writeEventTitle(EventFact event) { return txt; } + public static String writeEventText(EventFact event) { + String txt = ""; + if( event.getValue() != null ) { + if( event.getValue().equals("Y") && event.getTag()!=null && + ( event.getTag().equals("BIRT") || event.getTag().equals("CHR") || event.getTag().equals("DEAT") ) ) + txt = Global.context.getString(R.string.yes); + else txt = event.getValue(); + txt += "\n"; + } + //if( fatto.getType() != null ) txt += fatto.getType() + "\n"; // Included in event title + if( event.getDate() != null ) txt += new Datatore(event.getDate()).writeDateLong() + "\n"; + if( event.getPlace() != null ) txt += event.getPlace() + "\n"; + Address indirizzo = event.getAddress(); + if( indirizzo != null ) txt += Dettaglio.writeAddress(indirizzo, true) + "\n"; + if( event.getCause() != null ) txt += event.getCause(); + return txt.trim(); + } + private int chosenSex; private void placeEvent(LinearLayout layout, String title, String text, Object object) { View eventView = LayoutInflater.from(layout.getContext()).inflate(R.layout.individuo_eventi_pezzo, layout, false); @@ -152,14 +152,14 @@ private void placeEvent(LinearLayout layout, String title, String text, Object o .setPositiveButton(android.R.string.ok, (dialog, i) -> { Global.settings.expert = true; Global.settings.save(); - Memoria.aggiungi(object); + Memory.aggiungi(object); startActivity(new Intent(getContext(), Nome.class)); }).setNegativeButton(android.R.string.cancel, (dialog, i) -> { - Memoria.aggiungi(object); + Memory.aggiungi(object); startActivity(new Intent(getContext(), Nome.class)); }).show(); } else { - Memoria.aggiungi(object); + Memory.aggiungi(object); startActivity(new Intent(getContext(), Nome.class)); } }); @@ -185,19 +185,19 @@ private void placeEvent(LinearLayout layout, String title, String text, Object o ((EventFact)object).setValue(new ArrayList<>(sexes.keySet()).get(item)); aggiornaRuoliConiugali(one); dialog.dismiss(); - refresh(1); + refresh(); U.save(true, one); }).show()); } else { // All other events U.placeMedia(otherLayout, object, false); eventView.setOnClickListener(v -> { - Memoria.aggiungi(object); + Memory.aggiungi(object); startActivity(new Intent(getContext(), Evento.class)); }); } } else if( object instanceof GedcomTag ) { eventView.setOnClickListener(v -> { - Memoria.aggiungi(object); + Memory.aggiungi(object); startActivity(new Intent(getContext(), app.familygem.detail.Estensione.class)); }); } @@ -267,7 +267,7 @@ public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.Context menu.add(0, 220, 0, R.string.copy); menu.add(0, 221, 0, R.string.delete); } else if( pieceObject instanceof Note ) { - if( ((TextView)view.findViewById(R.id.nota_testo)).getText().length() > 0 ) + if( ((TextView)view.findViewById(R.id.note_text)).getText().length() > 0 ) menu.add(0, 225, 0, R.string.copy); if( ((Note)pieceObject).getId() != null ) menu.add(0, 226, 0, R.string.unlink); @@ -282,7 +282,6 @@ public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.Context public boolean onContextItemSelected(MenuItem item) { List nomi = one.getNames(); List fatti = one.getEventsFacts(); - int cosa = 0; // cosa aggiornare dopo la modifica switch( item.getItemId() ) { // Nome case 200: // Copia nome @@ -294,35 +293,30 @@ public boolean onContextItemSelected(MenuItem item) { case 201: // Sposta su nomi.add(nomi.indexOf(pieceObject) - 1, (Name)pieceObject); nomi.remove(nomi.lastIndexOf(pieceObject)); - cosa = 2; break; case 202: // Sposta giù nomi.add(nomi.indexOf(pieceObject) + 2, (Name)pieceObject); nomi.remove(nomi.indexOf(pieceObject)); - cosa = 2; break; case 203: // Elimina if( U.preserva(pieceObject) ) return false; one.getNames().remove(pieceObject); - Memoria.annullaIstanze(pieceObject); + Memory.annullaIstanze(pieceObject); pieceView.setVisibility(View.GONE); - cosa = 2; break; // Evento generico case 211: // Sposta su fatti.add(fatti.indexOf(pieceObject) - 1, (EventFact)pieceObject); fatti.remove(fatti.lastIndexOf(pieceObject)); - cosa = 1; break; case 212: // Sposta giu fatti.add(fatti.indexOf(pieceObject) + 2, (EventFact)pieceObject); fatti.remove(fatti.indexOf(pieceObject)); - cosa = 1; break; case 213: // todo Conferma elimina one.getEventsFacts().remove(pieceObject); - Memoria.annullaIstanze(pieceObject); + Memory.annullaIstanze(pieceObject); pieceView.setVisibility(View.GONE); break; // Estensione @@ -331,7 +325,7 @@ public boolean onContextItemSelected(MenuItem item) { break; // Nota case 225: // Copia - U.copiaNegliAppunti(getText(R.string.note), ((TextView)pieceView.findViewById(R.id.nota_testo)).getText()); + U.copiaNegliAppunti(getText(R.string.note), ((TextView)pieceView.findViewById(R.id.note_text)).getText()); return true; case 226: // Scollega U.scollegaNota((Note)pieceObject, one, pieceView); @@ -339,7 +333,7 @@ public boolean onContextItemSelected(MenuItem item) { case 227: Object[] capi = U.eliminaNota((Note)pieceObject, pieceView); U.save(true, capi); - refresh(0); + refresh(); return true; // Citazione fonte case 230: // Copia @@ -350,39 +344,19 @@ public boolean onContextItemSelected(MenuItem item) { case 231: // Elimina // todo conferma : Vuoi eliminare questa citazione della fonte? La fonte continuerà ad esistere. one.getSourceCitations().remove(pieceObject); - Memoria.annullaIstanze(pieceObject); + Memory.annullaIstanze(pieceObject); pieceView.setVisibility(View.GONE); break; default: return false; } + refresh(); U.save(true, one); - refresh(cosa); return true; } - // Update person ID in the toolbar and change date - void refreshId() { - TextView idView = getActivity().findViewById(R.id.persona_id); - idView.setText("INDI " + one.getId()); - refresh(1); - } - - // Update content of Facts tab - void refresh(int what) { - if( what == 0 ) { // Only replace change date - LinearLayout layout = getActivity().findViewById(R.id.contenuto_scheda); - if( changeView != null ) - layout.removeView(changeView); - changeView = U.placeChangeDate(layout, one.getChange()); - } else { // Reload the fragment - FragmentManager fragmentManager = requireActivity().getSupportFragmentManager(); - fragmentManager.beginTransaction().detach(this).commit(); - fragmentManager.beginTransaction().attach(this).commit(); - if( what == 2 ) { // Also update person name in toolbar - CollapsingToolbarLayout toolbarLayout = requireActivity().findViewById(R.id.toolbar_layout); - toolbarLayout.setTitle(U.epiteto(one)); - } - } + // Update content + void refresh() { + ((ProfileActivity)requireActivity()).refresh(); } } diff --git a/app/src/main/java/app/familygem/IndividuoMedia.java b/app/src/main/java/app/familygem/ProfileMediaFragment.java similarity index 61% rename from app/src/main/java/app/familygem/IndividuoMedia.java rename to app/src/main/java/app/familygem/ProfileMediaFragment.java index 9bf1aa80..50cbab18 100644 --- a/app/src/main/java/app/familygem/IndividuoMedia.java +++ b/app/src/main/java/app/familygem/ProfileMediaFragment.java @@ -1,9 +1,7 @@ -// Scheda Foto package app.familygem; import android.os.Bundle; import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.view.ContextMenu; @@ -15,28 +13,31 @@ import org.folg.gedcom.model.Media; import org.folg.gedcom.model.MediaContainer; import org.folg.gedcom.model.Person; +import app.familygem.list.GalleryFragment; +import app.familygem.list.GalleryAdapter; import app.familygem.visitor.ListaMediaContenitore; import static app.familygem.Global.gc; -public class IndividuoMedia extends Fragment { +// Profile media tab +public class ProfileMediaFragment extends Fragment { - Person uno; - ListaMediaContenitore visitaMedia; + Person one; + ListaMediaContenitore mediaVisitor; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View vistaMedia = inflater.inflate(R.layout.individuo_scheda, container, false); if( gc != null ) { final LinearLayout scatola = vistaMedia.findViewById(R.id.contenuto_scheda); - uno = gc.getPerson(Global.indi); - if( uno != null ) { - visitaMedia = new ListaMediaContenitore(gc, true); - uno.accept(visitaMedia); + one = gc.getPerson(Global.indi); + if( one != null ) { + mediaVisitor = new ListaMediaContenitore(gc, true); + one.accept(mediaVisitor); RecyclerView griglia = new RecyclerView(scatola.getContext()); griglia.setHasFixedSize(true); RecyclerView.LayoutManager gestoreLayout = new GridLayoutManager(getContext(), 2); griglia.setLayoutManager(gestoreLayout); - AdattatoreGalleriaMedia adattatore = new AdattatoreGalleriaMedia(visitaMedia.listaMedia, true); + GalleryAdapter adattatore = new GalleryAdapter(mediaVisitor.listaMedia, true); griglia.setAdapter(adattatore); scatola.addView(griglia); } @@ -44,14 +45,14 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa return vistaMedia; } - // Menu contestuale + // Context menu Media media; Object container; // Le immagini non sono solo di 'uno', ma anche dei suoi subordinati EventFact, SourceCitation... @Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { media = (Media)view.getTag(R.id.tag_oggetto); container = view.getTag(R.id.tag_contenitore); - if( visitaMedia.listaMedia.size() > 1 && media.getPrimary() == null ) + if( mediaVisitor.listaMedia.size() > 1 && media.getPrimary() == null ) menu.add(0, 0, 0, R.string.primary_media); if( media.getId() != null ) menu.add(0, 1, 0, R.string.unlink); @@ -61,22 +62,22 @@ public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.Context public boolean onContextItemSelected( MenuItem item ) { int id = item.getItemId(); if( id == 0 ) { // Principale - for( ListaMediaContenitore.MedCont medCont : visitaMedia.listaMedia ) // Li resetta tutti poi ne contrassegna uno + for( ListaMediaContenitore.MedCont medCont : mediaVisitor.listaMedia ) // Li resetta tutti poi ne contrassegna uno medCont.media.setPrimary(null); media.setPrimary("Y"); if( media.getId() != null ) // Per aggiornare la data cambiamento nel Media record piuttosto che nella Person U.save(true, media); else - U.save(true, uno); + U.save(true, one); refresh(); return true; } else if( id == 1 ) { // Scollega - Galleria.scollegaMedia(media.getId(), (MediaContainer)container); - U.save(true, uno); + GalleryFragment.scollegaMedia(media.getId(), (MediaContainer)container); + U.save(true, one); refresh(); return true; } else if( id == 2 ) { // Elimina - Object[] capi = Galleria.eliminaMedia(media, null); + Object[] capi = GalleryFragment.eliminaMedia(media, null); U.save(true, capi); refresh(); return true; @@ -84,16 +85,8 @@ public boolean onContextItemSelected( MenuItem item ) { return false; } - // Rinfresca il contenuto del frammento Media + // Refresh the content void refresh() { - // ricarica il fragment - FragmentManager fragmentManager = requireActivity().getSupportFragmentManager(); - fragmentManager.beginTransaction().detach(this).commit(); - fragmentManager.beginTransaction().attach(this).commit(); - F.unaFoto(Global.gc, uno, requireActivity().findViewById(R.id.persona_foto)); - F.unaFoto(Global.gc, uno, requireActivity().findViewById(R.id.persona_sfondo)); - // Scheda eventi - IndividuoEventi tabEventi = (IndividuoEventi)requireActivity().getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.schede_persona + ":1"); - tabEventi.refresh(1); + ((ProfileActivity)requireActivity()).refresh(); } } diff --git a/app/src/main/java/app/familygem/IndividuoFamiliari.java b/app/src/main/java/app/familygem/ProfileRelativesFragment.java similarity index 80% rename from app/src/main/java/app/familygem/IndividuoFamiliari.java rename to app/src/main/java/app/familygem/ProfileRelativesFragment.java index b2a04872..770f8b4b 100644 --- a/app/src/main/java/app/familygem/IndividuoFamiliari.java +++ b/app/src/main/java/app/familygem/ProfileRelativesFragment.java @@ -4,7 +4,6 @@ import android.os.Bundle; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.MenuItem; @@ -20,17 +19,17 @@ import app.familygem.detail.Famiglia; import static app.familygem.Global.gc; -public class IndividuoFamiliari extends Fragment { +public class ProfileRelativesFragment extends Fragment { - private View vistaFamiglia; - Person uno; + private View tabView; + Person one; @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) { - vistaFamiglia = inflater.inflate(R.layout.individuo_scheda, container, false); + tabView = inflater.inflate(R.layout.individuo_scheda, container, false); if( gc != null ) { - uno = gc.getPerson( Global.indi); - if( uno != null ) { + one = gc.getPerson( Global.indi); + if( one != null ) { /* ToDo Mostrare/poter settare nelle famiglie geniotriali il pedigree, in particolare 'adopted' LinearLayout scatola = vistaFamiglia.findViewById( R.id.contenuto_scheda ); for( ParentFamilyRef pfr : uno.getParentFamilyRefs() ) { @@ -41,18 +40,18 @@ public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle s U.metti( scatola, altroTag.nome, altroTag.testo ); } */ // Famiglie di origine: genitori e fratelli - List listaFamiglie = uno.getParentFamilies(gc); + List listaFamiglie = one.getParentFamilies(gc); for( Family famiglia : listaFamiglie ) { for( Person padre : famiglia.getHusbands(gc) ) createCard(padre, Relation.PARENT, famiglia); for( Person madre : famiglia.getWives(gc) ) createCard(madre, Relation.PARENT, famiglia); for( Person fratello : famiglia.getChildren(gc) ) // solo i figli degli stessi due genitori, non i fratellastri - if( !fratello.equals(uno) ) + if( !fratello.equals(one) ) createCard(fratello, Relation.SIBLING, famiglia); } // Fratellastri e sorellastre - for( Family famiglia : uno.getParentFamilies(gc) ) { + for( Family famiglia : one.getParentFamilies(gc) ) { for( Person padre : famiglia.getHusbands(gc) ) { List famigliePadre = padre.getSpouseFamilies(gc); famigliePadre.removeAll(listaFamiglie); @@ -69,12 +68,12 @@ public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle s } } // Coniugi e figli - for( Family family : uno.getSpouseFamilies(gc) ) { + for( Family family : one.getSpouseFamilies(gc) ) { for( Person marito : family.getHusbands(gc) ) - if( !marito.equals(uno) ) + if( !marito.equals(one) ) createCard(marito, Relation.PARTNER, family); for( Person moglie : family.getWives(gc) ) - if( !moglie.equals(uno) ) + if( !moglie.equals(one) ) createCard(moglie, Relation.PARTNER, family); for( Person figlio : family.getChildren(gc) ) { createCard(figlio, Relation.CHILD, family); @@ -82,17 +81,17 @@ public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle s } } } - return vistaFamiglia; + return tabView; } void createCard(final Person person, Relation relation, Family family) { - LinearLayout scatola = vistaFamiglia.findViewById(R.id.contenuto_scheda); + LinearLayout scatola = tabView.findViewById(R.id.contenuto_scheda); View vistaPersona = U.mettiIndividuo(scatola, person, Famiglia.getRole(person, family, relation, false) + Famiglia.writeLineage(person, family)); vistaPersona.setOnClickListener(v -> { getActivity().finish(); // Rimuove l'attività attale dallo stack - Memoria.replacePrimo(person); - Intent intento = new Intent(getContext(), Individuo.class); + Memory.replacePrimo(person); + Intent intento = new Intent(getContext(), ProfileActivity.class); intento.putExtra("scheda", 2); // apre la scheda famiglia startActivity(intento); }); @@ -101,9 +100,9 @@ void createCard(final Person person, Relation relation, Family family) { // ma è usato anche qui sotto per spostare i molteplici matrimoni } - private void spostaRiferimentoFamiglia(int direzione) { - Collections.swap(uno.getSpouseFamilyRefs(), posFam, posFam + direzione); - U.save(true, uno); + private void moveFamilyRef(int direction) { + Collections.swap(one.getSpouseFamilyRefs(), posFam, posFam + direction); + U.save(true, one); refresh(); } @@ -118,8 +117,8 @@ public void onCreateContextMenu( ContextMenu menu, View vista, ContextMenu.Conte person = gc.getPerson(indiId); family = (Family)vista.getTag(R.id.tag_famiglia); posFam = -1; - if( uno.getSpouseFamilyRefs().size() > 1 && !family.getChildren(gc).contains(person) ) { // solo i coniugi, non i figli - List refi = uno.getSpouseFamilyRefs(); + if( one.getSpouseFamilyRefs().size() > 1 && !family.getChildren(gc).contains(person) ) { // solo i coniugi, non i figli + List refi = one.getSpouseFamilyRefs(); for( SpouseFamilyRef sfr : refi ) if( sfr.getRef().equals(family.getId()) ) posFam = refi.indexOf(sfr); @@ -133,13 +132,13 @@ public void onCreateContextMenu( ContextMenu menu, View vista, ContextMenu.Conte menu.add(0, 302, 0, familyLabels[1]); if( posFam > 0 ) menu.add(0, 303, 0, R.string.move_before); - if( posFam >= 0 && posFam < uno.getSpouseFamilyRefs().size() - 1 ) + if( posFam >= 0 && posFam < one.getSpouseFamilyRefs().size() - 1 ) menu.add(0, 304, 0, R.string.move_after); menu.add(0, 305, 0, R.string.modify); if( Famiglia.findParentFamilyRef(person, family) != null ) menu.add(0, 306, 0, R.string.lineage); menu.add(0, 307, 0, R.string.unlink); - if( !person.equals(uno) ) // Qui non può eliminare sè stesso + if( !person.equals(one) ) // Qui non può eliminare sè stesso menu.add(0, 308, 0, R.string.delete); } @@ -153,9 +152,9 @@ public boolean onContextItemSelected(MenuItem item) { } else if( id == 302 ) { // Famiglia come coniuge U.qualiConiugiMostrare(getContext(), person, family); } else if( id == 303 ) { // Sposta su - spostaRiferimentoFamiglia(-1); + moveFamilyRef(-1); } else if( id == 304 ) { // Sposta giù - spostaRiferimentoFamiglia(1); + moveFamilyRef(1); } else if( id == 305 ) { // Modifica Intent intento = new Intent(getContext(), EditaIndividuo.class); intento.putExtra("idIndividuo", indiId); @@ -180,12 +179,8 @@ public boolean onContextItemSelected(MenuItem item) { return true; } - // Rinfresca il contenuto del frammento Familiari + // Refresh the content public void refresh() { - FragmentManager fragmentManager = requireActivity().getSupportFragmentManager(); - fragmentManager.beginTransaction().detach(this).commit(); - fragmentManager.beginTransaction().attach(this).commit(); - requireActivity().invalidateOptionsMenu(); - // todo aggiorna la data cambiamento nella scheda Fatti + ((ProfileActivity)requireActivity()).refresh(); } } diff --git a/app/src/main/java/app/familygem/Settings.java b/app/src/main/java/app/familygem/Settings.java index c7990985..427afee0 100644 --- a/app/src/main/java/app/familygem/Settings.java +++ b/app/src/main/java/app/familygem/Settings.java @@ -25,7 +25,7 @@ public class Settings { // Must be consistent with the 'Global.gc' opened tree. // It is not reset by closing the tree, to be reused by 'Load last opened tree at startup'. boolean autoSave; - boolean loadTree; + boolean loadTree; // At startup load last opened tree public boolean expert; boolean shareAgreement; Diagram diagram; @@ -86,7 +86,7 @@ public void save() { } // The tree currently open - Tree getCurrentTree() { + public Tree getCurrentTree() { for( Tree alb : trees ) { if( alb.id == openTree ) return alb; @@ -146,7 +146,7 @@ Diagram init() { 30 albero derivato da cui sono state estratte tutte le novità OPPURE privo di novità già all'arrivo (grigio). Eliminabile */ - static class Tree { + public static class Tree { int id; String title; Set dirs; @@ -154,7 +154,7 @@ static class Tree { int persons; int generations; int media; - String root; + public String root; List shares; // dati identificativi delle condivisioni attraverso il tempo e lo spazio String shareRoot; // id della Person radice dell'albero in Condivisione int grade; // grado della condivisione diff --git a/app/src/main/java/app/familygem/Alberi.java b/app/src/main/java/app/familygem/TreesActivity.java similarity index 84% rename from app/src/main/java/app/familygem/Alberi.java rename to app/src/main/java/app/familygem/TreesActivity.java index e5adba12..ae88d670 100644 --- a/app/src/main/java/app/familygem/Alberi.java +++ b/app/src/main/java/app/familygem/TreesActivity.java @@ -43,13 +43,13 @@ import java.util.Map; import app.familygem.visitor.ListaMedia; -public class Alberi extends AppCompatActivity { +public class TreesActivity extends AppCompatActivity { - List> elencoAlberi; + List> treeList; SimpleAdapter adapter; - View rotella; + View progress; Fabuloso welcome; - Esportatore esportatore; + Exporter exporter; private boolean autoOpenedTree; // To open automatically the tree at startup only once // The birthday notification IDs are stored to display the corresponding person only once private ArrayList consumedNotifications = new ArrayList<>(); @@ -57,11 +57,11 @@ public class Alberi extends AppCompatActivity { @Override protected void onCreate(Bundle savedState) { super.onCreate(savedState); - setContentView(R.layout.alberi); - ListView vistaLista = findViewById(R.id.lista_alberi); - rotella = findViewById(R.id.alberi_circolo); + setContentView(R.layout.trees); + ListView listView = findViewById(R.id.trees_list); + progress = findViewById(R.id.trees_progress); welcome = new Fabuloso(this, R.string.tap_add_tree); - esportatore = new Esportatore(Alberi.this); + exporter = new Exporter(this); // Al primissimo avvio String referrer = Global.settings.referrer; @@ -72,9 +72,9 @@ else if( referrer != null && referrer.matches("[0-9]{14}") ) { new AlertDialog.Builder(this).setTitle(R.string.a_new_tree) .setMessage(R.string.you_can_download) .setPositiveButton(R.string.download, (dialog, id) -> { - Facciata.scaricaCondiviso(this, referrer, rotella); + Facciata.scaricaCondiviso(this, referrer, progress); }).setNeutralButton(R.string.cancel, null).show(); - } // Se non c'è nessun albero + } // If there is no tree else if( Global.settings.trees.isEmpty() ) welcome.show(); @@ -86,10 +86,10 @@ else if( Global.settings.trees.isEmpty() ) if( Global.settings.trees != null ) { // Lista degli alberi genealogici - elencoAlberi = new ArrayList<>(); + treeList = new ArrayList<>(); // Dà i dati in pasto all'adattatore - adapter = new SimpleAdapter(this, elencoAlberi, + adapter = new SimpleAdapter(this, treeList, R.layout.pezzo_albero, new String[]{"titolo", "dati"}, new int[]{R.id.albero_titolo, R.id.albero_dati}) { @@ -97,48 +97,48 @@ else if( Global.settings.trees.isEmpty() ) @Override public View getView(final int position, View convertView, ViewGroup parent) { View treeView = super.getView(position, convertView, parent); - int treeId = Integer.parseInt(elencoAlberi.get(position).get("id")); + int treeId = Integer.parseInt(treeList.get(position).get("id")); Settings.Tree tree = Global.settings.getTree(treeId); boolean derivato = tree.grade == 20; boolean esaurito = tree.grade == 30; if( derivato ) { - treeView.setBackgroundColor(getResources().getColor(R.color.evidenziaMedio)); + treeView.setBackgroundColor(getResources().getColor(R.color.accent_medium)); ((TextView)treeView.findViewById(R.id.albero_dati)).setTextColor(getResources().getColor(R.color.text)); treeView.setOnClickListener(v -> { - if( !AlberoNuovo.confronta(Alberi.this, tree, true) ) { + if( !NewTreeActivity.confronta(TreesActivity.this, tree, true) ) { tree.grade = 10; // viene retrocesso Global.settings.save(); aggiornaLista(); - Toast.makeText(Alberi.this, R.string.something_wrong, Toast.LENGTH_LONG).show(); + Toast.makeText(TreesActivity.this, R.string.something_wrong, Toast.LENGTH_LONG).show(); } }); } else if( esaurito ) { treeView.setBackgroundColor(getResources().getColor(R.color.consumed)); - ((TextView)treeView.findViewById(R.id.albero_titolo)).setTextColor(getResources().getColor(R.color.grayText)); + ((TextView)treeView.findViewById(R.id.albero_titolo)).setTextColor(getResources().getColor(R.color.gray_text)); treeView.setOnClickListener(v -> { - if( !AlberoNuovo.confronta(Alberi.this, tree, true) ) { + if( !NewTreeActivity.confronta(TreesActivity.this, tree, true) ) { tree.grade = 10; // viene retrocesso Global.settings.save(); aggiornaLista(); - Toast.makeText(Alberi.this, R.string.something_wrong, Toast.LENGTH_LONG).show(); + Toast.makeText(TreesActivity.this, R.string.something_wrong, Toast.LENGTH_LONG).show(); } }); } else { treeView.setBackgroundColor(getResources().getColor(R.color.back_element)); treeView.setOnClickListener(v -> { - rotella.setVisibility(View.VISIBLE); + progress.setVisibility(View.VISIBLE); if( !(Global.gc != null && treeId == Global.settings.openTree) ) { // se non è già aperto if( !openGedcom(treeId, true) ) { - rotella.setVisibility(View.GONE); + progress.setVisibility(View.GONE); return; } } - startActivity(new Intent(Alberi.this, Principal.class)); + startActivity(new Intent(TreesActivity.this, Principal.class)); }); } - treeView.findViewById(R.id.albero_menu).setOnClickListener( vista -> { - boolean esiste = new File( getFilesDir(), treeId + ".json" ).exists(); - PopupMenu popup = new PopupMenu( Alberi.this, vista ); + treeView.findViewById(R.id.albero_menu).setOnClickListener(vista -> { + boolean esiste = new File(getFilesDir(), treeId + ".json").exists(); + PopupMenu popup = new PopupMenu(TreesActivity.this, vista); Menu menu = popup.getMenu(); if( treeId == Global.settings.openTree && Global.daSalvare ) menu.add(0, -1, 0, R.string.save); @@ -170,17 +170,17 @@ public View getView(final int position, View convertView, ViewGroup parent) { Global.daSalvare = false; } else if( id == 0 ) { // Apre un albero derivato openGedcom(treeId, true); - startActivity(new Intent(Alberi.this, Principal.class)); + startActivity(new Intent(TreesActivity.this, Principal.class)); } else if( id == 1 ) { // Info Gedcom - Intent intento = new Intent(Alberi.this, InfoAlbero.class); + Intent intento = new Intent(TreesActivity.this, InfoAlbero.class); intento.putExtra("idAlbero", treeId); startActivity(intento); } else if( id == 2 ) { // Rinomina albero - AlertDialog.Builder builder = new AlertDialog.Builder(Alberi.this); - View vistaMessaggio = getLayoutInflater().inflate(R.layout.albero_nomina, vistaLista, false); + AlertDialog.Builder builder = new AlertDialog.Builder(TreesActivity.this); + View vistaMessaggio = getLayoutInflater().inflate(R.layout.albero_nomina, listView, false); builder.setView(vistaMessaggio).setTitle(R.string.title); EditText editaNome = vistaMessaggio.findViewById(R.id.nuovo_nome_albero); - editaNome.setText(elencoAlberi.get(position).get("titolo")); + editaNome.setText(treeList.get(position).get("titolo")); AlertDialog dialogo = builder.setPositiveButton(R.string.rename, (dialog, i1) -> { Global.settings.rinomina(treeId, editaNome.getText().toString()); aggiornaLista(); @@ -198,40 +198,40 @@ public View getView(final int position, View convertView, ViewGroup parent) { inputMethodManager.showSoftInput(editaNome, InputMethodManager.SHOW_IMPLICIT); }, 300); } else if( id == 3 ) { // Media folders - startActivity(new Intent(Alberi.this, CartelleMedia.class) + startActivity(new Intent(TreesActivity.this, CartelleMedia.class) .putExtra("idAlbero", treeId) ); } else if( id == 4 ) { // Correggi errori findErrors(treeId, false); } else if( id == 5 ) { // Condividi albero - startActivity(new Intent(Alberi.this, Condivisione.class) + startActivity(new Intent(TreesActivity.this, Condivisione.class) .putExtra("idAlbero", treeId) ); } else if( id == 6 ) { // Confronta con alberi esistenti - if( AlberoNuovo.confronta(Alberi.this, tree, false) ) { + if( NewTreeActivity.confronta(TreesActivity.this, tree, false) ) { tree.grade = 20; aggiornaLista(); } else - Toast.makeText(Alberi.this, R.string.no_results, Toast.LENGTH_LONG).show(); + Toast.makeText(TreesActivity.this, R.string.no_results, Toast.LENGTH_LONG).show(); } else if( id == 7 ) { // Esporta Gedcom - if( esportatore.apriAlbero(treeId) ) { + if( exporter.openTree(treeId) ) { String mime = "application/octet-stream"; String ext = "ged"; int code = 636; - if( esportatore.quantiFileMedia() > 0 ) { + if( exporter.quantiFileMedia() > 0 ) { mime = "application/zip"; ext = "zip"; code = 6219; } - F.salvaDocumento(Alberi.this, null, treeId, mime, ext, code); + F.salvaDocumento(TreesActivity.this, null, treeId, mime, ext, code); } } else if( id == 8 ) { // Fai backup - if( esportatore.apriAlbero(treeId) ) - F.salvaDocumento(Alberi.this, null, treeId, "application/zip", "zip", 327); + if( exporter.openTree(treeId) ) + F.salvaDocumento(TreesActivity.this, null, treeId, "application/zip", "zip", 327); } else if( id == 9 ) { // Elimina albero - new AlertDialog.Builder(Alberi.this).setMessage(R.string.really_delete_tree) + new AlertDialog.Builder(TreesActivity.this).setMessage(R.string.really_delete_tree) .setPositiveButton(R.string.delete, (dialog, id1) -> { - deleteTree(Alberi.this, treeId); + deleteTree(TreesActivity.this, treeId); aggiornaLista(); }).setNeutralButton(R.string.cancel, null).show(); } else { @@ -243,31 +243,31 @@ public View getView(final int position, View convertView, ViewGroup parent) { return treeView; } }; - vistaLista.setAdapter(adapter); + listView.setAdapter(adapter); aggiornaLista(); } // Barra personalizzata - ActionBar barra = getSupportActionBar(); - View barraAlberi = getLayoutInflater().inflate(R.layout.alberi_barra, null); - barraAlberi.findViewById(R.id.alberi_opzioni).setOnClickListener(v -> startActivity( - new Intent(Alberi.this, Opzioni.class)) + ActionBar bar = getSupportActionBar(); + View treesBar = getLayoutInflater().inflate(R.layout.trees_bar, null); + treesBar.findViewById(R.id.trees_settings).setOnClickListener(v -> startActivity( + new Intent(this, Opzioni.class)) ); - barra.setCustomView(barraAlberi); - barra.setDisplayShowCustomEnabled(true); + bar.setCustomView(treesBar); + bar.setDisplayShowCustomEnabled(true); // FAB findViewById(R.id.fab).setOnClickListener(v -> { welcome.hide(); - startActivity(new Intent(Alberi.this, AlberoNuovo.class)); + startActivity(new Intent(this, NewTreeActivity.class)); }); // Automatic load of last opened tree of previous session if( !birthdayNotifyTapped(getIntent()) && !autoOpenedTree && getIntent().getBooleanExtra("apriAlberoAutomaticamente", false) && Global.settings.openTree > 0 ) { - vistaLista.post(() -> { + listView.post(() -> { if( openGedcom(Global.settings.openTree, false) ) { - rotella.setVisibility(View.VISIBLE); + progress.setVisibility(View.VISIBLE); autoOpenedTree = true; startActivity(new Intent(this, Principal.class)); } @@ -279,11 +279,11 @@ && getIntent().getBooleanExtra("apriAlberoAutomaticamente", false) && Global.set protected void onResume() { super.onResume(); // Nasconde la rotella, in particolare quando si ritorna indietro a questa activity - rotella.setVisibility(View.GONE); + progress.setVisibility(View.GONE); } - // Essendo Alberi launchMode=singleTask, onRestart viene chiamato anche con startActivity (tranne il primo) - // però ovviamente solo se Alberi ha chiamato onStop (facendo veloce chiama solo onPause) + // Essendo TreesActivity launchMode=singleTask, onRestart viene chiamato anche con startActivity (tranne il primo) + // però ovviamente solo se TreesActivity ha chiamato onStop (facendo veloce chiama solo onPause) @Override protected void onRestart() { super.onRestart(); @@ -311,7 +311,7 @@ private boolean birthdayNotifyTapped(Intent intent) { if( treeId > 0 && !consumedNotifications.contains(notifyId) ) { new Handler().post(() -> { if( openGedcom(treeId, true) ) { - rotella.setVisibility(View.VISIBLE); + progress.setVisibility(View.VISIBLE); Global.indi = intent.getStringExtra(Notifier.INDI_ID_KEY); consumedNotifications.add(notifyId); startActivity(new Intent(this, Principal.class)); @@ -339,12 +339,12 @@ public void onInstallReferrerSetupFinished(int risposta) { String referrer = dettagli.getInstallReferrer(); if( referrer != null && referrer.matches("[0-9]{14}") ) { // It's a dateId Global.settings.referrer = referrer; - new AlertDialog.Builder( Alberi.this ).setTitle( R.string.a_new_tree ) - .setMessage( R.string.you_can_download ) - .setPositiveButton( R.string.download, (dialog, id) -> { - Facciata.scaricaCondiviso( Alberi.this, referrer, rotella ); - }).setNeutralButton( R.string.cancel, (di, id) -> welcome.show() ) - .setOnCancelListener( d -> welcome.show() ).show(); + new AlertDialog.Builder(TreesActivity.this).setTitle(R.string.a_new_tree) + .setMessage(R.string.you_can_download) + .setPositiveButton(R.string.download, (dialog, id) -> { + Facciata.scaricaCondiviso(TreesActivity.this, referrer, progress); + }).setNeutralButton(R.string.cancel, (di, id) -> welcome.show()) + .setOnCancelListener(d -> welcome.show()).show(); } else { // È qualunque altra cosa Global.settings.referrer = null; // lo annulla così non lo cercherà più welcome.show(); @@ -352,7 +352,7 @@ public void onInstallReferrerSetupFinished(int risposta) { Global.settings.save(); irc.endConnection(); } catch( Exception e ) { - U.toast(Alberi.this, e.getLocalizedMessage()); + U.toast(TreesActivity.this, e.getLocalizedMessage()); } break; // App Play Store inesistente sul device o comunque risponde in modo errato @@ -367,13 +367,13 @@ public void onInstallReferrerSetupFinished(int risposta) { @Override public void onInstallReferrerServiceDisconnected() { // Mai visto comparire - U.toast(Alberi.this, "Install Referrer Service Disconnected"); + U.toast(TreesActivity.this, "Install Referrer Service Disconnected"); } }); } void aggiornaLista() { - elencoAlberi.clear(); + treeList.clear(); for( Settings.Tree alb : Global.settings.trees ) { Map dato = new HashMap<>(3); dato.put("id", String.valueOf(alb.id)); @@ -382,7 +382,7 @@ void aggiornaLista() { if( Global.gc != null && Global.settings.openTree == alb.id && alb.persons < 100 ) InfoAlbero.refreshData(Global.gc, alb); dato.put("dati", scriviDati(this, alb)); - elencoAlberi.add(dato); + treeList.add(dato); } adapter.notifyDataSetChanged(); } @@ -398,16 +398,16 @@ static String scriviDati(Context contesto, Settings.Tree alb) { return dati; } - // Apertura del Gedcom temporaneo per estrarne info in Alberi - static Gedcom apriGedcomTemporaneo(int idAlbero, boolean mettiInGlobale) { + // Lightly open a Gedcom tree for different purposes + static Gedcom openTemporaryGedcom(int treeId, boolean putInGlobal) { Gedcom gc; - if( Global.gc != null && Global.settings.openTree == idAlbero ) + if( Global.gc != null && Global.settings.openTree == treeId ) gc = Global.gc; else { - gc = readJson(idAlbero); - if( mettiInGlobale ) { - Global.gc = gc; // per poter usare ad esempio U.unaFoto() - Global.settings.openTree = idAlbero; // così Global.gc e Global.preferenze.idAprendo sono sincronizzati + gc = readJson(treeId); + if( putInGlobal ) { + Global.gc = gc; // To be able to use for example F.oneImage() + Global.settings.openTree = treeId; // So Global.gc and Global.settings.openTree are consistent } } return gc; @@ -491,23 +491,23 @@ static void deleteFilesAndDirs(File fileOrDirectory) { } @Override - public void onActivityResult( int requestCode, int resultCode, Intent data ) { - super.onActivityResult( requestCode, resultCode, data ); + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); if( resultCode == AppCompatActivity.RESULT_OK ) { Uri uri = data.getData(); boolean result = false; if( requestCode == 636 ) { // Esporta il GEDCOM - result = esportatore.esportaGedcom( uri ); + result = exporter.exportGedcom(uri); } else if( requestCode == 6219 ) { // Esporta il GEDCOM zippato coi media - result = esportatore.esportaGedcomZippato( uri ); + result = exporter.exportZippedGedcom(uri); } // Esporta il backup ZIP else if( requestCode == 327 ) { - result = esportatore.esportaBackupZip( null, -1, uri ); + result = exporter.exportZipBackup(null, -1, uri); } if( result ) - Toast.makeText( Alberi.this, esportatore.messaggioSuccesso, Toast.LENGTH_SHORT ).show(); + Toast.makeText(TreesActivity.this, exporter.successMessage, Toast.LENGTH_SHORT).show(); else - Toast.makeText( Alberi.this, esportatore.messaggioErrore, Toast.LENGTH_LONG ).show(); + Toast.makeText(TreesActivity.this, exporter.errorMessage, Toast.LENGTH_LONG).show(); } } @@ -818,4 +818,4 @@ Gedcom findErrors(final int treeId, final boolean correct) { } return gc; } -} \ No newline at end of file +} diff --git a/app/src/main/java/app/familygem/U.java b/app/src/main/java/app/familygem/U.java index 3f1312b4..305103aa 100644 --- a/app/src/main/java/app/familygem/U.java +++ b/app/src/main/java/app/familygem/U.java @@ -1,5 +1,3 @@ -// Static methods used all across the app - package app.familygem; import android.app.Activity; @@ -74,6 +72,7 @@ import org.folg.gedcom.parser.JsonParser; import org.joda.time.Months; import org.joda.time.Years; +import app.familygem.constant.Choice; import app.familygem.constant.Format; import app.familygem.constant.Gender; import app.familygem.detail.ArchivioRef; @@ -84,6 +83,9 @@ import app.familygem.detail.Fonte; import app.familygem.detail.Immagine; import app.familygem.detail.Nota; +import app.familygem.list.FamiliesFragment; +import app.familygem.list.GalleryAdapter; +import app.familygem.list.SourcesFragment; import app.familygem.visitor.ContenitoriMedia; import app.familygem.visitor.ContenitoriNota; import app.familygem.visitor.ListaCitazioniFonte; @@ -91,6 +93,7 @@ import app.familygem.visitor.RiferimentiNota; import app.familygem.visitor.TrovaPila; +// Static methods used all across the app public class U { public static String s(int id) { @@ -100,7 +103,7 @@ public static String s(int id) { // Da usare dove capita che 'Global.gc' possa essere null per ricaricarlo static void gedcomSicuro(Gedcom gc) { if( gc == null ) - Global.gc = Alberi.readJson(Global.settings.openTree); + Global.gc = TreesActivity.readJson(Global.settings.openTree); } // Id of the main person of a GEDCOM or null @@ -115,7 +118,7 @@ static String getRootId(Gedcom gedcom, Settings.Tree tree) { // restituisce l'id della Person iniziale di un Gedcom // Todo Integrate into getRootId(Gedcom,Tree) ??? - static String trovaRadice(Gedcom gc) { + public static String trovaRadice(Gedcom gc) { if( gc.getHeader() != null ) if( valoreTag(gc.getHeader().getExtensions(), "_ROOT") != null ) return valoreTag(gc.getHeader().getExtensions(), "_ROOT"); @@ -125,12 +128,12 @@ static String trovaRadice(Gedcom gc) { } // riceve una Person e restituisce stringa con nome e cognome principale - static String epiteto(Person person) { + public static String epiteto(Person person) { return epiteto(person, false); } - static String epiteto(Person person, boolean twoLines) { + static String epiteto(Person person, boolean multiLines) { if( person != null && !person.getNames().isEmpty() ) - return nomeCognome(person.getNames().get(0), twoLines ? "\n" : " "); + return writeFullName(person.getNames().get(0), multiLines ? "\n" : " "); return "[" + s(R.string.no_name) + "]"; } @@ -162,7 +165,7 @@ else if( !value.isEmpty() ) // Name only } // riceve una Person e restituisce il titolo nobiliare - static String titolo(Person p) { + public static String titolo(Person p) { // GEDCOM standard INDI.TITL for( EventFact ef : p.getEventsFacts() ) if( ef.getTag() != null && ef.getTag().equals("TITL") && ef.getValue() != null ) @@ -174,60 +177,68 @@ static String titolo(Person p) { return ""; } - // Restituisce il nome e cognome addobbato di un Name - static String nomeCognome(Name n, String divider) { - String completo = ""; - if( n.getValue() != null ) { - String grezzo = n.getValue().trim(); + /** + * @param name The Name of a person + * @param divider Can be a space " " or a new line "\n" + * @return The full, decorated name + */ + public static String writeFullName(Name name, String divider) { + String full = ""; + if( name.getValue() != null ) { + String grezzo = name.getValue().trim(); int slashPos = grezzo.indexOf('/'); int lastSlashPos = grezzo.lastIndexOf('/'); if( slashPos > -1 ) // Se c'è un cognome tra '/' - completo = grezzo.substring(0, slashPos).trim(); // nome + full = grezzo.substring(0, slashPos).trim(); // nome else // Oppure è solo nome senza cognome - completo = grezzo; - if( n.getNickname() != null ) - completo += divider + "\"" + n.getNickname() + "\""; + full = grezzo; + if( name.getNickname() != null ) + full += divider + "\"" + name.getNickname() + "\""; if( slashPos < lastSlashPos ) - completo += divider + grezzo.substring(slashPos + 1, lastSlashPos).trim(); // cognome + full += divider + grezzo.substring(slashPos + 1, lastSlashPos).trim(); // cognome if( lastSlashPos > -1 && grezzo.length() - 1 > lastSlashPos ) - completo += " " + grezzo.substring(lastSlashPos + 1).trim(); // dopo il cognome + full += " " + grezzo.substring(lastSlashPos + 1).trim(); // dopo il cognome } else { - if( n.getPrefix() != null ) - completo = n.getPrefix(); - if( n.getGiven() != null ) - completo += " " + n.getGiven(); - if( n.getNickname() != null ) - completo += divider + "\"" + n.getNickname() + "\""; - if( n.getSurname() != null ) - completo += divider + n.getSurname(); - if( n.getSuffix() != null ) - completo += " " + n.getSuffix(); + if( name.getPrefix() != null ) + full = name.getPrefix(); + if( name.getGiven() != null ) + full += " " + name.getGiven(); + if( name.getNickname() != null ) + full += divider + "\"" + name.getNickname() + "\""; + if( name.getSurname() != null ) + full += divider + name.getSurname(); + if( name.getSuffix() != null ) + full += " " + name.getSuffix(); } - completo = completo.trim(); - return completo.isEmpty() ? "[" + s(R.string.empty_name) + "]" : completo; + full = full.trim(); + return full.isEmpty() ? "[" + s(R.string.empty_name) + "]" : full; } // Return the surname of a person, optionally lowercase for comparaison. Can return null. - static String surname(Person person) { + public static String surname(Person person) { return surname(person, false); } - static String surname(Person person, boolean lowerCase) { + public static String surname(Person person, boolean lowerCase) { String surname = null; if( !person.getNames().isEmpty() ) { Name name = person.getNames().get(0); String value = name.getValue(); if( value != null && value.lastIndexOf('/') - value.indexOf('/') > 1 ) //value.indexOf('/') < value.lastIndexOf('/') - surname = value.substring(value.indexOf('/') + 1, value.lastIndexOf('/')); + surname = value.substring(value.indexOf('/') + 1, value.lastIndexOf('/')).trim(); else if( name.getSurname() != null ) - surname = name.getSurname(); + surname = name.getSurname().trim(); + } + if( surname != null ) { + if( surname.isEmpty() ) + return null; + else if( lowerCase ) + surname = surname.toLowerCase(); } - if( lowerCase && surname != null ) - surname = surname.toLowerCase(); return surname; } // Riceve una person e trova se è morto o seppellito - static boolean isDead(Person person) { + public static boolean isDead(Person person) { for( EventFact eventFact : person.getEventsFacts() ) { if( eventFact.getTag().equals("DEAT") || eventFact.getTag().equals("BURI") ) return true; @@ -425,9 +436,9 @@ private static String stripCommas(String place) { return place; } - // Estrae i soli numeri da una stringa che può contenere anche lettere - static int soloNumeri(String id) { - //return Integer.parseInt( id.replaceAll("\\D+","") ); // sintetico ma lento + // Extract only digits from a string that can also contain letters + public static int getNumberOnly(String id) { + //return Integer.parseInt( id.replaceAll("\\D+","") ); // Synthetic but slow int num = 0; int x = 1; for( int i = id.length() - 1; i >= 0; --i ) { @@ -480,7 +491,7 @@ public static String nuovoId(Gedcom gc, Class classe) { private static void calcolaMax(Object oggetto) { try { String idStringa = (String)oggetto.getClass().getMethod("getId").invoke(oggetto); - int num = soloNumeri(idStringa); + int num = getNumberOnly(idStringa); if( num > max ) max = num; } catch( Exception e ) { e.printStackTrace(); @@ -527,7 +538,7 @@ else if( pacco.getRef() != null ) } public static void eliminaEstensione(GedcomTag estensione, Object contenitore, View vista) { - if( contenitore instanceof ExtensionContainer ) { // IndividuoEventi + if( contenitore instanceof ExtensionContainer ) { // ProfileFactsFragment ExtensionContainer exc = (ExtensionContainer)contenitore; @SuppressWarnings("unchecked") List lista = (List)exc.getExtension(ModelParser.MORE_TAGS_EXTENSION_KEY); @@ -542,7 +553,7 @@ public static void eliminaEstensione(GedcomTag estensione, Object contenitore, V if( gt.getChildren().isEmpty() ) gt.setChildren(null); } - Memoria.annullaIstanze(estensione); + Memory.annullaIstanze(estensione); if( vista != null ) vista.setVisibility(View.GONE); } @@ -586,7 +597,7 @@ public static void metti(LinearLayout scatola, String tit, String testo) { // Compone il testo coi dettagli di un individuo e lo mette nella vista testo // inoltre restituisce lo stesso testo per Confrontatore - static String details(Person person, TextView detailsView) { + public static String details(Person person, TextView detailsView) { String dates = twoDates(person, false); String places = twoPlaces(person); if( dates.isEmpty() && places == null && detailsView != null ) { @@ -605,27 +616,27 @@ else if( places != null ) } public static View mettiIndividuo(LinearLayout scatola, Person persona, String ruolo) { - View vistaIndi = LayoutInflater.from(scatola.getContext()).inflate(R.layout.pezzo_individuo, scatola, false); + View vistaIndi = LayoutInflater.from(scatola.getContext()).inflate(R.layout.piece_person, scatola, false); scatola.addView(vistaIndi); - TextView vistaRuolo = vistaIndi.findViewById(R.id.indi_ruolo); + TextView vistaRuolo = vistaIndi.findViewById(R.id.person_info); if( ruolo == null ) vistaRuolo.setVisibility(View.GONE); else vistaRuolo.setText(ruolo); - TextView vistaNome = vistaIndi.findViewById(R.id.indi_nome); + TextView vistaNome = vistaIndi.findViewById(R.id.person_name); String nome = epiteto(persona); if( nome.isEmpty() && ruolo != null ) vistaNome.setVisibility(View.GONE); else vistaNome.setText(nome); - TextView vistaTitolo = vistaIndi.findViewById(R.id.indi_titolo); + TextView vistaTitolo = vistaIndi.findViewById(R.id.person_title); String titolo = titolo(persona); if( titolo.isEmpty() ) vistaTitolo.setVisibility(View.GONE); else vistaTitolo.setText(titolo); - details(persona, vistaIndi.findViewById(R.id.indi_dettagli)); - F.unaFoto(Global.gc, persona, vistaIndi.findViewById(R.id.indi_foto)); + details(persona, vistaIndi.findViewById(R.id.person_details)); + F.oneImage(Global.gc, persona, vistaIndi.findViewById(R.id.person_image)); if( !isDead(persona) ) - vistaIndi.findViewById(R.id.indi_lutto).setVisibility(View.GONE); + vistaIndi.findViewById(R.id.person_mourning).setVisibility(View.GONE); if( Gender.isMale(persona) ) - vistaIndi.findViewById(R.id.indi_bordo).setBackgroundResource(R.drawable.casella_bordo_maschio); + vistaIndi.findViewById(R.id.person_border).setBackgroundResource(R.drawable.casella_bordo_maschio); else if( Gender.isFemale(persona) ) - vistaIndi.findViewById(R.id.indi_bordo).setBackgroundResource(R.drawable.casella_bordo_femmina); + vistaIndi.findViewById(R.id.person_border).setBackgroundResource(R.drawable.casella_bordo_femmina); vistaIndi.setTag(persona.getId()); return vistaIndi; } @@ -640,29 +651,29 @@ public static void placeNotes(LinearLayout layout, Object container, boolean det // Place a single note on a layout, with details or not static void placeNote(final LinearLayout layout, final Note note, boolean detailed) { final Context context = layout.getContext(); - View noteView = LayoutInflater.from(context).inflate(R.layout.pezzo_nota, layout, false); + View noteView = LayoutInflater.from(context).inflate(R.layout.piece_note, layout, false); layout.addView(noteView); - TextView textView = noteView.findViewById(R.id.nota_testo); + TextView textView = noteView.findViewById(R.id.note_text); textView.setText(note.getValue()); int sourceCiteNum = note.getSourceCitations().size(); - TextView sourceCiteView = noteView.findViewById(R.id.nota_fonti); + TextView sourceCiteView = noteView.findViewById(R.id.note_sources); if( sourceCiteNum > 0 && detailed ) sourceCiteView.setText(String.valueOf(sourceCiteNum)); else sourceCiteView.setVisibility(View.GONE); textView.setEllipsize(TextUtils.TruncateAt.END); if( detailed ) { textView.setMaxLines(10); noteView.setTag(R.id.tag_oggetto, note); - if( context instanceof Individuo ) { // Fragment individuoEventi + if( context instanceof ProfileActivity ) { // ProfileFactsFragment ((AppCompatActivity)context).getSupportFragmentManager() - .findFragmentByTag("android:switcher:" + R.id.schede_persona + ":1") // non garantito in futuro + .findFragmentByTag("android:switcher:" + R.id.profile_pager + ":1") // non garantito in futuro .registerForContextMenu(noteView); } else if( layout.getId() != R.id.dispensa_scatola ) // nelle AppCompatActivity tranne che nella dispensa ((AppCompatActivity)context).registerForContextMenu(noteView); noteView.setOnClickListener(v -> { if( note.getId() != null ) - Memoria.setPrimo(note); + Memory.setPrimo(note); else - Memoria.aggiungi(note); + Memory.aggiungi(note); context.startActivity(new Intent(context, Nota.class)); }); } else { @@ -696,15 +707,15 @@ public static Object[] eliminaNota(Note note, View view) { Global.gc.setNotes(null); } else { // LOCAL note new TrovaPila(Global.gc, note); - NoteContainer nc = (NoteContainer)Memoria.oggettoContenitore(); + NoteContainer nc = (NoteContainer)Memory.oggettoContenitore(); nc.getNotes().remove(note); // rimuove solo se è una nota locale, non se object note if( nc.getNotes().isEmpty() ) nc.setNotes(null); capi = new HashSet<>(); - capi.add(Memoria.oggettoCapo()); - Memoria.arretra(); + capi.add(Memory.oggettoCapo()); + Memory.arretra(); } - Memoria.annullaIstanze(note); + Memory.annullaIstanze(note); if( view != null ) view.setVisibility(View.GONE); return capi.toArray(); @@ -712,14 +723,14 @@ public static Object[] eliminaNota(Note note, View view) { // Elenca tutti i media di un oggetto contenitore public static void placeMedia(LinearLayout layout, Object container, boolean detailed) { - RecyclerView griglia = new AdattatoreGalleriaMedia.RiciclaVista(layout.getContext(), detailed); + RecyclerView griglia = new GalleryAdapter.RiciclaVista(layout.getContext(), detailed); griglia.setHasFixedSize(true); RecyclerView.LayoutManager gestoreLayout = new GridLayoutManager(layout.getContext(), detailed ? 2 : 3); griglia.setLayoutManager(gestoreLayout); List listaMedia = new ArrayList<>(); for( Media med : ((MediaContainer)container).getAllMedia(Global.gc) ) listaMedia.add(new ListaMediaContenitore.MedCont(med, container)); - AdattatoreGalleriaMedia adattatore = new AdattatoreGalleriaMedia(listaMedia, detailed); + GalleryAdapter adattatore = new GalleryAdapter(listaMedia, detailed); griglia.setAdapter(adattatore); layout.addView(griglia); } @@ -735,7 +746,7 @@ public static void placeSourceCitations(LinearLayout layout, Object container) { View vistaCita = LayoutInflater.from(layout.getContext()).inflate(R.layout.pezzo_citazione_fonte, layout, false); layout.addView(vistaCita); if( citaz.getSource(Global.gc) != null ) // source CITATION - ((TextView)vistaCita.findViewById(R.id.fonte_testo)).setText(Biblioteca.titoloFonte(citaz.getSource(Global.gc))); + ((TextView)vistaCita.findViewById(R.id.fonte_testo)).setText(SourcesFragment.titoloFonte(citaz.getSource(Global.gc))); else // source NOTE, oppure Citazione di fonte che è stata eliminata vistaCita.findViewById(R.id.citazione_fonte).setVisibility(View.GONE); String t = ""; @@ -751,16 +762,16 @@ public static void placeSourceCitations(LinearLayout layout, Object container) { placeNotes(scatolaAltro, citaz, false); placeMedia(scatolaAltro, citaz, false); vistaCita.setTag(R.id.tag_oggetto, citaz); - if( layout.getContext() instanceof Individuo ) { // Fragment individuoEventi + if( layout.getContext() instanceof ProfileActivity ) { // ProfileFactsFragment ((AppCompatActivity)layout.getContext()).getSupportFragmentManager() - .findFragmentByTag("android:switcher:" + R.id.schede_persona + ":1") + .findFragmentByTag("android:switcher:" + R.id.profile_pager + ":1") .registerForContextMenu(vistaCita); } else // AppCompatActivity ((AppCompatActivity)layout.getContext()).registerForContextMenu(vistaCita); vistaCita.setOnClickListener(v -> { Intent intento = new Intent(layout.getContext(), CitazioneFonte.class); - Memoria.aggiungi(citaz); + Memory.aggiungi(citaz); layout.getContext().startActivity(intento); }); } @@ -793,11 +804,11 @@ else if( source.getAbbreviation() != null ) ((AppCompatActivity)layout.getContext()).registerForContextMenu(vistaFonte); } else { vistaTesto.setMaxLines(2); - txt = Biblioteca.titoloFonte(source); + txt = SourcesFragment.titoloFonte(source); } vistaTesto.setText(txt); vistaFonte.setOnClickListener(v -> { - Memoria.setPrimo(source); + Memory.setPrimo(source); layout.getContext().startActivity(new Intent(layout.getContext(), Fonte.class)); }); } @@ -806,7 +817,7 @@ else if( source.getAbbreviation() != null ) public static View linkaPersona(LinearLayout scatola, Person p, int scheda) { View vistaPersona = LayoutInflater.from(scatola.getContext()).inflate(R.layout.pezzo_individuo_piccolo, scatola, false); scatola.addView(vistaPersona); - F.unaFoto(Global.gc, p, vistaPersona.findViewById(R.id.collega_foto)); + F.oneImage(Global.gc, p, vistaPersona.findViewById(R.id.collega_foto)); ((TextView)vistaPersona.findViewById(R.id.collega_nome)).setText(epiteto(p)); String dati = twoDates(p, false); TextView vistaDettagli = vistaPersona.findViewById(R.id.collega_dati); @@ -819,8 +830,8 @@ public static View linkaPersona(LinearLayout scatola, Person p, int scheda) { else if( Gender.isFemale(p) ) vistaPersona.findViewById(R.id.collega_bordo).setBackgroundResource(R.drawable.casella_bordo_femmina); vistaPersona.setOnClickListener(v -> { - Memoria.setPrimo(p); - Intent intento = new Intent(scatola.getContext(), Individuo.class); + Memory.setPrimo(p); + Intent intento = new Intent(scatola.getContext(), ProfileActivity.class); intento.putExtra("scheda", scheda); scatola.getContext().startActivity(intento); }); @@ -847,11 +858,11 @@ static String testoFamiglia(Context contesto, Gedcom gc, Family fam, boolean una // Usato da dispensa static void linkaFamiglia(LinearLayout scatola, Family fam) { - View vistaFamiglia = LayoutInflater.from(scatola.getContext()).inflate(R.layout.pezzo_famiglia_piccolo, scatola, false); + View vistaFamiglia = LayoutInflater.from(scatola.getContext()).inflate(R.layout.piece_family, scatola, false); scatola.addView(vistaFamiglia); - ((TextView)vistaFamiglia.findViewById(R.id.famiglia_testo)).setText(testoFamiglia(scatola.getContext(), Global.gc, fam, false)); + ((TextView)vistaFamiglia.findViewById(R.id.family_text)).setText(testoFamiglia(scatola.getContext(), Global.gc, fam, false)); vistaFamiglia.setOnClickListener(v -> { - Memoria.setPrimo(fam); + Memory.setPrimo(fam); scatola.getContext().startActivity(new Intent(scatola.getContext(), Famiglia.class)); }); } @@ -860,12 +871,12 @@ static void linkaFamiglia(LinearLayout scatola, Family fam) { static void linkaMedia(LinearLayout scatola, Media media) { View vistaMedia = LayoutInflater.from(scatola.getContext()).inflate(R.layout.pezzo_media, scatola, false); scatola.addView(vistaMedia); - AdattatoreGalleriaMedia.arredaMedia(media, vistaMedia.findViewById(R.id.media_testo), vistaMedia.findViewById(R.id.media_num)); + GalleryAdapter.arredaMedia(media, vistaMedia.findViewById(R.id.media_testo), vistaMedia.findViewById(R.id.media_num)); LinearLayout.LayoutParams parami = (LinearLayout.LayoutParams)vistaMedia.getLayoutParams(); parami.height = dpToPx(80); - F.dipingiMedia(media, vistaMedia.findViewById(R.id.media_img), vistaMedia.findViewById(R.id.media_circolo)); + F.paintMedia(media, vistaMedia.findViewById(R.id.media_img), vistaMedia.findViewById(R.id.media_circolo)); vistaMedia.setOnClickListener(v -> { - Memoria.setPrimo(media); + Memory.setPrimo(media); scatola.getContext().startActivity(new Intent(scatola.getContext(), Immagine.class)); }); } @@ -873,13 +884,13 @@ static void linkaMedia(LinearLayout scatola, Media media) { // Aggiunge un autore al layout static void linkAutore(LinearLayout scatola, Submitter autor) { Context contesto = scatola.getContext(); - View vista = LayoutInflater.from(contesto).inflate(R.layout.pezzo_nota, scatola, false); + View vista = LayoutInflater.from(contesto).inflate(R.layout.piece_note, scatola, false); scatola.addView(vista); - TextView testoNota = vista.findViewById(R.id.nota_testo); + TextView testoNota = vista.findViewById(R.id.note_text); testoNota.setText(autor.getName()); - vista.findViewById(R.id.nota_fonti).setVisibility(View.GONE); + vista.findViewById(R.id.note_sources).setVisibility(View.GONE); vista.setOnClickListener(v -> { - Memoria.setPrimo(autor); + Memory.setPrimo(autor); contesto.startActivity(new Intent(contesto, Autore.class)); }); } @@ -918,7 +929,7 @@ else if( record instanceof Submitter ) } // Aggiunge al layout il pezzo con la data e tempo di Cambiamento - public static View placeChangeDate(final LinearLayout layout, final Change change) { + public static void placeChangeDate(final LinearLayout layout, final Change change) { View changeView = null; if( change != null && Global.settings.expert ) { changeView = LayoutInflater.from(layout.getContext()).inflate(R.layout.pezzo_data_cambiamenti, layout, false); @@ -938,11 +949,10 @@ public static View placeChangeDate(final LinearLayout layout, final Change chang // Grazie al mio contributo la data cambiamento può avere delle note placeNotes(scatolaNote, change, false); changeView.setOnClickListener(v -> { - Memoria.aggiungi(change); + Memory.aggiungi(change); layout.getContext().startActivity(new Intent(layout.getContext(), Cambiamenti.class)); }); } - return changeView; } // Chiede conferma di eliminare un elemento @@ -1029,7 +1039,7 @@ static void saveJson(Gedcom gedcom, int treeId) { new Notifier(Global.context, gedcom, treeId, Notifier.What.DEFAULT); } - static int castJsonInt(Object unknown) { + public static int castJsonInt(Object unknown) { if( unknown instanceof Integer ) return (int)unknown; else return ((JsonPrimitive)unknown).getAsInt(); } @@ -1044,7 +1054,7 @@ static float pxToDp(float pixels) { return pixels / Global.context.getResources().getDisplayMetrics().density; } - static int dpToPx(float dips) { + public static int dpToPx(float dips) { return (int)(dips * Global.context.getResources().getDisplayMetrics().density + 0.5f); } @@ -1066,7 +1076,7 @@ static void autorePrincipale(Context contesto, final String idAutore) { new AlertDialog.Builder(contesto).setMessage(R.string.make_main_submitter) .setPositiveButton(android.R.string.yes, (dialog, id) -> { if( testa[0] == null ) { - testa[0] = AlberoNuovo.creaTestata(Global.settings.openTree + ".json"); + testa[0] = NewTreeActivity.creaTestata(Global.settings.openTree + ".json"); Global.gc.setHeader(testa[0]); } testa[0].setSubmitterRef(idAutore); @@ -1084,15 +1094,16 @@ static Submitter autoreFresco(Gedcom gc) { return null; } - // Verifica se un autore ha partecipato alle condivisioni, per non farlo eliminare - static boolean autoreHaCondiviso(Submitter autore) { - List condivisioni = Global.settings.getCurrentTree().shares; - boolean inviatore = false; - if( condivisioni != null ) - for( Settings.Share share : condivisioni ) - if( autore.getId().equals(share.submitter) ) - inviatore = true; - return inviatore; + // Check if a submitter has participated in the shares + // Used by Podio and Dettaglio to avoid deleting the submitter + public static boolean submitterHasShared(Submitter submitter) { + List shares = Global.settings.getCurrentTree().shares; + boolean shared = false; + if( shares != null ) + for( Settings.Share share : shares ) + if( submitter.getId().equals(share.submitter) ) + shared = true; + return shared; } // Elenco di stringhe dei membri rappresentativi delle famiglie @@ -1132,7 +1143,7 @@ private static void concludiSceltaGenitori(Context contesto, Person perno, int c if( cosaAprire > 0 ) // Viene impostata la famiglia da mostrare Global.familyNum = qualeFamiglia; // normalmente è la 0 if( cosaAprire < 2 ) { // Mostra il diagramma - if( contesto instanceof Principal ) { // Diagram, Anagrafe o Principal stesso + if( contesto instanceof Principal ) { // Diagram, Anagrafe or Principal itself FragmentManager fm = ((AppCompatActivity)contesto).getSupportFragmentManager(); // Nome del frammento precedente nel backstack String previousName = fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 1).getName(); @@ -1145,10 +1156,10 @@ private static void concludiSceltaGenitori(Context contesto, Person perno, int c } else { // Viene mostrata la famiglia Family family = perno.getParentFamilies(Global.gc).get(qualeFamiglia); if( contesto instanceof Famiglia ) { // Passando di Famiglia in Famiglia non accumula attività nello stack - Memoria.replacePrimo(family); + Memory.replacePrimo(family); ((Activity)contesto).recreate(); } else { - Memoria.setPrimo(family); + Memory.setPrimo(family); contesto.startActivity(new Intent(contesto, Famiglia.class)); } } @@ -1169,10 +1180,10 @@ private static void concludiSceltaConiugi(Context contesto, Person perno, Family Global.indi = perno.getId(); famiglia = famiglia == null ? perno.getSpouseFamilies(Global.gc).get(quale) : famiglia; if( contesto instanceof Famiglia ) { - Memoria.replacePrimo(famiglia); + Memory.replacePrimo(famiglia); ((Activity)contesto).recreate(); // Non accumula activity nello stack } else { - Memoria.setPrimo(famiglia); + Memory.setPrimo(famiglia); contesto.startActivity(new Intent(contesto, Famiglia.class)); } } @@ -1256,27 +1267,27 @@ else if( relazione == 4 && famSposi.size() > 1 ) { }).show(); return true; } - // Non avendo trovato una famiglia di perno, dice ad Anagrafe di cercare di collocare perno nella famiglia del destinatario - if( intento.getStringExtra("idFamiglia") == null && intento.getBooleanExtra("anagrafeScegliParente", false) ) + // Not having found a family of pivot, tell Anagrafe to try to place the pivot in the recipient's family + if( intento.getStringExtra("idFamiglia") == null && intento.getBooleanExtra(Choice.PERSON, false) ) intento.putExtra("collocazione", "FAMIGLIA_ESISTENTE"); return false; } // Conclusione della funzione precedente static void concludiMultiMatrimoni(Context contesto, Intent intento, Fragment frammento) { - if( intento.getBooleanExtra("anagrafeScegliParente", false) ) { - // apre Anagrafe + if( intento.getBooleanExtra(Choice.PERSON, false) ) { + // Open Anagrafe if( frammento != null ) frammento.startActivityForResult(intento, 1401); else ((Activity)contesto).startActivityForResult(intento, 1401); - } else // apre EditaIndividuo + } else // Open EditaIndividuo contesto.startActivity(intento); } // Controlla che una o più famiglie siano vuote e propone di eliminarle // 'ancheKo' dice di eseguire 'cheFare' anche cliccando Cancel o fuori dal dialogo - static boolean controllaFamiglieVuote(Context contesto, Runnable cheFare, boolean ancheKo, Family... famiglie) { + public static boolean controllaFamiglieVuote(Context contesto, Runnable cheFare, boolean ancheKo, Family... famiglie) { List vuote = new ArrayList<>(); for( Family fam : famiglie ) { int membri = fam.getHusbandRefs().size() + fam.getWifeRefs().size() + fam.getChildRefs().size(); @@ -1289,7 +1300,7 @@ static boolean controllaFamiglieVuote(Context contesto, Runnable cheFare, boolea new AlertDialog.Builder(contesto).setMessage(R.string.empty_family_delete) .setPositiveButton(android.R.string.yes, (dialog, i) -> { for( Family fam : vuote ) - Chiesa.deleteFamily(fam); // Così capita di salvare più volte insieme... ma vabè + FamiliesFragment.deleteFamily(fam); // Così capita di salvare più volte insieme... ma vabè if( cheFare != null ) cheFare.run(); }).setNeutralButton(android.R.string.cancel, (dialog, i) -> { if( ancheKo ) cheFare.run(); diff --git a/app/src/main/java/app/familygem/constant/Choice.java b/app/src/main/java/app/familygem/constant/Choice.java new file mode 100644 index 00000000..07164241 --- /dev/null +++ b/app/src/main/java/app/familygem/constant/Choice.java @@ -0,0 +1,9 @@ +package app.familygem.constant; + +public class Choice { + public static final String PERSON = "choosePerson"; + public static final String MEDIA = "chooseMedia"; + public static final String NOTE = "chooseNote"; + public static final String SOURCE = "chooseSource"; + public static final String REPOSITORY = "chooseRepo"; +} diff --git a/app/src/main/java/app/familygem/constant/Gender.java b/app/src/main/java/app/familygem/constant/Gender.java index a9d4b673..057294ed 100644 --- a/app/src/main/java/app/familygem/constant/Gender.java +++ b/app/src/main/java/app/familygem/constant/Gender.java @@ -14,7 +14,7 @@ public enum Gender { // Find the gender of a Person public static Gender getGender(Person person) { for( EventFact fact : person.getEventsFacts() ) { - if( fact.getTag() != null && fact.getTag().equals("SEX") ) { + if( "SEX".equals(fact.getTag()) ) { if( fact.getValue() == null ) return OTHER; // There is 'SEX' tag but the value is empty else { diff --git a/app/src/main/java/app/familygem/detail/Archivio.java b/app/src/main/java/app/familygem/detail/Archivio.java index ba020286..285b7d90 100644 --- a/app/src/main/java/app/familygem/detail/Archivio.java +++ b/app/src/main/java/app/familygem/detail/Archivio.java @@ -6,7 +6,7 @@ import java.util.List; import app.familygem.Dettaglio; import app.familygem.Global; -import app.familygem.Magazzino; +import app.familygem.list.RepositoriesFragment; import app.familygem.R; import app.familygem.U; @@ -43,6 +43,6 @@ public void impagina() { @Override public void elimina() { - U.updateChangeDate((Object[])Magazzino.delete(a)); + U.updateChangeDate((Object[])RepositoriesFragment.delete(a)); } } diff --git a/app/src/main/java/app/familygem/detail/ArchivioRef.java b/app/src/main/java/app/familygem/detail/ArchivioRef.java index a595c201..ad48f6ea 100644 --- a/app/src/main/java/app/familygem/detail/ArchivioRef.java +++ b/app/src/main/java/app/familygem/detail/ArchivioRef.java @@ -11,7 +11,7 @@ import org.folg.gedcom.model.RepositoryRef; import org.folg.gedcom.model.Source; import app.familygem.Dettaglio; -import app.familygem.Memoria; +import app.familygem.Memory; import app.familygem.R; import app.familygem.U; import static app.familygem.Global.gc; @@ -46,9 +46,9 @@ public static View mettiArchivio(LinearLayout scatola, final Repository repo) { View cartaRepo = LayoutInflater.from(contesto).inflate(R.layout.pezzo_fonte, scatola, false); scatola.addView(cartaRepo); ((TextView)cartaRepo.findViewById(R.id.fonte_testo)).setText(repo.getName()); - ((CardView)cartaRepo).setCardBackgroundColor(contesto.getResources().getColor(R.color.archivio)); + ((CardView)cartaRepo).setCardBackgroundColor(contesto.getResources().getColor(R.color.repository)); cartaRepo.setOnClickListener(v -> { - Memoria.setPrimo(repo); + Memory.setPrimo(repo); contesto.startActivity(new Intent(contesto, Archivio.class)); }); return cartaRepo; @@ -57,9 +57,9 @@ public static View mettiArchivio(LinearLayout scatola, final Repository repo) { @Override public void elimina() { // Elimina la citazione all'archivio a aggiorna la data della fonte che la conteneva - Source contenitore = (Source)Memoria.oggettoContenitore(); + Source contenitore = (Source)Memory.oggettoContenitore(); contenitore.setRepositoryRef(null); U.updateChangeDate(contenitore); - Memoria.annullaIstanze(r); + Memory.annullaIstanze(r); } } \ No newline at end of file diff --git a/app/src/main/java/app/familygem/detail/Autore.java b/app/src/main/java/app/familygem/detail/Autore.java index 9f67fbb4..b319fed8 100644 --- a/app/src/main/java/app/familygem/detail/Autore.java +++ b/app/src/main/java/app/familygem/detail/Autore.java @@ -15,7 +15,7 @@ public void impagina() { setTitle(R.string.submitter); a = (Submitter)cast(Submitter.class); placeSlug("SUBM", a.getId()); - place(getString(R.string.value), "Value", false, true); // Value de che? + place(getString(R.string.value), "Value", false, true); // Value of what? place(getString(R.string.name), "Name"); place(getString(R.string.address), a.getAddress()); place(getString(R.string.www), "Www"); @@ -32,6 +32,6 @@ public void impagina() { public void elimina() { // Ricordiamo che almeno un autore deve essere specificato // non aggiorna la data di nessun record - Podio.eliminaAutore( a ); + Podio.deleteSubmitter(a); } } diff --git a/app/src/main/java/app/familygem/detail/CitazioneFonte.java b/app/src/main/java/app/familygem/detail/CitazioneFonte.java index 6a3aad9c..d64c5f6c 100644 --- a/app/src/main/java/app/familygem/detail/CitazioneFonte.java +++ b/app/src/main/java/app/familygem/detail/CitazioneFonte.java @@ -4,7 +4,7 @@ import org.folg.gedcom.model.SourceCitation; import org.folg.gedcom.model.SourceCitationContainer; import app.familygem.Dettaglio; -import app.familygem.Memoria; +import app.familygem.Memory; import app.familygem.R; import app.familygem.U; import static app.familygem.Global.gc; @@ -41,12 +41,12 @@ public void impagina() { @Override public void elimina() { - Object contenitore = Memoria.oggettoContenitore(); - if( contenitore instanceof Note ) // Note non extende SourceCitationContainer - ((Note)contenitore).getSourceCitations().remove( c ); + Object contenitore = Memory.oggettoContenitore(); + if( contenitore instanceof Note ) // Note doesn't extend SourceCitationContainer + ((Note)contenitore).getSourceCitations().remove(c); else - ((SourceCitationContainer)contenitore).getSourceCitations().remove( c ); - U.updateChangeDate( Memoria.oggettoCapo() ); - Memoria.annullaIstanze(c); + ((SourceCitationContainer)contenitore).getSourceCitations().remove(c); + U.updateChangeDate(Memory.oggettoCapo()); + Memory.annullaIstanze(c); } } diff --git a/app/src/main/java/app/familygem/detail/Estensione.java b/app/src/main/java/app/familygem/detail/Estensione.java index e7735428..da33eaa8 100644 --- a/app/src/main/java/app/familygem/detail/Estensione.java +++ b/app/src/main/java/app/familygem/detail/Estensione.java @@ -2,7 +2,7 @@ import org.folg.gedcom.model.GedcomTag; import app.familygem.Dettaglio; -import app.familygem.Memoria; +import app.familygem.Memory; import app.familygem.R; import app.familygem.U; @@ -29,7 +29,7 @@ public void impagina() { @Override public void elimina() { - U.eliminaEstensione(e, Memoria.oggettoContenitore(), null); - U.updateChangeDate(Memoria.oggettoCapo()); + U.eliminaEstensione(e, Memory.oggettoContenitore(), null); + U.updateChangeDate(Memory.oggettoCapo()); } } diff --git a/app/src/main/java/app/familygem/detail/Evento.java b/app/src/main/java/app/familygem/detail/Evento.java index 2afcd845..6bb7b8aa 100644 --- a/app/src/main/java/app/familygem/detail/Evento.java +++ b/app/src/main/java/app/familygem/detail/Evento.java @@ -5,8 +5,8 @@ import org.folg.gedcom.model.PersonFamilyCommonContainer; import java.util.Arrays; import app.familygem.Dettaglio; -import app.familygem.IndividuoEventi; -import app.familygem.Memoria; +import app.familygem.ProfileFactsFragment; +import app.familygem.Memory; import app.familygem.R; import app.familygem.U; @@ -21,10 +21,10 @@ public class Evento extends Dettaglio { @Override public void impagina() { e = (EventFact)cast(EventFact.class); - if( Memoria.oggettoCapo() instanceof Family ) - setTitle(writeEventTitle((Family)Memoria.oggettoCapo(), e)); + if( Memory.oggettoCapo() instanceof Family ) + setTitle(writeEventTitle((Family)Memory.oggettoCapo(), e)); else - setTitle(IndividuoEventi.writeEventTitle(e)); // It includes e.getDisplayType() + setTitle(ProfileFactsFragment.writeEventTitle(e)); // It includes e.getDisplayType() placeSlug(e.getTag()); if( Arrays.asList(eventTags).contains(e.getTag()) ) // è un evento (senza Value) place(getString(R.string.value), "Value", false, true); @@ -56,9 +56,9 @@ public void impagina() { @Override public void elimina() { - ((PersonFamilyCommonContainer)Memoria.oggettoContenitore()).getEventsFacts().remove(e); - U.updateChangeDate(Memoria.oggettoCapo()); - Memoria.annullaIstanze(e); + ((PersonFamilyCommonContainer)Memory.oggettoContenitore()).getEventsFacts().remove(e); + U.updateChangeDate(Memory.oggettoCapo()); + Memory.annullaIstanze(e); } // Elimina i principali tag vuoti e eventualmente aggiunge la 'Y' diff --git a/app/src/main/java/app/familygem/detail/Famiglia.java b/app/src/main/java/app/familygem/detail/Famiglia.java index 92155319..fe7a20f5 100644 --- a/app/src/main/java/app/familygem/detail/Famiglia.java +++ b/app/src/main/java/app/familygem/detail/Famiglia.java @@ -17,9 +17,8 @@ import app.familygem.Dettaglio; import app.familygem.EditaIndividuo; import app.familygem.Global; -import app.familygem.Individuo; -import app.familygem.IndividuoFamiliari; -import app.familygem.Memoria; +import app.familygem.ProfileActivity; +import app.familygem.Memory; import app.familygem.R; import app.familygem.U; import app.familygem.constant.Gender; @@ -97,7 +96,7 @@ else if( parentFam.size() > 1 ) { if( parentFam.size() == 2 ) { // Swappa tra le 2 famiglie genitoriali Global.indi = p.getId(); Global.familyNum = parentFam.indexOf(f) == 0 ? 1 : 0; - Memoria.replacePrimo(parentFam.get(Global.familyNum)); + Memory.replacePrimo(parentFam.get(Global.familyNum)); recreate(); } else // Più di due famiglie U.qualiGenitoriMostrare( this, p, 2 ); @@ -106,13 +105,13 @@ else if( spouseFam.size() > 1 ) { if( spouseFam.size() == 2 ) { // Swappa tra le 2 famiglie coniugali Global.indi = p.getId(); Family altraFamiglia = spouseFam.get(spouseFam.indexOf(f) == 0 ? 1 : 0); - Memoria.replacePrimo(altraFamiglia); + Memory.replacePrimo(altraFamiglia); recreate(); } else U.qualiConiugiMostrare(this, p, null); } else { - Memoria.setPrimo(p); - startActivity(new Intent(this, Individuo.class)); + Memory.setPrimo(p); + startActivity(new Intent(this, ProfileActivity.class)); } }); if( unRappresentanteDellaFamiglia == null ) @@ -209,9 +208,8 @@ public static void chooseLineage(Context context, Person person, Family family) new AlertDialog.Builder(context).setSingleChoiceItems(pediTexts, actual, (dialog, i) -> { parentFamilyRef.setRelationshipType(pediTypes[i]); dialog.dismiss(); - if( context instanceof Individuo ) - ((IndividuoFamiliari)((Individuo)context).getSupportFragmentManager() - .findFragmentByTag("android:switcher:" + R.id.schede_persona + ":2")).refresh(); + if( context instanceof ProfileActivity ) + ((ProfileActivity)context).refresh(); else if( context instanceof Famiglia ) ((Famiglia)context).refresh(); U.save(true, person); diff --git a/app/src/main/java/app/familygem/detail/Fonte.java b/app/src/main/java/app/familygem/detail/Fonte.java index bf9bc017..7278bce8 100644 --- a/app/src/main/java/app/familygem/detail/Fonte.java +++ b/app/src/main/java/app/familygem/detail/Fonte.java @@ -8,9 +8,9 @@ import android.widget.TextView; import org.folg.gedcom.model.RepositoryRef; import org.folg.gedcom.model.Source; -import app.familygem.Biblioteca; +import app.familygem.list.SourcesFragment; import app.familygem.Dettaglio; -import app.familygem.Memoria; +import app.familygem.Memory; import app.familygem.R; import app.familygem.U; import app.familygem.visitor.ListaCitazioniFonte; @@ -26,7 +26,7 @@ public void impagina() { f = (Source)cast(Source.class); placeSlug("SOUR", f.getId()); ListaCitazioniFonte citazioni = new ListaCitazioniFonte(gc, f.getId()); - f.putExtension("citaz", citazioni.lista.size()); // per la Biblioteca + f.putExtension("citaz", citazioni.lista.size()); // For SourcesFragment place(getString(R.string.abbreviation), "Abbreviation"); place(getString(R.string.title), "Title", true, true); place(getString(R.string.type), "Type", false, true); // _type @@ -46,11 +46,11 @@ public void impagina() { if( f.getRepositoryRef() != null ) { View vistaRef = LayoutInflater.from(this).inflate(R.layout.pezzo_citazione_fonte, box, false); box.addView(vistaRef); - vistaRef.setBackgroundColor(getResources().getColor(R.color.archivioCitazione)); + vistaRef.setBackgroundColor(getResources().getColor(R.color.repository_citation)); final RepositoryRef refArchivio = f.getRepositoryRef(); if( refArchivio.getRepository(gc) != null ) { ((TextView)vistaRef.findViewById(R.id.fonte_testo)).setText(refArchivio.getRepository(gc).getName()); - ((CardView)vistaRef.findViewById(R.id.citazione_fonte)).setCardBackgroundColor(getResources().getColor(R.color.archivio)); + ((CardView)vistaRef.findViewById(R.id.citazione_fonte)).setCardBackgroundColor(getResources().getColor(R.color.repository)); } else vistaRef.findViewById(R.id.citazione_fonte).setVisibility(View.GONE); String t = ""; if( refArchivio.getValue() != null ) t += refArchivio.getValue() + "\n"; @@ -62,7 +62,7 @@ public void impagina() { U.placeNotes((LinearLayout)vistaRef.findViewById(R.id.citazione_note), refArchivio, false); vistaRef.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { - Memoria.aggiungi(refArchivio); + Memory.aggiungi(refArchivio); startActivity(new Intent(Fonte.this, ArchivioRef.class)); } }); @@ -78,6 +78,6 @@ public void onClick(View v) { @Override public void elimina() { - U.updateChangeDate(Biblioteca.eliminaFonte(f)); + U.updateChangeDate(SourcesFragment.eliminaFonte(f)); } } diff --git a/app/src/main/java/app/familygem/detail/Immagine.java b/app/src/main/java/app/familygem/detail/Immagine.java index 4105019a..b5fc1acd 100644 --- a/app/src/main/java/app/familygem/detail/Immagine.java +++ b/app/src/main/java/app/familygem/detail/Immagine.java @@ -16,10 +16,10 @@ import app.familygem.BuildConfig; import app.familygem.Dettaglio; import app.familygem.F; -import app.familygem.Galleria; +import app.familygem.list.GalleryFragment; import app.familygem.Global; import app.familygem.Lavagna; -import app.familygem.Memoria; +import app.familygem.Memory; import app.familygem.R; import app.familygem.U; import app.familygem.visitor.RiferimentiMedia; @@ -59,39 +59,39 @@ public void impagina() { if( riferiMedia.capostipiti.size() > 0 ) U.mettiDispensa(box, riferiMedia.capostipiti.toArray(), R.string.used_by); else if( ((Activity)box.getContext()).getIntent().getBooleanExtra("daSolo", false) ) - U.mettiDispensa(box, Memoria.oggettoCapo(), R.string.into); + U.mettiDispensa(box, Memory.oggettoCapo(), R.string.into); } - void immaginona(Media m, int posizione) { + void immaginona(Media media, int position) { vistaMedia = LayoutInflater.from(this).inflate(R.layout.immagine_immagine, box, false); - box.addView(vistaMedia, posizione); + box.addView(vistaMedia, position); ImageView vistaImg = vistaMedia.findViewById(R.id.immagine_foto); - F.dipingiMedia(m, vistaImg, vistaMedia.findViewById(R.id.immagine_circolo)); + F.paintMedia(media, vistaImg, vistaMedia.findViewById(R.id.immagine_circolo)); vistaMedia.setOnClickListener(vista -> { - String percorso = (String)vistaImg.getTag(R.id.tag_percorso); + String path = (String)vistaImg.getTag(R.id.tag_percorso); Uri uri = (Uri)vistaImg.getTag(R.id.tag_uri); - int tipoFile = (int)vistaImg.getTag(R.id.tag_tipo_file); - if( tipoFile == 0 ) { // Il file è da trovare - F.appAcquisizioneImmagine(this, null, 5173, null); + int tipoFile = (int)vistaImg.getTag(R.id.tag_file_type); + if( tipoFile == 0 ) { // Il file è da trovare + F.mediaAppList(this, null, 5173, null); } else if( tipoFile == 2 || tipoFile == 3 ) { // Apre file con altra app // todo se il tipo è 3 ma è un url (pagina web senza immagini) cerca di aprirlo come un file:// - if( percorso != null ) { - File file = new File(percorso); + if( path != null ) { + File file = new File(path); if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP - && percorso.startsWith(getExternalFilesDir(null).getPath()) ) - // Un'app può essere file provider solo delle SUE cartelle + && path.startsWith(getExternalFilesDir(null).getPath()) ) + // An app can be a file provider only of its folders uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", file); - else // KitKat e tutte le altre cartelle + else // KitKat and all other folders uri = Uri.fromFile(file); } String mimeType = getContentResolver().getType(uri); - Intent intento = new Intent(Intent.ACTION_VIEW); - intento.setDataAndType(uri, mimeType); - intento.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // Serve per le cartelle di proprietà dell'app (provider) - List resolvers = getPackageManager().queryIntentActivities(intento, 0); - // per un'estensione come .tex di cui ha trovato il tipo mime, non c'è nessuna app predefinita + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(uri, mimeType); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // Serve per le cartelle di proprietà dell'app (provider) + List resolvers = getPackageManager().queryIntentActivities(intent, 0); + // per un'estensione come .tex di cui ha trovato il tipo mime, non c'è nessuna app predefinita if( mimeType == null || resolvers.isEmpty() ) { - intento.setDataAndType(uri, "*/*"); // Brutta lista di app generiche + intent.setDataAndType(uri, "*/*"); // Brutta lista di app generiche } // Da android 7 (Nougat api 24) gli uri file:// sono banditi in favore di uri content:// perciò non riesce ad aprire i file if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ) { // ok funziona nell'emulatore con Android 9 @@ -99,17 +99,17 @@ void immaginona(Media m, int posizione) { StrictMode.class.getMethod("disableDeathOnFileUriExposure").invoke(null); } catch( Exception e ) {} } - startActivity( intento ); + startActivity(intent); } else { // Immagine vera e propria - Intent intento = new Intent( Immagine.this, Lavagna.class ); - intento.putExtra( "percorso", percorso ); + Intent intento = new Intent(Immagine.this, Lavagna.class); + intento.putExtra("path", path); if( uri != null ) - intento.putExtra( "uri", uri.toString() ); - startActivity( intento ); + intento.putExtra("uri", uri.toString()); + startActivity(intento); } }); - vistaMedia.setTag( R.id.tag_oggetto, 43614 ); // per il suo menu contestuale - registerForContextMenu( vistaMedia ); + vistaMedia.setTag(R.id.tag_oggetto, 43614); // per il suo menu contestuale + registerForContextMenu(vistaMedia); } public void aggiornaImmagine() { @@ -120,6 +120,6 @@ public void aggiornaImmagine() { @Override public void elimina() { - U.updateChangeDate(Galleria.eliminaMedia(m, null)); + U.updateChangeDate(GalleryFragment.eliminaMedia(m, null)); } } \ No newline at end of file diff --git a/app/src/main/java/app/familygem/detail/Indirizzo.java b/app/src/main/java/app/familygem/detail/Indirizzo.java index f503c35c..97dc14fa 100644 --- a/app/src/main/java/app/familygem/detail/Indirizzo.java +++ b/app/src/main/java/app/familygem/detail/Indirizzo.java @@ -2,7 +2,7 @@ import org.folg.gedcom.model.Address; import app.familygem.Dettaglio; -import app.familygem.Memoria; +import app.familygem.Memory; import app.familygem.R; import app.familygem.U; @@ -29,8 +29,8 @@ public void impagina() { @Override public void elimina() { - eliminaIndirizzo(Memoria.oggettoContenitore()); - U.updateChangeDate(Memoria.oggettoCapo()); - Memoria.annullaIstanze(a); + eliminaIndirizzo(Memory.oggettoContenitore()); + U.updateChangeDate(Memory.oggettoCapo()); + Memory.annullaIstanze(a); } } diff --git a/app/src/main/java/app/familygem/detail/Nome.java b/app/src/main/java/app/familygem/detail/Nome.java index 180b645d..f34108eb 100644 --- a/app/src/main/java/app/familygem/detail/Nome.java +++ b/app/src/main/java/app/familygem/detail/Nome.java @@ -4,7 +4,7 @@ import org.folg.gedcom.model.Person; import app.familygem.Dettaglio; import app.familygem.Global; -import app.familygem.Memoria; +import app.familygem.Memory; import app.familygem.R; import app.familygem.U; import static app.familygem.Global.gc; @@ -54,6 +54,6 @@ public void elimina() { Person costui = gc.getPerson(Global.indi); costui.getNames().remove(n); U.updateChangeDate(costui); - Memoria.annullaIstanze(n); + Memory.annullaIstanze(n); } } diff --git a/app/src/main/java/app/familygem/detail/Nota.java b/app/src/main/java/app/familygem/detail/Nota.java index d4e5ad0a..9933706e 100644 --- a/app/src/main/java/app/familygem/detail/Nota.java +++ b/app/src/main/java/app/familygem/detail/Nota.java @@ -4,7 +4,7 @@ import org.folg.gedcom.model.Note; import app.familygem.Dettaglio; import app.familygem.Global; -import app.familygem.Memoria; +import app.familygem.Memory; import app.familygem.R; import app.familygem.U; import app.familygem.visitor.RiferimentiNota; @@ -32,8 +32,8 @@ public void impagina() { RiferimentiNota rifNota = new RiferimentiNota(Global.gc, n.getId(), false); if( rifNota.tot > 0 ) U.mettiDispensa(box, rifNota.capostipiti.toArray(), R.string.shared_by); - } else if( ((Activity)box.getContext()).getIntent().getBooleanExtra("daQuaderno", false) ) { - U.mettiDispensa(box, Memoria.oggettoCapo(), R.string.written_in); + } else if( ((Activity)box.getContext()).getIntent().getBooleanExtra("fromNotes", false) ) { + U.mettiDispensa(box, Memory.oggettoCapo(), R.string.written_in); } } diff --git a/app/src/main/java/app/familygem/Chiesa.java b/app/src/main/java/app/familygem/list/FamiliesFragment.java similarity index 87% rename from app/src/main/java/app/familygem/Chiesa.java rename to app/src/main/java/app/familygem/list/FamiliesFragment.java index 2fa1dd91..d21b9960 100644 --- a/app/src/main/java/app/familygem/Chiesa.java +++ b/app/src/main/java/app/familygem/list/FamiliesFragment.java @@ -1,4 +1,4 @@ -package app.familygem; +package app.familygem.list; import android.content.Intent; import android.os.Bundle; @@ -25,10 +25,14 @@ import java.util.Iterator; import java.util.List; import java.util.Set; +import app.familygem.Global; +import app.familygem.Memory; +import app.familygem.R; +import app.familygem.U; import app.familygem.detail.Famiglia; import static app.familygem.Global.gc; -public class Chiesa extends Fragment { +public class FamiliesFragment extends Fragment { private LinearLayout layout; private List familyList; @@ -37,19 +41,19 @@ public class Chiesa extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { - View view = inflater.inflate(R.layout.magazzino, container, false); - layout = view.findViewById(R.id.magazzino_scatola); + View view = inflater.inflate(R.layout.scrollview, container, false); + layout = view.findViewById(R.id.scrollview_layout); if( gc != null ) { familyList = new ArrayList<>(); refresh(What.RELOAD); if( familyList.size() > 1 ) setHasOptionsMenu(true); - idsAreNumeric = verificaIdNumerici(); + idsAreNumeric = checkIdsNumeric(); view.findViewById(R.id.fab).setOnClickListener(v -> { - Family newFamily = nuovaFamiglia(true); + Family newFamily = newFamily(true); U.save(true, newFamily); // Se torna subito indietro in Chiesa rinfresca la lista con la famiglia vuota - Memoria.setPrimo(newFamily); + Memory.setPrimo(newFamily); startActivity(new Intent(getContext(), Famiglia.class)); }); } @@ -57,7 +61,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bu } void placeFamily(LinearLayout layout, FamilyWrapper wrapper) { - View familyView = LayoutInflater.from(layout.getContext()).inflate(R.layout.pezzo_famiglia, layout, false); + View familyView = LayoutInflater.from(layout.getContext()).inflate(R.layout.families_item, layout, false); layout.addView(familyView); TextView infoView = familyView.findViewById(R.id.family_info); switch( order ) { @@ -100,14 +104,14 @@ void placeFamily(LinearLayout layout, FamilyWrapper wrapper) { childrenView.setText(children); registerForContextMenu(familyView); familyView.setOnClickListener(v -> { - Memoria.setPrimo(wrapper.family); + Memory.setPrimo(wrapper.family); layout.getContext().startActivity(new Intent(layout.getContext(), Famiglia.class)); }); familyView.setTag(wrapper.id); // solo per il menu contestuale Elimina qui in Chiesa } // Delete a family, removing the refs from members - static void deleteFamily(Family family) { + public static void deleteFamily(Family family) { if( family == null ) return; Set membri = new HashSet<>(); // Remove references to the family from family members @@ -144,17 +148,17 @@ static void deleteFamily(Family family) { // The family is deleted gc.getFamilies().remove(family); gc.createIndexes(); // necessario per aggiornare gli individui - Memoria.annullaIstanze(family); + Memory.annullaIstanze(family); Global.familyNum = 0; // Nel caso fortuito che sia stata eliminata proprio questa famiglia U.save(true, membri.toArray(new Object[0])); } - static Family nuovaFamiglia(boolean aggiungi) { - Family nuova = new Family(); - nuova.setId(U.nuovoId(gc, Family.class)); - if( aggiungi ) - gc.addFamily(nuova); - return nuova; + public static Family newFamily(boolean addToGedcom) { + Family family = new Family(); + family.setId(U.nuovoId(gc, Family.class)); + if( addToGedcom ) + gc.addFamily(family); + return family; } private Family selected; @@ -186,14 +190,14 @@ public boolean onContextItemSelected( MenuItem item ) { return true; } - // Verifica se tutti gli id delle famiglie contengono numeri - // Appena un id contiene solo lettere restituisce false - boolean verificaIdNumerici() { - esterno: - for( Family f : gc.getFamilies() ) { - for( char c : f.getId().toCharArray() ) { - if (Character.isDigit(c)) - continue esterno; + // Check if all family ids contain only numbers + // As soon as an id contains only letters it returns false + boolean checkIdsNumeric() { + outer: + for( Family family : gc.getFamilies() ) { + for( char character : family.getId().toCharArray() ) { + if( Character.isDigit(character) ) + continue outer; } return false; } @@ -206,12 +210,12 @@ void sortFamilies() { switch( order ) { case 1: // Ordina per ID if( idsAreNumeric ) - return U.soloNumeri(f1.id) - U.soloNumeri(f2.id); + return U.getNumberOnly(f1.id) - U.getNumberOnly(f2.id); else return f1.id.compareToIgnoreCase(f2.id); case 2: if( idsAreNumeric ) - return U.soloNumeri(f2.id) - U.soloNumeri(f1.id); + return U.getNumberOnly(f2.id) - U.getNumberOnly(f1.id); else return f2.id.compareToIgnoreCase(f1.id); case 3: // Ordina per cognome @@ -236,10 +240,10 @@ void sortFamilies() { } } - enum What { + public enum What { RELOAD, UPDATE, BASIC } - void refresh(What toDo) { + public void refresh(What toDo) { if( toDo == What.RELOAD ) { // Reload all families from Global.gc familyList.clear(); for( Family family : gc.getFamilies() ) diff --git a/app/src/main/java/app/familygem/list/GalleryAdapter.java b/app/src/main/java/app/familygem/list/GalleryAdapter.java new file mode 100644 index 00000000..31479a09 --- /dev/null +++ b/app/src/main/java/app/familygem/list/GalleryAdapter.java @@ -0,0 +1,177 @@ +package app.familygem.list; + +import android.app.Activity; +import android.content.Context; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.RecyclerView; +import android.content.Intent; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; +import org.folg.gedcom.model.Media; +import org.folg.gedcom.model.Person; +import java.util.List; +import app.familygem.Dettaglio; +import app.familygem.F; +import app.familygem.Global; +import app.familygem.ProfileActivity; +import app.familygem.Memory; +import app.familygem.Principal; +import app.familygem.R; +import app.familygem.U; +import app.familygem.constant.Choice; +import app.familygem.detail.Immagine; +import app.familygem.visitor.ListaMediaContenitore; +import app.familygem.visitor.TrovaPila; + +// Adapter for the RecyclerView of media gallery +public class GalleryAdapter extends RecyclerView.Adapter { + + private List listaMedia; + private boolean dettagli; + + public GalleryAdapter(List listaMedia, boolean dettagli) { + this.listaMedia = listaMedia; + this.dettagli = dettagli; + } + + @Override + public gestoreVistaMedia onCreateViewHolder(ViewGroup parent, int tipo) { + View vista = LayoutInflater.from(parent.getContext()).inflate(R.layout.pezzo_media, parent, false); + return new gestoreVistaMedia(vista, dettagli); + } + @Override + public void onBindViewHolder(final gestoreVistaMedia gestore, int posizione) { + gestore.setta(posizione); + } + @Override + public int getItemCount() { + return listaMedia.size(); + } + @Override + public long getItemId(int position) { + return position; + } + @Override + public int getItemViewType(int position) { + return position; + } + + class gestoreVistaMedia extends RecyclerView.ViewHolder implements View.OnClickListener { + View vista; + boolean dettagli; + Media media; + Object contenitore; + ImageView vistaImmagine; + TextView vistaTesto; + TextView vistaNumero; + gestoreVistaMedia( View vista, boolean dettagli ) { + super(vista); + this.vista = vista; + this.dettagli = dettagli; + vistaImmagine = vista.findViewById( R.id.media_img ); + vistaTesto = vista.findViewById( R.id.media_testo ); + vistaNumero = vista.findViewById( R.id.media_num ); + } + void setta(int posizione) { + media = listaMedia.get(posizione).media; + contenitore = listaMedia.get(posizione).contenitore; + if( dettagli ) { + arredaMedia(media, vistaTesto, vistaNumero); + vista.setOnClickListener(this); + ((Activity)vista.getContext()).registerForContextMenu(vista); + vista.setTag(R.id.tag_oggetto, media); + vista.setTag(R.id.tag_contenitore, contenitore); + // Registra menu contestuale + final AppCompatActivity activity = (AppCompatActivity)vista.getContext(); + if( vista.getContext() instanceof ProfileActivity ) { // ProfileMediaFragment + activity.getSupportFragmentManager() + .findFragmentByTag( "android:switcher:" + R.id.profile_pager + ":0" ) // non garantito in futuro + .registerForContextMenu( vista ); + } else if( vista.getContext() instanceof Principal ) // GalleryFragment + activity.getSupportFragmentManager().findFragmentById(R.id.contenitore_fragment).registerForContextMenu(vista); + else // nelle AppCompatActivity + activity.registerForContextMenu(vista); + } else { + RecyclerView.LayoutParams params = new RecyclerView.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT, U.dpToPx(110)); + int margin = U.dpToPx(5); + params.setMargins(margin, margin, margin, margin); + vista.setLayoutParams(params); + vistaTesto.setVisibility(View.GONE); + vistaNumero.setVisibility(View.GONE); + } + F.paintMedia( media, vistaImmagine, vista.findViewById(R.id.media_circolo) ); + } + @Override + public void onClick(View v) { + AppCompatActivity activity = (AppCompatActivity)v.getContext(); + // GalleryFragment in modalità scelta dell'oggetto media + // Restituisce l'id di un oggetto media a ProfileMediaFragment + if( activity.getIntent().getBooleanExtra(Choice.MEDIA, false) ) { + Intent intent = new Intent(); + intent.putExtra("mediaId", media.getId()); + activity.setResult(Activity.RESULT_OK, intent); + activity.finish(); + } else { // GalleryFragment in modalità normale apre Immagine + Intent intento = new Intent(v.getContext(), Immagine.class); + if( media.getId() != null ) { // tutti i Media record + Memory.setPrimo(media); + } else if( (activity instanceof ProfileActivity && contenitore instanceof Person) // media di primo livello nell'Indi + || activity instanceof Dettaglio ) { // normale apertura nei Dettagli + Memory.aggiungi(media); + } else { // da GalleryFragment tutti i media semplici, o da ProfileMediaFragment i media sotto molteplici livelli + new TrovaPila(Global.gc, media); + if( activity instanceof Principal ) // Solo in GalleryFragment + intento.putExtra("daSolo", true); // così poi Immagine mostra la dispensa + } + v.getContext().startActivity(intento); + } + } + } + + public static void arredaMedia(Media media, TextView vistaTesto, TextView vistaNumero) { + String testo = ""; + if( media.getTitle() != null ) + testo = media.getTitle() + "\n"; + if( Global.settings.expert && media.getFile() != null ) { + String file = media.getFile(); + file = file.replace( '\\', '/' ); + if( file.lastIndexOf('/') > -1 ) { + if( file.length() > 1 && file.endsWith("/") ) // rimuove l'ultima barra + file = file.substring( 0, file.length()-1 ); + file = file.substring( file.lastIndexOf('/') + 1 ); + } + testo += file; + } + if( testo.isEmpty() ) + vistaTesto.setVisibility( View.GONE ); + else { + if( testo.endsWith("\n") ) + testo = testo.substring( 0, testo.length()-1 ); + vistaTesto.setText( testo ); + } + if( media.getId() != null ) { + vistaNumero.setText( String.valueOf(GalleryFragment.popolarita(media)) ); + vistaNumero.setVisibility( View.VISIBLE ); + } else + vistaNumero.setVisibility( View.GONE ); + } + + // Questa serve solo per creare una RecyclerView con le iconcine dei media che risulti trasparente ai click + // todo però impedisce lo scroll in Dettaglio + public static class RiciclaVista extends RecyclerView { + boolean dettagli; + public RiciclaVista( Context context, boolean dettagli) { + super(context); + this.dettagli = dettagli; + } + @Override + public boolean onTouchEvent( MotionEvent e ) { + super.onTouchEvent( e ); + return dettagli; // quando è false la griglia non intercetta il click + } + } +} diff --git a/app/src/main/java/app/familygem/Galleria.java b/app/src/main/java/app/familygem/list/GalleryFragment.java similarity index 75% rename from app/src/main/java/app/familygem/Galleria.java rename to app/src/main/java/app/familygem/list/GalleryFragment.java index c486a1e3..6509356a 100644 --- a/app/src/main/java/app/familygem/Galleria.java +++ b/app/src/main/java/app/familygem/list/GalleryFragment.java @@ -1,6 +1,6 @@ -// Lista dei Media +// List of Media -package app.familygem; +package app.familygem.list; import android.app.Activity; import android.content.Intent; @@ -23,55 +23,62 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Set; +import app.familygem.F; +import app.familygem.Global; +import app.familygem.CartelleMedia; +import app.familygem.Memory; +import app.familygem.R; +import app.familygem.U; +import app.familygem.constant.Choice; import app.familygem.visitor.ListaMediaContenitore; import app.familygem.visitor.RiferimentiMedia; import app.familygem.visitor.TrovaPila; import static app.familygem.Global.gc; -public class Galleria extends Fragment { +public class GalleryFragment extends Fragment { - ListaMediaContenitore visitaMedia; - AdattatoreGalleriaMedia adattatore; + ListaMediaContenitore mediaVisitor; + GalleryAdapter adapter; @Override - public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle bandolo ) { - setHasOptionsMenu( true ); - View vista = inflater.inflate( R.layout.galleria, container, false ); - RecyclerView griglia = vista.findViewById( R.id.galleria ); - griglia.setHasFixedSize( true ); + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { + setHasOptionsMenu(true); + View view = inflater.inflate(R.layout.gallery, container, false); + RecyclerView recyclerView = view.findViewById(R.id.gallery_recycler); + recyclerView.setHasFixedSize(true); if( gc != null ) { - visitaMedia = new ListaMediaContenitore( gc, !getActivity().getIntent().getBooleanExtra("galleriaScegliMedia",false ) ); - gc.accept( visitaMedia ); + mediaVisitor = new ListaMediaContenitore(gc, !getActivity().getIntent().getBooleanExtra(Choice.MEDIA, false)); + gc.accept(mediaVisitor); arredaBarra(); - RecyclerView.LayoutManager gestoreLayout = new GridLayoutManager( getContext(), 2 ); - griglia.setLayoutManager( gestoreLayout ); - adattatore = new AdattatoreGalleriaMedia( visitaMedia.listaMedia, true ); - griglia.setAdapter( adattatore ); - vista.findViewById( R.id.fab ).setOnClickListener( v -> - F.appAcquisizioneImmagine( getContext(), Galleria.this, 4546, null ) + RecyclerView.LayoutManager gestoreLayout = new GridLayoutManager(getContext(), 2); + recyclerView.setLayoutManager(gestoreLayout); + adapter = new GalleryAdapter(mediaVisitor.listaMedia, true); + recyclerView.setAdapter(adapter); + view.findViewById(R.id.fab).setOnClickListener(v -> + F.mediaAppList(getContext(), GalleryFragment.this, 4546, null) ); } - return vista; + return view; } // Andandosene dall'attività resetta l'extra se non è stato scelto un media condiviso @Override public void onPause() { super.onPause(); - getActivity().getIntent().removeExtra("galleriaScegliMedia"); + getActivity().getIntent().removeExtra(Choice.MEDIA); } // Scrive il titolo nella barra void arredaBarra() { - ((AppCompatActivity)getActivity()).getSupportActionBar().setTitle( visitaMedia.listaMedia.size() + ((AppCompatActivity)getActivity()).getSupportActionBar().setTitle( mediaVisitor.listaMedia.size() + " " + getString(R.string.media).toLowerCase() ); } - // Aggiorna i contenuti della galleria - void ricrea() { - visitaMedia.listaMedia.clear(); - gc.accept( visitaMedia ); - adattatore.notifyDataSetChanged(); + // Update gallery contents + public void ricrea() { + mediaVisitor.listaMedia.clear(); + gc.accept(mediaVisitor); + adapter.notifyDataSetChanged(); arredaBarra(); } @@ -81,7 +88,7 @@ static int popolarita( Media med ) { return riferiMedia.num; } - static Media nuovoMedia( Object contenitore ){ + public static Media nuovoMedia(Object contenitore){ Media media = new Media(); media.setId( U.nuovoId(gc,Media.class) ); media.setFileTag("FILE"); // Necessario per poi esportare il Gedcom @@ -95,7 +102,7 @@ static Media nuovoMedia( Object contenitore ){ } // Scollega da un contenitore un media condiviso - static void scollegaMedia(String mediaId, MediaContainer container) { + public static void scollegaMedia(String mediaId, MediaContainer container) { Iterator refs = container.getMediaRefs().iterator(); while( refs.hasNext() ) { MediaRef ref = refs.next(); @@ -118,15 +125,15 @@ public static Object[] eliminaMedia(Media media, View vista) { capi = eliminaMedia.capostipiti; } else { // media LOCALE new TrovaPila(gc, media); // trova temporaneamente la pila del media per individuare il container - MediaContainer container = (MediaContainer)Memoria.oggettoContenitore(); + MediaContainer container = (MediaContainer)Memory.oggettoContenitore(); container.getMedia().remove(media); if( container.getMedia().isEmpty() ) container.setMedia(null); capi = new HashSet<>(); // set con un solo Object capostipite - capi.add( Memoria.oggettoCapo() ); - Memoria.arretra(); // elimina la pila appena creata + capi.add(Memory.oggettoCapo()); + Memory.arretra(); // elimina la pila appena creata } - Memoria.annullaIstanze(media); + Memory.annullaIstanze(media); if( vista != null ) vista.setVisibility(View.GONE); return capi.toArray(new Object[0]); diff --git a/app/src/main/java/app/familygem/QuadernoAdapter.java b/app/src/main/java/app/familygem/list/NotesAdapter.java similarity index 86% rename from app/src/main/java/app/familygem/QuadernoAdapter.java rename to app/src/main/java/app/familygem/list/NotesAdapter.java index 21f78421..ec9c8e16 100644 --- a/app/src/main/java/app/familygem/QuadernoAdapter.java +++ b/app/src/main/java/app/familygem/list/NotesAdapter.java @@ -1,4 +1,4 @@ -package app.familygem; +package app.familygem.list; import android.content.Context; import android.view.ContextMenu; @@ -12,9 +12,11 @@ import org.folg.gedcom.model.Note; import java.util.Iterator; import java.util.List; +import app.familygem.Global; +import app.familygem.R; import app.familygem.visitor.RiferimentiNota; -public class QuadernoAdapter extends RecyclerView.Adapter implements Filterable { +public class NotesAdapter extends RecyclerView.Adapter implements Filterable { List noteList; private final LayoutInflater inflater; @@ -22,7 +24,7 @@ public class QuadernoAdapter extends RecyclerView.Adapter data, boolean sharedOnly) { + NotesAdapter(Context context, List data, boolean sharedOnly) { this.inflater = LayoutInflater.from(context); this.noteList = data; this.sharedOnly = sharedOnly; @@ -30,7 +32,7 @@ public class QuadernoAdapter extends RecyclerView.Adapter noteIterator = noteList.iterator(); while( noteIterator.hasNext() ) { @@ -86,8 +88,8 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL ViewHolder(View itemView) { super(itemView); - textView = itemView.findViewById(R.id.nota_testo); - countView = itemView.findViewById(R.id.nota_citazioni); + textView = itemView.findViewById(R.id.note_text); + countView = itemView.findViewById(R.id.note_citations); itemView.setOnClickListener(this); itemView.setOnCreateContextMenuListener(this); } diff --git a/app/src/main/java/app/familygem/Quaderno.java b/app/src/main/java/app/familygem/list/NotesFragment.java similarity index 72% rename from app/src/main/java/app/familygem/Quaderno.java rename to app/src/main/java/app/familygem/list/NotesFragment.java index 9de19559..cbb7c077 100644 --- a/app/src/main/java/app/familygem/Quaderno.java +++ b/app/src/main/java/app/familygem/list/NotesFragment.java @@ -1,4 +1,4 @@ -package app.familygem; +package app.familygem.list; import static app.familygem.Global.gc; import android.content.Context; @@ -20,13 +20,17 @@ import org.folg.gedcom.model.NoteRef; import java.util.ArrayList; import java.util.List; +import app.familygem.Memory; +import app.familygem.R; +import app.familygem.U; +import app.familygem.constant.Choice; import app.familygem.detail.Nota; import app.familygem.visitor.ListaNote; import app.familygem.visitor.TrovaPila; -public class Quaderno extends Fragment implements QuadernoAdapter.ItemClickListener { +public class NotesFragment extends Fragment implements NotesAdapter.ItemClickListener { - QuadernoAdapter adapter; + NotesAdapter adapter; public static List getAllNotes(boolean sharedOnly) { // Shared notes @@ -44,12 +48,12 @@ public static List getAllNotes(boolean sharedOnly) { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bandolo ) { - View view = inflater.inflate(R.layout.ricicla_vista, container, false); - RecyclerView recyclerView = view.findViewById(R.id.riciclatore); + View view = inflater.inflate(R.layout.recycler_view, container, false); + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - boolean sharedOnly = getActivity().getIntent().getBooleanExtra("quadernoScegliNota", false); + boolean sharedOnly = getActivity().getIntent().getBooleanExtra(Choice.NOTE, false); List allNotes = getAllNotes(sharedOnly); - adapter = new QuadernoAdapter(getContext(), allNotes, sharedOnly); + adapter = new NotesAdapter(getContext(), allNotes, sharedOnly); adapter.setClickListener(this); recyclerView.setAdapter(adapter); @@ -61,29 +65,29 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle ba return view; } - // Andandosene dall'attività senza aver scelto una nota condivisa resetta l'extra + // Leaving the activity without choosing a shared note resets the extra @Override public void onPause() { super.onPause(); - getActivity().getIntent().removeExtra("quadernoScegliNota"); + getActivity().getIntent().removeExtra(Choice.NOTE); } @Override public void onItemClick(View view, int position) { Note note = adapter.getItem(position); - // Restituisce l'id di una nota a Individuo e Dettaglio - if( getActivity().getIntent().getBooleanExtra("quadernoScegliNota", false) ) { + // Return the id of a note to Individual and Detail + if( getActivity().getIntent().getBooleanExtra(Choice.NOTE, false) ) { Intent intento = new Intent(); - intento.putExtra("idNota", note.getId()); + intento.putExtra("noteId", note.getId()); getActivity().setResult(AppCompatActivity.RESULT_OK, intento); getActivity().finish(); - } else { // Apre il dettaglio della nota + } else { // Open the note detail Intent intento = new Intent(getContext(), Nota.class); - if( note.getId() != null ) { // Nota condivisa - Memoria.setPrimo(note); - } else { // Nota semplice + if( note.getId() != null ) { // Shared note + Memory.setPrimo(note); + } else { // Simple note new TrovaPila(gc, note); - intento.putExtra("daQuaderno", true); + intento.putExtra("fromNotes", true); } getContext().startActivity(intento); } @@ -91,7 +95,7 @@ public void onItemClick(View view, int position) { @Override public boolean onContextItemSelected(MenuItem item) { - if( item.getItemId() == 0 ) { // Elimina + if( item.getItemId() == 0 ) { // Delete Object[] capi = U.eliminaNota(adapter.selectedNote, null); U.save(false, capi); getActivity().recreate(); @@ -101,12 +105,11 @@ public boolean onContextItemSelected(MenuItem item) { return true; } - // menu opzioni nella toolbar @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // Search inside notes - inflater.inflate(R.menu.cerca, menu); - final SearchView searchView = (SearchView)menu.findItem(R.id.ricerca).getActionView(); + inflater.inflate(R.menu.search, menu); + final SearchView searchView = (SearchView)menu.findItem(R.id.search_item).getActionView(); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextChange(String query) { @@ -121,8 +124,8 @@ public boolean onQueryTextSubmit(String q) { }); } - // Crea una nuova nota condivisa, attaccata a un contenitore oppure slegata - static void newNote(Context context, Object container) { + // Create a new shared note, attached or not to a container. + public static void newNote(Context context, Object container) { Note note = new Note(); String id = U.nuovoId(gc, Note.class); note.setId(id); @@ -134,7 +137,7 @@ static void newNote(Context context, Object container) { ((NoteContainer)container).addNoteRef(noteRef); } U.save(true, note); - Memoria.setPrimo(note); + Memory.setPrimo(note); context.startActivity(new Intent(context, Nota.class)); } } diff --git a/app/src/main/java/app/familygem/Magazzino.java b/app/src/main/java/app/familygem/list/RepositoriesFragment.java similarity index 77% rename from app/src/main/java/app/familygem/Magazzino.java rename to app/src/main/java/app/familygem/list/RepositoriesFragment.java index abd90457..c95d139c 100644 --- a/app/src/main/java/app/familygem/Magazzino.java +++ b/app/src/main/java/app/familygem/list/RepositoriesFragment.java @@ -1,6 +1,4 @@ -// List of repositories - -package app.familygem; +package app.familygem.list; import android.app.Activity; import android.content.Context; @@ -26,15 +24,31 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import app.familygem.Global; +import app.familygem.Memory; +import app.familygem.R; +import app.familygem.U; +import app.familygem.constant.Choice; import app.familygem.detail.Archivio; import static app.familygem.Global.gc; -public class Magazzino extends Fragment { +// List of repositories +public class RepositoriesFragment extends Fragment { + + LinearLayout layout; + int order; // For sorting @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { - View view = inflater.inflate(R.layout.magazzino, container, false); - LinearLayout layout = view.findViewById(R.id.magazzino_scatola); + View view = inflater.inflate(R.layout.scrollview, container, false); + layout = view.findViewById(R.id.scrollview_layout); + view.findViewById(R.id.fab).setOnClickListener(v -> newRepository(getContext(), null)); + return view; + } + + @Override + public void onStart() { + super.onStart(); if( gc != null ) { List repos = gc.getRepositories(); ((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(repos.size() + " " @@ -42,9 +56,9 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bu if( repos.size() > 1 ) setHasOptionsMenu(true); Collections.sort(repos, (r1, r2) -> { - switch( Global.ordineMagazzino ) { + switch( order ) { case 1: // Ordina per id - return U.soloNumeri(r1.getId()) - U.soloNumeri(r2.getId()); + return U.getNumberOnly(r1.getId()) - U.getNumberOnly(r2.getId()); case 2: // Ordine alfabetico return r1.getName().compareToIgnoreCase(r2.getName()); case 3: // Ordina per numero di fonti @@ -53,19 +67,20 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bu return 0; } }); + layout.removeAllViews(); for( Repository repo : repos ) { - View repoView = inflater.inflate(R.layout.magazzino_pezzo, layout, false); + View repoView = getLayoutInflater().inflate(R.layout.scrollview_item, layout, false); layout.addView(repoView); - ((TextView)repoView.findViewById(R.id.magazzino_nome)).setText(repo.getName()); - ((TextView)repoView.findViewById(R.id.magazzino_archivi)).setText(String.valueOf(countSources(gc, repo))); + ((TextView)repoView.findViewById(R.id.item_name)).setText(repo.getName()); + ((TextView)repoView.findViewById(R.id.item_num)).setText(String.valueOf(countSources(gc, repo))); repoView.setOnClickListener(v -> { - if( getActivity().getIntent().getBooleanExtra("magazzinoScegliArchivio", false) ) { + if( getActivity().getIntent().getBooleanExtra(Choice.REPOSITORY, false) ) { Intent intento = new Intent(); - intento.putExtra("idArchivio", repo.getId()); + intento.putExtra("repoId", repo.getId()); getActivity().setResult(Activity.RESULT_OK, intento); getActivity().finish(); } else { - Memoria.setPrimo(repo); + Memory.setPrimo(repo); startActivity(new Intent(getContext(), Archivio.class)); } }); @@ -78,15 +93,13 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bu if( repo.getExtensions().isEmpty() ) repo.setExtensions(null); } - view.findViewById(R.id.fab).setOnClickListener(v -> newRepository(getContext(), null)); } - return view; } @Override public void onPause() { super.onPause(); - getActivity().getIntent().removeExtra("magazzinoScegliArchivio"); + getActivity().getIntent().removeExtra(Choice.REPOSITORY); } // Count how many sources are present in a repository @@ -102,7 +115,7 @@ static int countSources(Gedcom gedcom, Repository repo) { } // Create a new repository, optionally linking a source to it - static void newRepository(Context context, Source source) { + public static void newRepository(Context context, Source source) { Repository repo = new Repository(); repo.setId(U.nuovoId(gc, Repository.class)); repo.setName(""); @@ -113,7 +126,7 @@ static void newRepository(Context context, Source source) { source.setRepositoryRef(repoRef); } U.save(true, repo); - Memoria.setPrimo(repo); + Memory.setPrimo(repo); context.startActivity(new Intent(context, Archivio.class)); } @@ -129,7 +142,7 @@ public static Source[] delete(Repository repo) { sources.add(sour); } gc.getRepositories().remove(repo); - Memoria.annullaIstanze(repo); + Memory.annullaIstanze(repo); return sources.toArray(new Source[0]); } @@ -143,21 +156,21 @@ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { subMenu.add(0, 3, 0, R.string.sources_number); } @Override - public boolean onOptionsItemSelected( MenuItem item ) { + public boolean onOptionsItemSelected(MenuItem item) { switch( item.getItemId() ) { case 1: - Global.ordineMagazzino = 1; + order = 1; break; case 2: - Global.ordineMagazzino = 2; + order = 2; break; case 3: - Global.ordineMagazzino = 3; + order = 3; break; default: return false; } - getFragmentManager().beginTransaction().replace(R.id.contenitore_fragment, new Magazzino()).commit(); + onStart(); return true; } diff --git a/app/src/main/java/app/familygem/Biblioteca.java b/app/src/main/java/app/familygem/list/SourcesFragment.java similarity index 58% rename from app/src/main/java/app/familygem/Biblioteca.java rename to app/src/main/java/app/familygem/list/SourcesFragment.java index 15772eec..779d26e6 100644 --- a/app/src/main/java/app/familygem/Biblioteca.java +++ b/app/src/main/java/app/familygem/list/SourcesFragment.java @@ -1,7 +1,4 @@ -// Lista delle Fonti (Sources) -// A differenza di Chiesa utilizza un adapter per il RecyclerView - -package app.familygem; +package app.familygem.list; import android.app.Activity; import android.content.Context; @@ -34,52 +31,58 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import app.familygem.Global; +import app.familygem.Memory; +import app.familygem.R; +import app.familygem.U; +import app.familygem.constant.Choice; import app.familygem.detail.Fonte; import app.familygem.visitor.ListaCitazioniFonte; import static app.familygem.Global.gc; -public class Biblioteca extends Fragment { +// List of sources +public class SourcesFragment extends Fragment { - private List listaFonti; - private BibliotecAdapter adattatore; - private int ordine; + private List sourceList; + private SourcesAdapter adapter; + private int order; @Override - public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle bandolo ) { - listaFonti = gc.getSources(); - ((AppCompatActivity) getActivity()).getSupportActionBar().setTitle( listaFonti.size() + " " + - getString(listaFonti.size()==1 ? R.string.source : R.string.sources).toLowerCase() ); - if( listaFonti.size() > 1 ) + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { + sourceList = gc.getSources(); + ((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(sourceList.size() + " " + + getString(sourceList.size() == 1 ? R.string.source : R.string.sources).toLowerCase()); + if( sourceList.size() > 1 ) setHasOptionsMenu(true); - View vista = inflater.inflate(R.layout.biblioteca, container, false); - RecyclerView vistaFonti = vista.findViewById( R.id.riciclatore ); - adattatore = new BibliotecAdapter(); - vistaFonti.setAdapter( adattatore ); - vista.findViewById( R.id.fab ).setOnClickListener( v -> nuovaFonte( getContext(), null ) ); - return vista; + View view = inflater.inflate(R.layout.sources, container, false); + RecyclerView recyclerView = view.findViewById(R.id.sources_recycler); + adapter = new SourcesAdapter(); + recyclerView.setAdapter(adapter); + view.findViewById(R.id.fab).setOnClickListener(v -> createNewSource(getContext(), null)); + return view; } - public class BibliotecAdapter extends RecyclerView.Adapter implements Filterable { + public class SourcesAdapter extends RecyclerView.Adapter implements Filterable { @Override - public GestoreFonte onCreateViewHolder( ViewGroup parent, int tipo ) { - View vistaFonte = LayoutInflater.from( parent.getContext() ) - .inflate(R.layout.biblioteca_pezzo, parent, false); - registerForContextMenu( vistaFonte ); - return new GestoreFonte( vistaFonte ); + public SourceHolder onCreateViewHolder(ViewGroup parent, int type) { + View sourceView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.source_item, parent, false); + registerForContextMenu(sourceView); + return new SourceHolder(sourceView); } @Override - public void onBindViewHolder( GestoreFonte gestore, int posizione ) { - Source fonte = listaFonti.get(posizione); - gestore.vistaId.setText( fonte.getId() ); - gestore.vistaId.setVisibility( ordine == 1 || ordine == 2 ? View.VISIBLE : View.GONE ); - gestore.vistaTitolo.setText( titoloFonte(fonte) ); - Object volte = fonte.getExtension("citaz"); + public void onBindViewHolder(SourceHolder holder, int position ) { + Source source = sourceList.get(position); + holder.idView.setText(source.getId()); + holder.idView.setVisibility(order == 1 || order == 2 ? View.VISIBLE : View.GONE); + holder.titleView.setText(titoloFonte(source)); + Object volte = source.getExtension("citaz"); // Conta delle citazioni con il mio metodo if( volte == null ) { - volte = quanteCitazioni( fonte ); - fonte.putExtension("citaz", volte ); + volte = quanteCitazioni(source); + source.putExtension("citaz", volte); } - gestore.vistaVolte.setText( String.valueOf(volte) ); + holder.numView.setText(String.valueOf(volte)); } // Filtra i titoli delle fonti in base alle parole cercate @Override @@ -88,20 +91,20 @@ public Filter getFilter() { @Override protected FilterResults performFiltering(CharSequence charSequence) { String query = charSequence.toString(); - if (query.isEmpty()) { - listaFonti = gc.getSources(); + if( query.isEmpty() ) { + sourceList = gc.getSources(); } else { List filteredList = new ArrayList<>(); - for (Source font : gc.getSources()) { - if( titoloFonte(font).toLowerCase().contains(query.toLowerCase()) ) { - filteredList.add(font); + for( Source source : gc.getSources() ) { + if( titoloFonte(source).toLowerCase().contains(query.toLowerCase()) ) { + filteredList.add(source); } } - listaFonti = filteredList; + sourceList = filteredList; } ordinaFonti(); // Riducendo la query riordina quelli che appaiono FilterResults filterResults = new FilterResults(); - filterResults.values = listaFonti; + filterResults.values = sourceList; return filterResults; } @Override @@ -112,33 +115,33 @@ protected void publishResults(CharSequence cs, FilterResults fr) { } @Override public int getItemCount() { - return listaFonti.size(); + return sourceList.size(); } } - class GestoreFonte extends RecyclerView.ViewHolder implements View.OnClickListener { - TextView vistaId; - TextView vistaTitolo; - TextView vistaVolte; - GestoreFonte( View vista ) { - super( vista ); - vistaId = vista.findViewById( R.id.biblioteca_id ); - vistaTitolo = vista.findViewById( R.id.biblioteca_titolo ); - vistaVolte = vista.findViewById( R.id.biblioteca_volte ); - vista.setOnClickListener(this); + class SourceHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + TextView idView; + TextView titleView; + TextView numView; + SourceHolder(View view) { + super(view); + idView = view.findViewById(R.id.source_id); + titleView = view.findViewById(R.id.source_title); + numView = view.findViewById(R.id.source_num); + view.setOnClickListener(this); } @Override public void onClick( View v ) { - // Restituisce l'id di una fonte a Individuo e Dettaglio - if( getActivity().getIntent().getBooleanExtra("bibliotecaScegliFonte",false) ) { + // Restituisce l'id di una fonte a ProfileActivity e Dettaglio + if( getActivity().getIntent().getBooleanExtra(Choice.SOURCE, false) ) { Intent intent = new Intent(); - intent.putExtra("idFonte", vistaId.getText().toString() ); - getActivity().setResult( Activity.RESULT_OK, intent ); + intent.putExtra("sourceId", idView.getText().toString()); + getActivity().setResult(Activity.RESULT_OK, intent); getActivity().finish(); } else { - Source fonte = gc.getSource( vistaId.getText().toString() ); - Memoria.setPrimo( fonte ); - startActivity( new Intent( getContext(), Fonte.class ) ); + Source source = gc.getSource(idView.getText().toString()); + Memory.setPrimo(source); + startActivity(new Intent(getContext(), Fonte.class)); } } } @@ -146,25 +149,25 @@ public void onClick( View v ) { @Override public void onPause() { super.onPause(); - getActivity().getIntent().removeExtra("bibliotecaScegliFonte"); + getActivity().getIntent().removeExtra(Choice.SOURCE); } // Mette in ordine le fonti secondo uno dei criteri // L'ordine poi diventa permanente nel Json private void ordinaFonti() { - if( ordine > 0 ) { - if( ordine == 5 || ordine == 6 ) { - for( Source fonte : listaFonti ) { + if( order > 0 ) { + if( order == 5 || order == 6 ) { + for( Source fonte : sourceList ) { if( fonte.getExtension("citaz") == null ) - fonte.putExtension( "citaz", quanteCitazioni(fonte) ); + fonte.putExtension("citaz", quanteCitazioni(fonte)); } } - Collections.sort( listaFonti, (f1, f2) -> { - switch( ordine ) { + Collections.sort(sourceList, (f1, f2) -> { + switch( order ) { case 1: // Ordina per id numerico - return U.soloNumeri(f1.getId()) - U.soloNumeri(f2.getId()); + return U.getNumberOnly(f1.getId()) - U.getNumberOnly(f2.getId()); case 2: - return U.soloNumeri(f2.getId()) - U.soloNumeri(f1.getId()); + return U.getNumberOnly(f2.getId()) - U.getNumberOnly(f1.getId()); case 3: // Ordine alfabeto dei titoli return titoloFonte(f1).compareToIgnoreCase( titoloFonte(f2) ); case 4: @@ -180,7 +183,7 @@ private void ordinaFonti() { } // Restituisce il titolo della fonte - static String titoloFonte( Source fon ) { + public static String titoloFonte( Source fon ) { String tit = ""; if( fon != null ) if( fon.getAbbreviation() != null ) @@ -235,34 +238,34 @@ private void cita( Object ogg, Source fonte ) { } } - static void nuovaFonte( Context contesto, Object contenitore ){ - Source fonte = new Source(); - fonte.setId( U.nuovoId( gc, Source.class ) ); - fonte.setTitle( "" ); - gc.addSource( fonte ); - if( contenitore != null ) { - SourceCitation citaFonte = new SourceCitation(); - citaFonte.setRef( fonte.getId() ); - if( contenitore instanceof Note ) ((Note)contenitore).addSourceCitation( citaFonte ); - else ((SourceCitationContainer)contenitore).addSourceCitation( citaFonte ); + public static void createNewSource(Context context, Object container) { + Source source = new Source(); + source.setId(U.nuovoId(gc, Source.class)); + source.setTitle(""); + gc.addSource(source); + if( container != null ) { + SourceCitation sourceCitation = new SourceCitation(); + sourceCitation.setRef(source.getId()); + if( container instanceof Note ) ((Note)container).addSourceCitation(sourceCitation); + else ((SourceCitationContainer)container).addSourceCitation(sourceCitation); } - U.save( true, fonte ); - Memoria.setPrimo( fonte ); - contesto.startActivity( new Intent( contesto, Fonte.class ) ); + U.save(true, source); + Memory.setPrimo(source); + context.startActivity(new Intent(context, Fonte.class)); } // Elimina la fonte, i Ref in tutte le SourceCitation che puntano ad essa, e le SourceCitation vuote // Restituisce un array dei capostipiti modificati // Todo le citazioni alla Source eliminata diventano Fonte-nota a cui bisognerebbe poter riattaccare una Source - public static Object[] eliminaFonte( Source fon ) { - ListaCitazioniFonte citazioni = new ListaCitazioniFonte( gc, fon.getId() ); + public static Object[] eliminaFonte(Source source) { + ListaCitazioniFonte citazioni = new ListaCitazioniFonte(gc, source.getId()); for( ListaCitazioniFonte.Tripletta cita : citazioni.lista ) { - SourceCitation sc = cita.citazione; - sc.setRef( null ); + SourceCitation cit = cita.citazione; + cit.setRef(null); // Se la SourceCitation non contiene altro si può eliminare boolean eliminabile = true; - if( sc.getPage()!=null || sc.getDate()!=null || sc.getText()!=null || sc.getQuality()!=null - || !sc.getAllNotes(gc).isEmpty() || !sc.getAllMedia(gc).isEmpty() || !sc.getExtensions().isEmpty() ) + if( cit.getPage() != null || cit.getDate() != null || cit.getText() != null || cit.getQuality() != null + || !cit.getAllNotes(gc).isEmpty() || !cit.getAllMedia(gc).isEmpty() || !cit.getExtensions().isEmpty() ) eliminabile = false; if( eliminabile ) { Object contenitore = cita.contenitore; @@ -271,20 +274,20 @@ public static Object[] eliminaFonte( Source fon ) { lista = ((Note)contenitore).getSourceCitations(); else lista = ((SourceCitationContainer)contenitore).getSourceCitations(); - lista.remove( sc ); + lista.remove(cit); if( lista.isEmpty() ) { if( contenitore instanceof Note ) - ((Note)contenitore).setSourceCitations( null ); + ((Note)contenitore).setSourceCitations(null); else - ((SourceCitationContainer)contenitore).setSourceCitations( null ); + ((SourceCitationContainer)contenitore).setSourceCitations(null); } } } - gc.getSources().remove( fon ); + gc.getSources().remove(source); if( gc.getSources().isEmpty() ) - gc.setSources( null ); - gc.createIndexes(); // necessario - Memoria.annullaIstanze( fon ); + gc.setSources(null); + gc.createIndexes(); // necessario + Memory.annullaIstanze(source); return citazioni.getCapi(); } @@ -297,13 +300,13 @@ public void onCreateOptionsMenu( Menu menu, MenuInflater inflater ) { subMenu.add(0, 2, 0, R.string.title); subMenu.add(0, 3, 0, R.string.citations); - // Ricerca nella Biblioteca - inflater.inflate(R.menu.cerca, menu); - final SearchView vistaCerca = (SearchView)menu.findItem(R.id.ricerca).getActionView(); + // Search in SourcesFragment + inflater.inflate(R.menu.search, menu); + final SearchView vistaCerca = (SearchView)menu.findItem(R.id.search_item).getActionView(); vistaCerca.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextChange(String query) { - adattatore.getFilter().filter(query); + adapter.getFilter().filter(query); return true; } @Override @@ -318,14 +321,14 @@ public boolean onQueryTextSubmit(String q) { public boolean onOptionsItemSelected( MenuItem item ) { int id = item.getItemId(); if( id > 0 && id <= 3 ) { - if( ordine == id*2-1 ) - ordine++; - else if( ordine == id*2 ) - ordine--; + if( order == id*2-1 ) + order++; + else if( order == id*2 ) + order--; else - ordine = id*2-1; + order = id*2-1; ordinaFonti(); - adattatore.notifyDataSetChanged(); + adapter.notifyDataSetChanged(); return true; } return false; @@ -334,7 +337,7 @@ else if( ordine == id*2 ) private Source source; @Override public void onCreateContextMenu(ContextMenu menu, View vista, ContextMenu.ContextMenuInfo info) { - source = gc.getSource(((TextView)vista.findViewById(R.id.biblioteca_id)).getText().toString()); + source = gc.getSource(((TextView)vista.findViewById(R.id.source_id)).getText().toString()); if( Global.settings.expert ) menu.add(0, 0, 0, R.string.edit_id); menu.add(0, 1, 0, R.string.delete); diff --git a/app/src/main/java/app/familygem/visitor/ContaCitazioniFonte.java b/app/src/main/java/app/familygem/visitor/ContaCitazioniFonte.java index 3c728d22..b293b2e8 100644 --- a/app/src/main/java/app/familygem/visitor/ContaCitazioniFonte.java +++ b/app/src/main/java/app/familygem/visitor/ContaCitazioniFonte.java @@ -1,5 +1,5 @@ // Contatore delle citazioni di una fonte -// Servirebbe per sostituire U.quanteCitazioni(Source) in Biblioteca +// Servirebbe per sostituire U.quanteCitazioni(Source) in SourcesFragment // è più preciso nella conta cioè non gli sfugge nulla, ma è quattro volte più lento package app.familygem.visitor; diff --git a/app/src/main/java/app/familygem/visitor/ListaCitazioniFonte.java b/app/src/main/java/app/familygem/visitor/ListaCitazioniFonte.java index ad852907..06444f3c 100644 --- a/app/src/main/java/app/familygem/visitor/ListaCitazioniFonte.java +++ b/app/src/main/java/app/familygem/visitor/ListaCitazioniFonte.java @@ -1,5 +1,5 @@ // Partendo dall'id di una fonte genera una lista di triplette: capostipite / contenitore / citazioni della fonte -// Usato da Biblioteca, da Fonte e da Conferma +// Usato da SourcesFragment, da Fonte e da Conferma package app.familygem.visitor; diff --git a/app/src/main/java/app/familygem/visitor/ListaMediaContenitore.java b/app/src/main/java/app/familygem/visitor/ListaMediaContenitore.java index b22b3627..2b30f88f 100644 --- a/app/src/main/java/app/familygem/visitor/ListaMediaContenitore.java +++ b/app/src/main/java/app/familygem/visitor/ListaMediaContenitore.java @@ -1,5 +1,5 @@ // Mappa ordinata dei media ciascuno col suo oggetto contenitore -// Il contenitore serve praticamente solo a scollegaMedia in IndividuoMedia +// Il contenitore serve praticamente solo a scollegaMedia in ProfileMediaFragment package app.familygem.visitor; diff --git a/app/src/main/java/app/familygem/visitor/TrovaPila.java b/app/src/main/java/app/familygem/visitor/TrovaPila.java index 24efe824..5ac9a67e 100644 --- a/app/src/main/java/app/familygem/visitor/TrovaPila.java +++ b/app/src/main/java/app/familygem/visitor/TrovaPila.java @@ -1,7 +1,3 @@ -// Visitatore che produce in Memoria la pila gerarchica degli oggetti tra il record capostipite e un oggetto dato -// ad es. Person > Media semplice -// oppure Family > Note > SourceCitation > Note semplice - package app.familygem.visitor; import org.folg.gedcom.model.Change; @@ -22,41 +18,46 @@ import org.folg.gedcom.model.Visitor; import java.util.Iterator; import java.util.List; -import app.familygem.Memoria; +import app.familygem.Memory; +/** + * Visitor that generates in Memory a hierarchic stack of objects from a leader record to a given object (target) + * E.g. Person > inline Media + * or Family > inline Note > SourceCitation > inline Note + */ public class TrovaPila extends Visitor { - private List pila; - private Object scopo; - private boolean trovato; + private List stack; + private Object target; + private boolean found; - public TrovaPila( Gedcom gc, Object scopo ) { - pila = Memoria.addPila(); // in una nuova pila apposta - this.scopo = scopo; - gc.accept( this ); + public TrovaPila(Gedcom gc, Object target) { + stack = Memory.addPila(); // In a new dedicated stack + this.target = target; + gc.accept(this); } - private boolean opera( Object oggetto, String tag, boolean capostipite ) { - if( !trovato ) { - if( capostipite ) - pila.clear(); // ogni capostipite fa ricominciare da capo una pila - Memoria.Passo passo = new Memoria.Passo(); - passo.oggetto = oggetto; + private boolean opera(Object object, String tag, boolean isLeader) { + if( !found ) { + if( isLeader ) + stack.clear(); // A leader restarts the stack from the beginning + Memory.Passo passo = new Memory.Passo(); + passo.oggetto = object; passo.tag = tag; - if( !capostipite ) + if( !isLeader ) passo.filotto = true; // li marchia per eliminarli poi in blocco onBackPressed - pila.add(passo); + stack.add(passo); } - if( oggetto.equals(scopo) ) { - Iterator passi = pila.iterator(); + if( object.equals(target) ) { + Iterator passi = stack.iterator(); while( passi.hasNext() ) { - PulisciPila pulitore = new PulisciPila( scopo ); - ((Visitable)passi.next().oggetto).accept( pulitore ); + PulisciPila pulitore = new PulisciPila(target); + ((Visitable)passi.next().oggetto).accept(pulitore); if( pulitore.daEliminare ) passi.remove(); } - trovato = true; - //Memoria.stampa("TrovaPila"); + found = true; + //Memory.stampa("TrovaPila"); } return true; } diff --git a/app/src/main/res/drawable-night/diagram_year_oval.xml b/app/src/main/res/drawable-night/diagram_year_oval.xml index a91c66ec..2ea64865 100644 --- a/app/src/main/res/drawable-night/diagram_year_oval.xml +++ b/app/src/main/res/drawable-night/diagram_year_oval.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/casella_bordo_femmina.xml b/app/src/main/res/drawable/casella_bordo_femmina.xml index 74340652..fea73830 100644 --- a/app/src/main/res/drawable/casella_bordo_femmina.xml +++ b/app/src/main/res/drawable/casella_bordo_femmina.xml @@ -2,6 +2,6 @@ + android:color="@color/female" /> \ No newline at end of file diff --git a/app/src/main/res/drawable/casella_bordo_maschio.xml b/app/src/main/res/drawable/casella_bordo_maschio.xml index fc08a8bb..debdedec 100644 --- a/app/src/main/res/drawable/casella_bordo_maschio.xml +++ b/app/src/main/res/drawable/casella_bordo_maschio.xml @@ -2,6 +2,6 @@ + android:color="@color/male" /> \ No newline at end of file diff --git a/app/src/main/res/drawable/casella_sfondo_evidente.xml b/app/src/main/res/drawable/casella_sfondo_evidente.xml index 03879b30..ace4f964 100644 --- a/app/src/main/res/drawable/casella_sfondo_evidente.xml +++ b/app/src/main/res/drawable/casella_sfondo_evidente.xml @@ -2,8 +2,8 @@ \ No newline at end of file diff --git a/app/src/main/res/drawable/casella_sfondo_sposo.xml b/app/src/main/res/drawable/casella_sfondo_sposo.xml index e373c8fe..5ae39601 100644 --- a/app/src/main/res/drawable/casella_sfondo_sposo.xml +++ b/app/src/main/res/drawable/casella_sfondo_sposo.xml @@ -1,5 +1,5 @@ - + diff --git a/app/src/main/res/drawable/casella_sfondo_sposo_stampa.xml b/app/src/main/res/drawable/casella_sfondo_sposo_stampa.xml index e2aa9b12..b8ccee74 100644 --- a/app/src/main/res/drawable/casella_sfondo_sposo_stampa.xml +++ b/app/src/main/res/drawable/casella_sfondo_sposo_stampa.xml @@ -1,5 +1,5 @@ - + diff --git a/app/src/main/res/drawable/cerchietto.xml b/app/src/main/res/drawable/cerchietto.xml index fa9742d0..4d8f186f 100644 --- a/app/src/main/res/drawable/cerchietto.xml +++ b/app/src/main/res/drawable/cerchietto.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/diagram_hearth.xml b/app/src/main/res/drawable/diagram_hearth.xml index 8d99a262..a3c43ac1 100644 --- a/app/src/main/res/drawable/diagram_hearth.xml +++ b/app/src/main/res/drawable/diagram_hearth.xml @@ -1,4 +1,4 @@ - + diff --git a/app/src/main/res/drawable/diagram_hearth_print.xml b/app/src/main/res/drawable/diagram_hearth_print.xml index 1c2f3dfe..320163f1 100644 --- a/app/src/main/res/drawable/diagram_hearth_print.xml +++ b/app/src/main/res/drawable/diagram_hearth_print.xml @@ -1,4 +1,4 @@ - + diff --git a/app/src/main/res/drawable/frecciona.xml b/app/src/main/res/drawable/frecciona.xml index 86b2893e..176346d6 100644 --- a/app/src/main/res/drawable/frecciona.xml +++ b/app/src/main/res/drawable/frecciona.xml @@ -5,6 +5,6 @@ android:viewportWidth="30.0" android:viewportHeight="10.0"> \ No newline at end of file diff --git a/app/src/main/res/drawable/ruotina.xml b/app/src/main/res/drawable/gear.xml similarity index 100% rename from app/src/main/res/drawable/ruotina.xml rename to app/src/main/res/drawable/gear.xml diff --git a/app/src/main/res/drawable/icon_background.xml b/app/src/main/res/drawable/icon_background.xml index cc8f6bf7..ca38eb24 100644 --- a/app/src/main/res/drawable/icon_background.xml +++ b/app/src/main/res/drawable/icon_background.xml @@ -1,5 +1,5 @@ - + diff --git a/app/src/main/res/drawable/menu_sfondo.xml b/app/src/main/res/drawable/menu_sfondo.xml index 3e25a63a..25ad9c0d 100644 --- a/app/src/main/res/drawable/menu_sfondo.xml +++ b/app/src/main/res/drawable/menu_sfondo.xml @@ -3,8 +3,8 @@ android:shape="rectangle"> \ No newline at end of file diff --git a/app/src/main/res/drawable/segnalino.xml b/app/src/main/res/drawable/segnalino.xml index 3e053b1f..68cb32f3 100644 --- a/app/src/main/res/drawable/segnalino.xml +++ b/app/src/main/res/drawable/segnalino.xml @@ -5,6 +5,6 @@ android:viewportWidth="10.0" android:viewportHeight="12.0"> \ No newline at end of file diff --git a/app/src/main/res/drawable/sghembo.xml b/app/src/main/res/drawable/sghembo.xml index a9deab99..fa4b7525 100644 --- a/app/src/main/res/drawable/sghembo.xml +++ b/app/src/main/res/drawable/sghembo.xml @@ -6,6 +6,6 @@ android:viewportHeight="5.0" android:autoMirrored="true"> \ No newline at end of file diff --git a/app/src/main/res/drawable/thumb.xml b/app/src/main/res/drawable/thumb.xml index 2501f33a..a6839067 100644 --- a/app/src/main/res/drawable/thumb.xml +++ b/app/src/main/res/drawable/thumb.xml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/app/src/main/res/layout/diagram_asterisk.xml b/app/src/main/res/layout/diagram_asterisk.xml index 9a8de5d8..fdb6cfdc 100644 --- a/app/src/main/res/layout/diagram_asterisk.xml +++ b/app/src/main/res/layout/diagram_asterisk.xml @@ -5,7 +5,7 @@ android:paddingLeft="6dp" android:paddingRight="6dp" android:text="*" - android:textColor="@color/evidenzia" + android:textColor="@color/accent" android:textSize="60sp" android:height="55dp" android:layout_marginTop="-10dp"/> \ No newline at end of file diff --git a/app/src/main/res/layout/diagram_settings.xml b/app/src/main/res/layout/diagram_settings.xml index 3d77f27c..d9e9deeb 100644 --- a/app/src/main/res/layout/diagram_settings.xml +++ b/app/src/main/res/layout/diagram_settings.xml @@ -4,106 +4,97 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> - - - + android:text="@string/generations_display_diagram"/> + android:layout_marginTop="20dp" + android:text="@string/ancestors"/> - + android:max="9"/> + android:layout_marginTop="40dp" + android:text="@string/uncles_great_uncles"/> - + android:max="9"/> - + android:layout_marginTop="40dp" + android:text="@string/partners"/> + android:layout_marginTop="40dp" + android:text="@string/descendants"/> - + android:max="9"/> + android:layout_marginTop="40dp" + android:text="@string/siblings_nephews"/> - + android:max="9"/> + android:layout_marginTop="40dp" + android:text="@string/uncles_cousins"/> - + android:max="9"/> + android:gravity="center_horizontal" + android:orientation="vertical"> - \ No newline at end of file + diff --git a/app/src/main/res/layout/dispensa.xml b/app/src/main/res/layout/dispensa.xml index 35442f2c..c4eed547 100644 --- a/app/src/main/res/layout/dispensa.xml +++ b/app/src/main/res/layout/dispensa.xml @@ -21,7 +21,7 @@ android:id="@+id/dispensa_scatola" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@color/primarioChiaro" + android:background="@color/primary_light" android:orientation="vertical" android:paddingLeft="8dp" android:paddingRight="8dp" diff --git a/app/src/main/res/layout/editore_data.xml b/app/src/main/res/layout/editore_data.xml index 001a9a18..10c2668a 100644 --- a/app/src/main/res/layout/editore_data.xml +++ b/app/src/main/res/layout/editore_data.xml @@ -4,131 +4,112 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> - - + android:text="@string/approximate"/> - - + android:textSize="18sp"/> - + android:text="B.C."/> + android:text="@string/double_date"/> - - + android:orientation="horizontal" + android:layoutDirection="ltr"> - + android:theme="@style/AppTheme.Wheel"/> - + android:theme="@style/AppTheme.Wheel"/> - + android:theme="@style/AppTheme.Wheel"/> - + android:theme="@style/AppTheme.Wheel"/> - - - + android:text="B.C."/> + android:text="@string/double_date"/> - - - + android:theme="@style/AppTheme.Wheel"/> - + android:theme="@style/AppTheme.Wheel"/> - + android:theme="@style/AppTheme.Wheel"/> - + android:theme="@style/AppTheme.Wheel"/> - - \ No newline at end of file + diff --git a/app/src/main/res/layout/pezzo_famiglia.xml b/app/src/main/res/layout/families_item.xml similarity index 95% rename from app/src/main/res/layout/pezzo_famiglia.xml rename to app/src/main/res/layout/families_item.xml index 712ae2f0..8b9f82fa 100644 --- a/app/src/main/res/layout/pezzo_famiglia.xml +++ b/app/src/main/res/layout/families_item.xml @@ -17,7 +17,7 @@ android:id="@+id/family_info" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="@color/grayText" + android:textColor="@color/gray_text" android:textSize="14sp"/> - \ No newline at end of file + diff --git a/app/src/main/res/layout/galleria.xml b/app/src/main/res/layout/gallery.xml similarity index 72% rename from app/src/main/res/layout/galleria.xml rename to app/src/main/res/layout/gallery.xml index 5e9e2a9c..03763f09 100644 --- a/app/src/main/res/layout/galleria.xml +++ b/app/src/main/res/layout/gallery.xml @@ -3,16 +3,13 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> - - + android:paddingBottom="80dp" + android:scrollbarStyle="outsideOverlay" + android:scrollbars="vertical"/> - - \ No newline at end of file + diff --git a/app/src/main/res/layout/individuo.xml b/app/src/main/res/layout/individuo.xml index 25895d7b..818a597d 100644 --- a/app/src/main/res/layout/individuo.xml +++ b/app/src/main/res/layout/individuo.xml @@ -4,86 +4,73 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" - android:fitsSystemWindows="true" > - + android:fitsSystemWindows="true"> - - + android:layout_height="250dp" + android:fitsSystemWindows="true" + app:contentScrim="?attr/colorPrimary" + app:expandedTitleGravity="center_horizontal|bottom" + app:expandedTitleMarginBottom="55dp" + app:layout_scrollFlags="scroll|exitUntilCollapsed"> - + app:layout_collapseMode="parallax"/> + android:layout_height="150dp" + android:layout_gravity="center_horizontal" + android:layout_marginTop="15dp"/> + android:layout_marginTop="140dp" + android:textStyle="bold" + app:layout_collapseMode="parallax"/> + + + + + - - - - - - - - - - - - - - + app:layout_behavior="@string/appbar_scrolling_view_behavior"/> - - \ No newline at end of file + diff --git a/app/src/main/res/layout/individuo_eventi_pezzo.xml b/app/src/main/res/layout/individuo_eventi_pezzo.xml index 673ba471..6db2b0fc 100644 --- a/app/src/main/res/layout/individuo_eventi_pezzo.xml +++ b/app/src/main/res/layout/individuo_eventi_pezzo.xml @@ -33,7 +33,7 @@ android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" android:layout_marginBottom="8dp" - android:background="@color/citazioneFonte" + android:background="@color/source_citation" android:padding="4dp" android:visibility="gone" /> @@ -42,5 +42,5 @@ android:layout_height="1dp" android:layout_below="@+id/evento_altro" android:layout_marginTop="8dp" - android:background="@color/primario" /> + android:background="@color/primary" /> \ No newline at end of file diff --git a/app/src/main/res/layout/lapide.xml b/app/src/main/res/layout/lapide.xml index 6665b999..d4f2fe7d 100644 --- a/app/src/main/res/layout/lapide.xml +++ b/app/src/main/res/layout/lapide.xml @@ -49,6 +49,6 @@ android:layout_marginTop="20dp" android:padding="4dp" android:text="www.familygem.app" - android:textColor="@color/primarioScuro"/> + android:textColor="@color/primary_dark"/> \ No newline at end of file diff --git a/app/src/main/res/layout/menu_item_extra.xml b/app/src/main/res/layout/menu_item_extra.xml index fe407303..5159a28d 100644 --- a/app/src/main/res/layout/menu_item_extra.xml +++ b/app/src/main/res/layout/menu_item_extra.xml @@ -7,6 +7,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" - android:textColor="@color/grayText" + android:textColor="@color/gray_text" android:layout_gravity="center_vertical"/> diff --git a/app/src/main/res/layout/albero_nuovo.xml b/app/src/main/res/layout/new_tree.xml similarity index 87% rename from app/src/main/res/layout/albero_nuovo.xml rename to app/src/main/res/layout/new_tree.xml index 32413cb4..391b6346 100644 --- a/app/src/main/res/layout/albero_nuovo.xml +++ b/app/src/main/res/layout/new_tree.xml @@ -4,11 +4,9 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true"> - - -