diff --git a/src/app/components/pab-table/pab-table.component.ts b/src/app/components/pab-table/pab-table.component.ts
index 1001e6e7d7d8ed58f8d2f13ad4335b60a9a086ef..8058576ef091e695b5793678cb61b3fbc0ae9a4f 100644
--- a/src/app/components/pab-table/pab-table.component.ts
+++ b/src/app/components/pab-table/pab-table.component.ts
@@ -246,8 +246,70 @@ export class PabTableComponent implements AfterViewInit, OnInit {
             && ! this.hasModel(cell) // editable cells listen to the click event for edition only
         ) {
             if ($event.shiftKey && cell !== this.latestClickedCell) { // shift + click
-                // @TODO interpopolate from this.latestClickedCell to this one
-                console.log("shift + click");
+                // interpolate from this.latestClickedCell to this one
+                if (! Array.isArray(cell.selectable)) { // multiselectable cells are not managed
+                    const wallsUIDs = this.getSortedWallsUIDs();
+                    let posOld: number;
+                    let posNew: number;
+                    // find positions depending on types, and only if types are equal
+                    if (cell.selectable instanceof ParallelStructure) {
+                        if (this.latestClickedCell.selectable instanceof ParallelStructure) {
+                            // interpolate walls
+                            posOld = wallsUIDs.indexOf(this.latestClickedCell.selectable.uid);
+                            posNew = wallsUIDs.indexOf(cell.selectable.uid);
+                            if (posOld !== posNew) {
+                                if (posOld > posNew) {
+                                    // invert order
+                                    [ posOld, posNew ] = [ posNew, posOld ];
+                                }
+                                // go
+                                for (let i = posOld; i <= posNew; i++) {
+                                    if (i < this.model.children.length) {
+                                        // push regular wall
+                                        this.selectedItems.push(this.model.children[i]);
+                                    } else {
+                                        // push downwall
+                                        this.selectedItems.push(this.model.downWall);
+                                    }
+                                    this.latestClickedCell = cell;
+                                }
+                            }
+                        }
+                    } else if (cell.selectable instanceof Structure) {
+                        if (this.latestClickedCell.selectable instanceof Structure) {
+                            // accept interpolation only if both devices are on the same column
+                            const columnOld = this.latestClickedCell.selectable.findPositionInParent();
+                            const columnNew = cell.selectable.findPositionInParent();
+                            if (columnOld === columnNew) {
+                                // interpolate devices
+                                posOld = wallsUIDs.indexOf(this.latestClickedCell.selectable.parent.uid);
+                                posNew = wallsUIDs.indexOf(cell.selectable.parent.uid);
+                                if (posOld !== posNew) {
+                                    if (posOld > posNew) {
+                                        // invert order
+                                        [ posOld, posNew ] = [ posNew, posOld ];
+                                    }
+                                    // go
+                                    for (let i = posOld; i <= posNew; i++) {
+                                        if (i < this.model.children.length) {
+                                            // push regular wall
+                                            this.selectedItems.push(this.model.children[i].structures[columnOld]);
+                                        } else {
+                                            // push downwall
+                                            this.selectedItems.push(this.model.downWall.structures[columnOld]);
+                                        }
+                                    }
+                                    this.latestClickedCell = cell;
+                                }
+                            }
+                        }
+                    }
+                    // clean selected items list (deduplicate, sort)
+                    this.selectedItems = this.selectedItems.filter(
+                        (item, index) => this.selectedItems.indexOf(item) === index // deduplicate
+                    );
+                    this.sortSelectedItems();
+                }
 
             } else if (
                 $event.ctrlKey // ctrl + click
@@ -272,6 +334,7 @@ export class PabTableComponent implements AfterViewInit, OnInit {
                     }
                     this.sortSelectedItems();
                 }
+                this.latestClickedCell = cell;
 
             } else { // just a click
                 if (this.isSelected(cell)) {
@@ -285,12 +348,13 @@ export class PabTableComponent implements AfterViewInit, OnInit {
                         this.selectedItems = [ cell.selectable ];
                     }
                 }
+                this.latestClickedCell = cell;
             }
-            this.latestClickedCell = cell;
 
             // clean list
             this.selectedItems = this.selectedItems.filter(e => e !== undefined);
 
+            this.clearSelection();
             $event.preventDefault();
             $event.stopPropagation();
             return false;
@@ -322,17 +386,30 @@ export class PabTableComponent implements AfterViewInit, OnInit {
         this.refresh();
     }
 
-    /**
-     * Ensures that this.selectedItems elements are ordered according to
-     * the walls order in the PAB (important for interpolation)
-     */
-    private sortSelectedItems() {
-        // extract PAB walls order
+    /** Unselects all selected text (side-effect of shift+clicking) */
+    private clearSelection() {
+        if (window.getSelection) {
+            const sel = window.getSelection();
+            sel.removeAllRanges();
+        }
+    }
+
+    // extract PAB walls order
+    private getSortedWallsUIDs(): string[] {
         const wallsUIDs: string[] = [];
         for (const c of this.pabTable.pab.children) {
             wallsUIDs.push(c.uid);
         }
         wallsUIDs.push(this.pabTable.pab.downWall.uid);
+        return wallsUIDs;
+    }
+
+    /**
+     * Ensures that this.selectedItems elements are ordered according to
+     * the walls order in the PAB (important for interpolation)
+     */
+    private sortSelectedItems() {
+        const wallsUIDs = this.getSortedWallsUIDs();
         // are items walls or devices ?
         if (this.onlyWallsAreSelected(false)) {
             // 1. walls : order by uid, according to model