diff --git a/src/module_vmap/module/javascript/app/vmap/tools/select/select.js b/src/module_vmap/module/javascript/app/vmap/tools/select/select.js
index 568395bf3cfad59de8c1f56c7ef278b2a33a1f34..2da086c67cb0d4828412271e0642000597b4c0b5 100755
--- a/src/module_vmap/module/javascript/app/vmap/tools/select/select.js
+++ b/src/module_vmap/module/javascript/app/vmap/tools/select/select.js
@@ -1556,7 +1556,7 @@ nsVmap.nsToolsManager.Select.prototype.selectController.prototype.updateBOValues
         'method': 'PUT',
         'url': oVmap['properties']['api_url'] + '/vmap/querys/' + bo_type,
         'headers': {
-            'Accept': 'application/x-vm-json'
+            'Accept': 'application/x-vm-json',
         },
         'data': data,
         'scope': this.$scope_,
@@ -1648,6 +1648,7 @@ nsVmap.nsToolsManager.Select.prototype.selectController.prototype.getFormDataFro
     oVmap.log('nsVmap.nsToolsManager.Select.prototype.selectController.prototype.getFormDataFromValues');
 
     var oFormData_ = new FormData();
+    var oUnchangedFiles = {};
 
     for (var key in oValues) {
 
@@ -1664,10 +1665,19 @@ nsVmap.nsToolsManager.Select.prototype.selectController.prototype.getFormDataFro
             oFormData_.append(key, oValues[key]['aFiles'][0]['name']);
         } else if (bIsMultipleFiles) {
             for (var i = 0; i < oValues[key].length; i++) {
-                if (goog.isDefAndNotNull(oValues[key][i]['name'])) {
-                    oFormData_.append(key + '[]', oValues[key][i], oValues[key][i]['name']);
+                if (oValues[key][i]._modified === false) {
+                    // Mémorise les fichiers non modifiés par l'utilisateur
+                    if (!goog.isArray(oUnchangedFiles[key])) {
+                        oUnchangedFiles[key] = [];
+                    }
+                    oUnchangedFiles[key].push(oValues[key][i]['name']);
                 } else {
-                    oFormData_.append(key + '[]', oValues[key][i]);
+                    // Ajoute les fichiers
+                    if (goog.isDefAndNotNull(oValues[key][i]['name'])) {
+                        oFormData_.append(key + '[]', oValues[key][i], oValues[key][i]['name']);
+                    } else {
+                        oFormData_.append(key + '[]', oValues[key][i]);
+                    }
                 }
             }
         } else {
@@ -1675,9 +1685,45 @@ nsVmap.nsToolsManager.Select.prototype.selectController.prototype.getFormDataFro
         }
     }
 
+    if (Object.keys(oUnchangedFiles).length > 0) {
+        oFormData_.append('vitis_unchanged_files', JSON.stringify(oUnchangedFiles));
+    }
+
     return oFormData_;
 };
 
