diff --git a/src/Lib/Ass/Line.cc b/src/Lib/Ass/Line.cc
index 18d2a9830fe44fc0fdd674e8675359493de1e303..652c3d64d651ecba8c5cf0804f170c1fb6570ee0 100644
--- a/src/Lib/Ass/Line.cc
+++ b/src/Lib/Ass/Line.cc
@@ -59,6 +59,12 @@ Line::Line(AssFactory *const factory, const QString &lineString)
     initSylFromString(___contentAsText);
 }
 
+void
+Line::generateLineText() noexcept
+{
+    // TODO : generate ___contentAsText from content
+}
+
 void
 Line::initSylFromString(const QString &line) noexcept
 {
@@ -163,4 +169,5 @@ void
 Line::setContent(const QVector<Syl> &syls) noexcept
 {
     content = syls;
+    generateLineText();
 }
diff --git a/src/Lib/Ass/Line.hh b/src/Lib/Ass/Line.hh
index 3ec42714b4a691feccfea06e92cc833bff445b08..8462b532979458df7ac337c7e5c298ad9c55b453 100644
--- a/src/Lib/Ass/Line.hh
+++ b/src/Lib/Ass/Line.hh
@@ -29,7 +29,7 @@ class Line final {
     AssFactory *const assFactory;
 
 public:
-    explicit Line(const Line &) = default;
+    //explicit Line(const Line &) = default;
     explicit Line(AssFactory *const, const QString &);
     Line &operator=(const Line &) = delete;
 
@@ -53,5 +53,6 @@ public:
 
 private:
     void initSylFromString(const QString &) noexcept;
+    void generateLineText() noexcept;
 };
 }
diff --git a/src/UI/DocumentViews/AssLinesModel.cc b/src/UI/DocumentViews/AssLinesModel.cc
index c02396a50156529b246b2c7126e18424ab52dadd..47c1febe4ae537ea711aeeae2cfbaa81b4d6a92b 100644
--- a/src/UI/DocumentViews/AssLinesModel.cc
+++ b/src/UI/DocumentViews/AssLinesModel.cc
@@ -20,6 +20,9 @@ AssLinesModel::Item::getLineText() const noexcept
     if (auto ptr = line.lock()) {
         for (const auto &syl : ptr->getContent()) {
             ret.append(syl.getContent());
+            ret.append("(");
+            ret.append(QString::number(syl.getDuration()));
+            ret.append(")");
             ret.append("|");
         }
     }
@@ -46,6 +49,12 @@ AssLinesModel::Item::getLineStyle() const noexcept
     return "";
 }
 
+void
+AssLinesModel::Item::setLine(Ass::LineWeakPtr l) noexcept
+{
+    line = l;
+}
+
 AssLinesModel::AssLinesModel(const QVector<Ass::LinePtr> &lines) noexcept
     : lineRealData(lines)
 {
@@ -142,3 +151,12 @@ AssLinesModel::flags(const QModelIndex &index) const noexcept
     [[maybe_unused]] const Item *item = static_cast<const Item *>(index.internalPointer());
     return Qt::ItemNeverHasChildren | Qt::ItemIsSelectable | QAbstractItemModel::flags(index);
 }
+
+void
+AssLinesModel::updateLine(int lineIndex, Ass::LinePtr line)
+{
+    qDebug() << data(index(lineIndex, 0), Qt::DisplayRole);
+    childs[lineIndex]->setLine(line);
+    qDebug() << data(index(lineIndex, 0), Qt::DisplayRole);
+    qDebug() << "";
+}
diff --git a/src/UI/DocumentViews/AssLinesModel.hh b/src/UI/DocumentViews/AssLinesModel.hh
index 60cc550b4cbdcbbf56b921187f8a671d42bf844c..ad45d4bd5f7cac276492500d4db8203d66c0d8e5 100644
--- a/src/UI/DocumentViews/AssLinesModel.hh
+++ b/src/UI/DocumentViews/AssLinesModel.hh
@@ -27,6 +27,8 @@ private:
         QString getLineText() const noexcept;
         QString getLineStyle() const noexcept;
 
+        void setLine(Ass::LineWeakPtr) noexcept;
+
     private:
         Ass::LineWeakPtr line;
     };
@@ -52,5 +54,8 @@ public:
 private:
     QVector<Item *> childs;
     const QVector<Ass::LinePtr> &lineRealData;
+
+public slots:
+    void updateLine(int, Ass::LinePtr);
 };
 }
