diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index 4ca3d3bd4273a121ab6ad26bb613d616db4998b3..1dfdd380e142e53466e4f6d482f529a6367ceb12 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -408,6 +408,5 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
         this.formulaireService.createFormulaire(nubPointer.nub.calcType, nubPointer.nub, nubPointer.meta.title).then((f) => {
             this.router.navigate(["/calculator", f.uid]);
         });
-        // console.log("__Nubs en session apr", Session.getInstance()["_nubs"].length);
     }
 }
diff --git a/src/app/services/formulaire/formulaire.service.ts b/src/app/services/formulaire/formulaire.service.ts
index 842b8bdd0dda3ca738f8fcbcf0381571641bfcd0..85e6bb0ac6cb3f0cb4d8cc76ba42fa7674db19f0 100644
--- a/src/app/services/formulaire/formulaire.service.ts
+++ b/src/app/services/formulaire/formulaire.service.ts
@@ -96,11 +96,58 @@ export class FormulaireService extends Observable {
         }
     }
 
+    /**
+     * Retourne le titre complet du type de module de calcul, dans la langue en cours
+     */
     public getLocalisedTitleFromCalculatorType(type: CalculatorType) {
         const sCalculator: string = CalculatorType[type].toUpperCase();
         return this._intlService.localizeText(`INFO_${sCalculator}_TITRE`);
     }
 
