diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 086cf75cc1df9cba18b19bc81c41cf870f91cd64..be4ab2aad2aa98226b7bb446c2916d5a120efa02 100755
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -59,7 +59,7 @@ endif (APPLE)
 
 # add_subdirectory( libs/scorek )
 add_subdirectory( libs/core )     # libNootkaCore
-# add_subdirectory( libs/score )    # libNootkaScore
+add_subdirectory( libs/score )    # libNootkaScore
 # add_subdirectory( libs/widgets )  # libNootkaWidgets
 # add_subdirectory( libs/sound )    # libNootkaSound
 # add_subdirectory( libs/misc )     # libNootkaMisc
@@ -88,6 +88,7 @@ qt5_add_resources(NOOTKA_SRC nootka.qrc)
 add_executable(nootka WIN32 ${NOOTKA_SRC} ${NOOTKA_EXE_ICON})
 target_link_libraries(nootka
     NootkaCore
+    NootkaScore
     Qt5::Core
     Qt5::Widgets
     Qt5::Qml
diff --git a/src/libs/core/music/tmeter.cpp b/src/libs/core/music/tmeter.cpp
index c40b4bf346e8df6718e3e4813fd2a76c53114758..f96429e09424b9fee95f08f194551c5523c8b919 100644
--- a/src/libs/core/music/tmeter.cpp
+++ b/src/libs/core/music/tmeter.cpp
@@ -17,7 +17,7 @@
  ***************************************************************************/
 
 #include "tmeter.h"
-// #include "tnoofont.h"
+#include "tnoofont.h"
 #include "trhythm.h"
 #include <QtGui/qfontmetrics.h>
 #include <QtGui/qpainter.h>
@@ -69,20 +69,19 @@ QPixmap Tmeter::pixmap(int fontSize, const QColor& c) {
   if (meter() == e_none)
     return QPixmap();
 
-//   TnooFont font(fontSize);
-//   QFontMetrics fm(font);
-//   QString upperDigit = TnooFont::digit(upper());
-//   QPixmap pix(QSize(fm.boundingRect(upperDigit).width() + 4, fontSize + 12)); // upper digit is usually wider
-//   /*/*pix.fill(Qt::transparent);
-//   QPainter p(&pix);
-//   p.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing, true);
-//   p.setFont(font);
-//   p.setPen(c == -1 ? qApp->palette().text().color() : c);
-//   p.setBrush(Qt::NoBrush);
-//   p.drawText(QRect(0, 0, pix.width(), fontSize / 2 + 8), Qt::AlignCenter, upperDigit);
-//   p.drawText(QRect(0, fontSize / 2 - 1, pix.width(), fontSize / 2 + 8), Qt::AlignCenter, TnooFont::digit(lower()));*/*/
-//   return pix;
-  return QPixmap();
+  TnooFont font(fontSize);
+  QFontMetrics fm(font);
+  QString upperDigit = TnooFont::digit(upper());
+  QPixmap pix(QSize(fm.boundingRect(upperDigit).width() + 4, fontSize + 12)); // upper digit is usually wider
+  pix.fill(Qt::transparent);
+  QPainter p(&pix);
+  p.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing, true);
+  p.setFont(font);
+  p.setPen(c == -1 ? qApp->palette().text().color() : c);
+  p.setBrush(Qt::NoBrush);
+  p.drawText(QRect(0, 0, pix.width(), fontSize / 2 + 8), Qt::AlignCenter, upperDigit);
+  p.drawText(QRect(0, fontSize / 2 - 1, pix.width(), fontSize / 2 + 8), Qt::AlignCenter, TnooFont::digit(lower()));
+  return pix;
 }
 
 
