Improved timeline
authorveltr
Mon, 09 Jul 2012 19:44:02 +0200
changeset 75 ef3377d7a4f7
parent 74 e107c77600e8
child 76 9b98700d12b7
Improved timeline
timeline/assets/sprites.psd
timeline/css/timeline.css
timeline/data/occurrences.json
timeline/img/sprites.png
timeline/js/timeline.js
Binary file timeline/assets/sprites.psd has changed
--- a/timeline/css/timeline.css	Fri Jul 06 18:57:20 2012 +0200
+++ b/timeline/css/timeline.css	Mon Jul 09 19:44:02 2012 +0200
@@ -1,5 +1,58 @@
-p, h2, h3 {
-    margin: 2px 0; padding: 0;
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed, 
+figure, figcaption, footer, header, hgroup, 
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+    margin: 0;
+    padding: 0;
+    border: 0;
+    font-size: 100%;
+    font: inherit;
+    vertical-align: baseline;
+}
+
+ul, li {
+    list-style: none;
+}
+
+input::-moz-focus-inner /*Remove button padding in FF*/
+{ 
+    border: 0;
+    padding: 0;
+}
+
+table {
+    border-collapse: separate; border-spacing: 0;
+}
+
+th, td {
+    vertical-align: top;
+}
+
+img a {
+    border: none;
+}
+
+body {
+    font-size: 10px; font-family: Arial, Helvetica, sans-serif;
+}
+
+/*************************************************/
+
+.Onglets {
+    display: inline-block; border-style: solid solid none none; border-color: #ccc; border-width: 1px;
+}
+
+.Onglets li {
+    display: inline-block; background: url(../img/barbgd.png); font-size: 14px; height: 15px; padding: 5px; border-style: none none none solid; border-color: #ccc; border-width: 1px;
 }
 
 /************************************************/
@@ -113,7 +166,7 @@
     position: absolute; top: 0; height: 100%; margin-left: -1px; width: 2px; background: #f000ff;
 }
 
-.Tl-Occurrence, .Tl-Cluster, .Tl-AddOccurrence {
+.Tl-Occurrence, .Tl-Cluster, .Tl-AddOccurrence, .Ls-OccIcon {
     width: 19px; height: 22px; background: url(../img/sprites.png); cursor: pointer;
 }
 
@@ -145,12 +198,44 @@
     background-position: -19px -72px;
 }
 
