add integration modifs
authorcavaliet
Mon, 10 Jun 2013 16:15:11 +0200
changeset 108 ba125e8615eb
parent 107 f354d24e08ca
child 109 12a4ca0db163
add integration modifs
src/metadatacomposer/static/metadatacomposer/css/style.css
src/metadatacomposer/static/metadatacomposer/js/edition.js
src/metadatacomposer/static/metadatacomposer/js/metadataplayer-core.js
src/metadatacomposer/static/metadatacomposer/js/tangle.js
src/metadatacomposer/templates/metadatacomposer_edit.html
--- a/src/metadatacomposer/static/metadatacomposer/css/style.css	Mon Jun 10 15:58:23 2013 +0200
+++ b/src/metadatacomposer/static/metadatacomposer/css/style.css	Mon Jun 10 16:15:11 2013 +0200
@@ -1,4 +1,5 @@
 .wrap{color: #2c3e50;}
+.tab-content{overflow: hidden;}
 .vignette-projet{position: relative;}
 .vignette-projet:hover a{display: block;}
 .vignette-projet a{ display:none;position: absolute; width: 50%; height: 100%; font-size: 50px; text-align: center; line-height: 140px; text-decoration: none;}
@@ -64,9 +65,7 @@
 .add-annotation-wrap, .form-info-general-annotation{padding: 10px 0;}
 .form-info-general-annotation ul.tagit {margin-left: 0px;width: 195px;}
 .form-info-general-annotation textarea{min-height:100px; height: 100px;min-width: 196px;}
-
 .add-annotation-wrap {margin-bottom: 20px; padding-top: 0;}
-
 .slider-duration{width: 435px;display: inline-block; margin-bottom: 10px;}
 .btn-save-annotation{margin-right: 10px;}
 .tab-pane.active{background-color: #F5F5F5;}
@@ -80,7 +79,6 @@
 .config-diaporama form{background-color: #34495e; padding: 4px 0; margin: 0; overflow: hidden;  line-height: 28px;}
 .config-diaporama form label{display: inline-block; padding-left: 10px;}
 .config-diaporama form input{margin-bottom: 0;}
-
 .edit-annotation-text textarea{max-width: 446px;}
 .wysiwyg-wrap{overflow: hidden; }
 .ui-slider-handle.ui-state-default.ui-corner-all{border-radius: 0;}
@@ -98,12 +96,8 @@
 .timeline-annotations .annotation:hover span,
 .annotation.editing span, 
 .annotation.editing i{display: inline;}
-ul.tagit{margin-left: 10px;-webkit-border-radius: 0px;
--moz-border-radius: 0px;
-border-radius: 0px;}
-
+ul.tagit{margin-left: 10px;-webkit-border-radius: 0px;-moz-border-radius: 0px;border-radius: 0px;}
 .video-wrap{position: relative;}
-.annotations-display{}
 .annotation-display-view{display:none;text-align:center; line-height:200px;background-color: #fff;position: absolute; width: 200px; margin-left: -100px; height: 200px; margin-top: -100px; top: 50%; left: 50%;}
 .list-current-annotations{position: absolute;bottom: 40px; left: 20px; margin: 0;}
 .list-current-annotations li{list-style: none; margin-top: 4px;}
@@ -111,53 +105,29 @@
 .list-current-annotations a span{display: none;}
 .list-current-annotations a:hover span{display: inline-block;}
 .annotation-audio-content textarea{max-width: 206px;}
-
 .annotation-links-content .links-form:nth-child(n+2){border-top:1px solid; padding-top: 20px;}
-
 td.list-chapter-tags, td.list-chapter-title, #list-annotations-rows > tr td:first-child{word-wrap: break-word; max-width: 75px;}
 td.begin, td.duration, td.end{max-width: 40px;}
-
 td.image-slideshow-row img{width: 60px; height: 60px;}
 .project-title-editor input{margin-bottom: 0;}
 #templates{display: none;}
-
 .title-slideshow-row{word-wrap: break-word;width: 76px;}
 .title-slideshow-row input{width: 70px;}
 .description-slideshow-row{word-wrap: break-word; width: 180px; }
 .description-slideshow-row span{max-height: 100px; display: inline-block; overflow: auto;}
 .description-slideshow-row textarea{width: 164px; max-width: 164px; height: 100px;}
 .label-modify-video, .label-add-video{display: none;}
-
-.shadow {
-    background-color: #00FFFF !important;
-}
+.shadow {background-color: #00FFFF !important;}
 .alert-message{display: none;}
-
+.alert{display: none;}
 /* Tangle */
-.time-tangle {
-	color: #2c3e50; cursor: w-resize; position: relative;
-	border-bottom: 1px dashed #2c3e50;
-}
+.time-tangle {color: #2c3e50; cursor: w-resize; position: relative;border-bottom: 1px dashed #2c3e50;}
 .time-tangle:hover, 
-.time-tangle.active {
-    color: #c0392b; 
-}
+.time-tangle.active {color: #c0392b;}
 .time-tangle:hover:after, 
-.time-tangle.active:after {
-	position: absolute;
-	display: inline-block;
-    color: #2c3e50;  top: 18px; left: 50%; width: 160px;
-    margin-left: -80px; font-size: 10px; text-align: center;
-    content: "glisser pour modifier";
-}
-
-.time-tangle.deactivate:hover {
-    border: none; color: #2c3e50;
-}
-
-.time-tangle.deactivate:hover:after {
-    display: none;
-}
+.time-tangle.active:after {position: absolute;display: inline-block;color: #2c3e50;  top: 18px; left: 50%; width: 160px;margin-left: -80px; font-size: 10px; text-align: center;content: "glisser pour modifier";}
+.time-tangle.deactivate:hover {border: none; color: #2c3e50;}
+.time-tangle.deactivate:hover:after {display: none;}
 
 .loader {
     background: url(../img/loader.gif) center no-repeat;
--- a/src/metadatacomposer/static/metadatacomposer/js/edition.js	Mon Jun 10 15:58:23 2013 +0200
+++ b/src/metadatacomposer/static/metadatacomposer/js/edition.js	Mon Jun 10 16:15:11 2013 +0200
@@ -1,208 +1,182 @@
 var myMedia = undefined,
     currentChapter = undefined,
     currentAnnotation = undefined,
+    currentSlider = undefined,
     secMiniChapter = 10;
 
 $(function(){
 
-var global = {
-    colorsIndex : 0,
-    colors : 
-        ['#1abc9c', '#3498db', '#9b59b6', '#2ecc71',  
-        '#f1c40f', '#ecf0f1', '#e67e22', '#e74c3c', '#95a5a6',
-        '#16a085', '#2980b9', '#8e44ad', '#27ae60', 
-         '#f39c12', '#c0392b', '#bdc3c7', '#d35400', '#7f8c8d']
-};
-
-
-//position de la video setCurrentTime
-$(".indicateur-annotation").draggable({
-    axis: "x",
-    containment: "parent",
-    drag: function(e, ui) {
-        var t = myMedia.duration * parseInt(ui.helper.css("left")) / ( $(".timeline-annotations").width() - 2 * ui.helper.width() );
-        myMedia.setCurrentTime(t);
-    }
-});
-
-//survol
-$(document).on('mouseover', '.timeline-annotations .annotation, #list-annotations-rows tr, .item-display-annotation' , function(){
-    if(!$(this).hasClass('shadow')) {
-        var idAnnotation = $(this).attr('data-id');
-        $('#annotation-timeline-'+idAnnotation+', #row-list-annotation-'+idAnnotation+', #item-current-annotation-'+idAnnotation).addClass('shadow');
-    }
-});
+    var global = {
+        colorsIndex : 0,
+        colors : 
+            ['#1abc9c', '#3498db', '#9b59b6', '#2ecc71',  
+            '#f1c40f', '#ecf0f1', '#e67e22', '#e74c3c', '#95a5a6',
+            '#16a085', '#2980b9', '#8e44ad', '#27ae60', 
+             '#f39c12', '#c0392b', '#bdc3c7', '#d35400', '#7f8c8d']
+    };
 
-$(document).on('mouseover', '.chapter-segment, .row-list-chapter' , function(){
-    if(!$(this).hasClass('shadow')) {
-        var idChapter = $(this).attr('data-id');
-        $('#row-list-chapter-'+idChapter+', #'+idChapter+', #form-chapter-edit-'+idChapter).addClass('shadow');
-    }
-});
-
-$(document).on('mouseout', '.shadow' , function(){
-    $('.shadow').removeClass('shadow');
-});
-
-
-$(document).on('click', '.annotation, .item-display-annotation', function(e){
-    e.preventDefault();
-    var idAnnotation = $(this).attr('data-id'),
-        annotation = _.find(annotations, function(c){ return c.id == idAnnotation; });
-    myMedia.setCurrentTime(annotation.begin);
-    if($('#tab-annotation-'+idAnnotation).length){
-        $('a[href=#tab-annotation-'+idAnnotation+']').tab('show');
-    }else{
-        openTab(annotation.type, annotation);
-    }
-});
-
-myProject.onLoad(function() {
-    myProject.regenerateTags = true;
-
-    $(".project-title").text(myProject.title);
-    $('.project-title-nav').text(myProject.title);
-
-    myMedia = myProject.getCurrentMedia();
-
-    var anntypes = myProject.getAnnotationTypes().searchByTitle("chapitrage");
-    if (!anntypes.length) {
-        chapterAnnType = new IriSP.AnnotationType(false, myProject);
-        chapterAnnType.title = "chapitrage";
-    } else {
-        chapterAnnType = anntypes[0];
+    function getTemplate(idTpl){
+        return $('#templates').find(idTpl).html();
     }
 
-//load Chapitre
+    myProject.onLoad(function() {
+        myProject.regenerateTags = true;
+
+        $(".project-title").text(myProject.title);
+        $('.project-title-nav').text(myProject.title);
+
+        myMedia = myProject.getCurrentMedia();
 
-    chapters = chapterAnnType.getAnnotations();
-    $.each(chapters, function(k, v){
-        v.color = getRandomColor();
-    });
-    renderChapter();
+        var anntypes = myProject.getAnnotationTypes().searchByTitle("chapitrage");
+        if (!anntypes.length) {
+            chapterAnnType = new IriSP.AnnotationType(false, myProject);
+            chapterAnnType.title = "chapitrage";
+        } else {
+            chapterAnnType = anntypes[0];
+        }
 
-//load Annotations
-    var anntypes = myProject.getAnnotationTypes().searchByTitle("annotations");
-    if (!anntypes.length) {
-        annotationsAnnType = new IriSP.AnnotationType(false, myProject);
-        annotationsAnnType.title = "annotations";
-    } else {
-        annotationsAnnType = anntypes[0];
-    }
+        //load Chapitre
+        chapters = chapterAnnType.getAnnotations();
+        $.each(chapters, function(k, v){
+            v.color = getRandomColor();
+        });
+        renderChapter();
 
-    annotations = annotationsAnnType.getAnnotations();
-    $.each(annotations, function(k, v){
-        var type = v.content.mimetype.split('-');
-        type = type[type.length-1]
-        v.type = type;
-        v.color = getRandomColor();
-    });
-    renderAnnotation();
+        //load Annotations
+        var anntypes = myProject.getAnnotationTypes().searchByTitle("annotations");
+        if (!anntypes.length) {
+            annotationsAnnType = new IriSP.AnnotationType(false, myProject);
+            annotationsAnnType.title = "annotations";
+        } else {
+            annotationsAnnType = anntypes[0];
+        }
+
+        annotations = annotationsAnnType.getAnnotations();
+        $.each(annotations, function(k, v){
+            var type = v.content.mimetype.split('-');
+            type = type[type.length-1]
+            v.type = type;
+            v.color = getRandomColor();
+        });
+        renderAnnotation();
 
 
-    IriSP.htmlPlayer(
-        myMedia,
-        $(".main-video"),
-        {
-            width: 460,
-            height: 345,
-            controls: true,
-            autostart: true,
-            url_transform: function(src) {
-                return [{
-                    type: "video/mp4",
-                    src: src.replace(/\.[\d\w]+$/,'.mp4').replace('rtmp://media.iri.centrepompidou.fr/ddc_player', 'http://media.iri.centrepompidou.fr')
-                }, {
-                    type: "video/webm",
-                    src: src.replace(/\.[\d\w]+$/,'.webm').replace('rtmp://media.iri.centrepompidou.fr/ddc_player', 'http://media.iri.centrepompidou.fr')
-                }];
+        IriSP.htmlPlayer(
+            myMedia,
+            $(".main-video"),
+            {
+                width: 460,
+                height: 345,
+                controls: true,
+                autostart: true,
+                url_transform: function(src) {
+                    return [{
+                        type: "video/mp4",
+                        src: src.replace(/\.[\d\w]+$/,'.mp4').replace('rtmp://media.iri.centrepompidou.fr/ddc_player', 'http://media.iri.centrepompidou.fr')
+                    }, {
+                        type: "video/webm",
+                        src: src.replace(/\.[\d\w]+$/,'.webm').replace('rtmp://media.iri.centrepompidou.fr/ddc_player', 'http://media.iri.centrepompidou.fr')
+                    }];
+                }
             }
-        }
-    );
+        );
 
-    myMedia.on("timeupdate", function(t) {
+        myMedia.on("timeupdate", function(t) {
 
-        //curseur chapitre
-        var wContainer = $('.chapitre-cut-wrap').width() - 1,
-            pos = wContainer * t / myMedia.duration,
-            btnCutChapter = $('.btn-cut-chapter'),
-            wBtnCutChapter = btnCutChapter.outerWidth();
+            //curseur chapitre
+            var wContainer = $('.chapitre-cut-wrap').width() - 1,
+                pos = wContainer * t / myMedia.duration,
+                btnCutChapter = $('.btn-cut-chapter'),
+                wBtnCutChapter = btnCutChapter.outerWidth();
+            
+            $(".indicateur-chapter, .indicateur-annotation").css("left",pos);
+            if(pos+wBtnCutChapter>wContainer){
+                btnCutChapter.css("left",(pos - wBtnCutChapter));
+            }else{
+                btnCutChapter.css("left",pos);
+            }
+            $('.info-time').text(t)
+            //annotations view
+            refreshAnnotationDisplay(t);
+
+        });//timeupdate
         
-        $(".indicateur-chapter, .indicateur-annotation").css("left",pos);
-        if(pos+wBtnCutChapter>wContainer){
-            btnCutChapter.css("left",(pos - wBtnCutChapter));
-        }else{
-            btnCutChapter.css("left",pos);
-        }
-        $('.info-time').text(t)
-        //annotations view
-        refreshAnnotationDisplay(t);
+    });//myProject.onLoad
 
-    });//timeupdate
-    
-});//myProject.onLoad
+/* Display annotation in timeline */
 
-function refreshAnnotationDisplay(t){
-    
-    var currentAnnotationsDisplay = new Array();
-    $.each(annotations, function(k, v){
+    //survol
+    $(document).on('mouseover', '.timeline-annotations .annotation, #list-annotations-rows tr, .item-display-annotation' , function(){
+        if(!$(this).hasClass('shadow')) {
+            var idAnnotation = $(this).attr('data-id');
+            $('#annotation-timeline-'+idAnnotation+', #row-list-annotation-'+idAnnotation+', #item-current-annotation-'+idAnnotation).addClass('shadow');
+        }
+    });
 
-        if(v.begin <= t && v.end >= t){
-            currentAnnotationsDisplay.push(v.id);
-            if(!$('#item-current-annotation-'+v.id).length){
-                var itemAnnotation = getTemplate('#tpl-item-annotation-display');
-                v.iconTab = getIcon(v.type);
-                itemAnnotation = Mustache.render(itemAnnotation, v);
-                $('.list-current-annotations').append(itemAnnotation)
-            }
+    $(document).on('mouseover', '.chapter-segment, .row-list-chapter' , function(){
+        if(!$(this).hasClass('shadow')) {
+            var idChapter = $(this).attr('data-id');
+            $('#row-list-chapter-'+idChapter+', #'+idChapter+', #form-chapter-edit-'+idChapter).addClass('shadow');
         }
     });
-    $.each($('.list-current-annotations li'), function(k, v){
+
+    $(document).on('mouseout', '.shadow' , function(){
+        $('.shadow').removeClass('shadow');
+    });
+
+    $(document).on('click', '.annotation, .item-display-annotation', function(e){
+        e.preventDefault();
         var idAnnotation = $(this).attr('data-id'),
-            annotationDisplayView = $('.annotation-display-view');
-        if($.inArray(idAnnotation, currentAnnotationsDisplay)<0){//il ne doit plus être affiché
-            $('#item-current-annotation-'+idAnnotation).remove();
-            if(annotationDisplayView.attr('data-id') == idAnnotation && annotationDisplayView.is(":visible")){
-                annotationDisplayView.hide();
-            }
+            annotation = _.find(annotations, function(c){ return c.id == idAnnotation; });
+        myMedia.setCurrentTime(annotation.begin);
+        if($('#tab-annotation-'+idAnnotation).length){
+            $('a[href=#tab-annotation-'+idAnnotation+']').tab('show');
+        }else{
+            openTab(annotation.type, annotation);
         }
     });
-    if(currentAnnotation !== undefined){ 
-        showCurrentAnnotationInTimeline(currentAnnotation.id);
-    }
-}
+
+    function refreshAnnotationDisplay(t){
+        var currentAnnotationsDisplay = new Array();
+        $.each(annotations, function(k, v){
 
-function showCurrentAnnotationInTimeline(idAnnotation){
-    $('.annotation').removeClass('editing');
-    $('#annotation-timeline-'+idAnnotation).addClass('editing');
-}
-//display annotation view
-$('.list-current-annotations').on('click', 'a', function(e){
-    e.preventDefault();
-    /*
-    var annotationDisplayView = $('.annotation-display-view'),
-        idAnnotation = $(this).attr('data-id');
-    var annotation = _.find(annotations, function(c){ return c.id == idAnnotation; });
+            if(v.begin <= t && v.end >= t){
+                currentAnnotationsDisplay.push(v.id);
+                if(!$('#item-current-annotation-'+v.id).length){
+                    var itemAnnotation = getTemplate('#tpl-item-annotation-display');
+                    v.iconTab = getIcon(v.type);
+                    itemAnnotation = Mustache.render(itemAnnotation, v);
+                    $('.list-current-annotations').append(itemAnnotation)
+                }
+            }
+        });
 
-    if(annotationDisplayView.attr('data-id') == idAnnotation && annotationDisplayView.is(":visible")){
-        annotationDisplayView.hide();
-    }else{
-        annotationDisplayView
-            .attr('data-id', idAnnotation)
-            .css('backgroundColor', annotation.color)
-            .text(annotation.type+' : '+annotation.title)
-            .show();
+        $.each($('.list-current-annotations li'), function(k, v){
+            var idAnnotation = $(this).attr('data-id'),
+                annotationDisplayView = $('.annotation-display-view');
+            if($.inArray(idAnnotation, currentAnnotationsDisplay)<0){//il ne doit plus être affiché
+                $('#item-current-annotation-'+idAnnotation).remove();
+                if(annotationDisplayView.attr('data-id') == idAnnotation && annotationDisplayView.is(":visible")){
+                    annotationDisplayView.hide();
+                }
+            }
+        });
+        if(currentAnnotation !== undefined){ 
+            showCurrentAnnotationInTimeline(currentAnnotation.id);
+        }
     }
-    */
-});
 
-//########### modal
+    function showCurrentAnnotationInTimeline(idAnnotation){
+        $('.annotation').removeClass('editing');
+        $('#annotation-timeline-'+idAnnotation).addClass('editing');
+    }
 
-    $(document).on('click', 'a.open-modal', function(e){
-
+    $('.list-current-annotations').on('click', 'a', function(e){
+        e.preventDefault();
     });
+    
 
-//select on bibliotheque
+/*  Modal */
 
     //confirmation suppression
     $("#modal-confirm").on('click', '#btn-delete-modal', function(e){
@@ -217,14 +191,12 @@
         }
     });
 
-//--apercu projet
-$(document).on('click', '.btn-apercu-projet.disabled', function(e){
-    e.preventDefault();
-});
+
 
-//--title-editor
+/* Title project */
+
     $(document).on('click', '.project-title-editor i, .project-title', function () {
-        disabledPreview();
+        
         var html = $('.project-title').html();
         var input = $('<input type="text" />');
         input.val(html);
@@ -239,12 +211,13 @@
         myProject.title = newTitle;
         $(this).replaceWith('<span class="project-title">'+newTitle+'</span></td>');
         $('.project-title-nav').text(newTitle);
+        disabledPreview();
     });
 
 
-//######################## chapter
+/*  Chapter */
 
-//edit
+    //edit
     $('.list-chapter-wrap').on('click', '.btn-edit-chapter', function(e){
         e.preventDefault();
         var idChapter = $(this).attr('data-chapter-id');
@@ -257,8 +230,6 @@
     });
 
     $('.chapter-widget-info').on('keyup', 'input[name=title], textarea', function(e){
-        disabledPreview();
-
         var name = $(this).attr('name'),
             value = $(this).val();
         currentChapter[name] = value;
@@ -268,15 +239,10 @@
             $('#row-list-chapter-'+idChapter).find('td:first').text(value);
             $(this).parents('form').find('.btn-delete-chapter').attr('data-title', value);
         }
+        disabledPreview();
     });
 
-
-
     function loadFormChapter(idChapter){
-
-        disabledPreview();
-        
-
         currentChapter = _.find(chapters, function(c){ return c.id == idChapter; });
         var chapterWrap = $('.chapter-widget-info'),
             indexChapter = _.indexOf(chapters, currentChapter),
@@ -294,63 +260,61 @@
         myMedia.setCurrentTime(currentChapter.begin);
     }
 
-    function getTemplate(idTpl){
-        return $('#templates').find(idTpl).html();
-    }
-//supprimer
-$(document).on('click', '.btn-delete-chapter', function(e){
-    e.preventDefault();
+    //delete chapter
+    $(document).on('click', '.btn-delete-chapter', function(e){
+        e.preventDefault();
 
-    if(chapters.length == 1){
-        $('#modal-alert .alert-message').hide();
-        $('#modal-alert #alert-chapter-number').show();
-        $('#modal-alert').modal('show');
-        return;
-    }
-    var idChapter = $(this).attr('data-chapter-id'),
-        btnDeleteModal = $("#modal-confirm #btn-delete-modal");
-    btnDeleteModal.attr('data-type-delete', 'chapter');
-    btnDeleteModal.attr('data-id', idChapter);
+        if(chapters.length == 1){
+            $('#modal-alert .alert-message').hide();
+            $('#modal-alert #alert-chapter-number').show();
+            $('#modal-alert').modal('show');
+            return;
+        }
+        var idChapter = $(this).attr('data-chapter-id'),
+            btnDeleteModal = $("#modal-confirm #btn-delete-modal");
+        btnDeleteModal.attr('data-type-delete', 'chapter');
+        btnDeleteModal.attr('data-id', idChapter);
 
-    var titleMedia = $(this).attr('data-title'),
-        urlDelete = $(this).attr('href');
-    $("#modal-confirm #btn-delete-modal").attr('href', urlDelete).focus();
-    $("#modal-confirm .modal-body").find('.titleMedia').text(titleMedia);
-    $("#modal-confirm").modal('show');
+        var titleMedia = $(this).attr('data-title'),
+            urlDelete = $(this).attr('href');
+        $("#modal-confirm #btn-delete-modal").attr('href', urlDelete).focus();
+        $("#modal-confirm .modal-body").find('.titleMedia').text(titleMedia);
+        $("#modal-confirm").modal('show');
+
+    });
+    $(document).on('click', '.btn-ok-chapter', function(e){
+        e.preventDefault();
+        $('.form-chapter-edit').remove();
+    });
 
-});
-$(document).on('click', '.btn-ok-chapter', function(e){
-    e.preventDefault();
-    $('.form-chapter-edit').remove();
-})
+    function deleteChapter(idChapter){
+        
+        $("#modal-confirm").modal('hide');
+        var chapter = _.find(chapters, function(c){ return c.id == idChapter; }),
+            indexChapter = _.indexOf(chapters, chapter),
+            chapterModify;
+        if(indexChapter == 0){
+            chapterModify = chapters[1];
+            chapterModify.setBegin(0);
+        }else{
+            chapterModify = chapters[indexChapter-1];
+            //var newEnd = new IriSP.Model.Time(chapter.end)
+            chapterModify.setEnd(chapter.end);
+        }
+        chapters.removeId(idChapter);
+        myProject.getAnnotations().removeId(idChapter, true);
+        renderChapter();
+        //si le formulaire est visible
+        if($('#form-chapter-edit-'+idChapter).length){
+            $('#form-chapter-edit-'+idChapter).remove();
+        }
+        disabledPreview();
+    }
 
-function deleteChapter(idChapter){
-    disabledPreview();
-    $("#modal-confirm").modal('hide');
-    var chapter = _.find(chapters, function(c){ return c.id == idChapter; }),
-        indexChapter = _.indexOf(chapters, chapter),
-        chapterModify;
-    if(indexChapter == 0){
-        chapterModify = chapters[1];
-        chapterModify.setBegin(0);
-    }else{
-        chapterModify = chapters[indexChapter-1];
-        //var newEnd = new IriSP.Model.Time(chapter.end)
-        chapterModify.setEnd(chapter.end);
+    function getRandomColor(){
+        return global.colors[(global.colorsIndex<global.colors.length) ? global.colorsIndex++ : (global.colorsIndex=0)];
     }
-    chapters.removeId(idChapter);
-    myProject.getAnnotations().removeId(idChapter, true);
-    renderChapter();
-    //si le formulaire est visible
-    if($('#form-chapter-edit-'+idChapter).length){
-        $('#form-chapter-edit-'+idChapter).remove();
-    }
-}
-
-function getRandomColor(){
-    return global.colors[(global.colorsIndex<global.colors.length) ? global.colorsIndex++ : (global.colorsIndex=0)];
-}
-//nouveau chapitre
+    //nouveau chapitre
     function newChapter(dataChapter, render){
         var chapter = new IriSP.Model.Annotation(false, myProject);
             chapter.setMedia(myMedia.id);
@@ -366,6 +330,8 @@
         myProject.getAnnotations().push(chapter);
         renderChapter();
         loadFormChapter(chapter.id);
+        disabledPreview();
+        $('#chapter-title').focus();
     }
 
     $('.chapter-widget').on('click', '.btn-cut-chapter', function(e){
@@ -380,11 +346,11 @@
             return;
         }
         var dataChapter = {
-            title : 'New',
+            title : '',
             begin : begin,
             end : end,
-            description : 'description',
-            keywords : ['tag1','tag2']
+            description : '',
+            keywords : []
         };
 
         newChapter(dataChapter, true);
@@ -408,7 +374,7 @@
     }
     
     function renderChapter(){
-        disabledPreview();
+        
 
         var chapterSegmentWrap = $('.chapter-segments'),
             wChapterSegmentWrap = chapterSegmentWrap.width(),
@@ -444,10 +410,7 @@
      
     }//renderChapter()
 
-
-
-//######################## annotation
-    
+/* Annotation */    
 
     function newAnnotation(dataAnnotation){
         var annotation = new IriSP.Model.Annotation(false, myProject);
@@ -464,12 +427,13 @@
 
         myProject.getAnnotations().push(annotation);
         annotations.push(annotation);
-        
+        disabledPreview();
+
         return annotation;
     }
 
     function renderAnnotation(){
-        disabledPreview();
+        
 
         var timeline = $('.timeline-annotations'),
             wTimeline = timeline.width(),
@@ -542,7 +506,7 @@
     //edit annotation
     $('#list-annotations').on('click', 'a.btn-edit-annotation', function(e){
         e.preventDefault();
-        disabledPreview();
+        
         var idAnnotation = $(this).attr('data-id');
         //si il est déjà ouvert
         if($('#tab-annotation-'+idAnnotation).length){
@@ -554,7 +518,7 @@
     });
 
     $('.tab-content').on('keyup', '.form-info-general-annotation input[name=title], .form-info-general-annotation textarea', function(e){
-        disabledPreview();
+        
         var name = $(this).attr('name'),
             value = $(this).val();
         currentAnnotation[name] = value;
@@ -565,6 +529,7 @@
             $('#annotation-timeline-'+ idAnnotation).attr('title', value);
             $('#annotation-timeline-'+ idAnnotation+' span').text(value);
         }
+        disabledPreview();
     });
 
     //delete annotation
@@ -578,15 +543,17 @@
     });
 
     function deleteAnnotation(idAnnotation){
-        disabledPreview();
+        
         $("#modal-confirm").modal('hide');
         annotations.removeId(idAnnotation);
         myProject.getAnnotations().removeId(idAnnotation, true);
         closeTab(idAnnotation);
         renderAnnotation();
+        disabledPreview();
     }
 
-//tab
+/* Tab */
+
     $('#onglet-annotations').on('click', 'a', function(e){
         e.preventDefault();
         $(this).tab('show');
@@ -631,6 +598,7 @@
             var output = Mustache.render(tplHead, dataView);
             $(tabContent).append(output);
             $(tabContent).find(".slider-duration").slider(configSlider(dataView));
+            currentSlider = $(tabContent).find(".slider-duration");
             $(tabContent).find(".ui-slider-range.ui-widget-header.ui-corner-all").css('background', dataView.color);
             $(tabContent).find('.tag-it').tagit(tagitParam);
             //type
@@ -734,6 +702,7 @@
     $('#onglet-annotations').on('show', 'a[data-toggle="annotation"]', function (e) {
         var idAnnotation = $(e.target).attr('data-id');
         currentAnnotation = _.find(annotations, function(c){ return c.id == idAnnotation; });
+        currentSlider = $('#tab-annotation-'+idAnnotation).find(".slider-duration");
         showCurrentAnnotationInTimeline(idAnnotation);
     });
 
@@ -762,7 +731,7 @@
         $('#tab-list-annotation').tab('show');
     }
 
-//video
+    //video
     function renderVideoInfo(videoWrap, dataVideo){
     
         var tplVideo = getTemplate('#tpl-video-row');
@@ -795,10 +764,11 @@
 
         labelModify.show();
         labelAdd.hide();
-        
+
+        disabledPreview();
     });
 
-//diaporama
+/* Slideshow */
 
     //bibliotheque
     $('.popup').on('click', '.bibliotheque-image a:not(.pagination a)', function(e){
@@ -818,6 +788,7 @@
         var listDiaporama = $('#diaporama-'+currentAnnotation.id);
         addImageToDiaporama(listDiaporama, image);
         $('.popup').modal('hide'); 
+        disabledPreview();
     });
 
     function addImageToDiaporama(diaporama, dataView){
@@ -851,6 +822,7 @@
             indexRow = $(this).parents('.row-image-diaporama').index();
         $(this).replaceWith(span);
         currentAnnotation.content.images[indexRow][name] = newValue;
+        disabledPreview();
     });
 
     $(document).on('blur', '.video-title-edit input, .video-description-edit textarea', function(){
@@ -859,6 +831,7 @@
             span = $('<span>').html(newValue);
         $(this).replaceWith(span);
         currentAnnotation.content[name] = newValue;
+        disabledPreview();
     });
 
     //bouton up / down
@@ -877,6 +850,7 @@
         currentAnnotation.content.images.move(oldIndex, newIndex);
 
         disabledBtnSortable(listDiaporama);
+        disabledPreview();
     });
 
     $('.tab-content').on('click','.btn-delete-image', function(e){
@@ -886,6 +860,7 @@
 
         rowImage.remove();
         currentAnnotation.content.images.splice(index, 1);
+        disabledPreview();
     });
 
     function disabledBtnSortable(listDiaporama){
@@ -894,246 +869,439 @@
         listDiaporama.find('tr.row-image-diaporama:last-child').find('.btn-sort.down').addClass('disabled');
     }
 
-    
-//links
-$('.tab-content').on('click', '.add-link', function(e){
-    e.preventDefault();
-    var tbody = $(this).parents('tfoot').siblings('tbody');
-    addLinkRow(tbody);
-});
-$('.tab-content').on('click', '.delete-link', function(e){
-    e.preventDefault();
-    var row = $(this).parents('tr'),
-        tbody = $(this).parents('tbody');
-
-    row.remove();
-    updateLinks(tbody);
-});
-function addLinkRow(tbody, dataView){
+    //links
+    $('.tab-content').on('click', '.add-link', function(e){
+        e.preventDefault();
+        var tbody = $(this).parents('tfoot').siblings('tbody');
+        addLinkRow(tbody);
+    });
+    $('.tab-content').on('click', '.delete-link', function(e){
+        e.preventDefault();
+        var row = $(this).parents('tr'),
+            tbody = $(this).parents('tbody');
 
-    //head commun à tous
-    var tplLinkRow = getTemplate('#tpl-links-row');
-    var output = Mustache.render(tplLinkRow, dataView);
-    tbody.append(output);
-
-}
-$('.tab-content').on('keyup', '.links-rows input', function(e){
-    var tbody = $(this).parents('.links-rows');
-    updateLinks(tbody);   
-});
-function updateLinks(tbody){
-    links = new Array();
+        row.remove();
+        updateLinks(tbody);
+    });
+    function addLinkRow(tbody, dataView){
 
-    $.each(tbody.find('tr'), function(k, v){
-        var urlLink = $(v).find('.url-link').val(),
-            titleLink = $(v).find('.title-link').val(),
-            link = {
-                url : urlLink,
-                title : titleLink
-            };
-            links.push(link);
+        //head commun à tous
+        var tplLinkRow = getTemplate('#tpl-links-row');
+        var output = Mustache.render(tplLinkRow, dataView);
+        tbody.append(output);
 
+    }
+    $('.tab-content').on('keyup', '.links-rows input', function(e){
+        var tbody = $(this).parents('.links-rows');
+        updateLinks(tbody);   
     });
-    currentAnnotation.content.links = links;
-}
+    function updateLinks(tbody){
+        links = new Array();
 
-//annotation audio
-$('.tab-content').on('keyup', '.annotation-audio-content input, .annotation-audio-content textarea', function(){
-    var name = $(this).attr('name'),
-        value = $(this).val();
-
-    currentAnnotation.content[name] = value;
-});
+        $.each(tbody.find('tr'), function(k, v){
+            var urlLink = $(v).find('.url-link').val(),
+                titleLink = $(v).find('.title-link').val(),
+                link = {
+                    url : urlLink,
+                    title : titleLink
+                };
+                links.push(link);
 
-//annotation slideshow
-$('.tab-content').on('click', '.btn-autostart', function(){
-    var autostart = $(this).attr('data-autostart');
-    if(autostart == "true"){ autostart = true;}
-    else {autostart = false;}
-    currentAnnotation.content.autostart = autostart;
-});
+        });
+        currentAnnotation.content.links = links;
+        disabledPreview();
+    }
 
-$('.tab-content').on('change keyup', '.config-diaporama input[name=duration]', function(){
-    var value = $(this).val();
-    if(!isNaN(value)){
-        currentAnnotation.content.slideduration = value * 1000;
-    }
-});
+    //annotation audio
+    $('.tab-content').on('keyup', '.annotation-audio-content input, .annotation-audio-content textarea', function(){
+        var name = $(this).attr('name'),
+            value = $(this).val();
 
-//save project
-$('.btn-save-project').bind('click', function(e){
-    $('.btn-apercu-projet').removeClass('disabled');
-
-    console.log(myProject.serialize());
+        currentAnnotation.content[name] = value;
+        disabledPreview();
+    });
 
-    $.ajax({
-        type: "POST",
-        url: urlSaveProject,
-        data: myProject.serialize(),
-        contentType: "application/cinelab",
-        headers: {
-            "X-CSRFToken": tokenSaveProject
-        },
-        success: function(data, status, request){
-            console.log('data : ', data);
-            console.log('status : ', status);
-            console.log('request : ', request);
+    //annotation slideshow
+    $('.tab-content').on('click', '.btn-autostart', function(){
+        var autostart = $(this).attr('data-autostart');
+        if(autostart == "true"){ autostart = true;}
+        else {autostart = false;}
+        disabledPreview();
+        currentAnnotation.content.autostart = autostart;
+    });
 
-        },
-        error: function(jqXHR, textStatus, errorThrown){
-            alert(gettext("Server error\nYour hashcut couldn't be published"));
+    $('.tab-content').on('change keyup', '.config-diaporama input[name=duration]', function(){
+        var value = $(this).val();
+        if(!isNaN(value)){
+            disabledPreview();
+            currentAnnotation.content.slideduration = value * 1000;
         }
     });
 
+    
+    //save project
+    $('.btn-save-project').bind('click', function(e){
+        e.preventDefault();
+        if($(this).hasClass('disabled')) return;
 
-});
+        showAlertByClassName('save-load');
+        var that = this;
+        $(this).addClass('disabled');
+
+        console.log(myProject.serialize());
+
+        $.ajax({
+            type: "POST",
+            url: urlSaveProject,
+            data: myProject.serialize(),
+            contentType: "application/cinelab",
+            headers: {
+                "X-CSRFToken": tokenSaveProject
+            },
+            success: function(data, status, request){
+                showAlertByClassName('save-ok');
+                $('.btn-apercu-projet').removeClass('disabled');
+                console.log('data : ', data);
+                console.log('status : ', status);
+                console.log('request : ', request);
 
-function disabledPreview(){
-    if(!$('.btn-apercu-projet').hasClass('disabled'))$('.btn-apercu-projet').addClass('disabled');
-}
+            },
+            error: function(jqXHR, textStatus, errorThrown){
+                showAlertByClassName('save-error');
+                //alert(gettext("Server error\nYour hashcut couldn't be published"));
+            },
+            complete : function(){
+                $(that).removeClass('disabled');
+            }
+        });
+    });
+    
+    //disabled preview
+    function disabledPreview(){
+        if(!$('.btn-apercu-projet').hasClass('disabled'))$('.btn-apercu-projet').addClass('disabled');
+    }
+    $(document).on('click', '.btn-apercu-projet.disabled', function(e){
+        e.preventDefault();
+    });
 
+    //alert
+    $('.alert').bind('close', function (e) {
+        e.preventDefault();
+        $(this).hide();
+    });
+
+    function showAlertByClassName(className){
+        $('.alert').hide();
+        $('.'+className).show();
+    }
 //################ config
-//tagit
-function onTagItChange(e, ui) {
-    var tagitType = $(this).attr('data-type'), 
-        value = $(this).val();
+    //tagit
+    function onTagItChange(e, ui) {
+        var tagitType = $(this).attr('data-type'), 
+            value = $(this).val();
+
+        disabledPreview();
+
+        if(tagitType == 'chapter'){
+            var idChapter = $(this).parents('form').attr('data-chapter-id');
+            currentChapter.keywords = value.split(',');
+            $('#row-list-chapter-'+idChapter).find('.list-chapter-tags').text(value);
+        }else{
+            currentAnnotation.keywords = value.split(',');
+        }
+    }
 
-    if(tagitType == 'chapter'){
-        var idChapter = $(this).parents('form').attr('data-chapter-id');
-        currentChapter.keywords = value.split(',');
-        $('#row-list-chapter-'+idChapter).find('.list-chapter-tags').text(value);
-    }else{
-        currentAnnotation.keywords = value.split(',');
+    var tagitParam = {
+        allowSpaces: true,
+        afterTagRemoved : onTagItChange,
+        afterTagAdded : onTagItChange
     }
-    
-}
+
+    //CLEditor annotation > text (wysiwyg) http://premiumsoftware.net/cleditor/docs/GettingStarted.html#optionalParameters
+    var wysiwygConfig = {
+        width:        450, 
+        height:       250, 
+        controls:     "bold italic underline strikethrough | font size " +
+                        "style | color highlight removeformat | bullets numbering | source",
+        fonts:        "Arial,Arial Black,Comic Sans MS,Courier New,Narrow,Garamond," +
+                        "Georgia,Impact,Sans Serif,Serif,Tahoma,Trebuchet MS,Verdana",
+        sizes:        "1,2,3,4,5,6,7",
+        styles:       [["Paragraph", "<p>"], ["Header 2", "<h2>"],
+                        ["Header 3", "<h3>"],  ["Header 4","<h4>"],  ["Header 5","<h5>"],
+                        ["Header 6","<h6>"]],
+        docType:      '<!DOCTYPE HTML>',
+        bodyStyle:    "margin:0; font-family: 'Helvetica Neue',​Helvetica,​Arial,​sans-serif;",
+        updateTextArea : function(text){
+            disabledPreview();
+            currentAnnotation.content.text = text;
+            return text;
+        },
+        updateFrame: function(text){
+            disabledPreview();
+            currentAnnotation.content.text = text;
+            return text;
+        }
+    };
 
-var tagitParam = {
-    afterTagRemoved : onTagItChange,
-    afterTagAdded : onTagItChange
-}
+    //slider
+    function configSlider(data){
+        return {
+            range: true,
+            values: [ data.begin.milliseconds, data.end.milliseconds ],
+            min: 0,
+            max: myMedia.duration.milliseconds,
+            slide: function( event, ui ) {
+                
+                data.setBegin(ui.values[0]);
+                data.setEnd(ui.values[1]);
+
+                var idSlider = $(this).attr('data-id'),
+                    wTimeline = $('.timeline-annotations').width(),
+                    annotationTimeline = $('#annotation-timeline-'+ data.id),
+                    width = Math.floor(data.getDuration() * wTimeline / myMedia.duration),
+                    left = Math.floor(data.begin * wTimeline / myMedia.duration);
+
+                $( '#'+ idSlider +'-begin span' ).html(data.begin.toString());
+                $( '#'+ idSlider +'-begin span' ).attr('data-milliseconds', data.begin);
+                $( '#'+ idSlider +'-duration' ).html(data.getDuration().toString());
+                $( '#'+ idSlider +'-end span' ).html(data.end.toString());
+                $( '#'+ idSlider +'-end span' ).attr('data-milliseconds', data.end);
+
+                annotationTimeline.css({
+                    left : left,
+                    width :width
+                });
+            },
+            start : function(){
+                var idSlider = $(this).attr('data-id'),
+                    annotationTimeline = $('#annotation-timeline-'+ data.id);
+                annotationTimeline.css('z-index',100);
+                disabledPreview();
+            },
+            stop : function(){
+                renderAnnotation();
+                refreshAnnotationDisplay(myMedia.getCurrentTime());
+            }
+        };
+    }
 
-//CLEditor annotation > text (wysiwyg)
-//http://premiumsoftware.net/cleditor/docs/GettingStarted.html#optionalParameters
-var wysiwygConfig = {
-    width:        450, 
-    height:       250, 
-    controls:     "bold italic underline strikethrough | font size " +
-                    "style | color highlight removeformat | bullets numbering | source",
-    fonts:        "Arial,Arial Black,Comic Sans MS,Courier New,Narrow,Garamond," +
-                    "Georgia,Impact,Sans Serif,Serif,Tahoma,Trebuchet MS,Verdana",
-    sizes:        "1,2,3,4,5,6,7",
-    styles:       [["Paragraph", "<p>"], ["Header 2", "<h2>"],
-                    ["Header 3", "<h3>"],  ["Header 4","<h4>"],  ["Header 5","<h5>"],
-                    ["Header 6","<h6>"]],
-    docType:      '<!DOCTYPE HTML>',
-    bodyStyle:    "margin:0; font-family: 'Helvetica Neue',​Helvetica,​Arial,​sans-serif;",
-    updateTextArea : function(text){
-        currentAnnotation.content.text = text;
-        return text;
-    },
-    updateFrame: function(text){
-        currentAnnotation.content.text = text;
-        return text;
+    //init annotation content data
+    function getContentAnnotationByType(type){
+        var content;
+        switch(type){
+            case 'audio':
+                content = {
+                    mimetype : "application/x-ldt-audio",
+                    url : "",
+                    embedcode : ""
+                };
+                break;
+            case 'video':
+                content = {
+                    mimetype : "application/x-ldt-video",
+                    url : "",
+                    embedcode : ""
+                };
+                break;
+            case 'text': 
+                content = {
+                    mimetype : "application/x-ldt-text",
+                    markup : "html",
+                    text : ""
+                };
+                break;
+            case 'links': 
+                content = {
+                    mimetype : "application/x-ldt-links",
+                    links : []
+                };
+                break;
+            case 'slideshow': 
+                content = {
+                    mimetype : "application/x-ldt-slideshow",
+                    slideduration : 1000,
+                    autostart : false,
+                    images : []
+                };
+                break;
+        }
+        return content;
+    }//getContentAnnotationByType
+
+    //unload
+    $(window).on("beforeunload", onLeave);
+    function onLeave(){
+        if($('.btn-apercu-projet').hasClass('disabled')) return "You have unsaved changes";
     }
-};
+
+/* Tangles */
+    var tangleMsPerPixel = 100,
+        activeTangle,
+        tangleStartX,
+        tangleStartVal,
+        tangleHasMoved;
+    
+    $('.chapter-widget-info').on('mousedown', '.time-tangle', function(evt){
+        activeTangle = $(this);
+        activeTangle.addClass("active");
+        tangleStartVal = +activeTangle.attr("data-milliseconds");
+        tangleStartX = evt.pageX;
+        tangleHasMoved = false;
+        $(this).parents('td').siblings('td').find(".time-tangle").addClass("deactivate");
+        return false;
+    });
+
+    $('.tab-content').on('mousedown', '.time-tangle', function(evt){
+        activeTangle = $(this);
+        activeTangle.addClass("active");
+        tangleStartVal = +activeTangle.attr("data-milliseconds");
+        tangleStartX = evt.pageX;
+        tangleHasMoved = false;
+        $(this).parents('td').siblings('td').find(".time-tangle").addClass("deactivate");
+        return false;
+    });
+
+    $(document)
+        .mousemove(function(evt) {
+            if (activeTangle) {
+                tangleHasMoved = true;
+                var newval = new IriSP.Model.Time(tangleMsPerPixel * (evt.pageX - tangleStartX) + tangleStartVal);
+                activeTangle.trigger("valuechange", newval);
+                return false;
+            }
+        })
+        .mouseup(function() {
+
+            if (activeTangle) {
+                if(activeTangle.hasClass('slider-tangle')){
+                    renderAnnotation();
+                    refreshAnnotationDisplay(myMedia.getCurrentTime());
+                }
+                $(".time-tangle").removeClass("active deactivate");
+                activeTangle = undefined;
+            }
+        });
+
+    //chapters
+    function updateRenderChapter(chapterData){
+        var segment = $('.chapter-segments li#'+chapterData.id),
+            wChapterSegmentWrap = $('.chapter-segments').width(),
+            wSegmentNew = chapterData.getDuration() * wChapterSegmentWrap / myMedia.duration,
+            lSegmentNew = chapterData.begin * wChapterSegmentWrap / myMedia.duration,
+            row = $('#row-list-chapter-'+chapterData.id),
+            form = ($('#form-chapter-edit-'+chapterData.id).length) ? $('#form-chapter-edit-'+chapterData.id) : false;
+
+        segment.css({
+            width : wSegmentNew,
+            left : lSegmentNew
+        });
+
+        row.find('.begin').text(chapterData.begin);
+        console.log(chapterData.getDuration())
+        row.find('.duration').text(chapterData.getDuration());
+        row.find('.end').text(chapterData.end);
 
-//slider
-function configSlider(data){
-    return {
-        range: true,
-        values: [ data.begin.milliseconds, data.end.milliseconds ],
-        min: 0,
-        max: myMedia.duration.milliseconds,
-        slide: function( event, ui ) {
-            
-            data.setBegin(ui.values[0]);
-            data.setEnd(ui.values[1]);
+        if(form){
+            form.find('.begin').text(chapterData.begin);
+            form.find('.begin').attr('data-milliseconds',chapterData.begin);
+            form.find('.duration').text(chapterData.getDuration());
+            form.find('.end').text(chapterData.end);
+            form.find('.end').attr('data-milliseconds',chapterData.end);
+        }
+    }
+
+    function updateChapterDuration(val, chapterBefore, chapterAfter){
+
+        if (val<=chapterAfter.end && val>=chapterBefore.begin && chapterAfter.end-val>secMiniChapter*1000 && val-chapterBefore.begin>secMiniChapter*1000) {
+            disabledPreview();
+            chapterAfter.setBegin(val);
+            chapterBefore.setEnd(val);
+
+            updateRenderChapter(chapterAfter);
+            updateRenderChapter(chapterBefore);
+        }
+    }
+
+    $('.chapter-widget-info').on('valuechange', '.tangle-start', function(evt, val){
+        var indexChapter = _.indexOf(chapters, currentChapter);
+        if(indexChapter == 0 || chapters.length<=1) return;
+        
+        var chapterBefore = chapters[indexChapter-1],
+            chapterAfter = currentChapter;
+
+        updateChapterDuration(val, chapterBefore, chapterAfter);
+    });
+
+    $('.chapter-widget-info').on('valuechange', '.tangle-end', function(evt, val){
+        var indexChapter = _.indexOf(chapters, currentChapter);
+        if(indexChapter == chapters.length-1 || chapters.length<=1) return;
+        
+        var chapterAfter = chapters[indexChapter+1],
+            chapterBefore = currentChapter;
+
+            updateChapterDuration(val, chapterBefore, chapterAfter);
+    });
 
-            var idSlider = $(this).attr('data-id'),
-                wTimeline = $('.timeline-annotations').width(),
-                annotationTimeline = $('#annotation-timeline-'+ data.id),
-                width = Math.floor(data.getDuration() * wTimeline / myMedia.duration),
-                left = Math.floor(data.begin * wTimeline / myMedia.duration);
+//annotations
+
+    $('.tab-content').on('valuechange', '.tangle-start', function(evt, val){
+        var max = currentSlider.slider('values')[1],
+            min = 0,
+            beginOrEnd = 'begin';
+
+        updateAnnotationDuration(val, min, max, beginOrEnd);
+    });
+
+    $('.tab-content').on('valuechange', '.tangle-end', function(evt, val){
+        var max = myMedia.duration,
+            min = currentSlider.slider('values')[0],
+            beginOrEnd = 'end';
+
+        updateAnnotationDuration(val, min, max, beginOrEnd);
+    });
 
-            $( '#'+ idSlider +'-begin' ).html(data.begin.toString());
-            $( '#'+ idSlider +'-duration' ).html(data.getDuration().toString());
-            $( '#'+ idSlider +'-end' ).html(data.end.toString());
+    function updateAnnotationDuration(val, min, max, beginOrEnd){
+        var idAnnotation = currentAnnotation.id,
+            tabAnnotation = $('#tab-annotation-'+idAnnotation),
+            spanTangleStart = tabAnnotation.find('.tangle-start'),
+            spanTangleEnd = tabAnnotation.find('.tangle-end'),
+            spanDuration = tabAnnotation.find('#'+idAnnotation+'-duration');
+
+        if(val<max && val>min){
+            disabledPreview();
+            if(beginOrEnd == 'begin'){currentAnnotation.setBegin(val);}
+            if(beginOrEnd == 'end'){currentAnnotation.setEnd(val);}
+
+            spanTangleStart.html(currentAnnotation.begin.toString());
+            spanTangleStart.attr('data-milliseconds', currentAnnotation.begin);
+            spanDuration.html(currentAnnotation.getDuration().toString());
+            spanTangleEnd.html(currentAnnotation.end.toString());
+            spanTangleEnd.attr('data-milliseconds', currentAnnotation.end);
+
+            var wTimeline = $('.timeline-annotations').width(),
+            annotationTimeline = $('#annotation-timeline-'+ idAnnotation),
+            width = Math.floor(currentAnnotation.getDuration() * wTimeline / myMedia.duration),
+            left = Math.floor(currentAnnotation.begin * wTimeline / myMedia.duration);
 
             annotationTimeline.css({
                 left : left,
                 width :width
             });
-        },
-        start : function(){
-            var idSlider = $(this).attr('data-id'),
-                annotationTimeline = $('#annotation-timeline-'+ data.id);
-            annotationTimeline.css('z-index',100);
-        },
-        stop : function(){
-            renderAnnotation();
-            refreshAnnotationDisplay(myMedia.getCurrentTime());
+            currentSlider.slider('values', [currentAnnotation.begin, currentAnnotation.end])
         }
-    };
-}
+    }
 
-//init annotation content data
-function getContentAnnotationByType(type){
-    var content;
-    switch(type){
-        case 'audio':
-            content = {
-                mimetype : "application/x-ldt-audio",
-                url : "",
-                embedcode : ""
-            };
-            break;
-        case 'video':
-            content = {
-                mimetype : "application/x-ldt-video",
-                url : "",
-                embedcode : ""
-            };
-            break;
-        case 'text': 
-            content = {
-                mimetype : "application/x-ldt-text",
-                markup : "html",
-                text : ""
-            };
-            break;
-        case 'links': 
-            content = {
-                mimetype : "application/x-ldt-links",
-                links : []
-            };
-            break;
-        case 'slideshow': 
-            content = {
-                mimetype : "application/x-ldt-slideshow",
-                slideduration : 1000,
-                autostart : false,
-                images : []
-            };
-            break;
-    }
-    return content;
-}//getContentAnnotationByType
+    //test
+    $('.log-annotations').bind('click', function(e){
+        e.preventDefault();
+        console.log(annotations.length + ' annotations', annotations);
+        currentSlider.slider( "values", 0, 55 );
+    });
 
-
-
-
-//test
-
-$('.log-annotations').bind('click', function(e){
-    e.preventDefault();
-    console.log(annotations.length + ' annotations', annotations);
-});
-
-$('.log-chapters').bind('click', function(e){
-    e.preventDefault();
-    console.log(chapters.length + ' chapitres',chapters);
-});
+    $('.log-chapters').bind('click', function(e){
+        e.preventDefault();
+        console.log(chapters.length + ' chapitres',chapters);
+    });
 
 });//ready
 
--- a/src/metadatacomposer/static/metadatacomposer/js/metadataplayer-core.js	Mon Jun 10 15:58:23 2013 +0200
+++ b/src/metadatacomposer/static/metadatacomposer/js/metadataplayer-core.js	Mon Jun 10 16:15:11 2013 +0200
@@ -1180,7 +1180,10 @@
             return (_e.elementType === _listId);
         });
     } else {
-        return this.contents[_listId] || new IriSP.List(this.directory);
+        if (typeof this.contents[_listId] === "undefined") {
+            this.contents[_listId] = new IriSP.List(this.directory);
+        }
+        return this.contents[_listId];
     }
 };
 
--- a/src/metadatacomposer/static/metadatacomposer/js/tangle.js	Mon Jun 10 15:58:23 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/* Tangles */
-    var tangleMsPerPixel = 100,
-        activeTangle,
-        tangleStartX,
-        tangleStartVal,
-        tangleHasMoved;
-    
-    $('.chapter-widget-info').on('mousedown', '.time-tangle', function(evt){
-        activeTangle = $(this);
-        activeTangle.addClass("active");
-        tangleStartVal = +activeTangle.attr("data-milliseconds");
-        tangleStartX = evt.pageX;
-        tangleHasMoved = false;
-        $(this).parents('td').siblings('td').find(".time-tangle").addClass("deactivate");
-        return false;
-    });
-
-    $(document)
-        .mousemove(function(evt) {
-            if (activeTangle) {
-                tangleHasMoved = true;
-                var newval = new IriSP.Model.Time(tangleMsPerPixel * (evt.pageX - tangleStartX) + tangleStartVal);
-                activeTangle.trigger("valuechange", newval);
-                return false;
-            }
-        })
-        .mouseup(function() {
-            if (activeTangle) {
-                $(".time-tangle").removeClass("active deactivate");
-                activeTangle = undefined;
-            }
-        });
-
-    function updateRenderChapter(chapterData){
-        var segment = $('.chapter-segments li#'+chapterData.id),
-            wChapterSegmentWrap = $('.chapter-segments').width(),
-            wSegmentNew = chapterData.getDuration() * wChapterSegmentWrap / myMedia.duration,
-            lSegmentNew = chapterData.begin * wChapterSegmentWrap / myMedia.duration,
-            row = $('#row-list-chapter-'+chapterData.id),
-            form = ($('#form-chapter-edit-'+chapterData.id).length) ? $('#form-chapter-edit-'+chapterData.id) : false;
-
-        segment.css({
-            width : wSegmentNew,
-            left : lSegmentNew
-        });
-
-        row.find('.begin').text(chapterData.begin);
-        console.log(chapterData.getDuration())
-        row.find('.duration').text(chapterData.getDuration());
-        row.find('.end').text(chapterData.end);
-
-        if(form){
-            form.find('.begin').text(chapterData.begin);
-            form.find('.begin').attr('data-milliseconds',chapterData.begin);
-            form.find('.duration').text(chapterData.getDuration());
-            form.find('.end').text(chapterData.end);
-            form.find('.end').attr('data-milliseconds',chapterData.end);
-        }
-    }
-
-    function updateChapterDuration(val, chapterBefore, chapterAfter){
-
-        if (val<=chapterAfter.end && val>=chapterBefore.begin && chapterAfter.end-val>secMiniChapter*1000 && val-chapterBefore.begin>secMiniChapter*1000) {
-            chapterAfter.setBegin(val);
-            chapterBefore.setEnd(val);
-
-            updateRenderChapter(chapterAfter);
-            updateRenderChapter(chapterBefore);
-        }
-    }
-
-    $('.chapter-widget-info').on('valuechange', '.tangle-start', function(evt, val){
-        var indexChapter = _.indexOf(chapters, currentChapter);
-        if(indexChapter == 0 || chapters.length<=1) return;
-        
-        var chapterBefore = chapters[indexChapter-1],
-            chapterAfter = currentChapter;
-
-        updateChapterDuration(val, chapterBefore, chapterAfter);
-    });
-
-    $('.chapter-widget-info').on('valuechange', '.tangle-end', function(evt, val){
-        var indexChapter = _.indexOf(chapters, currentChapter);
-        if(indexChapter == chapters.length-1 || chapters.length<=1) return;
-        
-        var chapterAfter = chapters[indexChapter+1],
-            chapterBefore = currentChapter;
-
-            updateChapterDuration(val, chapterBefore, chapterAfter);
-
-        
-    });
-    /*
-    $(".tangle-start")
-        .mouseup(function(evt) {
-
-            if (!tangleHasMoved && currentMedia && currentSegment) {
-                currentMedia.setCurrentTime(currentSegment.begin);
-            }
-        })
-        .on("valuechange", function(evt, val) {
-
-            if (currentMedia && currentSegment) {
-                currentSegment.setBegin(val);
-            }
-        });
-
-    $(".tangle-end")
-        .mouseup(function(evt) {
-            if (!tangleHasMoved && currentMedia && currentSegment) {
-                currentMedia.setCurrentTime(currentSegment.end);
-            }
-        })
-        .on("valuechange", function(evt, val) {
-            if (currentMedia && currentSegment) {
-                currentSegment.setEnd(val);
-            }
-        });
-    $(".tangle-duration").on("valuechange", function(evt, val) {
-        if (currentMedia && currentSegment) {
-            currentSegment.setDuration(val);
-        }
-       
-    }); */
\ No newline at end of file
--- a/src/metadatacomposer/templates/metadatacomposer_edit.html	Mon Jun 10 15:58:23 2013 +0200
+++ b/src/metadatacomposer/templates/metadatacomposer_edit.html	Mon Jun 10 16:15:11 2013 +0200
@@ -40,6 +40,20 @@
         </header>
         <section>
             <div class="container">
+                <div class="row alerts">
+                    <div class="save-load alert alert-info fade in">
+                        <button type="button" class="close" data-dismiss="alert">&times;</button>
+                        <i class="icon-spinner icon-spin"></i> Enregistrement du projet en cours...
+                    </div>
+                    <div class="save-ok  alert alert-success fade in">
+                        <button type="button" class="close" data-dismiss="alert">&times;</button>
+                        <i class="icon-save"></i> Le projet a bien été sauvegardé !
+                    </div>
+                    <div class="save-error alert alert-error fade in">
+                        <button type="button" class="close" data-dismiss="alert">&times;</button>
+                        <i class="icon-warning-sign"></i> Une erreur est survenue lors de la sauvegarde du projet.
+                    </div>
+                </div>
                 <div class="row project-head">
                     <div class="span7">
                         <div class="project-title-editor">
@@ -49,7 +63,7 @@
 
                     </div>
                     <div class="span5 text-right project-action">
-                        <a href="{% url 'composer_preview_player' branding=branding ldt_id=ldt_id %}" class="btn disabled btn-apercu-projet"><i class="icon-eye-open"></i> Voir aperçu</a>
+                        <a href="{% url 'composer_preview_player' branding=branding ldt_id=ldt_id %}" class="btn btn-apercu-projet"><i class="icon-eye-open"></i> Voir aperçu</a>
                         <a href="#" class="btn btn-success btn-save-project"><i class="icon-save"></i> Sauvegarder le projet</a>
                     </div>
                 </div>
@@ -491,7 +505,6 @@
             </div><!-- /.container -->
         </section>
         <footer>
-            <a href="#" class="log-annotations">Log annotations</a> - <a href="#" class="log-chapters">Log chapitres</a>
         </footer>
     </div>
 
@@ -558,9 +571,13 @@
                 </thead>
                 <tbody>
                     <tr>
-                        <td id="{% templatetag openvariable %}id{% templatetag closevariable %}-begin" class="span1">{% templatetag openvariable %}begin{% templatetag closevariable %}</td>
+                        <td id="{% templatetag openvariable %}id{% templatetag closevariable %}-begin" class="span1">
+                            <span data-milliseconds="{% templatetag openvariable %}begin.milliseconds{% templatetag closevariable %}" class="time-tangle tangle-start slider-tangle">{% templatetag openvariable %}begin{% templatetag closevariable %}</span>
+                        </td>
                         <td id="{% templatetag openvariable %}id{% templatetag closevariable %}-duration" class="span1">{% templatetag openvariable %}getDuration{% templatetag closevariable %}</td>
-                        <td id="{% templatetag openvariable %}id{% templatetag closevariable %}-end" class="span1">{% templatetag openvariable %}end{% templatetag closevariable %}</td>
+                        <td id="{% templatetag openvariable %}id{% templatetag closevariable %}-end" class="span1">
+                            <span data-milliseconds="{% templatetag openvariable %}end.milliseconds{% templatetag closevariable %}" class="time-tangle tangle-end slider-tangle">{% templatetag openvariable %}end{% templatetag closevariable %}</span>
+                        </td>
                     </tr>
                 </tbody>
             </table>
@@ -905,7 +922,6 @@
     <script src="{% static 'metadatacomposer/js/metadataplayer-core.js' %}"></script>
     <script src="{% static 'metadatacomposer/js/ldt-serializer.js' %}"></script>
     <script src="{% static 'metadatacomposer/js/common.js' %}"></script>
-    <script src="{% static 'metadatacomposer/js/tangle.js' %}"></script>
     <script src="{% static 'metadatacomposer/js/edition.js' %}"></script>
     <script>
     var spinParam = {