+nsVmap.nsToolsManager.Select.prototype.selectController.prototype.getUnchangedFilesFromValues = function (oValues) {
+    oVmap.log('nsVmap.nsToolsManager.Select.prototype.selectController.prototype.getUnchangedFilesFromValues');
+
+    var oUnchangedFiles = {};
+    for (var key in oValues) {
+
+        var bIsMultipleFiles = false;
+        if (goog.isObject(oValues[key])) {
+            if (goog.isDefAndNotNull(oValues[key].length)) {
+                bIsMultipleFiles = true
+            }
+        }
+
+        // Fichier ?
+        if (bIsMultipleFiles) {
+            for (var i = 0; i < oValues[key].length; i++) {
+                if (oValues[key][i]._modified === false) {
+
+                    if (!goog.isArray(oUnchangedFiles[key])) {
+                        oUnchangedFiles[key] = [];
+                    }
+
+                    oUnchangedFiles[key].push(oValues[key][i]['name']);
+
+                }
+            }
+        }
+    }
+
+    return oUnchangedFiles;
+};
+
 /**
  * Suggest if realy want to delete the object and call submitDeleteObject
  * @param {object} selection
diff --git a/src/module_vmap/web_service/ws/Querys.class.inc b/src/module_vmap/web_service/ws/Querys.class.inc
index 99e92395030dfdd19bc2272813b6ed738a049875..e3f6c006b90ed4dee2b35d01f17a7f9b57fc9532 100644
--- a/src/module_vmap/web_service/ws/Querys.class.inc
+++ b/src/module_vmap/web_service/ws/Querys.class.inc
@@ -1439,16 +1439,34 @@ class Querys extends Vmap {
 
         $this->aValues['my_vitis_id'] = $this->aValues[$bo_id_field];
 
+        // Fichiers inchangés à ne pas supprimer
+        if (!empty($this->aValues['vitis_unchanged_files'])) {
+            $aUnchangedFiles = json_decode($this->aValues['vitis_unchanged_files'], true);
+        }
+
         // Fichiers à uploader ?
         if (!empty($_FILES) && !empty($this->aValues['my_vitis_id'])) {
             foreach ($_FILES as $sName => $aFile) {
 
+                // Fichiers à ne pas supprimer
+                $aExceptions = [];
+                if (!empty($aUnchangedFiles[$sName])) {
+                    $aExceptions = $aUnchangedFiles[$sName];
+                }
+
                 // Nettoyage de l'espace ws_data
-                $this->oFilesManager->emptyWsDataDir('vitis', $sBusinessObjectId, $this->aValues['my_vitis_id'], $sName, 'documents');
+                $this->oFilesManager->emptyWsDataDir('vitis', $sBusinessObjectId, $this->aValues['my_vitis_id'], $sName, 'documents', $aExceptions);
 
                 // Écriture des fichiers
                 $aUploadReturn = $this->oFilesManager->uploadInWsDataDir('vitis', $sBusinessObjectId, $this->aValues['my_vitis_id'], $sName, 'documents', -1, "all", null, true);
                 $this->aValues[$sName] = $aUploadReturn['field_value'];
+
+                // Re-inscrit en base les fichiers à ne pas supprimer
+                $aFiles = explode('|', $this->aValues[$sName]);
+                for ($i=0; $i < count($aExceptions); $i++) {
+                    array_unshift($aFiles, $aExceptions[$i]);
+                }
+                $this->aValues[$sName] = implode('|', $aFiles);
             }
         }
 
diff --git a/src/vitis/client/javascript/externs/formReader/component/file_picker/file_picker.js b/src/vitis/client/javascript/externs/formReader/component/file_picker/file_picker.js
index 2c1224b8aeef3587f60ed9fdd11d0314e39cf75b..81dfd4bf356cd92fe633a0a411fac0d3dadac2e2 100644
--- a/src/vitis/client/javascript/externs/formReader/component/file_picker/file_picker.js
+++ b/src/vitis/client/javascript/externs/formReader/component/file_picker/file_picker.js
@@ -86,7 +86,7 @@ nsVitisComponent.FilePickerDirective = function ($timeout, $translate, propertie
                     // Affiche les images présentes sur le serveur
                     var aAvaliableFiles = scope["oFormValues"][scope["sFormDefinitionName"]][scope['field'].name];
                     if (goog.isDefAndNotNull(aAvaliableFiles)) {
-                        scope['addExistingFiles'](aAvaliableFiles).then(function(){
+                        scope['addFilesFromURL'](aAvaliableFiles).then(function(){
 
                             // Initialise l'affichage des images
                             scope['initPreview']();
@@ -129,41 +129,48 @@ nsVitisComponent.FilePickerDirective = function ($timeout, $translate, propertie
                         scope['aFiles'].push(files[i]);
                     }
                 }
+
+                console.log("scope['aFiles']: ", scope['aFiles']);
             }
 
             /**
-             * Lit les images déjà présentes à partir de leur URL
+             * Lit les images à partir de leur URL
              * @param  {array} aAvaliableFiles tableau d'URL
              * @return {promise}
              */