+    /**
+     * Retourne le titre cour du type de module de calcul, dans la langue en cours
+     * (pour les titres d'onglets par défaut)
+     */
+    public getLocalisedShortTitleFromCalculatorType(type: CalculatorType) {
+        const sCalculator: string = CalculatorType[type].toUpperCase();
+        return this._intlService.localizeText(`INFO_${sCalculator}_TITRE_COURT`);
+    }
+
+    /**
+     * Checks if the given calculator name (tab title) is already used by any existing
+     * form; if so, adds a number after it
+     */
+    private suffixNameIfNeeded(name: string) {
+        let found = false;
+        let maxNumber = 0;
+
+        // extract base name
+        let baseName = name;
+        const re1 = new RegExp("^.+( \\d+)$");
+        const matches1 = re1.exec(name);
+        if (matches1) {
+            baseName = baseName.replace(matches1[1], "");
+        }
+
+        // browse session calculators
+        const re2 = new RegExp("^" + baseName + "( (\\d+))?$");
+        for (const f of this.formulaires) {
+            const matches2 = re2.exec(f.calculatorName);
+            if (matches2) {
+                found = true;
+                if (matches2[2] !== undefined) {
+                    const nb = Number(matches2[2]);
+                    maxNumber = Math.max(maxNumber, nb);
+                }
+            }
+        }
+        // suffix if needed
+        if (found) {
+            name = baseName + " " + (maxNumber + 1);
+        }
+        return name;
+    }
+
     public loadConfig(ct: CalculatorType): Promise<any> {
         const f: string = this.getConfigPathPrefix(ct) + "config.json";
         return this._httpService.httpGetRequestPromise(f);
@@ -161,24 +208,31 @@ export class FormulaireService extends Observable {
         const prom: Promise<any> = this.loadConfig(ct);
         return prom.then(s => {
             f.preparseConfig(s);
+
             // Associe le Nub fourni (chargement de session / duplication de module), sinon en crée un nouveau
             if (nub) {
                 f.currentNub = nub;
             } else {
                 f.initNub();
             }
-            // Restaure le nom du module
+
+            // Restaure le nom du module, sinon affecte le nom par défaut
+            let tempName: string;
             if (calculatorName) {
-                f.calculatorName = calculatorName;
+                tempName = calculatorName;
             } else {
-                f.calculatorName = decode(this.getLocalisedTitleFromCalculatorType(ct));
+                tempName = decode(this.getLocalisedShortTitleFromCalculatorType(ct));
             }
+            // Suffixe le nom du module si nécessaire
+            f.calculatorName = this.suffixNameIfNeeded(tempName);
+
             f.parseConfig();
+
             // add fieldsets for existing structures if needed
             if (f.currentNub instanceof ParallelStructure) {
                 for (s of f.currentNub.structures) {
                     for (const e of f.allFormElements) {
-                        if (e instanceof FieldsetContainer) { // @TODO manage many containers one day
+                        if (e instanceof FieldsetContainer) { // @TODO manage many containers one day ?
                             e.addFromTemplate(0, undefined, s);
                         }
                     }
diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index 4e0057b97cfc9a65f15972f8dee961f13c8a1693..d1a56cc1cfd1a8efc8fa949fdfa7579f129eec91 100644
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -41,11 +41,15 @@
     "INFO_CALCULATOR_RESULTS_TITLE": "Results",
     "INFO_CALCULATOR_VALEURS": "Values",
     "INFO_CLOISONS_TITRE": "Fish ladder: Cross walls",
+    "INFO_CLOISONS_TITRE_COURT": "Cross walls",
     "INFO_CLOSE_DIALOGUE_TEXT": "Warning ! Parameters and results will be lost. Really close?",
     "INFO_CLOSE_DIALOGUE_TITRE": "Please confirm",
     "INFO_CONDUITEDISTRIBUTRICE_TITRE": "Distributor pipe",
+    "INFO_CONDUITEDISTRIBUTRICE_TITRE_COURT": "D. pipe",
     "INFO_COURBEREMOUS_TITRE": "Backwater curves",
+    "INFO_COURBEREMOUS_TITRE_COURT": "B. curves",
     "INFO_DEVER_TITRE": "Free flow weir stage-discharge laws",
+    "INFO_DEVER_TITRE_COURT": "Free flow SD",
     "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_0": "Emergent",
     "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_1": "Quasi-emergent",
     "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_2": "Submerged",
@@ -104,6 +108,7 @@
     "INFO_EXTRARES_LIB_YT": "Supercritical depth (m)",
     "INFO_EXTRARES_LIB_ZF2": "Downstream bottom elevation (m)",
     "INFO_LECHAPTCALMON_TITRE": "Lechapt-Calmon",
+    "INFO_LECHAPTCALMON_TITRE_COURT": "Lechapt-Calmon",
     "INFO_LIB_ALPHA": "Alpha coefficient",
     "INFO_LIB_BETA": "Beta coefficient",
     "INFO_LIB_CD": "Discharge coefficient",
@@ -121,6 +126,7 @@
     "INFO_LIB_ZRAM": "Upstream apron elevation (m)",
     "INFO_LIB_ZT": "Triangle top elevation (m)",
     "INFO_MACRORUGO_TITRE": "Rock-ramp fishpasses",
+    "INFO_MACRORUGO_TITRE_COURT": "RR fishpasses",
     "INFO_MENU_HELP_TITLE": "Help",
     "INFO_MENU_LOAD_SESSION_TITLE": "Load session",
     "INFO_MENU_NOUVELLE_CALC": "New calculation module",
@@ -140,8 +146,11 @@
     "INFO_OPTION_NONE_F": "None",
     "INFO_OUVRAGE": "Structure",
     "INFO_PABDIMENSIONS_TITRE": "Fish ladder: dimensions",
+    "INFO_PABDIMENSIONS_TITRE_COURT": "FL: dimensions",
     "INFO_PABPUISSANCE_TITRE": "Fish ladder: dissipated power",
+    "INFO_PABPUISSANCE_TITRE_COURT": "FL: diss. power",
     "INFO_PARALLELSTRUCTURE_TITRE": "Parallel structures",
+    "INFO_PARALLELSTRUCTURE_TITRE_COURT": "// structures",
     "INFO_PARAMFIELD_GRAPH_TYPE": "Graph type",
     "INFO_PARAMFIELD_GRAPH_TYPE_HISTOGRAM": "Histogram",
     "INFO_PARAMFIELD_IN_CALCULATION": "In calculation",
@@ -167,6 +176,7 @@
     "INFO_PARAMMODE_MINMAX": "Min/max",
     "INFO_PARAMMODE_LIST": "Values list",
     "INFO_REGIMEUNIFORME_TITRE": "Uniform flow calculation",
+    "INFO_REGIMEUNIFORME_TITRE_COURT": "Uniform flow",
     "INFO_REMOUSRESULTS_ABSCISSE": "Abscissa (m)",
     "INFO_REMOUSRESULTS_BERGE": "Embankment",
     "INFO_REMOUSRESULTS_FOND": "Bottom",
@@ -182,6 +192,7 @@
     "INFO_REMOUS_RESSAUT_DEHORS": "Hydraulic jump detected %sens% abscissa %x% m",
     "INFO_REMOUS_RESSAUT_HYDRO": "Hydraulic jump detected between abscissa %xmin% and %xmax% m",
     "INFO_SECTIONPARAMETREE_TITRE": "Parametric section",
+    "INFO_SECTIONPARAMETREE_TITRE_COURT": "Param. section",
     "INFO_SETUP_NEWTON_MAX_ITER": "Newton iteration limit",
     "INFO_SETUP_PRECISION_AFFICHAGE": "Display accuracy",
     "INFO_SETUP_PRECISION_CALCUL": "Computation accuracy",
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index 0b88860267614c05862ab3569966e0fb4a9ac758..8dbc1646b5caefed4424d5b3d577d7e748864dc9 100644
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -41,11 +41,15 @@
     "INFO_CALCULATOR_RESULTS_TITLE": "Résultats",
     "INFO_CALCULATOR_VALEURS": "Valeurs",
     "INFO_CLOISONS_TITRE": "Passe à bassin&nbsp;: Cloisons",
+    "INFO_CLOISONS_TITRE_COURT": "Cloisons",
     "INFO_CLOSE_DIALOGUE_TEXT": "Attention&nbsp;! Les paramètres et résultats du module de calcul seront perdus. Vraiment fermer&nbsp;?",
     "INFO_CLOSE_DIALOGUE_TITRE": "Confirmer la fermeture",
     "INFO_CONDUITEDISTRIBUTRICE_TITRE": "Conduite distributrice",
+    "INFO_CONDUITEDISTRIBUTRICE_TITRE_COURT": "Conduite distri.",
     "INFO_COURBEREMOUS_TITRE": "Courbes de remous",
+    "INFO_COURBEREMOUS_TITRE_COURT": "Remous",
     "INFO_DEVER_TITRE": "Lois de déversoirs dénoyés",
+    "INFO_DEVER_TITRE_COURT": "Déver. dénoyés",
     "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_0": "Emergent",
     "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_1": "Quasi-émergent",
     "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_2": "Immergé",
@@ -104,6 +108,7 @@
     "INFO_EXTRARES_LIB_YT": "Tirant d'eau torrentiel (m)",
     "INFO_EXTRARES_LIB_ZF2": "Cote de fond aval (m)",
     "INFO_LECHAPTCALMON_TITRE": "Lechapt-Calmon",
+    "INFO_LECHAPTCALMON_TITRE_COURT": "Lechapt-Calmon",
     "INFO_LIB_ALPHA": "Coefficient alpha",
     "INFO_LIB_BETA": "Coefficient béta",
     "INFO_LIB_CD": "Coefficient de débit",
@@ -127,6 +132,7 @@
     "INFO_MENU_EMPTY_SESSION_TITLE": "Nouvelle session",
     "INFO_MENU_NOUVELLE_CALC": "Nouveau module de calcul",
     "INFO_MACRORUGO_TITRE": "Passe à macro-rugosités",
+    "INFO_MACRORUGO_TITRE_COURT": "Macro-rugo.",
     "INFO_OPTION_NO": "Non",
     "INFO_OPTION_YES": "Oui",
     "INFO_OPTION_CANCEL": "Annuler",
@@ -140,8 +146,11 @@
     "INFO_OPTION_NONE_F": "Aucune",
     "INFO_OUVRAGE": "Ouvrage",
     "INFO_PABDIMENSIONS_TITRE": "Passe à bassin&nbsp;: dimensions",
+    "INFO_PABDIMENSIONS_TITRE_COURT": "PAB&nbsp;: dimensions",
     "INFO_PABPUISSANCE_TITRE": "Passe à bassin&nbsp;: puissance dissipée",
+    "INFO_PABPUISSANCE_TITRE_COURT": "PAB&nbsp;: puissance",
     "INFO_PARALLELSTRUCTURE_TITRE": "Lois d'ouvrages",
+    "INFO_PARALLELSTRUCTURE_TITRE_COURT": "Ouvrages",
     "INFO_PARAMFIELD_GRAPH_TYPE": "Type de graphe",
     "INFO_PARAMFIELD_GRAPH_TYPE_HISTOGRAM": "Histogramme",
     "INFO_PARAMFIELD_IN_CALCULATION": "En calcul",
@@ -167,6 +176,7 @@
     "INFO_PARAMMODE_MINMAX": "Min/max",
     "INFO_PARAMMODE_LIST": "Liste de valeurs",
     "INFO_REGIMEUNIFORME_TITRE": "Régime uniforme",
+    "INFO_REGIMEUNIFORME_TITRE_COURT": "R. uniforme",
     "INFO_REMOUSRESULTS_ABSCISSE": "Abscisse (m)",
     "INFO_REMOUSRESULTS_BERGE": "Berge",
     "INFO_REMOUSRESULTS_FOND": "Fond",
@@ -182,6 +192,7 @@
     "INFO_REMOUS_RESSAUT_DEHORS": "Ressaut hydraulique détecté à l'%sens% de l'abscisse %x% m",
     "INFO_REMOUS_RESSAUT_HYDRO": "Ressaut hydraulique détecté entre les abscisses %xmin% et %xmax% m",
     "INFO_SECTIONPARAMETREE_TITRE": "Section paramétrée",
+    "INFO_SECTIONPARAMETREE_TITRE_COURT": "Sec. param.",
     "INFO_SETUP_NEWTON_MAX_ITER": "Newton : nombre d'itérations maximum",
     "INFO_SETUP_PRECISION_AFFICHAGE": "Précision d'affichage",
     "INFO_SETUP_PRECISION_CALCUL": "Précision de calcul",