diff --git a/src/libs/core/tinitcorelib.cpp b/src/libs/core/tinitcorelib.cpp
index 72347bf78c3e7dc035ee548ca4957b6863e56b45..2a9fdf2d22ff97f84d6d5b508516d55a4f6772b5 100644
--- a/src/libs/core/tinitcorelib.cpp
+++ b/src/libs/core/tinitcorelib.cpp
@@ -116,7 +116,8 @@ void prepareTranslations(QApplication* a, QTranslator& qt, QTranslator& noo) {
 bool loadNootkaFont(QApplication* a) {
     QFontDatabase fd;
   int fid = fd.addApplicationFont(Tpath::main + QLatin1String("fonts/nootka.ttf"));
-  if (fid == -1) {
+  int fid2 = fd.addApplicationFont(Tpath::main + QLatin1String("fonts/Scorek.otf"));
+  if (fid == -1 || fid2 == -1) {
       QMessageBox::critical(0, QString(), a->translate("main", "<center>Can not load a font.<br>Try to install nootka.ttf manually.</center>"));
       return false;
   }
diff --git a/src/libs/core/tnoofont.cpp b/src/libs/core/tnoofont.cpp
index bc3ca8b50f779c713e930e69400a9229c5a2f684..dbe961b2905156f6aa52905718c4ad27e359b4b1 100644
--- a/src/libs/core/tnoofont.cpp
+++ b/src/libs/core/tnoofont.cpp
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2014-2015 by Tomasz Bojczuk                             *
+ *   Copyright (C) 2014-2016 by Tomasz Bojczuk                             *
  *   seelook@gmail.com                                                     *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -16,18 +16,58 @@
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
  ***************************************************************************/
 
+/** Glyphs (some)
+ * Rests:
+ * 0xe102 - whole rest
+ * 0xe103 - half rest
+ * 0xe108 - quarter rest
+ * 0xe10A - eight rest
+ * 0xe10B - sixteen rest
+ *
+ * Flags
+ * 0xe21C - eight Up
+ * 0xe21D - sixteen Up
+ * 0xe221 - eight Down
+ * 0xe221 - sixteen Down
+ *
+ * Note heads:
+ * 0xe191 - whole (empty but big)
+ * 0xe192 - half (empty)
+ * 0xe193 - quarter and above (full)
+ * Note symbols (head, stem and flag)
+ * 0x0043 - 'C' - whole - head only
+ * 0x0044 - 'D' - half (stem up)
+ * ... and so on till
+ * 0x0047 - 'G' - sixteen
+ * stems down starts from
+ * 0x004A - 'J' - half - (stem down)
+ * ... till 0x004D - 'M' - sixteen
+ *
+ * Accidentals (all are centered in glyph height but those available by letters: B b # x are placed at a bottom)
+ * 0xe123 - double flat (also B)
+ * 0xe11a - flat (also b)
+ * 0xe10e - sharp (also #)
+ * 0xe125 - double sharp (also x)
+ * 0xe116
+ *
+ * digits [0-9] starts from 0x0180
+ */
 
 #include "tnoofont.h"
+#include <math.h>
+
 
 TnooFont::TnooFont(int pointSize) :
-	QFont("nootka", pointSize)
+  QFont(QStringLiteral("nootka"), pointSize)
 {
   setPixelSize(pointSize);
   setBold(false);
   setWeight(50); // Normal
 }
 
-
+//#################################################################################################
+//###################              STATIC              ############################################
+//#################################################################################################
 QString TnooFont::tag(const QString& tag, const QString& text, int fontSize, const QString& extraStyle) {
   QString fSize;
   if (fontSize)
@@ -40,3 +80,20 @@ QString TnooFont::tag(const QString& tag, const QString& text, int fontSize, con
 }
 
 
+quint16 TnooFont::getCharFromRhythm(quint16 rhythm, bool stemUp, bool rest) {
+  int baseChar = 67, stemGap = 0;
+  if (rest)
+      baseChar = 0xe107;
+  else if (!stemUp && rhythm > 1) // stem down only if no rest and half note at least
+      stemGap = 6;
+  if (rhythm)
+    return baseChar + (int)std::log2(rhythm) + stemGap;
+  else
+    return 0xe193;
+}
+
+
+
+
+
+
diff --git a/src/libs/core/tnoofont.h b/src/libs/core/tnoofont.h
index 567c0f54d1e5bdbd2468828eac87eb1fcbb11792..d2bf3eed8f121b9aa3b6ff4d3ebca3806ef49fde 100644
--- a/src/libs/core/tnoofont.h
+++ b/src/libs/core/tnoofont.h
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2014 by Tomasz Bojczuk                                  *
+ *   Copyright (C) 2014-2016 by Tomasz Bojczuk                             *
  *   seelook@gmail.com                                                     *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -44,10 +44,20 @@ public:
       /** tag() method with span tag */
   static QString span(const QString& text, int fontSize = 0, const QString& extraStyle = QString()) {
                   return  tag("span", text, fontSize, extraStyle); }
-	
-      /** Overloaded method with current font size */
-// 	QString span(const QString& text, const QString& extraStyle = "") { return span(text, pointSize(), extraStyle); }
 
+      /** Bare digits starts from UNI-0x180 in nootka.ttf
+       * due to glyphs of ordinary numbers are used for strings (circled).
+       * This method returns proper string of given digit
+       */
+  static QString digit(quint8 d) { return (d / 10 ? QString(QChar(0x0180 + d / 10)) : QString()) + QString(QChar(0x0180 + d % 10)); }
+
+      /** Converts rhythm value (0, 1, 2, 4 - 16) into uni-code char number in Nootka font
+       * 0 (no rhythm returns full note head symbol)
+       * set @p stemUp to false to get symbols with stem down.
+       * Returned characters are optimized for score (staff lines height),
+       * to get just note symbol use 'n' and 'N' (stem down) instead
+       */
+  static quint16 getCharFromRhythm(quint16 rhythm, bool stemUp = true, bool rest = false);
 
 };
 
diff --git a/src/libs/score/CMakeLists.txt b/src/libs/score/CMakeLists.txt
index d99e28c3a8091c37684f123c30e75825a1091653..8325c354fd2a0fe257aaef4d65af45e454799a27 100644
--- a/src/libs/score/CMakeLists.txt
+++ b/src/libs/score/CMakeLists.txt
@@ -7,34 +7,42 @@ include_directories( . ../core )
 add_definitions(-DNOOTKACORE_LIBRARY)
 
 set(LIB_NOOTKASCORE_SRC
-	graphics/tnotepixmap.cpp
-
-	widgets/tselectclef.cpp
-
-	tscoreitem.cpp
-	tscoreclef.cpp
-	tscorekeysignature.cpp
-	tscorenote.cpp
-	tscorescene.cpp
-	tscorescordature.cpp
-	tscorestaff.cpp
-	tscore5lines.cpp
-	tnotecontrol.cpp
-  tpaneitem.cpp
-	tscorelines.cpp
-	tsimplescore.cpp
-	tmultiscore.cpp
+#   tscoreplugin.cpp
+#   graphics/tnotepixmap.cpp
+
+  declarative/descore.cpp
+  declarative/denote.cpp
+
+  tscoreitem.cpp
+  tscoreclef.cpp
+  tscorekeysignature.cpp
+  tscorenote.cpp
+  tnoteitem.cpp
+  tscorescene.cpp
+  tscorescordature.cpp
+  tscorestaff.cpp
+  tscoremeasure.cpp
+  tscorebeam.cpp
+  tscoretie.cpp
+  tscore5lines.cpp
+  tscorelines.cpp
+  tscoremeter.cpp
 )
 
+
+# qt5_add_resources(LIB_NOOTKASCORE_SRC score.qrc)
+
+
 add_library(NootkaScore SHARED ${LIB_NOOTKASCORE_SRC} )
 target_link_libraries(NootkaScore NootkaCore Qt5::Widgets)
 
-if(UNIX AND NOT APPLE) 	# Linux path for Nootka library
+
+if(UNIX AND NOT APPLE)   # Linux path for Nootka library
   install(TARGETS NootkaScore DESTINATION lib/nootka)
 else(UNIX AND NOT APPLE)
-  if(WIN32) 			# Windows
+  if(WIN32)       # Windows
     install(TARGETS NootkaScore DESTINATION .)
-  else(WIN32) 			# MacOs
+  else(WIN32)       # MacOs
     install(TARGETS NootkaScore DESTINATION "${CMAKE_INSTALL_PREFIX}/nootka.app/Contents/Frameworks")
   endif(WIN32)
 endif(UNIX AND NOT APPLE)
diff --git a/src/libs/score/tnoteitem.cpp b/src/libs/score/tnoteitem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8a1789ef017ba8a26f1916c556913278d8e1d0c9
--- /dev/null
+++ b/src/libs/score/tnoteitem.cpp
@@ -0,0 +1,167 @@
+/***************************************************************************
+ *   Copyright (C) 2016 by Tomasz Bojczuk                                  *
+ *   seelook@gmail.com                                                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 3 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+
+#include "tnoteitem.h"
+#include <music/trhythm.h>
+#include <QtWidgets/qapplication.h>
+#include <QtGui/qpalette.h>
+#include <QtGui/qpainter.h>
+
+#include <QtCore/qdebug.h>
+
+
+#define DOT (0xe1e7)
+#define WHOLE_REST (0xe4e2)
+#define BASE_HEAD (0xe0a1)
+
+#define STEM_HEIGHT (5.8)
+#define HALF_STEM (0.1)
+#define HEAD_WIDTH (2.35938) // width of black note head glyph for default font size of 6
+#define FONT_SIZE (6)
+
+#define STEM_DOWN_Y (1.2)
+#define STEM_UP_Y (0.79)
+#define MID_LINE (20.0)
+#define FLAG_GLYPH (0xe238)
+
+
+TnoteItem::TnoteItem(TscoreScene* scene, const Trhythm& r) :
+  TscoreItem(scene)
+{
+  m_rhythm = new Trhythm(r);
+  m_stem = new QGraphicsLineItem(this);
+  m_stem->hide();
+  m_flag = new QGraphicsSimpleTextItem(this);
+  m_flag->setFont(QFont(QStringLiteral("Scorek"), 5));
+  m_flag->hide();
+  setColor(qApp->palette().text().color());
+  setAcceptHoverEvents(false);
+}
+
+
+TnoteItem::~TnoteItem()
+{
+  delete m_rhythm;
+}
+
+
+void TnoteItem::setItAsCursor() {
+  delete m_flag;
+  m_flag = nullptr;
+  delete m_stem;
+  m_stem = nullptr;
+}
+
+
+/**
+ * Except setting Y coordinate,
+ * this method takes care about stem length when note is much above or below staff.
+ * Stem is prolonged until middle staff line (as professional scores have)
+ *
+ * TODO: WHAT ABOUT PIANO STAFF WHERE ARE TWO MIDDLE LINES
+ */
+void TnoteItem::setY(qreal yPos) {
+  QGraphicsItem::setY(yPos);
+  if (m_stem) {
+    if (m_stem->isVisible()) {
+      if (m_rhythm->stemDown())
+        m_stem->setLine(HALF_STEM, STEM_DOWN_Y, HALF_STEM, qMax(STEM_HEIGHT + STEM_DOWN_Y, MID_LINE - yPos));
+      else
+        m_stem->setLine(HEAD_WIDTH - HALF_STEM, STEM_UP_Y, HEAD_WIDTH - HALF_STEM,
+                qMin(-(STEM_HEIGHT + (m_rhythm->rhythm() > Trhythm::e_quarter && m_rhythm->hasDot() ? 1.0 : 0.0) - STEM_UP_Y), MID_LINE - yPos));
+    }
+    if (m_flag->isVisible()) {
+      if (m_rhythm->stemDown())
+        m_flag->setPos(HALF_STEM, m_stem->line().length() - STEM_DOWN_Y - 12.5);
+      else
+        m_flag->setPos(HEAD_WIDTH, STEM_UP_Y - m_stem->line().length() - 15.0);
+    }
+  }
+}
+
+
+/**
+ * It occurs only when stem is managed by @p TscoreBeam class, so there is no flag
+ * and no need to set flag position again
+ */
+void TnoteItem::setStemLength(qreal len) {
+  qreal y2 = m_stem->line().y1() + len;
+  if (m_rhythm->stemDown())
+    y2 = qMax(y2, MID_LINE - y());
+  else
+    y2 = qMin(y2, MID_LINE - y());
+  m_stem->setLine(m_stem->line().x1(), m_stem->line().y1(), m_stem->line().x2(), y2);
+}
+
+
+
+void TnoteItem::setColor(const QColor& c) {
+  m_color = c;
+  if (m_stem) {
+    m_stem->setPen(QPen(m_color, 2 * HALF_STEM));
+    m_flag->setBrush(m_color);
+  }
+}
+
+
+void TnoteItem::setRhythm(const Trhythm& r) {
+  if (r != *m_rhythm || r.stemDown() != m_rhythm->stemDown() || r.beam() != m_rhythm->beam()) {
+    *m_rhythm = r;
+    int v = BASE_HEAD + qMin(static_cast<int>(m_rhythm->rhythm()), 3);
+    if (m_stem) {
+      if (!m_rhythm->isRest() && m_rhythm->rhythm() > Trhythm::e_whole) {
+            m_stem->show();
+          if (m_rhythm->beam() == Trhythm::e_noBeam && m_rhythm->rhythm() > Trhythm::e_quarter) {
+              m_flag->setText(QString(QChar(FLAG_GLYPH + m_rhythm->rhythm() * 2 + (m_rhythm->stemDown() ? 1 : 0))));
+                m_flag->show();
+          } else
+              m_flag->hide();
+          setY(y()); // updates positions of stem and flag
+      } else {
+          m_stem->hide();
+          m_flag->hide();
+      }
+    }
+    if (m_rhythm->isRest())
+      v = WHOLE_REST + m_rhythm->rhythm();
+    m_noteLetter = QString(QChar(v));
+  }
+}
+
+
+void TnoteItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
+  Q_UNUSED(option)
+  Q_UNUSED(widget)
+
+//   paintBackground(painter, Qt::blue);
+  painter->setPen(m_color);
+
+  painter->setFont(QFont(QStringLiteral("Scorek"), FONT_SIZE));
+  painter->drawText(QPointF(0.0, 1.0), m_noteLetter);
+  if (m_rhythm->hasDot()) {
+    painter->drawText(QPointF(m_rhythm->rhythm() == Trhythm::e_whole ? 3.5 : 2.9, 1.0 - static_cast<qreal>(static_cast<int>(y()) % 2)),
+                      QString(QChar(DOT)));
+  }
+}
+
+
+QRectF TnoteItem::boundingRect() const {
+    return QRectF(0.0, -2.5, 3.0, 8.0); // it covers note heads and all rests
+}
+
+
diff --git a/src/libs/score/tnoteitem.h b/src/libs/score/tnoteitem.h
new file mode 100644
index 0000000000000000000000000000000000000000..9b4dfd03cd74ad672561bb7d74a59d23ec44bb11
--- /dev/null
+++ b/src/libs/score/tnoteitem.h
@@ -0,0 +1,78 @@
+/***************************************************************************
+ *   Copyright (C) 2016 by Tomasz Bojczuk                                  *
+ *   seelook@gmail.com                                                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 3 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+
+#ifndef TNOTEITEM_H
+#define TNOTEITEM_H
+
+
+#include <nootkacoreglobal.h>
+#include "tscoreitem.h"
+
+
+class Trhythm;
+
+
+/**
+ * Paints note head on the @class TscoreNote
+ * and rhythm when it is enabled.
+ * It paints steam and flag of whole and quarter notes
+ * but if rhythm has any beam,
+ * notes above quarter have hidden flags
+ *
+ * It can be just a cursor without stem and flag when @p setItAsCursor() is called
+ */
+class NOOTKACORE_EXPORT TnoteItem : public TscoreItem
+{
+
+public:
+  TnoteItem(TscoreScene* scene, const Trhythm& r);
+  virtual ~TnoteItem();
+
+  virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
+  virtual QRectF boundingRect() const;
+
+  void setColor(const QColor& c);
+  QColor color() { return m_color; }
+
+      /** In cursor mode there are no steam and flag - only note head or a rest */
+  void setItAsCursor();
+
+
+  void setRhythm(const Trhythm& r);
+  Trhythm* rhythm() const { return m_rhythm; } /**< Actual rhythm of a note */
+
+  QGraphicsLineItem* stem() { return m_stem; }
+
+      /** Sets stem length - adds @p len value to y1 of stem line */
+  void setStemLength(qreal len);
+
+      /** End point (p2) of stem line in parent note coordinates */
+  QPointF stemEndPoint() { return pos() + m_stem->line().p2(); }
+
+  void setY(qreal yPos);
+
+
+private:
+  QColor                       m_color;
+  Trhythm                     *m_rhythm; /**< This is pointer of @p Trhythm - Note head and flags are determined by it */
+  QString                      m_noteLetter; /**< single letter representing a note symbol in Nootka font */
+  QGraphicsLineItem           *m_stem;
+  QGraphicsSimpleTextItem     *m_flag;
+};
+
+#endif // TNOTEITEM_H
diff --git a/src/libs/score/tscorebeam.cpp b/src/libs/score/tscorebeam.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..acfb5c62951e90bc6f908ecddae702a966b93501
--- /dev/null
+++ b/src/libs/score/tscorebeam.cpp
@@ -0,0 +1,276 @@
+/***************************************************************************
+ *   Copyright (C) 2016 by Tomasz Bojczuk                                  *
+ *   seelook@gmail.com                                                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 3 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+
+#include "tscorebeam.h"
+#include "tscorenote.h"
+#include "tscorestaff.h"
+#include "tnoteitem.h"
+#include "tscoremeasure.h"
+#include <music/tnote.h>
+#include <QtWidgets/qgraphicsscene.h>
+#include <QtCore/qdebug.h>
+
+
+/**
+ * Simple structure to describe second beam line (sixteenth)
+ * which can be chunked when there are rests or eights in the group
+ */
+class T16beam {
+public:
+  T16beam(int firstStemNr = 0, QGraphicsPolygonItem* beamPoly = nullptr) : startStem(firstStemNr), b(beamPoly) {}
+  ~T16beam() { delete b; }
+  int startStem = -1; /**< Undefined by default */
+  int endStem = -1; /**< When remains undefined - beam is partial */
+
+      /** @p TRUE when beam is not connected to another stem */
+  bool isHalf() { return endStem == -1; }
+  QGraphicsPolygonItem* b = nullptr; /**< beam item */
+};
+
+
+#define MIN_STEM_HEIGHT (4) // minimal stem height (distance of note head to staff boundary)
+#define STEM_HEIGHT (5.8)
+#define SLOPER (1.5) // common value to change first and last stems length when there are more than two notes in a beam
+#define HALF_STEM (0.1) // half of stem line width - this is also distance that stem line takes above stem points
+#define BEAM_THICK (0.8) // thickness of a beam
+
+
+TscoreBeam::TscoreBeam(TscoreNote* sn, TscoreMeasure* m) :
+  QObject(m),
+  m_measure(m)
+{
+  sn->note()->rtm.setBeam(Trhythm::e_beamStart);
+  addNote(sn);
+  qDebug() << "     [BEAM] created for note id" << sn->index();
+}
+
+
+TscoreBeam::~TscoreBeam()
+{
+  qDebug() << "     [BEAM] deleted of id" << first()->index();
+  for (TscoreNote* note : m_notes) {
+    note->note()->rtm.setBeam(Trhythm::e_noBeam); // restore beams
+    note->setBeam(nullptr);
+  }
+  qDeleteAll(m_16_beams);
+  delete m_8_beam;
+}
+
+
+void TscoreBeam::addNote(TscoreNote* sn) {
+  if (m_notes.isEmpty() && sn->note()->rtm.beam() != Trhythm::e_beamStart) // TODO: delete it when no errors
+    qDebug() << "     [BEAM] new beam starts but not proper flag is set!";
+  else if (!m_notes.isEmpty() && last()->note()->rtm.beam() == Trhythm::e_beamEnd)
+    qDebug() << "     [BEAM] Adding note to beam group that already ended!";
+
+  if (m_notes.isEmpty())
+    m_summaryPos = 0;
+  m_summaryPos += sn->newNotePos();
+
+  m_notes << sn;
+  sn->setBeam(this);
+//   if (sn->newRhythm()->beam() == Trhythm::e_beamEnd)
+  connect(sn, &TscoreNote::noteWasClicked, this, &TscoreBeam::performBeaming);
+
+// 'main' beam of eights - always exists
+  if (sn->note()->rtm.beam() == Trhythm::e_beamStart) { // resume grouping, prepare for painting
+    m_8_beam = createBeam(sn);
+  }
+
+// beam of 16th - it may be chunked when rest or eight occurs
+  if (sn->note()->rhythm() == Trhythm::e_sixteenth) {
+    if (sn->note()->isRest()) {
+
+    } else {
+        if (m_16_beams.isEmpty() || m_notes.at(m_notes.count() - 2)->note()->rhythm() != Trhythm::e_sixteenth
+           || (m_notes.at(m_notes.count() - 2)->note()->rhythm() == Trhythm::e_sixteenth && m_notes.at(m_notes.count() - 2)->note()->isRest())) {
+        // is first in beam  or previous note was not a sixteenth or it was sixteenth but rest
+              m_16_beams << new T16beam(m_notes.count() - 1, createBeam(sn)); // then create new beam segment
+        } else if (!m_16_beams.isEmpty() && m_notes.at(m_notes.count() - 2)->note()->rhythm() == Trhythm::e_sixteenth
+                   && !m_notes.at(m_notes.count() - 2)->note()->isRest()) {
+        // there is 16 beam and previous note was 16th and not a rest
+              m_16_beams.last()->endStem = m_notes.count() - 1; // then set end stem for it
+        }
+    }
+  }
+
+}
+
+
+void TscoreBeam::closeBeam() {
+  last()->note()->rtm.setBeam(Trhythm::e_beamEnd);
+  connect(m_measure, &TscoreMeasure::updateBeams, this, &TscoreBeam::beamsUpdateSlot);
+
+  if (first()->note()->rtm.beam() == Trhythm::e_beamStart && last()->note()->rtm.beam() == Trhythm::e_beamEnd)
+    qDebug() << "     [BEAM] closed correctly with" << count() << "notes";
+  else
+    qDebug() << "     [BEAM] is corrupted!!!!";
+}
+
+//#################################################################################################
+//###################              PROTECTED           ############################################
+//#################################################################################################
+void TscoreBeam::beamsUpdateSlot(TscoreNote* sn) {
+  if (!sn || (sn->index() >= first()->index() && sn->index() <= last()->index()))
+    performBeaming();
+  else
+    qDebug() << "     [BEAM] ignored beaming of" << sn->index();
+}
+
+
+/**
+ * This method (slot) is invoked after TscoreNote is updated and placed apparently to the rhythm in measure (staff).
+ * TscoreNote::noteWasClicked() signal invokes it actually
+ *
+ * With @p stemDirStrength (strength of stem direction) we trying to determine preferred common direction of stems in the group.
+ * More far from middle of the staff (18) note is placed - stronger its direction has to be preserved
+ * to keep beaming more natural and looking good
+ * 
+ * @p stemsUpPossible keep true when there is enough space between note head and staff border for whole stem
+ * @p firstStemOff and @p lastStemOff are calculated to make appropriate stems longer
+ * and keep beam slope nice and avoid collisions with notes in between first and last ones.
+ *
+ * Then @p drawBeam() is called.
+ *
+ * TODO: WHAT ABOUT PIANO STAFF WHERE ARE TWO MIDDLE LINES
+*/
+void TscoreBeam::performBeaming() {
+// find common stem direction for beaming
+  int stemDirStrength = 0;
+  bool stemsUpPossible = true;
+  qint16 hiNote = 99, loNote = 0;
+  for (TscoreNote* sn : m_notes) {
+      stemDirStrength += sn->notePos() - 18;
+      if (sn->notePos() < MIN_STEM_HEIGHT)
+          stemsUpPossible = false;
+      hiNote = qMin(hiNote, sn->notePos());
+      loNote = qMax(loNote, sn->notePos());
+  }
+
+  if (last()->note()->rtm.beam() != Trhythm::e_beamEnd)
+      qDebug() << "     [BEAM] was not closed!!" << m_notes.size();
+
+  bool allStemsDown = !stemsUpPossible;
+  if (stemDirStrength < 0)
+    allStemsDown = true; // stems down are always possible
+
+  qreal firstStemOff = 0.0, lastStemOff = 0.0;
+  // pick up or pull down fist and/or last stems to keep beam above all notes and avoid collision of middle note(s) and beam
+  if (allStemsDown) {
+      firstStemOff = qMax(qreal(loNote - first()->notePos()) - SLOPER, 0.0);
+      lastStemOff = qMax(qreal(loNote - last()->notePos()) - SLOPER, 0.0);
+  } else {
+      firstStemOff = qMax(qreal(first()->notePos() - hiNote) - SLOPER, 0.0);
+      lastStemOff = qMax(qreal(last()->notePos() - hiNote) - SLOPER, 0.0);
+  }
+
+// initial setting stems directions and stem lines
+  for (int i = 0; i < count(); ++i) {
+    auto n = m_notes[i]; // cache pointer for multiple reuse
+    Trhythm r(n->note()->rtm);
+    r.setStemDown(allStemsDown);
+    n->setRhythm(r);
+    // set only first and last stems - the inner ones later - adjusted to leading beam line
+    if (n == last() || n == first()) {
+      if (n->note()->rtm.stemDown())
+        n->mainNote()->setStemLength((n->notePos() < n->staff()->height() - STEM_HEIGHT ? STEM_HEIGHT : 3.5)
+                                    + (n == first() ? firstStemOff : 0.0)
+                                    + (n == last() ? lastStemOff : 0.0));
+      else
+        n->mainNote()->setStemLength(-((n->notePos() < STEM_HEIGHT ? 3.5 : STEM_HEIGHT) - 0.85)
+                                    - (n == first() ? firstStemOff : 0.0)
+                                    - (n == last() ? lastStemOff : 0.0));
+    }
+  }
+
+  qDebug() << "     [BEAM" << first()->index() << "]" << "beaming was done" << stemDirStrength << m_16_beams.count();
+
+  drawBeam();
+}
+
+/**
+ * @p beamLine is calculated as a base line, inner stems fitted to it.
+ * If there are some sixteenths - @p m_16_beams are painted
+ */
+void TscoreBeam::drawBeam() {
+  QPointF stemOff(0.0, last()->note()->rtm.stemDown() ? HALF_STEM : -HALF_STEM); // offset to cover stem line thickness
+  QLineF beamLine(first()->pos() + first()->mainNote()->stemEndPoint() + stemOff, last()->pos() + last()->mainNote()->stemEndPoint() + stemOff);
+// adjust stem lines length to leading beam line for notes in between of the beam group
+  for (int i = 1; i < m_notes.count() - 1; ++i) {
+      QPointF stemEnd;
+      auto s = m_notes[i]->stem();
+      auto nPos = m_notes[i]->pos() + m_notes[i]->mainNote()->pos();
+      beamLine.intersect(QLineF(nPos + s->line().p1(), nPos + s->line().p2()), &stemEnd);
+      s->setLine(QLineF(s->line().p1(), stemEnd - nPos - 2 * stemOff));
+  }
+  QPolygonF poly;
+  poly << beamLine.p1() << beamLine.p2();
+      /** @p beamOff the lower point on a stem for bottom beam outline (it depends on beam line angel) */
+  QPointF beamOff(0.0, (last()->note()->rtm.stemDown() ? -BEAM_THICK : BEAM_THICK) / qCos(qDegreesToRadians(beamLine.angle())));
+  applyBeam(poly, beamOff, m_8_beam);
+
+  if (!m_16_beams.isEmpty()) {
+    QPointF beam16LineOff = beamOff * 1.5;
+    beamLine.translate(beam16LineOff);
+    for (T16beam* b16 : m_16_beams) {
+        poly.clear();
+        poly << m_notes[b16->startStem]->pos() + m_notes[b16->startStem]->mainNote()->stemEndPoint() + stemOff + beam16LineOff;
+        if (b16->isHalf()) { // 16th beam of fist stem is right-sided others are left-sided
+            QPointF halfPoint;
+            qreal halfX = poly.last().x() + BEAM_THICK * (b16->startStem == 0 ? 2 : -2);
+            // intersection point with fake stem line for chunked beam
+            beamLine.intersect(QLineF(halfX, poly.last().y(), halfX, poly.last().y() - 6.0), &halfPoint);
+            poly << halfPoint;
+        } else
+            poly << m_notes[b16->endStem]->pos() + m_notes[b16->endStem]->mainNote()->stemEndPoint()  + stemOff + beam16LineOff;
+        applyBeam(poly, beamOff, b16->b);
+    }
+  }
+  qDebug() << "     [BEAM" << first()->index() << "]" << "DRAW BEAM";
+}
+
+
+void TscoreBeam::changeStaff(TscoreStaff* st) {
+  for (T16beam* b16 : m_16_beams)
+    b16->b->setParentItem(st);
+  m_8_beam->setParentItem(st);
+}
+
+
+//#################################################################################################
+//###################              PRIVATE             ############################################
+//#################################################################################################
+
+void TscoreBeam::applyBeam(QPolygonF& poly, const QPointF& offset, QGraphicsPolygonItem* polyItem) {
+  poly << poly.last() + offset;
+  poly << poly.first() + offset;
+  poly << poly.first();
+  polyItem->setPolygon(poly);
+}
+
+
+QGraphicsPolygonItem* TscoreBeam::createBeam(TscoreNote* sn) {
+  QGraphicsPolygonItem* b = new QGraphicsPolygonItem(sn->staff());
+  b->setPen(Qt::NoPen);
+  b->setBrush(sn->mainNote()->color());
+  b->setZValue(55);
+  return b;
+}
+
+
+
diff --git a/src/libs/score/tscorebeam.h b/src/libs/score/tscorebeam.h
new file mode 100644
index 0000000000000000000000000000000000000000..784e9de7ed9b68e271e638bccbfe4daafcf11e48
--- /dev/null
+++ b/src/libs/score/tscorebeam.h
@@ -0,0 +1,105 @@
+/***************************************************************************
+ *   Copyright (C) 2016 by Tomasz Bojczuk                                  *
+ *   seelook@gmail.com                                                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 3 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+
+#ifndef TSCOREBEAM_H
+#define TSCOREBEAM_H
+
+
+#include <nootkacoreglobal.h>
+#include <QtCore/qobject.h>
+
+
+class TscoreNote;
+class QGraphicsLineItem;
+class QGraphicsPolygonItem;
+class TscoreMeasure;
+class TscoreStaff;
+class T16beam;
+
+
+/**
+ * This class manages displaying beams of note rhythmic groups
+ * also it paints stems of them
+ */
+class NOOTKACORE_EXPORT TscoreBeam : public QObject
+{
+
+  friend class TscoreMeasure;
+  friend class TscoreStaff;
+  friend class TscoreNote;
+
+  Q_OBJECT
+
+public:
+  explicit TscoreBeam(TscoreNote* sn, TscoreMeasure* m);
+  virtual ~TscoreBeam();
+
+      /** Adds @p TscoreNote to beam group.
+       * note has to have properly set beam state in TscoreNote::newRhythm()
+       * It changes stem direction of note(s) when necessary.
+       * It does not perform painting yet
+       */
+  void addNote(TscoreNote* sn);
+
+      /** Returns note @p id in beam group */
+  TscoreNote* note(int id) { return m_notes[id]; }
+
+      /** First note in the beam group */
+  TscoreNote* first() { return m_notes.first(); }
+
+      /** Last note in the beam group */
+  TscoreNote* last() { return m_notes.last(); }
+
+      /** Number of notes in the beam group */
+  int count() { return m_notes.count(); }
+  
+      /** Sets beam flag of the last note to 'beam end'  */
+  void closeBeam();
+
+protected:
+      /** calls @p performBeaming when note belongs to beam group */
+  void beamsUpdateSlot(TscoreNote* sn);
+  void performBeaming();
+  void drawBeam();
+
+      /**
+       * Because beams are parented with staff it is important
+       * to change their staff when measure is shifted between staves
+       */
+  void changeStaff(TscoreStaff* st);
+
+private:
+      /**
+       * Given polygon has to have two points (upper beam boundary line).
+       * This method adds bottom boundary, closes polygon
+       * and applying it into @c QGraphicsPolygonItem. 
+       */
+  void applyBeam(QPolygonF& poly, const QPointF& offset, QGraphicsPolygonItem* polyItem);
+
+      /** Initial routines of beam (polygon) - color of note, staff as the parent  */
+  QGraphicsPolygonItem* createBeam(TscoreNote* sn);
+
+private:
+  TscoreMeasure                    *m_measure;
+  QList<TscoreNote*>                m_notes;
+  QGraphicsPolygonItem             *m_8_beam; /**< line of main beam of eight */
+  QList<T16beam*>                   m_16_beams; /**< list of lines of sixteenths */
+  int                               m_summaryPos;
+};
+
+#endif // TSCOREBEAM_H
diff --git a/src/libs/score/tscoreclef.cpp b/src/libs/score/tscoreclef.cpp
index 7975b75460b9d6ee73b0e335637383bfa7436dce..9693c3d995c2b83bf5678ceda5d8836f095ea429 100644
--- a/src/libs/score/tscoreclef.cpp
+++ b/src/libs/score/tscoreclef.cpp
@@ -20,7 +20,6 @@
 #include "tscorescene.h"
 #include "tscorestaff.h"
 #include <music/tclef.h>
-#include "widgets/tselectclef.h"
 #include <tnoofont.h>
 #if defined (Q_OS_ANDROID)
   #include <touch/ttouchproxy.h>
@@ -32,9 +31,8 @@
 #include <QtWidgets/qdesktopwidget.h>
 #include <QtGui/qpalette.h>
 #include <QtWidgets/qgraphicsview.h>
-#include <QtCore/qtimer.h>
 
-#include <QtCore/qdebug.h>
+#include <QDebug>
 
 /*static*/
 QChar TscoreClef::clefToChar(Tclef clef) {
@@ -60,21 +58,19 @@ QChar TscoreClef::clefToChar(Tclef clef) {
   return ch;
 }
 
-
 QList<Tclef::Etype> TscoreClef::m_typesList = QList<Tclef::Etype>();
 
 
+
 TscoreClef::TscoreClef(TscoreScene* scene, TscoreStaff* staff, Tclef clef) :
   TscoreItem(scene),
   m_clef(Tclef(Tclef::e_none)),
-  m_lowerClef(0),
   m_textClef(0),
   m_readOnly(false)
 {
-  m_fakeMouseEvent = new QGraphicsSceneMouseEvent(QEvent::MouseButtonPress);
-  m_fakeMouseEvent->setButton(Qt::LeftButton);
   setStaff(staff);
   setParentItem(staff);
+  setFlag(QGraphicsItem::ItemHasNoContents);
   if (m_typesList.size() == 0) // initialize types list
     m_typesList << Tclef::e_treble_G << Tclef::e_bass_F << Tclef::e_bass_F_8down <<
     Tclef::e_alto_C << Tclef::e_tenor_C << Tclef::e_treble_G_8down;
@@ -85,54 +81,48 @@ TscoreClef::TscoreClef(TscoreScene* scene, TscoreStaff* staff, Tclef clef) :
 
   m_textClef->setFont(TnooFont(18));
   setClef(clef);
-  m_tapTimer = new QTimer(this);
-  connect(m_tapTimer, &QTimer::timeout, [=]{ m_textClef->setBrush(qApp->palette().highlight().color()); });
 }
 
 
 TscoreClef::~TscoreClef() {
-  if (m_clefMenu)
-    delete m_clefMenu;
-  delete m_fakeMouseEvent;
+//   if (m_clefMenu)
+//     delete m_clefMenu;
 }
 
 
 void TscoreClef::setClef(Tclef clef) {
   if (clef.type() == Tclef::e_pianoStaff) {
     if (!m_lowerClef) {
-        m_lowerClef = new TscoreClef(scoreScene(), staff(), Tclef(Tclef::e_bass_F));
-        m_lowerClef->setPos(0.5, getYclefPos(m_lowerClef->clef()) - (16.0 - staff()->lowerLinePos()));
-        connect(m_lowerClef, SIGNAL(clefChanged(Tclef)), this, SLOT(lowerClefChanged(Tclef)));
+      m_lowerClef = new TscoreClef(scoreScene(), staff(), Tclef(Tclef::e_bass_F));
+      m_lowerClef->setPos(0.5, getYclefPos(m_lowerClef->clef()) - (16.0 - staff()->lowerLinePos()) + 0.1);
+      connect(m_lowerClef, SIGNAL(clefChanged(Tclef)), this, SLOT(lowerClefChanged(Tclef)));
     } else // clefs already set to piano mode
         return;
     clef.setClef(Tclef::e_treble_G);
   } else {
-    if (m_lowerClef) {
-      m_lowerClef->deleteLater();
-      m_lowerClef = 0;
-    }
+    if (m_lowerClef)
+      delete m_lowerClef;
   }
-  m_clef = clef;
-  m_currClefInList = getClefPosInList(m_clef);
-  m_textClef->setText(QString(clefToChar(m_clef.type())));
-  qreal fineOff = 0.1;
-  if (clef.type() == Tclef::e_bass_F || clef.type() == Tclef::e_bass_F_8down)
-    fineOff = 0.0;
-  setPos(0.5, getYclefPos(m_clef) - (16.0 - staff()->upperLinePos()) + fineOff);
-  getStatusTip();
+      m_clef = clef;
+      m_currClefInList = getClefPosInList(m_clef);
+      m_textClef->setText(QString(clefToChar(m_clef.type())));
+      qreal fineOff = 0.1;
+      if (clef.type() == Tclef::e_bass_F || clef.type() == Tclef::e_bass_F_8down)
+        fineOff = 0.0;
+      setPos(0.5, getYclefPos(m_clef) - (16.0 - staff()->upperLinePos()) + fineOff);
+      getStatusTip();
 }
 
 
 QRectF TscoreClef::boundingRect() const {
-  return QRectF(0, 0, 6, 18); // optimal height for all clef types
+      return QRectF(0, 0, 6, 18); // optimal height for all clef types
 }
 
-
 void TscoreClef::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
   Q_UNUSED(painter)
   Q_UNUSED(option)
   Q_UNUSED(widget)
-// 	paintBackground(painter, Qt::magenta);
+//   paintBackground(painter, Qt::magenta);
 }
 
 //#################################################################################################
@@ -141,10 +131,9 @@ void TscoreClef::paint(QPainter* painter, const QStyleOptionGraphicsItem* option
 
 void TscoreClef::touched(const QPointF& scenePos) {
   Q_UNUSED(scenePos)
-  if (!readOnly())
-    m_tapTimer->start(300);
+  m_tapTimer.start();
 #if defined (Q_OS_ANDROID)
-  if (!readOnly() && !TtouchParams::i()->clefWasTouched && tMessage && !tMessage->isVisible() && tMessage->mainWindowOnTop()) {
+  if (!TtouchParams::i()->clefWasTouched && !tMessage->isVisible() && tMessage->mainWindowOnTop()) {
     tMessage->setMessage(TtouchProxy::touchClefHelp(), 0);
     TtouchParams::i()->clefWasTouched = true;
   }
@@ -153,22 +142,46 @@ void TscoreClef::touched(const QPointF& scenePos) {
 
 
 void TscoreClef::untouched(const QPointF& scenePos) {
-  m_tapTimer->stop();
-  if (!readOnly() && !scenePos.isNull() && m_textClef->brush().color() == qApp->palette().highlight().color()) {
-    m_textClef->setBrush(qApp->palette().text().color());
-    m_fakeMouseEvent->setPos(mapFromScene(scenePos));
-    QTimer::singleShot(5, [=]{ showMenu(); });
+  if (!scenePos.isNull() && m_tapTimer.hasExpired(300)) {
+    QGraphicsSceneMouseEvent me(QEvent::MouseButtonPress);
+    me.setPos(mapFromScene(scenePos));
+    me.setButton(Qt::LeftButton);
+    mousePressEvent(&me);
   }
 }
 
 
 void TscoreClef::mousePressEvent(QGraphicsSceneMouseEvent* event) {
-  if (m_readOnly)
+/*
+  if (m_readOnly) {
     TscoreItem::mousePressEvent(event);
-#if !defined (Q_OS_ANDROID)
-  else // FIXME: but it will not work on Android with mouse
-    showMenu();
-#endif
+  } else {
+    if (!m_menu) {
+      m_menu = new QMenu();
+      if (!m_clefMenu) {
+          m_clefMenu = new TclefMenu(m_menu);
+          connect(m_clefMenu, SIGNAL(statusTipRequired(QString)), this, SLOT(clefMenuStatusTip(QString)));
+      } else
+          m_clefMenu->setMenu(m_menu);
+      Tclef curClef = m_clef;
+      if (staff()->isPianoStaff())
+        curClef = Tclef(Tclef::e_pianoStaff);
+      m_clefMenu->selectClef(curClef);
+      #if defined (Q_OS_ANDROID)
+        Tclef cl = m_clefMenu->exec(QPoint(qApp->desktop()->availableGeometry().width() / 8, 10));
+      #else
+        Tclef cl = m_clefMenu->exec(QCursor::pos());
+      #endif
+      m_clefMenu->setMenu(0);
+      delete m_menu;
+      if (cl.type() == Tclef::e_none)
+        return;
+      if (curClef.type() != cl.type()) {
+        emit clefChanged(cl);
+      }
+    }
+  }
+  */
 }
 
 
@@ -182,9 +195,9 @@ void TscoreClef::lowerClefChanged(Tclef clef) {
 //##########################################################################################################
 
 void TscoreClef::getStatusTip() {
-  QString tip = QLatin1String("<b>") + m_clef.name() + QLatin1String("</b>  (") + m_clef.desc() + QLatin1String(")");
+  QString tip = "<b>" + m_clef.name() + "</b>  (" + m_clef.desc() + ")";
   if (!readOnly())
-    tip += QLatin1String("<br>") + tr("Click to select another clef.");
+    tip += "<br>" + tr("Click to select another clef.");
   setStatusTip(tip);
 }
 
@@ -214,36 +227,5 @@ int TscoreClef::getClefPosInList(Tclef clef) {
 }
 
 
-void TscoreClef::showMenu() {
-  if (!m_menu) {
-    m_menu = new QMenu();
-    if (!m_clefMenu) {
-        m_clefMenu = new TclefMenu(m_menu);
-        #if !defined (Q_OS_ANDROID)
-          connect(m_clefMenu, SIGNAL(statusTipRequired(QString)), this, SLOT(clefMenuStatusTip(QString)));
-        #endif
-    } else
-        m_clefMenu->setMenu(m_menu);
-    Tclef curClef = m_clef;
-    if (staff()->isPianoStaff())
-      curClef = Tclef(Tclef::e_pianoStaff);
-    m_clefMenu->selectClef(curClef);
-    #if defined (Q_OS_ANDROID)
-      Tclef cl = m_clefMenu->exec(QPoint(qApp->desktop()->availableGeometry().width() / 8, 10));
-    #else
-      Tclef cl = m_clefMenu->exec(QCursor::pos());
-    #endif
-    if (cl.type() != Tclef::e_none)
-      m_clef = cl;
-    m_clefMenu->setMenu(0);
-    delete m_menu;
-    if (cl.type() == Tclef::e_none)
-      return;
-
-    if (curClef.type() != cl.type())
-      QTimer::singleShot(5, [=]{ emit clefChanged(m_clef); });
-  }
-}
-
 
 
diff --git a/src/libs/score/tscoreclef.h b/src/libs/score/tscoreclef.h
index a9e8c83a815897f75b62ceb677cae007ef0ba400..f75d94a6c46c915cdbcefeec117bdb05fa3d1917 100644
--- a/src/libs/score/tscoreclef.h
+++ b/src/libs/score/tscoreclef.h
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2013-2016 by Tomasz Bojczuk                             *
+ *   Copyright (C) 2013-2017 by Tomasz Bojczuk                             *
  *   seelook@gmail.com                                                     *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -22,10 +22,11 @@
 #include <nootkacoreglobal.h>
 #include "tscoreitem.h"
 #include <music/tclef.h>
-#include <QtCore/qpointer.h>
+#include <QPointer>
+#include <QElapsedTimer>
 
 
-class TclefMenu;
+// class TclefMenu;
 
 
 /**
@@ -72,22 +73,22 @@ protected slots:
 private:
   int getYclefPos(Tclef clef);
   int getClefPosInList(Tclef clef);
-  void getStatusTip(); /**< Generates and refresh status tip depends on readOnly() and isClickable() state. */
-  void showMenu();
+      /** Generates and refresh status tip depends on readOnly() and isClickable() state. */
+  void getStatusTip();
 
 private:
   Tclef                              m_clef;
-  TscoreClef                        *m_lowerClef;
+  QPointer<TscoreClef>               m_lowerClef;
   QGraphicsSimpleTextItem           *m_textClef;
-  QPointer<TclefMenu>                m_clefMenu;
-  QPointer<QMenu>                    m_menu;
+//   QPointer<TclefMenu>                m_clefMenu;
+//   QPointer<QMenu>                    m_menu;
 
   int                                m_currClefInList;
-      /** List of all clef types except empty (none clef) and piano staff. */
+      /** List of all clef types exept empty (none clef) and piano staff. */
   static QList<Tclef::Etype>         m_typesList;
   bool                               m_readOnly; // when TRUE clef is locked
-  QTimer                            *m_tapTimer;
-  QGraphicsSceneMouseEvent          *m_fakeMouseEvent;
+  QElapsedTimer                      m_tapTimer;
+
 };
 
 #endif // TSCORECLEF_H
diff --git a/src/libs/score/tscorekeysignature.cpp b/src/libs/score/tscorekeysignature.cpp
index 43a2e9ff749ce4becec680ba4998f76efffc8416..fe0e55ae16f38977f8c3b8c4bc86333bbc4b81b3 100644
--- a/src/libs/score/tscorekeysignature.cpp
+++ b/src/libs/score/tscorekeysignature.cpp
@@ -31,10 +31,10 @@
 const qreal TscoreKeySignature::relatedLine = 3.0;
 
 void TscoreKeySignature::setKeyNameScale(QGraphicsTextItem* keyNameItem) {
-		qreal factor = (KEY_WIDTH + 5.0) / (keyNameItem->boundingRect().width());
-		if (keyNameItem->boundingRect().height() * factor > 8.0) // 8.0 is a measure of height - about 4 staff lines.
-				factor = (8.0 / keyNameItem->boundingRect().height());
-		keyNameItem->setScale(factor);
+    qreal factor = (KEY_WIDTH + 5.0) / (keyNameItem->boundingRect().width());
+    if (keyNameItem->boundingRect().height() * factor > 8.0) // 8.0 is a measure of height - about 4 staff lines.
+        factor = (8.0 / keyNameItem->boundingRect().height());
+    keyNameItem->setScale(factor);
 }
 
 
@@ -52,15 +52,15 @@ qint8 TscoreKeySignature::m_posOfAccidFlats[7] = { 4, 1, 5, 2, 6, 3, 7 };
 
 
 int nOff(Tclef::Etype c) {
-	if (c == Tclef::e_treble_G || c == Tclef::e_treble_G_8down)
-		return 3;
-	if (c == Tclef::e_bass_F || c == Tclef::e_bass_F_8down)
-		return 5;
-	if (c == Tclef::e_alto_C)
-		return 2;
-	if (c == Tclef::e_tenor_C)
-		return 4;
-	return 3;
+  if (c == Tclef::e_treble_G || c == Tclef::e_treble_G_8down)
+    return 3;
+  if (c == Tclef::e_bass_F || c == Tclef::e_bass_F_8down)
+    return 5;
+  if (c == Tclef::e_alto_C)
+    return 2;
+  if (c == Tclef::e_tenor_C)
+    return 4;
+  return 3;
 }
 /*end static*/
 
@@ -75,19 +75,19 @@ TscoreKeySignature::TscoreKeySignature(TscoreScene* scene, TscoreStaff* staff, q
   m_maxKey(7), m_minKey(-7)
 {
   setStaff(staff);
-	setParentItem(staff);
+  setParentItem(staff);
 
   TnooFont font(5);
   for (int i = 0; i < 7; i++) {
-			m_accidentals[i] = new QGraphicsSimpleTextItem();
-			registryItem(m_accidentals[i]);
-			m_accidentals[i]->setBrush(qApp->palette().text().color());
-			m_accidentals[i]->setFont(font);
-			m_accidentals[i]->setScale(scoreScene()->accidScale());
-			m_accidentals[i]->hide();
-	}
+      m_accidentals[i] = new QGraphicsSimpleTextItem();
+      registryItem(m_accidentals[i]);
+      m_accidentals[i]->setBrush(qApp->palette().text().color());
+      m_accidentals[i]->setFont(font);
+      m_accidentals[i]->setScale(scoreScene()->accidScale());
+      m_accidentals[i]->hide();
+  }
     
-	setStatusTip(tr("Key signature - to change it, click above or below the staff or use mouse wheel."));
+  setStatusTip(tr("Key signature - to change it, click above or below the staff or use mouse wheel."));
 }
 
 
@@ -118,9 +118,9 @@ void TscoreKeySignature::setKeySignature(qint8 keySign) {
 //       (int)staff()->accidInKeyArray[2] << (int)staff()->accidInKeyArray[3] << 
 //       (int)staff()->accidInKeyArray[4] << (int)staff()->accidInKeyArray[5] << (int)staff()->accidInKeyArray[6];
     m_keySignature = keySign;
-		updateKeyName();
-		if (m_lowKey && m_keySignature != m_lowKey->keySignature())
-				m_lowKey->setKeySignature(m_keySignature);
+    updateKeyName();
+    if (m_lowKey && m_keySignature != m_lowKey->keySignature())
+        m_lowKey->setKeySignature(m_keySignature);
     emit keySignatureChanged();
 }
 
@@ -139,66 +139,66 @@ qint8 TscoreKeySignature::getPosOfAccid(int noteNr, bool flatKey) {
 
 
 QPointF TscoreKeySignature::accidTextPos(int noteNr) {
-	if (noteNr >= 0 && noteNr < 7)
-			return mapToScene(m_accidentals[noteNr]->pos());
-	else 
-			return QPointF();
+  if (noteNr >= 0 && noteNr < 7)
+      return mapToScene(m_accidentals[noteNr]->pos());
+  else 
+      return QPointF();
 }
 
 
 void TscoreKeySignature::setClef(Tclef clef) {
-	if (clef.type() == Tclef::e_pianoStaff) {
-		m_clef = Tclef(Tclef::e_treble_G);
-		if (!m_lowKey) {
-				m_lowKey = new TscoreKeySignature(scoreScene(), staff());
-				m_lowKey->setParentItem(this);
-// 				m_lowKey->setPos(0.0, staff()->lowerLinePos() - 2.0);
-				m_lowKey->setPos(0.0, 14.0);
-				m_lowKey->setClef(Tclef(Tclef::e_bass_F));
-				m_lowKey->setZValue(30);
-// 				m_lowKey->setRelatedLine(2);
-// 				setRelatedLine(staff()->upperLinePos());
-				m_lowKey->setKeySignature(keySignature());
-				connect(m_lowKey, SIGNAL(keySignatureChanged()), this, SLOT(onLowKeyChanged()));
-		}
-	} else {
-		m_clef = clef;
-// 		setRelatedLine(staff()->upperLinePos());
-		if (m_lowKey) {
-			delete m_lowKey;
-		}
-	}
-	m_clefOffset = nOff(m_clef.type());
+  if (clef.type() == Tclef::e_pianoStaff) {
+    m_clef = Tclef(Tclef::e_treble_G);
+    if (!m_lowKey) {
+        m_lowKey = new TscoreKeySignature(scoreScene(), staff());
+        m_lowKey->setParentItem(this);
+//         m_lowKey->setPos(0.0, staff()->lowerLinePos() - 2.0);
+        m_lowKey->setPos(0.0, 14.0);
+        m_lowKey->setClef(Tclef(Tclef::e_bass_F));
+        m_lowKey->setZValue(30);
+//         m_lowKey->setRelatedLine(2);
+//         setRelatedLine(staff()->upperLinePos());
+        m_lowKey->setKeySignature(keySignature());
+        connect(m_lowKey, SIGNAL(keySignatureChanged()), this, SLOT(onLowKeyChanged()));
+    }
+  } else {
+    m_clef = clef;
+//     setRelatedLine(staff()->upperLinePos());
+    if (m_lowKey) {
+      delete m_lowKey;
+    }
+  }
+  m_clefOffset = nOff(m_clef.type());
   setKeySignature(keySignature());
 }
 
 
 void TscoreKeySignature::showKeyName(bool showIt) {
-	if (showIt) {
-		if (!m_keyNameText) {
-			m_keyNameText = new QGraphicsTextItem();
-			registryItem(m_keyNameText);
-			m_keyNameText->setZValue(7);
-			setKeySignature(keySignature());
-		}
-	}	else {
-			delete m_keyNameText;
-			m_keyNameText = 0;
-	}
+  if (showIt) {
+    if (!m_keyNameText) {
+      m_keyNameText = new QGraphicsTextItem();
+      registryItem(m_keyNameText);
+      m_keyNameText->setZValue(7);
+      setKeySignature(keySignature());
+    }
+  }  else {
+      delete m_keyNameText;
+      m_keyNameText = 0;
+  }
 }
 
 
 QRectF TscoreKeySignature::boundingRect() const{
-	  return QRectF(0, 0, KEY_WIDTH + 1.0, KEY_HEIGHT);
+    return QRectF(0, 0, KEY_WIDTH + 1.0, KEY_HEIGHT);
 }
 
 
 void TscoreKeySignature::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
-	Q_UNUSED(option)
-	Q_UNUSED(widget)
-	if (m_bgColor != -1) {
-			paintBackground(painter, m_bgColor);
-	}
+  Q_UNUSED(option)
+  Q_UNUSED(widget)
+  if (m_bgColor != -1) {
+      paintBackground(painter, m_bgColor);
+  }
 }
 
 
@@ -225,42 +225,10 @@ void TscoreKeySignature::setMinKey(int mk) {
 //##########################################################################################################
 
 void TscoreKeySignature::onLowKeyChanged() {
-	setKeySignature(m_lowKey->keySignature());
+  setKeySignature(m_lowKey->keySignature());
 }
 
 
-void TscoreKeySignature::mousePressEvent(QGraphicsSceneMouseEvent* event) {
-  if (!m_readOnly && event->button() == Qt::LeftButton) {
-		if (event->pos().y() > relatedLine + 4.0)
-			increaseKey(-1);
-		else if (event->pos().y() > 0.0) // ignore clicking on key name item
-			increaseKey(1);
-	}
-}
-
-
-void TscoreKeySignature::hoverEnterEvent(QGraphicsSceneHoverEvent* event) {
-	scoreScene()->mouseEntersOnKey(true);
-	TscoreItem::hoverEnterEvent(event);
-}
-
-
-void TscoreKeySignature::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) {
-	scoreScene()->mouseEntersOnKey(false);
-	TscoreItem::hoverLeaveEvent(event);
-}
-
-
-void TscoreKeySignature::untouched(const QPointF& scenePos) {
-	if (!m_readOnly && !scenePos.isNull()) {
-    QPointF fingerPos = mapFromScene(scenePos);
-		if (fingerPos.y() > relatedLine + 4.0)
-			increaseKey(-1);
-		else if (fingerPos.y() > 0.0) // ignore clicking on key name item
-			increaseKey(1);
-	}
-}
-
 
 void TscoreKeySignature::increaseKey(int step) {
   qint8 prevKey = m_keySignature;
@@ -277,13 +245,13 @@ void TscoreKeySignature::increaseKey(int step) {
 
 
 void TscoreKeySignature::updateKeyName() {
-	if (m_keyNameText) {
+  if (m_keyNameText) {
       m_keyNameText->setHtml(TkeySignature::getMajorName(m_keySignature) + QLatin1String("<br>") +
                               TkeySignature::getMinorName(m_keySignature));
-			setKeyNameScale(m_keyNameText);
-			m_keyNameText->setPos((boundingRect().width() - m_keyNameText->boundingRect().width() * m_keyNameText->scale()) / 2 - 2.5,
-						-2.0 - m_keyNameText->boundingRect().height() * m_keyNameText->scale());
-			}
+      setKeyNameScale(m_keyNameText);
+      m_keyNameText->setPos((boundingRect().width() - m_keyNameText->boundingRect().width() * m_keyNameText->scale()) / 2 - 2.5,
+            -2.0 - m_keyNameText->boundingRect().height() * m_keyNameText->scale());
+      }
 }
 
 
diff --git a/src/libs/score/tscorekeysignature.h b/src/libs/score/tscorekeysignature.h
index 1025d62873e71ee97e613b4a8b0f681511e3a21b..796be55eb6b7db94a85ffcf99404ef2aaebb05a0 100644
--- a/src/libs/score/tscorekeysignature.h
+++ b/src/libs/score/tscorekeysignature.h
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2013-2016 by Tomasz Bojczuk                             *
+ *   Copyright (C) 2013-2017 by Tomasz Bojczuk                             *
  *   seelook@gmail.com                                                     *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -37,83 +37,80 @@
 */
 class NOOTKACORE_EXPORT TscoreKeySignature : public TscoreItem
 {
+
   Q_OBJECT
-  
+
 public:
-    TscoreKeySignature(TscoreScene *scene, TscoreStaff *staff, qint8 keySign = 0);
-    
-        /** This methods get and set the key signature, and are called
-        * only from their parent @p TscoreWidgetSimple as continuation
-        * his public methods */
-    void setKeySignature(qint8 keySign);
-    qint8 keySignature() { return m_keySignature; }
-    void setClef(Tclef clef);
-		
-        /** Returns y coefficient of given note (0 - 7, 0 is c, 1 is d...).
-         * It depends on Tclef value*/
-    qint8 getPosOfAccid(int noteNr, bool flatKey = false);
-		
-				/** Returns position point of accidental text in staff coordinates. @p noteNr is [0-7] range */
-		QPointF accidTextPos(int noteNr);
-		
-		void showKeyName(bool showIt);
-		
-		void setReadOnly(bool readOnly) { m_readOnly = readOnly; if (m_lowKey) m_lowKey->setReadOnly(readOnly); }
-		bool readOnly() { return m_readOnly; }
-		
-				/** It sets background of the note segment. When sets to -1 means transparent - no background. */
-		void setBackgroundColor(QColor bg) { m_bgColor = bg; update(); }
-		
-				/** Static method that calculates scale factor of key signature name appropriate for available space above clef. */
-		static void setKeyNameScale(QGraphicsTextItem *keyNameItem);
-		static const qreal relatedLine; /** Y position of upper staff line in item coordinates */
-
-        /** Maximal key value possible to set, by default it is 7 */
-    qint8 maxKey() { return m_maxKey; }
-    void setMaxKey(int mk);
-
-        /** Minimal key value possible to set, by default it is -7 */
-    qint8 minKey() { return m_minKey; }
-    void setMinKey(int mk);
-
-    virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
-    virtual QRectF boundingRect() const;
-    
+  TscoreKeySignature(TscoreScene *scene, TscoreStaff *staff, qint8 keySign = 0);
+
+      /** This methods get and set the key signature, and are called
+      * only from their parent @p TscoreWidgetSimple as continuation
+      * his public methods */
+  void setKeySignature(qint8 keySign);
+  qint8 keySignature() { return m_keySignature; }
+  void setClef(Tclef clef);
+
+      /** Returns y coefficient of given note (0 - 7, 0 is c, 1 is d...).
+        * It depends on Tclef value*/
+  qint8 getPosOfAccid(int noteNr, bool flatKey = false);
+
+      /** Returns position point of accidental text in staff coordinates. @p noteNr is [0-7] range */
+  QPointF accidTextPos(int noteNr);
+
+  void showKeyName(bool showIt);
+
+  void setReadOnly(bool readOnly) { m_readOnly = readOnly; if (m_lowKey) m_lowKey->setReadOnly(readOnly); }
+  bool readOnly() { return m_readOnly; }
+
+      /** It sets background of the note segment. When sets to -1 means transparent - no background. */
+  void setBackgroundColor(QColor bg) { m_bgColor = bg; update(); }
+
+      /** Static method that calculates scale factor of key signature name appropriate for available space above clef. */
+  static void setKeyNameScale(QGraphicsTextItem *keyNameItem);
+  static const qreal relatedLine; /** Y position of upper staff line in item coordinates */
+
+      /** Maximal key value possible to set, by default it is 7 */
+  qint8 maxKey() { return m_maxKey; }
+  void setMaxKey(int mk);
+
+      /** Minimal key value possible to set, by default it is -7 */
+  qint8 minKey() { return m_minKey; }
+  void setMinKey(int mk);
+
+  virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
+  virtual QRectF boundingRect() const;
+
 signals:
-    void keySignatureChanged();
+  void keySignatureChanged();
 
 protected:
-		virtual void untouched(const QPointF& scenePos);
-    virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
-    virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event);
-    virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event);
-
-        /** Adds @p step to key value. Only 1 or -1 values are accepted. */
-    void increaseKey(int step);
-		void updateKeyName();
-		
+
+      /** Adds @p step to key value. Only 1 or -1 values are accepted. */
+  void increaseKey(int step);
+  void updateKeyName();
+
 protected slots:
-		void onLowKeyChanged();
+  void onLowKeyChanged();
 
 private:
-        /** Array of text items with # or b signs*/
-    QGraphicsSimpleTextItem 				*m_accidentals[7];
-		QPointer<QGraphicsTextItem>			 m_keyNameText;
-    qint8                            m_keySignature;
-		QPointer<TscoreKeySignature>		 m_lowKey;
-    
-        /** It keeps array of accidental symbol (# or b) positions
-        * (in PosY coordinates from TnoteView)
-        * @li [0] is position for f# and fb
-        * @li [1] c# and
-        * @li etc....    */
-    static qint8                     m_posOfAccid[7];
-    static qint8                     m_posOfAccidFlats[7];
-    Tclef  													 m_clef;
-		bool														 m_readOnly;
-		QColor 													 m_bgColor;
-		int															 m_clefOffset; /**< accidental distance from upper staff line depends on clef */
-    qint8                            m_maxKey, m_minKey;
+      /** Array of text items with # or b signs*/
+  QGraphicsSimpleTextItem          *m_accidentals[7];
+  QPointer<QGraphicsTextItem>       m_keyNameText;
+  qint8                             m_keySignature;
+  QPointer<TscoreKeySignature>      m_lowKey;
+
+      /** It keeps array of accidental symbol (# or b) positions
+      * (in PosY coordinates from TnoteView)
+      * @li [0] is position for f# and fb
+      * @li [1] c# and
+      * @li etc....    */
+  static qint8                      m_posOfAccid[7];
+  static qint8                      m_posOfAccidFlats[7];
+  Tclef                             m_clef;
+  bool                              m_readOnly;
+  QColor                            m_bgColor;
+  int                               m_clefOffset; /**< accidental distance from upper staff line depends on clef */
+  qint8                             m_maxKey, m_minKey;
 };
 
 #endif // TSCOREKEYSIGNATURE_H
diff --git a/src/libs/score/tscorelines.cpp b/src/libs/score/tscorelines.cpp
index 59abbb0add86e8e3914524ac41351298d0e05ce5..7f1ec60720bdb50dc11d023a4d05d1e0ca389b8e 100644
--- a/src/libs/score/tscorelines.cpp
+++ b/src/libs/score/tscorelines.cpp
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2014-2015 by Tomasz Bojczuk                             *
+ *   Copyright (C) 2014-2016 by Tomasz Bojczuk                             *
  *   seelook@gmail.com                                                     *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -19,68 +19,63 @@
 #include "tscorelines.h"
 #include "tscorenote.h"
 #include "tscorestaff.h"
-#include <QPen>
+#include <QtGui/qpen.h>
 
 TscoreLines::TscoreLines(TscoreNote* note) :
-	m_parentNote(note)
+  QGraphicsItemGroup(note),
+  m_parentNote(note)
 {
-	createLines();
+  createLines();
 }
 
 
 void TscoreLines::checkLines(int curPos) {
-	for (int i = 0; i < m_upper.size(); i++) {
-		if (curPos < m_upper[i]->line().y1())
-			m_upper[i]->show();
-		else 
-			m_upper[i]->hide();
-	}
-	if (m_parentNote && m_parentNote->staff()->isPianoStaff()) {
-		if (curPos == m_middle[0]->line().y1() - 1)
-			m_middle[0]->show();
-		else
-			m_middle[0]->hide();
-		if (curPos == m_middle[1]->line().y1() - 1)
-			m_middle[1]->show();
-		else
-			m_middle[1]->hide();
-	}
-	for (int i = 0; i < m_lower.size(); i++) {
-		if (curPos > m_lower[i]->line().y1() - 2) 
-			m_lower[i]->show();
-		else 
-			m_lower[i]->hide();
-	}
+  for (int i = 0; i < m_upper.size(); i++) {
+    if (curPos < m_upper[i]->line().y1())
+      m_upper[i]->show();
+    else
+      m_upper[i]->hide();
+  }
+  if (m_parentNote && m_parentNote->staff()->isPianoStaff()) {
+    if (curPos == m_middle[0]->line().y1() - 1)
+      m_middle[0]->show();
+    else
+      m_middle[0]->hide();
+    if (curPos == m_middle[1]->line().y1() - 1)
+      m_middle[1]->show();
+    else
+      m_middle[1]->hide();
+  }
+  for (int i = 0; i < m_lower.size(); i++) {
+    if (curPos > m_lower[i]->line().y1() - 2)
+      m_lower[i]->show();
+    else
+      m_lower[i]->hide();
+  }
 }
 
 
 void TscoreLines::hideAllLines() {
-	hideLines(m_upper);
-	hideLines(m_lower);
-	if (m_parentNote && m_parentNote->staff()->isPianoStaff())
-		hideLines(m_middle);
+  hideLines(m_upper);
+  hideLines(m_lower);
+  if (m_parentNote && m_parentNote->staff()->isPianoStaff())
+    hideLines(m_middle);
 }
 
 
 void TscoreLines::setParent(TscoreNote* sn) {
   m_parentNote = sn;
-	for (int i = 0; i < m_upper.size(); i++)
-		m_upper[i]->setParentItem(sn);
-	for (int i = 0; i < m_middle.size(); i++)
-		m_middle[i]->setParentItem(sn);
-	for (int i = 0; i < m_lower.size(); i++)
-		m_lower[i]->setParentItem(sn);
+  setParentItem(sn);
 }
 
 
-
 void TscoreLines::setColor(const QColor& lineColor) {
-	for (int i = 0; i < m_upper.size(); i++)
-        m_upper[i]->setPen(QPen(lineColor, 0.2));
-	for (int i = 0; i < m_lower.size(); i++)
-      m_lower[i]->setPen(QPen(lineColor, 0.2));
-	for (int i = 0; i < m_middle.size(); i++)
-      m_middle[i]->setPen(QPen(lineColor, 0.2));
+  for (int i = 0; i < m_upper.size(); i++)
+        m_upper[i]->setPen(QPen(lineColor, 0.2, Qt::SolidLine, Qt::RoundCap));
+  for (int i = 0; i < m_lower.size(); i++)
+      m_lower[i]->setPen(QPen(lineColor, 0.2, Qt::SolidLine, Qt::RoundCap));
+  for (int i = 0; i < m_middle.size(); i++)
+      m_middle[i]->setPen(QPen(lineColor, 0.2, Qt::SolidLine, Qt::RoundCap));
 }
 
 //##########################################################################################
@@ -88,47 +83,46 @@ void TscoreLines::setColor(const QColor& lineColor) {
 //##########################################################################################
 
 QGraphicsLineItem* TscoreLines::createNoteLine(int yPos) {
-	QGraphicsLineItem *line = new QGraphicsLineItem();
-	line->hide();
-	line->setParentItem(m_parentNote);
-	line->setZValue(7);
-	line->setLine(2.5, yPos, 7.0, yPos);
-	return line;
+  QGraphicsLineItem *line = new QGraphicsLineItem(this);
+  line->hide();
+  line->setZValue(7);
+  line->setLine(0.0, yPos, 3.3, yPos);
+  return line;
 }
 
 
 void TscoreLines::createLines() {
-	deleteLines(m_upper);
-	deleteLines(m_middle);
-	deleteLines(m_lower);
+  deleteLines(m_upper);
+  deleteLines(m_middle);
+  deleteLines(m_lower);
   int i = m_parentNote->staff()->upperLinePos() - 2;
   while (i > 0) { // upper lines
-		m_upper << createNoteLine(i);
+    m_upper << createNoteLine(i);
     i -= 2;
   }
   i = m_parentNote->staff()->upperLinePos() + 10.0; // distance between upper and lower (or lower grand staff) staff line
   if (m_parentNote->staff()->isPianoStaff()) {
-		i = m_parentNote->staff()->lowerLinePos() + 10.0;
-		m_middle << createNoteLine(m_parentNote->staff()->upperLinePos() + 10);
-		m_middle << createNoteLine(m_parentNote->staff()->lowerLinePos() - 2);
-	}
+    i = m_parentNote->staff()->lowerLinePos() + 10.0;
+    m_middle << createNoteLine(m_parentNote->staff()->upperLinePos() + 10);
+    m_middle << createNoteLine(m_parentNote->staff()->lowerLinePos() - 2);
+  }
   while (i < m_parentNote->boundingRect().height()) {
-		m_lower << createNoteLine(i);
+    m_lower << createNoteLine(i);
     i += 2;
   }
 }
 
 
 void TscoreLines::deleteLines(TaddLines& linesList) {
-	for (int i = 0; i < linesList.size(); i++)
-		delete linesList[i];
-	linesList.clear();
+  for (int i = 0; i < linesList.size(); i++)
+    delete linesList[i];
+  linesList.clear();
 }
 
 
 void TscoreLines::hideLines(TaddLines& linesList) {
-	for (int i=0; i < linesList.size(); i++)
-		linesList[i]->hide();
+  for (int i=0; i < linesList.size(); i++)
+    linesList[i]->hide();
 }
 
 
diff --git a/src/libs/score/tscorelines.h b/src/libs/score/tscorelines.h
index 5850a9739ad4dd133efe3dc97933f25903609787..5b62fccb82e4c2a46e7d9fe51ae97621da09fc7c 100644
--- a/src/libs/score/tscorelines.h
+++ b/src/libs/score/tscorelines.h
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2014-2015 by Tomasz Bojczuk                             *
+ *   Copyright (C) 2014-2016 by Tomasz Bojczuk                             *
  *   seelook@gmail.com                                                     *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -20,7 +20,7 @@
 #define TSCORELINES_H
 
 #include <nootkacoreglobal.h>
-#include <QGraphicsObject>
+#include <QtWidgets/qgraphicsitem.h>
 
 class TscoreItem;
 class TscoreNote;
@@ -28,47 +28,47 @@ class TscoreNote;
 
 typedef QList<QGraphicsLineItem*> TaddLines; /** List of graphics lines  */
 
-/** 
+/**
  * There are additional lines appearing above or below a staff (or between piano staves)
  * Every @class TscoreNote has it and note cursor as well.
  * It has method to determine which lines has to be shown depending on note position:
  * @p checkLines()
  */
-class NOOTKACORE_EXPORT TscoreLines
+class NOOTKACORE_EXPORT TscoreLines : public QGraphicsItemGroup
 {
 
 public:
-	TscoreLines(TscoreNote* note);
-	
-	TaddLines& up() { return m_upper; }
-	TaddLines& mid() { return m_middle; }
-	TaddLines& lo() { return m_lower; }
-	
-	void setColor(const QColor& lineColor);
-	
-			/** Recreates lines adjusting them to new staff (clef) */
-	void adjustLines(TscoreNote* scoreNote) { m_parentNote = scoreNote; createLines(); }
-	
-	void hideAllLines();
-	
-	void checkLines(int curPos); /** Checks whose lines show and hide. @p curPos is current position of note those lines belong to. */
-	
-	void setParent(TscoreNote* sn);
-	
+  TscoreLines(TscoreNote* note);
+
+  TaddLines& up() { return m_upper; }
+  TaddLines& mid() { return m_middle; }
+  TaddLines& lo() { return m_lower; }
+
+  void setColor(const QColor& lineColor);
+
+      /** Recreates lines adjusting them to new staff (clef) */
+  void adjustLines(TscoreNote* scoreNote) { m_parentNote = scoreNote; createLines(); }
+
+  void hideAllLines();
+
+  void checkLines(int curPos); /** Checks whose lines show and hide. @p curPos is current position of note those lines belong to. */
+
+  void setParent(TscoreNote* sn);
+
 private:
-	QGraphicsLineItem* createNoteLine(int yPos);
-	
-					/** Common method creating upper and lower staff lines.
-				 * It appends new lines to list 
-				 * so do not forget to clear list before every next call. */
-	void createLines();
-	void hideLines(TaddLines &linesList);	
-	void deleteLines(TaddLines &linesList); /** Deletes lines in the list and clears the list */
-	
+  QGraphicsLineItem* createNoteLine(int yPos);
+
+          /** Common method creating upper and lower staff lines.
+         * It appends new lines to list
+         * so do not forget to clear list before every next call. */
+  void createLines();
+  void hideLines(TaddLines &linesList);
+  void deleteLines(TaddLines &linesList); /** Deletes lines in the list and clears the list */
+
 private:
-	TaddLines 				m_upper, m_middle, m_lower;
-	TscoreNote			 *m_parentNote;
-	
+  TaddLines         m_upper, m_middle, m_lower;
+  TscoreNote       *m_parentNote;
+
 };
 
 #endif // TSCORELINES_H
diff --git a/src/libs/score/tscoremeasure.cpp b/src/libs/score/tscoremeasure.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8eae9472c40d013ca30a8f4829477546927ef134
--- /dev/null
+++ b/src/libs/score/tscoremeasure.cpp
@@ -0,0 +1,733 @@
+/***************************************************************************
+ *   Copyright (C) 2016 by Tomasz Bojczuk                                  *
+ *   seelook@gmail.com                                                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 3 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+
+#include "tscoremeasure.h"
+#include "tscorenote.h"
+#include "tscorestaff.h"
+#include "tscoremeter.h"
+#include "tscorebeam.h"
+#include "tscoretie.h"
+#include "tscorescene.h"
+#include <music/tmeter.h>
+#include <music/tnote.h>
+#include <QtWidgets/qapplication.h>
+#include <QtCore/qdebug.h>
+#include <QtGui/qpen.h>
+#include <QtGui/qpalette.h>
+
+
+/** For debug purposes: displays content of given measure */
+void content (TscoreMeasure* m) {
+  QString c;
+  if (m->isEmpty())
+      c = QStringLiteral("is empty");
+  else
+      for (TscoreNote* sn : m->notes()) {
+        c += QStringLiteral("<");
+        if (sn->note()->isValid() && !sn->note()->isRest())
+          c += sn->note()->toText();
+        else
+          c += QLatin1String("r");
+        c += QLatin1String(">");
+        c += QString("%1%2").arg(sn->note()->weight()).arg(sn->note()->hasDot() ? QStringLiteral(".") : QString());
+        c += QString("(%1) ").arg(sn->rhythmGroup());
+      }
+  qDebug() << m->debug() << c;
+}
+
+
+/*static*/
+int TscoreMeasure::groupDuration(const QList<TscoreNote*>& notes) {
+  int total = 0;
+  for (TscoreNote* sn : notes)
+    total += sn->note()->duration();
+  return total;
+}
+
+//#################################################################################################
+//###################            TscoreMeasure         ############################################
+//#################################################################################################
+/**
+ * This class is grouping notes (TscoreNote) into measure.
+ * Notes are added through:
+ * - @p insertNote() - adds single note
+ * - @p prependNotes() - adds QList<TscoreNote*> at the measure beginning
+ * - @p noteChangedSlot() - connected to every note when it changes the rhythm
+ *
+ * In @p updateRhythmicGroups() each note gets rhythmic group number
+ * and array m_firstInGr keeps indexes of first note in each group.
+ * (groups are defined in TscoreMeter class and depend on meter)
+ * @p resolveBeaming() sets beams (creates TscoreBeam if necessary)
+ * @p checkBarLine() manages measure bar line
+ *
+ * @p releaseAtEnd() takes a given duration of notes from the measure end
+ * then @p shiftReleased() moves them to the next measure
+ */
+TscoreMeasure::TscoreMeasure(TscoreStaff* staff, int nr) :
+  QObject(staff),
+  m_id(nr),
+  m_staff(staff),
+  m_firstInGr(new qint8[1])
+{
+  m_duration = m_staff->scoreScene()->scoreMeter() ? m_staff->scoreScene()->scoreMeter()->meter()->duration() : 0;
+  m_free = duration();
+  m_barLine = new QGraphicsLineItem;
+  m_barLine->hide();
+  m_barLine->setPen(QPen(qApp->palette().text().color(), 0.2));
+  m_barLine->setZValue(50);
+}
+
+
+TscoreMeasure::~TscoreMeasure()
+{
+  delete[] m_firstInGr;
+  delete m_barLine;
+}
+
+
+Tmeter* TscoreMeasure::meter() const {
+  return m_staff->scoreScene()->scoreMeter()->meter();
+}
+
+
+TscoreMeter* TscoreMeasure::scoreMeter() const {
+  return m_staff->scoreScene()->scoreMeter();
+}
+
+
+void TscoreMeasure::setStaff(TscoreStaff* st) {
+  m_staff = st;
+  setParent(st);
+  for (TscoreBeam* b : m_beams)
+    b->changeStaff(st);
+
+  if (st->firstMeasure() == this) { // this measure was the last and went at the beginning of the next staff
+      auto first = firstNote();
+      if (first->note()->rtm.tie() > Trhythm::e_tieStart) { // tie continues or ends on first note
+        auto prev = first->prevNote();
+        if (prev->tie())
+          prev->tie()->checkStaves();
+
+        else // TODO: delete if not occurs
+          qDebug() << debug() << "first note has tie flag set but tie doesn't exists";
+      }
+  } else if (st->lastMeasure() == this) { // this measure was the first and went at the end of previous staff
+      auto last = lastNote();
+      if (last->tie())
+        last->tie()->checkStaves();
+  }
+}
+
+
+void TscoreMeasure::changeMeter(const Tmeter& m) {
+  m_duration = m.duration();
+  m_free = duration();
+  // TODO: recalculate measure, move notes if not fit to the meter to next measure or ask for notes from next
+  if (m.meter() == Tmeter::e_none) {
+      for (TscoreNote* sn : m_notes) {
+        sn->setRhythm(Trhythm(Trhythm::e_none));
+      }
+  } else {
+      for (TscoreNote* sn : m_notes) {
+        sn->setRhythm(Trhythm(m.lower() == 4 ? Trhythm::e_quarter : Trhythm::e_eighth, !sn->note()->isValid()));
+        m_free -= sn->note()->duration();
+      }
+  }
+//   qDebug() << debug() << "duration" << duration() << "remained" << m_free;
+  // TODO: recalculate or remove beams when no meter
+}
+
+
+void TscoreMeasure::prependNotes(QList<TscoreNote*>& nl) {
+  QList<TscoreNote*> notesToOut;
+  Tnote newNote; // new note that has to be created when rhythm duration is split
+  int notesDur = groupDuration(nl);
+
+  if (nl.first()->note()->rhythm() != Trhythm::e_none && m_free - notesDur < 0) // move notes to the next measure if not enough space
+    releaseAtEnd(notesDur, notesToOut, newNote);
+
+  for (int i = 0; i < nl.size(); ++i) {
+    m_notes.insert(i, nl[i]);
+    connect(nl[i], &TscoreNote::noteGoingToChange, this, &TscoreMeasure::noteChangedSlot);
+  }
+
+  updateRhythmicGroups();
+  resolveBeaming(m_notes.first()->rhythmGroup());
+  checkBarLine();
+
+  for (TscoreBeam* b : m_beams)
+    b->performBeaming();
+
+  shiftReleased(notesToOut, newNote);
+
+  content(this);
+}
+
+
+void TscoreMeasure::appendNotes(QList<TscoreNote*>& nl) {
+  if (groupDuration(nl) > m_free) { // TODO: It should never occur - delete checking after all
+    qDebug() << debug() << "MEASURE HAS NO FREE SPACE FOR SO MANY NOTES. appendNotes skipped";
+    return;
+  }
+
+  int lastIndex = lastNoteId() - firstNoteId();
+  for (int i = 0; i < nl.size(); ++i) {
+    m_notes.append(nl[i]);
+    connect(nl[i], &TscoreNote::noteGoingToChange, this, &TscoreMeasure::noteChangedSlot);
+  }
+
+  updateRhythmicGroups();
+  resolveBeaming(m_notes[lastIndex]->rhythmGroup());
+  checkBarLine();
+}
+
+
+void TscoreMeasure::insertNote(int id, TscoreNote* sn) {
+//   qDebug() << debug() << sn->note()->rtm.xmlType() << "inserting id" << id << "count" << m_notes.count() << "free" << m_free;
+  int noteDur = sn->note()->duration();
+  int resolveAfter = 0; // un-resolvable duration of new note
+
+  QList<TscoreNote*> notesToOut;
+  Tnote newNote; // new note that has to be created when rhythm duration is split
+
+  if (sn->note()->rhythm() != Trhythm::e_none && m_free - noteDur < 0) { // move notes to the next measure if not enough space
+    int toRelease = releaseAtEnd(noteDur - m_free, notesToOut, newNote, id);
+    if (toRelease > 0) { // There is still not enough space
+      if (m_free > 0) { // measure has some free space for the new note but not for entire
+          if (Trhythm(m_free).rhythm() == Trhythm::e_none) {
+              Trhythm subRhythm(noteDur - m_free, sn->note()->isRest());
+              subRhythm.setTie(sn->note()->rtm.tie());
+              subRhythm.setStemDown(sn->note()->rtm.stemDown());
+              if (subRhythm.rhythm() == Trhythm::e_none)
+                qDebug() << debug() << "can not shrink note to duration" << noteDur - m_free;
+              sn->setRhythm(subRhythm);
+              splitThenInsert(m_free, id, *sn->note(), sn->isReadOnly());
+              insertNote(lastNoteId() + 1, sn);
+              if (!sn->note()->isRest())
+                lastNote()->tieWithNext();
+              return;
+          }
+          Trhythm oldRhythm(sn->note()->rtm);
+          sn->setRhythm(Trhythm(m_free, sn->note()->isRest()));
+          copyRhythmParams(sn, oldRhythm);
+//           sn->note()->rtm.setTie(oldRhythm.tie());
+//           sn->note()->rtm.setStemDown(oldRhythm.stemDown());
+          if (newNote.rhythm() != Trhythm::e_none) // TODO: remove when tested
+            qDebug() << "NEW NOTE is already created!!!";
+          Trhythm newRtm(noteDur - m_free, sn->note()->isRest());
+          if (newRtm.rhythm() == Trhythm::e_none) // two notes have to be added
+            resolveAfter = noteDur - m_free; // do it after
+          else
+            newNote = Tnote(*sn->note(), newRtm);
+          noteDur = m_free;
+      } else { // measure has not at all space
+          qDebug() << debug() << "move entire note" << sn->note()->toText();
+          notesToOut << sn;
+          m_staff->shiftToMeasure(m_staff->measures().indexOf(this) + 1, notesToOut);
+          return;
+      }
+    }
+  }
+
+  m_free -= noteDur;
+  m_notes.insert(id, sn);
+
+  qDebug() << debug() << "measure got a note" << sn->note()->rtm.xmlType() << "FREE" << m_free << "out" << notesToOut.count();
+  connect(sn, &TscoreNote::noteGoingToChange, this, &TscoreMeasure::noteChangedSlot);
+
+  updateRhythmicGroups();
+  resolveBeaming(sn->rhythmGroup());
+  checkBarLine();
+
+  shiftReleased(notesToOut, newNote);
+  if (resolveAfter) {
+    auto lastN = lastNote();
+    splitThenInsert(resolveAfter, lastN->index() + 1, *lastN->note(), lastN->isReadOnly());
+  }
+
+  content(this);
+}
+
+
+void TscoreMeasure::removeNote(int noteToRemove) {
+  if (noteToRemove >= 0 && noteToRemove < m_notes.count()) {
+      int rmDur = m_notes[noteToRemove]->note()->duration();
+      disconnect(m_notes[noteToRemove], &TscoreNote::noteGoingToChange, this, &TscoreMeasure::noteChangedSlot);
+      if (m_barLine->parentItem() == m_notes[noteToRemove])
+          m_barLine->setParentItem(nullptr); // reset bar-line parent - otherwise it will be deleted with the note
+      m_notes.removeAt(noteToRemove);
+
+      if (rmDur == duration()) {
+        qDebug() << "A special case when removing note is as long as the measure - remove whole measure then";
+      }
+      m_free += rmDur;
+      fill();
+  } else
+      qDebug() << debug() << "Tried to remove note out of range";
+}
+
+
+qreal TscoreMeasure::notesWidth() {
+  if (!isEmpty())
+    return lastNote()->rightX() - firstNote()->x();
+  else
+    return 0.0;
+}
+
+
+int TscoreMeasure::freeAt(int noteId) const {
+  int total = 0;
+  for (int i = noteId; i < m_notes.size(); ++i)
+    total += m_notes[i]->note()->duration();
+  return total;
+}
+
+
+int TscoreMeasure::durationAt(int noteId) const {
+  int total = 0;
+  int end = qMin<int>(noteId, m_notes.size());
+  for (int i = 0; i < end; ++i)
+    total += m_notes[i]->note()->duration();
+  return total;
+}
+
+
+int TscoreMeasure::firstNoteId() const {
+  return m_notes.count() ? m_notes.first()->index() : 0;
+}
+
+
+int TscoreMeasure::lastNoteId() const {
+  return m_notes.count() ? m_notes.last()->index() : 0;
+}
+
+
+char TscoreMeasure::debug() {
+  QTextStream o(stdout);
+  o << " \033[01;33m[" << QString("%1/%2").arg(id()).arg(m_staff->number()) << " MEASURE]\033[01;00m";
+  return 32; // fake
+}
+
+
+//#################################################################################################
+//###################              PROTECTED           ############################################
+//#################################################################################################
+void TscoreMeasure::noteChangedSlot(TscoreNote* sn) {
+  Tnote newNote; // new note that has to be created when rhythm duration is split
+  QList<TscoreNote*> notesToOut;
+
+  if (sn->rhythmChanged()) {
+    // TODO: if new duration of changed note is longer than whole measure duration - split it here and create new measure with single note
+    //       - still we don't know new pitch
+    int prevDur = sn->rhythm()->duration();
+    int newDur = sn->note()->duration();
+    int nextMeasDur = 0;
+    qDebug() << debug() << "rhythm changed from" << sn->rhythm()->string() << "to" << sn->note()->rtm.string() << "free" << m_free;
+    if (m_free - (newDur - prevDur) < 0) { // There is not enough space for this note with longer duration
+      /** 1. Try to release measure (move notes after this @p sn one to the next measure) */
+        int leftDur = releaseAtEnd(newDur - prevDur - m_free, notesToOut, newNote, sn->index() - firstNoteId() + 1);
+        if (leftDur) {
+          sn->moveNote(sn->note()->isRest() ? 0 : sn->newNotePos()); // update position of note head
+          sn->staff()->updatePitch(sn->index()); // update Tnote according to new head position
+      /** 2. There is still not enough space for new duration - splitting duration of this @p sn note to fill free space in this measure
+        * and create part of that duration in the next one */
+          nextMeasDur = newDur - (m_free + prevDur);
+          Trhythm oldRhythm(sn->note()->rtm);
+          Trhythm newRtmOfChanged(m_free + prevDur);
+          if (newRtmOfChanged.rhythm() == Trhythm::e_none) {
+      /** 3. Unfortunately remained free space in the measure can't be filled with single rhythm value  */
+              qDebug() << debug() << "To fill measure with remaining duration need to split note of" << m_free + prevDur;
+              TrhythmList solvedList;
+              Trhythm::resolve(m_free + prevDur, solvedList);
+              if (solvedList.size() == 2) {
+                  solvedList.first().setRest(oldRhythm.isRest());
+                  solvedList.last().setRest(oldRhythm.isRest());
+                  sn->note()->rtm.setRhythm(solvedList.first().duration());
+                  copyRhythmParams(sn, oldRhythm);
+                  Tnote n2(*sn->note(), solvedList.last());
+                  // TODO: common code with @p split
+                  auto inserted = m_staff->insertNote(n2, sn->index() + 1, sn->isReadOnly());
+                  fixStemDirection(inserted);
+                  m_notes.insert(inserted->index() - firstNoteId(), inserted);
+                  connect(inserted, &TscoreNote::noteGoingToChange, this, &TscoreMeasure::noteChangedSlot);
+//                   inserted->setGroup(sn->group());
+                  m_staff->updateNotesPos(inserted->index());
+                  if (!sn->note()->isRest())
+                    restoreTie(oldRhythm.tie(), sn);
+              } else
+                  qDebug() << debug() << "Can not resolve duration of" << m_free + prevDur;
+          } else {
+              sn->note()->rtm.setRhythm(newRtmOfChanged);
+              copyRhythmParams(sn, oldRhythm);
+          }
+        }
+        qDebug() << debug() << "RECALCULATED, remained" << nextMeasDur;
+        updateRhythmicGroups();
+        resolveBeaming(sn->rhythmGroup());
+        checkBarLine();
+        if (nextMeasDur) {
+      /** 4. At the beginning of the next staff, create new note of the same pitch with remaining duration. */
+          Trhythm nextMeasRtm(nextMeasDur);
+          if (nextMeasRtm.rhythm() == Trhythm::e_none) {
+              splitThenInsert(nextMeasDur, lastNoteId() + 1, *sn->note(), sn->isReadOnly());
+          } else {
+              auto nextMeasNote = m_staff->insertNote(lastNoteId() + 1, Tnote(*sn->note(), nextMeasRtm), sn->isReadOnly());
+              fixStemDirection(nextMeasNote);
+          }
+          if (!sn->note()->isRest())
+            lastNote()->tieWithNext();
+        }
+    } else if (newDur == prevDur) {
+        if (sn->note()->isRest() != sn->rhythm()->isRest())
+          qDebug() << debug() << "note" << sn->index() << "changed to/from rest";
+        resolveBeaming(sn->rhythmGroup(), sn->rhythmGroup());
+        checkBarLine();
+    } else { // measure duration is less than meter - take notes from the next measure
+        m_free += prevDur - newDur;
+        qDebug() << debug() << "needs duration" << m_free;
+        fill();
+    }
+  }
+
+  shiftReleased(notesToOut, newNote);
+}
+
+
+void TscoreMeasure::updateRhythmicGroups() {
+  if (duration() == 0)
+    return; 
+
+  qDebug() << debug() << "Updating rhythmic groups";
+
+  int notePos = 0, grNr = 0, currGr = 0;
+  delete[] m_firstInGr;
+  m_firstInGr = new qint8[scoreMeter()->groupCount()];
+  m_firstInGr[0] = 0; // first note in measure also begins first rhythmic group
+  for (int i = 0; i < m_notes.size(); ++i) {
+    if (currGr != grNr) {
+      m_firstInGr[grNr] = i;
+      currGr = grNr;
+    }
+    m_notes[i]->setRhythmGroup(grNr);
+    notePos += m_notes[i]->note()->duration();
+    while (grNr < scoreMeter()->groupCount() && notePos >= scoreMeter()->groupPos(grNr))
+      grNr++;
+  }
+  if (currGr < scoreMeter()->groupCount() - 1) { // fill the rest of the array
+    for (int gr = currGr + 1; gr < scoreMeter()->groupCount(); ++gr)
+      m_firstInGr[gr] = -1; // with '-1' - means no notes yet
+  }
+  m_free = m_duration - notePos;
+}
+
+
+void TscoreMeasure::resolveBeaming(int firstGroup, int endGroup) {
+  if (m_notes.count() < 2)
+    return;
+
+  if (endGroup == -1)
+    endGroup = scoreMeter()->groupCount() - 1;
+
+  // delete beams in groups affected by rhythm change
+  if (!m_beams.isEmpty()) {
+    QMutableListIterator<TscoreBeam*> i(m_beams);
+    while (i.hasNext()) {
+      qint8 rg = i.next()->first()->rhythmGroup();
+      if (rg >= firstGroup && rg <= endGroup) {
+        delete i.value();
+        i.remove();
+      }
+    }
+  }
+
+  // create beams
+  while (firstGroup <= endGroup && m_firstInGr[firstGroup] > -1) {
+    int noteNr = qMax(1, int(m_firstInGr[firstGroup]) + 1);
+    while (noteNr < m_notes.count() && m_notes[noteNr]->rhythmGroup() == firstGroup) {
+        auto noteSeg = m_notes[noteNr]; // cache pointer to TscoreNote for multiple reuse
+        auto prevSeg = m_notes[noteNr - 1];
+        if (!noteSeg->note()->isRest() && !prevSeg->note()->isRest() // not a rest
+            && noteSeg->note()->rhythm() > Trhythm::e_quarter // sixteenth or eighth
+            && prevSeg->note()->rhythm() > Trhythm::e_quarter)
+        {
+          if (prevSeg->note()->rtm.beam() == Trhythm::e_noBeam) // start beam group
+              m_beams << new TscoreBeam(prevSeg, this);
+          if (!m_beams.isEmpty()) {
+              noteSeg->note()->rtm.setBeam(Trhythm::e_beamCont);
+              m_beams.last()->addNote(noteSeg);
+          }
+        }
+        noteNr++;
+    }
+    if (!m_beams.isEmpty() && m_beams.last()->last()->note()->rtm.beam() == Trhythm::e_beamCont)
+        m_beams.last()->closeBeam();
+    firstGroup++;
+  }
+}
+
+
+/**
+ *  iterate through notes in backward order (right to left), take note by note to release required duration
+ *  create a list from taken notes to send it to the next measure
+ *  split the latest note (the most right one in the measure) if necessary
+ *  half of the duration remains in current measure at the end tied with
+ *  a new note that has to be created and push to the beginning of the next measure
+ */
+int TscoreMeasure::releaseAtEnd(int dur, QList<TscoreNote*>& notesToOut, Tnote& newNote, int endNote) {
+  int noteNr = m_notes.count() - 1;
+  while (noteNr >= endNote && dur > 0) {
+      auto lastN = lastNote();
+      int lastDur = lastN->note()->duration();
+      if (lastDur > dur) { // last note is longer than required space - split it then create and move the rest of its duration to the next measure
+          if (Trhythm(lastDur - dur).rhythm() == Trhythm::e_none) { // subtracting can't be solved by single note
+            split(lastN);                                           // then split on two notes
+            continue;                                               // and call while loop again
+          }
+          Trhythm oldRhythm(lastN->note()->rtm); // preserve tie and stem direction
+          lastN->setRhythm(Trhythm(lastDur - dur, lastN->note()->isRest()));
+          copyRhythmParams(lastN, oldRhythm);
+//           lastN->note()->rtm.setStemDown(oldRhythm.stemDown());
+//           if (oldRhythm.tie())
+//             lastN->note()->rtm.setTie(Trhythm::e_tieCont);
+          newNote = Tnote(*lastN->note(), Trhythm(dur, lastN->note()->isRest()));
+//           newNote.rtm.setStemDown(oldRhythm.stemDown());
+          lastDur = dur;
+      } else { // last note is the same long or smaller than required space - so move it to the next measure
+          notesToOut << m_notes.takeLast();
+          disconnect(notesToOut.last(), &TscoreNote::noteGoingToChange, this, &TscoreMeasure::noteChangedSlot);
+          auto b = notesToOut.last()->beam();
+          if (b) {
+            m_beams.removeOne(b);
+            delete b;
+          }
+      }
+      dur -= lastDur;
+      m_free += lastDur; // note was taken out so there is more free space in the measure
+  }
+
+  return dur;
+}
+
+
+int TscoreMeasure::takeAtStart(int dur, QList<TscoreNote*>& notesToOut) {
+  qDebug() << debug() << "taking" << dur << "from the beginning";
+  content(this);
+  int noteNr = 0;
+  int retDur = 0;
+  while (noteNr < m_notes.count() && dur > 0) {
+    int firstDur = firstNote()->note()->duration();
+    if (firstDur > dur) { // first measure note is longer than required duration - shrink it and create new one
+      auto first = firstNote();
+      Trhythm oldRhythm(first->note()->rtm);
+      if (Trhythm(firstDur - dur).rhythm() == Trhythm::e_none) { // subtracting can't be solved by single note
+        split(first);                                            // then split on two notes
+        continue;                                                // and call while loop again
+      }
+      firstNote()->note()->setRhythm(Trhythm(firstDur - dur, first->note()->isRest()));
+      copyRhythmParams(first, oldRhythm);
+      firstDur = dur;
+      retDur = dur;
+      dur = 0;
+    } else { // first note is the same long or smaller than required space - so move it to the next measure
+      notesToOut << m_notes.takeFirst();
+      disconnect(notesToOut.last(), &TscoreNote::noteGoingToChange, this, &TscoreMeasure::noteChangedSlot);
+      dur -= firstDur;
+      auto b = notesToOut.last()->beam();
+      if (b) {
+        m_beams.removeOne(b);
+        delete b;
+      }
+    }
+    m_free += firstDur;
+    noteNr++;
+  }
+
+  qDebug() << debug() << notesToOut.count() << "taken at start." << "Now measure has" << m_notes.count() << "notes";
+  content(this);
+
+  if (m_free)
+    fill();
+
+  return retDur;
+}
+
+
+void TscoreMeasure::checkBarLine() {
+  if (duration() && m_free == 0) { // update bar line
+      if (m_barLine->parentItem() != lastNote()->parentItem()) {
+        m_barLine->setParentItem(lastNote());
+        QPointF barLinePos = lastNote()->mapFromParent(QPointF(lastNote()->rightX() - 0.2, 0.0));
+        m_barLine->setLine(barLinePos.x(), lastNote()->staff()->upperLinePos(), barLinePos.x(), lastNote()->staff()->upperLinePos() + 8.0);
+        m_barLine->show();
+      }
+  } else if (m_free > 0) {
+        m_barLine->hide();
+  } else // TODO: It should never occur - delete it when tested
+      qDebug() << debug() << "ARE YOU MAD? Measure has more notes than the meter allows!";
+}
+
+
+//#################################################################################################
+//###################              PRIVATE             ############################################
+//#################################################################################################
+
+void TscoreMeasure::addNewNote(Tnote& newNote) {
+// prepare tie, if any to restore it after new note will be created
+  auto lastN = lastNote();
+  auto lastTie = lastN->note()->rtm.tie(); // backup tie state to revert it after new note will be added
+
+// create a new note on the staff
+  auto inserted = m_staff->insertNote(lastN->index() + 1, newNote);
+  fixStemDirection(lastNote());
+  qDebug() << debug() << "creating new note after" << lastN->index() << lastN->note()->toText() << newNote.rtm.string();
+
+  if (!newNote.isRest()) {
+    lastN->tieWithNext();
+    if (lastTie == Trhythm::e_tieCont || lastTie == Trhythm::e_tieStart)
+      inserted->tieWithNext();
+  }
+}
+
+
+void TscoreMeasure::shiftReleased(QList<TscoreNote*>& notesToOut, Tnote& newNote) {
+  if (!notesToOut.isEmpty())
+    m_staff->shiftToMeasure(id() + 1, notesToOut);
+
+  if (newNote.rhythm() != Trhythm::e_none)
+    addNewNote(newNote);
+}
+
+
+void TscoreMeasure::fill() {
+  QList<TscoreNote*> notesToShift;
+  int remainDur = m_staff->shiftFromMeasure(id() + 1, m_free, notesToShift);
+  qDebug() << debug() << "fill, remain" << remainDur << "to shift:" << notesToShift.count();
+  for (int i = 0; i < notesToShift.size(); ++i) {
+    m_notes.append(notesToShift[i]);
+    connect(notesToShift[i], &TscoreNote::noteGoingToChange, this, &TscoreMeasure::noteChangedSlot);
+  }
+  if (remainDur) { // next measure has a part of a new note
+      qDebug() << debug() << remainDur << "remained in the next measure";
+      auto firstInNext = m_staff->measures()[id() + 1]->firstNote()->note();
+      Tnote newNote(*firstInNext, Trhythm(remainDur, firstInNext->isRest()));
+      auto inserted = m_staff->insertNote(newNote, lastNoteId() + 1, lastNote()->isReadOnly());
+//       copyRhythmParams(inserted, firstInNext->rtm);
+      fixStemDirection(inserted);
+      insertNote(inserted->index() - firstNoteId(), inserted);
+      m_staff->updateNotesPos();
+      if (!inserted->note()->isRest()) // add a tie
+        inserted->tieWithNext();
+  } else {
+      updateRhythmicGroups();
+      resolveBeaming(0);
+      checkBarLine();
+  }
+
+  content(this);
+}
+
+
+/**
+ * This method is called when subtracting from rhythm value can't be solved in single note.
+ * So given 'long' note is split, then calling method tries to subtract from smaller rhythm.
+ * Because adding new, split note doesn't change measure duration,
+ * this method simplifies process of adding new note to staff and measure.
+ * It ties notes as well.
+ */
+void TscoreMeasure::split(TscoreNote* sn) {
+  auto tieCopy = sn->note()->rtm.tie();
+//   if (!sn->note()->isRest())
+//     preserveTie(tieCopy, sn);
+
+  TrhythmList splitList;
+  sn->note()->rtm.split(splitList);
+  sn->note()->rtm.setRhythm(splitList.first());
+  Tnote n2(*sn->note(), splitList.last());
+  // TODO: common code like in @p noteChangedSlot() - do method of it
+  auto inserted = m_staff->insertNote(n2, sn->index() + 1, sn->isReadOnly());
+  fixStemDirection(inserted);
+  m_notes.insert(inserted->index() - firstNoteId(), inserted);
+  connect(inserted, &TscoreNote::noteGoingToChange, this, &TscoreMeasure::noteChangedSlot);
+  inserted->setGroup(sn->group());
+  m_staff->updateNotesPos(inserted->index());
+  // ------------
+
+  if (!sn->note()->isRest())
+    restoreTie(tieCopy, sn);
+}
+
+
+/**
+ * Looks for smallest rhythm that given duration divides on,
+ * then tries to assembly that duration for two notes which are multiplicity of obtained smallest value.
+ * Inserts that notes to staff using given @p id index
+ */
+void TscoreMeasure::splitThenInsert(int dur, int id, const Tnote& note, bool readOnly) {
+  qDebug() << debug() << "splitThenInsert" << dur << note.toText() << note.rtm.string();
+
+  TrhythmList twoSplit;
+  Trhythm::resolve(dur, twoSplit);
+  if (twoSplit.size() == 2) {
+      Trhythm& r1 = twoSplit.first(), r2 = twoSplit.last();
+      if (r1.rhythm() != Trhythm::e_none && r2.rhythm() != Trhythm::e_none) {
+          r1.setRest(note.isRest());
+          r2.setRest(note.isRest());
+        // We found it!
+          auto note1 = m_staff->insertNote(id, Tnote(note, r2), readOnly);
+          fixStemDirection(note1);
+          auto note2 = m_staff->insertNote(note1->index() + 1, Tnote(note, r1), readOnly);
+          fixStemDirection(note2);
+          if (!note1->note()->isRest())
+            note1->tieWithNext();
+      } else
+          qDebug() << debug() << "Can't resolve duration of " << dur;
+  } else
+      qDebug() << debug() << "Can't resolve duration" << dur << "and split it!";
+}
+
+
+void TscoreMeasure::fixStemDirection(TscoreNote* sn) {
+  sn->note()->rtm.setStemDown(sn->notePos() <= 18);
+}
+
+
+void TscoreMeasure::copyRhythmParams(TscoreNote* sn, const Trhythm& r) {
+  sn->note()->rtm.setTie(r.tie());
+  sn->note()->rtm.setStemDown(r.stemDown());
+}
+
+
+/**
+ * Restores ties.
+ * It always ties @p thisNote with the next one (if the same)
+ * and depends on @p tieCopy, adds ties to previous note and to the next one
+ */
+void TscoreMeasure::restoreTie(quint8 tieCopy, TscoreNote* thisNote) {
+  qDebug() << debug() << "restoring tie of" << thisNote->note()->toText() << thisNote->note()->rtm.string();
+  thisNote->tieWithNext();
+  auto prevNote = thisNote->prevNote();
+  auto nextNote = thisNote->nextNote();
+    if (tieCopy == Trhythm::e_tieCont) {
+        prevNote->tieWithNext();
+        nextNote->tieWithNext();
+    } else if (tieCopy == Trhythm::e_tieEnd)
+        prevNote->tieWithNext();
+    else // tie started
+        nextNote->tieWithNext();
+}
+
diff --git a/src/libs/score/tscoremeasure.h b/src/libs/score/tscoremeasure.h
new file mode 100644
index 0000000000000000000000000000000000000000..b5d456adfd48e729f20b37bc1b9d0bb43fa21cd4
--- /dev/null
+++ b/src/libs/score/tscoremeasure.h
@@ -0,0 +1,234 @@
+/***************************************************************************
+ *   Copyright (C) 2016 by Tomasz Bojczuk                                  *
+ *   seelook@gmail.com                                                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 3 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+
+#ifndef TSCOREMEASURE_H
+#define TSCOREMEASURE_H
+
+#include <nootkacoreglobal.h>
+#include <QtCore/qobject.h>
+
+
+class TscoreMeter;
+class TscoreStaff;
+class TscoreNote;
+class TscoreBeam;
+class QGraphicsLineItem;
+class Tmeter;
+class Tnote;
+class Trhythm;
+
+
+/**
+ * Implementation of the measure
+ */
+class NOOTKACORE_EXPORT TscoreMeasure : public QObject
+{
+
+  friend class TscoreStaff;
+
+  Q_OBJECT
+
+public:
+  explicit TscoreMeasure(TscoreStaff* staff, int nr);
+  virtual ~TscoreMeasure();
+
+  void changeMeter(const Tmeter& m);
+
+      /**
+       * Sets parent staff and parent object as well
+       */
+  void setStaff(TscoreStaff* st);
+
+  void insertNote(int id, TscoreNote* sn);
+
+      /**
+       * Inserts list of notes at the beginning of this measure.
+       * IT IS WASTING ENERGY TO ADDING WHOLE MEASURE THIS WAY!
+       * Use this method only for lists of notes shorter than measure duration
+       */
+  void prependNotes(QList<TscoreNote*>& nl);
+
+      /**
+       * Adds list of notes @p nl at the measure end.
+       * Measure has to have already space for them
+       */
+  void appendNotes(QList<TscoreNote*>& nl);
+
+      /**
+       * Removes note with index @p noteToRemove, 
+       * Asks the staff for notes from the next measure
+       * to fulfill free space
+       */
+  void removeNote(int noteToRemove);
+
+  QList<TscoreNote*>& notes() { return m_notes; }
+
+  bool isEmpty() { return m_notes.isEmpty(); }
+
+  TscoreNote* firstNote() { return m_notes.first(); }
+
+  TscoreNote* lastNote() { return m_notes.last(); }
+
+      /** Staff index of the first measure note */
+  int firstNoteId() const;
+
+      /** Staff index of the last measure note */
+  int lastNoteId() const;
+
+      /** @p TRUE when there is no more space in the measure */
+  bool isFull() const { return m_free == 0; }
+
+      /** Free 'rhythm space' remained in the measure */
+  int free() const { return m_free; }
+
+      /** Summary of notes duration starting from @p noteId to the end of measure */
+  int freeAt(int noteId) const;
+
+      /** Duration of the measure */
+  int duration() const { return m_duration; }
+
+      /** Duration of notes starting from measure begin until @p noteId  */
+  int durationAt(int noteId) const;
+
+  Tmeter* meter() const;
+  TscoreMeter* scoreMeter() const;
+
+      /**
+       * Measure index - number in current staff
+       * Starts from 0 in every staff.
+       */
+  int id() const { return m_id; }
+
+      /**
+       * Width of all notes in this measure.
+       * Difference between last note position with its rhythm gap
+       * and X coordinate of the first note
+       */
+  qreal notesWidth();
+
+      /** Prints debug message with [nr MEASURE] */
+  char debug();
+
+      /**
+       * Returns summary duration of notes in the list.
+       */
+  static int groupDuration(const QList<TscoreNote*>& notes);
+
+
+signals:
+
+      /**
+       * Emitted when measure was changed and re-beamed.
+       * TscoreNote parameter is a note that invoked change (or 0 if new one was added)
+       * so all other beam groups that don't contain this note has to be updated
+       */
+  void updateBeams(TscoreNote*);
+
+
+protected:
+
+      /**
+       * Returns first @c TscoreNote in given rhythmic group @p grNr or null pointer if none
+       */
+  TscoreNote* firstInGroup(int grNr) { return m_firstInGr[grNr] >= 0 ? m_notes[m_firstInGr[grNr]] : nullptr; }
+
+  void noteChangedSlot(TscoreNote* sn);
+
+      /** Only class TscoreStaff can do this */
+  void setId(int id) { m_id = id; }
+
+      /**
+       * Sets beams in measure notes starting from beam group of @p firstGroup
+       * till @p endGroup  or through all groups if not set.
+       */
+  void resolveBeaming(int firstGroup, int endGroup = -1);
+
+      /** Sets appropriate @p setRhythmGroup of every note in the measure. */
+  void updateRhythmicGroups();
+
+      /**
+       * Takes @p dur (duration) of notes at the measure end
+       * and creates a list of notes @p notesToOut to shift to the next measure.
+       * Also, if the last note has to be split
+       * - into @p newNote is put Tnote to be shifted at next measure beginning
+       * and tied with the last note of this measure.
+       * @p endNote is note number till taking out is performed (by default 0 - whole measure)
+       * Returned value is remaining duration.
+       */
+  int releaseAtEnd(int dur, QList<TscoreNote*>& notesToOut, Tnote& newNote, int endNote = 0);
+
+      /**
+       * Takes @p dur (duration) of notes at the measure beginning
+       * and packs them into @p notesToOut list.
+       */
+  int takeAtStart(int dur, QList<TscoreNote*>& notesToOut);
+
+      /** Checks to display or hide the bar line */
+  void checkBarLine();
+
+private:
+
+      /**
+       * Adds @p newNote with index +1 than the last note
+       * by invoking @p TscoreStaff::insertNote() 
+       */
+  void addNewNote(Tnote& newNote);
+
+      /**
+       * Common routine that performs:
+       * - shifting @p notesToOut to the next measure (if not empty)
+       * and creating new, tied note @p newNote at the beginning of the next measure 
+       */
+  void shiftReleased(QList<TscoreNote*>& notesToOut, Tnote& newNote);
+
+      /**
+       * Common method calling the staff for notes from the next measure
+       * to fill this one. @p m_free has to be updated before.
+       */
+  void fill();
+
+      /**
+       * Splits given note into two (using @p Trhythm::split()).
+       * It adds that second note to the staff and this measure
+       * and ties with given @p sn note
+       */
+  void split(TscoreNote* sn);
+
+      /** Splits given duration @p dur into two notes of @p note and adds them to the staff at @p id */
+  void splitThenInsert(int dur, int id, const Tnote& note, bool readOnly);
+
+  void fixStemDirection(TscoreNote* sn);
+
+      /** Restores ties of @p thisNote by given @p tieCopy value of @p Trhythm::Etie*/
+  void restoreTie(quint8 tieCopy, TscoreNote* thisNote);
+
+  void copyRhythmParams(TscoreNote* sn, const Trhythm& r);
+
+private:
+  int                      m_duration;
+  int                      m_id;
+  int                      m_free;
+  TscoreStaff             *m_staff; /**< Parent staff */
+  QList<TscoreNote*>       m_notes;
+  QList<TscoreBeam*>       m_beams;
+  QGraphicsLineItem       *m_barLine;
+  qint8                   *m_firstInGr; /**< quint8 is sufficient - measure never has more than 127 notes */
+};
+
+
+#endif // TSCOREMEASURE_H
diff --git a/src/libs/score/tscoremeter.cpp b/src/libs/score/tscoremeter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3be31ccf32d04aca97989070001cfadb4bdfe2f1
--- /dev/null
+++ b/src/libs/score/tscoremeter.cpp
@@ -0,0 +1,144 @@
+/***************************************************************************
+ *   Copyright (C) 2016-2017 by Tomasz Bojczuk                             *
+ *   seelook@gmail.com                                                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 3 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+
+#include "tscoremeter.h"
+#include "tscorestaff.h"
+// #include "graphics/tnotepixmap.h"
+#include <tnoofont.h>
+#include <music/tmeter.h>
+// #include <widgets/tpushbutton.h>
+#include <QtWidgets/QtWidgets>
+
+
+#define METRUM_HEIGHT (8.0)
+
+
+TscoreMeter::TscoreMeter(TscoreScene* scene, TscoreStaff* staff) :
+  TscoreItem(scene),
+  m_meter(new Tmeter(Tmeter::e_4_4)),
+  m_isReadOnly(false),
+  m_pianoStaff(false),
+  m_width(4.0)
+{
+  setStaff(staff);
+  setParentItem(staff);
+  setStatusTip(tr("Time signature"));
+}
+
+
+TscoreMeter::~TscoreMeter()
+{
+  delete m_meter;
+}
+
+
+void TscoreMeter::setMeter(const Tmeter& meter, bool emitSignal) {
+  *m_meter = meter;
+  m_upperDigit = TnooFont::digit(m_meter->upper());
+  m_lowerDigit = TnooFont::digit(m_meter->lower());
+  QFontMetrics fm(TnooFont(8));
+  m_width = fm.boundingRect(m_upperDigit).width();
+  update();
+
+// set notes grouping
+  m_groups.clear();
+  if (m_meter->lower() == 4) { // simple grouping: one group for each quarter
+    m_groups << 24 << 48; // 2/4 and above
+    if (m_meter->meter() > Tmeter::e_2_4)
+      m_groups << 72;
+    if (m_meter->meter() > Tmeter::e_3_4)
+      m_groups << 96;
+    if (m_meter->meter() > Tmeter::e_4_4)
+      m_groups << 120;
+    if (m_meter->meter() > Tmeter::e_5_4)
+      m_groups << 144;
+    if (m_meter->meter() > Tmeter::e_6_4)
+      m_groups << 168;
+  } else {
+    if (m_meter->meter() == Tmeter::e_3_8)
+      m_groups << 36;
+    else if (m_meter->meter() == Tmeter::e_5_8)
+      m_groups << 36 << 60;
+    else if (m_meter->meter() == Tmeter::e_6_8)
+      m_groups << 36 << 72;
+    else if (m_meter->meter() == Tmeter::e_7_8)
+      m_groups << 36 << 60 << 84;
+    else if (m_meter->meter() == Tmeter::e_9_8)
+      m_groups << 36 << 72 << 108;
+    else if (m_meter->meter() == Tmeter::e_12_8)
+      m_groups << 36 << 72 << 108 << 144;
+  }
+
+  updateOptGap();
+
+  if (emitSignal)
+    emit meterChanged();
+}
+
+
+void TscoreMeter::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
+  Q_UNUSED(option)
+  Q_UNUSED(widget)
+//   paintBackground(painter, Qt::yellow);
+  painter->setPen(qApp->palette().text().color());
+  painter->setFont(TnooFont(8));
+  painter->drawText(0, 0, m_width, 4.0, Qt::AlignCenter, m_upperDigit);
+  painter->drawText(0, 4, m_width, 4.0, Qt::AlignCenter, m_lowerDigit);
+  if (m_pianoStaff) {
+    painter->drawText(0, 14, m_width, 4.0, Qt::AlignCenter, m_upperDigit);
+    painter->drawText(0, 18, m_width, 4.0, Qt::AlignCenter, m_lowerDigit);
+  }
+}
+
+
+QRectF TscoreMeter::boundingRect() const {
+  return QRectF(0.0, 0.0, m_width, m_pianoStaff ? 22.0 : 8.0);
+}
+
+//#################################################################################################
+//###################              PROTECTED           ############################################
+//#################################################################################################
+
+void TscoreMeter::updateOptGap() {
+  if (m_meter->lower() == 4) {
+      m_optGap = m_meter->upper() * 2.0; // simple multiply number of quarters by gap for quarter (see TscoreNote)
+  } else {
+      if (m_meter->meter() == Tmeter::e_3_8)
+        m_optGap = 2.5; // quarter with dot
+      else if (m_meter->meter() == Tmeter::e_5_8)
+        m_optGap = 2.5 + 2.0; // quarter with dot and quarter
+      if (m_meter->meter() == Tmeter::e_6_8)
+        m_optGap = 2.0 * 2.5; // two quarters with dot
+      if (m_meter->meter() == Tmeter::e_7_8)
+        m_optGap = 2.5 + 2.0 * 2.0; // quarter with dot and two quarters
+      if (m_meter->meter() == Tmeter::e_9_8)
+        m_optGap = 3.0 * 2.5; // three quarters with dot
+      if (m_meter->meter() == Tmeter::e_12_8)
+        m_optGap = 4.0 * 2.5; // four quarters with dot
+  }
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/libs/score/tscoremeter.h b/src/libs/score/tscoremeter.h
new file mode 100644
index 0000000000000000000000000000000000000000..a19aa8a4aecd05a1df8fc9768ba73ee8c6e10020
--- /dev/null
+++ b/src/libs/score/tscoremeter.h
@@ -0,0 +1,98 @@
+/***************************************************************************
+ *   Copyright (C) 2016 by Tomasz Bojczuk                                  *
+ *   seelook@gmail.com                                                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 3 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+
+#ifndef TSCOREMETER_H
+#define TSCOREMETER_H
+
+
+#include "nootkacoreglobal.h"
+#include "tscoreitem.h"
+
+
+class Tmeter;
+
+
+#define MIN_GAP (1.0) /**< Minimal distance between notes of the shortest duration in a staff */
+
+
+/**
+ * Graphical representation of time signature on a staff (first one)
+ */
+class NOOTKACORE_EXPORT TscoreMeter : public TscoreItem
+{
+
+  Q_OBJECT
+
+public:
+  TscoreMeter(TscoreScene* scene, TscoreStaff* staff);
+  virtual ~TscoreMeter();
+
+  void setMeter(const Tmeter& meter, bool emitSignal = true);
+  Tmeter* meter() const { return m_meter; }
+
+  void setReadOnly(bool readOnly) { m_isReadOnly = readOnly; }
+  bool isReadOnly() { return m_isReadOnly; }
+
+      /** This is only way to inform const boundingRect about staff type changed */
+  void setPianoStaff(bool piano) { m_pianoStaff = piano; }
+  bool isPianoStaff() { return m_pianoStaff; }
+
+      /**
+       * Returns duration of given @p grNr group starting from measure beginning
+       * Describes grouping (beaming - beam connections) of notes in a single measure for current meter.
+       * This is a group of a few int values - each representing duration of the one group:
+       * - for 3/8 it is only single 36 value - whole measure under one beam
+       * - for 3/4 it is 24, 48, 72) - three groups
+       */
+  quint8 groupPos(int grNr) { return m_groups[grNr]; }
+
+      /** Number of beaming groups for this meter  */
+  int groupCount() { return m_groups.count(); }
+
+  virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
+  virtual QRectF boundingRect() const;
+
+  qreal width() { return m_width; }
+
+      /**
+       * @p optimalGap is summary of note gaps for
+       * optimal measure content, i.e.:
+       * 2/4  is | 4 4 | so two gaps of quarter note
+       * 5/8  is | 4. 4 | so gap of quarter with dot and just quarter
+       * 12/8 is | 4. 4. 4. 4. | so four gaps of quarter and dot
+       * It is used to determine has a staff space for a new measure
+       */
+  qreal optimalGap() { return m_optGap; }
+
+signals:
+  void meterChanged();
+
+private:
+  void updateOptGap();
+
+private:
+  Tmeter           *m_meter;
+  bool              m_isReadOnly, m_pianoStaff;
+  QString           m_upperDigit, m_lowerDigit;
+  qreal             m_width;
+  QList<quint8>     m_groups;
+  qreal             m_optGap;
+};
+
+
+#endif // TSCOREMETER_H
diff --git a/src/libs/score/tscorenote.cpp b/src/libs/score/tscorenote.cpp
index ee23f2018b7dee2c24c5ff2ab8d23f7605b02d86..a276ba1fb6c32d0362d22dd6129e0c8a838483de 100644
--- a/src/libs/score/tscorenote.cpp
+++ b/src/libs/score/tscorenote.cpp
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2013-2016 by Tomasz Bojczuk                             *
+ *   Copyright (C) 2013-2017 by Tomasz Bojczuk                             *
  *   seelook@gmail.com                                                     *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -21,9 +21,10 @@
 #include "tscorescene.h"
 #include "tscorestaff.h"
 #include "tnotecontrol.h"
+#include "tscorebeam.h"
+#include "tscoretie.h"
+#include "tscorelines.h"
 #include <graphics/tdropshadoweffect.h>
-#include <animations/tcrossfadetextanim.h>
-#include <animations/tcombinedanim.h>
 #include <music/tnote.h>
 #include <tnoofont.h>
 #include <QtCore/qeasingcurve.h>
@@ -37,10 +38,18 @@
 
 #include <QtCore/qdebug.h>
 
+
 #define SHORT_TAP_TIME (150) // 150 ms takes short tap - otherwise note is edited
+#define REST_Y (19.0)
+
 
+static const int accCharTable[6] = { 0xe123, 0xe11a, 0x20, 0xe10e, 0xe125, 0xe116 };
 
-const int accCharTable[6] = { 0xe123, 0xe11a, 0x20, 0xe10e, 0xe125, 0xe116 };
+char d(TscoreNote* sn) {
+  QTextStream o(stdout);
+  o << "   \033[01;29m[" << sn->index() << " NOTE]\033[01;00m";
+  return 32; // fake
+}
 
 /*static*/
 QString TscoreNote::getAccid(int accNr) {
@@ -48,20 +57,29 @@ QString TscoreNote::getAccid(int accNr) {
 }
 
 
-QGraphicsEllipseItem* TscoreNote::createNoteHead(QGraphicsItem* parentIt) {
-  QGraphicsEllipseItem *noteHead = new QGraphicsEllipseItem();
-	noteHead->setParentItem(parentIt);
-  noteHead->setRect(0, 0, 3.5, 2);
-  noteHead->hide();
-  return noteHead;
-}
-
-
 /** To avoid creating many tips - each one for every instance and waste RAM
- * this text exist as static variable 
+ * this text exist as static variable
  * and TscoreNote manages itself when status tip is necessary to be displayed. */
 QString TscoreNote::m_staticTip = QString();
-QString m_selectedTip = QString();
+QString TscoreNote::m_selectedTip = QString();
+
+const qreal TscoreNote::m_rtmGapArray[5][3] = {
+//  | bare | dot | triplet |
+    { 5.0,   6.0,   4.5}, // whole note
+    { 4.0,   5.0,   3.3}, // half note
+    { 2.0,   2.5,   1.3}, // quarter note
+    { 1.0,   1.5,   0.3}, // eighth note
+    { 0.15,  0.5,   0.0}  // sixteenth note
+};
+
+
+qreal TscoreNote::space(const Trhythm& r) {
+  if (r.rhythm() == Trhythm::e_none)
+    return 0.0;
+
+  int add = r.hasDot() ? 1 : (r.isTriplet() ? 2 : 0);
+  return m_rtmGapArray[static_cast<int>(r.rhythm()) - 1][add];
+}
 
 
 //#################################################################################################
@@ -70,77 +88,89 @@ QString m_selectedTip = QString();
 
 TscoreNote::TscoreNote(TscoreScene* scene, TscoreStaff* staff, int index) :
   TscoreItem(scene),
-  m_mainPosY(0.0),
-  m_accidental(0),
+  m_mainPosY(0.0), m_newPosY(0),
+  m_accidental(0), m_newAccid(0),
   m_index(index),
-  m_stringNr(0), m_stringText(nullptr),
+  m_stringNr(0), m_stringText(0),
   m_readOnly(false), m_emptyLinesVisible(true),
   m_nameText(0),
   m_ottava(0),
   m_bgColor(-1),
-  m_noteAnim(nullptr), m_popUpAnim(nullptr),
   m_selected(false),
   m_touchedToMove(false), m_wasTouched(false)
 {
   setStaff(staff);
-	setParentItem(staff);
+  setParentItem(staff);
+  setFlag(QGraphicsItem::ItemHasNoContents);
   m_height = staff->height();
+  m_width = scene->isRhythmEnabled() ? 4.0 : 7.0;
+//   m_width = 7.0;
   m_mainColor = qApp->palette().text().color();
-	m_note = new Tnote(0, 0, 0);
+  m_note = new Tnote(); // empty note with no rhythm
+
+  m_lines = new TscoreLines(this);
+  m_lines->setPos(0.6, 0.0);
+  m_mainNote = new TnoteItem(scoreScene(), Trhythm(Trhythm::e_none));
+  m_mainNote->setParentItem(this);
+  m_mainNote->hide();
+  m_mainNote->setX(3.0);
 
-	m_lines = new TscoreLines(this);
-  m_mainNote = createNoteHead(this);
-	
   m_mainAccid = new QGraphicsSimpleTextItem();
-	m_mainAccid->setParentItem(m_mainNote);
-	
+  m_mainAccid->setParentItem(m_mainNote);
+
   m_mainAccid->setFont(TnooFont(5));
-	bool prepareScale = false;
-	if (scoreScene()->accidScale() == -1.0) { // only when first TscoreNote is constructed
-			m_staticTip = 
-						tr("Click to enter a note, use horizontal scroll to change accidental.");
-		  m_selectedTip = "<br>" + tr("Right mouse button just selects a note.");
-			m_mainAccid->setText(getAccid(1));
-			scoreScene()->setAccidScale(6.0 / m_mainAccid->boundingRect().height());
-			prepareScale = true;
-	}
-	m_emptyText = new QGraphicsSimpleTextItem("n", this);
-		m_emptyText->setFont(TnooFont());
-		m_emptyText->setZValue(1);
-		QColor cc = qApp->palette().highlight().color();
-		cc.setAlpha(50);
-		m_emptyText->setBrush(cc);
-		m_emptyText->setPen(QPen(qApp->palette().highlight().color(), 0.1));
-		m_emptyText->setScale(5.5 / m_emptyText->boundingRect().width());
-		m_emptyText->setPos((7.0 - m_emptyText->boundingRect().width() * m_emptyText->scale()) / 2,
-												staff->upperLinePos() - 1 + (staff->isPianoStaff() ? 6 : 0));
-		m_emptyText->hide();
-		
+  bool prepareScale = false;
+  if (scoreScene()->accidScale() == -1.0) { // only when first instance of TscoreNote is constructed
+      m_staticTip = tr("Click to enter a note, use horizontal scroll to change accidental.");
+      m_selectedTip = QLatin1String("<br>") + tr("Right mouse button just selects a note.");
+      m_mainAccid->setText(getAccid(1));
+      scoreScene()->setAccidScale(6.0 / m_mainAccid->boundingRect().height());
+      prepareScale = true;
+  }
+  m_emptyText = new QGraphicsSimpleTextItem(QStringLiteral("n"), this);
+    m_emptyText->setFont(TnooFont(8));
+    m_emptyText->setZValue(1);
+    QColor cc = qApp->palette().highlight().color();
+    cc.setAlpha(50);
+    m_emptyText->setBrush(cc);
+    m_emptyText->setPen(QPen(qApp->palette().highlight().color(), 0.1));
+//     m_emptyText->setScale(m_width / m_emptyText->boundingRect().width());
+    m_emptyText->setPos((m_width - m_emptyText->boundingRect().width() * m_emptyText->scale()) / 2,
+                        staff->upperLinePos() + 1.0 + (staff->isPianoStaff() ? 6 : 0));
+    m_emptyText->hide();
+
   m_mainAccid->setScale(scoreScene()->accidScale());
-	if (prepareScale) {
-			scoreScene()->setAccidYoffset(m_mainAccid->boundingRect().height() * scoreScene()->accidScale() * 0.34);
-			m_mainAccid->setText(QString());
-	}
-	m_mainAccid->setPos(-3.0, - scoreScene()->accidYoffset());
-	
-	if (!scene->views().isEmpty() && scoreScene()->right() == 0)
-			initNoteCursor();
-	
+  if (prepareScale) {
+      scoreScene()->setAccidYoffset(m_mainAccid->boundingRect().height() * scoreScene()->accidScale() * 0.34);
+      m_mainAccid->setText(QString());
+  }
+  m_mainAccid->setPos(-2.3, - scoreScene()->accidYoffset());
+
   setColor(m_mainColor);
   m_mainNote->setZValue(34); // under
   m_mainAccid->setZValue(m_mainNote->zValue() - 1);
   if (staff->isPianoStaff())
-		setAmbitus(40, 2);
-	else
-		setAmbitus(34, 2);
-	connect(this, SIGNAL(statusTip(QString)), scene, SLOT(statusTipChanged(QString)));
+    setAmbitus(40, 2);
+  else
+    setAmbitus(34, 2);
+  connect(this, SIGNAL(statusTip(QString)), scene, SLOT(statusTipChanged(QString)));
+  setRhythmEnabled(scoreScene()->isRhythmEnabled());
   checkEmptyText();
 }
 
 
-TscoreNote::~TscoreNote() { // release work note and controls from destructing parent
-	if (scoreScene()->right() && (scoreScene()->workNote()->parentItem() == this || scoreScene()->right()->parentItem() == parentItem()))
-		scoreScene()->noteDeleted(this);
+TscoreNote::~TscoreNote() {
+  if (note()->rtm.tie() == Trhythm::e_tieEnd || note()->rtm.tie() == Trhythm::e_tieCont) {
+    auto prev = prevNote();
+    if (prev)
+      prev->tieRemove();
+  }
+  if (m_tie)
+    delete m_tie;
+
+  if (staff())
+    staff()->noteGoingDestroy(this);
+
   delete m_note;
 }
 
@@ -148,39 +178,76 @@ TscoreNote::~TscoreNote() { // release work note and controls from destructing p
 //#################### PUBLIC METHODS    #######################################
 //##############################################################################
 
+Trhythm* TscoreNote::rhythm() const {
+  return m_mainNote->rhythm();
+}
+
+
+void TscoreNote::setRhythm(const Trhythm& r) {
+//   m_mainNote->setRhythm(r);
+//   Trhythm old(m_note->rtm);
+  m_note->setRhythm(r);
+//   m_note->rtm.setTie(old.tie());
+//   m_note->rtm.setStemDown(old.stemDown());
+  update();
+}
+
+
 void TscoreNote::adjustSize() {
-	m_height = staff()->height();
-	m_lines->adjustLines(this);
-	setColor(m_mainColor);
-	if (staff()->isPianoStaff())
-		m_emptyText->setPos(m_emptyText->x(), m_emptyText->y() + 6);
-	else
-		m_emptyText->setPos(m_emptyText->x(), m_emptyText->y() - 6);
+  m_height = staff()->height();
+  m_lines->adjustLines(this);
+  setColor(m_mainColor);
+  if (staff()->isPianoStaff())
+    m_emptyText->setPos(m_emptyText->x(), m_emptyText->y() + 6);
+  else
+    m_emptyText->setPos(m_emptyText->x(), m_emptyText->y() - 6);
+}
+
+
+void TscoreNote::setRhythmEnabled(bool rhythmEnabled) {
+  if (rhythmEnabled != scoreScene()->isRhythmEnabled())
+      qDebug() << d(this) << "Note has rhythms available different than scene!";
+
+  if (rhythmEnabled) {
+//       m_emptyText->setText(QString(QChar(TnooFont::getCharFromRhythm(scoreScene()->workRhythm()->weight(), true, scoreScene()->workRhythm()->isRest()))));
+//       m_mainNote->setRhythm(Trhythm(scoreScene()->workRhythm()->rhythm(), !m_note->isValid()));
+//       if (!m_note->isValid())
+//         moveNote(15);
+  } else {
+        m_emptyText->setText(QStringLiteral("n"));
+//         m_mainNote->setRhythm(Trhythm(Trhythm::e_none));
+  }
+  changeWidth();
 }
 
 
 void TscoreNote::setColor(const QColor& color) {
-	m_mainColor = color;
-	m_mainNote->setPen(Qt::NoPen);
-	m_mainNote->setBrush(QBrush(m_mainColor, Qt::SolidPattern));
-	m_mainAccid->setBrush(QBrush(m_mainColor));
-	m_lines->setColor(color);
-	if (m_stringText)
-			m_stringText->setBrush(QBrush(m_mainColor));
+  m_mainColor = color;
+  m_mainNote->setColor(color);
+//   m_mainNote->setPen(Qt::NoPen); // TODO
+//   m_mainNote->setBrush(QBrush(m_mainColor, Qt::SolidPattern));
+  m_mainAccid->setBrush(QBrush(m_mainColor));
+  m_lines->setColor(color);
+  if (m_stringText)
+      m_stringText->setBrush(QBrush(m_mainColor));
 }
 
 
 void TscoreNote::selectNote(bool sel) {
-	m_selected = sel;
-	checkEmptyText();
+  m_selected = sel;
+  checkEmptyText();
 }
 
 
 void TscoreNote::moveNote(int posY) {
-// 		if (posY == 0 || !(posY >= m_ambitMax - 1 && posY <= m_ambitMin)) {
+//     if (posY == 0 || !(posY >= m_ambitMax - 1 && posY <= m_ambitMin)) {
   bool theSame = (posY == m_mainPosY);
   if (posY == 0 || !(posY >= 1 && posY <= m_height - 3)) {
-      hideNote();
+      if (m_mainNote->rhythm()->isRest()) {
+          m_mainNote->setY(REST_Y);
+          m_mainNote->show();
+      } else
+          hideNote();
       m_mainAccid->setText(QString());
       m_accidental = 0;
       return;
@@ -189,12 +256,12 @@ void TscoreNote::moveNote(int posY) {
       m_mainNote->show();
       m_mainAccid->show();
   }
-  if (m_noteAnim) { // initialize animation
-      m_noteAnim->setMoving(m_mainNote->pos(), QPointF(3.0, posY));
-      m_noteAnim->startAnimations();
-  } else { // just move a note
-    m_mainNote->setPos(3.0, posY);
-  }
+
+  if (note()->isRest())
+      m_mainNote->setY(REST_Y);
+  else if (posY != static_cast<int>(m_mainNote->y()))
+      m_mainNote->setY(posY);
+
   m_mainPosY = posY;
   int noteNr = (56 + staff()->notePosRelatedToClef(staff()->fixNotePos(posY))) % 7;
   QString newAccid = getAccid(m_accidental);
@@ -202,12 +269,8 @@ void TscoreNote::moveNote(int posY) {
     if (m_accidental == 0) {
         newAccid = getAccid(3); // neutral
         m_mainAccid->hide();
-        if (scoreScene()->isAccidAnimated() && !isReadOnly() && !theSame)
-            emit fromKeyAnim(newAccid, m_mainAccid->scenePos(), m_mainPosY);
     } else {
         if (staff()->accidInKeyArray[noteNr] == m_accidental) {
-          if (scoreScene()->isAccidAnimated() && !isReadOnly() && !theSame)
-              emit toKeyAnim(newAccid, m_mainAccid->scenePos(), m_mainPosY);
           if (staff()->extraAccids()) // accidental from key signature in braces
             newAccid = QString(QChar(accCharTable[m_accidental + 2] + 1));
           else
@@ -226,101 +289,124 @@ void TscoreNote::moveNote(int posY) {
     }
   }
   m_mainAccid->show();
-  if (m_noteAnim)
-    m_accidAnim->startCrossFading(newAccid, m_mainColor);
-  else
-    m_mainAccid->setText(newAccid);
-
+  m_mainAccid->setText(newAccid);
   setStringPos();
   m_lines->checkLines(posY);
-	checkEmptyText();
+  checkEmptyText();
 }
 
 
 void TscoreNote::setNote(int notePos, int accNr, const Tnote& n) {
-	m_accidental = accNr;
-	*m_note = n;
-	moveNote(notePos);
-	if (m_mainPosY == 0)
-			*m_note = Tnote(); // set note to null if beyond the score possibilities
-	if (m_nameText)
-			showNoteName();
+  m_accidental = accNr;
+  *m_note = n;
+  m_mainNote->setRhythm(Trhythm(n.rhythm(), notePos == 0, n.hasDot(), n.isTriplet()));
+  moveNote(notePos);
+  if (m_mainPosY == 0) {
+    m_note->note = 0;
+    m_note->alter = 0;
+//     m_mainNote->setY(REST_Y);
+  }
+//   if (m_note->rhythm() != Trhythm::e_none)
+//     setRhythm(Trhythm(n.rhythm(), m_mainPosY == 0, n.hasDot(), n.isTriplet()));
+  changeWidth();
+  if (m_nameText)
+    showNoteName();
   checkEmptyText();
-	update();
+  update();
 }
 
 
 void TscoreNote::hideNote() {
-	m_mainNote->hide();
-	m_mainAccid->hide();
-	m_lines->hideAllLines();
-	m_mainPosY = 0;
-	m_accidental = 0;
-	m_mainNote->setPos(3.0, 0);
+  m_mainNote->hide();
+  m_mainAccid->hide();
+  m_lines->hideAllLines();
+  m_mainPosY = 0;
+  m_accidental = 0;
+  m_mainNote->setY(0);
 }
 
 
 void TscoreNote::moveWorkNote(const QPointF& newPos) {
-	QGraphicsSceneHoverEvent moveEvent(QEvent::GraphicsSceneHoverMove);
-	moveEvent.setPos(newPos);
-	hoverMoveEvent(&moveEvent);
-}
-
-
-void TscoreNote::hideWorkNote() {
-  m_touchedToMove = false;
-	if (scoreScene()->workNote() && scoreScene()->workNote()->isVisible()) {
-    scoreScene()->workNote()->hide();
-    scoreScene()->workLines()->hideAllLines();
-    scoreScene()->setWorkPosY(0);
-	}
-	if (touchEnabled()) {
-    checkEmptyText();
-    update();
-  }
+  QGraphicsSceneHoverEvent moveEvent(QEvent::GraphicsSceneHoverMove);
+  moveEvent.setPos(newPos);
+  hoverMoveEvent(&moveEvent);
 }
 
 
 void TscoreNote::markNote(QColor blurColor) {
-	if (blurColor == -1) {
-		m_mainNote->setPen(Qt::NoPen);
-		m_mainNote->setGraphicsEffect(0);
-	} else {
-		m_mainNote->setPen(QPen(blurColor, 0.2));
-		QGraphicsDropShadowEffect *bluredPen = new QGraphicsDropShadowEffect();
-		bluredPen->setBlurRadius(10);
-		bluredPen->setColor(QColor(blurColor.name()));
-		bluredPen->setOffset(0.5, 0.5);
-		m_mainNote->setGraphicsEffect(bluredPen /*TdropShadowEffect(blurColor)*/);
-	}
-	update();
+  if (blurColor == -1) {
+//     m_mainNote->setPen(Qt::NoPen); TODO: check it
+    m_mainNote->setGraphicsEffect(0);
+  } else {
+//     m_mainNote->setPen(QPen(blurColor, 0.2));
+    QGraphicsDropShadowEffect *bluredPen = new QGraphicsDropShadowEffect();
+    bluredPen->setBlurRadius(10);
+    bluredPen->setColor(QColor(blurColor.name()));
+    bluredPen->setOffset(0.5, 0.5);
+    m_mainNote->setGraphicsEffect(bluredPen /*TdropShadowEffect(blurColor)*/);
+  }
+  update();
+}
+
+
+TscoreNote* TscoreNote::nextNote() {
+  TscoreNote* next = nullptr; // find next note first
+  if (this == staff()->lastNote()) { // take first note from the next staff
+      auto st = staff()->nextStaff();
+      if (st)
+        next = st->firstNote();
+  } else // or just next one
+      next = staff()->noteSegment(index() + 1);
+  return next;
+}
+
+
+TscoreNote* TscoreNote::prevNote() {
+  if (staff()->count()) {
+      TscoreNote* prev = nullptr; // find next note first
+      if (this == staff()->firstNote()) { // take first note from the next staff
+          auto st = staff()->prevStaff();
+          if (st)
+            prev = st->lastNote();
+      } else // or just next one
+          prev = staff()->noteSegment(index() - 1);
+      return prev;
+  }
+  return nullptr;
+}
+
+
+qreal TscoreNote::space() {
+  return space(note()->rtm);
+}
+
+
+QGraphicsLineItem* TscoreNote::stem() {
+  return m_mainNote->stem();
 }
 
 
 void TscoreNote::setString(int realNr) {
-  if (realNr < 7) {
-      if (!m_stringText) {
+  if (!m_stringText) {
         m_stringText = new QGraphicsSimpleTextItem();
         m_stringText->setFont(TnooFont(5));
         m_stringText->setBrush(QBrush(m_mainColor));
         m_stringText->setParentItem(this);
         m_stringText->setZValue(-1);
-      }
-      m_stringText->setText(QString("%1").arg(realNr));
-      m_stringText->setScale(5.0 / m_stringText->boundingRect().width());
-      m_stringNr = realNr;
-      setStringPos();
-  } else
-      removeString();
+    }
+    m_stringText->setText(QString("%1").arg(realNr));
+    m_stringText->setScale(5.0 / m_stringText->boundingRect().width());
+    m_stringNr = realNr;
+    setStringPos();
 }
 
 
 void TscoreNote::removeString() {
-  if (m_stringText) {
-      delete m_stringText;
-      m_stringText = nullptr;
-  }
-  m_stringNr = 0;
+    if (m_stringText) {
+        delete m_stringText;
+        m_stringText = 0;
+    }
+    m_stringNr = 0;
 }
 
 
@@ -329,357 +415,364 @@ void TscoreNote::setReadOnly(bool ro) {
   m_readOnly = ro;
   m_emptyLinesVisible = !ro;
   checkEmptyText();
-  update();
 }
 
-
-/** If @p dropShadowColor is not set and @p m_nameText has already existed,
+/** If @dropShadowColor is not set and m_nameText has already existed,
  * previously color remained. */
 void TscoreNote::showNoteName(const QColor& dropShadowColor) {
-	bool setColor = false;
-	if (!m_nameText) {
-		m_nameText = new QGraphicsTextItem();
-		m_nameText->setDefaultTextColor(m_mainColor);
-		m_nameText->setParentItem(this);
-		m_nameText->setZValue(10);
-		m_nameText->setAcceptHoverEvents(false);
-		setColor = true;
-	}
-	if (dropShadowColor != -1)
-		setColor = true;
-	if (setColor) {
-		QGraphicsDropShadowEffect *dropEff = new QGraphicsDropShadowEffect();
-		if (dropShadowColor == -1)
-			dropEff->setColor(scoreScene()->nameColor());
-		else
-			dropEff->setColor(dropShadowColor);
-		dropEff->setOffset(0.7, 0.7);
-		dropEff->setBlurRadius(5.0);
-		m_nameText->setGraphicsEffect(dropEff);
-	}
-	if (m_note->note) {
-			m_nameText->setHtml(m_note->toRichText());
-			m_nameText->setScale(8.0 / m_nameText->boundingRect().height());
-			if (m_nameText->boundingRect().width() * m_nameText->scale() > boundingRect().width())
-					m_nameText->setScale(boundingRect().width() / (m_nameText->boundingRect().width()));
-			m_nameText->setPos((8.0 - m_nameText->boundingRect().width() * m_nameText->scale()) * 0.75, /*yy);*/
-							notePos() > staff()->upperLinePos() ? 
-										notePos() - (m_nameText->boundingRect().height() + 2.0) * m_nameText->scale(): // above note
-										notePos() + m_mainNote->boundingRect().height()); // below note
-			m_nameText->show();
-	} else
-			m_nameText->hide();
+  bool setColor = false;
+  if (!m_nameText) {
+    m_nameText = new QGraphicsTextItem();
+    m_nameText->setDefaultTextColor(m_mainColor);
+    m_nameText->setParentItem(this);
+    m_nameText->setZValue(10);
+    m_nameText->setAcceptHoverEvents(false);
+    setColor = true;
+  }
+  if (dropShadowColor != -1)
+    setColor = true;
+  if (setColor) {
+    QGraphicsDropShadowEffect *dropEff = new QGraphicsDropShadowEffect();
+    if (dropShadowColor == -1)
+      dropEff->setColor(scoreScene()->nameColor());
+    else
+      dropEff->setColor(dropShadowColor);
+    dropEff->setOffset(0.7, 0.7);
+    dropEff->setBlurRadius(5.0);
+    m_nameText->setGraphicsEffect(dropEff);
+  }
+  if (m_note->note) {
+      m_nameText->setHtml(m_note->toRichText());
+      m_nameText->setScale(8.0 / m_nameText->boundingRect().height());
+      if (m_nameText->boundingRect().width() * m_nameText->scale() > boundingRect().width())
+          m_nameText->setScale(boundingRect().width() / (m_nameText->boundingRect().width()));
+      m_nameText->setPos((8.0 - m_nameText->boundingRect().width() * m_nameText->scale()) * 0.75, /*yy);*/
+              notePos() > staff()->upperLinePos() ?
+                    notePos() - (m_nameText->boundingRect().height() + 2.0) * m_nameText->scale(): // above note
+                    notePos() + m_mainNote->boundingRect().height()); // below note
+      m_nameText->show();
+  } else
+      m_nameText->hide();
 }
 
 
 void TscoreNote::removeNoteName() {
-	delete m_nameText;
-	m_nameText = nullptr;
+  delete m_nameText;
+  m_nameText = 0;
 }
 
 
-void TscoreNote::enableNoteAnim(bool enable, int duration) {
-	if (enable) {
-			if (!m_noteAnim) {
-					m_noteAnim = new TcombinedAnim(m_mainNote, this);
-					m_noteAnim->setDuration(duration);
-					m_noteAnim->setMoving(mainNote()->pos(), mainNote()->pos());
-					m_noteAnim->moving()->setEasingCurveType(QEasingCurve::InExpo);
-					m_noteAnim->setScaling(1.0, 1.5);
-					m_noteAnim->scaling()->setEasingCurveType(QEasingCurve::OutQuint);
-					m_accidAnim = new TcrossFadeTextAnim(m_mainAccid, this);
-			}
-			m_accidAnim->setDuration(duration);
-	} else {
-			if (m_noteAnim) {
-				delete m_noteAnim;
-				m_noteAnim = nullptr;
-				delete m_accidAnim;
-				m_accidAnim = nullptr;
-			}
-	}
+void TscoreNote::setAmbitus(int lo, int hi) {
+  m_ambitMin = qBound(2, lo, (int)m_height - 3);
+  m_ambitMax = qBound(2, hi, (int)m_height - 3);
 }
 
 
-void TscoreNote::setAmbitus(int lo, int hi) { 
-	m_ambitMin = qBound(2, lo, (int)m_height - 1); 
-	m_ambitMax = qBound(2, hi, (int)m_height - 1);
+      /** When note duration is longer than shortest rhythm in current staff
+       *  a space (gap) is added to visually represent note duration as a space between notes */
+qreal TscoreNote::rightX() {
+//   int dur = m_mainNote->rhythm()->duration();
+  return x() + m_width + staff()->gapFactor() * space(note()->rtm);
+//   return x() + m_width + (dur > staff()->shortestRhythm() ? staff()->gapFactor() * (((dur / staff()->shortestRhythm()) - 1.0)) : 0.0);
 }
 
 
-QRectF TscoreNote::boundingRect() const{
-    return QRectF(0, 0, 7.0, m_height);
+void TscoreNote::update() {
+//   if (note()->rtm != *m_mainNote->rhythm())
+//   qDebug() << d(this) << "UPDATE";
+  m_mainNote->setRhythm(note()->rtm);
+  QGraphicsItem::update();
 }
 
 
 void TscoreNote::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
-	if (m_bgColor != -1) {
-// 			paintBackground(painter, m_bgColor);
-		QPointF center(3.5, m_mainPosY + 1.0);
-		if (m_mainPosY == 0)
-			center.setY(staff()->upperLinePos() + 4.0);
-		QRadialGradient gr(center, 10.0);
-		QColor c1 = m_bgColor;
-		c1.setAlpha(40);
-		QColor c2 = m_bgColor;
-		c2.setAlpha(80);
-		gr.setColorAt(0.0, c1);
-		gr.setColorAt(0.9, c1);
-		gr.setColorAt(0.95, c2);
-		gr.setColorAt(1.0, Qt::transparent);
-		painter->setBrush(gr);
-		painter->setPen(Qt::NoPen);
-		painter->drawRect(0.0, qMax(center.y() - 10.0, 0.0), 7.0, qMin(center.y() + 10.0, m_height));
-	}
-	if (scoreScene()->currentNote() == this && m_touchedToMove) {
+  Q_UNUSED(option)
+  Q_UNUSED(widget)
+//     paintBackground(painter, Qt::yellow);
+  if (m_bgColor != -1) {
+//       paintBackground(painter, m_bgColor);
+    QPointF center(m_width / 2.0, m_mainPosY + 1.0);
+    if (m_mainPosY == 0)
+      center.setY(staff()->upperLinePos() + 4.0);
+    QRadialGradient gr(center, 10.0);
+    QColor c1 = m_bgColor;
+    c1.setAlpha(40);
+    QColor c2 = m_bgColor;
+    c2.setAlpha(80);
+    gr.setColorAt(0.0, c1);
+    gr.setColorAt(0.9, c1);
+    gr.setColorAt(0.95, c2);
+    gr.setColorAt(1.0, Qt::transparent);
+    painter->setBrush(gr);
     painter->setPen(Qt::NoPen);
-    QColor workBg(scoreScene()->workColor);
+    painter->drawRect(0.0, qMax(center.y() - 10.0, 0.0), m_width, qMin(center.y() + 10.0, m_height));
+  }
+  // for debug - index number, tie, group number, beam
+  painter->setPen(Qt::red);
+  QFont f(qApp->font());
+  f.setPointSize(1);
+  painter->setFont(f);
+  painter->drawText(QRectF(0.0, 6.0, width(), 1.5), Qt::AlignCenter, QString::number(index()));
+  painter->drawText(QRectF(0.0, 9.0, width(), 1.5), Qt::AlignCenter,
+                    (beam() ? "B " : "") + QString::number(m_group) + (note()->rtm.stemDown() ? " \\/" : " /\\"));
+  if (note()->rtm.tie()) {
+    Trhythm::Etie t = note()->rtm.tie();
+    painter->drawText(QRectF(0.0, 7.5, width(), 1.5), Qt::AlignCenter,
+                      QString("T%1").arg(t == Trhythm::e_tieStart ? "s" : (t == Trhythm::e_tieCont ? "c" : "e")));
+  }
+
+  if (scoreScene()->currentNote() == this && m_touchedToMove) {
+    painter->setPen(Qt::NoPen);
+    QColor workBg(Qt::darkBlue);
     workBg.setAlpha(20);
     painter->setBrush(QBrush(workBg));
     painter->drawRect(boundingRect());
-	}
-  if (m_emptyLinesVisible && !m_selected && m_mainPosY == 0 && !hasCursor() && !isReadOnly()) {
-		QColor emptyNoteColor;
-		if (m_mainNote->pen().style() == Qt::NoPen)
-			emptyNoteColor = qApp->palette().highlight().color();
-		else
-			emptyNoteColor = m_mainNote->pen().color();
-		emptyNoteColor.setAlpha(120);
-		painter->setPen(QPen(emptyNoteColor, 0.4, Qt::SolidLine, Qt::RoundCap));
-		painter->drawLine(QLineF(0.5, staff()->upperLinePos() - 1.0, 6.5, staff()->upperLinePos() - 2.0));
-		qreal loLine = staff()->isPianoStaff() ? staff()->lowerLinePos() : staff()->upperLinePos();
-		painter->drawLine(QLineF(0.5, loLine + 10.0, 6.5, loLine + 9.0));
-	}
+  }
+  if (m_emptyLinesVisible && !m_selected && m_mainPosY == 0 && m_mainNote->rhythm()->rhythm() == Trhythm::e_none && !hasCursor()) {
+    QColor emptyNoteColor;
+//     if (m_mainNote->pen().style() == Qt::NoPen) // TODO: check it
+    if (!m_mainNote->graphicsEffect())
+      emptyNoteColor = qApp->palette().highlight().color();
+    else
+      emptyNoteColor = m_mainNote->color(); //m_mainNote->pen().color();
+    emptyNoteColor.setAlpha(120);
+    painter->setPen(QPen(emptyNoteColor, 0.4, Qt::SolidLine, Qt::RoundCap));
+    painter->drawLine(QLineF(0.5, staff()->upperLinePos() - 1.0, m_width - 0.5, staff()->upperLinePos() - 2.0));
+    qreal loLine = staff()->isPianoStaff() ? staff()->lowerLinePos() : staff()->upperLinePos();
+    painter->drawLine(QLineF(0.5, loLine + 10.0, m_width - 0.5, loLine + 9.0));
+  }
 }
 
 
-void TscoreNote::keyAnimFinished() {
-	if (!m_readOnly)
-			m_mainAccid->show();
+bool TscoreNote::rhythmChanged() const {
+  return *m_mainNote->rhythm() != m_note->rtm;
 }
 
 
-void TscoreNote::popUpAnim(int durTime) {
-	if (m_popUpAnim)
-		return;
-	m_popUpAnim = new TcombinedAnim(m_emptyText);
-		m_popUpAnim->setDuration(durTime);
-		m_popUpAnim->setMoving(QPointF(m_emptyText->x(), -10), m_emptyText->pos());
-	connect(m_popUpAnim, SIGNAL(finished()), this, SLOT(popUpAnimFinished()));
-	m_popUpAnim->startAnimations();
+void TscoreNote::setX(qreal x) {
+  bool xChanged = QGraphicsItem::x() != x;
+  QGraphicsItem::setX(x);
+  if (xChanged) {
+    if (m_beam && m_beam->last() == this) // when this note is the last one in a beam - update beam
+      m_beam->drawBeam();
+    if (note()->rtm.tie() == Trhythm::e_tieCont || note()->rtm.tie() == Trhythm::e_tieEnd) {
+      auto prev = prevNote();
+      if (prev->tie())
+        prev->tie()->updateLength();
+      else // TODO: delete it
+        qDebug() << d(this) << "BOOOOOOOOM! No tie in previous note of" << index();
+    }
+  }
 }
 
 
 
+void TscoreNote::setPos(const QPointF& pos) {
+  bool xChanged = QGraphicsItem::x() == pos.x();
+  QGraphicsItem::setPos(pos);
+  if (xChanged) {
+    if (m_beam && m_beam->last() == this) // when this note is the last one in a beam - update beam
+      m_beam->performBeaming();
+  }
+}
+
 //#################################################################################################
 //########################################## PROTECTED   ##########################################
 //#################################################################################################
 
-void TscoreNote::hoverEnterEvent(QGraphicsSceneHoverEvent* event) {
-// 	qDebug() << "hoverEnterEvent";
-	scoreScene()->noteEntered(this);
-	if (!isReadOnly()) {
-		emit statusTip(m_staticTip + (staff()->selectableNotes() ? m_selectedTip : QString()));
-		m_emptyText->hide();
-	}
-  TscoreItem::hoverEnterEvent(event);
-  update();
-}
-
-
-void TscoreNote::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) {
-// 	qDebug() << "hoverLeaveEvent";
-  hideWorkNote();
-	scoreScene()->noteLeaved(this);
-  TscoreItem::hoverLeaveEvent(event);
-	checkEmptyText();
-  update();
-}
-
-
-/** FIXME: disabling hover under Android removes mouse usage functionality.
- * But so far there is no possibility to test it.
- * But it solves calling this when touch only is used on real devices.
- * So far a reason of calling it is unknown... */
-void TscoreNote::hoverMoveEvent(QGraphicsSceneHoverEvent* event) {
-#if defined (Q_OS_ANDROID)
-  qDebug() << "hoverMoveEvent";
-  if (wasTouched()) // It doesn't work here
-      return;
-#else
-  if ((event->pos().y() >= m_ambitMax) && (event->pos().y() <= m_ambitMin)) {
-		if (staff()->isPianoStaff() && // dead space between staves
-			(event->pos().y() >= staff()->upperLinePos() + 10.6) && (event->pos().y() <= staff()->lowerLinePos() - 2.4)) {
-				hideWorkNote();
-				return;
-		}
-    if (event->pos().y() != scoreScene()->workPosY()) {
-			scoreScene()->noteMoved(this, event->pos().y() - 0.6);
-    }
-  }
-#endif
-}
-
 
 void TscoreNote::mousePressEvent(QGraphicsSceneMouseEvent* event) {
-	if (scoreScene()->workPosY()) { // edit mode
-		if (event->button() == Qt::LeftButton) {
-				m_accidental = scoreScene()->currentAccid();
+/*
+  if (scoreScene()->workPosY()) { // edit mode
+    if (event->button() == Qt::LeftButton) {
+        m_newAccid = scoreScene()->currentAccid();
+        m_newPosY = scoreScene()->workRhythm()->isRest() ? 0 : scoreScene()->workPosY();
+        qreal widthDiff = 0.0;
+        if (scoreScene()->isRhythmEnabled()) {
+            Trhythm::Etie oldTie = note()->rtm.tie();
+            if (note()->rtm != *scoreScene()->workRhythm()) {
+              note()->rtm.setRhythm(*scoreScene()->workRhythm());
+              qDebug() << d(this) << "rhythm changed" << rhythmChanged();
+              if (!pitchChanged() && !accidChanged()) // copy tie state
+                note()->rtm.setTie(oldTie);
+            } else {
+              note()->rtm.setStemDown(scoreScene()->workRhythm()->stemDown());
+              qDebug() << d(this) << "rhythm the same";
+            }
+            qreal newWidth = 4.0;
+            if (m_newAccid)
+              newWidth += 2.0; // when removed - width remains smaller
+            if (newWidth > m_width || newWidth < m_width) { // newWidth != m_width
+              widthDiff =  newWidth - m_width;
+              qDebug() << d(this) << "Note width differs" << m_width << newWidth << widthDiff;
+            }
+        }
+        if (pitchChanged() || rhythmChanged() || accidChanged() || widthDiff != 0.0) {
+            if ((pitchChanged() || accidChanged())) {
+              if (note()->rtm.tie()) {
+                if (note()->rtm.tie() == Trhythm::e_tieEnd || note()->rtm.tie() == Trhythm::e_tieCont) {
+                    auto prev = prevNote();
+                    if (prev)
+                      prev->tieRemove();
+                }
+                tieRemove();
+              }
+            }
+            emit noteGoingToChange(this);
+            staff()->prepareNoteChange(this);
+        }
+//         m_mainNote->setRhythm(*m_newRhythm);
+        m_accidental = m_newAccid;
         moveNote(scoreScene()->workPosY());
+        changeWidth();
+        staff()->onNoteClicked(m_index);
         emit noteWasClicked(m_index);
-				if (m_nameText)
-					showNoteName();
-				update();
+        if (m_nameText)
+          showNoteName();
+        update();
     } else if (event->button() == Qt::RightButton) {
-				if (!isReadOnly() && staff()->selectableNotes()) {
-						setBackgroundColor(qApp->palette().highlight().color());
-						emit noteWasSelected(m_index);
-						update();
-				}
+        if (!isReadOnly() && staff()->selectableNotes()) {
+            setBackgroundColor(qApp->palette().highlight().color());
+            emitNoteWasSelected();
+            update();
+        }
     }
-	} else { // read only mode
-		if (event->button() == Qt::LeftButton)
-			emit roNoteClicked(this, event->pos());
-		else if (event->button() == Qt::RightButton)
-			emit roNoteSelected(this, event->pos());
-	}
+  } else { // read only mode
+    if (event->button() == Qt::LeftButton)
+      emit roNoteClicked(this, event->pos());
+    else if (event->button() == Qt::RightButton)
+      emit roNoteSelected(this, event->pos());
+  }
+*/
 }
 
 
-void TscoreNote::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) {
-	if (scoreScene()->workPosY()) // edit mode
-		emit noteWasSelected(m_index);
-	else // read only mode
-		emit roNoteSelected(this, event->pos());
-}
 
+//##########################################################################################################
+//####################################         PRIVATE     #################################################
+//##########################################################################################################
 
-void TscoreNote::touched(const QPointF& scenePos) {
-	if (m_readOnly)
-    return;
-  m_wasTouched = true;
-  TscoreItem::touched(scenePos);
-  scoreScene()->noteEntered(this);
-  m_touchTime.start();
-  if (m_touchedToMove)
-    scoreScene()->hidePanes();
+void TscoreNote::setStringPos() {
+  if (m_stringText) {
+    qreal yy = staff()->upperLinePos() + 9.0; // below the staff
+    if (m_mainPosY > staff()->upperLinePos() + 4.0)
+        yy = staff()->upperLinePos() - 7.0; // above the staff
+    m_stringText->setPos(m_width + 0.5 - m_stringText->boundingRect().width() * m_stringText->scale(), yy);
+  }
 }
 
 
-void TscoreNote::touchMove(const QPointF& scenePos) {
-	if (m_readOnly)
-			return;
 
-  QPointF fingerPos = mapFromScene(scenePos);
-  if ((fingerPos.y() >= m_ambitMax) && (fingerPos.y() <= m_ambitMin)) {
-    if (m_touchTime.hasExpired(SHORT_TAP_TIME)) {
-      if (staff()->isPianoStaff() && // dead space between staves
-        (fingerPos.y() >= staff()->upperLinePos() + 10.6) && (fingerPos.y() <= staff()->lowerLinePos() - 2.4)) {
-          hideWorkNote();
-          return;
-      }
-      scoreScene()->noteMoved(this, fingerPos.y());
-      if (!m_touchedToMove)
-        scoreScene()->hidePanes();
-      m_touchedToMove = true;
-    }
+void TscoreNote::checkEmptyText() {
+  if (!scoreScene()->isRhythmEnabled()) {
+    if (!isReadOnly() && staff()->selectableNotes() && !m_selected && m_mainPosY == 0)
+      m_emptyText->show();
+    else
+      m_emptyText->hide();
   }
 }
 
 
-void TscoreNote::untouched(const QPointF& scenePos) {
-  if (m_readOnly) {
-    emit roNoteClicked(this, mapFromScene(scenePos));
-    return;
+qreal TscoreNote::estimateWidth(const Tnote& n) {
+  qreal w = 4.0;
+  if (n.rhythm() == Trhythm::e_none)
+    w = 7.0;
+  else {
+    if (n.alter != 0)
+      w += 2.0;
+    if (n.hasDot() || (n.rtm.weight() > 4 && n.rtm.beam() == Trhythm::e_noBeam))
+      w += 1.0;
   }
+  return w;
+}
 
-  m_wasTouched = false;
-  TscoreItem::untouched(scenePos);
-  if (scenePos.isNull()) { // touch canceled
-    hideWorkNote();
-    scoreScene()->hidePanes();
-    return;
-  }
 
-  if (m_touchTime.hasExpired(SHORT_TAP_TIME)) {
-    scoreScene()->showPanes();
-  } else {
-      if (m_touchedToMove) { // new note was selected aka clicked
-          m_touchedToMove = false;
-          QGraphicsSceneMouseEvent me(QEvent::MouseButtonPress);
-          me.setPos(QPointF(3.0, scoreScene()->workPosY())); // so far @p touchMove was not performed (SHORT_TAP_TIME not expired)
-          me.setButton(Qt::LeftButton);
-          mousePressEvent(&me);
-      } else
-          emit noteWasSelected(m_index);
-  }
-  scoreScene()->noteLeaved(this);
+void TscoreNote::emitNoteWasSelected() {
+  staff()->onNoteSelected(m_index);
+  emit noteWasSelected(m_index);
 }
 
-//##########################################################################################################
-//####################################         PRIVATE     #################################################
-//##########################################################################################################
 
-void TscoreNote::setStringPos() {
-	if (m_stringText) {
-    qreal yy = staff()->upperLinePos() + 9.0; // below the staff
-    if (m_mainPosY > staff()->upperLinePos() + 4.0)
-        yy = staff()->upperLinePos() - 7.0; // above the staff
-    m_stringText->setPos(7.5 - m_stringText->boundingRect().width() * m_stringText->scale(), yy);
-	}
+/**
+ * Note width:
+ * 4 - base (minimal) width of bare note (no accidental, no flag)
+ * 5 - eighth/sixteenth flag or a dot
+ * 6 - when note has accidental (neutral as well)
+ * 7 - an accidental and a flag or a dot (maximal width)
+ */
+void TscoreNote::changeWidth() {
+  qreal oldWidth = m_width;
+  qreal newWidth = 7.0;
+  if (scoreScene()->isRhythmEnabled()) {
+    newWidth = 4.0;
+    if (!m_mainAccid->text().isEmpty()) {
+        newWidth += 2.0;
+        m_mainNote->setX(2.5);
+        m_lines->setX(2.1);
+    } else {
+        m_mainNote->setX(0.5);
+        m_lines->setX(0.1);
+    }
+    if (m_mainNote->rhythm()->weight() > 4 && m_mainNote->rhythm()->beam() == Trhythm::e_noBeam)
+      newWidth += 1.0;
+  }
+  if (newWidth != oldWidth) {
+      qDebug() << d(this) << "Note changed width" << newWidth;
+      prepareGeometryChange();
+      m_width = newWidth;
+//       staff()->noteChangedWidth(index());
+  }
 }
 
 
-void TscoreNote::initNoteCursor() {
-  scoreScene()->initNoteCursor(this);
-	hideWorkNote();
+void TscoreNote::tieWithNext() {
+  if (!m_tie)
+    m_tie = TscoreTie::check(this);
+  else
+    qDebug() << d(this) << "has already tie";
 }
 
 
-void TscoreNote::checkEmptyText() {
-  if (!isReadOnly() && (!staff()->selectableNotes() || (staff()->selectableNotes() && !m_selected)) && m_mainPosY == 0)
-		m_emptyText->show();
-	else
-		m_emptyText->hide();
+void TscoreNote::tieRemove() {
+  if (m_tie) {
+    delete m_tie; // it will set this note tie to none
+    m_tie = nullptr;
+  }
 }
 
 
-void TscoreNote::popUpAnimFinished() {
-	m_popUpAnim->deleteLater();
-	m_popUpAnim = 0;
-}
 
 
 
 /*
 void TscoreNote::checkOctavation() {
-	bool notPossible = false;
-			if (pos < m_ambitMax) {
-				m_ottava = -1;
-				pos += 7;
-				if (pos < m_ambitMax) {
-					m_ottava = -2;
-					pos += 7;
-					if (pos < m_ambitMax)
-						notPossible = true;
-				}
-			} else {
-				m_ottava = 1;
-				pos -= 7;
-				if (pos > m_ambitMin) {
-					m_ottava = 2;
-					pos -= 7;
-					if (pos > m_ambitMin)
-						notPossible = true;
-				}
-			}
-			if (notPossible) {
-				m_ottava = 0;
-				m_mainPosY = 0;
-				hideNote();
-				return;
-			}
-			qDebug() << "octavation required" << (int)m_ottava;
+  bool notPossible = false;
+      if (pos < m_ambitMax) {
+        m_ottava = -1;
+        pos += 7;
+        if (pos < m_ambitMax) {
+          m_ottava = -2;
+          pos += 7;
+          if (pos < m_ambitMax)
+            notPossible = true;
+        }
+      } else {
+        m_ottava = 1;
+        pos -= 7;
+        if (pos > m_ambitMin) {
+          m_ottava = 2;
+          pos -= 7;
+          if (pos > m_ambitMin)
+            notPossible = true;
+        }
+      }
+      if (notPossible) {
+        m_ottava = 0;
+        m_mainPosY = 0;
+        hideNote();
+        return;
+      }
+      qDebug() << "octavation required" << (int)m_ottava;
 } */
 
 
diff --git a/src/libs/score/tscorenote.h b/src/libs/score/tscorenote.h
index 94c7ffd006e224dbd9583bfe990d3618f15bfe03..ceec86b3dfca73d52f75c9d76fde9a2e8c79b70b 100644
--- a/src/libs/score/tscorenote.h
+++ b/src/libs/score/tscorenote.h
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2013-2016 by Tomasz Bojczuk                             *
+ *   Copyright (C) 2013-2017 by Tomasz Bojczuk                             *
  *   seelook@gmail.com                                                     *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -26,170 +26,232 @@
 
 class TscoreLines;
 class Tnote;
-class TnoteControl;
-class TcombinedAnim;
-class TcrossFadeTextAnim;
-class TscoreControl;
+class Trhythm;
 class TscoreScene;
+class TnoteItem;
+class TscoreBeam;
+class TscoreTie;
 
 
-/*!
- * This class represents single note on a score. 
- * It is a rectangle area over the staff with handling mouse move event to display working note cursor.
- * It also grabs wheel event to manipulate accidentals
- * It can be set to read-only mode through setReadOnly() then mouse events are ignored.
- * When mouse cursor appears over it, @p TscoreNote starts to be a parent for @class TscoreControl
- * and it displays panes on the note sides with additional switches (accidentals, name menu, add/delete note)
+/**
+ * This class represents single note on a score.
  */
 class NOOTKACORE_EXPORT TscoreNote : public TscoreItem
 {
+
+  friend class TscoreMeasure;
+  friend class TscoreBeam;
+  friend class TscoreTie;
+
   Q_OBJECT
-  
+
 public:
-    TscoreNote(TscoreScene *scene, TscoreStaff *staff, int index);
-    ~TscoreNote();
-    
-				/** Index of this note instance. It is connected with note number in the list */
-		int index() { return m_index; }
-		void changeIndex(int newIndex) { m_index = newIndex; }
-		
-		void setReadOnly(bool ro);
-		bool isReadOnly() { return m_readOnly; }
-		
-				/** Points to Tnote instance.
-				 * TscoreNote is not aware of it. It is just container.
-				 * This value has to be set through setNote() */
-		Tnote* note() { return m_note; }
-		
-		void adjustSize(); /**< Grabs height from staff and adjust to it. */
-		
-        /** Sets color of main note. */
-    void setColor(const QColor& color);
-		
-				/** It sets background of the note segment. When sets to -1 means transparent - no background. */
-		void setBackgroundColor(QColor bg) { m_bgColor = bg; update(); }
-    
-        /** Adds blur effect to main note. If blurColor is -1 deletes the effect. */
-    void markNote(QColor blurColor);
-		
-    void moveNote(int posY);
-		void moveWorkNote(const QPointF& newPos);
-		
-				/** Returns true if note was selected */
-		bool isSelected() { return m_selected; }
-		void selectNote(bool sel);
-		
-				/** Sets note-head at given position and given accidental accidental. Also puts Tnote of it. */
-		void setNote(int notePos, int accNr, const Tnote& n);
-		
-				/** Returns pointer to main note QGraphicsEllipseItem.  */
-		QGraphicsEllipseItem* mainNote() { return m_mainNote; }
-		
-				/** Returns pointer to main accidental QGraphicsSimpleTextItem.  */
-		QGraphicsSimpleTextItem *mainAccid() { return m_mainAccid; }
-    
-				/** Min and Max values of Y coefficient on the staff */
-    void setAmbitus(int lo, int hi);
-
-        /** This return value of -2 is bb,  1 is #,  etc... */ 
-    int accidental() {return m_accidental;}
-    int ottava() { return m_ottava; } /**< NOTE: for this moment it is unused and set to 0 */
-    int notePos() { return m_mainPosY; }  /** Y Position of note head */
-
-    static QString getAccid(int accNr); /**< Returns QString with accidental symbol*/
-		
-		    /** Prepares note-head (ellipse) */
-    static QGraphicsEllipseItem* createNoteHead(QGraphicsItem* parentIt);
-		
-				/** It paints string number symbol. Automatically determines above or below staff. */
-    void setString(int realNr);
-    void removeString(); /**< Removes string number */
-		int stringNumber() { return m_stringNr; } /**< Number of displayed string or 0 if none. */
-		
-				/** Starts displaying note name of this note. 
-				 * Name will change appropriate to moved note until removeNoteName() will be invoked.
-				 * If no color is set the default one defined in TscoreScene will be used. */
-		void showNoteName(const QColor& dropShadowColor = -1);
-		void removeNoteName();
-		QGraphicsTextItem* noteName() { return m_nameText; } /**< Graphics item of note name text */
-		
-				/** Enables moving note animation during its position (pitch) change.
-				 * In fact, when accidental is visible it is animated as well. */
-		void enableNoteAnim(bool enable, int duration = 150);
-		bool isNoteAnimEnabled() { return (bool)m_noteAnim; }
-		
-		void popUpAnim(int durTime); /**< Performs pop-up animation */
-    
-        /** Defines when lines above and below staff are visible when note is empty. */
-    void setEmptyLinesVisible(bool visible) { m_emptyLinesVisible = visible; }
-    bool emptyLinesVisible() { return m_emptyLinesVisible; }
-    bool wasTouched() { return m_wasTouched; } /**< @p TRUE during touch only */
-    
-    virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
-    virtual QRectF boundingRect() const;
-		
+  TscoreNote(TscoreScene *scene, TscoreStaff *staff, int index);
+  ~TscoreNote();
+
+      /** Index of this note instance. It is connected with note number in the list */
+  int index() { return m_index; }
+  void changeIndex(int newIndex) { m_index = newIndex; }
+
+  void setReadOnly(bool ro);
+  bool isReadOnly() { return m_readOnly; }
+
+  void adjustSize(); /**< Grabs height from staff and adjust to it. */
+
+      /**
+       * Sets color of main note. 
+       */
+  void setColor(const QColor& color);
+  QColor color() const { return m_mainColor; }
+
+      /** It sets background of the note segment. When sets to -1 means transparent - no background. */
+  void setBackgroundColor(QColor bg) { m_bgColor = bg; update(); }
+
+      /** Adds blur effect to main note. If blurColor is -1 deletes the effect. */
+  void markNote(QColor blurColor);
+
+  void moveNote(int posY);
+  void moveWorkNote(const QPointF& newPos);
+
+      /** Returns true if note was selected */
+  bool isSelected() const { return m_selected; }
+  void selectNote(bool sel);
+
+      /** Points to Tnote instance.
+        * TscoreNote is not aware of it. It is just container.
+        * This value has to be set through setNote() */
+  Tnote* note() { return m_note; }
+
+      /** Sets note-head at given position and given accidental accidental. Also puts Tnote of it. */
+  void setNote(int notePos, int accNr, const Tnote& n);
+
+  Trhythm* rhythm() const; /**< Returns Trhythm of note */
+  void setRhythm(const Trhythm& r); /**< Sets rhythm of note */
+
+  void setRhythmEnabled(bool rhythmEnabled); /**< Switches rhythm on/off */
+
+      /** Returns pointer to main note @p TnoteItem.  */
+  TnoteItem* mainNote() { return m_mainNote; }
+
+      /** A line representing note stem */
+  QGraphicsLineItem* stem();
+
+      /** Returns pointer to main accidental QGraphicsSimpleTextItem.  */
+  QGraphicsSimpleTextItem *mainAccid() { return m_mainAccid; }
+
+      /** Min and Max values of Y coefficient on the staff */
+  void setAmbitus(int lo, int hi);
+
+      /** This return value of -2 is bb,  1 is #,  etc... */
+  qint8 accidental() const {return m_accidental;}
+
+      /** NOTE: for this moment it is unused and set to 0 */
+  qint8 ottava() const { return m_ottava; }
+
+      /** Y Position of note head */
+  qint16 notePos() const { return m_mainPosY; }
+
+      /** Position of note after click but before head was moved */
+  qint16 newNotePos() const { return m_newPosY; }
+
+      /** Accidental going to be set. */
+  qint8 newAccidental() const { return m_newAccid; }
+
+  bool accidChanged() const { return (bool)m_newAccid != (bool)m_accidental; } /**< @p TRUE only when accidental appears or hides */
+  bool pitchChanged() const { return m_newPosY != m_mainPosY; }
+  bool rhythmChanged() const;
+
+  static QString getAccid(int accNr); /**< Returns QString with accidental symbol*/
+
+      /**
+       * Pointer to the note after this segment or the first one in the next staff
+       * or null if no note.
+       */
+  TscoreNote* nextNote();
+
+      /**
+       * Pointer to the note before this segment or the last one in the previous staff
+       * or null if no note.
+       */
+  TscoreNote* prevNote();
+
+      /**
+       * Returns space factor after note with given @p r rhythm.
+       */
+  static qreal space(const Trhythm& r);
+
+      /**
+       * Space factor after this note
+       */
+  qreal space();
+
+      /** It paints string number symbol. Automatically determines above or below staff. */
+  void setString(int realNr);
+  void removeString(); /**< Removes string number */
+  int stringNumber() const { return m_stringNr; } /**< Number of displayed string or 0 if none. */
+
+      /** Starts displaying note name of this note.
+        * Name will change appropriate to moved note until removeNoteName() will be invoked.
+        * If no color is set the default one defined in TscoreScene will be used. */
+  void showNoteName(const QColor& dropShadowColor = -1);
+  void removeNoteName();
+  QGraphicsTextItem* noteName() { return m_nameText; } /**< Graphics item of note name text */
+
+      /** Defines when lines above and below staff are visible when note is empty. */
+  void setEmptyLinesVisible(bool visible) { m_emptyLinesVisible = visible; }
+  bool emptyLinesVisible() const { return m_emptyLinesVisible; }
+  bool wasTouched() const { return m_wasTouched; } /**< @p TRUE during touch only */
+
+      /** Overrides standard @p QGraphicsItem::update() method,
+       * checks are rhythms (@p note()->rtm and @p workNote->rhythm() the same) */
+  void update();
+
+      /** Number of rhythmical group in the measure, -1 (undefined) by default */
+  qint8 rhythmGroup() { return m_group; }
+  void setRhythmGroup(qint8 g) { m_group = g; }
+
+      /**
+       * Pointer to @p TscoreBeam or null if note has no beam 
+       */
+  TscoreBeam* beam() { return m_beam; }
+  void setBeam(TscoreBeam* b) { m_beam = b; }
+
+      /** Ties this note with the next one (if they are the same) */
+  void tieWithNext();
+
+      /** Pointer to @p TscoreTie (ligature) or null if note has no tie */
+  TscoreTie* tie() const { return m_tie; }
+
+      /** Removes the tie of this note. */
+  void tieRemove();
+
+  virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
+  virtual QRectF boundingRect() const { return QRectF(0.0, 0.0, m_width, m_height); }
+  qreal width() const { return m_width; }
+  qreal height() const { return m_height; }
+  qreal rightX(); /**< shortcut to X coordinate of right note corner plus gap related to rhythm and staff gap factor */
+  qreal estimateWidth(const Tnote& n); /**< Estimate width of the given note @p n */
+
+  void setX(qreal x);
+  void setPos(const QPointF &pos);
+  void setPos(qreal ax, qreal ay) { setPos(QPointF(ax, ay)); }
+
 signals:
-    void noteWasClicked(int);
-		void noteWasSelected(int); /**< When right button was clicked. */
-		
-		void toKeyAnim(const QString&, const QPointF&, int notePos); /**< Emitted when accidental has been in key already */
-		void fromKeyAnim(const QString&, const QPointF&, int notePos); /**< Emitted when neutral is necessary */
-		
-		void roNoteClicked(TscoreNote*, const QPointF&); /**< Emitted after mouse left click in read only state with clicked position. */
-		void roNoteSelected(TscoreNote*, const QPointF&); /**< Emitted after mouse right click or double click in read only state */
-		
+  void noteWasClicked(int);
+  void noteWasSelected(int); /**< When right button was clicked. */
+
+  void roNoteClicked(TscoreNote*, const QPointF&); /**< Emitted after mouse left click in read only state with clicked position. */
+  void roNoteSelected(TscoreNote*, const QPointF&); /**< Emitted after mouse right click or double click in read only state */
+
+  void noteGoingToChange(TscoreNote*); /**< Emitted when note was pressed or @p setNote() was invoked */
+
 public slots:
-		void keyAnimFinished();
-    void hideNote(); /**< Hides main note */
-    void hideWorkNote(); /**< Hides pointing (work) note */
+  void hideNote(); /**< Hides main note */
 
 protected:
-    virtual void touched(const QPointF& scenePos);
-    virtual void untouched(const QPointF& scenePos);
-    virtual void touchMove(const QPointF& scenePos);
-		
-    virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
-    virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event);
-    
-    virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event);
-    virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event);
-    virtual void hoverMoveEvent(QGraphicsSceneHoverEvent* event);
+
+  virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
 
 private:
-    QGraphicsEllipseItem                   *m_mainNote;
-    QGraphicsSimpleTextItem                *m_mainAccid;
-    QColor                                  m_mainColor;
-		TcrossFadeTextAnim                     *m_accidAnim;
-		Tnote                                  *m_note;
-    
-    int                            					m_mainPosY, m_accidental;
-    int                            					m_index; /**< note index in external list */
-//     int 													m_noteNr; // note number depends on octave
-    int                            					m_ambitMin, m_ambitMax; /**< Represents range (ambitus) of notes on score */
-		int 													 					m_stringNr;
-		QGraphicsSimpleTextItem 							 *m_stringText;
-    qreal                          					m_height;
-		bool													 					m_readOnly, m_emptyLinesVisible;
-		QGraphicsTextItem											 *m_nameText;
-		int 													 					m_ottava; /**< values from -2 (two octaves down), to 2 (two octaves up) */
-		QColor                         					m_bgColor;
-		TcombinedAnim													 *m_noteAnim, *m_popUpAnim;
-		QGraphicsSimpleTextItem								 *m_emptyText;
-		bool													 					m_selected;
-		TscoreLines														 *m_lines;
-		
-		bool 																		m_touchedToMove; /**< Determines whether cursor follows moving finger */
-		bool                                    m_wasTouched;
-		static QString													m_staticTip;
-    QElapsedTimer                           m_touchTime;
-    
+  TnoteItem                               *m_mainNote;
+  QGraphicsSimpleTextItem                 *m_mainAccid;
+  QColor                                   m_mainColor;
+  Tnote                                   *m_note;
+
+  qint16                                   m_mainPosY, m_newPosY;
+  qint8                                    m_accidental, m_newAccid;
+  int                                      m_index; /**< note index in external list */
+//     int                                 m_noteNr; // note number depends on octave
+  quint16                                  m_ambitMin, m_ambitMax; /**< Represents range (ambitus) of notes on score */
+  quint8                                   m_stringNr;
+  QGraphicsSimpleTextItem                 *m_stringText;
+  qreal                                    m_width, m_height;
+  bool                                     m_readOnly, m_emptyLinesVisible;
+  QGraphicsTextItem                       *m_nameText;
+  qint8                                    m_ottava; /**< values from -2 (two octaves down), to 2 (two octaves up) */
+  QColor                                   m_bgColor;
+  QGraphicsSimpleTextItem                 *m_emptyText;
+  bool                                     m_selected;
+  TscoreLines                             *m_lines;
+
+  bool                                     m_touchedToMove; /**< Determines whether cursor follows moving finger */
+  bool                                     m_wasTouched;
+  static QString                           m_staticTip, m_selectedTip;
+  QElapsedTimer                            m_touchTime;
+
+  qint8                                    m_group = -1;
+  TscoreBeam                              *m_beam = nullptr;
+  TscoreTie                               *m_tie = nullptr;
+
+  static const qreal                       m_rtmGapArray[5][3]; /**< static array with space definitions for each rhythm value */
+
 private:
-		void setStringPos(); /**< Determines and set string number position (above or below the staff) depends on note position */
-		void initNoteCursor(); /**< Creates note cursor when first TscoreNote instance is created and there is a view */
-		void checkEmptyText(); /**< Decides whether show or hide text about empty note. */
-		
-private slots:
-		void popUpAnimFinished();
+  void setStringPos(); /**< Determines and set string number position (above or below the staff) depends on note position */
+  void initNoteCursor(); /**< Creates note cursor when first TscoreNote instance is created and there is a view */
+  void checkEmptyText(); /**< Decides whether show or hide text about empty note. */
+  void changeWidth(); /**< Changes bounding rectangle width appropriate to current accidental and rhythm */
+  void emitNoteWasSelected();
+
 };
 
 #endif // TSCORENOTE_H
diff --git a/src/libs/score/tscorescene.cpp b/src/libs/score/tscorescene.cpp
index 4b1fbf31c6edbf77057f327ac72fefa812cb59c2..0e2768d2c9e63f0fbdeefb25d205f0864d676ce7 100644
--- a/src/libs/score/tscorescene.cpp
+++ b/src/libs/score/tscorescene.cpp
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2013-2015 by Tomasz Bojczuk                             *
+ *   Copyright (C) 2013-2017 by Tomasz Bojczuk                             *
  *   seelook@gmail.com                                                     *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -17,68 +17,45 @@
  ***************************************************************************/
 
 #include "tscorescene.h"
-#include "tnotecontrol.h"
-#include "tscorestaff.h"
+#include "tscoremeter.h"
+#include "tscoremeasure.h"
 #include <graphics/tdropshadoweffect.h>
 #include <tnoofont.h>
-#include <QGraphicsView>
-#include <QGraphicsEffect>
-#include <QApplication>
-#include <QTimer>
-#include <QDebug>
+#include <music/trhythm.h>
+#include <music/tmeter.h>
+#include <QtWidgets/qgraphicseffect.h>
+#include <QtWidgets/qapplication.h>
+#include <QtCore/qdebug.h>
 
 
 #define WORK_HIDE_DELAY (5000)
+#define REST_Y (19.0)
+#define WORK_X (1.2) // x coordinate of the cursor note head
 
 
 TscoreScene::TscoreScene(QObject* parent) :
   QGraphicsScene(parent),
-  m_workPosY(0),
-  m_workNote(0),
-  m_workAccid(0), m_workAccid2(0),
   m_nameColor(Qt::darkCyan),
-  m_rightBox(0), m_leftBox(0),
   m_accidYoffset(0.0),
   m_accidScale(-1.0),
   m_scoreNote(0),
-  m_controlledNotes(true),
-  m_mouseOverKey(false), m_rectIsChanging(false)
+  m_scoreMeter(nullptr)
 {
-	m_showTimer = new QTimer(this);
-	m_hideTimer = new QTimer(this);
   setDoubleAccidsEnabled(true);
   m_currentAccid = 0;
-	
-	connect(m_showTimer, SIGNAL(timeout()), this, SLOT(showTimeOut()));
-	connect(m_hideTimer, SIGNAL(timeout()), this, SLOT(hideTimeOut()));
+
 }
 
 
-TscoreScene::~TscoreScene() 
+TscoreScene::~TscoreScene()
 {
-	if (m_rightBox) { // all items are into scene so they will be deleted
-		delete m_rightBox; // but the last TscoreNote has to skip deleting depending items itself
-		m_rightBox = 0;
-	}
+  delete m_scoreMeter;
 }
 
 
 void TscoreScene::setCurrentAccid(char accid) {
-	char prevAcc = m_currentAccid;
-  m_currentAccid = char(qBound(int(-m_dblAccFuse), int(accid), int(m_dblAccFuse)));
-	if (m_workAccid && prevAcc != m_currentAccid) {
-		m_workAccid->setText(TscoreNote::getAccid(m_currentAccid));
-//     if (m_workAccid2)
-//       m_workAccid2->setText(TscoreNote::getAccid(m_currentAccid));
-		if (m_currentAccid == 0)
-			m_workAccid->hide();
-		else
-			m_workAccid->show();
-		if (m_leftBox)
-			m_leftBox->setAccidental(m_currentAccid);
-		if (m_hideTimer->isActive())
-			m_hideTimer->start(1000);
-	}
+  char prevAcc = m_currentAccid;
+  m_currentAccid = (char)qBound((int)-m_dblAccFuse, (int)accid, (int)m_dblAccFuse);
 }
 
 
@@ -92,209 +69,16 @@ void TscoreScene::setDoubleAccidsEnabled(bool enable) {
 
 void TscoreScene::addBlur(QGraphicsItem* item, qreal radius) {
   QGraphicsBlurEffect *blur = new QGraphicsBlurEffect();
-  blur->setBlurRadius(radius / views()[0]->transform().m11());
+//   blur->setBlurRadius(radius / views()[0]->transform().m11());
   item->setGraphicsEffect(blur);
 }
 
 
-void TscoreScene::adjustCursor(TscoreNote* sn) {
-	if (m_rightBox && !views().isEmpty()) {
-		m_rightBox->adjustSize();
-		m_leftBox->adjustSize();
-		workLines()->adjustLines(sn);
-		setPointedColor(workColor);
-	}
-}
-
-
-void TscoreScene::setPointedColor(const QColor& color) {
-	workColor = color;
-	m_workNote->setPen(QPen(workColor, 0.2));
-	m_workNote->setBrush(QBrush(workColor, Qt::SolidPattern));
-	m_workAccid->setBrush(QBrush(workColor));
-//   if (m_workAccid2)
-//       m_workAccid2->setBrush(QBrush(workColor));
-	m_workLines->setColor(color);
-}
-
-//##########################################################################################
-//#######################        Note CURSOR     ###########################################
-//##########################################################################################
-
-void TscoreScene::noteEntered(TscoreNote* sn) {
-  m_hideTimer->stop();
-  if (!m_rectIsChanging && sn != m_scoreNote && sn != 0) {
-    m_scoreNote = sn;
-    if (controlledNotes()) {
-      if (right()->isEnabled()) {
-        if (sn->index() < sn->staff()->maxNoteCount() - 1)
-          right()->setPos(sn->pos().x() + sn->boundingRect().width(), (sn->parentItem()->boundingRect().height() - right()->boundingRect().height() + 6.0) / 2.0);
-        else // Put right pane on the left if the last note on the staff
-          right()->setPos(sn->pos().x() - right()->boundingRect().width(), (sn->parentItem()->boundingRect().height() - right()->boundingRect().height() + 6.0) / 2.0);
-        right()->setScoreNote(sn);
-      }
-      if (left()->isEnabled()) {
-        if (sn->index() < sn->staff()->maxNoteCount() - 1)
-          left()->setPos(sn->pos().x() - left()->boundingRect().width(), (sn->parentItem()->boundingRect().height() - right()->boundingRect().height() + 6.0) / 2.0);
-        else
-          left()->setPos(sn->pos().x() - left()->boundingRect().width() - (right()->isEnabled() ? right()->boundingRect().width() : 0.0),
-                         (sn->parentItem()->boundingRect().height() - right()->boundingRect().height() + 6.0) / 2.0);
-        left()->setScoreNote(sn);
-      }
-    }
-    if (workNote()->parentItem() != sn)
-      setCursorParent(sn);
-	}
-}
-
-
-void TscoreScene::noteMoved(TscoreNote* sn, int yPos) {
-  if (!m_rectIsChanging) {
-    setWorkPosY(yPos);
-    workNote()->setPos(3.0, workPosY());
-    workLines()->checkLines(yPos);
-    if (!workNote()->isVisible())
-      showTimeOut();
-    if (sn != m_scoreNote) {
-        noteEntered(sn);
-        if (TscoreItem::touchEnabled())
-          m_workNote->show(); // show note immediately when touched
-        else
-          m_showTimer->start(300); // show with delay when mouse over to avoid flickering
-    } else {
-        m_hideTimer->start(WORK_HIDE_DELAY);
-    }
-  }
-}
-
-
-void TscoreScene::noteLeaved(TscoreNote* sn) {
-	Q_UNUSED(sn)
-  if (!m_rectIsChanging) {
-    m_showTimer->stop();
-    m_hideTimer->start(TscoreItem::touchEnabled() ? 2000 : 300);
-  }
-}
-
-
-void TscoreScene::noteDeleted(TscoreNote* sn) {
-	if (right() && (workNote()->parentItem() == sn || right()->parentItem() == sn->parentItem())) {
-		right()->setScoreNote(0);
-		left()->setScoreNote(0);
-		setCursorParent(0);
-		hideTimeOut();
-    statusTipChanged(""); // hide status tip of deleting note
-	}
-	m_scoreNote = 0;
-}
-
-
-void TscoreScene::controlMoved() {
-	m_hideTimer->start(WORK_HIDE_DELAY);
-}
-
-
-void TscoreScene::prepareToChangeRect() {
-  m_rectIsChanging = true;
-  hideTimeOut();
+void TscoreScene::setScoreMeter(TscoreMeter* m) {
+  m_scoreMeter = m;
 }
 
 
-void TscoreScene::restoreAfterRectChange() {
-  m_rectIsChanging = false;
-}
-
-
-//##########################################################################################
-//#######################        PROTECTED       ###########################################
-//##########################################################################################
-
-void TscoreScene::initNoteCursor(TscoreNote* scoreNote) {
-	if (!m_workNote) {
-		m_workLines = new TscoreLines(scoreNote);
-		workColor = qApp->palette().highlight().color();
-		workColor.setAlpha(200);
-		m_workNote = TscoreNote::createNoteHead(scoreNote);
-//     if (TscoreNote::touchEnabled())
-//       m_workNote->setRect(-10.5, 0, 22, 2); // long ellipse for touch screens visible under finger
-//     else
-    m_workNote->setRect(0, 0, 3.5, 2); // normal note head
-		QGraphicsDropShadowEffect *workEffect = new QGraphicsDropShadowEffect();
-		workEffect->setOffset(3.0, 3.0);
-		workEffect->setBlurRadius(15);
-		workEffect->setColor(qApp->palette().text().color());
-		m_workNote->setGraphicsEffect(workEffect);
-    m_workNote->setZValue(35);
-		m_workAccid = new QGraphicsSimpleTextItem();
-		m_workAccid->setBrush(QBrush(workColor));
-		m_workAccid->setParentItem(m_workNote);
-		m_workAccid->setFont(TnooFont(5));
-		m_workAccid->setScale(accidScale());
-//     if (TscoreNote::touchEnabled())
-//       m_workAccid->setPos(-13.5, - accidYoffset());
-//     else
-    m_workAccid->setPos(-3.0, - accidYoffset());
-//     if (TscoreNote::touchEnabled()) { // two the same accidentals on long note sides
-//       m_workAccid2 = new QGraphicsSimpleTextItem();
-//       m_workAccid2->setBrush(QBrush(workColor));
-//       m_workAccid2->setParentItem(m_workAccid);
-//       m_workAccid2->setFont(TnooFont(5));
-//       m_workAccid2->setPos(21, 0);
-//     }
-    m_workAccid->hide();
-		setPointedColor(workColor);
-		
-    m_rightBox = new TnoteControl(false, scoreNote->staff(), this);
-    m_leftBox = new TnoteControl(true, scoreNote->staff(), this);
-		m_leftBox->addAccidentals();
-	}
-}
-
-
-void TscoreScene::setCursorParent(TscoreNote* sn) {
-	workNote()->setParentItem(sn);
-	m_workLines->setParent(sn);
-}
-
-
-//##########################################################################################
-//#######################     PROTECTED SLOTS    ###########################################
-//##########################################################################################
-
-void TscoreScene::showPanes() {
-  if (left()->isEnabled())
-    left()->show();
-  if (right()->isEnabled())
-    right()->show();
-}
-
-
-void TscoreScene::hidePanes() {
-  if (left()->isEnabled())
-    left()->hide();
-  if (right()->isEnabled())
-    right()->hide();
-}
-
-
-void TscoreScene::showTimeOut() {
-	m_showTimer->stop();
-	m_workNote->show();
-  showPanes();
-}
-
-
-void TscoreScene::hideTimeOut() {
-	m_hideTimer->stop();
-  if (m_scoreNote)
-    m_scoreNote->hideWorkNote();
-  hidePanes();
-  TscoreNote *sn = m_scoreNote;
-  m_scoreNote = 0;
-  if (TscoreItem::touchEnabled() && sn)
-    sn->update();
-}
-
 
 
 
diff --git a/src/libs/score/tscorescene.h b/src/libs/score/tscorescene.h
index 70e2cd59ad5ea08211f236cc1fd9aa674f8d6d2c..22e0b04f90c2135f7b9f3f5ef4c26a194e18e8c5 100644
--- a/src/libs/score/tscorescene.h
+++ b/src/libs/score/tscorescene.h
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2013-2015 by Tomasz Bojczuk                             *
+ *   Copyright (C) 2013-2017 by Tomasz Bojczuk                             *
  *   seelook@gmail.com                                                     *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -20,138 +20,81 @@
 #define TSCORESCENE_H
 
 #include <nootkacoreglobal.h>
-#include <QGraphicsScene>
 #include "tscorenote.h"
+#include "tnoteitem.h"
 #include "tscorelines.h"
+#include <QtWidgets/qgraphicsscene.h>
+
 
-class QTimer;
-class TnoteControl;
 class QGraphicsItem;
+class TscoreMeter;
+class Tmeter;
 
 
-/** 
+/**
  * This is subclass of QGraphicsScene that handles additional operations of Nootka score.
- * 
- * It manages a 'note cursor' - note shape under mouse and 'note controllers' - panes on the sides of a note.
- * Three methods are responsible for smart displaying cursor/panes:
- * - @p noteMoved() - invokes timer to display cursor when mouse stays over a note segment 
- * and timer to hide it when cursor stops over the segment
- * - @p noteLeaved() - invokes timer to hide cursor when mouse leaves the segment
- * - @p controlEntered() - to stop timers and keep cursor and pane visible
- * - @p controlLeaved() - to hide (the same as @p noteLeaved())
  */
 class NOOTKACORE_EXPORT TscoreScene : public QGraphicsScene
 {
-		
-		friend class TscoreNote;
-	
+
+  friend class TscoreNote;
+  friend class TscoreStaff;
+
   Q_OBJECT
-  
+
 public:
-    TscoreScene(QObject* parent = 0);
-    virtual ~TscoreScene();
-        
-        
-    void setDoubleAccidsEnabled(bool enable);
-		
-        /** Returns value 2 when double accidentals are enabled and 1 if not. */
-    qint8 doubleAccidsFuse() { return m_dblAccFuse; }
-    
-        
-    void setCurrentAccid(char accid); /** Working accidental in  also changed by buttons. */
-    char currentAccid() { return m_currentAccid; }
-    
-        /** Adds blur graphics effect. In the contrary to QGraphicsItem::setGraphicsEffect() 
-         * a radius value in global scale.  */
-    void addBlur(QGraphicsItem *item, qreal radius);
-		
-				/** Adjust note cursor and TnoteControl to new staff size. 
-				 * For performance reason it has to be called once for all adjustSize() of TscoreNote
-				 * because there is only one instance of note cursor and TnoteControl */
-		void adjustCursor(TscoreNote* sn);
-		bool isCursorVisible() { return m_workNote->isVisible(); }
-		
-				/** Note controllers, appear with cursor. 
-				 * There are automatically created with first note instance 
-				 * when score scene has a view. */
-		TnoteControl* right() { return m_rightBox; }
-		TnoteControl* left() { return m_leftBox; }
-		void setNameColor(const QColor& nameC) { m_nameColor = nameC; }
-		QColor nameColor() { return m_nameColor; }
-		
-				/** Sets color of pointing (work) note. */
-    void setPointedColor(const QColor& color);
-		
-		qreal accidYoffset() { return m_accidYoffset; } /** Y offset of accidental item */
-		qreal accidScale() { return m_accidScale; } /** Scale of accidental text item */
-
-		bool isAccidAnimated() const { return m_accidAnimated; } /** Whether note accidental to key signature animations are allowed */
-		void enableAccidsAnimation(bool anim) { m_accidAnimated = anim; } /** Sets state of note accidental to key signature animations */
-		
-				/** Additional note controls are displayed when note gets cursor.
-				 This is default behavior and without those controls accidentals can not be managed with wheel. */
-		void setControlledNotes(bool controlled) { m_controlledNotes = controlled; }
-		bool controlledNotes() { return m_controlledNotes; }
-		
-		void noteEntered(TscoreNote* sn); /** Prepares note cursor. From @p TscoreNote::hoverEnterEvent() */
-		void noteMoved(TscoreNote* sn, int yPos); /** Starts show timer if hidden or restarts hide timer. From @p TscoreNote::hoverMoveEvent() */
-		void noteLeaved(TscoreNote* sn); /** Starts hide timer. From @p TscoreNote::hoverLeaveEvent() */
-		void noteDeleted(TscoreNote* sn); /** From @p TscoreNote::~TscoreNote() */
-		void controlMoved(); /** Restarts hide timer. From @p TnoteControl::hoverMoveEvent()*/
-		void controlLeaved(TscoreNote* sn) { noteLeaved(sn); } /** From @p TnoteControl::hoverLeaveEvent */
-		TscoreNote* currentNote() { return m_scoreNote; }
-		
-		void mouseEntersOnKey(bool onKey) { m_mouseOverKey = onKey; } /** score key informs that has or has not a mouse cursor */
-		bool keyHasMouse() { return m_mouseOverKey; }
-		
-		void prepareToChangeRect(); /** It has to be invoked whenever score rectangle is going to change. I.e. by resize event of a view. */
-    void restoreAfterRectChange(); /** Scene will try to adjust itself to new size.  */
-
-       /** Sets note cursor parent item to 0 */
-    void releaseNoteCursor() { setCursorParent(0); }
-		
+  TscoreScene(QObject* parent = 0);
+  virtual ~TscoreScene();
+
+
+  void setDoubleAccidsEnabled(bool enable);
+      /** Returns value 2 when double accidentals are enabled and 1 if not. */
+  qint8 doubleAccidsFuse() { return m_dblAccFuse; }
+
+  void setCurrentAccid(char accid); /**< Working accidental in  also changed by buttons. */
+  char currentAccid() { return m_currentAccid; }
+
+      /** Adds blur graphics effect. In the contrary to QGraphicsItem::setGraphicsEffect()
+        * a radius value in global scale.  */
+  void addBlur(QGraphicsItem *item, qreal radius);
+
+  void setNameColor(const QColor& nameC) { m_nameColor = nameC; }
+  QColor nameColor() { return m_nameColor; }
+
+  qreal accidYoffset() { return m_accidYoffset; } /**< Y offset of accidental item */
+  qreal accidScale() { return m_accidScale; } /**< Scale of accidental text item */
+
+  bool isRhythmEnabled() { return (bool)m_scoreMeter; } /**< @p TRUE when score has rhythm enabled. */
+  TscoreMeter* scoreMeter() { return m_scoreMeter; } /**< Score meter - if it is @p nullptr - there is no rhythms */
+
+  void noteDeleted(TscoreNote* sn); /**< From @p TscoreNote::~TscoreNote() */
+  TscoreNote* currentNote() { return m_scoreNote; }
+
 signals:
-    void statusTip(QString);
-		
+  void statusTip(QString);
+
 protected:
-	// note cursor
-		QColor  workColor;
-		int workPosY() { return m_workPosY; }
-		void setWorkPosY(int wpY) { m_workPosY = wpY; }
-		QGraphicsEllipseItem* workNote() { return m_workNote; }
-		TscoreLines* workLines() { return m_workLines; }
-		void initNoteCursor(TscoreNote* parentIt);
-		QGraphicsSimpleTextItem* workAccid() { return m_workAccid; }
-		void setAccidYoffset(qreal aYo) { m_accidYoffset = aYo; }
-		void setAccidScale(qreal as) { m_accidScale = as; }
-		void setCursorParent(TscoreNote* sn); /** Sets parent of note cursor to this instance */
-		
-    
+// note cursor
+  void setAccidYoffset(qreal aYo) { m_accidYoffset = aYo; }
+  void setAccidScale(qreal as) { m_accidScale = as; }
+
+      /** Sets meter, enables rhythms if meter is valid or disables rhythm if it is @p nullptr.
+       * This is global meter for all score items and it is managed through @class TscoreStaff */
+  void setScoreMeter(TscoreMeter* m);
+
+
 protected slots:
-    void statusTipChanged(QString status) { emit statusTip(status); }
-    void showTimeOut();
-		void hideTimeOut();
-    void showPanes();
-    void hidePanes();
-    
+  void statusTipChanged(QString status) { emit statusTip(status); }
+
 private:
-        /** It is @p 2 if double accidentals are enabled and @p 1 if not*/
-    qint8 														m_dblAccFuse;
-    char  														m_currentAccid;
-	// note cursor
-		int                            		m_workPosY;
-		QGraphicsEllipseItem          	 *m_workNote;
-		QGraphicsSimpleTextItem       	 *m_workAccid, *m_workAccid2;
-		TscoreLines											 *m_workLines;
-		QColor														m_nameColor;
-		TnoteControl				  				 	 *m_rightBox, *m_leftBox;
-		qreal 									 					m_accidYoffset; /** difference between y note position. */
-    qreal									 						m_accidScale;
-		QTimer													 *m_showTimer, *m_hideTimer;
-		TscoreNote											 *m_scoreNote; /** current note segment or NULL. */
-		bool															m_controlledNotes;
-		bool															m_mouseOverKey, m_rectIsChanging;
-    bool                              m_accidAnimated;
+      /** It is @p 2 if double accidentals are enabled and @p 1 if not*/
+  qint8                             m_dblAccFuse;
+  char                              m_currentAccid;
+  QColor                            m_nameColor;
+  qreal                             m_accidYoffset; /**< difference between y note position. */
+  qreal                             m_accidScale;
+  TscoreNote                       *m_scoreNote; /**< current note segment or NULL. */
+  TscoreMeter                      *m_scoreMeter;
 };
 
 #endif // TSCORESCENE_H
diff --git a/src/libs/score/tscorestaff.cpp b/src/libs/score/tscorestaff.cpp
index b51d45b4a8ff930d0e6be5e3cf9a01647f5a4f7b..baa2fb3a4a0f21e7f26fb8ce7fd8830ff2214b15 100755
--- a/src/libs/score/tscorestaff.cpp
+++ b/src/libs/score/tscorestaff.cpp
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2013-2015 by Tomasz Bojczuk                             *
+ *   Copyright (C) 2013-2016 by Tomasz Bojczuk                             *
  *   seelook@gmail.com                                                     *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -24,314 +24,383 @@
 #include "tscorescordature.h"
 #include "tnotecontrol.h"
 #include "tscore5lines.h"
+#include "tscoremeter.h"
+#include "tscoremeasure.h"
+#include "tscoretie.h"
 #include <music/tnote.h>
-#include <animations/tcombinedanim.h>
+#include <music/trhythm.h>
+#include <music/tmeter.h>
 #include <tnoofont.h>
-#include <QApplication>
-#include <QGraphicsView>
-#include <QPalette>
-
-#include <QDebug>
-
-
-TnoteOffset::TnoteOffset(int noteOff, int octaveOff) :
-  note(noteOff),
-  octave(octaveOff)
-{}
-
+#include <QtWidgets/qapplication.h>
+#include <QtWidgets/qgraphicsview.h>
+#include <QtGui/qpalette.h>
+
+#include <QtCore/qdebug.h>
+
+
+void content(TscoreStaff* st) {
+  QString c;
+  for (int i = 0; i < st->count(); ++i) {
+    c += QStringLiteral("<");
+    if (st->noteSegment(i)->note()->isValid() && !st->noteSegment(i)->note()->isRest())
+      c += st->noteSegment(i)->note()->toText();
+    else
+      c += QLatin1String("r");
+    c += QLatin1String(">");
+    c += QString("%1%2").arg(st->noteSegment(i)->note()->weight()).arg(st->noteSegment(i)->note()->hasDot() ? QStringLiteral(".") : QString());
+    c += QString("(%1) ").arg(st->noteSegment(i)->rhythmGroup());
+  }
+  qDebug() << st->debug() << c;
+}
 
 
 TscoreStaff::TscoreStaff(TscoreScene* scene, int notesNr) :
   TscoreItem(scene),
   m_staffNr(-1), m_brace(0),
-  m_keySignature(0),
+  m_keySignature(nullptr),
   m_upperLinePos(16.0), m_lowerStaffPos(0.0),
-  m_height(36.0),
+  m_height(38.0),
   m_viewWidth(0.0),
   m_offset(TnoteOffset(3, 2)),
   m_isPianoStaff(false),
-	m_scordature(0), m_enableScord(false), m_tidyKey(false),
-	m_accidAnim(0), m_flyAccid(0),
-	m_selectableNotes(false), m_extraAccids(false),
-	m_maxNotesCount(0),
-	m_loNotePos(28.0), m_hiNotePos(12.0),
-	m_lockRangeCheck(false), m_autoAddedNoteId(-1)
+  m_scordature(0), m_enableScord(false), m_tidyKey(false),
+  m_selectableNotes(false), m_extraAccids(false),
+  m_maxNotesCount(0),
+  m_loNotePos(28.0), m_hiNotePos(12.0),
+  m_allNotesWidth(0.0),
+  m_gapFactor(1.0),
+  m_shortestR(12),
+  m_lockRangeCheck(false), m_autoAddedNoteId(-1),
+  m_scoreMeter(nullptr)
 {
-	setFlag(QGraphicsItem::ItemHasNoContents);
-	setZValue(10);
+  setFlag(QGraphicsItem::ItemHasNoContents);
+  setZValue(10);
   setAcceptHoverEvents(true);
 // Clef
   Tclef cl = Tclef();
   m_clef = new TscoreClef(scene, this, cl);
   connect(m_clef, SIGNAL(clefChanged(Tclef)), this, SLOT(onClefChanged(Tclef)));
-	m_clef->setZValue(29); // lower than key signature (if any)
+  m_clef->setZValue(29); // lower than key signature (if any)
+  m_measures << new TscoreMeasure(this, 0);
 // Notes
   for (int i = 0; i < notesNr; i++) {
       m_scoreNotes << new TscoreNote(scene, this, i);
-      m_scoreNotes[i]->setPos(7.0 + i * m_scoreNotes[i]->boundingRect().width(), 0);
-			m_scoreNotes[i]->setZValue(50);
-			connectNote(m_scoreNotes[i]);
+      m_scoreNotes[i]->setPos(7.0 + i * m_scoreNotes[i]->boundingRect().width(), 0.0);
+      m_scoreNotes[i]->setZValue(50);
+      measures().last()->insertNote(i, m_scoreNotes[i]);
   }
-  
+
 // Staff lines, it also sets m_width of staff
   m_5lines = new Tscore5lines(scoreScene());
   m_5lines->setParentItem(this);
-	prepareStaffLines();
-	
+  prepareStaffLines();
+
   for (int i = 0; i < 7; i++) // reset accidentals array
     accidInKeyArray[i] = 0;
-// Timer controlling automatic note adding to this staff  
-	m_addTimer = new QTimer(this);
-	m_addTimer->setSingleShot(true);
-	connect(m_addTimer, SIGNAL(timeout()), this, SLOT(addNoteTimeOut()));
 }
 
 
 TscoreStaff::~TscoreStaff() {
-	if (scoreScene()->right() && scoreScene()->right()->parentItem() == this) {
-		scoreScene()->right()->setParentItem(0);
-		scoreScene()->left()->setParentItem(0);
-	}		
+  m_goingDelete = true;
+  int measuresCnt = m_measures.count();
+  for (int m = 0; m < measuresCnt; ++m)
+    delete m_measures.takeLast();
+  int notesCnt = count();
+  for (int n = 0; n < notesCnt; ++n)
+    delete m_scoreNotes.takeLast();
+  if (m_scoreMeter)
+    setMeter(Tmeter());
 }
 
 //####################################################################################################
 //########################################## PUBLIC ##################################################
 //####################################################################################################
 
-int TscoreStaff::noteToPos(const Tnote& note)	{
-	int nPos = m_offset.octave * 7 + m_offset.note + upperLinePos() - 1 - (note.octave * 7 + (note.note - 1));
-	if (isPianoStaff() && nPos > lowerLinePos() - 5)
-		return nPos + 2;
-	else
-		return nPos;
+int TscoreStaff::noteToPos(const Tnote& note)  {
+  int nPos = m_offset.octave * 7 + m_offset.note + upperLinePos() - 1 - (note.octave * 7 + (note.note - 1));
+  if (isPianoStaff() && nPos > lowerLinePos() - 5)
+    return nPos + 2;
+  else
+    return nPos;
 }
 
-		/** Calculation of note position works As folow:
-		 * 1) expr: m_offset.octave * 7 + m_offset.note + upperLinePos() - 1 returns y position of note C in offset octave
-		 * 2) (note.octave * 7 + (note.note - 1)) is number of note to be set.
-		 * 3) Subtraction of them gives position of the note on staff with current clef and it is displayed 
-		 * when this value is in staff scale. */
+    /** Calculation of note position works As folow:
+     * 1) expr: m_offset.octave * 7 + m_offset.note + upperLinePos() - 1 returns y position of note C in offset octave
+     * 2) (note.octave * 7 + (note.note - 1)) is number of note to be set.
+     * 3) Subtraction of them gives position of the note on staff with current clef and it is displayed
+     * when this value is in staff scale. */
 void TscoreStaff::setNote(int index, const Tnote& note) {
-	if (index >= 0 && index < m_scoreNotes.size()) {
-		Tnote prevNote = *getNote(index);
-		if (note.note)
-				m_scoreNotes[index]->setNote(noteToPos(note), (int)note.alter, note);
-		else
-				m_scoreNotes[index]->setNote(0, 0, note);
-		if (prevNote != note) // check it only when note was really changed
-				checkNoteRange();
-	}
+  if (index >= 0 && index < m_scoreNotes.size()) {
+    Tnote prevNote = *getNote(index);
+    if (note.isValid())
+        m_scoreNotes[index]->setNote(noteToPos(note), (int)note.alter, note);
+    else
+        m_scoreNotes[index]->setNote(0, 0, note);
+    if (prevNote != note) // check it only when note was really changed
+        checkNoteRange();
+  }
 }
 
 
 Tnote* TscoreStaff::getNote(int index) {
-	return m_scoreNotes[index]->note();
-}
-
-
-void TscoreStaff::insertNote(int index, const Tnote& note, bool disabled) {
-	if (m_autoAddedNoteId > -1) // naughty user can insert or add new note just after clicking the last one what invokes auto adding
-		addNoteTimeOut();
-	index = qBound(0, index, m_scoreNotes.size()); // 0 - adds at the begin, size() - adds at the end
-	insert(index);
-	setNote(index, note);
-	m_scoreNotes[index]->setZValue(50);
-	setNoteDisabled(index, disabled);
-	if (number() > -1) {
-		emit noteIsAdding(number(), index);
-		if (maxNoteCount()) {
-			if (count() > maxNoteCount()) {
-					m_scoreNotes.last()->disconnect(SIGNAL(noteWasClicked(int)));
-					m_scoreNotes.last()->disconnect(SIGNAL(noteWasSelected(int)));
-          m_scoreNotes.last()->disconnect(SIGNAL(toKeyAnim(QString,QPointF,int)));
-          m_scoreNotes.last()->disconnect(SIGNAL(fromKeyAnim(QString,QPointF,int)));
-          m_scoreNotes.last()->disconnect(SIGNAL(destroyed(QObject*)));
-					emit noteToMove(number(), m_scoreNotes.takeLast());
-					checkNoteRange(); // find range again
-			} else if (count() == maxNoteCount())
-					emit noMoreSpace(number());
-		}
-	}
-	updateIndexes();
-	updateNotesPos(index);
-	if (number() == -1) {
-			updateLines();
-			updateSceneRect(); // Update only for single staff view
-	}
+  return m_scoreNotes[index]->note();
+}
+
+
+TscoreNote* TscoreStaff::insertNote(int index, const Tnote& note, bool disabled) {
+  if (m_autoAddedNoteId > -1) // naughty user can insert or add new note just after clicking the last one what invokes auto adding
+    addNoteTimeOut();
+
+  qDebug() << "\n";
+
+  //TODO: check is inserting note fit into a measure:
+  // - split it if it is longer, then shift the next measure
+
+  int measureNr = m_measures.count() - 1; // add to the last measure by default
+  if (index < count())
+    measureNr = measureOfNoteId(index);
+  if (measureNr < 0) {
+    qDebug() << debug() << "Not such a measure for index," << index << " inserting to the last measure";
+    measureNr = m_measures.count() - 1;
+  }
+  auto inserted = insertNote(note, index, disabled);
+
+  qDebug() << debug() << "--> inserting note" << (inserted->note()->isValid() ? inserted->note()->toText() : "rest")
+           << inserted->note()->rtm.xmlType() << (inserted->note()->hasDot() ? "." : QString())
+           << inserted->rhythm()->xmlType()
+           << "to measure" << measureNr;
+  m_measures[measureNr]->insertNote(index - m_measures[measureNr]->firstNoteId(), inserted);
+
+  if (number() > -1) {
+    emit noteIsAdding(number(), inserted->index());
+  }
+
+  fit();
+  updateNotesPos(/*index*/);
+  if (number() == -1) {
+      updateLines();
+      updateSceneRect(); // Update only for single staff view
+  }
+  return inserted;
 }
 
 
 void TscoreStaff::insertNote(int index, bool disabled) {
-	insertNote(index, Tnote(0, 0, 0), disabled);
+  insertNote(index, Tnote(), disabled);
 }
 
 
-void TscoreStaff::addNote(Tnote& note, bool disabled) {
-	insertNote(m_scoreNotes.size(), note, disabled);
+void TscoreStaff::addNote(const Tnote& note, bool disabled) {
+  insertNote(m_scoreNotes.size(), note, disabled);
 }
 
 
 void TscoreStaff::removeNote(int index) {
-	if (index >= 0 && index < count()) {
-		emit noteIsRemoving(number(), index);
-		if (m_autoAddedNoteId > -1) {
-			if (index == m_autoAddedNoteId) // just automatically added note deleted by user
-				m_autoAddedNoteId = -1;
-			else
-				m_autoAddedNoteId--;
-		}
-		delete m_scoreNotes[index];
-		m_scoreNotes.removeAt(index);
-		if (maxNoteCount() > count())
-				emit freeSpace(number(), 1);
-		updateIndexes();
-		updateNotesPos(index);
-    for (int i = index; i < count(); ++i) // refresh neutrals in all next notes
+  if (index >= 0 && index < count()) {
+    emit noteIsRemoving(number(), index);
+    if (m_autoAddedNoteId > -1) {
+      if (index == m_autoAddedNoteId) // just automatically added note deleted by user
+        m_autoAddedNoteId = -1;
+      else
+        m_autoAddedNoteId--;
+    }
+    auto removed = m_scoreNotes[index];
+    qDebug() << debug() << "Preparing to remove note nr" << index << removed->note()->toText() << removed->note()->rtm.string();
+    content(this);
+    int measureNr = measureOfNoteId(index);
+    if (measureNr > -1) {
+        m_measures[measureNr]->removeNote(index - m_measures[measureNr]->firstNoteId());
+    } else
+        qDebug() << debug() << "not such a measure for note with index" << index;
+//     m_allNotesWidth -= removed->width();
+    qDebug() << debug() << "After measure routines index is" << index << "removing id" << removed->index() 
+              << (index != removed->index() ? "BOOOOOOOM!!!!" : "");
+
+    bool tieAfter = !goingDelete() && removed->note()->rtm.tie() == Trhythm::e_tieCont;
+    delete m_scoreNotes.takeAt(index);
+
+    if (m_measures.last()->isEmpty())
+      delete m_measures.takeLast(); // it is empty, so delete it then
+
+//     if (maxNoteCount() > count())
+//     if (spaceForNotes() - m_allNotesWidth - m_gapsSum <= 7.0)
+//         emit freeSpace(number(), 1);
+    updateIndexes();
+    fit();
+    if (index < count())
+      updateNotesPos(index);
+    if (tieAfter) // restore tie between note before removed with note after removed (it should never crash if is TRUE)
+      m_scoreNotes[index - 1]->tieWithNext();
+    for (int i = index; i < count(); ++i) // refresh neutrals in all next notes TODO: IT HAS TO BE DONE BY MEASURE
       m_scoreNotes[i]->moveNote(m_scoreNotes[i]->notePos());
-		if (number() == -1)
-				updateSceneRect();
-	}
+    if (number() == -1) // single note mode only
+        updateSceneRect();
+  }
 }
 
 
 void TscoreStaff::addNotes(int index, QList<TscoreNote*>& nList) {
-	if (index >= 0 && index <= count() && nList.size() <= maxNoteCount() - index)
-	for (int i = index; i < nList.size() + index; i++) {
-		TscoreNote *sn = nList[i - index];
-		m_scoreNotes.insert(i, sn);
-		connectNote(sn);
-		sn->setParentItem(this);
-		sn->setStaff(this);
-	}
-	updateNotesPos(index);
-	updateIndexes();
-	checkNoteRange(false);
+//   if (index >= 0 && index <= count() && nList.size() <= maxNoteCount() - index) {
+      for (int i = index; i < nList.size() + index; i++) {
+        TscoreNote *sn = nList[i - index];
+        m_scoreNotes.insert(i, sn);
+        sn->setStaff(this);
+        sn->setParentItem(this);
+//         sn->setStaff(this);
+      }
+//   }
+  updateIndexes();
+//   updateNotesPos(index); // TODO: update position after resolving measure
+//   updateIndexes();
+  checkNoteRange(false);
 }
 
 
 void TscoreStaff::addNote(int index, TscoreNote* freeNote) {
-	m_scoreNotes.insert(index, freeNote);
-	connectNote(freeNote);
-	freeNote->setParentItem(this);
-	freeNote->setStaff(this);
-	updateNotesPos(index);
-	updateIndexes();
+  m_scoreNotes.insert(index, freeNote);
+  freeNote->setStaff(this);
+  freeNote->setParentItem(this);
+//   freeNote->setStaff(this);
+  updateNotesPos(index);
+  updateIndexes();
 }
 
 
 void TscoreStaff::takeNotes(QList<TscoreNote*>& nList, int from, int to) {
-	if (from >= 0 && from < count() && to < count() && to >= from) {
-		for (int i = from; i <= to; i++) { // 'from' is always the next item after takeAt() on current one
-			m_scoreNotes[from]->disconnect(SIGNAL(noteWasClicked(int)));
-			m_scoreNotes[from]->disconnect(SIGNAL(noteWasSelected(int)));
-			m_scoreNotes[from]->setParentItem(0); // to avoid deleting with staff as its parent
-			nList << m_scoreNotes.takeAt(from);
-		}
-		updateNotesPos();
-		updateIndexes();
-	}
+  if (from >= 0 && from < count() && to < count() && to >= from) {
+    for (int i = from; i <= to; i++) { // 'from' is always the next item after takeAt() on current one
+      m_scoreNotes[from]->setParentItem(0); // to avoid deleting with staff as its parent
+      nList << m_scoreNotes.takeAt(from);
+    }
+    if (m_scoreNotes.isEmpty())
+        emit staffIsEmpty();
+    else {
+        updateNotesPos();
+        updateIndexes();
+    }
+  }
 }
 
 
 void TscoreStaff::updateSceneRect() {
-// 	QRectF scRec = mapToScene(boundingRect()).boundingRect();
-// 	scene()->setSceneRect(0.0, 0.0, scRec.width() + (isPianoStaff() ? 2.5 : 1.5), scRec.height());
+//   QRectF scRec = mapToScene(boundingRect()).boundingRect();
+//   scene()->setSceneRect(0.0, 0.0, scRec.width() + (isPianoStaff() ? 2.5 : 1.5), scRec.height());
 }
 
 
 void TscoreStaff::setNoteDisabled(int index, bool isDisabled) {
-	if (index >=0 && index < m_scoreNotes.size())
-		m_scoreNotes[index]->setReadOnly(isDisabled);
+  if (index >=0 && index < m_scoreNotes.size())
+    m_scoreNotes[index]->setReadOnly(isDisabled);
 }
 
 
 void TscoreStaff::setEnableKeySign(bool isEnabled) {
-	if (isEnabled != (bool)m_keySignature) {
-		if (isEnabled) {
-			m_keySignature = new TscoreKeySignature(scoreScene(), this);
-// 			m_keySignature->setPos(7.0, 0.0);
-			m_keySignature->setPos(6.5, upperLinePos() - TscoreKeySignature::relatedLine);
-			m_keySignature->setClef(m_clef->clef());
-			m_keySignature->setZValue(30);
-			connect(m_keySignature, SIGNAL(keySignatureChanged()), this, SLOT(onKeyChanged()));
-			m_flyAccid = new QGraphicsSimpleTextItem;
-			registryItem(m_flyAccid);
-			m_flyAccid->setFont(TnooFont(5));
-			m_flyAccid->setScale(scoreScene()->accidScale());
+  if (isEnabled != (bool)m_keySignature) {
+    if (isEnabled) {
+      m_keySignature = new TscoreKeySignature(scoreScene(), this);
+      m_keySignature->setPos(6.5, upperLinePos() - TscoreKeySignature::relatedLine);
+      m_keySignature->setClef(m_clef->clef());
+      m_keySignature->setZValue(30);
+      connect(m_keySignature, SIGNAL(keySignatureChanged()), this, SLOT(onKeyChanged()));
+      m_flyAccid = new QGraphicsSimpleTextItem;
+      registryItem(m_flyAccid);
+      m_flyAccid->setFont(TnooFont(5));
+      m_flyAccid->setScale(scoreScene()->accidScale());
       m_flyAccid->setZValue(255);
-			m_flyAccid->hide();
-			if (m_scoreNotes.size())				
-					m_flyAccid->setBrush(m_scoreNotes[0]->mainNote()->brush());
-			m_accidAnim = new TcombinedAnim(m_flyAccid, this);
-			connect(m_accidAnim, SIGNAL(finished()), this, SLOT(accidAnimFinished()));
-			m_accidAnim->setDuration(400);
-			m_accidAnim->setScaling(m_flyAccid->scale(), m_flyAccid->scale() * 4.0);
-// 			m_accidAnim->scaling()->setEasingCurveType(QEasingCurve::OutQuint);
-			m_accidAnim->setMoving(QPointF(), QPointF()); // initialize moving
-			m_accidAnim->moving()->setEasingCurveType(QEasingCurve::OutBack);
-			for (int i = 0; i < m_scoreNotes.size(); i++) {
-				connect(m_scoreNotes[i], SIGNAL(fromKeyAnim(QString,QPointF,int)), this, SLOT(fromKeyAnimSlot(QString,QPointF,int)), Qt::UniqueConnection);
-				connect(m_scoreNotes[i], SIGNAL(toKeyAnim(QString,QPointF,int)), this, SLOT(toKeyAnimSlot(QString,QPointF,int)), Qt::UniqueConnection);
-        connect(m_scoreNotes[i], SIGNAL(destroyed(QObject*)), this, SLOT(noteDestroingSlot(QObject*)), Qt::UniqueConnection);
-// 				connect(m_accidAnim, SIGNAL(finished()), m_scoreNotes[i], SLOT(keyAnimFinished()));
-			}
-		} else {
+      m_flyAccid->hide();
+      if (m_scoreNotes.size())
+          m_flyAccid->setBrush(m_scoreNotes[0]->mainNote()->color());
+      if (m_scoreMeter)
+        m_scoreMeter->setPos(m_keySignature->x() + m_keySignature->boundingRect().width(), upperLinePos());
+    } else {
         m_keySignature->blockSignals(true);
         m_keySignature->setKeySignature(0);
         onKeyChanged();
         delete m_keySignature;
         m_keySignature = 0;
-        m_accidAnim->deleteLater();
-        m_accidAnim = 0;
         delete m_flyAccid;
         m_flyAccid = 0;
-		}
-		updateLines();
-		updateNotesPos();
-	}
+        if (m_scoreMeter)
+          m_scoreMeter->setPos(6.5, upperLinePos());
+    }
+    updateLines();
+    updateNotesPos();
+  }
 }
 
 
 void TscoreStaff::setScordature(Ttune& tune) {
-	if (!hasScordature()) {
-		m_scordature = new TscoreScordature(scoreScene(), this);
-		m_scordature->setParentItem(this);
-		m_scordature->setZValue(35); // above key signature
-	}
-	m_scordature->setTune(tune);
-	if (m_scordature->isScordatured())	{ 
-			m_enableScord = true;
-	} else { // nothing to show - standard tune
-			delete m_scordature;
-			m_scordature = 0;
-			m_enableScord = false;
-	}
-	updateWidth();
-	updateNotesPos();
+  if (!hasScordature()) {
+    m_scordature = new TscoreScordature(scoreScene(), this);
+    m_scordature->setParentItem(this);
+    m_scordature->setZValue(35); // above key signature
+  }
+  m_scordature->setTune(tune);
+  if (m_scordature->isScordatured())  {
+      m_enableScord = true;
+  } else { // nothing to show - standard tune
+      delete m_scordature;
+      m_scordature = 0;
+      m_enableScord = false;
+  }
+  updateWidth();
+  updateNotesPos();
 }
 
 
 void TscoreStaff::removeScordatute() {
-	delete m_scordature; 
-	m_scordature = 0; 
-	m_enableScord = false;
-	updateWidth();
-	updateNotesPos();
+  delete m_scordature;
+  m_scordature = 0;
+  m_enableScord = false;
+  updateWidth();
+  updateNotesPos();
 }
 
 
+void TscoreStaff::setMeter(const Tmeter& m) {
+  bool changed = false;
+  if (m.meter() != Tmeter::e_none && !m_scoreMeter) { // create score meter
+      m_scoreMeter = new TscoreMeter(scoreScene(), this);
+      m_scoreMeter->setPos(6.5 + (m_keySignature ? m_keySignature->boundingRect().width() : 0.0), upperLinePos());
+      m_scoreMeter->setZValue(30);
+      m_scoreMeter->setMeter(m);
+      changed = true;
+      connect(m_scoreMeter, &TscoreMeter::meterChanged, [=]{
+            updateWidth();
+            updateNotesPos();
+      });
+  } else if (m_scoreMeter && m.meter() == Tmeter::e_none) { // delete meter
+      delete m_scoreMeter;
+      m_scoreMeter = nullptr;
+      if (m_keySignature)
+        m_keySignature->setX(6.5);
+      changed = true;
+  } else if (m_scoreMeter)
+      m_scoreMeter->setMeter(m); // score meter will call signal to update staff
+  scoreScene()->setScoreMeter(m_scoreMeter);
+  if (changed && !measures().isEmpty()) {
+    measures().first()->changeMeter(m);
+    for (int i = 0; i < m_scoreNotes.size(); i++) // set default rhythm value for all notes or hide all stems when no rhythms
+      m_scoreNotes[i]->setRhythmEnabled((bool)m_scoreMeter);
+    updateWidth();
+    updateNotesPos();
+  }
+}
+
+
+
 void TscoreStaff::setDisabled(bool disabled) {
-	scoreClef()->setReadOnly(disabled);
+  scoreClef()->setReadOnly(disabled);
   scoreClef()->setAcceptHoverEvents(!disabled); // stops displaying status tip
-	if (scoreKey()) {
-		scoreKey()->setAcceptHoverEvents(!disabled); // stops displaying status tip
-		scoreKey()->setReadOnly(disabled);
-	}
-	for (int i = 0; i < count(); i++)
-		m_scoreNotes[i]->setReadOnly(disabled);
-	if (disabled && count())
-		m_scoreNotes[0]->hideWorkNote();
-// 	setControlledNotes(!disabled);
+  if (scoreKey()) {
+    scoreKey()->setAcceptHoverEvents(!disabled); // stops displaying status tip
+    scoreKey()->setReadOnly(disabled);
+  }
+  for (int i = 0; i < count(); i++)
+    m_scoreNotes[i]->setReadOnly(disabled);
+  if (m_scoreMeter)
+    m_scoreMeter->setReadOnly(!disabled);
+//   setControlledNotes(!disabled);
 }
 
 
@@ -341,127 +410,347 @@ QRectF TscoreStaff::boundingRect() const {
 
 
 int TscoreStaff::accidNrInKey(int noteNr, char key) {
-	int accidNr;
-	switch ((56 + notePosRelatedToClef(noteNr, m_offset)) % 7 + 1) {
-		case 1: accidNr = 1; break;
-		case 2: accidNr = 3; break;
-		case 3: accidNr = 5; break;
-		case 4: accidNr = 0; break;
-		case 5: accidNr = 2; break;
-		case 6: accidNr = 4; break;
-		case 7: accidNr = 6; break;
-	}
-	if (key < 0)
-		accidNr = 6 - accidNr;
-	return accidNr;
+  int accidNr;
+  switch ((56 + notePosRelatedToClef(noteNr, m_offset)) % 7 + 1) {
+    case 1: accidNr = 1; break;
+    case 2: accidNr = 3; break;
+    case 3: accidNr = 5; break;
+    case 4: accidNr = 0; break;
+    case 5: accidNr = 2; break;
+    case 6: accidNr = 4; break;
+    case 7: accidNr = 6; break;
+  }
+  if (key < 0)
+    accidNr = 6 - accidNr;
+  return accidNr;
 }
 
 
 void TscoreStaff::setPianoStaff(bool isPiano) {
-	if (isPiano != m_isPianoStaff) {
-		m_isPianoStaff = isPiano;
-		if (isPiano) {
-				m_upperLinePos = 14.0;
-				m_lowerStaffPos = 28.0;
-				m_height = 42.0;
+  if (isPiano != m_isPianoStaff) {
+    m_isPianoStaff = isPiano;
+    if (isPiano) {
+        m_upperLinePos = 14.0;
+        m_lowerStaffPos = 28.0;
+        m_height = 44.0;
         createBrace();
-		} else {
-				m_upperLinePos = 16.0;
-				m_lowerStaffPos = 0.0;
-				m_height = 36.0;
+    } else {
+        m_upperLinePos = 16.0;
+        m_lowerStaffPos = 0.0;
+        m_height = 38.0;
         delete m_brace;
-		}
-		prepareStaffLines();
-		if (m_keySignature)
-				m_keySignature->setPos(7.0, upperLinePos() - TscoreKeySignature::relatedLine);
-		for (int i = 0; i < count(); i++) {
-			noteSegment(i)->adjustSize();
-			noteSegment(i)->setAmbitus(isPiano ? 40 : 34, 2); // TODO It may cause problems when any other class will invoke note ambitus
-		}
-		if (count())
-			scoreScene()->adjustCursor(noteSegment(0));
-		emit pianoStaffSwitched();
-	}
+    }
+    prepareStaffLines();
+    if (m_scoreMeter) {
+        m_scoreMeter->setPianoStaff(m_isPianoStaff);
+        m_scoreMeter->setY(upperLinePos());
+    }
+    if (m_keySignature)
+        m_keySignature->setPos(6.5, upperLinePos() - TscoreKeySignature::relatedLine);
+    for (int i = 0; i < count(); i++) {
+      noteSegment(i)->adjustSize();
+      noteSegment(i)->setAmbitus(isPiano ? 40 : 34, 2); // TODO It may cause problems when any other class will invoke note ambitus
+    }
+    emit pianoStaffSwitched();
+  }
 }
 
 
 int TscoreStaff::fixNotePos(int pianoPos) {
-	if (isPianoStaff() && pianoPos > lowerLinePos() - 4)
-		return pianoPos - 2; // piano staves gap
-	else
-		return pianoPos;
+  if (isPianoStaff() && pianoPos > lowerLinePos() - 4)
+    return pianoPos - 2; // piano staves gap
+  else
+    return pianoPos;
 }
 
 
 void TscoreStaff::setViewWidth(qreal viewW) {
-  m_viewWidth = viewW;
-  if (viewW > 0.0)
-    m_maxNotesCount = getMaxNotesNr(viewW);
-  else
-    m_maxNotesCount = 0;
-  updateLines(); // calls updateWidth() as well
-  updateNotesPos();
+  qDebug() << debug() << "Old width" << m_viewWidth << "New width" << viewW;
+  if (viewW != m_viewWidth) {
+      m_viewWidth = viewW;
+      if (viewW > 0.0)
+        m_maxNotesCount = getMaxNotesNr(mapFromScene(viewW, 0.0).x());
+      else
+        m_maxNotesCount = 0;
+      updateLines(); // calls updateWidth() as well
+      updateNotesPos();
+  }
 }
 
 
 void TscoreStaff::checkNoteRange(bool doEmit) {
-	if (m_lockRangeCheck)
-		return;
-	qreal oldHi = m_hiNotePos, oldLo = m_loNotePos;
-		findHighestNote();
-		findLowestNote();
-		if (doEmit && oldHi != m_hiNotePos)
-			emit hiNoteChanged(number(), oldHi - m_hiNotePos);
-		if (doEmit && oldLo != m_loNotePos)
-			emit loNoteChanged(number(), m_loNotePos - oldLo);
-		return;
+  if (m_lockRangeCheck)
+    return;
+  qreal oldHi = m_hiNotePos, oldLo = m_loNotePos;
+    findHighestNote();
+    findLowestNote();
+    if (doEmit && oldHi != m_hiNotePos)
+      emit hiNoteChanged(number(), oldHi - m_hiNotePos);
+    if (doEmit && oldLo != m_loNotePos)
+      emit loNoteChanged(number(), m_loNotePos - oldLo);
+    return;
+}
+
+
+int TscoreStaff::measureOfNoteId(int id) {
+  if (m_measures.isEmpty()) {
+    qDebug() << debug() << "No measures in this staff, can not find it for note" << id;
+    return - 1;
+  }
+  if (m_measures.count() == 1)
+    return 0;
+  auto lastMeas = lastMeasure();
+  if (lastMeas && !lastMeas->isEmpty()) {
+    if (id >= lastMeas->lastNoteId())
+      return m_measures.count() - 1; // last measure for the last note
+  }
+  for (int i = 0; i < m_measures.size(); ++i) {
+    if (id >= m_measures[i]->firstNoteId() && id <= m_measures[i]->lastNoteId())
+      return i;
+  }
+
+  // TODO: It should never occur, delete it
+  qDebug() << debug() << "There is no measure for note id:" << id << "in this staff with notes number" << count();
+  return -1;
+}
+
+
+TscoreMeasure* TscoreStaff::nextMeasure(TscoreMeasure* before) {
+  if (before == lastMeasure()) {
+      auto st = nextStaff();
+      return st ? st->firstMeasure() : nullptr;
+  } else
+      return m_measures[before->id() + 1];
 }
 
 
-void TscoreStaff::enableToAddNotes(bool alowAdding) {
-	scoreScene()->left()->enableToAddNotes(alowAdding);
-	scoreScene()->right()->enableToAddNotes(alowAdding);
+TscoreStaff* TscoreStaff::nextStaff() {
+  auto st = this;
+  emit getNextStaff(st);
+  return st;
+}
+
+
+TscoreStaff * TscoreStaff::prevStaff() {
+  auto st = this;
+  emit getPrevStaff(st);
+  return st;
+}
+
+
+/**
+ * It is hard to imagine when other than the last measure of the staff is taken
+ */
+TscoreMeasure* TscoreStaff::takeMeasure(int measId) {
+  qDebug()  << debug() << "Taking measure" << measId;
+  if (measId >= 0 && measId < m_measures.count()) {
+      if (m_measures[measId]->isEmpty()) {
+        qDebug()  << debug() << "Measure" << measId << " to take is empty";
+        return nullptr;
+      }
+      int firstIndex = m_measures[measId]->firstNoteId();
+      int lastIndex = m_measures[measId]->lastNoteId();
+      for (int i = firstIndex; i <= lastIndex; ++i) {
+          m_scoreNotes[firstIndex]->setParentItem(0); // to avoid deleting with staff as its parent
+          m_scoreNotes.removeAt(firstIndex); // when note segment with firstIndex is removed the next segment is at the firstIndex position
+      }
+      updateIndexes();
+      auto retMeasure = m_measures.takeAt(measId); // take measure from list before fitting
+      fit();
+      // No need to update measure numbers
+      // TODO: positioning?
+      return retMeasure;
+  } else
+      qDebug() << debug() << "Unable to take measure" << measId << "out of range";
+  return nullptr;
+}
+
+
+/**
+ * Only entire measures are inserted, eventually partial, when it is the last measure,
+ * so there is no need to recalculate measure (content and beaming) just set notes position.
+ */
+void TscoreStaff::insertMeasure(int id, TscoreMeasure* m) {
+  if (m == nullptr) {
+    qDebug() << debug() << "Trying to insert measure which is NULL of id:" << id;
+    return;
+  }
+  qDebug() << debug() << "Inserting measure" << id;
+  int noteId = 0;
+  if (id > 0) // find index where to insert notes of the measure
+      noteId = m_measures[id - 1]->lastNoteId() + 1;
+  addNotes(noteId, m->notes());
+  m_measures.insert(id, m);
+//   addNotes(noteId, m->notes());
+//   m->setStaff(this);
+  for (int i = 0; i < m_measures.size(); ++i)
+    m_measures[i]->setId(i);
+  m->setStaff(this);
+  fit();
+  updateNotesPos();
+}
+
+
+char TscoreStaff::debug() {
+  QTextStream o(stdout);
+  o << "\033[01;34m[" << number() << " STAFF]\033[01;00m";
+  return 32; // fake
 }
 
 //##########################################################################################################
 //########################################## PROTECTED   ###################################################
 //##########################################################################################################
 
-void TscoreStaff::prepareStaffLines() {  
-	m_5lines->setPianoStaff(isPianoStaff());
+void TscoreStaff::prepareStaffLines() {
+  m_5lines->setPianoStaff(isPianoStaff());
   m_5lines->setPos(0.0, upperLinePos());
-	updateLines();
-	updateNotesPos();
-}
-
-
-void TscoreStaff::insert(int index) {
-	TscoreNote *newNote = new TscoreNote(scoreScene(), this, index);
-	newNote->setZValue(50);
-	connectNote(newNote);
-	m_scoreNotes.insert(index, newNote);
+  updateLines();
+  updateNotesPos();
 }
 
 
 void TscoreStaff::setEnableScordtature(bool enable) {
-	if (enable != m_enableScord) {
-		m_enableScord = enable;
-		updateWidth();
-		updateNotesPos();
-	}
+  if (enable != m_enableScord) {
+    m_enableScord = enable;
+    updateWidth();
+    updateNotesPos();
+  }
 }
 
 
 qreal TscoreStaff::notesOffset() {
-	qreal off = 0.0;
-	if (m_keySignature) {
+  qreal off = 0.0;
+  if (m_keySignature) {
       if (m_tidyKey)
         off = qAbs<char>(m_keySignature->keySignature()) * 1.3;
       else
         off = KEY_WIDTH + 1;
   } else if (m_enableScord)
-			off = KEY_WIDTH / 2;
-	return off;
+      off = KEY_WIDTH / 2;
+  if (m_scoreMeter)
+    off += m_scoreMeter->width();
+  return off;
+}
+
+
+void TscoreStaff::noteChangedWidth(int noteId) {
+  Q_UNUSED(noteId)
+  updateNotesPos();
+}
+
+
+void TscoreStaff::prepareNoteChange(TscoreNote* sn) {
+  if (sn == nullptr)
+    return;
+
+  if (sn->rhythmChanged() || sn->accidChanged())
+    fit();
+}
+
+
+TscoreNote* TscoreStaff::insertNote(const Tnote& note, int index, bool disabled) {
+  index = qBound(0, index, m_scoreNotes.size()); // 0 - adds at the begin, size() - adds at the end
+  if (index) {
+    auto prev = m_scoreNotes[index - 1];
+    if (prev->note()->rtm.tie() == Trhythm::e_tieStart || prev->note()->rtm.tie() == Trhythm::e_tieCont)
+        prev->tieRemove(); // it will also set a proper tie of next note if the previous was connected with it before inserting
+  }
+  auto n = insert(index);
+  setNote(index, note);
+  m_scoreNotes[index]->setZValue(50);
+  setNoteDisabled(index, disabled);
+  updateIndexes();
+  return n;
+}
+
+
+void TscoreStaff::fit() {
+  if (m_scoreNotes.isEmpty()) {
+    qDebug() << debug() << "Empty staff - nothing to fit";
+    return;
+  }
+
+  int measureNr = 0, mCnt = 0;
+  qreal factor = 2.0;
+  m_gapsSum = 0.0;
+  m_allNotesWidth = 0.0;
+  bool needShift = false;
+
+  for (int n = 0; n < m_scoreNotes.size(); ++n) {
+      if (mCnt < m_measures.count() && !m_measures[mCnt]->isEmpty() && noteSegment(n) == m_measures[mCnt]->firstNote()) {
+        measureNr = mCnt; // determine number of current measure
+        mCnt++;
+      }
+      m_gapsSum += noteSegment(n)->space();
+      m_allNotesWidth += noteSegment(n)->width();
+      if (n > 1) {
+        factor = (spaceForNotes() - m_allNotesWidth) / m_gapsSum;
+        if (factor < 1.0) { // shift current measure and the next ones
+          needShift = true;
+          break; // rest of the notes goes to the next staff
+        }
+      }
+  }
+  if (needShift) {
+      if (measureNr == 0) {
+          qDebug() << debug() << "There is no space in the staff but measure is not full. Breaking measures is NOT IMPLEMENTED!";
+      } else {
+          qDebug() << debug() << "Fitting detects need of shifting from measure" << measureNr;
+          if (m_measures.count() - measureNr - 1 > 1) {
+            qDebug() << debug() << "THE NEXT STAFF WILL FIT ITSELF A FEW TIMES" << m_measures.count() - measureNr - 1;
+            // TODO: if more measures are shifted this way, the next staff will fit itself a few times -TRY TO AVOID THAT
+          }
+          emit moveMeasure(this, m_measures.count() - 1); // it will perform fitting as well
+      }
+  } else if (factor > 2.0) { // staff has free space
+      auto st = nextStaff();
+      if (st && st != this && st->count()) {
+        qDebug() << debug() << "staff has free space - getting fist measure of staff" << st->number();
+        if (st->firstMeasure()->notesWidth() <= width() - contentWidth(1.0)) {
+          insertMeasure(m_measures.count(), st->takeMeasure(0));
+          st->updateNotesPos();
+        }
+      }
+  }
+  m_gapFactor = qBound(1.0, factor, 2.0); // notes in this staff are ready to positioning
+  qDebug() << debug() << "fitting... Gap factor is" << m_gapFactor;
+}
+
+
+void TscoreStaff::shiftToMeasure(int measureNr, QList<TscoreNote*>& notesToShift) {
+  qDebug() << debug() << "shift" << notesToShift.count() << "notes to measure" << measureNr;
+  if (measureNr == m_measures.count()) { // no such a measure - create it first
+    qDebug() << debug() << "Create new measure nr" << m_measures.count();
+    m_measures << new TscoreMeasure(this, m_measures.count());
+  }
+  m_measures[measureNr]->prependNotes(notesToShift);
+}
+
+
+int TscoreStaff::shiftFromMeasure(int measureNr, int dur, QList<TscoreNote*>& notesToShift) {
+  int retDur = 0;
+  if (measureNr < m_measures.count()) {
+      retDur = m_measures[measureNr]->takeAtStart(dur, notesToShift);
+      if (m_measures[measureNr]->isEmpty()) {
+        qDebug() << debug() << "Measure" << measureNr << "is empty - resetting duration" << retDur;
+        retDur = 0; // next (the last) measure is not able to return required duration, no tie required
+        delete m_measures.takeLast(); // it is empty, so delete it then
+      }
+  } else {
+      auto st = nextStaff();
+      if (st && st != this) {
+        qDebug() << debug() << "Looking for notes in the next staff id" << st->number();
+        st->shiftFromMeasure(0, dur, notesToShift);
+        if (!notesToShift.isEmpty()) {
+          QList<TscoreNote*> fakeList; // notesToShift has already all notes
+          st->takeNotes(fakeList, notesToShift.first()->index(), notesToShift.last()->index());
+          qDebug() << debug() << "Setting new staff for" << notesToShift.size() << "notes";
+          addNotes(count(), notesToShift);
+          content(this);
+        }
+      }
+  }
+  return retDur;
 }
 
 
@@ -470,8 +759,8 @@ qreal TscoreStaff::notesOffset() {
 //##########################################################################################################
 
 void TscoreStaff::onClefChanged(Tclef clef) {
-	setPianoStaff(clef.type() == Tclef::e_pianoStaff);
-	switch(clef.type()) {
+  setPianoStaff(clef.type() == Tclef::e_pianoStaff);
+  switch(clef.type()) {
     case Tclef::e_treble_G:
       m_offset = TnoteOffset(3, 2); break;
     case Tclef::e_treble_G_8down:
@@ -484,33 +773,27 @@ void TscoreStaff::onClefChanged(Tclef clef) {
       m_offset = TnoteOffset(4, 1); break;
     case Tclef::e_tenor_C:
       m_offset = TnoteOffset(2, 1); break;
-		case Tclef::e_pianoStaff:
+    case Tclef::e_pianoStaff:
       m_offset = TnoteOffset(3, 2); break;
-		default: break;
+    default: break;
   }
   m_lockRangeCheck = true;
   scoreClef()->setClef(clef);
   if (m_keySignature) {
-			disconnect(m_keySignature, SIGNAL(keySignatureChanged()), this, SLOT(onKeyChanged()));
+      disconnect(m_keySignature, SIGNAL(keySignatureChanged()), this, SLOT(onKeyChanged()));
       m_keySignature->setClef(m_clef->clef());
-			connect(m_keySignature, SIGNAL(keySignatureChanged()), this, SLOT(onKeyChanged()));
-	}
-	if (m_scoreNotes.size()) {
-			for (int i = 0; i < m_scoreNotes.size(); i++) {
-				if (m_scoreNotes[i]->notePos()) {
-						setNote(i, *(m_scoreNotes[i]->note()));
-				} 
-			}
-	}
-	m_lockRangeCheck = false;
-	checkNoteRange();
-	emit clefChanged(scoreClef()->clef());
-}
-
-
-void TscoreStaff::noteChangedAccid(int accid) {
-	if (scoreScene()->left())
-		scoreScene()->left()->setAccidental(accid);
+      connect(m_keySignature, SIGNAL(keySignatureChanged()), this, SLOT(onKeyChanged()));
+  }
+  if (m_scoreNotes.size()) {
+      for (int i = 0; i < m_scoreNotes.size(); i++) {
+        if (m_scoreNotes[i]->notePos()) {
+            setNote(i, *(m_scoreNotes[i]->note()));
+        }
+      }
+  }
+  m_lockRangeCheck = false;
+  checkNoteRange();
+  emit clefChanged(scoreClef()->clef());
 }
 
 
@@ -525,215 +808,233 @@ void TscoreStaff::setTidyKey(bool tidy) {
 
 void TscoreStaff::applyAutoAddedNote() {
   if (m_autoAddedNoteId > -1) {
-    m_addTimer->stop();
     emit noteIsAdding(number(), m_autoAddedNoteId);
-    if (m_autoAddedNoteId == maxNoteCount() - 1) // new staff is wanted
-        emit noMoreSpace(number());
+//     if (m_autoAddedNoteId == maxNoteCount() - 1) // new staff is wanted
+//     if (spaceForNotes() - m_allNotesWidth - m_gapsSum < 7.0)
+//         emit noMoreSpace(number());
     m_autoAddedNoteId = -1;
   }
 }
 
+
+// TODO: keep var for it instead of following calculations (it could be always actual when take care of it during clef/meter/key width changes)
+qreal TscoreStaff::spaceForNotes() {
+  return width() - (m_clef ? m_clef->boundingRect().width() : 0.0)
+                 - (m_keySignature ? m_keySignature->boundingRect().width() : 0.0)
+                 - (m_scoreMeter ? m_scoreMeter->width() : 0.0);
+}
+
+
+qreal TscoreStaff::contentWidth(qreal gapFact) {
+  return (m_clef ? m_clef->boundingRect().width() : 0.0)
+          + (m_keySignature ? m_keySignature->boundingRect().width() : 0.0)
+          + (m_scoreMeter ? m_scoreMeter->width() : 0.0)
+          + m_allNotesWidth + m_gapsSum * gapFact;
+}
+
+
+bool TscoreStaff::hasSpaceFor(qreal newWidth) {
+  return m_allNotesWidth + newWidth + (m_gapsSum * m_gapFactor) <= spaceForNotes();
+//   return width() - m_scoreNotes.last()->rightX() >= newWidth;
+}
+
+
+/**
+ * m_allNotesWidth + m_scoreNotes.first()->estimateWidth(n) ===> physical width of all notes
+ */
+bool TscoreStaff::hasSpaceFor(const Tnote& n) {
+  return m_allNotesWidth + m_scoreNotes.first()->estimateWidth(n) + (m_gapsSum * m_gapFactor) <= spaceForNotes();
+}
+
 //##########################################################################################################
 //####################################### PROTECTED SLOTS  #################################################
 //##########################################################################################################
 
 void TscoreStaff::onPianoStaffChanged(Tclef clef) {
-	setPianoStaff(clef.type() == Tclef::e_pianoStaff);
-	scoreClef()->setClef(clef);
+  setPianoStaff(clef.type() == Tclef::e_pianoStaff);
+  scoreClef()->setClef(clef);
 }
 
 
 void TscoreStaff::onKeyChanged() {
   for (int i = 0; i < m_scoreNotes.size(); i++) {
-    if (m_scoreNotes[i]->notePos())
-        m_scoreNotes[i]->moveNote(m_scoreNotes[i]->notePos());
+    auto noteSeg = m_scoreNotes[i];
+    if (noteSeg->notePos())
+        noteSeg->moveNote(noteSeg->notePos());
   }
 }
 
 
 void TscoreStaff::onNoteClicked(int noteIndex) {
-	if (m_autoAddedNoteId > -1) {
-		if (noteIndex == m_autoAddedNoteId - 1) {
-				m_addTimer->stop();
-				m_addTimer->start(2000);
-		} else
-				addNoteTimeOut();
-	}
-  int globalNr = notePosRelatedToClef(fixNotePos(m_scoreNotes[noteIndex]->notePos())
-				+ m_scoreNotes[noteIndex]->ottava() * 7, m_offset);
-	m_scoreNotes[noteIndex]->note()->note = (char)(56 + globalNr) % 7 + 1;
-	m_scoreNotes[noteIndex]->note()->octave = (char)(56 + globalNr) / 7 - 8;
-	m_scoreNotes[noteIndex]->note()->alter = (char)m_scoreNotes[noteIndex]->accidental();
-  for (int i = noteIndex + 1; i < count(); ++i) // refresh neutrals in all next notes
+  updatePitch(noteIndex);
+//   auto noteOfId = m_scoreNotes[noteIndex];
+//   int globalNr = notePosRelatedToClef(fixNotePos(noteOfId->notePos()) + noteOfId->ottava() * 7, m_offset);
+//   noteOfId->note()->note = (char)(56 + globalNr) % 7 + 1;
+//   noteOfId->note()->octave = (char)(56 + globalNr) / 7 - 8;
+//   noteOfId->note()->alter = (char)noteOfId->accidental();
+  if (m_autoAddedNoteId > -1) {
+      addNoteTimeOut();
+  }
+
+  for (int i = noteIndex + 1; i < count(); ++i) // refresh neutrals in all next notes // TODO: move it to measure
       m_scoreNotes[i]->moveNote(m_scoreNotes[i]->notePos());
-	emit noteChanged(noteIndex);
-	checkNoteRange();
-	// when score is in record mode the signal above invokes adding new note so count is increased and code below is skipped - This is a magic 
-	if (scoreScene()->right() && scoreScene()->right()->notesAddingEnabled() && noteIndex == count() - 1 && noteIndex < maxNoteCount() - 1) {
-		m_addTimer->stop();
-		insert(noteIndex + 1);
-		m_scoreNotes.last()->popUpAnim(300);
-		updateIndexes();
-		updateNotesPos(noteIndex + 1);
-		m_addTimer->start(2000);
-		m_autoAddedNoteId = noteIndex + 1;
-	}
+
+  emit noteChanged(noteIndex);
+  checkNoteRange();
 }
 
 
 void TscoreStaff::onNoteSelected(int noteIndex) {
-// 	if (selectableNotes() || controlledNotes()) { // no need to check, note does it
-		emit noteSelected(noteIndex);
+//   if (selectableNotes() || controlledNotes()) { // no need to check, note does it
+    emit noteSelected(noteIndex);
 }
 
 
 
 void TscoreStaff::onAccidButtonPressed(int accid) {
-	scoreScene()->setCurrentAccid(accid);
-	/** It is enough to do this as long as every TscoreNote handles mouseHoverEvent
-	 * which checks value set above and changes accidental symbol if necessary. */
+  scoreScene()->setCurrentAccid(accid);
+  /** It is enough to do this as long as every TscoreNote handles mouseHoverEvent
+   * which checks value set above and changes accidental symbol if necessary. */
 }
 
 
-void TscoreStaff::fromKeyAnimSlot(const QString& accidText, const QPointF& accidPos, int notePos) {
-	m_flyAccid->setText(accidText);
-	m_accidAnim->setMoving(mapFromScene(m_keySignature->accidTextPos(accidNrInKey(notePos, scoreKey()->keySignature()))),
-												 mapFromScene(accidPos));
-	m_accidAnim->startAnimations();
-	m_flyAccid->show();
-}
-
-
-void TscoreStaff::toKeyAnimSlot(const QString& accidText, const QPointF& accidPos, int notePos) {
-  if (m_noteWithAccidAnimed)
-    return;
-  else
-     m_noteWithAccidAnimed = static_cast<TscoreNote*>(sender());
-	m_flyAccid->setText(accidText);
-	m_accidAnim->setMoving(mapFromScene(accidPos),
-												 mapFromScene(m_keySignature->accidTextPos(accidNrInKey(notePos, scoreKey()->keySignature()))));
-	m_accidAnim->startAnimations();
-	m_flyAccid->show();
+void TscoreStaff::noteGoingDestroy(QObject* n) {
+  if (n == m_noteWithAccidAnimed)
+    m_noteWithAccidAnimed = 0;
 }
 
 
-void TscoreStaff::accidAnimFinished() {
-	m_flyAccid->hide();
-  if (m_noteWithAccidAnimed) {
-    m_noteWithAccidAnimed->keyAnimFinished();
-    m_noteWithAccidAnimed = 0;
+void TscoreStaff::addNoteTimeOut() {
+  if (m_autoAddedNoteId > -1) {
+    if (noteSegment(m_autoAddedNoteId)->notePos()) { // automatically added note was set - approve it
+        applyAutoAddedNote(); // puts m_autoAddedNoteId back to -1
+        qDebug() << debug() << "auto note approved" << m_scoreNotes.last()->note()->rtm.xmlType() << m_scoreNotes.last()->rhythm()->xmlType();
+        m_measures.last()->insertNote(m_scoreNotes.last()->index() - m_measures.last()->firstNoteId(), m_scoreNotes.last());
+        fit();
+    } else if (m_autoAddedNoteId != count() - 1) { // some note was added after this one - ignore
+        m_autoAddedNoteId = -1;
+    } else { // user gave up
+        delete noteSegment(m_autoAddedNoteId);
+        m_scoreNotes.removeAt(m_autoAddedNoteId);
+        m_autoAddedNoteId = -1;
+    }
   }
 }
 
 
-void TscoreStaff::noteDestroingSlot(QObject* n) {
-  Q_UNUSED(n)
-  if (sender() == m_noteWithAccidAnimed)
-    m_noteWithAccidAnimed = 0;
+void TscoreStaff::updatePitch(int noteIndex) {
+  auto sn = m_scoreNotes[noteIndex];
+  int globalNr = notePosRelatedToClef(fixNotePos(sn->notePos()) + sn->ottava() * 7, m_offset);
+  sn->note()->note = (char)(56 + globalNr) % 7 + 1;
+  sn->note()->octave = (char)(56 + globalNr) / 7 - 8;
+  sn->note()->alter = (char)sn->accidental();
+  qDebug() << debug() << "updating pitch of" << noteIndex << sn->note()->toText();
 }
 
 
-void TscoreStaff::addNoteTimeOut() {
-	if (m_autoAddedNoteId > -1) {
-		if (noteSegment(m_autoAddedNoteId)->notePos()) // automatically added note was set - approve it
-				applyAutoAddedNote(); // puts m_autoAddedNoteId back to -1
-		else if (noteSegment(m_autoAddedNoteId) == scoreScene()->currentNote()) {// note was not set but cursor is still over it
-				m_addTimer->stop();
-				m_addTimer->start(1000); // wait next 1000 ms
-		} else if (m_autoAddedNoteId != count() - 1) { // some note was added after this one - ignore
-				m_autoAddedNoteId = -1;
-		} else { // user gave up
-				delete noteSegment(m_autoAddedNoteId);
-				m_scoreNotes.removeAt(m_autoAddedNoteId);
-				m_autoAddedNoteId = -1;
-		}
-	}
-}
-
 //##########################################################################################################
 //########################################## PRIVATE     ###################################################
 //##########################################################################################################
 
 void TscoreStaff::updateIndexes() {
-	for (int i = 0; i < m_scoreNotes.size(); i++)
-		m_scoreNotes[i]->changeIndex(i); // Update index of next notes in the list
+  qDebug() << debug() << "updating indexes";
+  for (int i = 0; i < m_scoreNotes.size(); i++)
+    m_scoreNotes[i]->changeIndex(i); // Update index of next notes in the list
 }
 
 
 void TscoreStaff::updateNotesPos(int startId) {
-	qreal off = notesOffset();
-	for (int i = startId; i < m_scoreNotes.size(); i++) // update positions of the notes
-    m_scoreNotes[i]->setPos(7.0 + off + i * m_scoreNotes[0]->boundingRect().width(), 0);
+  qDebug() << debug() << "updating notes positions from" << startId;
+  if (m_scoreNotes.isEmpty())
+    return;
+
+  if (startId == 0)
+    m_scoreNotes[0]->setX(6.5 + notesOffset());
+  else
+    m_scoreNotes[startId]->setX(m_scoreNotes[startId - 1]->rightX());
+
+  int m = 0;
+  for (int i = startId + 1; i < m_scoreNotes.size(); i++) { // update positions of the notes
+      auto noteSeg = m_scoreNotes[i]; // cache pointer to TscoreNote for multiple reuse
+      noteSeg->setX(m_scoreNotes[i - 1]->rightX());
+      if (m < m_measures.count() && !m_measures[m]->isEmpty() && noteSeg == m_measures[m]->lastNote()) {
+        m_measures[m]->checkBarLine();
+        m++;
+      }
+      noteSeg->update();
+  }
+//     m_scoreNotes[i]->setPos(7.0 + off + i * m_scoreNotes[0]->boundingRect().width(), 0);
 }
 
 
 void TscoreStaff::updateLines() {
-	updateWidth();
+  updateWidth();
   m_5lines->setWidth(width());
 }
 
 
 void TscoreStaff::updateWidth() {
-	qreal off = notesOffset();
-	if (m_scoreNotes.size() < 1)
-			m_width = 10.0 + off + 2.0;
-	else
-			m_width = 10.0 + off + m_scoreNotes.size() * m_scoreNotes[0]->boundingRect().width() + 2.0;
-	if (m_viewWidth > 0.0)
-			m_width = m_viewWidth;
+  qreal off = notesOffset();
+  if (m_scoreNotes.size() < 1)
+      m_width = 10.0 + off + 2.0;
+  else
+      m_width = 10.0 + off + m_scoreNotes.size() * m_scoreNotes[0]->boundingRect().width() + 2.0;
+  if (m_viewWidth > 0.0)
+      m_width = m_viewWidth;
 }
 
 
 void TscoreStaff::createBrace() {
-	m_brace = new QGraphicsSimpleTextItem();
-	registryItem(m_brace);
+  m_brace = new QGraphicsSimpleTextItem();
+  registryItem(m_brace);
   m_brace->setFont(TnooFont(22));
-	m_brace->setText(QString(QChar(0xe16c)));
-	m_brace->setBrush(qApp->palette().text().color());
+  m_brace->setText(QString(QChar(0xe16c)));
+  m_brace->setBrush(qApp->palette().text().color());
 //   m_brace->setScale(22.18 / m_brace->boundingRect().height());
   m_brace->setScale(1.05619047619047619047);
-	m_brace->setPos(-2.4 * m_brace->scale(), upperLinePos() + (22.18 - m_brace->boundingRect().height() * m_brace->scale()) / 2.0);
+  m_brace->setPos(-2.4 * m_brace->scale(), upperLinePos() + (22.18 - m_brace->boundingRect().height() * m_brace->scale()) / 2.0);
   m_brace->setZValue(7);
 }
 
 
 int TscoreStaff::getMaxNotesNr(qreal maxWidth) {
-	maxWidth -= 1.0; // staff lines margins
-	if (scoreClef())
-		maxWidth -= CLEF_WIDTH;
-	if (scoreKey())
-		maxWidth -= KEY_WIDTH + 1;
-	else if (hasScordature())
-		maxWidth -= KEY_WIDTH / 2;
-	return int(maxWidth / 7.0);
+  maxWidth -= 1.0; // staff lines margins
+  if (scoreClef())
+    maxWidth -= CLEF_WIDTH;
+  if (scoreKey())
+    maxWidth -= KEY_WIDTH + 1;
+  else if (hasScordature())
+    maxWidth -= KEY_WIDTH / 2;
+  return int(maxWidth / 7.0);
 }
 
 
 void TscoreStaff::findHighestNote() {
-	m_hiNotePos = upperLinePos() - 4.0;
-	for (int i = 0; i < m_scoreNotes.size(); i++)
-		if (m_scoreNotes[i]->notePos()) // is visible
-			m_hiNotePos = qMin(qreal(m_scoreNotes[i]->notePos() - 2), m_hiNotePos);
+  m_hiNotePos = upperLinePos() - 4.0;
+  for (int i = 0; i < m_scoreNotes.size(); i++) {
+    auto noteSeg = m_scoreNotes[i];
+    if (noteSeg->notePos()) // is visible
+      m_hiNotePos = qMin(qreal(noteSeg->notePos() - (noteSeg->note()->rtm.stemDown() ? 2 : 4)), m_hiNotePos);
+  }
 }
 
 
 void TscoreStaff::findLowestNote() {
-	if (hasScordature()) {
-		m_loNotePos = height();
-		return;
-	}	
-	m_loNotePos = (isPianoStaff() ? lowerLinePos(): upperLinePos()) + 13.0;
-	for (int i = 0; i < m_scoreNotes.size(); i++)
-			m_loNotePos = qMax(qreal(m_scoreNotes[i]->notePos() + 2), m_loNotePos);
+  if (hasScordature()) {
+    m_loNotePos = height();
+    return;
+  }
+  m_loNotePos = (isPianoStaff() ? lowerLinePos(): upperLinePos()) + 13.0;
+  for (int i = 0; i < m_scoreNotes.size(); i++)
+      m_loNotePos = qMax(qreal(m_scoreNotes[i]->notePos() + (m_scoreNotes[i]->note()->rtm.stemDown() ? 4 : 2)), m_loNotePos);
 }
 
 
-void TscoreStaff::connectNote(TscoreNote* sn) {
-	connect(sn, SIGNAL(noteWasClicked(int)), this, SLOT(onNoteClicked(int)));
-	connect(sn, SIGNAL(noteWasSelected(int)), this, SLOT(onNoteSelected(int)));
-  connect(sn, SIGNAL(toKeyAnim(QString,QPointF,int)), this, SLOT(toKeyAnimSlot(QString,QPointF,int)), Qt::UniqueConnection);
-  connect(sn, SIGNAL(fromKeyAnim(QString,QPointF,int)), this, SLOT(fromKeyAnimSlot(QString,QPointF,int)), Qt::UniqueConnection);
-  connect(sn, SIGNAL(destroyed(QObject*)), this, SLOT(noteDestroingSlot(QObject*)), Qt::UniqueConnection);
+TscoreNote* TscoreStaff::insert(int index) {
+  auto newNote = new TscoreNote(scoreScene(), this, index);
+  newNote->setZValue(50);
+  m_scoreNotes.insert(index, newNote);
+  return newNote;
 }
 
 
@@ -741,3 +1042,5 @@ void TscoreStaff::connectNote(TscoreNote* sn) {
 
 
 
+
+
diff --git a/src/libs/score/tscorestaff.h b/src/libs/score/tscorestaff.h
index 696e93bbca7e19550d1a5cd32b3c0cb342a7ae51..64cde6a5c6b41f01be5f0890c28257f7cc0aa40d 100644
--- a/src/libs/score/tscorestaff.h
+++ b/src/libs/score/tscorestaff.h
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2013-2015 by Tomasz Bojczuk                             *
+ *   Copyright (C) 2013-2017 by Tomasz Bojczuk                             *
  *   seelook@gmail.com                                                     *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -17,16 +17,16 @@
  ***************************************************************************/
 
 
+class notesToShift;
 #ifndef TSCORESTAFF_H
 #define TSCORESTAFF_H
 
 #include <nootkacoreglobal.h>
 #include "tscoreitem.h"
 #include <music/tclef.h>
-#include <QPointer>
+#include <QtCore/qpointer.h>
 
 class QTimer;
-class TcombinedAnim;
 class Tnote;
 class Ttune;
 class TscoreKeySignature;
@@ -35,158 +35,181 @@ class TscoreNote;
 class TscoreClef;
 class TscoreScene;
 class Tscore5lines;
+class TscoreMeter;
+class Trhythm;
+class Tmeter;
+class TscoreMeasure;
 
 
-/** 
- * Describes offset of a note. 
+/**
+ * Describes offset of a note.
  */
 class NOOTKACORE_EXPORT TnoteOffset
 {
 public:
-  TnoteOffset(int noteOff, int octaveOff);
-  
-  int note;
-  int octave;
+  TnoteOffset(qint8 noteOff = 0, qint8 octaveOff = 0) : note(noteOff), octave(octaveOff) {}
+
+  qint8 note;
+  qint8 octave;
   int total() { return octave * 7 + note; }
 };
 
-/** 
- * @class TscoreStaff manages score items on the staff.
+/**
+ * @p TscoreStaff manages score items on the staff.
  * It has got:
- * - clef - @p TscoreClef - accessing by @p scoreClef()
- * - key signature - @p TscoreKeySignature - scoreKey()
+ * - clef of @p TscoreClef - available by @p scoreClef()
+ * - key signature - @p TscoreKeySignature - @p scoreKey()
+ * - meter (if enabled) - @p TscoreMeter - @p scoreMeter()
  * - notes (in QList) - @p TscoreNote - @p noteSegment(int nr)
  * - scordature - below clef through @p setScordature()
  */
 class NOOTKACORE_EXPORT TscoreStaff : public TscoreItem
 {
-    Q_OBJECT
-
-public:
-    
-	TscoreStaff(TscoreScene* scene, int notesNr);
-	virtual ~TscoreStaff();
 
-			/** Determines index of this staff in staff list in multi-staff mode.
-				* Otherwise (default) returns -1 */
-	void setStafNumber(int nr) { m_staffNr = nr; }
-	int number() { return m_staffNr; }
+  friend class TscoreNote;
+  friend class TscoreMeasure;
+  friend class TmultiScore;
 
-			/** Returns pointer to TscoreNote element in the score. */
-	TscoreNote* noteSegment(int nr) { return m_scoreNotes[nr]; }
+  Q_OBJECT
 
-	TscoreKeySignature* scoreKey() { return m_keySignature; }
+public:
 
-	TscoreClef* scoreClef() { return m_clef; }
+  TscoreStaff(TscoreScene* scene, int notesNr);
+  virtual ~TscoreStaff();
 
-	void setPianoStaff(bool isPiano);
-	bool isPianoStaff() { return m_isPianoStaff; }
+      /** Determines index of this staff in staff list in multi-staff mode.
+        * Otherwise (default) returns -1 */
+  void setStafNumber(int nr) { m_staffNr = nr; }
+  int number() { return m_staffNr; }
 
-			/** Returns current @p index note or Tnote(0, 0, 0) if not set. */
-	Tnote* getNote(int index);
-	void setNote(int index, const Tnote& note);
-	void setNoteDisabled(int index, bool isDisabled);
+      /** Returns pointer to TscoreNote element in the score. */
+  TscoreNote* noteSegment(int nr) { return m_scoreNotes[nr]; }
+  TscoreNote* firstNote() { return m_scoreNotes.first(); }
+  TscoreNote* lastNote() { return m_scoreNotes.last(); }
 
-	int count() { return m_scoreNotes.size(); } /**< Number of notes on the score */
+  TscoreKeySignature* scoreKey() { return m_keySignature; }
+
+  TscoreClef* scoreClef() { return m_clef; }
 
-			/** adds note at the end of the staff
-				* Empty Tnote creates new instance of TscoreNote item. */
-	void addNote(Tnote& note, bool disabled = false);
+  void setPianoStaff(bool isPiano);
+  bool isPianoStaff() const { return m_isPianoStaff; }
+
+      /** Returns current @p index note or Tnote(0, 0, 0) if not set. */
+  Tnote* getNote(int index);
+  void setNote(int index, const Tnote& note);
+  void setNoteDisabled(int index, bool isDisabled);
 
-			/** Adds notes from the list to this staff, starting from given @p index.
-				* Notes number in the list can not be bigger than available space on the staff */
-	void addNotes(int index, QList<TscoreNote*>& nList);
-	void addNote(int index, TscoreNote* freeNotet);
+  int count() { return m_scoreNotes.size(); } /**< Number of notes on the score */
 
-			/** Inserts note in given position (index).
-				* When @p index is out of scope adds it at the end. */
-	void insertNote(int index, const Tnote& note, bool disabled = false);
-	void insertNote(int index, bool disabled = false); /**< Insert empty note */
-	void removeNote(int index); /**< Deletes given note from the staff */
+      /** adds note at the end of the staff
+        * Empty Tnote creates new instance of TscoreNote item. */
+  void addNote(const Tnote& note, bool disabled = false);
 
-			/** Removes all note segments from @p from to @p to
-				* and puts those TscoreNote pointers to given @p nList.
-				* To grab all notes from a staff just invoke:
-				* takeNotes(smoeList, 0, count() - 1); */
-	void takeNotes(QList<TscoreNote*>& nList, int from, int to);
+      /** Adds notes from the list to this staff, starting from given @p index.
+        * Notes number in the list can not be bigger than available space on the staff */
+  void addNotes(int index, QList<TscoreNote*>& nList);
+  void addNote(int index, TscoreNote* freeNotet);
 
-	void setEnableKeySign(bool isEnabled);
+      /**
+       * Inserts note in given position (index).
+       * When @p index is out of scope adds it at the end.
+       * Returns pointer to inserted note
+       */
+  TscoreNote* insertNote(int index, const Tnote& note, bool disabled = false);
+  void insertNote(int index, bool disabled = false); /**< Inserts empty note at @p index position*/
+  void removeNote(int index); /**< Deletes given note from the staff */
 
-			/** This array keeps values (-1, 0 or 1) for accidentals in key sign.
-				* It is common for TscoreKeySignature and all TscoreNote.
-				* TscoreKeySignature::setAccidInKeyPointer and TscoreNote::setAccidInKeyPointer
-				* have to be set to connect them.
-				* When TscoreKeySignature is deleted it should be set to 0. */
-	char accidInKeyArray[7];
+      /** Removes all note segments from @p from to @p to
+        * and puts those TscoreNote pointers to given @p nList.
+        * To grab all notes from a staff just invoke:
+        * takeNotes(someList, 0, count() - 1); */
+  void takeNotes(QList<TscoreNote*>& nList, int from, int to);
 
-			/** Sets scordature according to given tune.
-				* To delete it just call this with Ttune::standardTune.*/
-	void setScordature(Ttune& tune);
-	bool hasScordature() { return (bool)m_scordature; } /**< @p TRUE when staff has got scordature. */
-	void removeScordatute();
+  void setEnableKeySign(bool isEnabled);
 
-	qreal upperLinePos() const { return m_upperLinePos; } /**< Y position of upper line of a staff. */
-	qreal lowerLinePos() const { return m_lowerStaffPos; } /**< Y position of lower line of a lower staff. */
-	qreal height() const { return m_height; } // staff height
-	qreal width() const { return m_width; } // staff width
+      /**
+       * This array keeps values (-1, 0 or 1) for accidentals in key sign.
+       * It is common for TscoreKeySignature and all TscoreNote.
+       * TscoreKeySignature::setAccidInKeyPointer and TscoreNote::setAccidInKeyPointer
+       * have to be set to connect them.
+       * When TscoreKeySignature is deleted it should be set to 0. 
+       */
+  char accidInKeyArray[7];
 
-	qreal loNotePos() { return m_loNotePos; } /**< Y position of lowest note on the staff */
-	qreal hiNotePos() { return m_hiNotePos; } /**< Y position of highest note on the staff */
+      /** Sets scordature according to given tune.
+        * To delete it just call this with Ttune::standardTune.*/
+  void setScordature(Ttune& tune);
+  bool hasScordature() { return (bool)m_scordature; } /**< @p TRUE when staff has got scordature. */
+  void removeScordatute();
 
-			/** Minimal height of the staff to display all its notes. */
-	qreal minHight() { return m_loNotePos - m_hiNotePos; }
+  void setMeter(const Tmeter& m);
+  TscoreMeter* scoreMeter() { return m_scoreMeter; }
 
-			/** Checks positions of all notes to find lowest and highest.
-				* @p doEmit determines whether this method sends appropriate signals */
-	void checkNoteRange(bool doEmit = true);
+  qreal upperLinePos() const { return m_upperLinePos; } /**< Y position of upper line of a staff. */
+  qreal lowerLinePos() const { return m_lowerStaffPos; } /**< Y position of lower line of a lower staff. */
+  qreal height() const { return m_height; } // staff height
+  qreal width() const { return m_width; } // staff width
 
-			/** Updates rectangle of QGraphicsScene to staff bounding rectangle. */
-	void updateSceneRect();
+  qreal loNotePos() const { return m_loNotePos; } /**< Y position of lowest note on the staff */
+  qreal hiNotePos() const { return m_hiNotePos; } /**< Y position of highest note on the staff */
 
-			/** Returns number of a note. upperLinePos() is note nr 0 but it depends on octave (clef).  */
-	int notePosRelatedToClef(int pos, TnoteOffset off) {
-									return off.octave * 7 - (pos + 1 - (int)upperLinePos() - off.note);  }
+      /** Minimal height of the staff to display all its notes. */
+  qreal minHight() const { return m_loNotePos - m_hiNotePos; }
 
-	int notePosRelatedToClef(int pos) { return notePosRelatedToClef(pos, m_offset); }
+      /** Checks positions of all notes to find lowest and highest.
+        * @p doEmit determines whether this method sends appropriate signals */
+  void checkNoteRange(bool doEmit = true);
 
-			/** Returns offset of a y coefficient of a note related to current clef. */
-	int noteOffset() { return m_offset.note; }
+      /** Updates rectangle of QGraphicsScene to staff bounding rectangle. */
+  void updateSceneRect();
 
-			/** octave offset related to middle (one-line) octave. */
-	int octaveOffset() { return m_offset.octave; }
+      /** Returns number of a note. upperLinePos() is note nr 0 but it depends on octave (clef).  */
+  int notePosRelatedToClef(int pos, TnoteOffset off) {
+                  return off.octave * 7 - (pos + 1 - (int)upperLinePos() - off.note);  }
 
-			/** Returns number of accidental in key signature, fe.: F# - 0, C# - 1 or Bb - 0, Eb - 1 */
-	int accidNrInKey(int noteNr, char key);
+  int notePosRelatedToClef(int pos) { return notePosRelatedToClef(pos, m_offset); }
 
-	int noteToPos(const Tnote& note); /**< Return Y position of given note. */
-	int fixNotePos(int pianoPos); /**< Checks is note position on grand staff and adds 2 to it. */
-	qreal notesOffset(); /**< X Position of first TscoreNote on the staff (depends on clef, key and scordature) */
+      /** Returns offset of a y coefficient of a note related to current clef. */
+  int noteOffset() { return int(m_offset.note); }
 
-			/** Informs a staff about QGraphicsView width displaying this staff.
-				* With this value the staff determines maximal lines width and maximal notes count.
-				* If not set (0.0) - single staff, If set - m_externWidth is ignored.
-				* This is very important for multi-system view (vertical staves) */
-	void setViewWidth(qreal viewW);
+      /** octave offset related to middle (one-line) octave. */
+  int octaveOffset() { return int(m_offset.octave); }
+
+      /** Returns number of accidental in key signature, fe.: F# - 0, C# - 1 or Bb - 0, Eb - 1 */
+  int accidNrInKey(int noteNr, char key);
+
+  int noteToPos(const Tnote& note); /**< Return Y position of given note. */
+  int fixNotePos(int pianoPos); /**< Checks is note position on grand staff and adds 2 to it. */
+  qreal notesOffset(); /**< X Position of first TscoreNote on the staff (depends on clef, key and scordature) */
 
-			/** Returns maximal note number which staff can display in single line in view area.
-				* or current notes count if staff is in linear mode */
-	int maxNoteCount() { return m_maxNotesCount ? m_maxNotesCount : count(); }
+      /**
+       * Informs a staff about QGraphicsView width displaying this staff.
+       * With this value the staff determines maximal lines width and maximal notes count.
+       * If not set (0.0) - single staff, If set - m_externWidth is ignored.
+       * This is very important for multi-system view (vertical staves) 
+       */
+  void setViewWidth(qreal viewW);
+
+      /**
+       * width of QGraphicsView in scene coordinates. 
+       */
+  qreal viewWidth() { return m_viewWidth; }
+
+      /** Returns maximal note number which staff can display in single line in view area.
+        * or current notes count if staff is in linear mode */
+  int maxNoteCount() { return m_maxNotesCount ? m_maxNotesCount : count(); }
 
 //--- note controllers/switches
-			/** Switches when note segments have colored background after their note are set */
-	void setSelectableNotes(bool selectable) { m_selectableNotes = selectable; }
-	bool selectableNotes() { return m_selectableNotes; }
+      /** Switches when note segments have colored background after their note are set */
+  void setSelectableNotes(bool selectable) { m_selectableNotes = selectable; }
+  bool selectableNotes() { return m_selectableNotes; }
 
-			/** Determines whether note controllers can add/remove note to the staff.
-				* Notice, when enabled, 'remove' (minus) is displayed only when staff has more notes than one. */
-	void enableToAddNotes(bool alowAdding);
+      /** Shows accidentals from key signature also near a note (in brackets) */
+  void setExtraAccids(bool extra) { m_extraAccids = extra; }
+  bool extraAccids() { return m_extraAccids; }
 
-			/** Shows accidentals from key signature also near a note (in brackets) */
-	void setExtraAccids(bool extra) { m_extraAccids = extra; }
-	bool extraAccids() { return m_extraAccids; }
-
-			/** Stops/starts capturing any mouse events. */
-	void setDisabled(bool disabled);
+      /** Stops/starts capturing any mouse events. */
+  void setDisabled(bool disabled);
 
       /** With tidy key - key signature width is adjusted exactly to space occupies by visible accidentals.
        * Calling this invokes notes replacing when @p tidy value really changes,
@@ -200,111 +223,230 @@ public:
        * If not exists - does nothing. */
   void applyAutoAddedNote();
 
-	virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) {};
-	virtual QRectF boundingRect() const;
+      /**
+       * Width of the staff without clef, key and meter items 
+       */
+  qreal spaceForNotes();
+
+      /**
+       * Return width of the staff content (clef, key signature, meter and all notes with rhythm gaps)
+       * @p gapFact parameter can regulate distance between notes.
+       */
+  qreal contentWidth(qreal gapFact = 1.0);
+
+  int shortestRhythm() { return m_shortestR; } /**< Shortest rhythm duration in the staff */
+  int longestRhythm() { return m_longestR; } /**< Longest rhythm duration in the staff */
+
+      /**
+       * Multiplexer of rhythm gaps between notes.
+       * It changes to place all notes nicely over entire staff width
+       */
+  qreal gapFactor() { return m_gapFactor; }
+
+      /**
+       * Virtual sum of rhythm gaps.
+       * Multiplied by @p m_gapFactor gives real width of all gaps 
+       */
+  qreal gapsSum() { return m_gapsSum; }
+
+  bool hasSpaceFor(qreal newWidth = 7.0); /**< @p TRUE when there is enough space for a new note at the staff end */
+  bool hasSpaceFor(const Tnote& n); /**< @p TRUE when there is enough space for given note */
+
+  int measureOfNoteId(int id); /**< Returns measure number where note with @p id can be placed */
+
+  QList<TscoreMeasure*>& measures() { return m_measures; } /**< List of measures on the staff */
+
+  TscoreMeasure* lastMeasure() { return m_measures.last(); }
+  TscoreMeasure* firstMeasure() { return m_measures.first(); }
+
+  TscoreMeasure* nextMeasure(TscoreMeasure* before);
+  TscoreMeasure* nextMeasure(int id) { return id < m_measures.count() ? nextMeasure(m_measures[id]) : nextMeasure(lastMeasure()); }
+
+      /**
+       * Returns pointer to the next staff or null if none or this staff is the last one.
+       */
+  TscoreStaff* nextStaff();
+
+      /**
+       * Returns pointer to the previous staff or null if none or this staff is the first one.
+       */
+  TscoreStaff* prevStaff();
+
+  bool goingDelete() { return m_goingDelete; }
+
+      /**
+       * Removes @p measId measure from the list and its notes from the staff as well.
+       * Returns @p TscoreMeasure pointer which contains list of taken notes.
+       */
+  TscoreMeasure* takeMeasure(int measId);
+  void insertMeasure(int id, TscoreMeasure* m);
+
+  virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) {};
+  virtual QRectF boundingRect() const;
+
+      /** Prints to std out debug info about this staff: [nr STAFF] in color */
+  char debug();
 
 signals:
-	void pianoStaffSwitched();
-	void noteChanged(int index);
+  void pianoStaffSwitched();
+  void noteChanged(int index);
 
-			/** Emitted when right button was clicked over note.
-				* @p selectableNotes or @p controlledNotes has to be set to @p TRUE */
-	void noteSelected(int index);
-	void clefChanged(Tclef);
+      /** Emitted when right button was clicked over note.
+        * @p selectableNotes or @p controlledNotes has to be set to @p TRUE */
+  void noteSelected(int index);
+  void clefChanged(Tclef);
 
-			/** When staff has no more space to display next note segment.
-				* Argument is staff number */
-	void noMoreSpace(int);
+      /** When staff has no more space to display next note segment.
+        * Argument is staff number */
+  void noMoreSpace(int);
 
-			/** Emitted usually after removing a note. Staff has extra free space.
-				* First argument is staff number, the second one is amount of space for new note(s) */
-	void freeSpace(int, int);
+      /** Emitted usually after removing a note. Staff has extra free space.
+        * First argument is staff number, the second one is amount of space for new note(s) */
+  void freeSpace(int, int);
 
-			/** There was no space for a note emitting as an argument.
-				* Usually it was the last note on this staff before inserting another note. */
-	void noteToMove(int, TscoreNote*);
+      /** There was no space for a note emitting as an argument.
+        * Usually it was the last note on this staff before inserting another note. */
+  void noteToMove(int, TscoreNote*);
 
-			/** Emitting just before note will be removed and deleted.
-				* First argument is staff number and second is note number in the list.
-				* Signal is emitted when note still exists. */
-	void noteIsRemoving(int, int);
+      /** Emitting just before note will be removed and deleted.
+        * First argument is staff number and second is note number in the list.
+        * Signal is emitted when note still exists. */
+  void noteIsRemoving(int, int);
 
-	void noteIsAdding(int, int); /**< Emitting when note is added/inserted to a staff */
+  void noteIsAdding(int, int); /**< Emitting when note is added/inserted to a staff */
 
-			/** Signals informing about changing note range on the staff.
-				* Sending parameters are the staff number and difference of Y position. */
-	void loNoteChanged(int,qreal);
-	void hiNoteChanged(int,qreal);
+      /** Signals informing about changing note range on the staff.
+        * Sending parameters are the staff number and difference of Y position. */
+  void loNoteChanged(int, qreal);
+  void hiNoteChanged(int, qreal);
 
+      /** This staff asks to take out its measure (usually the last one) with given number  */
+  void moveMeasure(TscoreStaff*, int);
 
-public slots:
-	void onClefChanged(Tclef clef); /**< It is connected with clef, but also refresh m_offset appropriate to current clef. */
-	void noteChangedAccid(int accid); /**< TscoreNote wheel event - changes accidental */
+      /**
+       * Asks for next staff. 
+       * In the argument pointer of the next staff is put or null if none.
+       */
+  void getNextStaff(TscoreStaff*&);
 
-protected:
-			/** Creates staff lines at first call, sets lines width, creates lower staff lines as well.
-				* It also calls createBrace().  */
-	void prepareStaffLines();
+      /**
+       * Asks for previous staff.
+       * In the argument pointer of the next staff is put or null if none.
+       */
+  void getPrevStaff(TscoreStaff*&);
+
+      /** When staff has no more notes */
+  void staffIsEmpty();
 
-			/** It doesn't add scordature like setScordature() method,
-				* just make place (re-sizes staff width if necessary) for scordature.
-				* setScordature calls it itself. */
-	void setEnableScordtature(bool enable);
 
-			/** Calculates current width of a staff depends on is key sign. enabled. */
-	void updateWidth();
+public slots:
+  void onClefChanged(Tclef clef); /**< It is connected with clef, but also refresh m_offset appropriate to current clef. */
 
-	void updateIndexes(); /**< Iterates through all notes, sets theirs indexes. It must to be invoked after inserting or removing a note. */
-	void updateLines(); /**< Updates staff lines  */
-	void updateNotesPos(int startId = 0); /**< Replaces (performs pos()) all TscoreNote items. Starts from @p startId */
 
-			/** Protected method that creates new TscoreNote note instance and inserts it to m_scoreNotes.
-				* It doesn't perform any checks */
-	void insert(int index);
+protected:
+
+      /**
+       * Creates staff lines at first call, sets lines width, creates lower staff lines as well.
+       * It also calls @p createBrace().  
+       */
+  void prepareStaffLines();
+
+      /**
+       * It doesn't add scordature like @p setScordature() method,
+       * just make place (re-sizes staff width if necessary) for scordature.
+       * @p setScordature() calls it itself.
+       */
+  void setEnableScordtature(bool enable);
+
+      /** Calculates current width of a staff depends on is key sign. enabled. */
+  void updateWidth();
+
+  void updateIndexes(); /**< Iterates through all notes, sets theirs indexes. It must to be invoked after inserting or removing a note. */
+  void updateLines(); /**< Updates staff lines  */
+  void updateNotesPos(int startId = 0); /**< Replaces (performs pos()) all TscoreNote items. Starts from @p startId */
+
+  void noteChangedWidth(int noteId); /**< Called by @class TscoreNote  */
+  void prepareNoteChange(TscoreNote* sn = nullptr);
+
+  TscoreNote* insertNote(const Tnote& note, int index, bool disabled = false);
+
+      /**
+       * Fits all notes on the staff by calculating their rhythm gaps and widths.
+       * Determines when there is too many notes (measures)
+       * and shift them to the next staff.
+       * Updates (and fits) the gap factor @p m_gapFactor
+       */
+  void fit();
+
+      /**
+       * Shifts given @p notesToShift list to measure @p measureNr.
+       * All shifted notes still belongs to this staff,
+       * so their positions and indexes don't change.
+       */
+  void shiftToMeasure(int measureNr, QList<TscoreNote*>& notesToShift);
+
+  int shiftFromMeasure(int measureNr, int dur, QList<TscoreNote*>& notesToShift);
+
+      /**
+       * Every note segment call this before it will be deleted 
+       */
+  void noteGoingDestroy(QObject* n);
+
+      /**
+       * Takes actual position of note item @p noteIndex and sets its @p TscoreNote::note() to appropriate value  
+       */
+  void updatePitch(int noteIndex);
 
 protected slots:
-	void onKeyChanged();
-	void onNoteClicked(int noteIndex);
-	void onNoteSelected(int noteIndex);
-	void onAccidButtonPressed(int accid); // TnoteControl accid button pressed
-	void onPianoStaffChanged(Tclef clef); // clef demands piano staff
-	void toKeyAnimSlot(const QString& accidText, const QPointF& accidPos, int notePos);
-	void fromKeyAnimSlot(const QString& accidText, const QPointF& accidPos, int notePos);
-	void accidAnimFinished();
-	void addNoteTimeOut();
-  void noteDestroingSlot(QObject* n); /**< Every note segment call this before it will be deleted */
+  void onKeyChanged();
+  void onNoteClicked(int noteIndex);
+  void onNoteSelected(int noteIndex);
+  void onAccidButtonPressed(int accid); // TnoteControl accid button pressed
+  void onPianoStaffChanged(Tclef clef); // clef demands piano staff
+  void addNoteTimeOut();
 
 private:
-	int 															 m_staffNr;
-	Tscore5lines                      *m_5lines;
-	TscoreClef              					*m_clef;
-	QGraphicsSimpleTextItem 					*m_brace;
-	TscoreKeySignature								*m_keySignature;
-	QList<TscoreNote*>       					 m_scoreNotes;
-	qreal                    					 m_upperLinePos, m_lowerStaffPos;
-	qreal                    					 m_height, m_width;
-	qreal															 m_viewWidth; /**< width of QGraphicsView in scene coordinates. */
-	TnoteOffset              					 m_offset;
-	bool 										 					 m_isPianoStaff;
-	TscoreScordature				 					*m_scordature;
-	bool										 					 m_enableScord, m_tidyKey;
-	TcombinedAnim											*m_accidAnim;
-	QGraphicsSimpleTextItem 					*m_flyAccid;
-	bool 										 					 m_selectableNotes, m_extraAccids;
-	int																 m_maxNotesCount;
-	qreal															 m_loNotePos, m_hiNotePos;
-	bool															 m_lockRangeCheck; /**< to prevent the checking during clef switching */
-	QPointer<QTimer>									 m_addTimer;
-	int																 m_autoAddedNoteId; /**< Index of automatically added last note. */
-	QPointer<TscoreNote>               m_noteWithAccidAnimed; /**< Pointer to note segment currently invoked to key animation */
+  int                                 m_staffNr;
+  Tscore5lines                       *m_5lines;
+  TscoreClef                         *m_clef;
+  QGraphicsSimpleTextItem            *m_brace;
+  TscoreKeySignature                 *m_keySignature;
+  QList<TscoreNote*>                  m_scoreNotes;
+  QList<TscoreMeasure*>               m_measures;
+  qreal                               m_upperLinePos, m_lowerStaffPos;
+  qreal                               m_height, m_width;
+  qreal                               m_viewWidth; /**< width of QGraphicsView in scene coordinates. */
+  TnoteOffset                         m_offset;
+  bool                                m_isPianoStaff;
+  TscoreScordature                   *m_scordature;
+  bool                                m_enableScord, m_tidyKey;
+  QGraphicsSimpleTextItem            *m_flyAccid;
+  bool                                m_selectableNotes, m_extraAccids;
+  int                                 m_maxNotesCount;
+  qreal                               m_loNotePos, m_hiNotePos;
+  qreal                               m_allNotesWidth; /**< Width of all notes on the staff (without gaps between) */
+  qreal                               m_gapFactor; /**< multiplexer of rhythm gaps between notes */
+  qreal                               m_gapsSum; /**< Virtual sum of rhythm gaps - multiplied by @p m_gapFactor gives real width of all gaps */
+  int                                 m_shortestR, m_longestR;
+  bool                                m_lockRangeCheck; /**< to prevent the checking during clef switching */
+  int                                 m_autoAddedNoteId; /**< Index of automatically added last note. */
+  QPointer<TscoreNote>                m_noteWithAccidAnimed; /**< Pointer to note segment currently invoked to key animation */
+  TscoreMeter                        *m_scoreMeter;
+  bool                                m_goingDelete = false;
 
 private:
-	void createBrace();
-	int getMaxNotesNr(qreal maxWidth); /**< Calculates notes number from given width */
-	void findLowestNote(); /**< Checks all Y positions of staff notes ti find lowest one */
-	void findHighestNote(); /**< Checks all Y positions of staff notes ti find highest one */
-	void connectNote(TscoreNote *sn); /**< Performs all TscoreNote connections to this staff */
+  void createBrace();
+  int getMaxNotesNr(qreal maxWidth); /**< Calculates notes number from given width */
+  void findLowestNote(); /**< Checks all Y positions of staff notes ti find lowest one */
+  void findHighestNote(); /**< Checks all Y positions of staff notes ti find highest one */
+
+    /**
+    * Private method that creates new TscoreNote note instance and inserts it to m_scoreNotes.
+    * It doesn't perform any checks, and returns instance of created note
+    */
+  TscoreNote* insert(int index);
 
 };
 
 #endif // TSCORESTAFF_H
+
diff --git a/src/libs/score/tscoretie.cpp b/src/libs/score/tscoretie.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a809630d6ca5ad92f269b6fb36bc011286d31fbc
--- /dev/null
+++ b/src/libs/score/tscoretie.cpp
@@ -0,0 +1,137 @@
+/***************************************************************************
+ *   Copyright (C) 2016 by Tomasz Bojczuk                                  *
+ *   seelook@gmail.com                                                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 3 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+
+#include "tscoretie.h"
+#include "tscorenote.h"
+#include <music/tnote.h>
+#include <tnoofont.h>
+#include <QtWidgets/qgraphicsitem.h>
+#include <QtGui/qbrush.h>
+
+#include <QtCore/qdebug.h>
+
+/**
+ * @p TscoreTie class supports all kinds of tie combinations.
+ * As long as graphically tie bow is an independent single element between two notes
+ * and it is not aware about others
+ * logically, through @p Tnote::rtm.tie many notes can be connected.
+ *
+ * @p TrhythmPane calls @p TscoreTie::check when user clicks tie item on it
+ *
+ * TODO: - graphically a bow doesn't look like score engraving tradition used to do.
+ *       - extra tie at the staff beginning collides with key signature
+ */
+
+TscoreTie::TscoreTie(TscoreNote* sn1, TscoreNote* sn2) :
+  m_firstNote(sn1),
+  m_scondNote(sn2)
+{
+  if (firstNote()->note()->rtm.tie()) // continue tie if first note already belongs to someone
+    firstNote()->note()->rtm.setTie(Trhythm::e_tieCont);
+  else // or start a new one
+    firstNote()->note()->rtm.setTie(Trhythm::e_tieStart);
+
+  if (secondNote()->tie()) // second note has a tie so set it to continue
+    secondNote()->note()->rtm.setTie(Trhythm::e_tieCont);
+  else // or end the tie on second note
+    secondNote()->note()->rtm.setTie(Trhythm::e_tieEnd);
+
+  m_tieItem = newTie(firstNote());
+  updateLength();
+  checkStaves();
+}
+
+
+TscoreTie::~TscoreTie()
+{
+  qDebug() << "[TIE] deleting" << firstNote()->index() << firstNote()->note()->toText() << "with" << secondNote()->index();
+  Trhythm& firstRtm = firstNote()->note()->rtm;
+  if (firstRtm.tie() == Trhythm::e_tieCont)
+    firstRtm.setTie(Trhythm::e_tieEnd);
+  else
+    firstRtm.setTie(Trhythm::e_noTie);
+
+  Trhythm& secondRtm = secondNote()->note()->rtm;
+  if (secondRtm.tie() == Trhythm::e_tieCont) // when second note has a tie - set it to tie start
+    secondRtm.setTie(Trhythm::e_tieStart);
+  else
+    secondRtm.setTie(Trhythm::e_noTie);
+
+  delete m_tieItem;
+  if (m_extraTieItem)
+    delete m_extraTieItem;
+}
+
+
+/*static*/
+TscoreTie* TscoreTie::check(TscoreNote* sn) {
+  if (sn && !sn->tie()) {
+    auto next = sn->nextNote();
+    if (!sn->note()->isRest() && next && !next->note()->isRest() && sn->note()->compareNotes(*next->note()))
+        return new TscoreTie(sn, next);
+  }
+  return nullptr;
+}
+
+
+void TscoreTie::checkStaves() {
+  if ((m_extraTieItem == nullptr) != (firstNote()->staff() == secondNote()->staff())) {
+      if (m_extraTieItem) {
+          delete m_extraTieItem;
+          m_extraTieItem = nullptr;
+      } else {
+          m_extraTieItem = newTie(secondNote());
+          QTransform t;
+          t.scale(1.0, secondNote()->note()->rtm.stemDown() ? -1.0 : 1.0);
+          m_extraTieItem->setTransform(t);
+          m_extraTieItem->setPos(-m_extraTieItem->boundingRect().width(),
+                                 secondNote()->notePos() + (secondNote()->note()->rtm.stemDown() ? 3.7 : - 1.8));
+      }
+      updateLength();
+  }
+}
+
+//#################################################################################################
+//###################              PROTECTED           ############################################
+//#################################################################################################
+
+void TscoreTie::updateLength() {
+  QTransform t;
+  if (firstNote()->staff() == secondNote()->staff())
+    t.scale((secondNote()->x() - firstNote()->x() - firstNote()->width() * 0.8) / m_tieItem->boundingRect().width(),
+            firstNote()->note()->rtm.stemDown() ? -1.0 : 1.0);
+  else
+    t.scale(1.0, firstNote()->note()->rtm.stemDown() ? -1.0 : 1.0);
+  m_tieItem->setTransform(t);
+  m_tieItem->setPos(firstNote()->width(), firstNote()->notePos() + (firstNote()->note()->rtm.stemDown() ? 3.7 : - 1.8));
+}
+
+
+QGraphicsSimpleTextItem * TscoreTie::newTie(TscoreNote* parentNote) {
+  auto tie = new QGraphicsSimpleTextItem(QString(QChar(0xe18c)), parentNote); // tie symbol
+  tie->setFont(TnooFont(5));
+  tie->setBrush(QBrush(parentNote->color()));
+  return tie;
+}
+
+
+
+
+
+
+
diff --git a/src/libs/score/tscoretie.h b/src/libs/score/tscoretie.h
new file mode 100644
index 0000000000000000000000000000000000000000..109726158ea70f54f6efaf61913b8deaf7749eb4
--- /dev/null
+++ b/src/libs/score/tscoretie.h
@@ -0,0 +1,82 @@
+/***************************************************************************
+ *   Copyright (C) 2016 by Tomasz Bojczuk                                  *
+ *   seelook@gmail.com                                                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 3 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+
+#ifndef TSCORETIE_H
+#define TSCORETIE_H
+
+
+#include <nootkacoreglobal.h>
+
+
+class QGraphicsSimpleTextItem;
+class TscoreNote;
+
+
+/**
+ * The bow connecting two notes (ligature)
+ * It could be created by constructor but there is static method
+ * @p TscoreTie::check() with @p TscoreNote as a parameter
+ * that checks given note and next one to it are they the same
+ * and returns @p TscoreTie instance or @p nullptr if not created.
+ * The common way to create tie is to call @p TscoreNote::tieWithNext()
+ *
+ * There is single bow adjusted to notes position if they lay at the same staff.
+ * When second note lays on the next one, an additional bow is added - before second note.
+ * @p checkStaves method manages it. It is invoked only from @p TscoreMeasure::setStaff.
+ *
+ * @p TscoreTie class also manages logical states of ties in @p TscoreNote::note.rtm.tie.
+ * Constructor and destrucor keep it up to date
+ */
+class NOOTKACORE_EXPORT TscoreTie
+{
+
+  friend class TscoreNote;
+
+public:
+  explicit TscoreTie(TscoreNote* sn1, TscoreNote* sn2);
+  virtual ~TscoreTie();
+
+      /**
+       * Initial static method to create new tie with next note to given one
+       * or delete the tie if given note has it already.
+       */
+  static TscoreTie* check(TscoreNote* sn);
+
+
+  TscoreNote* firstNote() { return m_firstNote; }
+  TscoreNote* secondNote() { return m_scondNote; }
+
+      /**
+       * Compares are staves of notes the same.
+       * Adds extra tie if different.
+       */
+  void checkStaves();
+
+protected:
+  void updateLength(); /**< Updates ties length according to current position */
+
+private:
+  QGraphicsSimpleTextItem* newTie(TscoreNote* parentNote);
+
+private:
+  TscoreNote                               *m_firstNote, *m_scondNote;
+  QGraphicsSimpleTextItem                  *m_tieItem;
+  QGraphicsSimpleTextItem                  *m_extraTieItem = nullptr; /**< Additional tie when 2nd note lays on another staff  */
+};
+
+#endif // TSCORETIE_H
diff --git a/src/main.cpp b/src/main.cpp
index 9f42f7873fcd5b919c39e87fe8aa179642946f45..3506e50e5968314d91c8d0ed35d82da3ca0baa32 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -18,7 +18,6 @@
 
 
 #if defined (Q_OS_ANDROID)
-  #include "ttouchstyle.h"
   #include <Android/tandroid.h>
 #endif
 #include <tinitcorelib.h>
@@ -35,6 +34,9 @@
 #include <QtCore/qfile.h>
 #include <QtCore/qsettings.h>
 
+#include <declarative/descore.h>
+#include <declarative/denote.h>
+
 
 static QString logFile;
 
@@ -104,6 +106,10 @@ int main(int argc, char *argv[])
       return 111;
 
     a->setWindowIcon(QIcon(Tpath::img("nootka")));
+
+    qmlRegisterType<DeScore>("Score", 1, 0, "Score");
+    qmlRegisterType<DeNote>("Score", 1, 0, "Note");
+
 // creating main window
     e = new QQmlApplicationEngine;
     e->rootContext()->setContextProperty(QStringLiteral("Tpath"), &pathObj);
diff --git a/src/qml/MainWindow.qml b/src/qml/MainWindow.qml
index 76e4fe0416c4d5a29db36da1229cf5b86dffa982..6992bb8565d618a68c607b47cebe586f0eef39fa 100644
--- a/src/qml/MainWindow.qml
+++ b/src/qml/MainWindow.qml
@@ -21,6 +21,7 @@ import QtQuick.Controls 2.0
 import QtQuick.Layouts 1.3
 import QtQuick.Window 2.0
 
+import Score 1.0
 
 ApplicationWindow {
   id: nootkaWindow
@@ -46,6 +47,29 @@ ApplicationWindow {
 
   header: TtoolBar {}
 
+  ColumnLayout {
+    anchors.fill: parent
+    Score {
+      Layout.fillWidth: true
+      Layout.fillHeight: true
+
+      Note {
+        pitch: 6
+        octave: 1
+        alter: -1
+        rhythm: Note.Esixteenth
+      }
+      Note {
+        pitch: 5
+        octave: 0
+        alter: 1
+        rhythm: Note.Esixteenth
+      }
+    }
+
+    Rectangle { height: nootkaWindow.height / 3; Layout.fillWidth: true; color: "blue" }
+  }
+
   Component.onCompleted: {}
 
 }