-.Tl-Occboth {
+.Tl-Occnarrative.Tl-Occa_valider {
     background-position: -38px -50px;
 }
 
+.Tl-Occpublication.Tl-Occa_valider {
+    background-position: -57px -50px;
+}
+
+.Tl-Occnarrative.Tl-Editing.Tl-Occa_valider {
+    background-position: -38px -72px;
+}
+
+.Tl-Occpublication.Tl-Editing.Tl-Occa_valider {
+    background-position: -57px -72px;
+}
+
+.Tl-Occnarrative.Tl-Occvalide {
+    background-position: -76px -50px;
+}
+
+.Tl-Occpublication.Tl-Occvalide {
+    background-position: -95px -50px;
+}
+
+.Tl-Occnarrative.Tl-Editing.Tl-Occvalide {
+    background-position: -76px -72px;
+}
+
+.Tl-Occpublication.Tl-Editing.Tl-Occvalide {
+    background-position: -95px -72px;
+}
+
+.Tl-Cluster {
+    background-position: -114px -50px;
+}
+
 .Tl-Link {
-    position: absolute; left: 0; bottom: 0; width: 11px; height: 11px; background: url(../img/sprites.png) -38px -83px; display: none;
+    position: absolute; left: 0; bottom: 0; width: 11px; height: 11px; background: url(../img/sprites.png) -114px -83px; display: none;
 }
 
 .Tl-ClusterCount {
@@ -237,3 +322,78 @@
 
 /**********************************/
 
+.Ls-Main {
+    width: 950px; height: 200px; background: #fafafa; border: 1px solid #cccccc;
+}
+
+.Ls-Filtres {
+    width: 540px;
+    float: left;
+}
+
+.Ls-Column {
+    width: 180px; height: 160px;
+    float: left;
+}
+
+.Ls-Main h2 {
+    text-align: center; margin: 0; font-size: 14px; font-weight: bold; clear: both;
+}
+
+.Ls-Resultats {
+    height: 200px; overflow: auto; border-left: 1px solid #cccccc;
+}
+
+.Ls-Input {
+    width: 100px; margin-right: 5px;
+}
+
+.Ls-Label {
+    display: inline-block; width: 30px; font-size: 12px;
+}
+
+.Ls-Main h3 {
+    font-size: 12px; font-weight: bold; margin: 5px 0 0;
+    clear: both;
+}
+
+.Ls-Critere {
+    font-size: 11px; background: #ffffff; color: #333333; cursor: pointer;
+    border-radius: 4px; margin: 2px; padding: 4px; display: inline-block; clear: both;
+}
+
+.Ls-Critere.Ls-Active {
+    background: #ffb0ff;
+}
+
+.Ls-Critere:hover {
+    background: #ffe0ff;
+}
+
+.Ls-Resultats ul {
+    border-top: 1px solid #cccccc;
+}
+
+li.Ls-Occurrence {
+    border-bottom: 1px solid #cccccc; clear: both;
+}
+
+.Ls-Occurrence-Title {
+    width: 260px; float: left; font-size: 14px;
+}
+
+.Ls-Occurrence-Date {
+    padding-top: 2px; font-size: 12px;
+}
+
+.Ls-CrWithIcon {
+    padding: 5px 2px;
+}
+
+.Ls-OccIcon {
+    float: right;
+}
+
+.Ls-CrWithIcon .Ls-OccIcon {
+    margin: -4px 0;
+}
--- a/timeline/data/occurrences.json	Fri Jul 06 18:57:20 2012 +0200
+++ b/timeline/data/occurrences.json	Mon Jul 09 19:44:02 2012 +0200
@@ -6,9 +6,8 @@
             "titre" : "Une histoire qui se passe à Carcassonne",
             "description" : "Ma première occurrence narrative",
             "univers" : "U06",
-            "statut" : "valide",
+            "statut" : "a_valider",
             "publie" : true,
-            "verrouille" : false,
             "personnagesSecondaires": [
                 "Personnage A",
                 "Personnage B"
@@ -23,7 +22,6 @@
             "univers" : "U01",
             "statut" : "valide",
             "publie" : true,
-            "verrouille" : false,
             "personnagesSecondaires": [
                 "Personnage A",
                 "Personnage B"
@@ -38,9 +36,8 @@
             "titre" : "Quelques minutes après au même endroit",
             "description" : "Ma troisième occurrence narrative",
             "univers" : "U01",
-            "statut" : "valide",
+            "statut" : "a_realiser",
             "publie" : true,
-            "verrouille" : false,
             "personnagesSecondaires": [
                 "Personnage A",
                 "Personnage B"
@@ -53,9 +50,8 @@
             "titre" : "Alors que, dans la Cité, Azda...",
             "description" : "Ma quatrième occurrence narrative",
             "univers" : "U07",
-            "statut" : "valide",
+            "statut" : "a_valider",
             "publie" : true,
-            "verrouille" : false,
             "personnagesSecondaires": [
                 "Personnage A",
                 "Personnage B"
@@ -72,9 +68,8 @@
             "titre" : "Nous publions des infos sur Bob la Carcasse",
             "description" : "Ma première occurrence de publication",
             "univers" : "U06",
-            "statut" : "valide",
+            "statut" : "a_realiser",
             "publie" : true,
-            "verrouille" : true,
             "dependDe" : [
                 "N01"
             ]
@@ -87,7 +82,6 @@
             "univers" : "U04",
             "statut" : "valide",
             "publie" : true,
-            "verrouille" : false,
             "dependDe" : []
         },
         {
@@ -96,9 +90,8 @@
             "titre" : "Encore des nouvelles d'Arthur, qui tweete",
             "description" : "Ma troisième occurrence de publication",
             "univers" : "U04",
-            "statut" : "valide",
+            "statut" : "a_valider",
             "publie" : true,
-            "verrouille" : false,
             "dependDe" : [
                 "N03"
             ]
Binary file timeline/img/sprites.png has changed
--- a/timeline/js/timeline.js	Fri Jul 06 18:57:20 2012 +0200
+++ b/timeline/js/timeline.js	Mon Jul 09 19:44:02 2012 +0200
@@ -11,6 +11,10 @@
 
 /* Utility Functions */
 
+Tlns.Utils.zeroPad = function(_n) {
+    return (_n < 10 ? "0" : "") + _n;
+}
+
 Tlns.Utils.SetDefaults = function(_object, _defaults, _options) {
     var _options = _options || {};
     _(_defaults).each(function(_v, _k) {
@@ -34,22 +38,19 @@
     if (typeof _data !== "object") {
         _date = new Date(_date);
     }
-    function zeroPad(_n) {
-        return (_n < 10 ? "0" : "") + _n
-    }
     var _params = {
         hours: _date.getHours(),
-        "0hours": zeroPad(_date.getHours()),
+        "0hours": Tlns.Utils.zeroPad(_date.getHours()),
         minutes: _date.getMinutes(),
-        "0minutes": zeroPad(_date.getMinutes()),
+        "0minutes": Tlns.Utils.zeroPad(_date.getMinutes()),
         seconds: _date.getSeconds(),
-        "0seconds": zeroPad(_date.getSeconds()),
+        "0seconds": Tlns.Utils.zeroPad(_date.getSeconds()),
         dayOfWeek: ["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"][_date.getDay()],
         shortDayOfWeek: ["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"][_date.getDay()],
         dayOfMonth: _date.getDate(),
-        "0dayOfMonth": zeroPad(_date.getDate()),
+        "0dayOfMonth": Tlns.Utils.zeroPad(_date.getDate()),
         monthNumber: 1+_date.getMonth(),
-        "0monthNumber": zeroPad(1+_date.getMonth()),
+        "0monthNumber": Tlns.Utils.zeroPad(1+_date.getMonth()),
         monthName: ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"][_date.getMonth()],
         shortMonthName: ["jan","fev","mar","avr","mai","jun","jul","aou","sep","oct","nov","dec"][_date.getMonth()],
         year: _date.getFullYear()
@@ -89,6 +90,50 @@
     _ctx.stroke();
 }
 
+Tlns.Utils.timeFieldProcess = function(_val) {
+    var _h = 0,
+        _m = 0,
+        _matches = _val.match(/(\d+)/g);
+    if (_matches && _matches.length) {
+        _h = Math.min(23, +(_matches[0]));
+        if (_matches.length > 1) {
+            _m = Math.min(59, +(_matches[1]));
+        }
+    }
+    return {
+        hours: _h,
+        minutes: _m,
+        text: Tlns.Utils.zeroPad(_h) + ':' + Tlns.Utils.zeroPad(_m)
+    }
+}
+
+Tlns.Utils.dateFieldProcess = function(_val) {
+    var _now = new Date(),
+        _y = _now.getFullYear(),
+        _m = 1 + _now.getMonth(),
+        _d = _now.getDate(),
+        _matches = _val.match(/(\d+)/g);
+    if (_matches && _matches.length) {
+        _d = Math.min(31, +(_matches[0]));
+        if (_matches.length > 1) {
+            _m = Math.min(12, +(_matches[1]));
+        }
+        if (_matches.length > 2) {
+            _y = parseInt(_matches[2]);
+            if (_y < 2000) {
+                _y += 2000;
+            }
+            _y = Math.min(2020, Math.max(2000, _y));
+        }
+    }
+    return {
+        year: _y,
+        month: _m,
+        date: _d,
+        text: Tlns.Utils.zeroPad(_d) + '/' + Tlns.Utils.zeroPad(_m) + '/' + _y
+    }
+}
+
 /* Defaults */
 
 Tlns.Defaults.Timeline = {
@@ -147,8 +192,13 @@
     sync_now: true,
     url_occurrences: '',
     occurrences: [],
-    cluster_spacing: 10,
-    tooltip_date_format: '{{dayOfMonth}} {{shortMonthName}} {{year}} {{0hours}}:{{0minutes}}'
+    cluster_spacing: 12,
+    tooltip_date_format: '{{dayOfMonth}} {{shortMonthName}} {{year}} {{0hours}}:{{0minutes}}',
+    statuses: {
+        "valide": "Validée",
+        "a_valider": "À valider",
+        "a_realiser": "À réaliser"
+    }
 }
 
 for (var _i = 0; _i < Tlns.Defaults.Timeline.timescales.length; _i++) {
@@ -157,7 +207,7 @@
 
 /* Templates */
 
-Tlns.Templates.Timeline = '<div class="Tl-TopBar"><div class="Tl-TopBar-Button Tl-Border-Right"><div class="Tl-TopBar-AddButton"></div></div><div class="Tl-TopBar-Spacer Tl-Border-Right"></div>'
+Tlns.Templates.Timeline = '<ul class="Onglets"><li>Frise chronologique</li><li>Liste des occurrences</li></ul><div class="Tl-Main"><div class="Tl-TopBar"><div class="Tl-TopBar-Button Tl-Border-Right"><div class="Tl-TopBar-AddButton"></div></div><div class="Tl-TopBar-Spacer Tl-Border-Right"></div>'
     + '<div class="Tl-TopBar-Button Tl-Border-Right"><div class="Tl-TopBar-PreviousButton"></div></div><div class="Tl-TopBar-TimeSpan Tl-TopBar-TextBtn Tl-Border-Right">--/--</div>'
     + '<div class="Tl-TopBar-Button Tl-Border-Right"><div class="Tl-TopBar-SyncButton"></div></div><div class="Tl-TopBar-Button Tl-Border-Right"><div class="Tl-TopBar-NextButton"></div></div><div class="Tl-TopBar-Spacer Tl-Border-Right"></div>'
     + '<div class="Tl-TopBar-Timescales">{{#timescales}}<div class="Tl-TopBar-Button Tl-TopBar-TextBtn Tl-Border-Right" data-level="{{level}}">{{label}}</div>{{/timescales}}</div></div>'
@@ -165,27 +215,30 @@
     + '<div class="Tl-MainPart"><div class="Tl-Layer Tl-Grid"></div><canvas class="Tl-Layer Tl-Canvas"></canvas><canvas class="Tl-Layer Tl-Linking-Canvas"></canvas><div class="Tl-Layer Tl-Occurrences"></div>'
     + '<ul class="Tl-Adding"><li class="Tl-AddingTitle">Ajout d\'une occurrence</li><li><span>Narrative</span><div class="Tl-AddOccurrence Tl-Occnarrative" occurrence-type="narrative" title="Glisser sur la frise chronologique pour ajouter"></div></li>'
     + '<li><span>De Publication</span><div class="Tl-AddOccurrence Tl-Occpublication" occurrence-type="publication" title="Glisser sur la frise chronologique pour ajouter"></div></li></ul></div>'
-    + '<div class="Tl-Overlay-Container"><div class="Tl-Overlay-Box"><div class="Tl-Overlay"><div class="Tl-Overlay-Tip-Top"></div><div class="Tl-Overlay-Main"></div><div class="Tl-Overlay-Tip-Bottom"></div></div></div></div></div>';
+    + '<div class="Tl-Overlay-Container"><div class="Tl-Overlay-Box"><div class="Tl-Overlay"><div class="Tl-Overlay-Tip-Top"></div><div class="Tl-Overlay-Main"></div><div class="Tl-Overlay-Tip-Bottom"></div></div></div></div></div></div>'
     
-Tlns.Templates.List = '<div class="Ls-Main"><h2>Filtres&nbsp;:</h2><h3>Titre</h3><p><input class="Ls-Search" type="search" placeholder="Rechercher" /></p><h3>Univers&nbsp;:</h3><ul class="Ls-Univers"></ul>'
-    + '<h3>Type d\'occurrence</h3><ul class="Ls-Occtypes"><li><input type="checkbox" value="narrative" checked>Narratives</li><li><input type="checkbox" value="publication" checked>de Publication</li></ul></p>'
-    + '<h2>Occurrences&nbsp;:</h2><ul class="Ls-Occurrences"></ul></div>';
+    +'<div class="Ls-Main"><div class="Ls-Filtres"><h2>Filtres&nbsp;:</h2>'
+    + '<div class="Ls-Column"><h3>Univers&nbsp;:</h3><ul class="Ls-Univers"></ul></div>'
+    + '<div class="Ls-Column"><h3>Type d\'occurrence&nbsp;:</h3><ul class="Ls-Occtypes"><li data="narrative" class="Ls-Critere Ls-Active Ls-CrWithIcon"><div class="Ls-OccIcon Tl-Occnarrative"></div>Narratives</li><li data="publication" class="Ls-Critere Ls-Active Ls-CrWithIcon"><div class="Ls-OccIcon Tl-Occpublication"></div>de Publication</li></ul>'
+    + '<h3>Statut&nbsp;:</h3><ul class="Ls-Occstatuses"><li data="a_realiser" class="Ls-Critere Ls-Active Ls-CrWithIcon"><div class="Ls-OccIcon Tl-Occpublication Tl-Occa_realiser"></div>À réaliser</li><li data="a_valider" class="Ls-Critere Ls-Active Ls-CrWithIcon"><div class="Ls-OccIcon Tl-Occpublication Tl-Occa_valider"></div>À valider</li><li data="valide" class="Ls-Critere Ls-Active Ls-CrWithIcon"><div class="Ls-OccIcon Tl-Occpublication Tl-Occvalide"></div>Validé</li></ul></div>'
+    + '<div class="Ls-Column"><h3>Recherche par titre&nbsp;:</h3><p><input class="Ls-Search" type="search" placeholder="Rechercher" /></p><h3>Date&nbsp;:</h3><p><label class="Ls-Label">Du </label><input class="Ls-From-Date Ls-Input" /></p><p><label class="Ls-Label">à </label><input class="Ls-From-Time Ls-Input" /></p><p><label class="Ls-Label">Au </label><input class="Ls-To-Date Ls-Input" /></p><p><label class="Ls-Label">à </label><input class="Ls-To-Time Ls-Input" /></p></div>'
+    + '</div><div class="Ls-Resultats"><h2>Occurrences&nbsp;:</h2><ul class="Ls-Occurrences"></ul></div></div>';
 
 Tlns.Templates.Univers = '<span class="Tl-UniversText">{{title}}</span>';
 
-Tlns.Templates.Univers_List = '{{#univers}}<li><input type="checkbox" value="{{id}}" checked>{{title}}</li>{{/univers}}';
+Tlns.Templates.Univers_List = '{{#univers}}<li data="{{id}}" class="Ls-Critere Ls-Active">{{title}}</li>{{/univers}}';
 
-Tlns.Templates.Occurrence = '{{#clusters}}<div class="Tl-Cluster Tl-Occ{{type}}" style="left: {{x}}px; top: {{y}}px;" cluster-contents="{{contents}}">'
+Tlns.Templates.Occurrence = '{{#clusters}}<div class="Tl-Cluster" style="left: {{x}}px; top: {{y}}px;" cluster-contents="{{contents}}">'
     + '<div class="Tl-ClusterCount">{{occurrences.length}}</div></div>{{/clusters}}'
-    + '{{#occurrences}}<div class="Tl-Occurrence Tl-OccOnGrid Tl-Occ{{type}}{{#editing}} Tl-Editing{{/editing}}" occurrence-id="{{id}}" style="left: {{x}}px; top: {{y}}px;">'
-    + '{{#locked}}<div class="Tl-Locked"></div>{{/locked}}<div class="Tl-Link"{{#editing}} style="display: block"{{/editing}}></div></div>{{/occurrences}}{{#open_cluster}}<div class="Tl-ClusterOverlay" style="left: {{x}}px; top: {{y}}px;">'
-    + '{{#occurrences}}<div class="Tl-Occurrence Tl-OccInCluster Tl-Occ{{type}}{{#editing}} Tl-Editing{{/editing}}" occurrence-id="{{id}}">'
+    + '{{#occurrences}}<div class="Tl-Occurrence Tl-OccOnGrid Tl-Occ{{type}} Tl-Occ{{status}}{{#editing}} Tl-Editing{{/editing}}" occurrence-id="{{id}}" style="left: {{x}}px; top: {{y}}px;">'
+//  + '{{#locked}}<div class="Tl-Locked"></div>{{/locked}}'
+    + '<div class="Tl-Link"{{#editing}} style="display: block"{{/editing}}></div></div>{{/occurrences}}{{#open_cluster}}<div class="Tl-ClusterOverlay" style="left: {{x}}px; top: {{y}}px;">'
+    + '{{#occurrences}}<div class="Tl-Occurrence Tl-OccInCluster Tl-Occ{{type}} Tl-Occ{{status}}{{#editing}} Tl-Editing{{/editing}}" occurrence-id="{{id}}">'
     + '{{#locked}}<div class="Tl-Locked"></div>{{/locked}}<div class="Tl-Link"{{#editing}} style="display: block"{{/editing}}></div></div>{{/occurrences}}</div>{{/open_cluster}}';
 
-Tlns.Templates.Occurrence_List = '{{#occurrences}}<li><h3>{{title}}</h3><p><b>Type d\'occurrence&nbsp;:</b> {{type}}</p><p>'
-    + '<b>Univers&nbsp;:</b> {{univers.title}}</p><p><b>Date&nbsp;:</b> {{formatted_date}}</p><p>{{description}}</p></li>{{/occurrences}}';
+Tlns.Templates.Occurrence_List = '{{#occurrences}}<li class="Ls-Occurrence"><div class="Ls-OccIcon Tl-Occ{{type}} Tl-Occ{{status}}"></div><div class="Ls-Occurrence-Title">{{title}}</div><div class="Tl-Tooltip-Date">{{formatted_date}}</div><div style="clear:both;"></div></li>{{/occurrences}}';
 
-Tlns.Templates.OccurrenceTooltip = '<h3 class="Tl-Tooltip-Title">{{title}}</h3><p class="Tl-Tooltip-Date">{{formatted_date}}</p>'
+Tlns.Templates.OccurrenceTooltip = '<h3 class="Tl-Tooltip-Title">{{title}}</h3><p class="Tl-Tooltip-Date">{{formatted_date}} - {{translated_status}}</p>'
     + '<p class="Tl-Tooltip-Description">{{description}}</p><p class="Tl-Tooltip-Characters">{{univers.mainCharacter}}{{#characters}}, {{.}}{{/characters}}</p>'
 
 /* Classes */
@@ -196,14 +249,12 @@
     Tlns.Utils.SetDefaults(this, Tlns.Defaults.Timeline, _options);
 
     /* Setting container CSS */
-    this.$ = $('#' + this.container);
-    this.$.addClass('Tl-Main');
-    this.$.css({
+    this.$ = $('#' + this.container).html(Mustache.to_html(Tlns.Templates.Timeline, this));
+    
+    this.$.find('.Tl-Main').css({
         width : this.width + "px",
         height : this.height + "px"
     });
-    this.$.html(Mustache.to_html(Tlns.Templates.Timeline, this));
-    
     this.main_height = this.height - this.$.find('.Tl-TopBar').outerHeight();
     this.$.find('.Tl-BottomPart').css("height", this.main_height + "px");
     this.$.find('.Tl-MainPart').css("width", this.main_width + "px");
@@ -226,6 +277,10 @@
         _this.drawGrid();
     }, 150);
     
+    this.throttledDrawList = _.throttle(function() {
+        _this.drawList();
+    }, 150);
+    
     this.setLevel(this.level);
     
     this.$.find('.Tl-TopBar-Timescales>div').click(function() {
@@ -296,7 +351,8 @@
                     date: _d,
                     titre: '<Nouvelle occurrence>',
                     univers: _this.univers[_u].id,
-                    publie: true
+                    publie: true,
+                    statut: 'a_realiser'
                 }
             );
         _occ.just_created = true;
@@ -318,14 +374,43 @@
         _this.onUniversLoaded(_data);
     });
     
-    
+    /* LIST */
     
-    /* LIST */
-
-    $("body").append(Mustache.to_html(Tlns.Templates.List, this));
-    
-    $(".Ls-Main input").bind("click change keyup", function() {
+    $("li.Ls-Critere").click(function() {
+        $(this).toggleClass("Ls-Active");
+        _this.throttledDrawList();
+    });
+    $(".Ls-Search").bind("keyup change click", function() {
+        _this.throttledDrawList();
+    });
+    $(".Ls-From-Date, .Ls-To-Date").datepicker(
+        {
+            dateFormat: "dd/mm/yy",
+            dayNames: [ "Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi" ],
+            dayNamesShort: [ "Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam" ],
+            dayNamesMin: [ "D", "L", "Ma", "Me", "J", "V", "S" ],
+            monthNames:  [ "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre" ],
+            monthNamesShort: [ "Jan", "Fév", "Mar", "Avr", "Mai", "Jun", "Jul", "Aoû", "Sep", "Oct", "Nov", "Déc" ],
+            showOtherMonths: true,
+            selectOtherMonths: true
+        }
+    ).change(function() {
+        var _val = $(this).val();
+        if (_val) {
+            $(this).val(Tlns.Utils.dateFieldProcess( _val ).text);
+        }
         _this.drawList();
+    }).bind("keyup", function() {
+        _this.throttledDrawList();
+    });
+    $(".Ls-From-Time, .Ls-To-Time").change(function() {
+        var _val = $(this).val();
+        if (_val) {
+            $(this).val(Tlns.Utils.timeFieldProcess( _val ).text);
+        }
+        _this.throttledDrawList();
+    }).bind("keyup", function() {
+        _this.throttledDrawList();
     });
     
 }
@@ -429,8 +514,9 @@
     
     $(".Ls-Univers").html(Mustache.to_html(Tlns.Templates.Univers_List, this));
     var _this = this;
-    $(".Ls-Univers input").bind("click change keyup", function() {
-        _this.drawList();
+    $(".Ls-Univers li.Ls-Critere").click( function() {
+        $(this).toggleClass("Ls-Active");
+        _this.throttledDrawList();
     });
     this.loadOccurrences();
 }
@@ -442,7 +528,7 @@
 Tlns.Classes.Timeline.prototype.setTime = function(_centralTime) {
     this.sync_now = false;
     this.central_time = _centralTime;
-    this.throttledDrawGrid();
+    this.changeSpan();
 }
 
 Tlns.Classes.Timeline.prototype.setLevel = function(_level) {
@@ -456,11 +542,11 @@
             }
         });
         this.level = _level;
-        this.throttledDrawGrid();
+        this.changeSpan();
     }
 }
 
-Tlns.Classes.Timeline.prototype.drawGrid = function() {
+Tlns.Classes.Timeline.prototype.changeSpan = function() {
     var _now = new Date().valueOf();
     if (this.sync_now) {
         this.central_time = _now;
@@ -468,12 +554,23 @@
     } else {
         this.$.find('.Tl-TopBar-SyncButton').removeClass("active");
     }
-    var _timescale = this.timescales[this.level],
-        _offset = new Date().getTimezoneOffset() * 60000;
-    this.current_scale = this.main_width / (_timescale.span)
+    var _timescale = this.timescales[this.level];
+    this.current_scale = this.main_width / (_timescale.span);
     this.start_time = this.central_time - (_timescale.span / 2);
     this.end_time = this.central_time + (_timescale.span / 2);
-    var _grid_width = Math.floor(_timescale.grid_interval * this.current_scale),
+    $(".Ls-From-Time").val(Tlns.Utils.dateFormat(this.start_time, '{{0hours}}:{{0minutes}}'));
+    $(".Ls-From-Date").val(Tlns.Utils.dateFormat(this.start_time, '{{0dayOfMonth}}/{{0monthNumber}}/{{year}}'));
+    $(".Ls-To-Time").val(Tlns.Utils.dateFormat(this.end_time, '{{0hours}}:{{0minutes}}'));
+    $(".Ls-To-Date").val(Tlns.Utils.dateFormat(this.end_time, '{{0dayOfMonth}}/{{0monthNumber}}/{{year}}'));
+    this.throttledDrawGrid();
+    this.throttledDrawList();
+}
+
+Tlns.Classes.Timeline.prototype.drawGrid = function() {
+    var _now = new Date().valueOf(),
+        _timescale = this.timescales[this.level],
+        _offset = new Date().getTimezoneOffset() * 60000,
+        _grid_width = Math.floor(_timescale.grid_interval * this.current_scale),
         _roundstart = Math.floor((this.start_time - _offset) / _timescale.grid_interval) * _timescale.grid_interval + _offset,
         _html = '';
     this.$.find('.Tl-TopBar-TimeSpan').html(Tlns.Utils.dateFormat(this.start_time, _timescale.start_date_format) + ' - ' + Tlns.Utils.dateFormat(this.end_time, _timescale.end_date_format));
@@ -514,7 +611,7 @@
     if (!this.mouse_down) {
         this.drawOccurrences();
     }
-    this.drawList();
+    this.throttledDrawList();
 }
 
 Tlns.Classes.Timeline.prototype.deleteOccurrence = function(_id) {
@@ -614,19 +711,12 @@
         _cluster.occurrences = _(_cluster.occurrences).sortBy(function(_o) {
             return _o.date;
         });
-        _cluster.type = _cluster.occurrences[0].type;
         _cluster.contents = _cluster.occurrences.map(function(_o) {
             return _o.type + ":" + _o.id;
         }).join("|");
         if (_cluster.contents == _this.open_cluster) {
             _openCluster = _cluster;
         }
-        for (var _i = 1; _i < _cluster.occurrences.length; _i++) {
-            if (_cluster.occurrences[_i].type !== _cluster.type) {
-                _cluster.type = "both";
-                break;
-            }
-        }
     });
     
     
@@ -680,7 +770,7 @@
             _id = _el.attr("occurrence-id");
         if (typeof _id !== "undefined") {
             _this.editing_occurrence = _this.getOccurrence(_id);
-            if (typeof _this.dragging_type === "undefined" && typeof _this.editing_occurrence !== "undefined" && !_this.editing_occurrence.locked) {
+            if (typeof _this.dragging_type === "undefined" && typeof _this.editing_occurrence !== "undefined" /* && !_this.editing_occurrence.locked */ ) {
                 _this.dragging_type = "occurrence";
                 _this.editing_occurrence.editing = true;
             }
@@ -690,9 +780,9 @@
             _id = _el.attr("occurrence-id");
         if (typeof _id !== "undefined") {
             var _occurrence = _this.getOccurrence(_id);
-            if (!_occurrence.locked) {
-                _el.find('.Tl-Link').show();
-            }
+//            if (!_occurrence.locked) {
+            _el.find('.Tl-Link').show();
+//            }
             if (!_this.is_dragging) {
                 var _html = Mustache.to_html(Tlns.Templates.OccurrenceTooltip, _occurrence);
                 _this.showTooltip(_occurrence.x, _occurrence.y, _html, (_event.pageY - _this.dragging_bounds.top) >= (.4 * _this.main_height) );
@@ -719,7 +809,7 @@
         var _el = $(this).parent(),
             _id = _el.attr("occurrence-id");
         _this.editing_occurrence = _this.getOccurrence(_id);
-        if (typeof _this.editing_occurrence !== "undefined" && !_this.editing_occurrence.locked) {
+        if (typeof _this.editing_occurrence !== "undefined" /* && !_this.editing_occurrence.locked */ ) {
             _this.dragging_type = "link";
             _this.editing_occurrence.editing = true;
         }
@@ -738,10 +828,25 @@
 }
 
 Tlns.Classes.Timeline.prototype.drawList = function() {
-    var _universfilter = $(".Ls-Univers input:checked").map(function(){return this.value}),
-        _occtypefilter = $(".Ls-Occtypes input:checked").map(function(){return this.value}),
-        _title = $(".Ls-Search").val(),
-        _titleregexp = new RegExp( "(" + _title.replace(/(\W)/gm, "\\$1") + ")", "gim" );
+    var _universfilter = $(".Ls-Univers li.Ls-Active").map(function(){return $(this).attr("data")}),
+        _occtypefilter = $(".Ls-Occtypes li.Ls-Active").map(function(){return $(this).attr("data")}),
+        _statusfilter = $(".Ls-Occstatuses li.Ls-Active").map(function(){return $(this).attr("data")}),
+        _title = $(".Ls-Search").val() || "",
+        _titleregexp = new RegExp( "(" + _title.replace(/(\W)/gm, "\\$1") + ")", "gim" ),
+        _startdate = false,
+        _enddate = false,
+        _fromDate = $(".Ls-From-Date").val(),
+        _toDate = $(".Ls-To-Date").val();
+    if (_fromDate) {
+        var _date = Tlns.Utils.dateFieldProcess(_fromDate),
+            _time = Tlns.Utils.timeFieldProcess($(".Ls-From-Time").val());
+        _startdate = new Date(_date.year, _date.month - 1, _date.date, _time.hours, _time.minutes);
+    }
+    if (_toDate) {
+        var _date = Tlns.Utils.dateFieldProcess(_toDate),
+            _time = Tlns.Utils.timeFieldProcess($(".Ls-To-Time").val());
+        _enddate = new Date(_date.year, _date.month - 1, _date.date, _time.hours, _time.minutes);
+    }
     $(".Ls-Occurrences").html(
         Mustache.to_html(
             Tlns.Templates.Occurrence_List,
@@ -749,9 +854,12 @@
                 occurrences: this.occurrences.filter(function(_occ) {
                     var _titletest = (!!_occ.title.match(_titleregexp)),
                         _keep = (
-                            ( !_title || _titletest )
+                               ( !_title || _titletest )
                             && (_(_occtypefilter).indexOf(_occ.type) !== -1)
                             && (_(_universfilter).indexOf(_occ.univers_id) !== -1)
+                            && (_(_statusfilter).indexOf(_occ.status) !== -1)
+                            && ( !_fromDate || _occ.date >= _startdate )
+                            && ( !_toDate || _occ.date <= _enddate )
                         );
                     return _keep;
                 })
@@ -759,7 +867,7 @@
         )
     );
     if (_title) {
-        $(".Ls-Occurrences h3").each(function() {
+        $(".Ls-Occurrence-Title").each(function() {
             $(this).html($(this).text().replace(_titleregexp, "<span style='background:yellow'>$1</span>"));
         });
     }
@@ -815,8 +923,9 @@
     this.univers_id = _data.univers;
     this.univers = this.timeline.getUnivers(this.univers_id);
     this.status = _data.statut;
+    this.translated_status = Tlns.Defaults.Timeline.statuses[this.status];
     this.published = _data.publie || false;
-    this.locked = _data.verrouille || false;
+//    this.locked = _data.verrouille || false;
     this.characters = _data.personnagesSecondaires || [];
     this.dependsOn = _(_data.dependDe || []).map(function(_id) {
         return "narrative_" + _id;