diff --git a/src/UI/DocumentViews/AudioVisualizer/TimingLine.cc b/src/UI/DocumentViews/AudioVisualizer/TimingLine.cc
index 29cd6c3067ff4fe9b9b279a129c489318878fcc2..752b8d403f680dceb9d1a10b3c5a32edf704a856 100644
--- a/src/UI/DocumentViews/AudioVisualizer/TimingLine.cc
+++ b/src/UI/DocumentViews/AudioVisualizer/TimingLine.cc
@@ -12,9 +12,10 @@ using namespace Vivy;
     connect(sep, &TimingSeparator::enterPress, this, &TimingLine::sepEnterPress);                  \
     connect(sep, &TimingSeparator::exitPress, this, &TimingLine::sepExitPress);
 
-TimingLine::TimingLine(Ass::Line *lineptr, QGraphicsItem *parent)
+TimingLine::TimingLine(Ass::Line *lineptr, int index, QGraphicsItem *parent)
     : QGraphicsObject(parent)
     , line(*lineptr)
+      , lineIndex(index)
 {
     setPos(TimingUtils::posFromMs(int(line.getStart()) * 10), TimingUtils::axisHeight());
     int currentTime = 0;
@@ -164,5 +165,9 @@ TimingLine::requestMove(int sepIndex, qreal x)
 
     line.setContent(syls);
 
+    if (given){
+        emit lineChanged(lineIndex, std::make_shared<Ass::Line>(line));
+    }
+
     return given;
 }
diff --git a/src/UI/DocumentViews/AudioVisualizer/TimingLine.hh b/src/UI/DocumentViews/AudioVisualizer/TimingLine.hh
index 18e68323d02abbf8766fc2c9618098c049a9f1f5..cda92bd848bc2bf234f4e7cd38039f1aeb66ae3a 100644
--- a/src/UI/DocumentViews/AudioVisualizer/TimingLine.hh
+++ b/src/UI/DocumentViews/AudioVisualizer/TimingLine.hh
@@ -11,7 +11,7 @@ namespace Vivy
 class TimingLine final : public QGraphicsObject {
     Q_OBJECT
 public:
-    explicit TimingLine(Ass::Line *, QGraphicsItem * = nullptr);
+    explicit TimingLine(Ass::Line *, int, QGraphicsItem * = nullptr);
 
     QRectF boundingRect() const override;
     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
@@ -20,12 +20,16 @@ private:
     Ass::Line line;
     QVector<TimingSeparator *> seps;
     QVector<TimingSyl *> timingSyls;
+    int lineIndex;
 
     qreal tempOffset{ 0 };
 
 public:
     qreal requestMove(int, qreal);
 
+signals:
+    void lineChanged(int, Ass::LinePtr);
+
 public slots:
     void timingSeparatorHasChanged(int, qreal);
     void sepEnterPress(int);
diff --git a/src/UI/DocumentViews/AudioVisualizer/TimingScene.cc b/src/UI/DocumentViews/AudioVisualizer/TimingScene.cc
index f602b328a5dd7be8486556047a9c3b838bfdc317..e1ddba5ee0c52e6a5d438f6eaa05fac4cc5da80c 100644
--- a/src/UI/DocumentViews/AudioVisualizer/TimingScene.cc
+++ b/src/UI/DocumentViews/AudioVisualizer/TimingScene.cc
@@ -90,11 +90,15 @@ TimingScene::rebuildScene()
         QVector<Ass::LinePtr> lines = assDocument->getLines();
         for (int i = 0; i < lines.size(); ++i) {
             if (auto line = lines.at(i).get()) {
-                TimingLine *l = new TimingLine(line);
+                TimingLine *l = new TimingLine(line, i);
                 l->setVisible(false);
                 addItem(l);
                 timingLines.append(l);
-                // TODO: Here connect timingLine.linechanged to lineassmodel or something
+                if (auto p = rootView.lock()) {
+                    if (auto assLinesModel = p->getAssLinesModel()) {
+                        connect(l, &TimingLine::lineChanged, assLinesModel, &AssLinesModel::updateLine);
+                    }
+                }
             }
         }
     }
diff --git a/src/UI/VivyDocumentView.hh b/src/UI/VivyDocumentView.hh
index ea6b8bfd75d326a039fece5e79055253bf802309..72a3c025ddc7eb2e3e28f655bf4bf1d4dab1064a 100644
--- a/src/UI/VivyDocumentView.hh
+++ b/src/UI/VivyDocumentView.hh
@@ -63,5 +63,10 @@ public:
     {
         return assLines == nullptr ? nullptr : reinterpret_cast<AssLinesView *>(assLines->widget());
     }
+
+    AssLinesModel *getAssLinesModel() const noexcept
+    {
+        return assModel.get();
+    }
 };
 }