-            scope['addExistingFiles'] = function(aAvaliableFiles) {
-                $log.log("formReader.FilePickerDirective.addExistingFiles");
+            scope['addFilesFromURL'] = function(aAvaliableFiles) {
+                $log.log("formReader.FilePickerDirective.addFilesFromURL");
 
                 var deferred = $q.defer();
+                var iCounter = 0;
 
                 if (goog.isArray(aAvaliableFiles)) {
 
-                    var iCounter = 0;
+                    // Assure que le ajaxLoader soit activé pendant le chargement
+                    for (var i = 0; i < 100; i++) {
+                        setTimeout(function () {
+                            if (iCounter < aAvaliableFiles.length) {
+                                showAjaxLoader();
+                            }
+                        }, i * 100);
+                    }
 
                     for (var i = 0; i < aAvaliableFiles.length; i++) {
 
-                        scope['downloadFileBlob'](aAvaliableFiles[i], 3).then(
-                            function success(oBlob){
-
-                                scope['aFiles'].push(oBlob);
-
-                                iCounter++;
-                                if (iCounter === aAvaliableFiles.length) {
-                                    deferred.resolve();
-                                }
-
-                            },
-                            function error(){
-                                iCounter++;
-                                if (iCounter === aAvaliableFiles.length) {
-                                    deferred.resolve();
-                                }
-                            });
+                        scope['downloadFileBlob'](aAvaliableFiles[i], true, 3).then(
+                        function success(oBlob){
+                            scope['aFiles'].push(oBlob);
+                            iCounter++;
+                            if (iCounter === aAvaliableFiles.length) {
+                                deferred.resolve();
+                            }
+                        },
+                        function error(){
+                            iCounter++;
+                            if (iCounter === aAvaliableFiles.length) {
+                                deferred.resolve();
+                            }
+                        });
                     }
                 }
 
@@ -175,12 +182,19 @@ nsVitisComponent.FilePickerDirective = function ($timeout, $translate, propertie
              *
              * @param  {string} sFileUrl URL du fichier
              * @param  {number|undefined} iRetry Nombre de fois à retenter en cas de problème
+             * @param  {boolean|undefined} bThumbnail True pour télécharger la thumbnail en priorité
              * @return {promise} fonction prenant le blob en paramètre
              */
-            scope['downloadFileBlob'] = function(sFileUrl, iRetry) {
+            scope['downloadFileBlob'] = function(sFileUrl, bThumbnail, iRetry) {
                 $log.log("formReader.FilePickerDirective.downloadFileBlob " + iRetry);
 
                 var deferred = $q.defer();
+                var bThumbnail = goog.isDefAndNotNull(bThumbnail) ? bThumbnail : false;
+                var oParams = {};
+
+                if (bThumbnail === true) {
+                    oParams['thumbnail'] = true;
+                }
 
                 ajaxRequest({
                     'method': 'GET',
@@ -188,6 +202,7 @@ nsVitisComponent.FilePickerDirective = function ($timeout, $translate, propertie
                     'headers': {
                         'Accept': 'application/x-vm-json'
                     },
+                    'params': oParams,
                     'ajaxLoader': true,
                     'responseType': 'blob',
                     'success': function(response) {
@@ -200,6 +215,8 @@ nsVitisComponent.FilePickerDirective = function ($timeout, $translate, propertie
 
                             if (goog.isDefAndNotNull(sFileName)) {
                                 oBlob['name'] = sFileName;
+                                oBlob._url = sFileUrl;
+                                oBlob._modified = false;
                                 deferred.resolve(oBlob);
                             } else {
                                 console.error('cannot get name from headers : ', response['headers']);
@@ -208,7 +225,7 @@ nsVitisComponent.FilePickerDirective = function ($timeout, $translate, propertie
                                 if (goog.isDefAndNotNull(iRetry)) {
                                     if (iRetry > 0) {
                                         iRetry--;
-                                        scope['downloadFileBlob'](sFileUrl, iRetry).then(
+                                        scope['downloadFileBlob'](sFileUrl, bThumbnail, iRetry).then(
                                             function success(oBlob){
                                                 deferred.resolve(oBlob);
                                             },
@@ -364,7 +381,8 @@ nsVitisComponent.FilePickerDirective = function ($timeout, $translate, propertie
                             scope.$applyAsync(function(){
                                 scope[sPreviewContainer].push({
                                     'name': oFile['name'],
-                                    'src': picFile['result']
+                                    'src': picFile['result'],
+                                    _url: oFile._url
                                 });
                             });
                         }, oFile));
diff --git a/src/vitis/vas/rest/class/vmlib/files/Files_manager.class.inc b/src/vitis/vas/rest/class/vmlib/files/Files_manager.class.inc
index 058d6eba6a2b166ea7071c9feaaea7905d929024..2aac729c0e6750eeab4052379335582cb42e0499 100644
--- a/src/vitis/vas/rest/class/vmlib/files/Files_manager.class.inc
+++ b/src/vitis/vas/rest/class/vmlib/files/Files_manager.class.inc
@@ -477,7 +477,7 @@ class Files_manager{
      *@param $sContainer folder between $sObject and $mId
      *@return true if the disrectory has benn cleaned
      */
-    public function emptyWsDataDir($sModule, $sObject, $mId, $sField, $sContainer = ""){
+    public function emptyWsDataDir($sModule, $sObject, $mId, $sField, $sContainer = "", $aExceptions = []){
 
         // controle les attributs pour éviter les mauvais placements
         if (strpos($sModule, '/') > -1){
@@ -518,12 +518,27 @@ class Files_manager{
             $sDestDir .= "/" . $sField;
         }
 
+        // Ajoute les miniatures aux exceptions
+        $aMinExceptions = [];
+        for ($i=0; $i < count($aExceptions); $i++) {
+            $aMinException = explode('.', $aExceptions[$i]);
+            array_pop($aMinException);
+            array_push($aMinException, 'min');
+            array_push($aMinException, 'jpg');
+            array_push($aMinExceptions, implode('.', $aMinException));
+        }
+        for ($i=0; $i < count($aMinExceptions); $i++) {
+            array_push($aExceptions, $aMinExceptions[$i]);
+        }
+
         // création du fichier si besoin
         if (is_dir($sDestDir)){
             $files = glob($sDestDir . '/*'); // get all file names
             foreach($files as $file){ // iterate files
                 if(is_file($file)){
-                    unlink($file); // delete file
+                    if (!in_array(basename($file), $aExceptions)) {
+                        unlink($file);
+                    }
                 }
             }
             return true;
diff --git a/src/vitis/vas/rest/ws/vitis/FileDownloader.class.inc b/src/vitis/vas/rest/ws/vitis/FileDownloader.class.inc
index 7242f83a9ddec1bc86346c8286dacfe1f2a12323..399b7743cfdcd17270052f1643876fe07bc74b5f 100755
--- a/src/vitis/vas/rest/ws/vitis/FileDownloader.class.inc
+++ b/src/vitis/vas/rest/ws/vitis/FileDownloader.class.inc
@@ -172,6 +172,21 @@ class FileDownloader extends Vitis {
     }
 
     function getFile($sFilePath, $sFileName) {
+
+        // Utilisation thumnail
+        if ($this->aValues["thumbnail"] == true) {
+            $sMinFilePath = $sFilePath;
+            $aMinFilePath = explode('.', $sMinFilePath);
+            array_pop($aMinFilePath);
+            array_push($aMinFilePath, 'min');
+            array_push($aMinFilePath, 'jpg');
+            $sMinFilePath = implode('.', $aMinFilePath);
+            if (file_exists($sMinFilePath)) {
+                $sFilePath = $sMinFilePath;
+            }
+        }
+
+
         // Le fichier existe ?
         if (file_exists($sFilePath)) {
             $sContentType = $this->getMime($sFilePath);