Skip to content

Instantly share code, notes, and snippets.

@pagetronic
Created January 31, 2022 16:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pagetronic/f4cc68f8d949fa4977d4c115e1639a7e to your computer and use it in GitHub Desktop.
Save pagetronic/f4cc68f8d949fa4977d4c115e1639a7e to your computer and use it in GitHub Desktop.
Intent modeler
package fr.gendarmerie.docpro.settings.shortcuts;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.graphics.drawable.Icon;
import androidx.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import fr.gendarmerie.docpro.BuildConfig;
import fr.gendarmerie.docpro.R;
import fr.gendarmerie.docpro.settings.shortcuts.launcher.ActivityShortcutsReceiver;
import fr.gendarmerie.docpro.tabs.TabBookmarks;
import fr.gendarmerie.docpro.tabs.TabDomaines;
import fr.gendarmerie.docpro.tabs.TabFiches;
import fr.gendarmerie.docpro.tabs.TabFormation;
import fr.gendarmerie.docpro.tabs.TabGuides;
import fr.gendarmerie.docpro.tabs.TabMementos;
import fr.gendarmerie.docpro.tabs.TabReflexes;
import fr.gendarmerie.docpro.tabs.TabRestreint;
import fr.gendarmerie.docpro.tabs.TabUpdates;
import fr.gendarmerie.docpro.tabs.TabVideos;
import fr.gendarmerie.docpro.tabs.bases.TabBase;
import fr.gendarmerie.docpro.tabs.bases.TabBaseNodes;
import fr.gendarmerie.docpro.utils.DocumentType;
import fr.gendarmerie.docpro.utils.Fx;
/**
* Class permettant de modéliser les Onglets.
* Elle permet à la fois de créer les Intent pour composer un lanceur et de les parser afin de composer l'interface.
*/
public class ShortsModels {
/*
* Raccourcis proposé par défaut. Dans la page des parametres.
*/
private static final List<Model> baseShortcuts = Arrays.asList(
new Model("Mementos", R.drawable.icon_justice,
new Model.TabModel(TabMementos.class),
new Model.TabModel(TabReflexes.class),
new Model.TabModel(TabBookmarks.class, DocumentType.MEMENTOS, DocumentType.FICHES_REFLEXES),
new Model.TabModel(TabUpdates.class, DocumentType.MEMENTOS, DocumentType.FICHES_REFLEXES)
),
new Model("Vidéos", R.drawable.icon_video,
new Model.TabModel(TabVideos.class),
new Model.TabModel(TabBookmarks.class, DocumentType.VIDEOS),
new Model.TabModel(TabUpdates.class, DocumentType.VIDEOS)
),
new Model("DocPro Simple", R.drawable.icon_docpro_black,
new Model.TabModel(TabDomaines.class),
new Model.TabModel(TabMementos.class),
new Model.TabModel(TabBookmarks.class),
new Model.TabModel(TabUpdates.class)
)
);
/*
* Onglets de base sans personnalisation.
*/
private static final List<Class<? extends TabBase>> failsafe = Arrays.asList(
TabDomaines.class,
TabMementos.class,
TabFiches.class,
TabReflexes.class,
TabGuides.class,
TabVideos.class,
TabFormation.class,
TabUpdates.class,
TabRestreint.class,
TabBookmarks.class
);
/*
* Caractères utilisés pour transposer un model en chaine de caractères passée en Intent.
*/
private static final String INTENT_TAB_KEY = "basetabs";
private static final String INTENT_TAB_SEPARATOR = ", ";
private static final String INTENT_TAB_DOCS_START = "@";
private static final String INTENT_TAB_DOCS_SEPARATOR = "+";
/**
* Récupérer les racourics proposés par défaut.
*
* @return Un tableau de models
*/
public static List<Model> getBaseShortcuts() {
return baseShortcuts;
}
/**
* Récupérer les Tabs si elles sont transmise en Intent.
*
* @param intent l'intent qui peut etre inexistante
* @return la liste des Onglets dans l'ordre et paramatrés en fonction.
*/
public static List<TabBase> getTabs(@Nullable Intent intent) {
List<TabBase> basetabs = new ArrayList<>();
if (intent != null && intent.hasExtra(INTENT_TAB_KEY)) {
for (String basetabsIntent : intent.getStringExtra(INTENT_TAB_KEY).split(Pattern.quote(INTENT_TAB_SEPARATOR))) {
try {
String[] setting = basetabsIntent.split(INTENT_TAB_DOCS_START);
@SuppressWarnings("unchecked")
TabBase frag = ((Class<? extends TabBase>) Class.forName(setting[0])).newInstance();
if (setting.length > 1) {
TabBaseNodes fragNode = ((TabBaseNodes) frag);
fragNode.clearDocumentsTypes();
for (String type : setting[1].split(Pattern.quote(INTENT_TAB_DOCS_SEPARATOR))) {
fragNode.checkDocumentsTypes(true, DocumentType.find(Integer.parseInt(type)));
}
}
basetabs.add(frag);
} catch (Exception e) {
if (BuildConfig.DEBUG) {
e.printStackTrace();
}
}
}
return basetabs;
}
for (Class<? extends TabBase> tab : failsafe) {
try {
basetabs.add(tab.newInstance());
} catch (Exception e) {
if (BuildConfig.DEBUG) {
e.printStackTrace();
}
}
}
return basetabs;
}
/**
* Une classe de modélisation d'un lanceur d'une interface personnalisée
*/
public static class Model {
private final String title;
private final int logo;
private final List<TabModel> tabs;
/**
* Créer un modèle de lanceur
*
* @param title du lanceur
* @param logo du lanceur
* @param tabs Onglets chargés par le lanceur
*/
public Model(String title, int logo, TabModel... tabs) {
this(title, logo, tabs != null && tabs.length > 0 ? Arrays.asList(tabs) : new ArrayList<>());
}
/**
* Créer un modèle de lanceur
*
* @param title du lanceur
* @param logo du lanceur
* @param tabs Onglets chargés par le lanceur
*/
public Model(String title, int logo, List<TabModel> tabs) {
this.title = title;
this.logo = logo;
this.tabs = tabs;
}
/**
* @return le logo
*/
public int getLogo() {
return logo;
}
/**
* @return le titre
*/
public String getTitle() {
return title;
}
/**
* Récupérer le ShortcutInfo du Model
*
* @param context le context pour accéder aux ressources
*
* @return ShortcutInfo les informations de racourcis
*/
public ShortcutInfo getShortCutInfo(Context context) {
Intent intent = new Intent(context, ActivityShortcutsReceiver.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(INTENT_TAB_KEY, getBasetabs());
String id = "docpro_" + Fx.getRandomString(10);
intent.putExtra("title", getTitle());
intent.putExtra("id", id);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
Icon icon = Icon.createWithResource(context, getLogo());
return new ShortcutInfo.Builder(context, id)
.setIntent(intent)
.setIcon(icon)
.setShortLabel(getTitle()).build();
}
/**
* Récupérer la représentation texte du modèle
*
* @return la représentation
*/
private String getBasetabs() {
List<String> basetabs = new ArrayList<>();
for (TabModel basetab : this.tabs) {
basetabs.add(basetab.getBasetab());
}
return StringUtils.join(basetabs, INTENT_TAB_SEPARATOR);
}
/**
* Une classe de modélisation d'un onglet de lanceur
*/
public static class TabModel {
private final Class<? extends TabBase> tab;
private final List<DocumentType> documentTypes;
private TabBase tabInstance = null;
/**
* @param tab la classe de l'onglet
* @param documentTypes les types documents à afficher
*/
public TabModel(Class<? extends TabBaseNodes> tab, DocumentType... documentTypes) {
this.tab = tab;
this.documentTypes = documentTypes != null && documentTypes.length > 0 ? Arrays.asList(documentTypes) : new ArrayList<>();
}
/**
* @param tab la classe de l'onglet
*/
public TabModel(Class<? extends TabBase> tab) {
this.tab = tab;
this.documentTypes = new ArrayList<>();
}
/**
* Récupérer la représentation texte du modèle d'onglet
*
* @return la représentation
*/
public String getBasetab() {
String baseTab = tab.getCanonicalName();
if (documentTypes != null) {
baseTab += INTENT_TAB_DOCS_START + StringUtils.join(documentTypes, INTENT_TAB_DOCS_SEPARATOR);
}
return baseTab;
}
/**
* @return la classe de l'onglet
*/
public Class<? extends TabBase> getTab() {
return tab;
}
/**
* Pas très propre, mais pas le choix pour avoir un fichier de strings à distribuer pour la correction d'orthographe.
*
* unchecked parce que je ne sais pas comment vérifier.
*
* @return une instance de l'onglet
*/
@SuppressWarnings("unchecked")
public <T extends TabBase> T getTabInstance() {
if (tabInstance == null) {
try {
tabInstance = tab.newInstance();
} catch (Exception ignore) {
}
}
return (T) tabInstance;
}
/**
* Ajouter ou supprimer un type de document au model
*
* @param add à true s'il faut ajouter, à false pour enlever
* @param documentType le type de document à enlever ou ajouter
*/
public void setDocumentType(boolean add, final DocumentType documentType) {
if (add) {
if (!documentTypes.contains(documentType)) {
documentTypes.add(documentType);
}
} else {
documentTypes.remove(documentType);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment